假设我有一个函数f = @(x) myfun(x)
;
我可以使用fzero
来获得最接近给定x0
的解决方案,但我是否可以获取特定区域中的所有解决方案,例如:-5 < x < 5
?
即。
是否有可能得到类似于roots
的结果的解,但对于非多项式?
答案 0 :(得分:6)
是的,你可以。
有一个很好的submission on the file exchange可以让你做到这一点。它的工作原理是通过Chebychev多项式逼近曲线,然后找到该多项式的所有实根。
如果您愿意,可以将根的这些估计值用作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
例如,每万次改进只有8份,不少于46次额外的功能评估。
答案 1 :(得分:2)
首先是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