1

I have an integral expression which I defined on Matlab using

x = 0:1/1000:1;
g = @(x) (exp(-1./x.^2).*heaviside(x)).*(exp(-1./(1-x).^2).*heaviside(1-x));
t = 0:1/1000:1; 
f = zeros(size(t));
for i = 1:length(t)
    f(i) = integral(g,0,t(i));
end

I can plot it, for example, using plot(t,f), but for other purposes I would like to attach a function handle to f, i.e. something like f = @(t) zeros(size(t)). I have not been able to figure it out thus far. f = @(t) integral(@(x)g(x),0,t) is also not sufficient.

Jason Born
  • 163
  • 1
  • 14

2 Answers2

2

Sorry, I can't comment yet. But does this work?

funcHand= @(t) integral(g,0,t);

You don't have to define x in your code above, since the input to integral is a function handle.

Then to check it's the same:

f2 = zeros(size(t));
for i = 1:length(t)
    f2(i) = funcHand(t(i));
end

Whoops, the other answer said all the above (just replaced the for loop with arrayfun. I didn't see it while writing the answer.

Edit

If you want to build-in the for loop, try:

funcHand= @(t) arrayfun(@(u) integral(g, 0, u),t);

And test:

plot(funcHand(t))
  • Thanks for your help, but unfortunately your code also does not work. I get the same errors. Essentially, I want to be able to write `f(t)` in the following lines. – Jason Born Feb 08 '17 at 17:15
  • Beat me to it. Nice. – Mad Physicist Feb 08 '17 at 17:21
  • I just spelled out your answer... hopefully it answers the Q. –  Feb 08 '17 at 17:24
  • @MadPhysicist Indeed. It also worked out very nicely, so I'd like to thank both of you. I will delay awarding the "answered" tag, as per the usual Stack Exchange conventions, but Mad Physicist, I hope you won't mind if I award it to Jon...he could perhaps do with the reputation points in any case. – Jason Born Feb 08 '17 at 17:24
  • It does. I think OP didn't read the part about not passing an array into the non-arrayfun version. – Mad Physicist Feb 08 '17 at 17:24
  • @user3482534. I don't mind at all. Jon came up with the final answer before I did and I would select his answer in your place. I just updated mine for completeness – Mad Physicist Feb 08 '17 at 17:26
1

Try

f = @(u) integral(g, 0, u)

The additional level of indirection in g seems superfluous. Note that I have called the input u. Keep in mind that f will not accept vectors as its inputs. So doing something like f(t) in your current workspace will not create the same array as your for loop is doing. You will have to iterate through the array. The convenience function arrayfun will do this for you:

o = arrayfun(f, t)

It is roughly equivalent to the loop you have now:

o = zeros(size(t));
for i = 1:length(o)
    o(i) = f(t(i));
end

arrayfun can actually be incorporated into your function handle to allow it to process vector arguments:

h = @(t) arrayfun(f, t)

To avoid the proliferation of unnecessary function handles, you can do

f = @(t) arrayfun(@(u) integral(g, 0, u), t)
Mad Physicist
  • 107,652
  • 25
  • 181
  • 264
  • I get errors: `A and B must be floating-point scalars. Error in @(u)integral(g,0,u)`. Would you be able to expand on what you mean by "you will have to iterate through the array"? – Jason Born Feb 08 '17 at 17:01
  • @user3482534. It looks like you are trying to pass in `t` for you. I specifically mentioned that this will be impossible. See my updated solution. Also, @Jon's answer. – Mad Physicist Feb 08 '17 at 17:22