Ecuación diferencial de primer orden

prev.gif (997 bytes)chapter.gif (1105 bytes)home.gif (1232 bytes)next.gif (1211 bytes)

Ecuaciones diferenciales

Introducción

Ecuación diferencial de primer orden

Código fuente


Introducción

Los métodos más sencillos como el de Euler o las mejoras de este procedimiento, tienen dos defectos esenciales: la exactitud es pequeña y los errores crecen sistemáticamente.

El procedimiento de Runge-Kutta se puede programar fácilmente en los ordenadores, y además se emplea mucho en la práctica, debido a la su exactitud relativamente elevada de la solución aproximada de la ecuación diferencial. La justificación del procedimiento de Runge-Kutta no es sencilla, el lector interesado puede consultar algún libro de métodos numéricos de análisis que como el que se cita en la bibliografía.

 

Ecuaciones diferenciales de primer orden

Sea una ecuación diferencial de primer orden, con la condición inicial

Se elige una anchura de paso h, y se calculan cuatro números k1, k2, k3, k4 de acuerdo con el procedimiento esquematizado en la tabla adjunta. Según el procedimiento ordinario de Runge-Kutta, a partir del valor de x en el instante t se determina el valor de x en el instante t+h mediante la fórmula que figura en la última fila de dicha tabla.

 

La jerarquía de clases

Definimos una clase base abstracta denomina RungeKutta, cuya función miembro resolver nos calcule la solución aproximada de la ecuación diferencial x en el instante final tf, cuando le pasamos el estado inicial, es decir, el valor de x0 en el instante inicial t0. La función devuelve el estado del sistema que puede ser la posición del móvil, la intensidad de la corriente eléctrica en un circuito, etc., es decir, el valor de x, en el instante t.

public abstract class RungeKutta {
    public double resolver(double tf, double t0, double x, double h){
        double k1, k2, k3, k4;
        for(double t=t0; t<tf; t+=h){
            k1=h*f(x, t);
            k2=h*f(x+k1/2, t+h/2);
            k3=h*f(x+k2/2, t+h/2);
            k4=h*f(x+k3, t+h);
            x+=(k1+2*k2+2*k3+k4)/6;
        }
        return x;
    }
    abstract public double f(double x, double t);
} 

En la clase Funcion derivada de RungeKutta describimos el modelo físico particular, redefiniendo la función f(x, t). Consideremos la ecuación diferencial que describe la desintegración de una sustancia radioactiva en otra estable.

Donde a es la constante de desintegración radioactiva. A la izquierda tenemos la ecuación diferencial y a la drecha su solución analítica.

La definición de la clase Funcion define la función f(x), tomando el valor de la constante de desintegración a igual a 0.1

public class Funcion extends RungeKutta{
    public double f(double x, double t){
        return (-0.1*x);
    }
}

La llamada a la función resolver se efectuará desde un objeto de la clase derivada Funcion. Se nos pedirá los siguientes datos: el estado inicial, es decir, el número de núcleos x0 en el instante inicial t0, el instante final t en el que queremos calcular el nuevo estado del sistema x, y el paso h para resolver numéricamente la ecuación diferencial. La función miembro resolver devuelve el número de núcleos quedan sin desintegrar en dicho instante t.

        double h=0.5;       //paso

        double x0=5000;     //número inicial de núcleos en el instante t=0
        double t=20.0;      //resolver la e. d. hasta este instante

        double x=new Funcion().resolver(t, 0, x0, h);
        System.out.println("valor aprox. de x "+(int)x);

Comparamos el valor exacto y el valor aproximado, tomando como paso h el valor 0.5, el número inicial de núcleos, 5000, y el instante t, 20. Se obtiene para el resultado aproximado 676 y para el resultado exacto 676, lo que nos confirma la exactitud del procedimiento de Runge-Kutta.

// valor exacto
        x=(int)(x0*Math.exp(-0.1*t));
        System.out.println("valor exacto de x "+(int)x);

 

El código fuente

disco.gif (1035 bytes) RungeKutta.java, Funcion.java, RkApp1java