1
$\begingroup$

I try to integrate a function and plot it in Octave. Integration itself works, i.e. I can evaluate the function g like g(1.5) but plotting fails.

f = @(x) ( (1) .* and((0 < x),(x <= 1)) + (-1) .* and((1 <x),(x<=2)));
g = @(x) (quadcc(f,0,x));

x = -1.0:0.01:3.0;
plot(x,g(x));

But receive the following error:

quadcc: upper limit of integration (B) must be a single real scalar

As far as I can tell this is because the plot passes a vector (namely x) to g which passes it down to quadcc which cannot handle vector arguments for the third argument.

So I understand what's the reason for the error but have no clue how to get the desired result instead.

N.B. This is just a simplified version of the real function I use, but the real function is also constant on a finite set of intervals ( number of intervals is less than ten if that matters). I need to integrate the real function 3 times in succession (f represents a jerk and I need to determine functions for acceleration, velocity and distance). So I cannot compute the integrals by hand like I could in this simple case.

$\endgroup$
0
$\begingroup$

As you observed, Octave integration routines only take scalars as lower and upper integration boundaries. So you cannot pass the vector x = -1.0:.01:3.0 as an argument.

Possible solutions:

Use a for loop, e.g. y = x; for j = 1:length(x) y(j) = g(x(j)); end; plot(x,y)

... which will waste a lot of cycles ... ... or ...

Use a low end integration routine such as the midpoint rule (you're plotting the results, right? Why use quadcc?) and write your own quadrature routine that accepts vector arguments.

$\endgroup$
  • $\begingroup$ it's been so long since I asked this question, I don't remember the use case any more ;-). The only thing I remember is that I switched from Octave to C#... Thanks anyway for your effort. $\endgroup$ – Onur Jun 18 '14 at 13:17
1
$\begingroup$

I do not know if it is valuable to answer this question at this moment, but it is indeed a valuable question in terms of how to use (and think in terms of) GNU Octave.

GNU Octave is based on vector and matrices.

We have a function $f$

f = @(x) ( (1) .* and((0 < x),(x <= 1)) + (-1) .* and((1 <x),(x<=2)));

which, in terms of GNU Octave, is a vectorized function (i.e. if $x$ is a vector, then $f$ is also a vector).

In order to plot the integral of $f$, we have to understand its integral $g$ must be also a vector. The problem is here that function quadcc is not vectorized, you cannot enter an $x$ which is a vector into quadcc. To my knowledge integration procedures are given most of the time in scalar form (not vectorized!).

To do what is demanded in the question above, the simpler way is recurring to a loop, e.g. defining $g$ as following

function y = g(x)
  f = @(x) ( (1) .* and((0 < x),(x <= 1)) + (-1) .* and((1 <x),(x<=2)));  
  y = [];
  for i = 1:length(x), 
    y = [y; quadcc(f,0,x(i))];
  end
end

This way you have a vectorized version of the integral of $f$.

$\endgroup$
0
$\begingroup$

You could use cumtrapz instead of quadcc.

$\endgroup$
  • $\begingroup$ How would you rewrite the function g? g = @(x) (quadcc( 0:0.1:x, f(0:0.1:x))); doesn't work. The plot results in an error ` plt2vv: vector lengths must match`. $\endgroup$ – Onur Nov 21 '12 at 8:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.