You are on page 1of 11

Programación Para Ciencia y Tecnología (PPCT)

Práctica 5: Ecuaciones Diferenciales


Ordinarias

Curso 2022/23

1. Objetivos
El objetivo de esta práctica es el de implementar y aplicar métodos para resolver dos
tipos de problemas diferentes para ecuaciones diferenciales ordinarias:
Problemas de valores iniciales.
Problemas de contorno.

2. Problemas de valores iniciales


Consideramos en esta sección problemas de valores iniciales, expresados como:
( ′
y (x) = f (x, y(x)), x ∈ [a, b]
y(a) = α

donde f : [a, b] × Rn → Rn , y(x) ∈ Rn , α ∈ Rn .

2.1. Método de Runge-Kutta de orden 4


El Algoritmo 1 corresponde al método de Runge-Kutta de orden 4 para sistemas de n
ecuaciones diferenciales. Al implementarlo en Python habrá que tener en cuenta algunos
aspectos:
Al inicio, habrá que obtener el valor de n, que será igual al número de elementos del
vector alfa, e inicializar x e y como arrays de las dimensiones adecuadas. Podemos usar
la función numpy.zeros para ello. Ejemplo de uso de numpy.zeros:

1
Algoritmo 1: rungekutta4
Entrada: f : función que define el sistema y ′ = f (x, y) de n ecuaciones diferenciales.
a: valor inicial de x, en el cual conocemos la solución.
b: valor final de x.
alfa: vector, de n elementos, con la solución en el extremo inicial (a).
m: número de subintervalos en los que dividimos el intervalo entre a y b.
Resultado: x: vector de abscisas, de longitud m + 1, donde se obtiene la solución.
y: matriz de resultados, de (m + 1) filas y n columnas.
b−a
1 h=
m
2 x1 = a
3 y1 = alfa
4 para i ∈ rango(m) hacer
5 xi+1 = a + ih
6 k1 = f (xi , yi )
7 k2 = f (xi + h2 , yi + h2 k1)
8 k3 = f (xi + h2 , yi + h2 k2)
9 k4 = f (xi + h, yi + h k3)
10 yi+1 = yi + h6 (k1 + 2 k2 + 2 k3 + k4)
11 fin para

>>> v=np.zeros(3) # v será un vector de 3 elementos


>>> M=np.zeros((5,3)) # M será una matriz de 5 filas y 3 columnas

El algoritmo supone que los índices de x e y empiezan en 1, pero en Python empezarán


en cero. Eso solo afecta a las líneas 2, 3 y 5 del algoritmo. En el caso de la línea 5, ten
en cuenta que, si los índices empiezan en cero, tendremos:

x1 = a + h 



x2 = a + 2h ⇒ xi+1 =?
..



. 

Podemos usar 4 variables distintas para k1, k2, k3 y k4 (en vez de un único array).
Cada una de estas variables será un array.

El algoritmo usa la notación y1 , y2 , y3 ,... para referirse a cada una de las filas de la
matriz y. En Python, nos referimos a cada fila del array y como y[0], y[1], y[2]... (o
bien y[0,:], y[1,:], y[2,:]...)

2
Ejercicio 1.
Implementa en Python la función rungekutta4, correspondiente al Algoritmo 1, para
resolver sistemas de ecuaciones diferenciales de primer orden mediante el método de
Runga-Kutta de orden 4.

A continuación aplicaremos la función anterior para resolver distintos problemas. Para


ello, habrá que definir la función f (x, y) correspondiente al sistema de ecuaciones diferenciales
y ′ = f (x, y). Por ejemplo, si tenemos:
y ′ − 2y = x + 3
donde el sistema está formado por una sola ecuación, en primer lugar hay que expresar la
ecuación dejando y ′ aislada:
y ′ = x + 2y + 3
y a continuación definiríamos en Python una función f (x, y) = x + 2y + 3. Por ejemplo:
>>> def f(x,y): return x+2*y+3
Por otra parte, si tenemos un sistema, como:
y1′ − 2y1 = x
)

y2′ − 0.6y1 − 3y2 = x2


lo ponemos en primer lugar en la forma:
y1′ = 2y1 + x
)

y2′ = 0.6y1 + 3y2 + x2


La función correspondiente será:
" #
2y1 + x
f (x, y) =
0.6y1 + 3y2 + x2
Podemos definirla en Python de esta manera:
>>> def f(x,y): return np.array([2*y[0]+x, 0.6*y[0]+3*y[1]+x**2])
Observa que en este caso la función debe devolver un array de numpy. Ten en cuenta también
que el primer elemento de y es y[0].

Ejercicio 2.
Resuelve el siguiente problema mediante la función rungekutta4, usando 10 interva-
los:
y ′ − y + x2 − 1 = 0, x ∈ [1, 3]
y(1) = 2.64086

Solución:

3
x y(x)
1 2.64086
1.2 3.17994
1.4 3.7324
... ...
2.6 6.22814
2.8 6.2177
3 5.95727
Podemos juntar los valores de x e y en una sola matriz, de forma que se visualice
como la tabla anterior. Para ello, ejecutamos:
>>> np.hstack((x[:,np.newaxis],y))

