赞
踩
考虑以下形式的非线性方程:
f ( x ) = 0 \boldsymbol{f}\left( \boldsymbol{x} \right) =0 f(x)=0
其中 f : R → R \boldsymbol{f}:\mathbb{R}\rightarrow \mathbb{R} f:R→R是非线性函数。 问题是找到一个点 x = x ∗ \boldsymbol{x}=\boldsymbol{x}^* x=x∗使得 f ( x ∗ ) = 0 \boldsymbol{f}\left( \boldsymbol{x}^* \right) =0 f(x∗)=0。然后, x = x ∗ \boldsymbol{x}=\boldsymbol{x}^* x=x∗被称为函数 f f f的根。 例如,如果 f ( x ) = e − x − cos x + 0.5 \boldsymbol{f}\left( \boldsymbol{x} \right) =\boldsymbol{e}^{-\boldsymbol{x}}-\cos \boldsymbol{x}+0.5 f(x)=e−x−cosx+0.5,则 f ( x ) = e − x − cos x + 0.5 = 0 \boldsymbol{f}\left( \boldsymbol{x} \right) =\boldsymbol{e}^{-\boldsymbol{x}}-\cos \boldsymbol{x}+0.5=0 f(x)=e−x−cosx+0.5=0的根位于曲线 e − x + 0.5 \boldsymbol{e}^{-\boldsymbol{x}}+0.5 e−x+0.5与 cos ( x ) \cos \left( \boldsymbol{x} \right) cos(x) 的交点 如xia图4.1所示。
在本中,将讨论四种求解给定非线性方程的方法,即二分法,牛顿-拉夫森法,割线和迭代法,并在MATLAB和Python中实现。
假设函数 f ( x ) \boldsymbol{f}\left( \boldsymbol{x} \right) f(x) 在间隔 [ a , b ] \left[ \boldsymbol{a},\boldsymbol{b} \right] [a,b] 中是连续的,并且随着函数从a移至b,其符号从正变为负,反之亦然。 中间值定理的直接结果是,连续函数无法在不经过零的情况下在一个间隔内改变其符号。
二等分方法是一种迭代方法,该方法在每次迭代中将包含根的间隔分为两个相等的子间隔,将不包含根的一半除去,然后在另一半中寻找根。
如果间隔 [ a , b ] \left[ \boldsymbol{a},\boldsymbol{b} \right] [a,b] 分为两个相等的子间隔 [ a , c ] \left[ \boldsymbol{a},\boldsymbol{c} \right] [a,c] 和 [ c , b ] \left[ \boldsymbol{c},\boldsymbol{b} \right] [c,b] ,其中 c = ( a + b ) / 2 \boldsymbol{c}=\left( \boldsymbol{a}+\boldsymbol{b} \right) /2 c=(a+b)/2是间隔 [ a , b ] \left[ \boldsymbol{a},\boldsymbol{b} \right] [a,b] 的中点。函数 f f f的根在 [ a , c ] \left[ \boldsymbol{a},\boldsymbol{c} \right] [a,c] 或 [ c , b ] \left[ \boldsymbol{c},\boldsymbol{b} \right] [c,b] 中。 如果它位于 [ a , c ] \left[ \boldsymbol{a},\boldsymbol{c} \right] [a,c] 中,则 f ( a ) ⋅ f ( c ) < 0 \boldsymbol{f}\left( \boldsymbol{a} \right) \cdot \boldsymbol{f}\left( \boldsymbol{c} \right) <0 f(a)⋅f(c)<0。在这种情况下,我们知道根不在 [ a , c ] \left[ \boldsymbol{a},\boldsymbol{c} \right] [a,c] 区间内,因此我们在 [ c , b ] \left[ \boldsymbol{c},\boldsymbol{b} \right] [c,b] 中寻找它 ,二等分法继续将包含根的间隔分为两个子间隔,这样一个子间隔包含根,而另一个不包含根。 因此,该方法仅考虑包含根的间隔并丢弃不包含。
实现二分法的MATLAB代码部分如下,
function x = Bisection(f, a, b, Epsilon)
while b-a ≥ Epsilon
c = (a+b)/2 ;
if f(a)*f(c) < 0
b = c ;
elseif f(b)*f(c) < 0
a = c ;
else
x = c ;
end
end
x=c ;
现在,我们可以从命令提示符处调用函数二分法,
>> format long
>> Epsilon = 1e-8 ;
>> f = @(x) xˆ2 - 3 ;
>> r = Bisection(f, 1, 2, Epsilon)
r =
1.732050813734531
>> s = Bisection(f, -2, -1, Epsilon)
s =
-1
实现二分法的Python代码部分如下,
In [1]: f = lambda x: x**2 - 3
In [2]: a, b = 1., 2.
In [3]: Eps = 1e-8
In [4]: x, Iters = Bisection(f, a, b, Eps)
In [5]: print(’Approximate root is:’, x, ’\nIterations:’, Iters)
Approximate root is: 1.7320508062839508
Iterations: 25
如果函数 f ( x ) \boldsymbol{f}\left( \boldsymbol{x} \right) f(x) 在点 x 0 \boldsymbol{x}_0 x0附近是连续的,则可以用以下形式编写:
f ( x ) = f ( x 0 ) + f ′ ( x 0 ) ( x − x 0 ) + O ( ( x − x 0 ) 2 ) \boldsymbol{f}\left( \boldsymbol{x} \right) =\boldsymbol{f}\left( \boldsymbol{x}_0 \right) +\boldsymbol{f}^{\prime}\left( \boldsymbol{x}_0 \right) \left( \boldsymbol{x}-\boldsymbol{x}_0 \right) +\mathcal{O}\left( \left( \boldsymbol{x}-\boldsymbol{x}_0 \right) ^2 \right) f(x)=f(x0)+f′(x0)(x−x0)+O((x−x0)2)
现在,如果 x 1 \boldsymbol{x}_1 x1是函数 f ( x ) \boldsymbol{f}\left( \boldsymbol{x} \right) f(x) 的根,则 f ( x 1 ) = 0 \boldsymbol{f}\left( \boldsymbol{x}_1 \right) =0 f(x1)=0。即:
f ( x 0 ) + f ′ ( x 0 ) ( x − x 0 ) ≈ f ( x 1 ) = 0 \boldsymbol{f}\left( \boldsymbol{x}_0 \right) +\boldsymbol{f}^{\prime}\left( \boldsymbol{x}_0 \right) \left( \boldsymbol{x}-\boldsymbol{x}_0 \right) \approx \boldsymbol{f}\left( \boldsymbol{x}_1 \right) =0 f(x0)+f′(x0)(x−x0)≈f(x1)=0
根据以上公式:
x 1 = x 0 − f ( x n ) f ′ ( x 0 ) \boldsymbol{x}_1=\boldsymbol{x}_0-\frac{\boldsymbol{f}\left( \boldsymbol{x}_{\boldsymbol{n}} \right)}{\boldsymbol{f}^{\prime}\left( \boldsymbol{x}_0 \right)} x1=x0−f′(x0)f(xn)
假设 f ′ ( x 0 ) ≠ 0 \boldsymbol{f}^{\prime}\left( \boldsymbol{x}_0 \right) \ne 0 f′(x0)=0。
牛顿-拉夫森法是一种迭代方法,用于找到最接近函数 f ( x ) \boldsymbol{f}\left( \boldsymbol{x} \right) f(x) 到初始猜测值 x 0 x_0 x0的近似值。 从 x 0 x_0 x0开始,它会生成一个数字序列 x 0 , x 1 , x 2 , ⋯ , \boldsymbol{x}_0,\boldsymbol{x}_1,\boldsymbol{x}_2,\cdots , x0,x1,x2,⋯,其中,
x n + 1 = x n − f ( x n ) f ′ ( x n ) \boldsymbol{x}_{\boldsymbol{n}+1}=\boldsymbol{x}_{\boldsymbol{n}}-\frac{\boldsymbol{f}\left( \boldsymbol{x}_{\boldsymbol{n}} \right)}{\boldsymbol{f}^{\prime}\left( \boldsymbol{x}_{\boldsymbol{n}} \right)} xn+1=xn−f′(xn)f(xn)
这个数字序列收敛到 f f f的最接近 x 0 \boldsymbol{x}_0 x0的根。
要使用牛顿-拉夫森方法为函数 f ( x ) = x 2 − 3 \boldsymbol{f}\left( \boldsymbol{x} \right) =\boldsymbol{x}^2-3 f(x)=x2−3求根,请注意 f ′ ( x ) = 2 x \boldsymbol{f}^{\prime}\left( \boldsymbol{x} \right) =2\boldsymbol{x} f′(x)=2x,因此,迭代方法的形式为:
x ( n + 1 ) = x ( n ) − f ( x ( n ) ) f ′ ( x ( n ) ) = x ( n ) − ( x ( n ) 2 − 3 ) 2 x ( n ) \boldsymbol{x}^{\left( \boldsymbol{n}+1 \right)}=\boldsymbol{x}^{\left( \boldsymbol{n} \right)}-\frac{\boldsymbol{f}\left( \boldsymbol{x}^{\left( \boldsymbol{n} \right)} \right)}{\boldsymbol{f}^{\prime}\left( \boldsymbol{x}^{\left( \boldsymbol{n} \right)} \right)}=\boldsymbol{x}^{\left( \boldsymbol{n} \right)}-\frac{\left( \boldsymbol{x}^{\left( \boldsymbol{n} \right) ^2}-3 \right)}{2\boldsymbol{x}^{\left( \boldsymbol{n} \right)}} x(n+1)=x(n)−f′(x(n))f(x(n))=x(n)−2x(n)(x(n)2−3)
MATLAB函数NewtonRaphson.m实现了NewtonRaphson方法:
function [x, Iter] = NewtonRaphson(f, fp, x0, Epsilon)
Iter = 0 ;
x1 = x0 - f(x0)/fp(x0) ;
while abs(f(x1)) ≥ Epsilon
x0 = x1 ;
x1 = x0 - f(x0)/fp(x0) ;
Iter = Iter + 1 ;
end
x = x1 ;
从命令提示符处调用NewtonRaphson函数:
>> format long
>> f = @(x) xˆ2 - 3 ;
>> fp = @(x) 2*x ;
>> Epsilon = 1e-8 ;
>> x0 = 1 ;
>>[x, Iterations] = NewtonRaphson(f, fp, x0, Epsilon)
x =
1.732050810014728
Iterations =
3
>> [x, Iterations] = NewtonRaphson(f, fp, -x0, Epsilon)
x =
-1.732050810014728
Iterations =
3
Python函数NewtonRaphson的代码为:
一次运行上述代码 x 0 = 1.0 \boldsymbol{x}_0=1.0 x0=1.0,另一次运行 x 0 = − 1.0 \boldsymbol{x}_0=-1.0 x0=−1.0:
In [6]: x, Iters = NewtonRaphson(f, fp, x0, Eps)
In [7]: print(’Approximate root is:’, x, ’\nIterations:’, Iters)
Approximate root is: 1.7320508100147276
Iterations: 4
In [8]: x, Iters = NewtonRaphson(f, fp, -x0, Eps)
In [9]: print(’Approximate root is:’, x, ’\nIterations:’, Iters)
Approximate root is: -1.7320508100147276
Iterations: 4
割线法与牛顿-拉夫森法具有近似的形式,但是它不需要解析形式为 x n ( f ′ ( x n ) ) \boldsymbol{x}_{\boldsymbol{n}}\left( \boldsymbol{f}^{\prime}\left( \boldsymbol{x}_{\boldsymbol{n}} \right) \right) xn(f′(xn)) 的 f ( x ) \boldsymbol{f}\left( \boldsymbol{x} \right) f(x) 的导数。 它将 f ′ ( x n ) \boldsymbol{f}^{\prime}\left( \boldsymbol{x}_{\boldsymbol{n}} \right) f′(xn) 替换为有限差分公式:
f ′ ( x n ) ≈ f ( x n ) − f ( x n − 1 ) x n − x n − 1 \boldsymbol{f}^{\prime}\left( \boldsymbol{x}_{\boldsymbol{n}} \right) \approx \frac{\boldsymbol{f}\left( \boldsymbol{x}_{\boldsymbol{n}} \right) -\boldsymbol{f}\left( \boldsymbol{x}_{\boldsymbol{n}}-1 \right)}{\boldsymbol{x}_{\boldsymbol{n}}-\boldsymbol{x}_{\boldsymbol{n}-1}} f′(xn)≈xn−xn−1f(xn)−f(xn−1)
因此,割线方法的形式为:
x n + 1 = x n − x n − x n − 1 f ( x n ) − f ( x n − 1 ) f ( x n ) \boldsymbol{x}_{\boldsymbol{n}+1}=\boldsymbol{x}_{\boldsymbol{n}}-\frac{\boldsymbol{x}_{\boldsymbol{n}}-\boldsymbol{x}_{\boldsymbol{n}-1}}{\boldsymbol{f}\left( \boldsymbol{x}_{\boldsymbol{n}} \right) -\boldsymbol{f}\left( \boldsymbol{x}_{\boldsymbol{n}-1} \right)}\boldsymbol{f}\left( \boldsymbol{x}_{\boldsymbol{n}} \right) xn+1=xn−f(xn)−f(xn−1)xn−xn−1f(xn)
从某个包含 f ( x ) \boldsymbol{f}\left( \boldsymbol{x} \right) f(x) 根的间隔 [ a , b ] \left[ \boldsymbol{a},\boldsymbol{b} \right] [a,b] 开始,割线方法迭代逼近 [ a , b ] \left[ \boldsymbol{a},\boldsymbol{b} \right] [a,b] 中 f ( x ) \boldsymbol{f}\left( \boldsymbol{x} \right) f(x) 的零。
MATLAB函数Secant实现割线方法。 它接收一个函数 f f f,其间隔 [ a , b ] \left[ \boldsymbol{a},\boldsymbol{b} \right] [a,b] 的界限包含 f f f的根,并且公差 ε > 0 \boldsymbol{\varepsilon }>0 ε>0。它应用割线方法返回近似解 x x x和迭代次数。
function [x, Iterations] = Secant(f, a, b, Eps)
x = b - ((b-a)*f(b))/(f(b)-f(a)) ;
Iterations = 1 ;
while fabs(f(x)) ≥ Eps
a = b ;
b = x ;
x = b - ((b-a)*f(b))/(f(b)-f(a)) ;
Iterations = Iterations + 1 ;
end
调用MATLAB函数以找到 x 2 − 3 = 0 \boldsymbol{x}^2-3=0 x2−3=0的近似根,如下所示。
>> f = @(x) xˆ2-3 ;
>> a = 1; b = 2 ;
>> Eps = 1e-8 ;
>> [x, Iterations] = Secant(f, a, b, Eps)
x =
1.732050807565499
Iterations =
5
函数Secant的Python代码如下。
为了找到等式 x 2 − 3 = 0 \boldsymbol{x}^2-3=0 x2−3=0的根,使用了以下Python指令:
点 x ∗ \boldsymbol{x}^* x∗是函数 g ( x ) \boldsymbol{g}\left( \boldsymbol{x} \right) g(x) 的不动点,如果
g ( x ∗ ) = x ∗ \boldsymbol{g}\left( \boldsymbol{x}^* \right) =\boldsymbol{x}^* g(x∗)=x∗
假设函数 f ( x ) \boldsymbol{f}\left( \boldsymbol{x} \right) f(x) 是可微的,可以写成
f ( x ) = g ( x ) − x \boldsymbol{f}\left( \boldsymbol{x} \right) =\boldsymbol{g}\left( \boldsymbol{x} \right) -\boldsymbol{x} f(x)=g(x)−x
如果 x 1 x_1 x1是 f ( x ) \boldsymbol{f}\left( \boldsymbol{x} \right) f(x) 的根,则
f ( x 1 ) = g ( x 1 ) − x 1 = 0 ⟹ x 1 = g ( x 1 ) \boldsymbol{f}\left( \boldsymbol{x}_1 \right) =\boldsymbol{g}\left( \boldsymbol{x}_1 \right) -\boldsymbol{x}_1=0\Longrightarrow \boldsymbol{x}_1=\boldsymbol{g}\left( \boldsymbol{x}_1 \right) f(x1)=g(x1)−x1=0⟹x1=g(x1)
这意味着 x 1 x_1 x1是函数 g ( x ) \boldsymbol{g}\left( \boldsymbol{x} \right) g(x) 的不动点。 朝固定点进行迭代的方法的思想是将函数 f ( x ) \boldsymbol{f}\left( \boldsymbol{x} \right) f(x) 编写为 g ( x ) − x \boldsymbol{g}\left( \boldsymbol{x} \right) -\boldsymbol{x} g(x)−x的形状,并从一些初始猜测 x 0 x_0 x0开始,该方法生成数字 x 0 , x 1 , x 2 , ⋯ \boldsymbol{x}_0,\boldsymbol{x}_1,\boldsymbol{x}_2,\cdots x0,x1,x2,⋯ 的序列,使用迭代规则收敛到函数 g ( x ) \boldsymbol{g}\left( \boldsymbol{x} \right) g(x) 的固定点:
x n + 1 = g ( x n ) \boldsymbol{x}_{\boldsymbol{n}+1}=\boldsymbol{g}\left( \boldsymbol{x}_{\boldsymbol{n}} \right) xn+1=g(xn)
为了说明迭代方法的工作原理,将使用它来找到函数的根
f ( x ) = x 2 − 3 \boldsymbol{f}\left( \boldsymbol{x} \right) =\boldsymbol{x}^2-3 f(x)=x2−3
首先,函数 x 2 − 3 \boldsymbol{x}^2-3 x2−3以 g ( x ) − x \boldsymbol{g}\left( \boldsymbol{x} \right) -\boldsymbol{x} g(x)−x的形式编写。 一种可能的选择是编写:
f ( x ) = x 2 − 3 = x 2 + 2 x + 1 − 2 x − 4 = ( x + 1 ) 2 − 2 x − 4 \boldsymbol{f}\left( \boldsymbol{x} \right) =\boldsymbol{x}^2-3=\boldsymbol{x}^2+2\boldsymbol{x}+1-2\boldsymbol{x}-4=\left( \boldsymbol{x}+1 \right) ^2-2\boldsymbol{x}-4 f(x)=x2−3=x2+2x+1−2x−4=(x+1)2−2x−4
如果 x ∗ \boldsymbol{x}^* x∗是 f ( x ) \boldsymbol{f}\left( \boldsymbol{x} \right) f(x) 的根,则:
f ( x ∗ ) = ( x ∗ + 1 ) 2 − 2 x ∗ − 4 = 0 \boldsymbol{f}\left( \boldsymbol{x}^* \right) =\left( \boldsymbol{x}^*+1 \right) ^2-2\boldsymbol{x}^*-4=0 f(x∗)=(x∗+1)2−2x∗−4=0
从中得出,
x ∗ = ( x ∗ + 1 ) 2 − 4 2 \boldsymbol{x}^*=\frac{\left( \boldsymbol{x}^*+1 \right) ^2-4}{2} x∗=2(x∗+1)2−4
从初始点 x 0 x_0 x0开始,为 f ( x ) \boldsymbol{f}\left( \boldsymbol{x} \right) f(x) 求根的迭代方法是:
详情请参考 - 亚图跨际
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。