Chapt2 非线性方程求根 ¶
概览 ¶
- 求解代数方程和超越方程的实数根
- 根的分离 ( 预先给出根的一个粗略位置 )
- 近似根的精确化 ( 向真实根逼近 )
- 求解多项式的所有实数根和复数根
收敛阶 ¶
划界法 ¶
二分法 ¶
取左右端点中点
%二分法
function [c,err,yc]=bisect(f,a,b,delta)
ya=feval(f,a);
yb=feval(f,b);
if ya*yb>0
disp('Note: f(a)*f(b)>0')
return
end
max_times=1+round((log(b-a)-log(delta))/log(2));
for k=1:max_times
c=(a+b)/2;
yc=feval(f,c);
if yc==0
a=c;
b=c;
elseif yb*yc>0
b=c;
yb=yc;
else
a=c;
ya=yc;
end
if b-a<delta
break
end
end
c=(a+b)/2;
err=abs(b-a)/2;
yc=feval(f,c);

试位法 ¶
取左右端点连成直线与 X 轴的交点
%试位法
function [c,err,yc]=regula(f,a,b,delta,epsilon,max1)
ya=feval(f,a);
yb=feval(f,b);
if ya*yb>0
disp('Note: f(a)*f(b)>0')
return
end
for k=1:max1
dx=yb*(b-a)/(yb-ya); %dx为c,b之间的距离
c=b-dx;
ac=c-a; %ac为a,c之间的距离
yc=feval(f,c);
if yc==0
break
elseif yb*yc>0
b=c;
yb=yc;
else
a=c;
ya=yc;
end
dx=min(abs(dx),ac);
if abs(dx)<delta
break
end
if abs(yc)<epsilon
break
end
c=b-yb*(b-a)/(yb-ya);
err=abs(b-a);
yc=feval(f,c);
end


开方法 ¶
不动点迭代 ¶
取接近满足 f(x)=x 不动点的点
%不动点迭代
function [k,p,err,P]=fixpt(g,p0,delta,max1)
P(1)=p0;
for k=2:max1
P(k)=feval(g,P(k-1));
err=abs(P(k)-P(k-1));
relerr=err/(abs(P(k))+eps);
p=P(k);
if (err<delta) || (relerr<delta)
break
end
if k==max1
disp('maximum number of iteration exceeded')
end
end
Newton-Raphson 方法 ¶
取某点切线与 x 轴的交点 ( 等价于 g(x)=x-f(x)/f'(x) 不动点 )
%Newton-Raphson方法
function [p0,err,k,y]=newton(f,df,p0,delta,epsilon,max_times)
for k=1:max_times
p1=p0-feval(f,p0)/feval(df,p0);
err=abs(p1-p0);
relerr=2*err/(abs(p1)+delta);
p0=p1;
y=feval(f,p0);
if (err<delta) || (relerr<delta) || (abs(y)<epsilon)
break
end
end



割线法 ¶
取同侧端点连成直线与 x 轴交点
%割线法
function [p1,err,k,y]=secant(f,p0,p1,delta,epsilon,max_times)
for k=1:max_times
p2=p1-feval(f,p1)*(p1-p0)/(feval(f,p1)-feval(f,p0));
err=abs(p2-p1)
relerr=2*err/(abs(p2)+delta);
p0=p1;
p1=p2;
y=feval(f,p1);
if (err<delta || (relerr<delta) || abs(y)<epsilon)
break
end
end
if k==max_times
disp('maximum number of iteration exceeded')
end
针对重根的改进 ¶
总结 ¶
评论区
如果有什么问题或想法,欢迎大家在下方留言~