Перезапустите свой Ньютон Рафсон из другого стартового положения.
Я вложил здесь некоторый код, который я реализовал в разработке библиотеки финансовых инструментов. Смотрите здесь мой код для Ньютона Рафсона. В качестве одного из входных параметров вы видите начальную позицию 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++ - это книга, которая будет посвящена этим вопросам.
Это зависит от начальной точки. Установите его на что-то отрицательное/ближе к корню, и вы его получите. – nhahtdh
@nhahtdh, так как я могу реализовать код, который я дал, чтобы найти все корни? – user3215609