Why do these errors appear? quad2d, dblquad - matlab

I have a huge function to integrate:
syms x y
f=(228155022448185.*(cos((2.*pi).*y)./exp(131738205584307./(35184372088832*x)) - 1)*(cos((8.*pi).*y)/exp(131738205584307./(8796093022208*x)) - 1)*(cos((8.*pi).*y)/exp(131738205584307./(8796093022208.*x)) + cos((18.*pi).*y)/exp(1185643850258763./(35184372088832.*x)) - 2))/((18014398509481984. *(x.^2)).*exp(x. * ((1981232555272083.*(y.^2))/2251799813685248 - y./16 + 1./16)))
I need to integrate it (x:[0,inf) and y:[0,1]), but I receive an error for quad2d and dblquad.
quad2d(quadfun,0,100,0,1)
??? Error using ==> quad2d>tensor at 350
Integrand output size does not match the input size.
Error in ==> quad2d at 164
[Qsub,esub] = tensor(thetaL,thetaR,phiB,phiT);
and
dblquad(quadfun,0,100,0,1)
??? Error using ==> dblquad>innerintegral at 74
Inputs must be floats, namely single or double.
Error in ==> quad at 76
y = f(x, varargin{:});
Error in ==> dblquad at 53
Q = quadf(#innerintegral, ymin, ymax, tol, trace, intfcn, ...
Could you explain why these errors appear? And how can I fix it?

The quad function family doesn't work with symbolic math. Instead, you can either:
Use symbolic integration with int. To compute a double integral, invoke int twice consecutively, each time with a different integration variable.
Define an equivalent regular function that accepts non-symbolic parameters and pass its handle to quad. I'd do it with an anonymous function -- just start your definition with f = #(x, y) instead of f =, and that's it (also remember that f is a function handle now, so you don't need to write the ampersat (#) when passing it around).

Related

Error using integral: A and B must be floating-point scalars

I want to evaluate the simple example of integral
a = max(solve(x^3 - 2*x^2 + x ==0 , x));
fun = #(x) exp(-x.^2).*log(x).^2;
q = integral(fun,0,a)
and the error is
Error using integral (line 85)
A and B must be floating-point scalars.
Any tips? The lower limit of my integral must be a function, not a number.
The Matlab command solve returns symbolic result. integral accepts only numeric input. Use double to convert symbolic to numeric. As your code is written now, already max should throw an error due to symbolic input. The following works.
syms x;
a = max(double(solve(x^3 - 2*x^2 + x)));
fun = #(x) exp(-x.^2).*log(x).^2;
q = integral(fun,0,a)
Output: 1.9331.
the lower limit of my integral must be a function, not a number
integral is a numeric integration routine; the limits of integration must be numeric.
Check values of a by mouse over in breakpoint or removing the ; from the end of the line so it prints a. Based on the error, a is not a scalar float. You might need another max() or double() statement to transform the vector to a single value.
Solve Help : http://www.mathworks.com/help/symbolic/solve.html
Integral Help : http://www.mathworks.com/help/ref/integral.html

Getting points from an anonymous function after integration in MATLAB

I want to get value of v(U,n0) for various points in MATLAB
eq = #(q,U,n0) 2*(1-cos(2*pi*q));
hq = #(q,U,n0) ((eq)^2+2*U*n0*(eq))^(1/2);
y = #(q,U,n0) (((eq)+(U*n0))/hq)-1;
a = -0.5;
b = 0.5;
v = #(U,n0) quad(#(q) y(q,U,n0),a,b);
But I get lots of errors like
>> v(1,2)
Undefined function 'plus' for input arguments of type 'function_handle'.
Error in #(q,U,n0)(((eq)+(U*n0))/hq)-1
Error in #(q)y(q,U,n0)
Error in quad (line 72) y = f(x, varargin{:});
Error in #(U,n0)quad(#(q)y(q,U,n0),a,b)
Can anybody help me out with the errors?
You are using function handles without specifying their arguments. For example, after you define eq(q,U,n0), you use it in hq like a variable (eq) without any inputs. Whenever you use a function, you must give it inputs, so use eq(q,U,n0), not just eq.

matlab not allowed sinc(0)

I try to plot these 2 graphs on the same plot but matlab return error 'can't divide by zero' and refer me to sinc of 0.
I don't know what to do bc sinc(0)=1, I don't understand the problem.
my code:
syms x
ezplot(heaviside(x+1) - heaviside(x-1), [-2, 2])
hold
t=-2:0.1:2;
syms k
r=symsum( ((sinc(k/2)/2)*exp((1i)*k*pi*(t/2))), -1,1);
plot(t,r)
problem:
??? Error: File: aa.m Line: 6 Column: 18
Unexpected MATLAB expression.
Current plot held
??? Error using ==> mupadmex
Error in MuPAD command: Division by zero [_power];
during evaluation of 'sum::sum'
Error in ==> sym.symsum at 74
r = mupadmex('symobj::map',f.s,'symobj::symsum',x.s,a.s,b.s);
Error in ==> aa at 6
r=symsum( ((sinc(k/2)/2)*exp((1i)*k*pi*(t/2))), -1,1);
Use this alternative definition for sinc:
ssinc=#(X)(1./(gamma(1+X).*gamma(1-X)))
syms x
ezplot(heaviside(x+1) - heaviside(x-1), [-2, 2])
hold
t=-2:0.1:2;
syms k
r=symsum( ((ssinc(k/2)/2)*exp((1i)*k*pi*(t/2))), -1,1);
plot(t,r)
This code uses an alternative definition of the sinc function:
(Source: Wikipedia)
Another solution, instead of using an alternative definition with the gamma function, I added a correction to redefine the x=0 point.
The original function has a 0/0 situation, I redefined it using a correction function with correction(0)=1 and correction(1)=0 otherwise. This changes to function to 1/1 at sinc(0).
%correction(0)=1, correction(x)=0 otherwise. A little bit idiotic, but I'm unable to define this in a simpler way which is compartible to the symbolic toolbox:
correction=#(x)(((heaviside(x)-.5).^2)-.25)*-4
%redefine sinc using the original function, but use correction(x) to fix sinc(0)
ssinc=#(x)((sin(pi*x)+correction(x))./((pi*x)+correction(x)))
syms x
ezplot(heaviside(x+1) - heaviside(x-1), [-2, 2])
hold
t=-2:0.1:2;
syms k
r=symsum( ((ssinc(k/2)/2)*exp((1i)*k*pi*(t/2))), -1,1);
plot(t,r)

How to use quadgk function in matlab as a function handle?

I am trying to solve a double integral where I am solving both inner as well as outer integral with quadgk function.
% The integrand is of course a function of both x and y
integrand = #(x,y) (phi(j,y,X) - phi(j,x,X))*(phi(i,y,X) - phi(i,x,X))/abs(y-x)^(2*s+1)
% The inner integral is a function of x, and integrates over y
inner = #(x) quadgk(#(y)integrand(x,y), x-lambda, x+lambda)
% The inner integral is integrated over x to yield the value of the double integral
dblIntegral = quadgk(inner, -(1+lambda), 1+lambda)
and I am getting this following error:
integrand = #(x,y)(phi(j,y,X)-phi(j,x,X))*(phi(i,y,X)-phi(i,x,X))/abs(y-x)^(2*s+1)
inner = #(x)quadgk(#(y)integrand(x,y),x-lambda,x+lambda)
??? Error using ==> quadgk at 108
A and B must be scalar floats.
Error in ==> #(x)quadgk(#(y)integrand(x,y),x-lambda,x+lambda)
Error in ==> quadgk>evalFun at 344
fx = FUN(x);
Error in ==> quadgk>f1 at 362
[y,too_close] = evalFun(tt);
Error in ==> quadgk>vadapt at 258
[fx,too_close] = f(x);
Error in ==> quadgk at 197
[q,errbnd] = vadapt(#f1,interval);
Error in ==> frational_laplacian at 29
dblIntegral = quadgk(inner, -(1+lambda), 1+lambda)
You're getting that problem because internally quadgk evaluates the passed function using a vector of values. This means that in the line
dblIntegral = quadgk(inner, -(1+lambda), 1+lambda)
the function inner is being called with x being a vector. quadgk requires that a and b (in this case x±lambda) be scalars, so you get the error you've been seeing. If you want to ensure that inner always gets a scalar as input, you can use
dblIntegral = quadgk(#(x)arrayfun(inner,x), -(1+lambda), 1+lambda)

Error using fzero in Matlab: Undefined function or method 'det' for input arguments of type 'function_handle'

I have the same kind of problem described in this topic:
Using fzero: Undefined function or method 'isfinite' for input arguments of type 'sym'
Their answers really helped me, but I am still stuck.
I also have to find the zeros of a function of w, this function is defined in several steps:
So the only unknown is w, and I defined other objects such as:
lambda= #(w) ((16*rho(i)*A(i)*w^2*Lprime(i)^2)/(E(j)*I(i)))^0.25;
beta=#(w) lambda*b(i)^0.5;
gamma=#(w) lambda*Lprime(i)^0.5;
Then, I define a 4*4 matrix M2:
M2=#(w) [besselj(4,beta) bessely(4,beta) besseli(4,beta) besselk(4,beta);
besselj(3,beta) bessely(3,beta) besseli(3,beta) -besselk(3,beta);
besselj(2,gamma) bessely(2,gamma) besseli(2,gamma) besselk(2,gamma);
besselj(4,gamma) bessely(4,gamma) besseli(4,gamma) besselk(4,gamma)];
Then the equation to be solved is: det(M2)=0. But w=0 is one of the solutions, and I want the first non-zero solution, so I wrote:
delta = #(w) det(M2);
S(i,j)=fzero(delta,500);
Then I run the program, and Matlab says:
??? Error using ==> fzero at 235
FZERO cannot continue because user supplied function_handle ==> #(w)det(M2)
failed with the error below.
Undefined function or method 'det' for input arguments of type 'function_handle'.
Error in ==> frequencies at 57
S(i,j)=fzero(delta,500);
I also tried with the subs and the eval methods, and they don't work either, the error messages are in those cases:
??? Undefined function or method 'isfinite' for input arguments of type 'sym'.
Error in ==> fzero at 323
elseif ~isfinite(fx) || ~isreal(fx)
Error in ==> frequencies at 58
S(i,j)=fzero(#(w) subs(delta,'w',w),500);
Which is the same error as edio's I guess. And:
??? Error using ==> fzero at 307
FZERO cannot continue because user supplied function_handle ==> #(w)eval(delta)
failed with the error below.
Undefined function or method 'eval' for input arguments of type 'function_handle'.
Error in ==> frequencies at 59
S(i,j)=fzero(#(w)eval(delta),500);
Can you help me please?
Your problem appears to be that you are never evaluating your anonymous functions when you place them within other anonymous functions. For example, you define the function lambda as such:
lambda = #(w) ((16*rho(i)*A(i)*w^2*Lprime(i)^2)/(E(j)*I(i)))^0.25;
But when you use it in beta, you need to evaluate it using the input value for w, like so:
beta = #(w) lambda(w)*b(i)^0.5;
%# ^--------------Pass w to lambda to evaluate the function
As such, I believe your other anonymous functions should be defined as follows:
gamma = #(w) lambda(w)*Lprime(i)^0.5;
M2 = #(w) [besselj(4,beta(w)) bessely(4,beta(w)) besseli(4,beta(w)) ...
besselk(4,beta(w)); ...
besselj(3,beta(w)) bessely(3,beta(w)) besseli(3,beta(w)) ...
-besselk(3,beta(w)); ...
besselj(2,gamma(w)) bessely(2,gamma(w)) besseli(2,gamma(w)) ...
besselk(2,gamma(w)); ...
besselj(4,gamma(w)) bessely(4,gamma(w)) besseli(4,gamma(w)) ...
besselk(4,gamma(w))];
delta = #(w) det(M2(w));
A note about efficiency...
There is a GLARING efficiency problem I'm noticing here. By using anonymous functions instead of any other type of function (primary functions, nested functions, or subfunctions) you are going to end up evaluating the same function with the same input multiple times over.
For example, each time you evaluate M2 to create your matrix you will be evaluating both beta and gamma 8 times with the same input! Notice the improvement you could make by placing M2 in a function and passing as input w and the two function handles beta and gamma:
function newMatrix = M2(w,betaFcn,gammaFcn)
bw = betaFcn(w); %# Evaluate the beta function once
gw = gammaFcn(w); %# Evaluate the gamma function once
newMatrix = [besselj(4,bw) bessely(4,bw) besseli(4,bw) besselk(4,bw); ...
besselj(3,bw) bessely(3,bw) besseli(3,bw) -besselk(3,bw); ...
besselj(2,gw) bessely(2,gw) besseli(2,gw) besselk(2,gw); ...
besselj(4,gw) bessely(4,gw) besseli(4,gw) besselk(4,gw)];
end
And your new delta function would look like this:
delta = #(w) det(M2(w,beta,gamma));
Hi thank you very much for your help.
It works, but the last line has to change, obviously (it still took me 10 minuts for figure it out):
lambda= #(w) ((16*rho(i)*A(i)*w^2*Lprime(i)^2)/(E(j)*I(i)))^0.25;
beta=#(w) lambda(w)*b(i)^0.5;
gamma=#(w) lambda(w)*Lprime(i)^0.5;
M2=#(w) [besselj(4,beta(w)) bessely(4,beta(w)) besseli(4,beta(w)) besselk(4,beta(w));
besselj(3,beta(w)) bessely(3,beta(w)) besseli(3,beta(w)) -besselk(3,beta(w));
besselj(2,gamma(w)) bessely(2,gamma(w)) besseli(2,gamma(w)) besselk(2,gamma(w));
besselj(4,gamma(w)) bessely(4,gamma(w)) besseli(4,gamma(w)) besselk(4,gamma(w))];
delta = #(w) det(M2(w));
S(i,j)=fzero(#(w) delta(w),500);
And now it is really faster than before, in another case where the function solve could handle the resolution, it took like 10 seconds for each loop, now it's like 0.06 seconds
I will try your other solution to see the improvements.
Thank you a lot.