Análisis Numéricos.
Condições de conclusão
2. Método de Newton Raphson
2.1. Código Fuente
//Autor Desconocido
#include <iostream>
using namespace std;
//Seccion de #includes
#include <iostream>
#include <iomanip> // setprecision
#include <cmath>
//Seccion constantes simbolicas
#define PRECISION 10 //Cantidad maxima de decimales
#define MAX_ITERACIONES 100 //Cantidad maxima de iteraciones
#define INTERVALOS 6 //Intervalos posibles
//Prototipos
void tabula(double a, double b, int intervalos); // Muestra un # tabulado de intervalos
double f(double x); // Retorna el valor de la funcion evaluada en x
double f_derivada(double x); // Retorna la derivada de la funcion evaluada en x
int main()
{
double a;
double b;
double tolerancia; // Tolerancia
double x0; // Primera aproximacion
double x1; // Siguiente aproximacion
double error; // Diferencia entre dos aproximaciones sucesivas: x1 - x0
int iteracion; // # de iteraciones
bool converge = true;
cout << setprecision(PRECISION); // Se establece la precision
cout << "\nCalculo de las raices de una funcion aplicando el metodo de Newton - Raphson\n";
cout << "\nIngrese el intervalo inicial [a,b]:" << endl;
// Se ingresa el intervalo
cout << "\na = ";
cin >> a;
cout << "b = ";
cin >> b;
// Se tabulan los valores de f para INTERVALOS intervalos
tabula(a, b, INTERVALOS);
// Se pide elegir una aproximaci�n inicial
cout << "\nEscoja el punto inicial adecuado: x0 = ";
cin >> x0;
// Se pide ingresar la tolerancia
cout << "Tolerancia = ";
cin >> tolerancia;
// Iteraciones
// Se imprimen los valores de la primera aproximacion
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; // Se sobrepas� la m�xima cantidad de iteraciones permitidas
break;
} else {
x1 = x0 - f(x0) / f_derivada(x0); // C�lculo de la siguiente aproximaci�n
error = fabs(x1 - x0); // El error es la diferencia entre dos aproximaciones sucesivas
// Se imprimen los valores de la siguiente aproximaci�n x1, f(x1), f_derivada(x1), error
cout << "\nIteracion #" << iteracion << endl;
cout << "x" << iteracion << " = " << x1 << "\n"
<< "f(x" << iteracion << ") = " << f(x1) << "\n"
<< "f'(x" << iteracion << ") = " << f_derivada(x1) << "\n"
<< "error = " << error << endl;
// La diferencia entre dos aproximaciones sucesivas es tambi�n conocida como error.
// La condici�n de terminaci�n consiste en que que el error debe ser <= que la tolerancia dada
// Si se cumple la condici�n de terminaci�n, se ha encontrado la raiz aproximada buscada.
if (error <= tolerancia) { // Condici�n de terminaci�n
converge = true;
break;
// Si no se cumple el criterio de terminaci�n, se pasa a la siguiente iteraci�n
} else {
x0 = x1;
iteracion++;
}
}
} while (1);
// Respuesta final
if (converge) {
cout << "\n\nPara una tolerancia de " << tolerancia << " la raiz de f es: " << x1 << endl;
} else {
cout << "\n\nSe sobrepas� la m�xima cantidad de iteraciones permitidas" << endl;
}
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;
}
}
//Esta es la funci�n de nuestro ejemplo
double f(double x)
{
return x * exp(cos(x)) / 1.5 - 1;
//return exp(-x) + 3 * x - 3;
}
//Esta es la derivada de la funci�n de nuestro ejemplo
double f_derivada(double x)
{
return exp(cos(x)) * (1 - x * sin(x)) / 1.5;
//return -1 * exp(-x) + 3;
}
De observar la gráfica en los entornos cercanos al origen de eje x e y vemos que x1=2 e x2=4 son puntos en los que se observa que la curva tiene una raíz ( y=0) . La ejecución de esto se vería:
Podemos ver los cambios de signos en los distintos valores de f(x), esto nos dá una pista de los valores de x que podemos proponer para iniciar otra iteración con puntos cercanos a la raiz.
Vamos a tomar 3.3 como inicio para un nuevo cálculo, la salida sería:
Lo que se indica como error en la iteración, es la diferencia respecto del cálculo anterior. Vamos a probar con otros valores que permitan realizar mas iteraciones. Vemos que hay otra raiz entre 0 y 1 coma algo...
Nuevamente podemos ver que los signos de f(x) cambian para x1= 0.5 y x2=0.75 , así que ponemos como punto de inicio, 0.5 y elegimos una precisión de 0.01
En este caso luego de 3 iteraciones se obtiene la tolerancia deseada.