Método de la secante

El método de la secante implementa la misma idea que el método de Newton usando la aproximación de la secante a la derivada: $$ f’(x) \approx \dfrac{f(p_1)-f(p_0)}{p_1-p_0} $$ para valores cercanos a $x$, $p_0$ y $p_1$.

Diagrama de flujo

Inicio
Inicio
Los datos
ingresados son
adecuados?
Los datos...
   Aproximaciones
  iniciales p0, p1,
error, máx. iteraciones
Aproximaciones...
k=k+1
k=k+1
p=p1-[f(p1)(p1-p0)]/[f(p1)-f(p0)]
p=p1-[f(p1)(p1-p0)]/[f(p1)-...
k<kmax y 
|f(p)|>eps
k<kmax y...
Fin
Fin
No
No
  La raíz de f es p
o no converge 
en kmáx pasos 
La raíz de f es p...
No
No
p0=p1
p1=p
p0=p1...
Viewer does not support full SVG 1.1

Código

El siguiente codigo implementa el método de la secante en C++:

///////////////////////////////////////////////////////////////////////////////////
// Programa para hallar la raíz de una función usando el método de la secante	 //
// El programa requiere un subprograma para las funciones f,	 		 //
// Los puntos iniciales p0 y p1, la tolerancia de error eps, y el máximo número	 //
// de iteraciones permitidas, kmax. 						 //
// El programa muestra una tabla con los valores de x y su evaluación en f.	 //
///////////////////////////////////////////////////////////////////////////////////
# include <iostream>
# include <iomanip>
# include <math.h> // para log x
using namespace std; // Para usar cout


long double f(long double x); // Declara la función f
long double secante(long double p0, long double p1); // Declara la función secante

int main(){
    int kmax;
    long double p0, p1, p, eps;
    cout << "p0, p1, eps, kmax\n";
    cin >> p0 >> p1 >> eps >> kmax;
    // Verificamos que los valores ingresados permitan usar el algoritmo
    while(isnan(f(p0)) || isnan(f(p1))){
        if(isnan(f(p0)))
            cout << "La funcion no esta definida en " << p0;
        else if(isnan(f(p1)))
            cout << "La funcion no esta definida en " << p1;
   		cout << "Ingrese nuevamente las aproximacion iniciales p0, p1\n";
   		cin >> p0 >> p1;
    }
    cout << "Los valores ingresados son \n";
    cout <<  "p0= " << p0 << "p1= " << p1 << " eps = " << eps << "  kmax = " << kmax << endl;
    cout << "Los resultados son\n"; // Muestra el encabezado de la tabla
    cout << "k" << setw(15) << "x" << setw(22) << "f(x)\n";
    cout << 0 << setprecision(10) << setw(20) << p0 << setw(20) << f(p0)
             << endl;
    cout << 1 << setprecision(10) << setw(20) << p1 << setw(20) << f(p1)
             << endl;         
    int k=2;
    p=p0;
    cout.setf(ios::fixed);
    while ((k<=kmax) && (fabs(f(p))>eps)){
        p0=p; 
        p=p1-f(p1)/secante(p0,p1);
        // Muestra los valores de k, p y f(p)
        cout << k << setprecision(10) << setw(20) << p << setw(20) << f(p)
             << endl;
        k++; // incrementa el contador del ciclo        
    };
    if (fabs(f(p))<=eps) cout << "La raiz de f es " << p0; 
    else if (k>kmax) cout << "El metodo no converge en " << kmax << " pasos";
    return 0;
}
// El subprograma para ingresar la función f
long double f(long double x){
    return pow(x,3)-2*pow(x,2)-5;
}

// El subprograma para calcular la secante de dos puntos
long double secante(long double p0, long double p1){
    return (f(p1)-f(p0))/(p1-p0);
}
José Luis León Medina
José Luis León Medina
Investigador Posdoctoral CONAHCYT

Mis intereses en investigación se centran en el campo de la topología algebraica, en particular propiedades homotópicas como la complejidad topológica.