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$
  • $\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 Mar 21 '16 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 Mar 23 '16 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 Mar 23 '16 at 18:56
  • $\begingroup$ i ended up using a parfor loop, which gave the best efficiency $\endgroup$ – TensoR Mar 28 '16 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 Apr 26 '16 at 4:53
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$
  • $\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 Mar 23 '16 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 Jun 19 '16 at 23:42

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.