2013-05-29 11 views

回答

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次額外的功能評估。

+0

@RobertP:沒有,我知道的...這是有些奇怪,因爲[切比雪夫多項式(http://en.wikipedia.org/wiki/Chebyshev_polynomials)是最好的選擇用於多項式逼近。事實上,至少對於你正在處理的功能類型(平滑,連續等)而言,準確度可能會相當高。唯一的缺點是可能很難選擇'n'的'好'值(這是內置繪圖功能派上用場的地方)。 –

+1

+1用於提示Chebychev多項式,我發現它們在許多計算方面非常有用。 – bla

2

首先出現的是Matlab的內置在使用的符號數學工具箱選項:mathworks.com/help/symbolic/mupad_ref/numeric-realroots.html

另一種選擇,如果你的函數很乖,只是養活fsolve用正確的猜測,所以儘管它使用的是循環,這是一個有效的計算。例如:

A=linspace(-5,5,1000); 
[email protected](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 
+0

謝謝@natan!我不知道'numeric :: realroots'。第二個解決方案也很好! =) –

相關問題