7

假设我有一个函数f = @(x) myfun(x)

我可以fzero用来获得最接近给定的解决方案x0,但我可以在特定区域获得所有解决方案,例如:-5 < x < 5

即是否有可能得到一个类似于 的结果roots但对于非多项式的解?

4

2 回答 2

6

是的你可以。

文件交换上有一个很好的提交,可以让你做到这一点。它的工作原理是用切比雪夫多项式逼近你的曲线,然后找到该多项式的所有实根。

如果您愿意,可以将这些对根的估计用作 的初始值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 项附加功能评估,只有万分之八的改进。

于 2013-05-29T09:15:44.957 回答
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
于 2013-05-29T09:55:36.067 回答