La función np.hstack concatena varias matrices de forma horizontal. Se le proporcio-


na una tupla de matrices a concatenar (de ahí los dobles paréntesis). Además, usamos
x[:,np.newaxis] para transformar el vector x en una matriz de una sola columna, para
poder concatenarla con y.

Para representar gráficamente la solución, usaremos la orden plot:


>>> from matplotlib import pyplot as plt
>>> plt.plot(x,y)

En general, la variable y será una matriz de n columnas, donde cada columna será una
variable dependiente distinta. En ese caso, la gráfica tendrá una línea por cada columna, y
deberemos etiquetar cada línea con el nombre de la variable correspondiente. Supongamos,
por ejemplo, que y tiene 3 columnas, correspondientes a las variables u1 , u2 y u3 . Para obtener
la gráfica, haríamos:
>>> plt.plot(x,y,label=['u1','u2','u3'])
>>> plt.legend()

Ejercicio 3.
Representa gráficamente la solución obtenida en el ejercicio anterior. Deberías obtener
una gráfica como la de la figura 1.

Ejercicio 4.
Resuelve, mediante la función rungekutta4, el siguiente sistema de ecuaciones dife-
renciales de orden 1, usando 10 intervalos:

u′1 + (2x2 + 1)e2x = 3u1 + 2u2


)
0≤x≤1
u′2 − (x2 + 2x − 4)e2x = 4u1 + u2

4
Figura 1: Gráfica correspondiente al ejercicio 3.

con las condiciones iniciales: )


u1 (0) = 1
u2 (0) = 1
Representa gráficamente la solución obtenida.
Solución:
x u1 (x) u2 (x)
0 1 1
0.1 1.46923 1.16488
0.2 2.12458 1.51116
... ... ...
0.8 22.9721 21.6384
0.9 35.864 35.1212
1 56.6365 57.0045
Si la solución no coincide, comprueba si la función f (x, u) está bien definida. Por
ejemplo, comprueba que: " # " #
1 6.92258
f (0.5, )= .
4 0.52472
La gráfica obtenida debería ser como la de la figura 2.

5
Figura 2: Gráfica de la solución del ejercicio 4

2.2. Método de Adams-Bashforth de orden 4


Algoritmo 2: adamsbas4
Entrada: f : función que define el sistema y ′ = f (x, y) de n ecuaciones diferenciales.
a: valor inicial de x, en el cual conocemos la solución.
b: valor final de x.
alfa: vector, de n elementos, con la solución en el extremo inicial (a).
m: número de subintervalos en los que dividimos el intervalo entre a y b.
Resultado: x: vector de abscisas, de longitud m + 1, donde se obtiene la solución.
y: matriz de resultados, de (m + 1) filas y n columnas.
b−a
1 h=
m
2 Obtener los primeros 4 valores de x y las 4 primeras filas de y llamando a la función
rungekutta4
3 para i ∈ rango(3, m) hacer
4 xi+1 = a + ih
h
5 yi+1 = yi + 24 (55f (xi , yi ) − 59f (xi−1 , yi−1 ) + 37f (xi−2 , yi−2 ) − 9f (xi−3 , yi−3 ))
6 fin para
El Algoritmo 2 corresponde al método de Adams-Bashforth de orden 4 para sistemas de
n ecuaciones diferenciales. Se recurre al método de Runge-Kutta de orden 4 para obtener la
solución en los primeros subintervalos.
Al implementarlo en Python, ten en cuenta:

Igual que en el caso de Runge-Kutta, se debe obtener al inicio el valor de n, e inicializar


x e y como arrays de las dimensiones adecuadas.

En la línea 2, puedes usar x[:4] e y[:4] para indicar los primeros 4 elementos de x y
las primeras 4 filas de y, respectivamente. Al llamar a rungekutta4, los valores de los

6
argumentos b y m deben corresponder a los 3 primeros subintervalos.

Ejercicio 5.
Implementa en Python la función adamsbas4, correspondiente al Algoritmo 2, para
resolver sistemas de ecuaciones diferenciales de primer orden mediante el método de
Adams-Bashforth de orden 4.

Ejercicio 6.
Vuelve a resolver el problema del ejercicio 2, usando en este caso la función adamsbas4
(de nuevo con 10 intervalos).
Solución: Fíjate sobre todo en los últimos valores (los primeros se calculan con el
método de Runge-Kutta).
x y(x)
1 2.64086
1.2 3.17994
1.4 3.7324
... ...
2.6 6.23086
2.8 6.22168
3 5.96295

En el siguiente ejercicio se pide resolver una ecuación diferencial de orden mayor que 1.
Para ello, habrá que transformar la ecuación en un sistema de ecuaciones diferenciales de
orden 1.

Ejercicio 7.
Resolver, mediante el método de Adams-Bashforth de orden 4, la siguiente ecuación
diferencial:
y ′′ − 2y ′ + 2y = e2x sen x, 0≤x≤1
con las condiciones iniciales )
y(1) = −0.3
y ′ (1) = 2.6

