runge kutta

15
C ´ omo Programar en C++ el M ´ etodo Runge-Kutta de 4to Orden Felipe Gonz´ alez Cataldo www.gnm.cl/fgonzalez 28 de junio de 2011 1. Introducci´ on Este art´ ıculo pretende ser una gu´ ıa para cualquier persona que quiera aprender a implementar en el lenguaje C++ (o haya olvidado c´ omo hacerlo) el m´ etodo de Runge-Kutta para resolver distintos tipos de ecuaciones diferenciales. Tambi´ en proporciona una soluci´ on para quienes necesitan saber la soluci´ on a un problema regido por ecuaciones diferenciales y s´ olo buscan un c´ odigo hecho que resuelva sus ecuaciones sin tener que aprender un m´ etodo para resolverlas, ya que este documento cuenta con ejemplos resueltos, con el c´ odigo adjunto, lo que permite al usuario solamente reemplazar las ecuaciones que necesita resolver sin necesidad de entender el c´ odigo completo. Espero que este art´ ıculo sea de utilidad para la comunidad cient´ ıfica, que comunmente se ve en la necesidad de resolver ecuaciones diferenciales num´ ericamente y no encuentra manuales claros para hacerlo. Este documento pre- tende ser uno. Cualquier sugerencia, no duden en mandar un email a [email protected]. 2. Ecuaciones Diferenciales de Primer Orden Considere una funci´ on diferenciable y : R R que cumple una ecuaci´ on diferencial de primer orden del tipo y 0 (t)= f (y(t),t), (1) donde f es cierta funci´ on que depende de la funci´ on y y del par´ ametro t R. Conociendo el valor de y en alg´ un punto, digamos y(t n ) y n , el m´ etodo de Runge-Kutta permite aproximar, para un τ R dado, el valor de y en t n + τ , que definiremos como y n+1 y(t n + τ ), con un error del orden de τ 5 . El m´ etodo consiste en definir k 1 f (y n ,t n ) (2a) k 2 f y n + τ 2 k 1 ,t n + τ 2 (2b) k 3 f y n + τ 2 k 2 ,t n + τ 2 (2c) k 4 f (y n + τk 3 ,t n + τ ) , (2d) y tomar y n+1 = y n + τ 6 [k 1 +2k 2 +2k 3 + k 4 ] . (3) Podemos realizar recursivamente esta operaci´ on para obtener y(t) en cualquier intervalo [a.b], con a = t n y b = t n + . S´ olo tenemos que iterar N veces. 1

Upload: edwardflores

Post on 30-Sep-2015

43 views

Category:

Documents


0 download

DESCRIPTION

Runge Kutta

