Integral and scalar product function handles matlab - matlab

I need to compute this kind of integral
I defined the two f(x,y) and g(x,y) inside a single function
h = {#(x,y) f, #(x,y) g};
where f and g are formulas defined before. In this way I have a 1x2 cell and I want to compute the scalar product as
F = #(x,y) dot(h,E)
where E is a vector 2x1 and then integrate
int = integral2(F,a,b,c,d);
giving me this error
Undefined function 'conj' for input arguments of type 'cell'.
Error in dot (line 37)
c = sum(conj(a).*b);
Error in tm_np>#(R,PHI)dot(e_n_even,E)
Error in integral2Calc>integral2t/tensor (line 228)
Z = FUN(X,Y); NFE = NFE + 1;
Error in integral2Calc>integral2t (line 55)
[Qsub,esub] = tensor(thetaL,thetaR,phiB,phiT);
Error in integral2Calc (line 9)
[q,errbnd] = integral2t(fun,xmin,xmax,ymin,ymax,optionstruct);
Error in integral2 (line 106)
Q = integral2Calc(fun,xmin,xmax,yminfun,ymaxfun,opstruct);
I don't understand why is giving me this error. As result of the integral I should have a 2x1 vector

The problem is the generation of your data. integral2 accepts only functions that get #(x,y) as vector input and return the same size. in your case h is already not that, and F has no #(x,y) inputs (well, it has, but you decided not to pass them to h!!!).
% sample data
f=#(x,y)x.^2+y;
g=#(x,y)y.^2+x+3;
E=[3 1];
% Create auxiliary fucntion
mydot=#(x,y)(f(x,y).*E(1)+g(x,y).*E(2));
% work
int = integral2(mydot,0,3,1,5);

Related

Creating array handles for function that returns vector of polynomial expressions

I am trying to use the numerical integration function 'integral'
I created a function of four polynomial functions
[x; x^2; x^3; x^4]
now I want to integrate this vector row by row using the integral function.
I tried making a function handle for the function and passed it to the 'integral' function
function f = test(x)
f = [x,x^2,x^3,x^4];
end
However, I get the following error when calling it command line:
test_var=#test
integral(test_var,0,1)
Error using ^
One argument must be a square matrix and the other must be a scalar.
Use POWER (.^) for elementwise power.
Error in test (line 2)
f = [x,x^2,x^3,x^4];
Error in integralCalc/iterateScalarValued (line 314)
fx = FUN(t);
Error in integralCalc/vadapt (line 132)
[q,errbnd] = iterateScalarValued(u,tinterval,pathlen);
Error in integralCalc (line 75)
[q,errbnd] = vadapt(#AtoBInvTransform,interval);
Error in integral (line 88)
Q = integralCalc(fun,a,b,opstruct);
According to the documentation of integral:
q = integral(fun, xmin, xmax)
For a scalar-valued function fun you need to define the function so that it accepts vector input and produces vector output.
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 have a vector-valued function fun you need to use the input flag 'ArrayValued':
Set this flag to true to indicate that fun is a function that accepts a scalar input and returns a vector, matrix, or N-D array output.
and in that case the requirement in item 1 above is not necessary:
If you set the 'ArrayValued' option to true, then fun must accept a scalar and return an array of fixed size.
So, you need to add the input flag 'ArrayValued' to indicate that you have a vector-valued function:
f = #(x) [x; x^2; x^3; x^4]; % or [x; x.^2; x.^3; x.^4];
integral(f, 0, 1, 'ArrayValued', true) % or integral(#f, 0, 1, 'ArrayValued', true)
% if f is defined in a file
gives
ans =
0.500000000000000
0.333333333333333
0.250000000000000
0.200000000000000

MATLAB: Using an anonymous function within symsum, then fsolve

In MATLAB, I wish to define an anonymous function which has a definite sum in it, and another anonymous function in that. Here's a MWE which hopefully describes what I am trying to do:
clear; n=1; syms j; a=0; b=sqrt(0.5);
Finv = #(x) logninv(x,a,b);
fun = #(x) 0.5-symsum(Finv(j*x), j, 1, n+1);
fsolve(fun,0.1)
The error returned is:
Error using symfun>validateArgNames (line 211) Second input must be a
scalar or vector of unique symbolic variables.
Error in symfun (line 45)
y.vars = validateArgNames(inputs);
Error in sym/subsasgn (line 762)
C = symfun(B,[inds{:}]);
Error in logninv (line 60) p(p < 0 | 1 < p) = NaN;
Error in #(x)logninv(x,a,b)
Error in #(x)0.5-symsum(Finv(j*x),j,1,n+1)
Error in fsolve (line 217)
fuser = feval(funfcn{3},x,varargin{:});
Caused by:
Failure in initial user-supplied objective function evaluation. FSOLVE cannot
continue.
For this particular choice of Finv I solved it using eval and feval as follows:
clear; n=1; syms j; a=0; b=sqrt(0.5);
Finv = #(x) logninv(x,a,b);
fun = #(x) 0.5-eval(symsum(feval(symengine,'logninv',j*x,a,b), j, 1, n+1));
fsolve(fun,0.1)
which produces the answer in this special case because Finv=#(x) logninv(x,a,b), but this defeats the point, which is that I want to be able to define Finv as a univariate function of my choice, not necessarily a predefined MuPAD expression like 'logninv'.
Any advice would be most appreciated.
Try to force the second variable (i.e., j) as being a symbolic variable with a scalar (numerical) data type. Note in his code, that is only variable is not being initialized.
clear; n=1; syms j integer; a=0; b=sqrt(0.5);
Alternatively, you can check assumptions on each variable. For example,
assumptions(j)

How do I plot functions involving integration in Matlab?

I have a characteristic function CF(t, param1, param2, ...) available (here params are parameters of some distribution and are considered fixed). I want to use Gil-Pelaez formula to obtain the CDF instead, so I wrote the following:
function [ F ] = CDF( x, param1, param2, ... )
integrand = #(v) imag(exp(-1i.*v.*x) .* CF(t, param1, param2, ...)) ./ v;
F = 0.5 - (1./pi) .* integral(integrand, 0, 100);
end
This works for single value, e.g. CDF(0.1, param1, param2, ...) gives me desired result. Now I want to plot CDF against a range of x, so I did
x = linspace(-1,1,100);
y = CDF(x, param1, param2, ...)
plot(x, y)
and I end up with the errors like these:
Not enough input arguments.
Error in integralCalc/iterateScalarValued (line 314)
fx = FUN(t);
Error in integralCalc/vadapt (line 132)
[q,errbnd] = iterateScalarValued(u,tinterval,pathlen);
Error in integralCalc (line 75)
[q,errbnd] = vadapt(#AtoBInvTransform,interval);
Error in integral (line 88)
Q = integralCalc(fun,a,b,opstruct);
But y = CDF(x, param1, param2, ...) does work, so the culprit seems to be the exp(-1i.*v.*x) part of the integrand, as the size of v and x does not match. But I am not sure how to fix this.
You have guessed it right that the sizes of v and x don't match which is causing the error. integral passes vector values to the function handle to speed up computations by calculating function values for multiple points at once.
But in this case you should set the parameter 'ArrayValued' to true in the call to integral in the CDF function. This would force integral to pass scalar values of v to the function handle and then CDF would be able to return vector valued y for vector valued x

3D Spherical Plot in Matlab with Derivatives and Bessel Functions

I want to plot the following function B(r,theta,phi) in spherical coordinates.
Bo = 1;
a = 1; % m
lambda = 1; % m^-1
syms r theta;
Br = 2*Bo*(a/r)*besselj(1,lambda*r)*cos(theta)
Bth = -Bo*(a/r)*diff(r*besselj(1,lambda*r),r)*sin(theta)
Bph = lambda*a*Bo*besselj(1,lambda*r)*sin(theta)
[Bx,By,Bz]=sph2cart(Bth,Bph,Br);
x=linspace(0,a);
y=linspace(0,a);
z=linspace(0,a);
quiver3(x,y,z,Bx,By,Bz)
When I run the above code, I receive the following warning and error.
Warning: Using only the real component of complex data.
> In getRealData (line 14)
In quiver3parseargs (line 87)
In quiver3HGUsingMATLABClasses (line 41)
In quiver3 (line 41)
In taylor_state (line 19)
Error using quiver3 (line 43)
DOUBLE cannot convert the input expression into a double array.
If the input expression contains a symbolic variable, use VPA.
Error in taylor_state (line 19)
quiver3(x,y,z,Bx,By,Bz)

How do I create function handle from cfit, multiply with other function handle and integrate the term?

I try to get an integral of two function handles in Matlab. The first function handle would be a weibull probability density function and the second function handle is based on a cfit I created with linear interpolation of single points.
x = 0:0.1:35;
fun1 = #(x) wblpdf(x,weibullAlpha,weibullBeta);
fun2 = #(x) feval(cfitObject,x);
fun3 = #(x) (fun(x).*fun2(x));
y = integral(fun3,0,35); % Using quad(fun3,0,35) doesn't work either.
I receive the following error:
Error using integralCalc/finalInputChecks (line 515)
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.
Error in integralCalc/iterateScalarValued (line 315)
finalInputChecks(x,fx);
Error in integralCalc/vadapt (line 132)
[q,errbnd] = iterateScalarValued(u,tinterval,pathlen);
Error in integralCalc (line 75)
[q,errbnd] = vadapt(#AtoBInvTransform,interval);
Error in integral (line 88)
Q = integralCalc(fun,a,b,opstruct);
Error in test (line 7) % "test" is the name of the script file.
y = integral(fun3,0,35);
The problem must have to do something with "fun2" since the code works just fine with e.g.
fun2 = x.^2;
Note: if I plot fun2 with the cfitObject I don't get an error. It's also possible to integrate the function using quad().
x = 0:0.1:35;
fun2 = #(x) feval(cfitObject,x);
y = quad(fun2,0,35);
plot(x, fun2(x))
Any help is greatly appreciated!
Your code seems to be ok. Probably the problem is that fun2 cannot take vectorized input, it could be resolved by modifying fun2 (cfitObject) to be able to handle vector input or telling the software that the function in the integral is array valued:
y = integral(fun3, 0, 35, 'ArrayValued', 1);