Solución de ecuaciones diferenciales con condiciones en los extremos
Procedimiento bvp4c de MATLAB
El procedimiento
en el intervalo [a,b], bajo las condiciones de contorno especificadas por una función
g(y(a),y(b))=0.
Se define la función
para una función y(x) definida en el intervalo [a,b] cuyos extremos tienen valores fijos α y β. Pero también podrían estar fijados los valores de las pendientes de la función en dichos puntos
o una combinación de ambas, hay otras posibilidades de condiciones de contorno
Se utiliza
Al primer argumento, se le pasa un vector de puntos iniciales en el intervalo [a,b], son suficientes cinco valores igualmente espaciados,
Al segundo, se le pasa un vector de dos componentes
...
xIni=linspace(a,b,5);
solinit = bvpinit(xIni, @guess);
function g = guess(x)
g = [sin(x), cos(x)];
end
Se utiliza la función
El procedimiento
Ejemplos
Ejemplo 1Vamos a integrar la ecuación diferencial con las condiciones en los extremos a=0, b=4
El procedimiento
Como hemos visto al aplicar el procedimientro
ode45 , una ecuación diferencial de segundo orden se convierte en un sistema de dos ecuaciones diferenciales de primer ordenDefinimos la función que especifica las condiciones en los extremos
Definimos la aproximación inicial en
solinit , que va a consistir en cinco puntos 0,1,2,3,4,5 en el intervalo [0,4] y una aproximación inicial[s1, s2] . La elección adecuada de la aproximación inicial es crucial para econtrar la solución. En los ejemplos que siguen eligiremos valores constantes, pero no siempre es posible para encontrar la solución buscada
function dx = odefun(~,x)
dx = [x(2), -abs(x(1))];
end
function res = bcfun(xa,xb)
res = [xa(1), xb(1)+2];
end
Se los pasamos al procedimiento
Con el valor devuelto
... x=linspace(0,4); %100 puntos, por defecto y = deval(sol,x); plot(x,y(1,:)); ...
La ecuación diferencial admite dos soluciones, la segunda se obtiene con la aproximación inicial
Reunimos las porciones de código, para crear la función
function ecuacion_diferencial_1
solinit = bvpinit(linspace(0,4,5), [1,0]); %primera aproximación
sol1 = bvp4c(@odefun, @bcfun, solinit);
solinit = bvpinit(linspace(0,4,5), [-1,0]); %segunda aproximación
sol2 = bvp4c(@odefun, @bcfun, solinit);
x=linspace(0,4);
y = deval(sol1,x);
hold on
plot(x,y(1,:));
y = deval(sol2,x);
plot(x,y(1,:));
grid on
xlabel('x')
ylabel('y')
title('Condiciones en los extremos')
%ecuación diferencial
function dx = odefun(~,x)
dx = [x(2), -abs(x(1))];
end
%condiciones en los extremos
function res = bcfun(xa,xb)
res = [xa(1), xb(1)+2];
end
end

Sea la ecuación diferencial, con las condiciones en los extremos a=1, b=2.5
function ecuacion_diferencial_8
solinit = bvpinit(linspace(1,2.5,5), [0.1,0]);
sol = bvp4c(@f, @extremos, solinit);
t=linspace(1,2.5);
x = deval(sol,t);
plot(t,x(1,:));
grid on
xlabel('x')
ylabel('y')
title('Condiciones en los extremos')
disp(x(2,end)) %pendiente en x=2.5
%ecuación diferencial
function dx = f(t,x)
dx = [x(2), -x(2)/t-2];
end
%condiciones en los extremos
function res = extremos(xa,xb)
res = [xa(1)-1, xb(2)+1];
end
end

