Python 牛顿';s求根法

Python 牛顿';s求根法,python,numpy,math,newtons-method,Python,Numpy,Math,Newtons Method,我正在尝试实现牛顿在Python中寻找根的方法 预期结果是B点,但Python返回A点: 代码: import matplotlib.pyplot as plt import numpy as np def f(theta): return 1 - (((2 * 1.5) * np.sin(theta))/ 2.7) def derivative(f, x): dx = 1E-8 return (f(x + dx) - f(x)) / dx def x_next(

我正在尝试实现牛顿在Python中寻找根的方法

预期结果是B点,但Python返回A点:

代码:

import matplotlib.pyplot as plt
import numpy as np

def f(theta):
    return 1 - (((2 * 1.5) * np.sin(theta))/ 2.7)

def derivative(f, x):
    dx = 1E-8
    return (f(x + dx) - f(x)) / dx

def x_next(f, x_n):
    return 1 - (f(x_n) / derivative(f, x_n))

def newtons_method(f, x_n = 1, i = 0, max_iter = 100):
    i = i + 1
    if (i == max_iter):
        return None
    x_n = x_next(f, x_n)
    if (abs(f(x_n)) < 1E-4):
        return x_n
    print("i:",i,"x_n:",x_n,"f(x_n)",f(x_n))
    newtons_method(f, x_n, i, max_iter)

print(newtons_method(f))
导入matplotlib.pyplot作为plt
将numpy作为np导入
def(θ):
返回1-((2*1.5)*np.sin(θ))/2.7)
def衍生物(f,x):
dx=1E-8
返回(f(x+dx)-f(x))/dx
def x_next(f,x_n):
返回1-(f(x_n)/导数(f,x_n))
定义牛顿法(f,x,n=1,i=0,max,iter=100):
i=i+1
如果(i==最大值):
一无所获
x_n=x_next(f,x_n)
如果(abs(f(x_n))<1E-4:
返回x\n
打印(“i:,i,“x_n:,x_n”,“f(x_n)”,f(x_n))
牛顿法(f,x,i,max,iter)
印刷(牛顿法(f))

你的主要问题在于你的日常工作
x\u下一步
。您有一个
1
,其中应该有一个
x\n
。所以日常生活应该是

def x_next(f, x_n):
    return x_n - (f(x_n) / derivative(f, x_n))
你的衍生程序也很糟糕。如果你必须近似导数,牛顿-拉斐逊不是最好的方法。您使用的近似方法在数值上也不好,尽管它确实遵循导数的定义。如果必须使用近似值,请使用

def derivative(f, x):
    dx = 1E-8
    return (f(x + dx) - f(x - dx)) / (2.0 * dx)
但在这种情况下,导数很容易直接计算。因此,最好使用

def derivative(f, x):
    return -2 * 1.5 * np.cos(x) / 2.7
您也不打印根及其函数值的最终近似值——您计算它并返回,而不打印它。因此,在测试返回语句之前,请将您的
print
语句放在此处

通过这些更改(加上注释掉从未使用过的
matplotlib
的导入),您的代码现在就可以使用了

#import matplotlib.pyplot as plt
import numpy as np

def f(theta):
    return 1 - (((2 * 1.5) * np.sin(theta))/ 2.7)

def derivative(f, x):
    return -2 * 1.5 * np.cos(x) / 2.7

def x_next(f, x_n):
    return x_n - (f(x_n) / derivative(f, x_n))

def newtons_method(f, x_n = 1, i = 0, max_iter = 100):
    i = i + 1
    if (i == max_iter):
        return None
    x_n = x_next(f, x_n)
    print("i:",i,"x_n:",x_n,"f(x_n)",f(x_n))
    if (abs(f(x_n)) < 1E-4):
        return x_n
    newtons_method(f, x_n, i, max_iter)

print(newtons_method(f))
这就是你想要的。如果你坚持对导数使用数值近似,使用我上面给出的版本,结果略有不同:

i: 1 x_n: 1.10832642185337 f(x_n) 0.005607493482616466
i: 2 x_n: 1.1196379360265405 f(x_n) 6.373526104597182e-05

你的主要问题在于你的例行程序
x\u next
。您有一个
1
,其中应该有一个
x\n
。所以日常生活应该是

def x_next(f, x_n):
    return x_n - (f(x_n) / derivative(f, x_n))
你的衍生程序也很糟糕。如果你必须近似导数,牛顿-拉斐逊不是最好的方法。您使用的近似方法在数值上也不好,尽管它确实遵循导数的定义。如果必须使用近似值,请使用

def derivative(f, x):
    dx = 1E-8
    return (f(x + dx) - f(x - dx)) / (2.0 * dx)
但在这种情况下,导数很容易直接计算。因此,最好使用

def derivative(f, x):
    return -2 * 1.5 * np.cos(x) / 2.7
您也不打印根及其函数值的最终近似值——您计算它并返回,而不打印它。因此,在测试返回语句之前,请将您的
print
语句放在此处

通过这些更改(加上注释掉从未使用过的
matplotlib
的导入),您的代码现在就可以使用了

#import matplotlib.pyplot as plt
import numpy as np

def f(theta):
    return 1 - (((2 * 1.5) * np.sin(theta))/ 2.7)

def derivative(f, x):
    return -2 * 1.5 * np.cos(x) / 2.7

def x_next(f, x_n):
    return x_n - (f(x_n) / derivative(f, x_n))

def newtons_method(f, x_n = 1, i = 0, max_iter = 100):
    i = i + 1
    if (i == max_iter):
        return None
    x_n = x_next(f, x_n)
    print("i:",i,"x_n:",x_n,"f(x_n)",f(x_n))
    if (abs(f(x_n)) < 1E-4):
        return x_n
    newtons_method(f, x_n, i, max_iter)

print(newtons_method(f))
这就是你想要的。如果你坚持对导数使用数值近似,使用我上面给出的版本,结果略有不同:

i: 1 x_n: 1.10832642185337 f(x_n) 0.005607493482616466
i: 2 x_n: 1.1196379360265405 f(x_n) 6.373526104597182e-05