使用python实现了简单的二分法求非线性方程根。
# -*- coding: utf-8 -*-
"""
Created on Thu Dec 13 22:16:35 2018
@author: zwq
Python实现二分法求解非线性方程
"""
import math
class ConditionError(Exception):
def __init__(self,ErrorInfo):
super().__init__(self)
self.errormsg = ErrorInfo
def __str__(self):
return self.errormsg
def f(x):
'''Nonlinear function to be solved
$f(x)=(x+1)(x-1)(x-2)$
'''
return math.sin(10*x)*x**3-2*x**2-x+2
def BisectionMethod(f,a,b,err=1e-5,max_iter=100):
'''A root-finding method:Bisection method.
Args
----------
f: callable function
The nonlinear function to be solved.
a,b: float
The initial interval, which satisfies the condition:a<b
err: float
Tollerence of the result.
max_iter: int
Maximun iterations.
Outs
----------
x0: float
The root between interval [a,b].
tol: float
Tollerence of the result.
iters:
Number of iterations when the method stopped.
'''
if a>b:
raise ConditionError('Wrong interval setup,it must be: a<b')
if (f(a)>0 and f(b)>0) or (f(a)<0 and f(b)<0):
print("Can't find the root of function as the condition is insurficient!")
n = 1
while n<max_iter:
c = (a+b)/2
print("n={},c={}".format(n,f(c)))
if f(c)==0 or (b-a)/2<err:
x0=c
break
n += 1
if f(a)*f(c)>0: #
a = c
# b = b
else:
# a = a
b = c
print("n={},tol={},x0={}".format(n,abs(f(x0)),x0))
tol, iters = abs(f(x0)), n
return x0,tol,iters
if __name__ == '__main__':
BisectionMethod(f,-1,2,err=1e-5)
运行结果如下:
n=1,c=0.8801344656671077
n=2,c=-2.504534955764064
n=3,c=0.012266242456421939
n=4,c=-2.4383552746206343
n=5,c=-1.081818390163496
n=6,c=-0.46130714994246524
n=7,c=-0.20365757414906271
n=8,c=-0.09034016716723503
n=9,c=-0.03769095321814975
n=10,c=-0.012375583961710568
n=11,c=2.951770163184264e-05
n=12,c=-0.006151983786208071
n=13,c=-0.00305597088059395
n=14,c=-0.0015119110800037028
n=15,c=-0.0007408678162565963
n=16,c=-0.000355592839670571
n=17,c=-0.00016301701468535157
n=18,c=-6.674451795252168e-05
n=19,c=-1.8612123517947055e-05
n=19,tol=1.8612123517947055e-05,x0=0.8764705657958984
伪代码:
INPUT: Function f, endpoint values a, b, tolerance TOL, maximum iterations NMAX
CONDITIONS: a < b, either f(a) < 0 and f(b) > 0 or f(a) > 0 and f(b) < 0
OUTPUT: value which differs from a root of f(x)=0 by less than TOL
N ← 1
While N ≤ NMAX # limit iterations to prevent infinite loop
c ← (a + b)/2 # new midpoint
If f(c) = 0 or (b – a)/2 < TOL then # solution found
Output(c)
Stop
EndIf
N ← N + 1 # increment step counter
If sign(f(c)) = sign(f(a)) then a ← c else b ← c # new interval
EndWhile
Output("Method failed.") # max number of steps exceeded
伪代码参考链接:
[1]https://en.wikipedia.org/wiki/Bisection_method