Skip to main content

Gil

I suck at programming.
I'm not a good student.

Newton-Raphson

13 min read

Método de Newton-Raphson     Gilberto Rogel García    A01630171

--Introducción y antecedentes (para qué sirve y qué resuelve) del método

De las fórmulas para localizar raíces, la fórmula de Newton-Raphson es de las más ampliamente utilizadas. Si el valor inicial para la raíz es xi, entonces se puede trazar una tangente desde el punto [xi, f(xi)] de la curva. Por lo común, el punto donde esta tangente cruza al eje x representa una aproximación mejorada de la raíz.

--En qué consiste el método

El método de Newton-Raphson se deduce a partir de esta interpretación geométrica. Se tiene que la primera derivada en x es equivalente a la pendiente:

            f’(xi)= ( f(xi) -0 ) / ( xi –(xi+1) )

que se arregla para obtener

            xi+1= xi – ( f(xi) / f’(xi) )

--Requisitos previos del método

Una función y su derivada.

--Diagrama de flujo

 

--Criterio de detención del método (error)

El error debe ser proporcional al cuadrado del error anterior. En otras palabras, el número de cifras significativas de precisión aproximadamente se duplica en cada iteración.

--Código fuente

"stdafx.h"

<iostream>

<cmath>

<iomanip>

<Windows.h>

 

 

PRECISION 4

MAX_ITERACIONES 100

INTERVALOS 6

 

using namespace std;

 

void tabula(double a, double b, int intervalos);   

double f(double x);

double f_derivada(double x);

void newton_raphson(double x0, double tolerancia, int max_interaciones);   

 

 

int main()

{

            double a;

            double b;

            double tolerancia;  

            double x0;

 

            cout << setprecision(PRECISION);   

            cout << "\nEscoja el punto inicial adecuado:   x0 = ";

            cin >> x0;

 

           

            cout << "Tolerancia = ";

            cin >> tolerancia;

 

 

            newton_raphson(x0, tolerancia, MAX_ITERACIONES);

 

            cin.get();

            cin.get();

            return 0;

}

 

 

void tabula(double a, double b, int intervalos)

{

            int puntos = intervalos + 1;

 

            double ancho = (b - a) / intervalos;

 

            cout << "\n\tx\t\tf(x) " << endl;

            for (int i = 0; i < puntos; i++) {

                        cout << "\t" << a << "\t\t" << f(a) << endl;

                        a = a + ancho;

            }

}

 

 

double f(double x)

{

           

            return exp(x) - pow(x, 2) + (3 * x) - 2;

}

 

 

double f_derivada(double x)

{

           

            return exp(x) - (2*x) + 3;

}

 

 

void newton_raphson(double x0, double tolerancia, int max_iteraciones)

{

            double x1;

            double error;   

            int iteracion;

            bool converge = true;

 

           

            cout << "\nAproximacion inicial:\n";

            cout << "x0 = " << x0 << "\n"

                        << "f(x0) = " << f(x0) << "\n"

                        << "f'(x0) = " << f_derivada(x0) << endl;

 

            iteracion = 1;

            do {

 

                        if (iteracion > max_iteraciones) {

                                    converge = false;  

                                    break;

 

                        }

                        else {

                                    x1 = x0 - f(x0) / f_derivada(x0);

                                    error = fabs(x1 - x0); 

 

                                                                                                           

                                    cout << "\a";

                                   

                                    cout << "\n\nIteracion #" << iteracion << endl;

                                    cout << "\nx" << iteracion << "     = " << x1 << "\n"

                                                << "f(x" << iteracion << ")  = " << f(x1) << "\n"

                                                << "f'(x" << iteracion << ") = " << f_derivada(x1) << "\n"

                                                << "error  = " << error << endl;

 

                                   

                                    if (error <= tolerancia) {

                                                converge = true;

                                                break;

 

                                               

                                    }

                                    else {

                                                x0 = x1;

                                                iteracion++;

                                    }

                        }

 

            } while (1);

 

 

            cout << "\a";

            if (converge) {

                        cout << "\n\nPara una tolerancia de " << tolerancia << " la RAIZ APROXIMADA de f es = " << x1 << endl;

 

            }

            else {

                        cout << "\n\nSe sobrepasó la máxima cantidad de iteraciones permitidas" << endl;

            }

}

--Pruebas y resultados con casos de éxito, casos de falla y casos frontera

Cuando probamos el método de Newton-Raphson con la función f(x) = tan-1(x) - .3, el método diverge si no tomas un valor inicial cercano a la raíz, en la imagen por ejemplo tome el valor x = 3

 

 

Cuando tomas un valor cercano a la raíz, en este caso x = 1 , el método encuentra la raíz:

 

--Conclusiones

El método de Newton-Raphson algunas veces no converge, sino que oscila. Esto ocurre si no hay raíz real, si la raíz es un punto de inflexión o si el valor inicial esta muy alejado de la raíz buscada  y alguna otra parte de la función “atrapa” la iteración.

Cuando el método de Newton-Raphson converge, se obtienen resultados en relativamente pocas interacciones, ya que para raíces no repetidas este método converge con orden 2 y el error Ei+1 es proporcional al cuadrado del resultado anterior Ei.

 

Referencias:

http://www.bragitoff.com/2015/10/newton-raphson-lab-write-up-with-algorithm-and-flow-chart/

 

http://test.cua.uam.mx/MN/Methods/Raices/NewtonRaphson/NewtonRaphson.php