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 -1Ejemplo 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