x轴上下交点的寻根功能

时间:2019-03-28 15:55:22

标签: python python-3.x numerical-methods

我需要找到由x给出的曲线的x轴的上下交点

y=f(x)=10⋅exp(sin(x))−(x^2)/2

为了找到曲线的弧长,在Python中

我已经尝试了两种方法,我完全无法使用的割线方法。还有找到一个交点的牛顿法。

from math import exp 
from math import sin
from math import cos

def func( x ): 
    return 10*exp(sin(x))-(x**2)/2

def derivFunc( x ): 
    return 10*exp(sin(x))*cos(x)-x

def newtonRaphson( x ): 
    h = func(x) / derivFunc(x) 
    while abs(h) >= 0.0001: 
        h = func(x)/derivFunc(x) 

        x = x - h 

    print("The value of the root is : ", 
                             "%.4f"% x) 


x0 = -20 
newtonRaphson(x0) 

给出

The value of the root is :  -5.7546

然后是第二种方法

import math 
from math import exp 
from math import sin


def f(x):

    f = 10*exp(sin(x))-(x**2)/2
    return f; 

def secant(x1, x2, E):
    n = 0; xm = 0; x0 = 0; c = 0;
    if (f(x1) * f(x2) < 0):
        while True:
            x0 = ((x1 * f(x2) - x2 * f(x1)) /(f(x2) - f(x1)));
            c = f(x1) * f(x0);
x1 = x2;
x2 = x0;
n += 1;
if (c == 0): 
    xm = ((x1 * f(x2) - x2 * f(x1)) /(f(x2) - f(x1)));
if(abs(xm - x0) < E):
    print("Root of the given equation =",round(x0, 6));
    print("No. of iterations = ", n); 
    print("Can not find a root in ","the given inteval"); 
x1 = 0; x2 = 1;
E = 0.0001;
secant(x1, x2, E);             

仅导致

NameError: name 'x2' is not defined

但是,只要我尝试定义字符就不会运行

我希望能够获得x轴的上下交点,所以我可以找到弧长。还有一种方法可以绘制图形吗?

1 个答案:

答案 0 :(得分:1)

关于牛顿-拉夫森法:

正常行为

它主要按预期工作。该方法只能收敛到单个根,具体取决于起点。要获得另一个根,您需要另一个起点。

您的函数产生:

>>> newtonRaphson(-20)
-5.7545790362989
>>> newtonRaphson(5)
3.594007784799419

这似乎是正确的。

臭虫

不能保证Newton-Raphson方法收敛,它可能会进入无限循环,在这种情况下,您的程序将无限期地挂起,或者某个点的导数可能为零,在这种情况下,您将无法计算{ {1}}。您需要处理这些情况。

样式

有很多事情可以证明:

  • 该错误必须修复
  • 您的Newton-Raphson方法目前仅适用于一种功能。您应该将函数和派生函数作为参数传递,以便可以将方法应用于所需的任何函数。
  • 所需的精度和最大迭代次数也可以作为参数传递
  • 在函数中进行打印是一种不好的做法。您应该返回该值,这样您就可以决定对结果做任何事情。
  • 您应遵循PEP8的样式准则
  • 如果您打算重复使用它,请添加一个文档字符串(很有可能,这是一个非常有用的工具!)

我对这种方法的看法:

h

用法:

def newton_raphson(f, df, x, epsilon = 0.0001, maxiter = 1000): 
    """ Estimates the root of a function.

    Gives an estimate to the required precision of a root of the given function
    using the Newton-Raphson method.

    Raises an Exception if the Newton-Raphson method doesn't converge in the
    specified number of iterations.
    Raises a ZeroDivisionError if the derivative is zero at a calculated point

    :param f: The function 
    :param df: The function's derivative
    :param x: the starting point for the method
    :param epsilon: The desired precision
    :param maxiter: The maximum number of iterations

    :return: The root extimate
    :rtype: float
    """

    for _ in range(maxiter):
        h = f(x)/df(x) 
        if abs(h) < epsilon:
            return x
        x = x - h 

    raise Exception("Newton Raphson method didn't "
                    + "converge in {} iterations".format(maxiter))

关于割线方法:

我对那个不太熟悉,所以我只想提一下您的错误是由于识别错误所致。此处已修复:

>>> print(newton_raphson(func, derivFunc, 20))
-5.7545790362989
>>> print(newton_raphson(func, derivFunc, 5, 0.1, 100))
3.5837828560043477
>>> print(newton_raphson(func, derivFunc, 5, 0.001, 100))
3.594007784799419
>>> print(newton_raphson(func, derivFunc, 5, 1e-9, 4))
Traceback (most recent call last):
(...)
Exception: Newton Raphson method didn't converge in 4 iterations

如果您打算适当地实现此方法,则有关Newton-Raphson方法的评论仍将保留。