2016-10-17 2 views
0

Я работаю в простой программе, которая вычисляет корень любой заданной функции с использованием метода Ньютона-Рафсона. В этой программе я должен напечатать найденный корень и количество сделанных итераций. Сама программа в порядке, я могу найти корень любой заданной функции, но я не могу правильно подсчитать количество итераций. Он всегда равен 5 по максимуму. количество итераций или 1 меньше. Вот код в C++:Подсчет итераций в методе Ньютона-Рафсона

#include <iostream> 
#include <math.h> 
#include <stdlib.h> 

using namespace std; 

double f(float x) 
{ 
    double function1; 
    function1 = exp(x)- 4*pow(x,2); // given function 
    return function1; 
} 

double derivative(float x) 
{ 
    double derivative1; 
    derivative1 = exp(x) - 8*x; // derivative of given function 
    return derivative1; 
} 


void newtonMethod(double x0, double error, int N) 
{ 
    double xNext, xPrevious, root; 
    int k; 

    xPrevious = x0; 

    for(int i = 0; i < N || f(xNext) > error; i++) 
    { 
    xNext = xPrevious - (f(xPrevious)/derivative(xPrevious)); // calculates the next value of x 
    xPrevious = xNext; 
    root = xNext; 
    k = i; 
} 
cout << endl; 
cout << "Iterations made: " << k << endl; 
cout << endl; 
cout << endl; 
cout << endl; 
cout << "Root is: " << root << endl; 


} 

int main() 
{ 
    double x0, error; 
    int N; // max. number of iterations you can do 
    cout << "Enter x0: "; 
    cin >> x0; 
    cout << "Enter the error: "; 
    cin >> error; 
    cout << "Enter the max. number of iterations: "; 
    cin >> N; 
    newtonMethod(x0, error, N); 
} 

И я уверен, что ошибка в этом фрагменте кода:

;i < N || f(xNext) > error; 

Если я запускаю эту программу и положить N = 100, он показывает право но он печатает «Iterations made = 99», но это неправильно. Что мне делать, чтобы напечатать правильное количество итераций? Например, для функции в программе выше (e^x - 4x²) она должна остановиться на четвертой итерации, если я введу x0 = 0.5 и ошибку = 0.0001. Как это исправить?

+0

Компьютер работает в двоичном, а не в десятичном формате. '0,0001' не может быть представлен точно в двоичном формате, поэтому вы можете/не получить точный ответ. - * для функции в программе выше (e^x - 4x²) она должна остановиться на четвертой итерации, если я введу x0 = 0.5 и ошибку = 0.0001. * - В вашей математической книге да, на двоичной вычислительной машине , может быть, может и нет. – PaulMcKenzie

+0

Это не проблема, но код вроде этого 'double f (float x) {double function1; function1 = exp (x) - 4 * pow (x, 2); return function1; } 'слишком многословно. 'double f (floats x) {return exp (x) - 4 * pow (x, 2); } 'делает то же самое и его гораздо легче читать. –

+0

Вы правы в части кода, которая слишком многословна, но дело не в этом. Я написал еще одну программу с методом биссекции, и все прошло отлично. Ввод номера «0.0001» не вызвал непредвиденных ошибок. Я просто не могу понять, что вызывает эту ошибку в методе Ньютона. – Diego

ответ

1

Чтобы ответить на вопрос, который был почему следующий фрагмент кода не работает:

;i < N || f(xNext) > error; 

Это просто потому, что в течение условия цикла, это продолжающуюся условие, которое вычисляется , а не остановка состояние. В приведенном выше фрагменте кода то, что вы говорите компилятору: continue цикл, если либо i < N истинно, либо f(xNext) > error - это правда. Таким образом, при вводе x0 = 0.5, error = 0.0001 и N = 100, что петля делает то, что он не остановится, пока оба критерий не является ложным, т.е., когда я достигаю N и допуск в Р (х) меньше, чем ошибки.

Теперь решение просто поменять оператора || на оператора &&. Как это:

i < N && f(xNext) > error; 

, но затем, ваш xNext не инициализирован. Потому что ваши xNext и xPrevious равны в конце каждого цикла, я просто поставил бы xPrevious. Кроме того, как @Rathat написал, оценивая вашу толерантность в F (X) следует принимать его абсолютное значение, так:

i < N && abs(f(xPrevious)) > error; 

Наконец, следует вывести число итераций, как k + 1, так как вы начали с i = 0.

Это должно решить вашу проблему.

+0

Отличный ответ! – StaticBeagle

0

спасибо за все ответы. Я узнал, что не так, кроме логики состояния for, что @yuxiangDev объяснил очень хорошо. Несмотря на то, что код @RatHat полностью прав, ошибка была в библиотеке math.h, которую я использовал. Я пробовал с <cmath>, и он работал очень хорошо! лол.

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