说起牛顿下山法,首先要提牛顿法,牛顿法是求解非线性方程的一个重要方法,具体可以点击牛顿法;虽然牛顿法作为一个二阶的迭代收敛方法,但是其对于函数和初始点的要求都比较高,而牛顿下山法则是有效降低这些要求的一种技巧。
牛顿下山法的迭代公式如下
x
k
+
1
(
λ
)
=
x
k
−
λ
f
(
x
k
)
f
(
x
k
)
′
x_{k+1}(\lambda)=x_k-\lambda\frac{f(x_k)}{f(x_k)^\prime}
xk+1(λ)=xk−λf(xk)′f(xk)
其中
λ
=
m
a
x
(
2
−
t
:
∣
f
(
x
k
+
1
(
2
−
t
)
)
∣
<
∣
f
(
x
k
)
∣
,
t
=
0
,
1
,
2
,
.
.
.
)
\lambda=max(2^{-t}:\left|f(x_{k+1}(2^{-t}))\right|<\left|f(x_k)\right|,t=0,1,2,...)
λ=max(2−t:∣f(xk+1(2−t))∣<∣f(xk)∣,t=0,1,2,...)
即每步会修正牛顿迭代法中间的步长,使得每次迭代都保证距离真解更近。
matlab 代码如下
function y=f(fun,num)
x=num;
y=eval(fun); %先定义一个函数,可以表达所有的数学函数,fun为字符串,表示函数
function [x,k]=newton(x0,fun1,fun2,error) %fun1是原函数,fun2是导函数,error是收敛误差,x0是迭代初始点
x=x0;
y=f(fun1,x);
k=1; %标记迭代了多少次
while abs(y)>error
d=1;
x2=x-d*y/f(fun2,x);
while abs(f(fun1,x2))>abs(f(fun1,x))
d=d/2;
x2=x-d*y/f(fun2,x);
end
x=x2;
y=f(fun1,x);
k=k+1;
end
例如解如下方程
y
=
s
i
n
10
x
+
2
c
o
s
x
−
x
−
3
=
0
y=sin10x+2cosx-x-3=0
y=sin10x+2cosx−x−3=0
可知在[-3,0]有解,调用函数如下
[x,y]=newton(-1,'sin(10*x)+2*cos(x)-x-3','10*cos(10*x)-2*sin(x)-1',1e-4)
x =
-1.0773
y =
6
可见,迭代了6次,就收敛到1e-4以下了 ,但是该方程不止一个解,与初始点的选取有关