用Newton切線法、Newton下山法、割線法求一元非線性方程的近似解-Python
阿新 • • 發佈:2018-12-26
實驗內容
分別用Newton切線法、Newton下山法和割線法求方的近似根,其對應函式影象如下圖所示。
演算法描述
Newton切線法
迭代公式
演算法流程圖
Newton下山法
在和之間找一個更好的點使得:
迭代公式
演算法流程圖
割線法
迭代公式
演算法流程圖
實驗結果
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))