TRANSCRIPT

  • Como Programar en C++ el MetodoRunge-Kutta de 4to Orden

    Felipe Gonzalez Cataldowww.gnm.cl/fgonzalez

    28 de junio de 2011

    1. Introduccion

    Este artculo pretende ser una gua para cualquier persona que quiera aprender a implementar en el lenguaje C++(o haya olvidado como hacerlo) el metodo de Runge-Kutta para resolver distintos tipos de ecuaciones diferenciales.Tambien proporciona una solucion para quienes necesitan saber la solucion a un problema regido por ecuacionesdiferenciales y solo buscan un codigo hecho que resuelva sus ecuaciones sin tener que aprender un metodo pararesolverlas, ya que este documento cuenta con ejemplos resueltos, con el codigo adjunto, lo que permite al usuariosolamente reemplazar las ecuaciones que necesita resolver sin necesidad de entender el codigo completo.

    Espero que este artculo sea de utilidad para la comunidad cientfica, que comunmente se ve en la necesidad deresolver ecuaciones diferenciales numericamente y no encuentra manuales claros para hacerlo. Este documento pre-tende ser uno.

    Cualquier sugerencia, no duden en mandar un email a [email protected].

    2. Ecuaciones Diferenciales de Primer Orden

    Considere una funcion diferenciable y : R R que cumple una ecuacion diferencial de primer orden del tipo

    y(t) = f(y(t), t), (1)

    donde f es cierta funcion que depende de la funcion y y del parametro t R. Conociendo el valor de y en algunpunto, digamos y(tn) yn, el metodo de Runge-Kutta permite aproximar, para un R dado, el valor de y entn + , que definiremos como yn+1 y(tn + ), con un error del orden de 5. El metodo consiste en definir

    k1 f (yn, tn) (2a)k2 f

    (yn +

    2k1, tn +

    2

    )(2b)

    k3 f(yn +

    2k2, tn +

    2

    )(2c)

    k4 f (yn + k3, tn + ) , (2d)

    y tomar

    yn+1 = yn +

    6[k1 + 2k2 + 2k3 + k4] . (3)

    Podemos realizar recursivamente esta operacion para obtener y(t) en cualquier intervalo [a.b], con a = tn y b =tn +N . Solo tenemos que iterar N veces.

    1

  • 2.1. Ejemplo: ecuacion diferencial de primer orden

    Consideremos la ecuacion diferencialy(x) = y(x) tan(x) + x2,

    y la condicion inicial y(x0) = y0 para cierto x0 R. En este caso, la funcion f esta dada por

    f(a, b) = a tan(b) + b2,

    para la cual se tienef(y(x), x) = y(x) tan(x) + x2 = y(x),

    como en la ecuacion (1). Eligiendo algun valor para y tenemos:

    k1 = f(y0, x0) = y0 tan(x0) + x20

    k2 = f(y0 +

    2k1, x0 +

    2

    )=(y0 +

    2k1

    )tan

    (x0 +

    2

    )+(x0 +

    2

    )2k3 = f

    (y0 +

    2k2, x0 +

    2

    )=(y0 +

    2k2

    )tan

    (x0 +

    2

    )+(x0 +

    2

    )2k4 = f (y0 + k3, x0 + ) = (y0 + k3) tan (x0 + ) + (x0 + )

    2

    y1 = y0 +

    6[k1 + 2k2 + 2k3 + k4] .

    Ahora que tenemos y1 y(x1), con x1 = x0+ , podemos repetir el proceso y obtener y2 y(x2), donde x2 = x1+ .As, k1 = f(y1, x1), k2 = f(y1 +

    2k1, x1 + /2), etc. Podemos iterar este proceso hasta llegar a algun valor deseado

    de x, por ejemplo x = 25. Para ello basta repetir el proceso n veces, en donde xn sera tal que xn 6 25 < xn + 1.De este modo tendremos el valor de y para todo x {x0, . . . , xn}. Si es lo suficientemente pequeno, podemosconsiderar que hemos obtenido el valor de y(x) para todo x [x0, xn].

    2.2. Programa para ecuacion diferencial de primer orden

    Existen muchas formas de programar el metodo de Runge-Kutta, pero lo esencial es la definicion de k1, k2, k3, k4y la funcion f . A continuacion presento un programa hecho en C++ que resuelve la ecuacion diferencial de primerorden del ejemplo anterior,

    y(x) = y(x) tan(x) + x2,

    para la condicion incial y(x0) = y0, usando el metodo Runge-Kutta. La forma en que el programa esta hecho pre-tende ser lo mas clara posible, separando el metodo de integracion de la ecuacion a resolver y del programa principal.

    El programa consiste en lo siguiente:

    1. Se define la funcion RK4 que toma un x (que al principio vale x0) y un y (que al principio vale y0 = y(x0)).Toma tambien una funcion f de dos parametros, que representa nuestra funcion f(y, x) = y tan(x) + x2, quemas adelante se declara como Ec 1er Orden, y un numero tau que representa el paso de tiempo . Usandoesto, encuentra cuanto vale y(x+tau).

    2. Cada vez que esta funcion es llamada, esta cambia el valor de x por x+tau, y el de y por y(x+tau), es decir,hace avanzar x e y un paso.

    3. En el programa principal simplemente pedimos al usuario las condiciones iniciales (xo e y(xo) = yo), yllamamos a la funcion Ec 1er Orden con un paso de tiempo tau= 0,1 dentro de un ciclo for. El ciclo se hace150 veces, por lo que obtendremos y(x) para los x entre x0 y x0 + 150 . En cada loop, el programa arroja x ey al archivo Solucion-1erOrden.txt.

    2

  • /*********************************************************//* INTEGRADOR DE ECUACIONES DIFERENCIALES *//*********************************************************/// AUTOR: FELIPE GONZALEZ CATALDO, Abril 2011.// www.gnm.cl/fgonzalez#include#include#includeusing namespace std;

    /* Funcion Runge Kutta para ecuaciones de primer orden , como y(x) = f(y,x) */void RK4(double & x, double & y, double f(double,double), double tau){double k1,k2,k3,k4;k1 = f(y,x);k2 = f(y+tau*k1/2.0, x+tau/2.0);k3 = f(y+tau*k2/2.0, x+tau/2.0);k4 = f(y+tau*k3, x+tau);y = y + (tau/6.0)*(k1+2*k2+2*k3+k4);x = x + tau;}

    //----------------- Que ecuacion desea resolver? -----------------//double Ec_1er_Orden(double y, double x){ return y*tan(x)+x*x;}//-----------------------------------------------------------------//

    int main(){cout

  • -2000

    -1500

    -1000

    -500

    0

    500

    1000

    1500

    2000

    0 2 4 6 8 10 12 14 16

    y

    x

    Grafico de la funcion y

    "./Solucion-1erOrden.txt"

    Cuadro 2: Grafico de y(x), solucion a la ecuacion y(x) = y(x) tan(x) + x2, con condicion inicial y(0) = 0.

    Ahora nuestro problema no es la ecuacion (4), sino el conjunto de ecuaciones acopladas en (6). Sobre este conjunto,aplicamos el metodo de Runge-Kutta: al igual que en la seccion anterior, definimos una funcion f , una para cadaecuacion diferencial:

    x1(t) = f1(x1(t), x2(t), t) x2(t), (7a)x2(t) = f2(x1(t), x2(t), t) F (x1(t), x2(t), t). (7b)

    Ahora aplicamos las definiciones en (2) a cada una de las ecuaciones diferenciales de primer orden en (7). Comocada ecuacion diferencial tiene cuatro k-es asociados, necesitaremos cuatro para cada una, ocho en total. Definiendo

    k(i)j como el j-esimo k asociado a fi (j = 1, 2, 3, 4; i = 1, 2) tenemos

    k(1)1 = f1

    (x1

    (n), x2(n), tn

    )(8a)

    k(2)1 = f2

    (x1

    (n), x2(n), tn

    )(8b)

    k(1)2 = f1

    (x1

    (n) +

    2k(1)1 , x2

    (n) +

    2k(2)1 , tn +

    2

    )(8c)

    k(2)2 = f2

    (x1

    (n) +

    2k(1)1 , x2

    (n) +

    2k(2)1 , tn +

    2

    )(8d)

    k(1)3 = f1

    (x1

    (n) +

    2k(1)2 , x2

    (n) +

    2k(2)2 , tn +

    2

    )(8e)

    k(2)3 = f2

    (x1

    (n) +

    2k(1)2 , x2

    (n) +

    2k(2)2 , tn +

    2

    )(8f)

    k(1)4 = f1

    (x1

    (n) + k(1)3 , x2

    (n) + k(2)3 , tn +

    )(8g)

    k(2)4 = f2

    (x1

    (n) + k(1)3 , x2

    (n) + k(2)3 , tn +

    )(8h)

    x1(n+1) = x1

    (n) +

    6

    [k(1)1 + 2k

    (1)2 + 2k

    (1)3 + k

    (1)4

    ](8i)

    x2(n+1) = x2

    (n) +

    6

    [k(2)1 + 2k

    (2)2 + 2k

    (2)3 + k

    (2)4

    ]. (8j)

    4

  • donde x1(n) yn y x2(n) ypn. Es importante notar que el orden en que estas ecuaciones son declaradas: todos los

    k1 deben ser declarados antes de los k2, ya que para obtener k(i)2 , es necesario conocer el valor de todos los k

    (i)1 . Lo

    mismo para k3 y k4. Es un error comun en la implementacion del codigo definir primero los cuatro k asociados

    a f1 (k(1)1 , k

    (1)2 , k

    (1)3 , k

    (1)4 ) y luego los k asociados a f2. Para resumir estos resultados, definimos

    x(t) (x1(t), x2(t)) (9a)f(x, t) (f1(x, t), f2(x, t)) . (9b)

    Con esto,

    x(t) = (x1(t), x2(t))

    = (x2(t), F (x1(t), x2(t), t))

    = (f1(x1(t), x2(t), t), f2(x1(t), x2(t), t))

    = (f1(x(t), t), f2(x(t), t))

    = f (x(t), t) ,

    es decir, UNA ecuacion diferencial (vectorial) de primer orden. Estas definiciones permiten que x guarde las posi-ciones y velocidades (y, y) = (x1, x2), mientras que f guarda las velocidades y aceleraciones (y, y) = (x1, x

    2).

    Ahora, definiendo k1 (k(1)1 , k(2)1 ), k2 (k(1)2 , k(2)2 ), k3 (k(1)3 , k(2)3 ), k4 (k(1)4 , k(2)4 ), las ecuaciones en (8) sereducen a

    k1 = f (xn, tn) (10a)

    k2 = f(xn +

    2k1, t+

    2

    )(10b)

    k3 = f(xn +

    2k2, t+

    2

    )(10c)

    k4 = f (xn + k3, t+ ) (10d)

    xn+1 = xn +

    6[k1 + 2k2 + 2k3 + k4], (10e)

    Con esto tenemos, basicamente, el mismo set que en (2). Lo unico que cambia en el metodo es que ahora tanto loskj como los xn son vectores con 2 coordenadas escalares.

    5

  • 3.1. Ejemplo: ecuacion diferencial de segundo orden

    Consideremos la ecuacion diferencial que rige el movimiento angular de un pendulo simple:

    (t) +g

    Lsin((t)) = 0,

    donde g es la aceleracion de gravedad y L el largo del pendulo. Consideremos las condiciones inciales (t0) 0 y(t0) 0 para cierto t0 R. En este caso, las funciones f estan dadas por

    f1(a, b, c) = b, f2(a, b, c) = gL

    sin(a),

    para las cuales se tiene

    f1((t), (t), t) = (t), f2((t), (t), t) = g

    Lsin((t)) = (t),

    como en la ecuacion (4). Eligiendo algun valor para y tenemos:

    k(1)1 = f1

    (x1

    (0), x2(0), t0

    )= x2

    (0)

    k(2)1 = f2

    (x1

    (0), x2(0), t0

    )= g

    Lsin(x1

    (0))

    k(1)2 = f1

    (x1

    (0) +

    2k(1)1 , x2

    (0) +

    2k(2)1 , t0 +

    2

    )= x2

    (0) +

    2k(2)1

    k(2)2 = f2

    (x1

    (0) +

    2k(1)1 , x2

    (0) +

    2k(2)1 , t0 +

    2

    )= g

    Lsin(x1

    (0) +

    2k(1)1

    )k(1)3 = f1

    (x1

    (0) +

    2k(1)2 , x2

    (0) +

    2k(2)2 , t0 +

    2

    )= x2

    (0) +

    2k(2)2

    k(2)3 = f2

    (x1

    (0) +

    2k(1)2 , x2

    (0) +

    2k(2)2 , t0 +

    2

    )= g

    Lsin(x1

    (0) +

    2k(1)2

    )k(1)4 = f1

    (x1

    (0) + k(1)3 , x2

    (0) + k(2)3 , t0 +

    )= x2

    (0) + k(2)3

    k(2)4 = f2

    (x1

    (0) + k(1)3 , x2

    (0) + k(2)3 , t0 +

    )= g

    Lsin(x1

    (0) + k(1)3

    )x1

    (1) = x1(0) +

    6

    [k(1)1 + 2k

    (1)2 + 2k

    (1)3 + k

    (1)4

    ]x2

    (1) = x2(0) +

    6

    [k(2)1 + 2k

    (2)2 + 2k

    (2)3 + k

    (2)4

    ].

    Ahora que tenemos x1(1) = 1 (t1), con t1 = t0 + , podemos repetir el proceso y obtener x1(2) = 2 (t2),

    donde t2 = t1 + . As, k(1)1 = f1(x1

    (1), x2(1), t1), k

    (1)2 = f1(x1

    (1) + 2k(1)1 , x2

    (1) + 2k(2)1 , t1 + /2), etc. Podemos iterar

    este proceso hasta llegar a algun valor deseado de t.

    6

  • 3.2. Programa para ecuacion diferencial de segundo orden

    Existen muchas formas de programar el metodo de Runge-Kutta, pero lo esencial es la definicion de k1, k2, k3, k4y la funcion f . A continuacion presento un programa hecho en C++ que resuelve la ecuacion diferencial de segundoorden del ejemplo anterior,

    (t) +g

    Lsin((t)) = 0,

    para g = 9,8 m/s2 y L = 1 m, con las condiciones iniciales (t0) = 0 y (t0) = 0 usando el metodo Runge-Kutta.

    La forma en que el programa esta hecho pretende ser lo mas clara posible, separando el metodo de integracion dela ecuacion a resolver y del programa principal.

    /****************************************************************//* INTEGRADOR DE ECUACIONES DIFERENCIALES *//****************************************************************/// AUTOR: FELIPE GONZALEZ CATALDO, Marzo 2011.// www.gnm.cl/fgonzalez#include#include#includeusing namespace std;

    /* Funcion Runge Kutta para ecuaciones de segundo orden , como y(x) = f(y,y,x) */double f1(double x1, double x2, double t){ return x2;}void RK4(double & t, double & x1, double & x2, double f2(double,double,double), double tau){double k1[2],k2[2],k3[2],k4[2];k1[0] = f1(x1,x2,t);k1[1] = f2(x1,x2,t);k2[0] = f1(x1+tau*k1[0]/2.0, x2+tau*k1[1]/2.0, t+tau/2.0);k2[1] = f2(x1+tau*k1[0]/2.0, x2+tau*k1[1]/2.0, t+tau/2.0);k3[0] = f1(x1+tau*k2[0]/2.0, x2+tau*k2[1]/2.0, t+tau/2.0);k3[1] = f2(x1+tau*k2[0]/2.0, x2+tau*k2[1]/2.0, t+tau/2.0);k4[0] = f1(x1+tau*k3[0], x2+tau*k3[1], t+tau);k4[1] = f2(x1+tau*k3[0], x2+tau*k3[1], t+tau);x1 = x1 + (tau/6.0)*(k1[0]+2*k2[0]+2*k3[0]+k4[0]);x2 = x2 + (tau/6.0)*(k1[1]+2*k2[1]+2*k3[1]+k4[1]);t = t + tau;}

    //----------------- Que ecuacion desea resolver? -------------------//double Ec_2o_Orden(double y, double yp,double x){ return -9.8*sin(y);}//-------------------------------------------------------------------//

    int main(){cout

  • 2. Toma tambien una funcion f2 de tres parametros, que representa nuestra funcion f2(x1, x2, t) = gL sin(x1),que mas adelante se declara como Ec 2o Orden, y un numero tau que representa el paso de tiempo .

    3. Usando esto, encuentra cuanto vale (t+tau) y (t+tau).

    4. Cada vez que esta funcion es llamada, esta cambia el valor de t por t+tau, el de x1 por (t+tau) y el de x2por (t+tau), es decir, hace avanzar t, x1 y x2 un paso.

    5. En el programa principal simplemente pedimos al usuario las condiciones iniciales (xo, (xo) = yo y (xo) =ypo), y llamamos a la funcion Ec 2o Orden con un paso de tiempo tau= 0,01 dentro de un ciclo for. El ciclose hace 2000 veces, por lo que obtendremos (t) para los t entre t0 y t0 + 2000 .

    6. En cada loop, el programa arroja x e y (que representan a t y (t), respectivamente) al archivo Solucion-2oOrden.txt.

    3.3. Grafico de la solucion

    -3

    -2

    -1

    0

    1

    2

    3

    0 2 4 6 8 10 12 14 16 18 20

    t

    Grafico de la funcion

    "./Solucion-2oOrden.txt"

    Cuadro 4: Grafico de (t), solucion a la ecuacion (t) = gL sin((t), con condiciones iniciales (0) = 1, (0) = 5,5.

    8

  • 0

    5

    10

    15

    20

    25

    30

    35

    40

    45

    0 2 4 6 8 10 12 14 16 18 20

    t

    Grafico de la funcion

    "./Solucion-2oOrden.txt"

    Cuadro 5: Grafico de )t), solucion a la ecuacion (t) = gL sin((t), con condiciones iniciales (0) = 1, (0) = 5,5.

    4. Ecuaciones Diferenciales Vectoriales de Primer Orden

    Considere una funcion diferenciable y : R Rm,y(t) y(t) = (y1(t), y2(t), . . . , ym(t)),

    que cumple una ecuacion diferencial de primer orden del tipo

    y(t) = f(y(t), t) (f1(y(t), t), f2(y(t), t), . . . , fm(y(t), t)), (11)donde f : Rm R Rm es un campo vectorial que depende de la funcion y y el parametro t R. Conociendoel valor de y en algun punto t = tn, digamos y(tn) yn = (yn(1), yn(2), . . . , yn(m)), el metodo de Runge-Kuttapermite aproximar, para un R dado, el valor de y en tn + , que definiremos como yn+1 y(tn + ), con unerror del orden de 5.

    Separemos primero la ecuacion diferencial (11) por componentes:

    y1(t) = f1(y(t), t) = f1(y1(t), y2(t), . . . , ym(t), t) (12a)y2(t) = f2(y(t), t) = f2(y1(t), y2(t), . . . , ym(t), t) (12b)

    ...

    ym(t) = fm(y(t), t) = fm(y1(t), y2(t), . . . , ym(t), t) (12c)

    Ahora aplicamos las definiciones en (2) a cada una de las ecuaciones diferenciales de primer orden en (12). Comocada ecuacion diferencial tiene cuatro k-es asociados, necesitaremos cuatro para cada una, 4m en total. Definiendo

    k(i)j como el j-esimo k asociado a fi (j = 1, 2, 3, 4; i = 1, 2, . . . ,m) tenemos

    k(i)1 = fi

    (yn

    (1), yn(2), . . . , yn

    (m), tn

    )(13a)

    k(i)2 = fi

    (yn

    (1) +

    2k(1)1 , yn

    (2) +

    2k(2)1 , . . . , yn

    (m) +

    2k(m)1 , tn +

    2

    )(13b)

    k(i)3 = fi

    (yn

    (1) +

    2k(1)2 , yn

    (2) +

    2k(2)2 , . . . , yn

    (m) +

    2k(m)2 , tn +

    2

    )(13c)

    k(i)4 = fi

    (yn

    (1) + k(1)3 , yn

    (2) + k(2)3 , . . . , yn

    (m) + k(m)3 , tn +

    )(13d)

    yn+1(i) = yn

    (i) +

    6

    [k(i)1 + 2k

    (i)2 + 2k

    (i)3 + k

    (i)4

    ]. (13e)

    9

  • De este modo, hemos encontrado yn+1 = (y1(n+1), y2

    (n+1), . . . , ym(n+1)). Es importante notar que el orden en que

    estas ecuaciones son declaradas: todos los k1 deben ser declarados antes de los k2, ya que para obtener k(i)2 , es

    necesario conocer el valor de todos los k(i)1 . Lo mismo para k3 y k4. Es un error comun en la implementacion del

    codigo definir primero los cuatro k asociados a f1 (k(1)1 , k

    (1)2 , k

    (1)3 , k

    (1)4 ) y luego los k asociados a f2, f3, etc.

    Para resumir estos resultados, definimos k1 (k(1)1 , k(2)1 , . . . , k(m)1 ), k2 (k(1)2 , k(2)2 , . . . , k(m)2 ), k3 (k(1)3 , k(2)3 , . . . , k(m)3 ),k4 (k(1)4 , k(2)4 , . . . , k(m)4 ), las ecuaciones en (13) se reducen a

    k1 = f (yn, tn) (14a)

    k2 = f(yn +

    2k1, t+

    2

    )(14b)

    k3 = f(yn +

    2k2, t+

    2

    )(14c)

    k4 = f (yn + k3, t+ ) (14d)

    yn+1 = yn +

    6[k1 + 2k2 + 2k3 + k4], (14e)

    Con esto tenemos, basicamente, el mismo set que en (2). Lo unico que cambia en el metodo es que ahora tanto loskj como los yn son vectores con m coordenadas escalares.

    10

  • 4.1. Ejemplo: ecuacion diferencial vectorial de primer orden

    Consideremos la ecuacion diferencialr(t) = B(t) r(t),

    donde B : R R3, y r : R R3. Consideremos la condicion incial r(t0) r0 = (r0(1), r0(2), r0(3)) para ciertot0 R. Escribamos la ecuacion diferencial por componentes:

    r1(t) = B2(t)r3(t)B3(t)r2(t)r2(t) = B3(t)r1(t)B1(t)r3(t)r3(t) = B1(t)r2(t)B2(t)r1(t)

    En este caso, la funcion f esta dada por f((a, b, c), t) = B(t) (a, b, c), cuyas componentes sonf1(a, b, c, t) = B2(t)cB3(t)b,f2(a, b, c, t) = B3(t)aB1(t)c,f3(a, b, c, t) = B1(t)bB2(t)a,

    para las cuales se tienef1(r1(t), r2(t), r3(t), t) = B2(t)r3(t)B3(t)r2(t) = r1(t),f2(r1(t), r2(t), r3(t), t) = B3(t)r1(t)B1(t)r3(t) = r2(t),f3(r1(t), r2(t), r3(t), t) = B1(t)r2(t)B2(t)r1(t) = r3(t).

    Eligiendo algun valor para y tenemos que k1 = f (r0, t0), es decir,

    k(1)1 = f1

    (r0

    (1), r0(2), r0

    (3), t0

    )= B2(t)r0

    (3) B3(t)r0(2),

    k(2)1 = f2

    (r0

    (1), r0(2), r0

    (3), t0

    )= B3(t)r0

    (1) B1(t)r0(3),

    k(3)1 = f3

    (r0

    (1), r0(2), r0

    (3), t0

    )= B1(t)r0

    (2) B2(t)r0(1).Para k2 = f

    (r0 +

    2k1, t+

    2

    )se tiene

    k(1)2 = f1

    (r0

    (1) +

    2k(1)1 , r0

    (2) +

    2k(2)1 , r0

    (3) +

    2k(3)1 , t0 +

    2

    )= B2(t)

    (r0

    (3) +

    2k(3)1

    )B3(t)

    (r0

    (2) +

    2k(2)1

    ),

    k(2)2 = f2

    (r0

    (1) +

    2k(1)1 , r0

    (2) +

    2k(2)1 , r0

    (3) +

    2k(3)1 , t0 +

    2

    )= B3(t)

    (r0

    (1) +

    2k(1)1

    )B1(t)

    (r0

    (3) +

    2k(3)1

    ),

    k(3)2 = f3

    (r0

    (1) +

    2k(1)1 , r0

    (2) +

    2k(2)1 , r0

    (3) +

    2k(3)1 , t0 +

    2

    )= B1(t)

    (r0

    (2) +

    2k(2)1

    )B2(t)

    (r0

    (1) +

    2k(1)1

    ).

    Finalmente, k3 = f(r0 +

    2k2, t+

    2

    ), es decir,

    k(1)3 = f1

    (r0

    (1) +

    2k(1)2 , r0

    (2) +

    2k(2)2 , r0

    (3) +

    2k(3)2 , tn +

    2

    )= B2(t)

    (r0

    (3) +

    2k(3)2

    )B3(t)

    (r0

    (2) +

    2k(2)2

    ),

    k(2)3 = f2

    (r0

    (1) +

    2k(1)2 , r0

    (2) +

    2k(2)2 , r0

    (3) +

    2k(3)2 , tn +

    2

    )= B3(t)

    (r0

    (1) +

    2k(1)2

    )B1(t)

    (r0

    (3) +

    2k(3)2

    ),

    k(3)3 = f3

    (r0

    (1) +

    2k(1)2 , r0

    (2) +

    2k(2)2 , r0

    (3) +

    2k(3)2 , tn +

    2

    )= B1(t)

    (r0

    (2) +

    2k(2)2

    )B2(t)

    (r0

    (1) +

    2k(1)2

    ),

    y k4 = f (yn + k3, t+ ), luego

    k(1)4 = f1

    (r0

    (1) + k(1)3 , r0

    (2) + k(2)3 , r0

    (3) + k(3)3 , tn +

    )= B2(t)

    (r0

    (3) + k(3)3

    )B3(t)

    (r0

    (2) + k(2)3

    ),

    k(2)4 = f2

    (r0

    (1) + k(1)3 , r0

    (2) + k(2)3 , r0

    (3) + k(3)3 , tn +

    )= B3(t)

    (r0

    (1) + k(1)3

    )B1(t)

    (r0

    (3) + k(3)3

    ),

    k(3)4 = f3

    (r0

    (1) + k(1)3 , r0

    (2) + k(2)3 , r0

    (3) + k(3)3 , tn +

    )= B1(t)

    (r0

    (2) + k(2)3

    )B2(t)

    (r0

    (1) + k(1)3

    ).

    Con esto, r1 = r0 +6 [k1 + 2k2 + 2k3 + k4], es decir,

    r1(1) = r0

    (1) +

    6

    [k(1)1 + 2k

    (1)2 + 2k

    (1)3 + k

    (1)4

    ]r1

    (2) = r0(2) +

    6

    [k(2)1 + 2k

    (2)2 + 2k

    (2)3 + k

    (2)4

    ]r1

    (3) = r0(3) +

    6

    [k(3)1 + 2k

    (3)2 + 2k

    (3)3 + k

    (3)4

    ]11

  • Ahora que tenemos r1 = (r1(1), r1

    (2), r1(3)) r(t1), con t1 = t0 + , podemos repetir el proceso y obtener r2 =

    (r2(1), r2

    (2), r2(3)) r(t2), donde t2 = t1 + . As,

    k(i)1 = fi

    (r1

    (1), r1(2), r1

    (3), t1

    ),

    k(i)2 = fi

    (r1

    (1) +

    2k(1)1 , r1

    (2) +

    2k(2)1 , r1

    (3) +

    2k(3)1 , t1 +

    2

    ),

    etc. Podemos iterar este proceso hasta llegar a algun valor deseado de t.

    4.2. Programa para ecuacion diferencial vectorial de primer orden

    Existen muchas formas de programar el metodo de Runge-Kutta, pero lo esencial es la definicion de k1, k2, k3, k4 yla funcion f . A continuacion presento un programa hecho en C++ que resuelve la ecuacion diferencial vectorial deprimer orden del ejemplo anterior,

    r(t) = B(t) r(t),para distintos B(t) = B1(t)x +B2(t)y +B3(t)z, con la condicion inicial r(t0) = r0 usando el metodo Runge-Kutta.La forma en que el programa esta hecho pretende ser lo mas clara posible, separando el metodo de integracion dela ecuacion a resolver y del programa principal.

    El programa consiste en lo siguiente:

    1. Mediante typedef se define el elemento Funcion como un puntero a una funcion tipo double de 4 argumentostipo double. Esto permite crear un nuevo tipo de variable Funcion que nos permite declarar funciones de 4argumentos o arreglos de las mismas.

    2. Se define la funcion RK4 que toma un t (que al principio vale t0) y un arreglo y[] que al principio vale

    y0 = (y(1)0 , y

    (2)0 , y

    (3)0 ), un arreglo de funciones f[] de 4 argumentos, que representa nuestra funcion

    f(a, b, c, t) = (f1(a, b, c, d), f2(a, b, c, d), f3(a, b, c, d)),

    que es un arreglo de 3 funciones de 4 variables. Esta funcion es declarada mas adelante como Ec 1er Orden.Por ultimo, toma un numero tau que representa el paso de tiempo .

    3. Al llamar a esta funcion (Ec 1er Orden) en el programa, con un tau, un t y un y[] dados, la funcion encuentracuanto vale r(t+tau).

    4. Cada vez que esta funcion es llamada, esta cambia el valor de t por t+tau, el de x1 por (t+tau) y el de x2por (t+tau), es decir, hace avanzar t, x1 y x2 un paso.

    5. En el programa principal simplemente pedimos al usuario las condiciones iniciales (xo, (xo) = yo y (xo) =ypo), y llamamos a la funcion Ec 2o Orden con un paso de tiempo tau= 0,01 dentro de un ciclo for. El ciclose hace 2000 veces, por lo que obtendremos (t) para los t entre t0 y t0 + 2000 .

    6. En cada loop, el programa arroja x e y (que representan a t y (t), respectivamente) al archivo Solucion-2oOrden.txt.

    12

  • /*********************************************************//* INTEGRADOR DE ECUACIONES DIFERENCIALES *//*********************************************************/// AUTOR: FELIPE GONZALEZ CATALDO, Mayo 2011.// www.gnm.cl/fgonzalez#include#include#includeusing namespace std;

    // Funcion de 4 variables: Puntero a una funcion de 4 argumentos double, que retorna un doubletypedef double (*Funcion) (double a, double b, double c, double t);

    /* Funcion Runge Kutta para ecuaciones de primer orden , como y(x) = f(y,x) */void RK4(double & t, double y[], Funcion f[], double tau){double k1[] = {f[0](y[0],y[1],y[2],t),f[1](y[0],y[1],y[2],t),f[2](y[0],y[1],y[2],t) };double k2[] = {f[0](y[0]+tau*k1[0]/2.0,y[1]+tau*k1[1]/2.0,y[2]+tau*k1[2]/2.0,t+tau/2.0),f[1](y[0]+tau*k1[0]/2.0,y[1]+tau*k1[1]/2.0,y[2]+tau*k1[2]/2.0,t+tau/2.0),f[2](y[0]+tau*k1[0]/2.0,y[1]+tau*k1[1]/2.0,y[2]+tau*k1[2]/2.0,t+tau/2.0) };double k3[] = {f[0](y[0]+tau*k2[0]/2.0,y[1]+tau*k2[1]/2.0,y[2]+tau*k2[2]/2.0,t+tau/2.0),f[1](y[0]+tau*k2[0]/2.0,y[1]+tau*k2[1]/2.0,y[2]+tau*k2[2]/2.0,t+tau/2.0),f[2](y[0]+tau*k2[0]/2.0,y[1]+tau*k2[1]/2.0,y[2]+tau*k2[2]/2.0,t+tau/2.0) };double k4[] = {f[0](y[0]+tau*k3[0],y[1]+tau*k3[1],y[2]+tau*k3[2],t+tau),f[1](y[0]+tau*k3[0],y[1]+tau*k3[1],y[2]+tau*k3[2],t+tau),f[2](y[0]+tau*k3[0],y[1]+tau*k3[1],y[2]+tau*k3[2],t+tau) };

    for (int q=0; q

  • 4.3. Grafico de la solucion

    -1.5-1

    -0.5 0

    0.5 1

    1.5 -2 -1.5-1 -0.5

    0 0.5 1 1.5

    2

    -2-1.5

    -1-0.5

    0 0.5

    1 1.5

    2

    z(t)

    Grafico de la funcion r(t)

    ./Solucion-1erOrdenN.txt u 2:3:4

    x(t)

    y(t)

    z(t)

    -1.5-1

    -0.5 0

    0.5 1

    1.5-2

    -1.5

    -1

    -0.5

    0

    0.5

    1

    1.5

    2

    -2-1.5-1-0.5 0 0.5 1 1.5 2z(t)

    Grafico de la funcion r(t)

    ./Solucion-1erOrdenN.txt u 2:3:4

    x(t)

    y(t)

    z(t)

    -1.5 -1 -0.5 0 0.5 1 1.5-2-1.5-1-0.5 0 0.5 1 1.5 2

    -2-1.5

    -1-0.5

    0 0.5

    1 1.5

    2

    z(t)

    Grafico de la funcion r(t)

    ./Solucion-1erOrdenN.txt u 2:3:4

    x(t) y(t)

    z(t)

    -1.5-1-0.5 0 0.5 1 1.5-2 -1.5 -1 -0.5 0 0.5 1 1.5 2

    -2-1.5

    -1-0.5

    0 0.5

    1 1.5

    2

    z(t)

    Grafico de la funcion r(t)

    ./Solucion-1erOrdenN.txt u 2:3:4

    x(t)y(t)

    z(t)

    Cuadro 7: Grafico de la trayectoria r(t), solucion a la ecuacion r(t) = B(t) r(t), con B(t) = (0, cos t, sin t) ycondicion inicial r(0) = (1, 1, 1).

    14

  • 5. Ecuaciones Diferenciales Vectoriales de Segundo Orden

    PRONTO...Ademas, en un futuro proximo: N Ecuaciones Diferenciales vectoriales de segundo orden (el problema de N cuerpos)

    15

    IntroduccinEcuaciones Diferenciales de Primer OrdenEjemplo: ecuacin diferencial de primer ordenPrograma para ecuacin diferencial de primer ordenGrfico de la solucin

    Ecuaciones Diferenciales de Segundo OrdenEjemplo: ecuacin diferencial de segundo ordenPrograma para ecuacin diferencial de segundo ordenGrfico de la solucin

    Ecuaciones Diferenciales Vectoriales de Primer OrdenEjemplo: ecuacin diferencial vectorial de primer ordenPrograma para ecuacin diferencial vectorial de primer ordenGrfico de la solucin

    Ecuaciones Diferenciales Vectoriales de Segundo Orden