Comprobamos con
>> ecuacion_diferencial_8
-1
Ejemplo 3
A final de la la página titulada Cuerda que gira alrededor de un eje, se describe un ejemplo significativo, comparándose la solución analítica y la que resulta de la aplicación del procedimiento
Aproximaciones sucesivas
Un problema típico de cinemática es el de apuntar un cañón para que el proyectil disparado impacte en el blanco. Tenemos dos posiciones la de disparo y la del blanco. Elegimos un ángulo de tiro, si el alcance es mayor o menor que la distancia desde la posición de disparo al blanco, cambiamos el ángulo de tiro y así, mediante aproximaciones sucesivas obtenemos el ángulo de disparo que hace que el proyectil impacte en el blanco.
El procedimiento para resolver la ecuación diferencial
es similar, se trata de elegir el valor adecuado , de la derivada primera en x=a (tangente del ángulo de tiro), para que al resolver la ecuación diferencial en el intervalo [a,b], obtengamos y(b)=β (acertar en el blanco).
Ecuaciones lineales
Supongamos que la ecuación diferencial con las condiciones en los extremos
La elección de la pendiente inicial, se realiza aplicando el principio de superposición
Sean las condiciones iniciales:
Sean las condiciones iniciales:
resolvemos la ecuación diferencial y obtenemos la solución y1(x). En el extremo b, y1(b)=β1 que será en general, distinto de β
resolvemos la ecuación diferencial y obtenemos la solución y2(x). En el extremo b, y2(b)=β2 que será en general, distinto de β
La solución de la ecuación diferencial es también la combinación lineal
como puede verificase fácilmente
En x=b se cumple
En x=a se cumple
Asignamos a c2=1. Eliminamos c1 el sistema de dos ecuaciones
Ejemplo
Resolvamos la ecuación diferencial, con las condiciones en los extremos que se especifican
para , obtenemos, β1=4.7876
para , obtenemos, β2=0.4360
Calculamos s a partir de s1, s2, β1, β2 y β
para , obtenemos β=-1, al resolver la ecuación diferencial
alfa=2; %en x=1
beta=-1; %en x=3
f=@(t,x) [x(2); (1-t/5)*x(1)+t];
s1=-1.5; %pendiente en x=1
[t,x]=ode45(f,[1,3],[alfa,s1]);
beta_1=x(end,1);
hold on
plot(t, x(:,1))
s2=-3.0; %pendiente en x=1
[t,x]=ode45(f,[1,3],[alfa,s2]);
beta_2=x(end,1);
plot(t, x(:,1))
s=(beta*(s1-s2)-s1*beta_2+s2*beta_1)/(beta_1-beta_2);
[t,x]=ode45(f,[1,3],[alfa,s]);
plot(t, x(:,1))
hold off
legend('-1.5','-3.0','s','location','northwest')
grid on
xlabel('x')
ylabel('y')
title('Condiciones en los extremos')

Cuando la ecuación diferencial es lineal acertamos en el 'blanco' (extremo derecho) al tercer intento
Resolvemos la ecuación diferencial utilizando el procedimiento
function ecuacion_diferencial_3
solinit = bvpinit(linspace(1,3,5), [0,-1]);
sol = bvp4c(@f, @extremos, solinit);
t=linspace(1,3);
x = deval(sol,t);
plot(t,x(1,:));
grid on
xlabel('x')
ylabel('y')
title('Condiciones en los extremos')
%ecuación diferencial
function dx = f(t,x)
dx = [x(2), (1-t/5)*x(1)+t];
end
%condiciones en los extremos
function res = extremos(xa,xb)
res = [xa(1)-2, xb(1)+1];
end
end

Ecuaciones diferenciales no lineales
Sea la ecuación diferencial con las condiciones en los extremos que se especifican
Resolvemos la ecuación diferencial en el intervalo [0,1] con las condiciones iniciales .Vamos cambiando s, representando la función F(s)=y(b,s)-1
alfa=4; %en x=0
beta=1; %en x=1
f=@(t,x) [x(2); 3*x(1)^2/2];
ss=linspace(-50,0,100);
fs=zeros(1,length(ss));
i=1;
for s=ss
[t,x]=ode45(f,[0,1],[alfa,s]);
fs(i)=x(end,1)-beta;
i=i+1;
end
hold on
plot(ss, fs)
grid on
xlabel('s')
ylabel('F(s)')
title('Ceros')

