matlab integral function handle nested - matlab

I have a problem with integrating nested function handles in Matlab:
fun = #(x,y) 2*x*y;
y = #(x,a) 5*a*x;
int = integral(#(x)fun(x,y(x,5)),0,2)
The actual nesting goes deeper and the actual functions are more complex but this example pretty much describes my problem which throws 'Error using *
Inner matrix dimensions must agree.'

The reason of this problem is that MATLAB tried to pass you a vector expecting that your function would return a vector of values. Try this one (notice the use of point-wise product):
fun = #(x,y) 2*x.*y;
y = #(x,a) 5*a.*x;
int = integral(#(x)fun(x,y(x,5)),0,2)
This this the excerpt from relevant MATLAB documentation:
For scalar-valued problems, the function y = fun(x) must accept a vector argument, x, and return a vector result, y. This generally means that fun must use array operators instead of matrix operators. For example, use .* (times) rather than * (mtimes). If you set the 'ArrayValued' option to true, then fun must accept a scalar and return an array of fixed size.

Related

Bessel's integral implementation

I'm trying to implement this integral representation of Bessel function of the first kind of order n.
here is what I tried:
t = -pi:0.1:pi;
n = 1;
x = 0:5:20;
A(t) = exp(sqrt(-1)*(n*t-x*sin(t)));
B(t) = integral(A(t),-pi,pi);
plot(A(t),x)
the plot i'm trying to get is as shown in the wikipedia page.
it said:
Error using * Inner matrix dimensions must agree.
Error in besselfn (line 8) A(t) = exp(sqrt(-1)*(n*t-x*sin(t)));
so i tried putting x-5;
and the output was:
Subscript indices must either be real positive integers or logicals.
Error in besselfn (line 8) A(t) = exp(sqrt(-1)*(n*t-x*sin(t)));
How to get this correct? what am I missing?
To present an anonymous function in MATLAB you can use (NOT A(t)=...)
A = #(t) exp(sqrt(-1)*(n*t-x.*sin(t)));
with element-by-element operations (here I used .*).
Additional comments:
You can use 1i instead of sqrt(-1).
B(t) cannot be the function of the t argument, because t is the internal variable for integration.
There are two independent variables in plot(A(t),x). Thus you can display plot just if t and x have the same size. May be you meant something like this plot(x,A(x)) to display the function A(x) or plot(A(x),x) to display the inverse function of A(x).
Finally you code can be like this:
n = 1;
x = 0:.1:20;
A = #(x,t) exp(sqrt(-1)*(n*t-x.*sin(t)));
B = #(x) integral(#(t) A(x,t),-pi,pi);
for n_x=1:length(x)
B_x(n_x) = B(x(n_x));
end
plot(x,real(B_x))

Using matlab fit object as a function

Matlab fit is no doubt useful but it is not clear how to use it as a function
apart from trivial integration and differentiation given on the official website:
http://uk.mathworks.com/help/curvefit/example-differentiating-and-integrating-a-fit.html
For example given a fit stored in the object 'curve' one can evaluate
curve(x) to get a number. But how one would, e.g. integrate |curve(x)|^2 (apart from clumsily creating a new fit)? Trying naively
curve = fit(x_vals,y_vals,'smoothingspline');
integral(curve(x)*curve(x), 0, 1)
gives an error:
Output of the function must be the same size as the input. If FUN is an array-valued integrand, set the 'ArrayValued' option to true.
I have also tried a work around by definining a normal function and an implicit function for the integrand (below) but both give the same error.
func=#(x)(curve(x))...; % trial solution 1
function func_val=func(curve, x)...; % trial solution 2
Defining function for the integrand followed by integration with option 'ArrayValued' set to 'true' works:
func=#(x)(curve(x)*curve(x));
integral(func,0,1,'ArrayValued',true)
You need to have the function vectorized, i.e use element-wise operations like curve(x).*curve(x) or curve(x).^2.
Also make sure that the shape of the output matches the input, i.e a row input gives a row output, similarly a column comes out as a column. It seems that evaluating the fit object always returns a column vector (e.g. f(1:10) returns a 10x1 vector not 1x10).
With that said, here is an example:
x = linspace(0,4*pi,100)';
y = sin(x);
y = y + 0.5*y.*randn(size(y));
f = fit(x, y, 'smoothingspline');
now you can integrate as:
integral(#(x) reshape(f(x).^2,size(x)), 0, 1)
in this case, it can be simplified as a simple transpose:
integral(#(x) (f(x).^2)', 0, 1)

Symbolic integration vs numeric integration in MATLAB

I have an expression with three variables x,y and v. I want to first integrate over v, and so I use int function in MATLAB.
The command that I use is the following:
g =int((1-fxyz)*pv, v, y,+inf)%
PS I haven't given you what the function fxyv is but it is very complicated and so int is taking so long and I am afraid after waiting it might not solve it.
I know one option for me is to integrate numerically using for example integrate, however I want to note that the second part of this problem requires me to integrate exp[g(x,y)] over x and y from 0 to infinity and from x to infinity respectively. So I can't take numerical values of x and y when I want to integrate over v I think or maybe not ?
Thanks
Since the question does not contain sufficient detail to attempt analytic integration, this answer focuses on numeric integration.
It is possible to solve these equations numerically. However, because of complex dependencies between the three integrals, it is not possible to simply use integral3. Instead, one has to define functions that compute parts of the expressions using a simple integral, and are themselves fed into other calls of integral. Whether this approach leads to useful results in terms of computation time and precision cannot be answered generally, but depends on the concrete choice of the functions f and p. Fiddling around with precision parameters to the different calls of integral may be necessary.
I assume that the functions f(x, y, v) and p(v) are defined in the form of Matlab functions:
function val = f(x, y, v)
val = ...
end
function val = p(v)
val = ...
end
Because of the way they are used later, they have to accept multiple values for v in parallel (as an array) and return as many function values (again as an array, of the same size). x and y can be assumed to always be scalars. A simple example implementation would be val = ones(size(v)) in both cases.
First, let's define a Matlab function g that implements the first equation:
function val = g(x, y)
val = integral(#gIntegrand, y, inf);
function val = gIntegrand(v)
% output must be of the same dimensions as parameter v
val = (1 - f(x, y, v)) .* p(v);
end
end
The nested function gIntegrand defines the object of integration, the outer performs the numeric integration that gives the value of g(x, y). Integration is over v, parameters x and y are shared between the outer and the nested function. gIntegrand is written in such a way that it deals with multiple values of v in the form of arrays, provided f and p do so already.
Next, we define the integrand of the outer integral in the second equation. To do so, we need to compute the inner integral, and therefore also have a function for the integrand of the inner integral:
function val = TIntegrandOuter(x)
val = nan(size(x));
for i = 1 : numel(x)
val(i) = integral(#TIntegrandInner, x(i), inf);
end
function val = TIntegrandInner(y)
val = nan(size(y));
for j = 1 : numel(y)
val(j) = exp(g(x(i), y(j)));
end
end
end
Because both function are meant to be fed as an argument into integral, they need to be able to deal with multiple values. In this case, this is implemented via an explicit for loop. TIntegrandInner computes exp(g(x, y)) for multiple values of y, but the fixed value of x that is current in the loop in TIntegrandOuter. This value x(i) play both the role of a parameter into g(x, y) and of an integration limit. Variables x and i are shared between the outer and the nested function.
Almost there! We have the integrand, only the outermost integration needs to be performed:
T = integral(#TIntegrandOuter, 0, inf);
This is a very convoluted implementation, which is not very elegant, and probably not very efficient. Again, whether results of this approach prove to be useful needs to be tested in practice. However, I don't see any other way to implement these numeric integrations in Matlab in a better way in general. For specific choices of f(x, y, v) and p(v), there might be possible improvements.

integral2 with fun calculated using vector

Im new to MATLAB. Want to use integral2 as follows
function num = numer(x)
fun=#(p,w) prod((p+1-p).*(1-w).*exp(w.*x.*x/2))
num= integral2(fun ,0,1,0,1)
end
I get several errors starting with
Error using .*
Matrix dimensions must agree.
Error in numer>#(p,w)prod(p+(1-w).*exp(w.*x.*x/2)) (line 5)
fun=#(p,w) prod(p+(1-w).*exp(w.*x.*x/2))
Can you please tell me what I do wrong.
Thanks
From the help for integral2:
All input functions must accept arrays as input and operate
elementwise. The function Z = FUN(X,Y) must accept arrays X and Y of
the same size and return an array of corresponding values.
When x was non-scalar, your function fun did not do this. By wrapping everything in prod, the function always returned a scalar. Assuming that your prod is in the right place to begin with and taking advantage of the properties of the exponential, I believe this version will do what you need for vector x:
x = [0 1];
lx = length(x);
fun = #(p,w)(p+1-p).^lx.*(1-w).^lx.*exp(w).^sum(x.*x/2);
num = integral2(fun,0,1,0,1)
Alternatively, fun = #(p,w)(p+1-p).^lx.*(1-w).^lx.*exp(sum(x.*x/2)).^w; could be used.

MATLAB Function (Solving an Error)

I have one file with the following code:
function fx=ff(x)
fx=x;
I have another file with the following code:
function g = LaplaceTransform(s,N)
g = ff(x)*exp(-s*x);
a=0;
b=1;
If=0;
h=(b-a)/N;
If=If+g(a)*h/2+g(b)*h/2;
for i=1:(N-1)
If=If+g(a+h*i)*h;
end;
If
Whenever I run the second file, I get the following error:
Undefined function or variable 'x'.
What I am trying to do is integrate the function g between 0 and 1 using trapezoidal approximations. However, I am unsure how to deal with x and that is clearly causing problems as can be seen with the error.
Any help would be great. Thanks.
Looks like what you're trying to do is create a function in the variable g. That is, you want the first line to mean,
"Let g(x) be a function that is calculated like this: ff(x)*exp(-s*x)",
rather than
"calculate the value of ff(x)*exp(-s*x) and put the result in g".
Solution
You can create a subfunction for this
function result = g(x)
result = ff(x) * exp(-s * x);
end
Or you can create an anonymous function
g = #(x) ff(x) * exp(-s * x);
Then you can use g(a), g(b), etc to calculate what you want.
You can also use the TRAPZ function to perform trapezoidal numerical integration. Here is an example:
%# parameters
a = 0; b = 1;
N = 100; s = 1;
f = #(x) x;
%# integration
X = linspace(a,b,N);
Y = f(X).*exp(-s*X);
If = trapz(X,Y) %# value returned: 0.26423
%# plot
area(X,Y, 'FaceColor',[.5 .8 .9], 'EdgeColor','b', 'LineWidth',2)
grid on, set(gca, 'Layer','top', 'XLim',[a-0.5 b+0.5])
title('$\int_0^1 f(x) e^{-sx} \,dx$', 'Interpreter','latex', 'FontSize',14)
The error message here is about as self-explanatory as it gets. You aren't defining a variable called x, so when you reference it on the first line of your function, MATLAB doesn't know what to use. You need to either define it in the function before referencing it, pass it into the function, or define it somewhere further up the stack so that it will be accessible when you call LaplaceTransform.
Since you're trying to numerically integrate with respect to x, I'm guessing you want x to take on values evenly spaced on your domain [0,1]. You could accomplish this using e.g.
x = linspace(a,b,N);
EDIT: There are a couple of other problems here: first, when you define g, you need to use .* instead of * to multiply the elements in the arrays (by default MATLAB interprets multiplication as matrix multiplication). Second, your calls g(a) and g(b) are treating g as a function instead of as an array of function values. This is something that takes some getting used to in MATLAB; instead of g(a), you really want the first element of the vector g, which is given by g(1). Similarly, instead of g(b), you want the last element of g, which is given by g(length(g)) or g(end). If this doesn't make sense, I'd suggest looking at a basic MATLAB tutorial to get a handle on how vectors and functions are used.