如題,Newton迭代為常見(jiàn)的非線性方程的解法,迭代形式為x1 = x-(newton(x)./diff(newton(x))),即第k個(gè)x減去f/f'
算法的實(shí)現(xiàn)較為容易,但實(shí)際編寫(xiě)代碼時(shí)出現(xiàn)了一個(gè)小問(wèn)題:對(duì)表達(dá)式求導(dǎo)后代入初始值
提前寫(xiě)出原表達(dá)式與其求導(dǎo)形式再進(jìn)行替換固然可行,但有些麻煩,不方便更改
一開(kāi)始選用subs來(lái)整體替換,但之后發(fā)現(xiàn)這樣會(huì)使得計(jì)算量變得極其龐大。

問(wèn)題出在sym表達(dá)式代入數(shù)值后得到的解是精確解,或者說(shuō)一組符號(hào)。在進(jìn)行運(yùn)算時(shí)它們才會(huì)自動(dòng)轉(zhuǎn)換為數(shù)值。但我們其實(shí)并不需要如此精確的分?jǐn)?shù)形式的解。于是決定提前算出導(dǎo)數(shù)在初始解下的值并使用roundn保留9位小數(shù),但這樣又會(huì)出現(xiàn)報(bào)錯(cuò)

于是搜索發(fā)現(xiàn)vpa能完美解決該問(wèn)題,附上大佬的帖子
https://blog.csdn.net/Davidietop/article/details/105364792
又在函數(shù)體中嘗試了許久,終于得到了解決,留下了感動(dòng)的淚水。順帶一提,與C++不同,matlab中變量的值好像不能反復(fù)改動(dòng),比如使用y=vpa(y,9)時(shí)結(jié)果較之前沒(méi)有絲毫改變,必須在第一次計(jì)算y時(shí)就使用vpa。

附上代碼
function f = equation(x)
f = x.^3-x-1;%這里題目要求的是這個(gè)方程,也可改為自行輸入
end
function y = newton(x)
syms a;
f1 = diff(equation(a));%存放導(dǎo)數(shù)形式
b=vpa(subs(f1,a,x),9);%代入x算出數(shù)值,保留9位有效數(shù)字
y=vpa(x-equation(x)./b,9);
end
x=input('x=');%輸入初值
eps=input('eps=');%誤差限
inff=input('解的容許下界為:');
supp=input('解的容許上界為:');
x1=1;%判斷是否到達(dá)所需精度
count = 0;
while (x1>eps)
? ? xb=x;
? ? x=newton(xb);
? ? x1=vpa(abs(x-xb),9);
? ? count=count+1;
end
if(x>supp||x<inff)
? disp('在給定區(qū)間內(nèi)找不到合適的解');
else
disp('符合精度的解為: ');
fprintf('%.6f',x)
disp('迭代次數(shù)為:');
disp(count);
end