1. 下面非线性方程组
2.牛顿迭代法公式
3.几何说明
4.用Python编程
4.1定义函数包
# -*-coding:UTF-S -*-
"""
@author:
@file_name:nonlinear_functions.py
@time:2024-01-08 19:31
@IDE:PyCharm
@copyright:automatic
"""
import sympy # 导入包,符号运算需要
import math # 导入包,数值运算需要
# 数值运算 定义函数
def numeric_function(x):
"""
采用数值求解下面非线性函数
2*exp(-x)*sin(x)+2*cos(x)+0.25
:param x:
:return:返回一个所需求解的函数
"""
return 2 * math.exp(-x) * math.sin(x) + 2 * math.cos(x) + 0.25
def numeric_diff_function(x):
"""
newton 法:求非线性方程需要求非线性方程的微分
:param x:
:return:
"""
# u'v+uv',返回一个对非线性函数的一阶导数
return 2 * math.exp(-x) * (- math.cos(x) - math.sin(x)) - 2 * math.sin(x)
# 符号运算,定义函数
def symbolic_ope_function():
"""
需要定义符号,符号运算是x是一个符号,不是一个值
:return:
"""
# 定义符号
x = sympy.Symbol("x") # 定义符号变量x
return 2 * sympy.exp(-x) * (- sympy.cos(x) - sympy.sin(x)) - 2 * sympy.sin(x)
def diff_symbolic_ope_function():
"""
符号运算可以直接求导数
:return:
"""
return symbolic_ope_function().diff()
# 是对上个函数symbolic_operation_function()直接求微分
4.2 求解
# -*-coding:UTF-S -*-
"""
@author:
@file_name:nonlinear_equation_newton_iteration.py
@time:2024-01-08 19:30
@IDE:PyCharm
@copyright:automatic
"""
# 输入包
import math # 输入数学包
import sympy # 输入符号包
# 从另一个包中导入函数
from data.nonlinear_functions import numeric_function, numeric_diff_function, symbolic_ope_function, diff_symbolic_ope_function
# 数值运算
def numerical_newton_iteration(x0, eps=1e-10, max_iter=100):
# 定义函数,输入三个参数,分别是初始值,精度,迭代次数
"""
用数值方法求解非线性方程
:param x0: 初始值
:param eps: 精度
:param max_iter:最大迭代次数
:return:
"""
print("%5s, %21s, %21s" % ("iter", "ApproximateRoot", "ErrorPrecision"))
# 定义初值
x_next = x0
for iter in range(max_iter):
# 循环次数[0,max_iter-1]
x_before = x_next # 近似解不断更替,直至收敛
x_next = x_before - numeric_function(x_before) / numeric_diff_function(x_before)
# 算精度
tol = abs(x_next - x_before)
# 输出
print("%3d, %20.15f, %20.15e" % (iter + 1, x_next, tol))
# 如果精度满足要求,跳出
if tol <= eps:
break
# 符号运算
def symbolic_newton_iteration(x0, eps=1e-10, max_iter=100):
"""
用符号运算求解非线性方程
:param x0: 初始值
:param eps: 精度
:param max_iter:最大迭代次数
:return: 近似解
"""
fh,dfh = symbolic_ope_function(),diff_symbolic_ope_function()
# 把两个函数给fh和dfh
x = fh.free_symbols.pop() # 返回集合{x,y,z}中的x
x_next = x0 # 初始化
for iter in range(max_iter):
x_before = x_next # 近似解不断更替
fx = fh.evalf(subs=({x: x_before})) # 用evalf函数求解fh函数
dfx = dfh.evalf(subs=({x: x_before}))
# 核心公式
x_next = x_before - fx / dfx
# 算精度
tol = abs(x_next - x_before)
print("%3d, %20.15f, %20.15e" % (iter + 1, x_next, tol))
# 如果满足精度跳出
if tol <= eps:
break
if __name__ == '__main__':
x0 = float(input("1.请输入初始值x0:"))
eps = float(input("2.请输入精度eps:"))
max_iter = int(input("3.请输入最大迭代次数max_iter:"))
numerical_newton_iteration(x0=x0, eps=eps, max_iter=max_iter) # 运行函数
print("=" * 50)
symbolic_newton_iteration(x0=x0, eps=eps, max_iter=max_iter)