Solución:
Observa que en este caso vamos de a = 1 hasta b = 0.

7
x y(x) y ′ (x)
1 -0.3 2.6
0.9 -0.505462 1.56163
0.8 -0.621632 0.802945
... ... ...
0.2 -0.497611 -0.604008
0.1 -0.437162 -0.596985
0 -0.378676 -0.567239
Si los resultados no coinciden, comprueba que el sistema de orden 1 obtenido es:

u′1 = u2
)
,
u′2 = 2u2 − 2u1 + e2x sen x

con las condiciones iniciales: )


u1 (1) = −0.3
u2 (1) = 2.6
Comprueba que la función f (x, u) del sistema anterior está bien definida. Por ejemplo:
" # " #
−3 2
f (0.3, )=
2 10.53847

Ejercicio 8.
Representa gráficamente la solución del ejercicio anterior.
Deberías obtener una gráfica como la de la figura 3.

Figura 3: Gráfica correspondiente al ejercicio 8.

8
La figura 3 muestra las variables u1 y u2 , que corresponden a y e y ′ , respectivamen-
te. A menudo nos interesará únicamente el valor de y. En ese caso, para hacer la gráfica,
ejecutaremos:
>>> plt.plot(x,y[:,0]) # Usar solo la columna 0 de la matriz y
Más en general, puede que nos interese hacer una gráfica solo de algunas de las variables
(columnas) de la matriz y. Por ejemplo, si solo nos interesan las columnas 0 y 3, haremos:
>>> plt.plot(x,y[:,(0,3)],label=['u1','u4'])
>>> plt.legend()

3. Problemas de contorno. Método del disparo


En esta sección consideramos problemas de contorno, dados por la ecuación de segundo
orden:
y ′′ = f (x, y, y ′ ), a ≤ x ≤ b
con las condiciones iniciales )
y(a) = α
y(b) = β
donde y(x), α, β ∈ R.
Este tipo de problemas se puede resolver mediante el método del disparo (Algoritmo 3).
Algunos aspectos a tener en cuenta son:
Es necesario definir la función g del sistema u′ = g(x, u), de orden 1, equivalente al
sistema inicial y ′′ = f (x, y, y ′ ), de orden 2. Se trata de definir una función g dentro de
la propia función disparo. La función g será:
" #
u2
g(x, u) =
f (x, u1 , u2 )

El valor de u1 (b) corresponde al último valor de la primera columna de la matriz u. En


Python, el valor se puede obtener como u[-1,0].

Ejercicio 9.
Resuelve, mediante el método del disparo, la siguiente ecuación diferencial:

y ′′ = −(y ′ )2 − y + ln(x), 1 ≤ x ≤ 2,

con las condiciones iniciales )


y(1) = 0
y(2) = ln(2)
utilizando un valor inicial de y ′ (1) = 0.7, 10 intervalos y una tolerancia de 10−7 .
Representa gráficamente la solución.

9
Algoritmo 3: disparo
Entrada: f : función que define la ecuación diferencial y ′′ = f (x, y, y ′ )
a, b: valor inicial y valor final de x, respectivamente
alfa: solución (escalar) en el extremo inicial (a).
beta: solución (escalar) en el extremo final (b).
m: número de subintervalos en los que dividimos el intervalo entre a y b.
t0: valor inicial de y ′ (a).
tol: tolerancia máxima para |y(b) − beta|.
maxiter: número máximo de iteraciones.
Resultado: x: vector de abscisas, de longitud m + 1, donde se obtiene la solución.
y: matriz de resultados, de (m + 1) filas y 2 columnas.
1 Definir la función g(x, u) del sistema de orden 1 equivalente:
u′1 = u2
)

u′2 = f (x, u1 , u2 ) " #


alf a
2 Obtener x, u mediante rungekutta4 con g(x, u) y u(a) =
t0
3 ybt0 = u1 (b)
4 t1 = t0 + beta − ybt0
5 k=1 # Número de iteraciones realizadas
6 mientras |u1 (b) − beta| ≥ tol y k ≤ maxiter hacer " #
alf a
7 Obtener x, u mediante rungekutta4 con g(x, u) y u(a) =
t1
8 ybt1 = u1 (b)
(beta − ybt1)(t0 − t1)
9 t = t1 +
ybt0 − ybt1
10 t0 = t1
11 t1 = t
12 ybt0 = ybt1
13 k =k+1
14 fin mientras
15 si |u1 (b) − beta| ≥ tol entonces
16 Error: se ha llegado al número máximo de iteraciones.
17 fin si
18 y=u

10
Solución:
x y(x) y ′ (x)
1 0 1
1.1 0.09531 0.909092
1.2 0.182321 0.833334
... ... ...
1.8 0.587787 0.555556
1.9 0.641854 0.526316
2 0.693147 0.5
La gráfica correspondiente de y(x) puede verse en la Figura 4.
Si la solución no coincide, comprueba que la función f (x, y, y ′ ) que has utilizado es
correcta. Por ejemplo:
f (0.3, 0.6, 0.8) = −2.44397.

Figura 4: Gráfica de y(x) correspondiente al ejercicio 9.

11

You might also like