- 左迁
-
clear,clc
%% 求ln(x+sinx)=0的根。初值x0分别取0.1, 1,1.5, 2, 4进行计算
eq1 = @(x) log(x+sin(x));
x10 = [.1,1.5,2,4];
[x1,val1,flag1] = arrayfun(@(i)newton(eq1,x10(i)),1:length(x10));%未加速
[x1s,val1s,flag1s] = arrayfun(@(i)newton(eq1,x10(i),1),1:length(x10));%加速
%% 求sinx=0的根。初值x0分别取1,1.4,1.6, 1.8,3进行计算
eq2 = @(x) sin(x);
x20 = [1,1.4,1.6,1.8,3];
[x2,val2,flag2] = arrayfun(@(i)newton(eq2,x20(i)),1:length(x20));%未加速
[x2s,val2s,flag2s] = arrayfun(@(i)newton(eq2,x20(i),1),1:length(x20));%加速
以上程序要用到的newton函数如下,已经帮你集成了Steffensen加速法,具体用法函数里边写得很清楚,自己复制粘贴到m文件保存,m文件命名为newton.m,放在同一路径下方可使用
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [x,val,exitflag] = newton(eq,x0,steff,tol,mindx,maxiter)
%牛顿法解方程
%[x,val,exitflag] = newton(eq,x0,steff,tol,mindx,maxiter)
%x为方程的解;
%val为上述x带入eq的值;
%exitflag为1,求解成功;exitflag为0,达到最大迭代次数未收敛;
%exitflag为-1,步长达到最小未收敛;
%eq:函数句柄;
%x0:初值,默认为0到1随机;
%steff为加速参数,非负则加速。默认不加速;
%tol:容差,默认1e-10;
%mindx:最小迭代步长,默认1e-8;
%maxiter:最大迭代数目,默认1e4;
%例如 x = newton(@(x)log(x+sin(x)),1) 得到 x = 0.5110;
%14-Nov-2011 11:39:48,by JJBNJZ
if ~isa(eq,"function_handle")
error("我擦,要我说几遍你才知道要用函数句柄啊")
end
if nargin < 6
maxiter = 1e4;
if nargin < 5
mindx= 1e-8;
if nargin < 4
tol= 1e-10;
if nargin < 3
steff = -1;
if nargin < 2
warning("初值都没给,那从0到1之间随便选了啊")
x0 = rand;
end
end
end
end
end
x = x0;
val = eq(x0);
exitflag = 1;
eval(["df =@(x)" char(diff(eq(sym("x")))),";"]);
if abs(val) <= tol
disp("你给的初值就是解,还算个毛啊,再见")
return
end
if steff <= 0
for iter = 1 : maxiter
val = eq(x);
dval = df(x);
xnew = x - val/dval;
val = eq(xnew);
if abs(val) < tol
x = xnew;
return
end
if abs(x-xnew) < mindx
exitflag = -1;
disp(["迭代步长已经小于设定的最小步长(默认1e-8),",...
"而表达式的值没有小于给定容差(默认1e-10)"])
x = xnew;
return
end
x = xnew;
end
else
st=@(x)x - eq(x)/df(x);
for iter = 1 : maxiter
xnew = x - (st(x)-x)^2 / (st(st(x)) -2*st(x) + x);
val = eq(xnew);
if abs(val) < tol
x = xnew;
return
end
if abs(x-xnew) < mindx
exitflag = -1;
disp(["迭代步长已经小于设定的最小步长(默认1e-8),",...
"而表达式的值没有小于给定容差(默认1e-10)"])
x = xnew;
return
end
x = xnew;
end
end
disp("因达到最大迭代次数而终止,求解失败;解决方法,要么增大容差(精度下降),要么增大迭代次数(变慢)")
exitflag = 0;
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
问题分析什么的就自己写吧,无非是些:“解方程,初值是关键”,“自从我用了Steffensen的加速方法后,嘿,还别说,还真对得起咱这张脸,从前不收脸的也收脸了,收脸的速度的也快了”,“牛顿法求解方程得到的解和初值间的距离居然和初值的导数值有关,导数值越小的初值解出来离初值越远,怎么回事呢?自己看书吧”,“不管怎么说,steffensen还是收敛的比较好的,相比没有他,我们离初值更近了╮(╯_╰)╭”
- 瑞瑞爱吃桃
-
同学,你交大的吧,自己学一下matlab。
- 北有云溪
-
function x_star=newton(fname,dfname,x0,e,n)
if nargin<5
n=50;
end
if nargin<4
e=10^(-5);
end
digits(50);
x=x0;
x0=x+2*e;
k=0;
while abs(x0-x)>e
k=k+1;
if k>n
error("迭代失败");
return;
end
x0=x;
x=x0-feval(fname,x0)/feval(dfname,x0);
disp(x);
end
x_star=x;
disp(k);
end
- 大鱼炖火锅
-
兄弟你是选的赵海良的课呀?