假设我有一个函数f = @(x) myfun(x)
;
我可以fzero
用来获得最接近给定的解决方案x0
,但我可以在特定区域获得所有解决方案,例如:-5 < x < 5
?
即是否有可能得到一个类似于 的结果roots
但对于非多项式的解?
是的你可以。
文件交换上有一个很好的提交,可以让你做到这一点。它的工作原理是用切比雪夫多项式逼近你的曲线,然后找到该多项式的所有实根。
如果您愿意,可以将这些对根的估计用作 的初始值fzero
,但通常(至少对于平滑和其他表现良好的曲线)已经可以通过使用更高阶的 Chebychev 近似来满足精度要求。
对于您的示例,仅使用 18 个函数评估(我对文件进行了稍微修改的版本,但本质是相同的):
>> f = @(A) 17.7*sin(A).*cos(A)+87*sin(A).^2-9.65*cos(A)-47*sin(A);
>> R = FindRealRoots(f, -5,5, 17)
R =
-3.709993256346244
-3.345207732130925
-0.201929737187637
0.572382702285053
2.573423209113534
2.937157987217741
>> R2 = R;
>> funcCount = 0;
>> for ii = 1:numel(R)
[R2(ii), ~,~, output] = fzero(f,R2(ii));
funcCount = funcCount + output.funcCount;
end
>> max(abs(R2(:)-R(:)))
ans =
8.564253235401331e-004
>> funcCount
ans =
46
例如,对于不少于 46 项附加功能评估,只有万分之八的改进。
首先是使用符号数学工具箱的 Matlab 内置选项: mathworks.com/help/symbolic/mupad_ref/numeric-realroots.html
如果您的函数表现良好,另一种选择就是fsolve
提供正确的猜测,因此即使它使用循环,它也是一种有效的计算。例如:
A=linspace(-5,5,1000);
f=@(A) 17.7.*sin(A).*cos(A)+87.*sin(A).^2-9.65*cos(A)-47*sin(A)
idx = find(diff(sign(f(A))));
for n=1:numel(idx)
r(n)=fzero(f,A(idx(n)))
end
r=
-3.709541990613713
-3.345170894638306
-0.202018624930518
0.572128202319968
2.573643316565874
2.938014412541281