реализация методов ньютонов - PullRequest
0 голосов
/ 07 октября 2011

Я отправил несколько часов назад вопрос о методе ньютонов, получил ответы и хочу всех поблагодарить, теперь я попытался реализовать сам код

#include <iostream>
#include <math.h>
using namespace std;
#define h powf(10,-7)
#define PI 180
float funct(float x){

    return cos(x)-x;


}
float derivative (float x){
    return (( funct(x+h)-funct(x-h))/(2*h));

}
int main(){
    float tol=.001;
    int N=3;
    float p0=PI/4;
    float p=0;
    int i=1;
    while(i<N){

        p=p0-(float)funct(p0)/derivative(p0);
        if ((p-p0)<tol){
            cout<<p<<endl;
            break;

        }


        i=i+1;
        p0=p;


    if (i>=N){
        cout<<"solution not found "<<endl;
        break;
    }
    }



    return 0;
}

но я записываю вывод "решение не найдено", в книге после трех итераций, когда n = 3, он находит решение, подобное этому .7390851332, поэтому мой вопрос в том, как мало я должен изменить h или как я должен изменить свой код так что, получить правильный ответ?

Ответы [ 3 ]

2 голосов
/ 07 октября 2011

Несколько вещей:

  1. 2 итерации редко бывает достаточно даже в лучшем случае.
  2. Вы должны убедиться, что ваша отправная точка действительно сходится.
  3. Помните о разрушительной отмене функции derivative. Вы вычитаете два числа, которые очень близки друг к другу, поэтому разница будет терять большую точность.

Чтобы расширить последнюю точку, общий метод заключается в уменьшении h при сходстве значения. Но, как я уже упоминал в вашем предыдущем вопросе, этот «корректирующий» метод h существенно (алгебраически) сводится к методу Secant.

1 голос
/ 07 октября 2011

Если вы сделаете h слишком маленьким, то ваша производная будет неточной из-за округления с плавающей запятой. Ваш код выиграл бы от использования двойной точности, а не одинарной, особенно если вы проводите дифференцирование по конечной разнице. С двойной точностью ваше значение h будет в порядке. Если вы придерживаетесь одинарной точности, вам нужно будет использовать большее значение.

Только разрешить 2 итерации кажется довольно ограничительным. Увеличьте N и заставьте вашу программу распечатать количество использованных итераций.

Кроме того, нет необходимости использовать Pow. Просто напишите 1e-7.

1 голос
/ 07 октября 2011

Вы разрешаете только 2 итерации, которых может быть недостаточно, чтобы приблизиться к ответу. Если у вас есть только 1 правильный бит для запуска, вы можете ожидать, что в лучшем случае будет около 4 хороших битов после 2 итераций. Вам нужна точность в 10 бит (0,001 - примерно 1/2 ^ 10), вам нужно разрешить как минимум еще 2 итерации.

Более того, свойство квадратичной сходимости сохраняется только тогда, когда вы близки к решению. Когда вы находитесь дальше, может потребоваться больше времени, чтобы приблизиться к решению.

Оптимальное значение h для вычисления числовой производной с использованием центральных разностей составляет 0,005 * max (1, | x |) для одинарной точности (с плавающей запятой), где | x | является абсолютным значением аргумента, х. Для двойной точности это примерно 5e-6 * max (1, | x |).

...