Vemos que la función F(s) se anula para dos valores de s, el primero próximo a s=-35.8 y el segundo próximo a s=-8.1
Aplicamos el procedimiento del punto medio para obtener la primera raíz, que se encuentra en el intervalo (-40,-20)
alfa=4; %en x=0
beta=1; %en x=1
f=@(t,x) [x(2); 3*x(1)^2/2];
a=-40; %intervalo dónde se encuentra la pimera raíz
b=-20;
CERO=1e-10;
ERROR=0.001;
MAXITER=100;
for i=1:MAXITER
m=(a+b)/2;
[t,x]=ode45(f,[0,1],[alfa,a]);
ya=x(end,1)-beta;
[t,x]=ode45(f,[0,1],[alfa,m]);
ym=x(end,1)-beta;
if abs(ym)<CERO
break
elseif abs((a-b)/m)<ERROR
break
elseif (ya*ym)<0
b=m;
else
a=m;
end
end
if(i==MAXITER)
error('no se ha encontrado la raiz')
end
disp(m)
-35.8496
La segunda raíz se encuentra en el intervalo (-15,-5), cambiamos los valores de las variables
-8.0005
Representamos las dos posibles soluciones de la ecuación diferencial no lineal
alfa=4; %en x=0
f=@(t,x) [x(2); 3*x(1)^2/2];
hold on
for s=[-35.8496,-8.0005]
[t,x]=ode45(f,[0,1],[alfa,s]);
plot(t, x(:,1))
end
hold off
grid on
legend('-35.8496','-8.0005')
xlabel('x')
ylabel('y')
title('Condiciones en los extremos')

Resolvemos la ecuación diferencial utilizando el procedimiento
function ecuacion_diferencial_4
solinit = bvpinit(linspace(0,1,5), [-10,1]);
sol1 = bvp4c(@f, @extremos, solinit);
solinit = bvpinit(linspace(0,1,5), [4,1]);
sol2 = bvp4c(@f, @extremos, solinit);
t=linspace(0,1);
x = deval(sol1,t);
hold on
plot(t,x(1,:));
x = deval(sol2,t);
plot(t,x(1,:));
hold off
grid on
xlabel('x')
ylabel('y')
title('Condiciones en los extremos')
%ecuación diferencial
function dx = f(~,x)
dx = [x(2), 3*x(1)^2/2];
end
%condiciones en los extremos
function res = extremos(xa,xb)
res = [xa(1)-4, xb(1)-1];
end
end
Método de las diferencias finitas
Se divide el intervalo [a, b] en N partes iguales de longitud h=(b-a)/N. Las abscisas de cada uno de sus extremos son xi=a+i·h, i=0,1, ...N
Reemplazamos las derivadas por diferencias finitas utilizando el desarrollo en serie de Taylor de una función alrededor de xi
Si x=xi+1=xi+h
-
Si x=xi-1=xi-h
En este sistema de dos ecuaciones, despejamos la derivada primera y la derivada segunda en xi
Ecuación diferencial lineal
Sea la ecuación diferencial lineal con condiciones en los extremos a y b

