我使用matlab进行符号计算。经过长时间的计算,我得到了x的函数,它是贝塞尔函数的组合,我想找到它是零。
为此,我在 Matlab 中使用fzero
函数。但是,虽然它非常适合单个贝塞尔函数,但它不适用于矿山函数。 >> 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)
为什么会这样?如何解决问题?
提前致谢
我认为您误会将函数句柄与符号表示
。fzero 需要一个函数句柄。
因此,如果您这样做:
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)
你得到
3.8173
请注意,如果要调用符号函数,则必须间接执行此操作:
fzero(@(x)eval(DELTA_xi), 3.5)
Rasman 已经为你的问题提供了一个解决方案,但我想我会更详细地解释为什么你会出错,并给你另一个可能的解决方案。
首先,考虑代码中的这个匿名函数:
fcn1 = @(x) besselj(0,x);
此函数x
获取一个输入参数,并将其传递给函数 BESSELJ 进行计算并作为输出返回。FZERO 使用此功能没有问题。
现在考虑代码中的另一个匿名函数,它的表达式是使用符号变量DELTA_xi
创建的符号方程'x'
:
fcn2 = @(x) DELTA_xi;
这个函数x
接受一个输入参数,但是这个输入参数应该怎么做呢?MATLAB 不会自动知道将输入变量x
连接到 DELTA_xi
中的符号变量'x'
,因此当这个函数被 FZERO 计算时,它将简单地返回符号方程DELTA_xi
(FZERO 无法使用,如您看到的错误所示)。
像在 Rasman 的解决方案中使用函数 EVAL 一样,将使用从 FZERO 传递到匿名函数的x
可用值来评估DELTA_xi
,从而解决您的问题。但是,另一种解决方案是使用 SUBS 函数,如下所示:
fzero(@(x) subs(DELTA_xi,'x',x), 3.5)
这将替换x
的输入值来替换DELTA_xi
中出现的符号变量'x'
,本质上与EVAL做同样的事情,但明确说明输入参数替换了哪个符号变量。区别?请注意,这将起作用:
fzero(@(y) subs(DELTA_xi,'x',y), 3.5)
但这不会:
fzero(@(y) eval(DELTA_xi), 3.5)
因为输入变量和符号变量的名称不匹配。