非线性方程组求解的常用方法
二分逼近法
对于实数域的函数
f
(
x
)
f(x)
f(x),如果存在实数
k
k
k,使得
f
(
x
)
=
0
f(x)=0
f(x)=0,则
x
=
k
x=k
x=k,就是函数
f
(
x
)
f(x)
f(x)的零点。
如果函数
f
(
x
)
f(x)
f(x)是连续函数,且在区间
[
a
,
b
]
[a,b]
[a,b]上是单调函数,只要
f
(
a
)
f(a)
f(a)和
f
(
b
)
f(b)
f(b)异号,就说明在区间
[
a
,
b
]
[a,b]
[a,b]内一定有零点,此时就可以使用二分逼近法近似的找到这个零点。
假如
f
(
a
)
<
0
,
f
(
b
)
>
0
f(a)<0,f(b)>0
f(a)<0,f(b)>0:
1.如果
f
(
(
a
+
b
)
/
2
)
=
0
f((a+b)/2)=0
f((a+b)/2)=0,则
(
a
+
b
)
/
2
(a+b)/2
(a+b)/2就是零点;
2.如果
f
(
(
a
+
b
)
/
2
)
<
0
f((a+b)/2)<0
f((a+b)/2)<0,则零点在区间
[
(
a
+
b
)
/
2
,
b
]
[(a+b)/2,b]
[(a+b)/2,b]上,令
a
=
(
a
+
b
)
/
2
a=(a+b)/2
a=(a+b)/2,继续从第1步开始判断;
3.如果
f
(
(
a
+
b
)
/
2
)
>
0
f((a+b)/2)>0
f((a+b)/2)>0,则零点在区间
[
a
,
(
a
+
b
)
/
2
]
[a,(a+b)/2]
[a,(a+b)/2]上,令
b
=
(
a
+
b
)
/
2
b=(a+b)/2
b=(a+b)/2,继续从第1步开始判断。
局限性不能计算复根和重根。
def func(x):
f = 2*(x**2) + 3.2*x - 1.8
return f
def null_point(a, b):
mid = (a+b)/2
while (b-a) > 0.000000001:
if func(a) * func(mid) < 0:
b = mid
else:
a = mid
mid = (a+b)/2
return mid
print(null_point(-0.8, 8))
0.44096736444625995
牛顿迭代法的数学原理
首先选择一个接近函数
f
(
x
)
f(x)
f(x)零点的
x
0
x_{0}
x0作为迭代初始值,计算相应的
f
(
x
0
)
f(x_{0})
f(x0)和切线斜率
f
′
(
x
0
)
f'(x_{0})
f′(x0)(这里
f
′
(
x
)
f'(x)
f′(x)是函数
f
(
x
)
f(x)
f(x)的一阶导函数);
然后经过点
(
x
0
,
f
(
x
0
)
)
(x_{0},f(x_{0}))
(x0,f(x0))做一条斜率为
f
′
(
x
0
)
f'(x_{0})
f′(x0)的直线,该直线与
x
x
x轴有一个交点,由方程:
f
(
x
0
)
=
(
x
0
−
x
)
f
′
(
x
0
)
f(x_{0})=(x_{0}-x)f'(x_{0})
f(x0)=(x0−x)f′(x0)
求解这个方程,可以得到:
x
1
=
x
0
−
f
(
x
0
)
/
f
′
(
x
0
)
x_{1}=x_{0}-f(x_{0})/f'(x_{0})
x1=x0−f(x0)/f′(x0)
利用
x
1
x_{1}
x1开始下一轮迭代,迭代公式:
x
n
+
1
=
x
n
−
f
(
x
n
)
/
f
′
(
x
n
)
x_{n+1}=x_{n}-f(x_{n})/f'(x_{n})
xn+1=xn−f(xn)/f′(xn)
用牛顿迭代法求解非线性方程的实例
导函数的求解与近似公式
一阶导函数的近似表达
f
′
(
x
0
)
=
f
(
x
0
+
0.000005
)
−
f
(
x
0
−
0.000005
)
0.00001
f'(x_{0})=\frac{f(x_{0}+0.000005)-f(x_{0}-0.000005)}{0.00001}
f′(x0)=0.00001f(x0+0.000005)−f(x0−0.000005)
算法实现
def func(x):
f = 2*(x**2) + 3.2*x - 1.8
return f
def derivative(x):
return (func(x+0.000005)-func(x-0.000005))/0.00001
def Newton_iteration(x0):
x1 = x0 - func(x0) / derivative(x0)
while abs(x0-x1) > 0.00000001:
x0 = x1
x1 = x0 - func(x0) / derivative(x0)
return x1
print(Newton_iteration(8))
print(Newton_iteration(-8))
0.44096736459908564
-2.040967364599086