2014-01-22 2 views
1

Как я могу использовать метод Ньютона, чтобы найти все корни полинома, а не только уникальные?Алгоритм Ньютона-Рафсона: найти все корни включают отрицательные

Ссылка на код: 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?

+0

Это зависит от начальной точки. Установите его на что-то отрицательное/ближе к корню, и вы его получите. – nhahtdh

+0

@nhahtdh, так как я могу реализовать код, который я дал, чтобы найти все корни? – user3215609

ответ

2

Перезапустите свой Ньютон Рафсон из другого стартового положения.

Я вложил здесь некоторый код, который я реализовал в разработке библиотеки финансовых инструментов. Смотрите здесь мой код для Ньютона Рафсона. В качестве одного из входных параметров вы видите начальную позицию 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 в шаблоне). Примечание. Я включил класс исключений, поскольку у Ньютона Рафсона есть некоторые проблемы.

Использовать алгоритм деления пополам для более стабильного алгоритма. На практике вы можете использовать числа, меньшие, чем 1.E-6.

Значение должно быть здесь указателем на функцию, которая оценивает вашу квадратичную функцию, цель должна быть установлена ​​в 0, а производная должна быть указателем на функцию, которая оценивает производную от вашей функции.

В вашем случае мой код шаблона может быть упрощена: Заменить код diff = Target-(Object.*Value)(x); с diff = (Object.*Value)(x); Заменить x = x - diff/(-derivative); с x = x - diff/(derivative); Этот код будет более узнаваемого как алгоритм Ньютона-Рафсона. Если вы хотите увеличить скорость конвергенции, используйте алгоритм Галлея (да, парень из кометы) или алгоритм домохозяина.

См. Числовые рецепты в C++ для альтернативной реализации. Численные рецепты на C++ - это книга, которая будет посвящена этим вопросам.

Смежные вопросы