非线性方程求根
调包
import math
import sympy as sp
二分法
#二分法
def Dichotomy(a,b,fStr,epsilon = 1e-6,eta = 1e-9):
def f(x):
return globals()[fStr](x)
n = 0
fa = f(a)
fb = f(b)
if fa * fb >= 0:
print("算法失败")
return
while abs(b - a) > epsilon:
x = (a + b) / 2
fx = f(x)
if abs(fx) < eta:
return x,n
else:
if fa * fx < 0:
b = x
fb = fx
else:
a = x
fa = fx
n += 1
return x,n
牛顿迭代法
#牛顿迭代法
def Newton(x0,fStr,epsilon = 1e-6,eta = 1e-9,N = 1000):
def f(x):
return globals()[fStr](x)
def f_(x):
x_ = sp.symbols("x_")
return sp.diff(f(x_),x_).evalf(subs={x_:x})
n = 0
while True:
if f_(x0) == 0 or n > N:
print("算法失败")
return
x1 = x0 - f(x0) / f_(x0)
n += 1
if abs(x1 - x0) < epsilon or abs(f(x1)) < eta:
return x1,n
x0 = x1
单点弦截法
#单点弦截法
def SinglePoint(x0,x1,fStr,epsilon = 1e-6,eta = 1e-9,N = 1000):
def f(x):
return globals()[fStr](x)
n = 0
while True:
x2 = x1 - f(x1) / (f(x1) - f(x0)) * (x1 - x0)
n += 1
if abs(x2 - x1) < epsilon or abs(f(x2)) < eta:
return x2,n
x1 = x2
两点弦截法
#两点弦截法
def DoublePoint(x0,x1,fStr,epsilon = 1e-6,eta = 1e-9,N = 1000):
def f(x):
return globals()[fStr](x)
n = 0
while True:
x2 = x1 - f(x1) / (f(x1) - f(x0)) * (x1 - x0)
n += 1
if abs(x2 - x1) < epsilon or abs(f(x2)) < eta:
return x2,n
x0 = x1
x1 = x2
例题
def f1(x):
return x**3 + x**2 - 3 * x - 3
q1 = Dichotomy(1,2,"f1")
print("二分法:",q1)
originNums = [1,1.25,1.5,2,3]
print("\n牛顿迭代法:")
for i in originNums:
print("当初值为" + str(i) + "时,f(x)的根为:",Newton(i,"f1")[0])
print("迭代次数:",Newton(i,"f1")[1])
points = [[0,3],[1,2],[1.3,1.7],[1.4,1.6]]
print("\n单点弦截法:")
for i in points:
print("当x0=" + str(i[0]) + ",x1=" + str(i[1]) + "时:")
print("单点弦截法结果:",SinglePoint(i[0],i[1],"f1")[0]," 迭代次数:",SinglePoint(i[0],i[1],"f1")[1])
print("\n两点弦截法:")
for i in points:
print("当x0=" + str(i[0]) + ",x1=" + str(i[1]) + "时:")
print("两点弦截法结果:",DoublePoint(i[0],i[1],"f1")[0]," 迭代次数:",DoublePoint(i[0],i[1],"f1")[1])
结果如下:(原方程根为1.732051)