问题
I use matlab for symbolic calculations. After long calculations I've got a function of x, which is the combination of bessel functions and I want to find it's zeros.
For that purpose I use fzero
function in Matlab. But while it works perfectly for single bessel functions, it wont work for the mine one.
>> fzero(@(x)besselj(0,x), 3.5)
ans =
2.4048
>> fzero(@(x)DELTA_xi, 3.5) ??? Undefined function or method 'isfinite' for input arguments of type 'sym'.
Error in ==> fzero at 333 elseif ~isfinite(fx) || ~isreal(fx)
>> DELTA_xi besseli(1, (3*x)/10)*besselj(1, (3*x)/10)*besselk(1, x)*bessely(0, x) - besseli(1, (3*x)/10)*besselj(1, (3*x)/10)*besselk(0, x)*bessely(1, x) - besseli(1, (3*x)/10)*bessely(1, (3*x)/10)*besselj(0, x)*besselk(1, x) + besseli(1, (3*x)/10)*bessely(1, (3*x)/10)*besselj(1, x)*besselk(0, x) - besselj(1, (3*x)/10)*besselk(1, (3*x)/10)*besseli(0, x)*bessely(1, x) - besselj(1, (3*x)/10)*besselk(1, (3*x)/10)*besseli(1, x)*bessely(0, x) + besselk(1, (3*x)/10)*bessely(1, (3*x)/10)*besseli(0, x)*besselj(1, x) + besselk(1, (3*x)/10)*bessely(1, (3*x)/10)*besseli(1, x)*besselj(0, x)
Why this happens? How to solve the issue?
Thanks in advance
回答1:
I think you've mistaken function handles with symbolic representation.
fzero needs a function handle.
so if you do:
DELTA_xi = @(x) besseli(1, (3*x)/10)*besselj(1, (3*x)/10)*besselk(1, x)*bessely(0, x) - besseli(1, (3*x)/10)*besselj(1, (3*x)/10)*besselk(0, x)*bessely(1, x) - besseli(1, (3*x)/10)*bessely(1, (3*x)/10)*besselj(0, x)*besselk(1, x) + besseli(1, (3*x)/10)*bessely(1, (3*x)/10)*besselj(1, x)*besselk(0, x) - besselj(1, (3*x)/10)*besselk(1, (3*x)/10)*besseli(0, x)*bessely(1, x) - besselj(1, (3*x)/10)*besselk(1, (3*x)/10)*besseli(1, x)*bessely(0, x) + besselk(1, (3*x)/10)*bessely(1, (3*x)/10)*besseli(0, x)*besselj(1, x) + besselk(1, (3*x)/10)*bessely(1, (3*x)/10)*besseli(1, x)*besselj(0, x)
fzero(DELTA_xi, 3.5)
you get
3.8173
note that if you want to call a symbolic function, you'll have to do it indirectly:
fzero(@(x)eval(DELTA_xi), 3.5)
回答2:
Rasman already gave you one solution to your problem, but I thought I'd explain in more detail why you were getting your error and give you another possible solution.
First, consider this anonymous function from your code:
fcn1 = @(x) besselj(0,x);
This function takes one input argument x
and passes it to the function BESSELJ to be evaluated and returned as output. FZERO has no problem using this function.
Now consider this other anonymous function from your code, which has as its expression the symbolic equation DELTA_xi
created using the symbolic variable 'x'
:
fcn2 = @(x) DELTA_xi;
This function takes an input argument x
, but what should be done with this input argument? MATLAB doesn't automatically know to connect the input variable x
to the symbolic variable 'x'
in DELTA_xi
, so when this function gets evaluated by FZERO it will simply return the symbolic equation DELTA_xi
(which FZERO is unable to use, as indicated by the error you see).
Using the function EVAL like in Rasman's solution will evaluate DELTA_xi
using the available value for x
passed from FZERO to the anonymous function, solving your problem. However, another solution is to use the SUBS function like so:
fzero(@(x) subs(DELTA_xi,'x',x), 3.5)
Which will substitute the input value x
for every occurrence of the symbolic variable 'x'
in DELTA_xi
, essentially doing the same thing as EVAL but explicitly stating which symbolic variable the input argument replaces. The difference? Note that this will work:
fzero(@(y) subs(DELTA_xi,'x',y), 3.5)
But this will not:
fzero(@(y) eval(DELTA_xi), 3.5)
Because the name of the input variable and the symbolic variable don't match.
来源:https://stackoverflow.com/questions/6074062/using-fzero-undefined-function-or-method-isfinite-for-input-arguments-of-type