本文分别采用python代码实现二分法,固定点法,牛顿法,割线法来求某方程的零点。
这几种方法是数值优化中求方程零点的非常常用的方法。
首先是二分法(最简单):
# Finds the root, or solution, of the form f(x) = 0. f(x) is a continuous
# function defined on an interval [a,b] and where f(a) and f(b) have
# opposite signs [f(a)*f(b) < 0]
# Also, uses:
# abs((w(n)-w(n-q))/w(n)) <= 10^-5 as the tolerance
import math
# globals
TOL = 10 ** -5
A = 1
B = 2
N = 100
# give python eqn of the formula using python math syntax
# def f(x):
# return (math.pow(x, 3) - x - 2)
def f(x):
return math.pow(x,2)-2
# INPUT: function (func), low guess (a), high guess (b), tolerance (tol),
# MAX iterations (N)
# CONDITIONS: a < b, f(a)*f(b) < 0
# OUTPUT: value which differs from a root of f(x)=0 by less than 'tol'
def bisect(func, low, high, tol, N):
# switch low and high if low is larger than high
if low > high:
low = temp
low = high
high = temp
# check if valid input
if func(low) * func(high) > 0:
print("Check input for low and high guess (f(low) and f(high) must have different signs)")
lastFuncVal = func(low)
for i in range(0, N):
mid = (high + low) / 2.0
if func(mid) == 0 or (high - low) / 2.0 < tol:
return mid
# same sigh
if func(mid) * func(low) > 0:
low = mid
# diff sign
else:
high = mid
lastFuncVal = func(mid)
return "Method failed after {} iterations".format(N)
print("Bisection method soln: x = ", bisect(f, A, B, TOL, N))
固定点法:
# Finds the root of equation in the form of x = f(x) or g(x) = x - f(x) by using the fixed point method
import math
# globals
APPROX = 4.6
TOL = 10 ** -4
N = 100
# function to test using python syntax in form g(x) = x - f(x)
def f(x):
return (1 / math.tan(x)) - (1 / x) + x
# def f(x):
# return math.pow(x,2)-2
def fixedPoint(func, approx, tol, n):
for i in range(0, n):
p = func(approx)
if abs(p - approx) < tol:
return p
approx = p
return "Method failed after {} iterations".format(n)
print("Fixed point soln: x = ", fixedPoint(f, APPROX, TOL, N) )
牛顿法:
# program to find solution to equation, namely f(x) = 0, using newton's
# method
import math
import time
# globals
APPROX = 0.1
TOL = 10**-5
N = 100
# functions we are using, namely f and f'
# def f(x):
# return math.pow((1+x),204)-440*x-1
def f(x):
return math.pow(x,2)-2
def fprime(x):
return 2*x
# Actual Newton's Method
def newtons(approx, tol, n):
p0 = approx
for i in range(0, n):
p = p0 - (f(p0)/fprime(p0)) # this is the calculation of the guess
if abs(p - p0) < tol:
return p
p0 = p
return "The method failed after {} iterations".format(n)
# Call the method and print its answer
output = newtons(APPROX, TOL, N)
print ("Newton's method soln: x = ", output)
割线法:
# finds the solution to f(x) = 0 using secant method
import math
# globals
APPROX = 0.1
TOL = 10**-5
N = 100
# function we are using
# def f(x):
# return math.pow((1+x),204)-440*x-1
def f(x):
return math.pow(x,2)-2
# Actual Secant Method
def secant(p0, p1, tol, N):
for i in range(0, N):
p = p1 - ((f(p1)*(p1-p0))/(f(p1) - f(p0)))
if abs(p-p1) < tol:
return p
p0 = p1
p1 = p
return "Them method failed after {} iterations">format(N)
print("Secant method soln: x = ", secant(.1,.09,math.pow(10,-5),100))