牛顿法寻找根

问题描述 投票:0回答:1

我试图落实在Python寻根牛顿法。

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

geogebra

码:

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))
python numpy math newtons-method
1个回答
2
投票

你的主要问题是在你的日常x_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.1083264212579311 f(x_n) 0.005607493777795347
i: 2 x_n: 1.1196379358595814 f(x_n) 6.373534192993802e-05

这是你想要的。如果你坚持使用的衍生物的数值逼近,用我上面给的版本,结果略有不同:

i: 1 x_n: 1.10832642185337 f(x_n) 0.005607493482616466
i: 2 x_n: 1.1196379360265405 f(x_n) 6.373526104597182e-05
© www.soinside.com 2019 - 2024. All rights reserved.