实验内容
分别用Newton切线法、Newton下山法和割线法求方
x
2
−
2
x
−
e
x
+
2
=
0
x^2-2x-e^x+2=0
x2−2x−ex+2=0的近似根,其对应函数图像如下图所示。
算法描述
Newton切线法
迭代公式
x k + 1 = x k − f ( x k ) f ( x k ) x_{k+1}=x_k-\frac{f(x_k)}{f (x_k)} xk+1=xk−f(xk)f(xk)
算法流程图
Newton下山法
在 x k x_k xk和 x k + 1 x_{k+1} xk+1之间找一个更好的点 x k + 1 ‾ \overline{x_{k+1}} xk+1使得: ∣ f ( x k + 1 ‾ ) ∣ < ∣ f ( x k ) ∣ |f(\overline{x_{k+1}})|<|f(x_k)| ∣f(xk+1)∣<∣f(xk)∣
迭代公式
x k + 1 = x k − r ⋅ f ( x k ) f ( x k ) x_{k+1}=x_k-r\cdot\frac{f(x_k)}{f (x_k)} xk+1=xk−r⋅f(xk)f(xk)
算法流程图
割线法
迭代公式
x k + 1 = x k − x k − x 0 f ( x k ) − f ( x 0 ) f ( x k ) x_{k+1}=x_k-\frac{x_k-x_0}{f(x_k )-f(x_0 ) } f(x_k ) xk+1=xk−f(xk)−f(x0)xk−x0f(xk)
算法流程图
实验结果
Python代码求解
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time : 2018/10/14 19:59
# @Author : Guojing Li
# @File : SolveNonlinearEquation.py
# @Software: PyCharm
"""
Methods of solving non-linear equation
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This module includes three Methods of solving my non-linear equation and a plot function.
You can choose a Methods to get the solution of my non-linear equation.
This is my non-linear equation: x**2 - 2*x - exp(x) + 2 = 0
"""
import math
from matplotlib import pyplot as plt
import numpy as np
def plot_nonlinear_equation():
"""
绘制函数f(x) = x**2 - 2*x - exp(x) + 2 和函数f(x) = 0的图像
:return: None
"""
X = np.arange(-3, 3, 0.01)
Y = [f(x) for x in X]
plt.plot(X, Y, linewidth='2', linestyle="-" )
plt.hlines(0, -3, 3, colors='r')
plt.xlim(-3, 3)
plt.ylabel("f(x)")
plt.xlabel("x")
plt.legend(["f(x) = x**2 - 2*x - exp(x) + 2 ", "f(x) = 0"])
plt.show()
def f(x):
"""
:param x:
:return: f(x)
"""
return x**2 - 2*x - math.exp(x) + 2
def df(x):
"""
:param x:
:return: f(x)的导数
"""
return 2*x - 2 - math.exp(x)
def tangent_method(x, ep=1e-05, max_iteration=500):
"""
牛顿切线法求解非线性方程
:param x: x初始值
:param ep: 精度
:param max_iteration: 最大迭代次数
:return: 迭代次数, 方程的解
"""
print("牛顿切线法求解方程,精度为", ep, ",最大迭代次数为", max_iteration)
print("初始值:x =", x)
for iteration in range(max_iteration):
if (df(x) == 0):
exit("导数为0,迭代失败")
x1 = x - f(x)/df(x)
print("第", iteration+1, "次迭代,x =", x1)
if(math.fabs(x1-x) <= ep):
return iteration+1, x1
else:
x = x1
exit("以迭代到上限值")
def downhill_method(x, ep=1e-05, max_iteration=500):
"""
牛顿下山法求解非线性方程
:param x: x初始值
:param ep: 精度
:param max_iteration: 最大迭代次数
:return: 迭代次数, 方程的解
"""
print("牛顿下山法求解方程,精度为", ep, ",最大迭代次数为", max_iteration)
print("初始值:x =", x)
for iteration in range(max_iteration):
if (df(x) == 0):
exit("导数为0,迭代失败")
r = 1
x1 = x - r*f(x)/df(x)
while (math.fabs(f(x1)) > math.fabs(f(x))):
r = r / 2
x1 = x - r*f(x)/df(x)
if (math.fabs(f(x1)) < math.fabs(f(x))):
print("下山调整后,r = ", r)
x1 = x - r*f(x)/df(x)
print("第", iteration + 1, "次迭代,x =", x1)
if(math.fabs(x1-x) <= ep):
return iteration+1, x1
else:
x = x1
exit("以迭代到上限值")
def secant_method(x0, x1, ep=1e-05, max_iteration=500):
"""
割线法求解非线性方程
:param x0: x0初始值
:param x1: x1初始值
:param ep: 精度
:param max_iteration: 最大迭代次数
:return: 迭代次数, 方程的解
"""
print("割线法求解方程,精度为", ep, ",最大迭代次数为", max_iteration)
print("初始值:x0 =", x0, ", x1 = ", x1)
for iteration in range(max_iteration):
if(math.fabs(x1-x0) <= ep):
return iteration, x1
else:
x2 = x1 - f(x1)*(x1-x0)/(f(x1)-f(x0))
x0 = x1
x1 = x2
print("第", iteration+1, "次迭代,x0 =", x0, ", x1 =", x1)
exit("以迭代到上限值")
if __name__ == "__main__":
#绘制函数f(x) = x**2 - 2*x - exp(x) + 2 和函数f(x) = 0的图像函数的调用
plot_nonlinear_equation()
#牛顿切线法函数的调用
count, result = tangent_method(1)
print("共迭代%d次, 方程的解为%.17f" % (count, result))
#牛顿下山法函数的调用
count, result = downhill_method(1)
print("共迭代%d次, 方程的解为%.17f" % (count, result))
# #割线法函数的调用
count, result = secant_method(0, 1)
print("共迭代%d次, 方程的解为%.17f" % (count, result))