假設我有一個函數f = @(x) myfun(x)
;是否可以在Matlab中獲得任意方程的幾個解?
我可以使用fzero
來得到最接近給定x0
的解決方案,但我可以在特定區域獲得所有解決方案,例如:-5 < x < 5
?
I.e. 是否有可能得到類似於roots
的結果的解決方案,但對於非多項式?
假設我有一個函數f = @(x) myfun(x)
;是否可以在Matlab中獲得任意方程的幾個解?
我可以使用fzero
來得到最接近給定x0
的解決方案,但我可以在特定區域獲得所有解決方案,例如:-5 < x < 5
?
I.e. 是否有可能得到類似於roots
的結果的解決方案,但對於非多項式?
是的,你可以。
有一個不錯的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次額外的功能評估。
首先出現的是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
謝謝@natan!我不知道'numeric :: realroots'。第二個解決方案也很好! =) –
@RobertP:沒有,我知道的...這是有些奇怪,因爲[切比雪夫多項式(http://en.wikipedia.org/wiki/Chebyshev_polynomials)是最好的選擇用於多項式逼近。事實上,至少對於你正在處理的功能類型(平滑,連續等)而言,準確度可能會相當高。唯一的缺點是可能很難選擇'n'的'好'值(這是內置繪圖功能派上用場的地方)。 –
+1用於提示Chebychev多項式,我發現它們在許多計算方面非常有用。 – bla