1
$\begingroup$

I have a simple question that I wasn't able to find an answer to. I have a function f(x) where x is some vector, for example:

function f=f(x)
    f=x.^4;
end

Then I want to integrate with bounds as vectors:

x=1:0.1:10;
x_0=2*ones(size(x));
g=integral(@f,x_0,x);

and I want to get g as a vector g(i)=integral(@f,x_0(i),x(i)). However, this will return an error that the bounds have to be scalars.

Obviously I can use a loop:

x=1:0.1:10;
x_0=2*ones(size(x));
for i=1:length(x)
    g(i)=integral(@f,x_0(i),x(i));
end

but that can be very inefficient if I have big vectors that are repeatedly integrated.

Is there a simple efficient way to do this vectorized without a loop?

$\endgroup$
5
  • $\begingroup$ I assume that your function f is just an example. A for loop is the way to do this. As the documentation indicates, integral only handles scalar bounds. This makes sense as the integration might be quite different for different bounds, which would potentially diminish any benefits from parallelization. for loops aren't terribly inefficient in current versions of Matlab. However, you should be sure to pre-allocate your output g. And if the lower bound x_0 is constant, then you don't need to turn it into a vector. $\endgroup$
    – horchler
    Commented Mar 21, 2016 at 16:37
  • $\begingroup$ @horchler ok, so your 100% sure that there isn't a way to "vectorize" this with efficiency? arrayfun for example is a way to vectorize but is less efficient than the for loop $\endgroup$
    – TensoR
    Commented Mar 23, 2016 at 18:13
  • 1
    $\begingroup$ What do you think arrayfun is other than a for loop in disguise? ;-) And, as you indicate, it's often less efficient for applications like this. If you want faster, you'll need to implement your own quadrature routine, or solve the integral symbolically (or come up with a suitable approximation) and vectorize the evaluation of the result. $\endgroup$
    – horchler
    Commented Mar 23, 2016 at 18:56
  • $\begingroup$ i ended up using a parfor loop, which gave the best efficiency $\endgroup$
    – TensoR
    Commented Mar 28, 2016 at 14:00
  • $\begingroup$ Is performance the only metric of interest? Have you considered writing a small c++ code and calling it from Matlab with coder.ceval('cfun_name'). This may give you the performance your looking for. $\endgroup$
    – Charles
    Commented Apr 26, 2016 at 4:53

1 Answer 1

1
$\begingroup$

I think arrayfun is what you are looking for:

arrayfun(@(x_1, x_2) integral(@(y) y.^4, x_1, x_2), x_0, x)
$\endgroup$
2
  • $\begingroup$ i already came across arrayfun, which indeed can sort of "vectorize" this, but sadly from what i've seen and looked up arrayfun is even less efficient than a loop. do you know of any other way? $\endgroup$
    – TensoR
    Commented Mar 23, 2016 at 18:17
  • $\begingroup$ I'm not sure why you're asking for another way of avoiding the for loop - the question becomes where the for loop ends up. You could instead write your own integral function that accepts vector bounds, but then you will have moved the for loop one level deeper into your code. There is no way to just get rid of it $\endgroup$
    – cbcoutinho
    Commented Jun 19, 2016 at 23:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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