问题回顾
一段质量均匀分布的电缆线悬挂在两点之间,构成一段悬链,其满足如下微分方程:
问题分析
1.二分法
首先确定有根区间,将区间二等分,通过判断f(x)的符号,逐步将有根区间缩小,直至有根区间足够地小,便可求出满足精度要求的近似根。通过悬链最低点张力的唯一性,可以确定该区间只有一个根。
用 (xl,xr)来表示我们所感兴趣的根,初始为(1000,1500),MATLAB脚本程序如下,保留10位有效数字。
clear;
x_l = 1000; % the initial value of the left bound of x is 1000
x_r = 1500; % the initial value of the right bound of x is 15000
x_m = mean([x_l,x_r]); % x_m is the mean value of the two bounds
x_g = 0; % x_g is the target value of the Bolzano method
e_a = 5e-11;
i = 0;
if f(x_l)*f(x_r)>0
error('invalid input');
else
while (abs(x_g-x_m)/x_m>e_a) % tolerance of accuracy
if f(x_m)==0 % find the accurate root
break;
else
if f(x_l)*f(x_m)<0
x_r = x_m; % update the new estimation to the interval
else
x_l = x_m;
end
end
x_g = x_m;
x_m = mean([x_r,x_l]);
i = i + 1;
end
end
fprintf('x = %.17f i = %d\n', x_m, i);
程序输出为
x = 1266.32436044747009873 i = 32
本例中用了 32 次迭代达到了保留10位有效数字的计算准则。下面用图表示出迭代过程。
2.试位法
与二分法不同,每次区间的划分点不在中点,而是两区间函数值点连线与 x 轴的交点, 递归地做这样的划分求解最终的结果,图示结果附后。
clear;
x_l = 1000; % the initial value of the left bound of x is 1000
x_r = 1500; % the initial value of the right bound of x is1500
x_c = x_r; % x_c is the cross point of the two bound and the x-axis
x_t = 0; % x_t is the target ROOT of the eqation
e_a = 5e-11;
i = 0; % iteration tag
while (abs(x_t-x_c)/x_c>e_a)
x_t=x_c; % update the target value with the cross point
if f(x_t)==0
break;
else
x_c = x_r - f(x_r)*(x_l-x_r)/(f(x_l)-f(x_r));
if f(x_c)*f(x_r)<0
x_l = x_c;
else
x_r = x_c;
end
end
i = i+1;
end
fprintf('x = %.17f i = %d\n', x_c, i);
程序输出为
x = 1266.32436040640868669 i = 16
本例中用了 16 次迭代达到了保留10位有效数字的计算准则。下面用图表示出迭代过程。
根据计算结果可以看到,此例中试位法较二分法更为快速地收敛到了想要的解,且并也已经出现“一个划界点保持不动”的现象。
3.不动点迭代
clear;
x_t = 1000; % the initial is 1000
x_c = 0;
e_a = 5e-11;
for i=1:1000 % iteration tag
x_c = f(x_t) + x_t;
if(abs(x_c-x_t)/x_c<e_a) % tolerance of accuracy
break;
end
x_t = x_c;
end
fprintf('x = %.17f i = %d\n', x_c, i);
程序输出为
x = 1266.32436009672028376 i = 115
本例中用了 115 次迭代达到了小数点后 10 位有效数字的计算准则。下面用图表示出迭代过程。
4.Newton-Raphson法
clear;
x_t = 1000; % the initial is 1000
x_c = 0;
e_a = 5e-11;
for i=1:1000 % iteration tag
x_c = x_t-f(x_t)/df(x_t);
if(abs(x_c-x_t)/x_c<e_a) % tolerance of accuracy
break;
end
x_t = x_c;
end
fprintf('x = %.17f i = %d\n', x_c, i);
程序输出为
x = 1266.32436039988829179 i = 5
5.割线法
clear;
x_t = 1000; % the initial value of the second bound of x is 1000
x_r = 1500; % the initial value of the first bound of x is 1500
x_c = 0;
e_a = 5e-11;
i = 0; % iteration tag
while (abs(x_r-x_t)/x_t>e_a)
x_c=x_t-f(x_t)*(x_t-x_r)/(f(x_t)-f(x_r)); % update the target
if f(x_c)==0
break;
else
x_r = x_t;
x_t = x_c;
end
i = i+1;
end
fprintf('x = %.17f i = %d\n', x_c, i);
程序输出为
x = 1266.32436039988601806 i = 7
小结
本文由实际问题出发,按照题目要求的五种方法分别解了一个非线性的方程,作图比较了五种方法的收敛速度,并用每种方法都得到了最终的结果(有十位有效数字),x = 1266.324360,即悬链最低点的张力为1266.324360。
下面列表总结一下每种方法得到结果的情况:
方法名称 | 初始估计 1 | 初始估计 2 | 迭代次数 |
---|---|---|---|
二分法 | 1000 | 1500 | 32 |
试位法 | 1000 | 1500 | 16 |
不动点迭代 | 1000 | \ | 115 |
Newton-Raphson法 | 1000 | \ | 5 |
割线法 | 1000 | 1500 | 7 |
二分法是最简单的方法,且易于在计算机上实现,对函数的条件要求也很低,只要求在有根区间上连续。缺点就是收敛速度较慢,本次实验进行了32次迭代得到结果,与公比为1/2的等比数列收敛速度相同。因此一般不单独使用,常用来为其他方法提供初值区间。
试位法作为二分法的改进,并不是单一的二分区间,而是利用区间两个端点的线性插值来求一个近似根,因此在大多数情况下优于二分法,收敛速度相对于二分法更快。但在实际计算中,如果区间内一阶导数值突然增长,函数图像有极大拐弯,且方程的根更靠近导数大的一侧,情况将会变得非常糟糕,出现“一个划界点保持不动”的现象,此时收敛速度会慢于二分法。本题中没有出现上述情况,进行了16次迭代后得到了结果。
为了减轻上述情况带来的影响,可以对试位法做出如下改进。如果一个端点重复两次或更多次作为新的含根区间的端点,我们将这个点的函数值乘以一个大于0小于1的常数因子w,比如可以取0.5,将停滞的边界点处的函数值变为原来的一半,能够使线性插值的根更接近于精确根。更加符合“试位”的思想。
不动点迭代法与前两种方法不同,只需要一个初始估计值。这种方法收敛较慢,本次实验迭代了115次才得出了最终结果。对初值的要求较高,需要提供较为近似的初始值x0.大多数情况下需要考虑迭代法的局部收敛性,在方成根的附近取初值。不动点迭代法是迭代法的基础,是一种一般性的方法,对研究方程解的存在性、唯一性和具体计算有重要的理论与实用价值。
Newton-Raphson法是经不动点迭代法变形而来的,是迭代法“收敛性”意义上的最优进化。牛顿法的速度很快,本次实验只用了5次迭代就得到了满足要求的解。它的最大优点是方程在单根附近有较高的收敛速度,且算法逻辑简单。但是由于牛顿法是局部收敛的,对初始估计的要求很高,如果没有估计合适,将会产生很差的结果,甚至无法得出答案。此外,牛顿法的每次迭代除了要计算函数值以外,还需要计算导数值,在导数较为复杂时,该方法会比较麻烦。
割线法是牛顿法和试位法的改进。类似于牛顿法,都是用差商估计斜率,但使用了两点的割线,避开了复杂的导数运算。采用两点投射到x轴上得到新的估计值的方法与试位法较为相似,但是初始估计不用界定根。收敛速度在中等到快,本次实验经过7次迭代后得到了结果。
对初始估计的要求很高,如果没有估计合适,将会产生很差的结果,甚至无法得出答案。此外,牛顿法的每次迭代除了要计算函数值以外,还需要计算导数值,在导数较为复杂时,该方法会比较麻烦。
割线法是牛顿法和试位法的改进。类似于牛顿法,都是用差商估计斜率,但使用了两点的割线,避开了复杂的导数运算。采用两点投射到x轴上得到新的估计值的方法与试位法较为相似,但是初始估计不用界定根。收敛速度在中等到快,本次实验经过7次迭代后得到了结果。
总而言之,不同的求解方法各有千秋,我们需要结合实际问题来选择恰当的方法。