Numerically integrate a function f(x) over x using MATLAB where f(x) has another argument y which is a vector

18 views (last 30 days)
I would like to numerically integrate a vector which represents a function f(x) over the range of x specified by bounds x0 and x1 in Matlab. I would like to check that the output of the integration is correct and that it converges.
There are the quad and quadl functions that serve well in identifying the required error tolerance, but they need the input argument to be a function and not the resulting vector of the function. There is also the trapz function where we can enter the two vectors x and f(x), but then it computes the integral of f(x) with respect to x depending on the spacing used by vector x. However, there is no given way using trapz to adjust the tolerance as in quad and quadl and make sure the answer is converging.
The main problem why I can't use quad and quadl functions is that f(x) is the following equation: f(x) = sum(exp(-1/2 *(x-y))), the summation is over y, where y is a vector of length n and x is an element that is given each time to the function f(x). Therefore, all elements in vector y are subtracted from element x and then the summation over y is calculated to give us the value f(x). This is done for m values of x, where m is not equal to n.
When I use quadl as explained in the Matlab manual, where f(x) is defined in a separate function .m file and then in the main calling file, I use Q = quadl(@f,x0,x1,tolerance,X,Y); here X is a vector of length m and Y is a vector of length L. Matlab gives an error: "??? Error using ==> minus Matrix dimensions must agree." at the line where I define the function f(x) in the .m function file. f(x) = sum(exp(-1/2 *(x-y)))
I assume the problem is that Matlab treats x and y as vectors that should be of the same length when they are subtracted from each other, whereas what's needed is to subtract the vector Y each time from a single element from the vector X.
Would you please recommend a way to solve this problem and successfully numerically integrate f(x) versus x with a method to control the tolerance?

Accepted Answer

Mike Hosea
Mike Hosea on 18 Sep 2012
Edited: Mike Hosea on 18 Sep 2012
If you have R2012a,
integral(@(x)sum(exp(-0.5*(x-y))),x0,x1,'ArrayValued',true)
For example,
>> y = 0:0.5:4;
>> x0 = 1; x1 = 7;
>> integral(@(x)sum(exp(-0.5*(x-y))),x0,x1,'ArrayValued',true,'AbsTol',1e-12,'RelTol',1e-10)
ans =
34.445963744387342
Even though this is scalar-valued, the ArrayValued option is useful because it prevents the integrator from trying to evaluate more than one x value at a time. This might be somewhat faster, and the technique works with QUADGK (and QUAD or QUADL, but don't use them).
>> y = 0:0.5:4;
>> x0 = 1; x1 = 7;
>> f = @(x)arrayfun(@(t)sum(exp(-0.5*(t-y))),x);
>> integral(f,x0,x1,'AbsTol',1e-12,'RelTol',1e-10)
ans =
34.445963744387342
  4 Comments
Dina
Dina on 18 Sep 2012
Thank you all very much. Unfortunately I don't have R2012a, I have R2011a, so I can't use the integral function.
However, I have posted this question on another forum and someone kindly provided me with the answer to my question using quadl.
The website is: stackoverflow.com/questions The person who provided the following answer is: macduff
From the documentationon quad it says:
The function y = fun(x) should accept a vector argument x and return a vector result y, the integrand evaluated at each element of x.
So every time we call the function, we need to evaluate the integrand at each given x.
Also, to parameterize the function call with the constant vector Y, I recommend an anonymous function call. There's a reasonable demo here. Here's how I implemented your problem in Matlab:
function Q = test_num_int(x0,x1,Y) Q = quad(@(x) myFun(x,Y),x0,x1); end
function fx = myFun(x,Y) fy = zeros(size(Y)); fx = zeros(size(x)); for jj=1:length(fx) for ii=1:length(Y) fy(ii) = exp(-1/2 *(x(jj)-Y(ii))); end fx(jj) = sum(fy); end end Then I called the function and got the following output:
Y = 0:0.1:1; x0 = 0; x1 = 1; Q = test_num_int(x0,x1,Y)
Q =
11.2544
The inputs for the lower and upper bound and the constant array are obviously just dummy values, but the integral converges very quickly, almost immediately. Hope this helps!
Thank you all for your help. I really appreciate it.

Sign in to comment.

More Answers (1)

Matt Fig
Matt Fig on 18 Sep 2012
Edited: Matt Fig on 18 Sep 2012
Mike's solution is essentially the same, but just to show you how to do what you want in your function M-file:
function [Y] = func_x(x)
% help here
y = 0:0.5:4; % Or however you were defining y.
Y = zeros(size(x));
for ii = 1:length(x)
Y(ii) = sum(exp(-1/2 *(x(ii)-y)));
end
Then from the command line you could call:
>> quadl(@func_x,1, 7)
ans =
34.4459638717806

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!