Introducimos la notación y(xi)=yi, p(xi)=pi, q(xi)=qi y r(xi)=ri.Transformamos la ecuación diferencial en una ecuación en diferencias finitas
Agrupando términos, obtenemos un sistema de N-1 ecuaciones con N-1 incógnitas
En forma matricial
Ejemplo 1
Resolvemos la ecuación diferencial lineal con condiciones en los extremos
Lo sustituimos por un sistema de N-1 ecuaciones con N-1 incógnitas, del siguiente modo
que en forma matricial se expresa
MATLAB facilita el trabajo con matrices: crear matrices, acceder a sus elementos, etc. Una vez que hemos definido el vector A de los coeficientes y el vector B de los términos independientes, despejamos el vector Y de las incógnitas, A·Y=B, utilizando el operador división por la izquierda '\'
alfa=0; %en x=-1
beta=0; %en x=1
N=50;
h=2/50;
A=diag(ones(1,N-2),1)+diag(ones(1,N-2),-1);
for i=1:N-1
A(i,i)=(1+(-1+i*h)^2)*h^2-2;
end
B=ones(N-1,1)*(-h^2);
Y=A\B;
plot(-1+(0:N)*h, [alfa, Y',beta],'-ro','markersize',3,'markeredgecolor'
,'r','markerfacecolor','r')
xlabel('x')
ylabel('y')
grid on
title('Diferencias finitas')

Resolvemos la ecuación diferencial utilizando el procedimiento
function ecuacion_diferencial_5
solinit = bvpinit(linspace(-1,1,5), [0,0]);
sol = bvp4c(@f, @extremos, solinit);
t=linspace(-1,1);
x = deval(sol,t);
plot(t,x(1,:));
grid on
xlabel('x')
ylabel('y')
title('Condiciones en los extremos')
%ecuación diferencial
function dx = f(t,x)
dx = [x(2), -1-(1+t^2)*x(1)];
end
%condiciones en los extremos
function res = extremos(xa,xb)
res = [xa(1), xb(1)];
end
end
Ejemplo 2
Resolvemos la ecuación diferencial lineal con condiciones en los extremos
Esta ecuación diferencial tiene solución analítica
>> syms x;
>> y=dsolve('D2y-2*Dy+y-x*exp(x)+x',x);
>> simplify(y)
ans =(x^3*exp(x))/6 - x + C5*exp(x) + C6*x*exp(x) - 2
Determinamos los coeficientes A y B a partir de las condiciones en los extremos: A=2, B=-5/3
Lo sustituimos por un sistema de N-1 ecuaciones con N-1 incógnitas, del siguiente modo
que en forma matricial se expresa
Observamos la coincidencia entre la solución analítica y numérica
alfa=0; %en x=0
beta=-4; %en x=2
N=50;
h=2/N;
A=diag((1-h)*ones(1,N-2),1)+diag((1+h)*ones(1,N-2),-1)+diag((h^2-2)*ones(1,N-1));
B=zeros(N-1,1);
for i=1:N-1
x=i*h;
B(i)=-h^2*(-x*exp(x)+x);
end
B(1)=B(1)-(1+h)*alfa;
B(N-1)=B(N-1)-(1-h)*beta;
Y=A\B;
hold on
plot((0:N)*h, [alfa Y',beta],'-ro','markersize',3,'markeredgecolor',
'r','markerfacecolor','r')
ye=@(x) (x.^3/6-5*x/3+2).*exp(x)-x-2; %exacta
fplot(ye,[0,2])
hold off
xlabel('x')
ylabel('y')
grid on
title('Diferencias finitas')

Resolvemos la ecuación diferencial utilizando el procedimiento
function ecuacion_diferencial_6
solinit = bvpinit(linspace(0,2,5), [0,0]);
sol = bvp4c(@f, @extremos, solinit);
t=linspace(0,2);
x = deval(sol,t);
plot(t,x(1,:));
grid on
xlabel('x')
ylabel('y')
title('Condiciones en los extremos')
%ecuación diferencial
function dx = f(t,x)
dx = [x(2), 2*x(2)-x(1)+t*exp(t)-t];
end
%condiciones en los extremos
function res = extremos(xa,xb)
res = [xa(1), xb(1)+4];
end
end
Ecuación diferencial no lineal
Este tipo de ecuaciones diferenciales con condiciones en los extremos son mucho más difíciles de resolver
Sustituimos por un sistema de N-1 ecuaciones con N-1 incógnitas, del siguiente modo
de forma explícita
Ejemplo
Resolvemos la ecuación diferencial no lineal con condiciones en los extremos
La solución analítica es
>> dsolve('D2y-y^3+y*Dy',x)
ans = -1/(C23 - x)
-1/(C20 + x/2)
Determinamos A sabiendo que y(1)=1/2, A=-1
En el otro extremo del intervalo, se cumple que y(2)=1/3
Comprobamos que y=1/(1+x) es solución de la ecuación diferencial
>> syms x; >> y=1/(1+x); >> diff(y,x,2)-y^3+y*diff(y,x) ans =0
El sistema de N-1 ecuaciones con N-1 incógnitas, es
Vamos a utilizar el procedimiento de Newton-Raphson para resolver este sistema de ecuaciones no lineales
El procedimiento se escribe
o bien, Y'=Y-J\G, utilizando el operador MATLAB, división por la izquierda \. Se obtiene el nuevo vector Y' de la izquierda, a partir del Y previo, a la derecha de la igualdad
El vector G son las ecuaciones (sin la igauldad a cero) y la matriz J es
Nota: Esta expresión se muestra muy pequeña para que quepa en la página, pero se puede aumentar, utilizando el botón derecho del ratón y seleccionando en el menú flotante, Math Settings/Scale all Math...
alfa=1/2; %en x=1
beta=1/3; %en x=2
N=10;
h=1/N;
y=ones(N-1,1);
G=zeros(N-1,1);
J=zeros(N-1);
for k=1:100
G(1)=y(2)-2*y(1)+alfa-h^2*(y(1)^3-y(1)*(y(2)-alfa)/(2*h));
for i=2:N-2
G(i)=y(i+1)-2*y(i)+y(i-1)-h^2*(y(i)^3-y(i)*(y(i+1)-y(i-1))/(2*h));
end
G(N-1)=beta-2*y(N-1)+y(N-2)-h^2*(y(N-1)^3-y(N-1)*(beta-y(N-2))/(2*h));
J(1,1)=-2-h^2*(3*y(1)^2-(y(2)-alfa)/(2*h));
J(N-1,N-1)=-2-h^2*(3*y(N-1)^2-(beta-y(N-2))/(2*h));
for i=2:N-2
J(i,i)=-2-h^2*(3*y(i)^2-(y(i+1)-y(i-1))/(2*h));
end
for i=2:N-1
J(i, i-1)=1-y(i)*h/2;
end
for i=1:N-2
J(i, i+1)=1+y(i)*h/2;
end
dy=-J\G;
if sqrt(norm(dy)/norm(y+dy))<0.0001
disp('Solución')
disp(y+dy)
break;
end
y=y+dy;
end
if k==100
disp('Se ha soprepasado el número de iteracciones');
end
hold on
plot(1+(0:N)*h, [alfa y',beta],'-ro','markersize',3,'markeredgecolor',
'r','markerfacecolor','r')
ye=@(x) 1./(x+1); %exacta
fplot(ye,[1,2])
hold off
xlabel('x')
ylabel('y')
grid on
title('Diferencias finitas')
Solución
0.4762
0.4546
0.4348
0.4167
0.4000
0.3846
0.3704
0.3571
0.3448
Observamos la coincidencia entre la solución analítica y numérica

Resolvemos la ecuación diferencial utilizando el procedimiento
function ecuacion_diferencial_7
solinit = bvpinit(linspace(1,2,5), [0,-1]);
sol = bvp4c(@f, @extremos, solinit);
t=linspace(1,2);
x = deval(sol,t);
plot(t,x(1,:));
grid on
xlabel('x')
ylabel('y')
title('Condiciones en los extremos')
%ecuación diferencial
function dx = f(~,x)
dx = [x(2), x(1)^3-x(1)*x(2)];
end
%condiciones en los extremos
function res = extremos(xa,xb)
res = [xa(1)-1/2, xb(1)-1/3];
end
end
Referencias
James V. Lambers, Amber C. Sumner. Explorations in Numerical Analysis. December 20, 2016. pp. 343-352