Newton-Raphson算法:查找所有根包括否定

时间:2014-01-22 16:48:14

标签: c++ algorithm

如何使用牛顿方法查找多项式的所有根,而不仅仅是唯一的?

代码链接:http://quantcorner.wordpress.com/2012/09/14/an-implementation-of-the-newton-raphson-algorithm-in-c-cpp-and-r/

作为一个例子,我有这个等式:x^2-12x+34=0,当我使用这个公式时,我只得到一个根4.5857,我怎样才能获得第二个根 - 7.4142

1 个答案:

答案 0 :(得分:2)

从不同的起始位置重新启动Newton Raphson。

我在这里粘贴了一些我在开发金融工具定价库时实施的代码。在这里看到我的代码为Newton Raphson。您将输入参数视为起始位置double start之一。您可以从网格上的不同位置开始,例如并将解决方案与您已经找到的解决方案进行比较。

#include "math.h"
#include "ExceptionClass.h"

template <class T, double (T::*Value)(const double) const,
                   double (T::*Derivative)(const double) const>
        double NewtonRaphson(double Target, double start, double Tolerance,
                             size_t max_count, const T& Object)
    {
    size_t count = 0;
    double diff = Target-(Object.*Value)(start);
    double x = start;
    double derivative = (Object.*Derivative)(start);

    do{
        count++;
        if(fabs(derivative) < 1.E-6)
            throw DivideByZeroException("Dividing by a derivative smaller than: 1.E-6!");

        x = x - diff/(-derivative);

        diff = Target-(Object.*Value)(x);
        derivative = (Object.*Derivative)(x);
    } while((fabs(diff)>Tolerance)&&(count < max_count));

    if(count >= max_count)
        throw("Newton-Raphson did not converge in the defined number of steps!");
    else return x;
    }

T是一个类,您可以在其中定义函数来计算(二次)方程(此处由模板中的double (T::*Value)(const double) const引用)和此方程的导数(此处由double (T::*Derivative)(const double) const引用)模板)。 注意我已经包含了一个异常类,因为Newton Raphson有一些问题。

使用二分算法获得更稳定的算法。 实际上,您可以使用小于1.E-6的数字。

值应该是指向评估二次函数的函数的指针,目标应设置为0,导数应该是指向函数导数的指针。

在您的情况下,我的模板代码可以简化: 将代码diff = Target-(Object.*Value)(x);替换为diff = (Object.*Value)(x);x = x - diff/(-derivative);替换为x = x - diff/(derivative);此代码将更容易被识别为Newton Raphson算法。 如果你想提高收敛速度,可以使用Halley(是彗星中的人)算法或Householder算法。

请参阅c ++中的数字配方以了解替代实现。 C ++中的数字配方是解决这类问题的书。