Monday, March 5, 2012
Una interface gráfica para estudiar las trayectorias en plano de fase de dos estados.
function dfase(op)
% DFASE(OP) Es una interface gráfica para estudiar las trayectorias en plano de fase
% de dos estados.
%
% Tiene la posibilidad de graficar:
% => Las trayectoria de los estados ingresando la condición inicial con la
% posición del mouse cuando se hace un click.
% => Las isoclinas.
% => Los vectores que indican la pendiente.
%
% Haciendo un click con el mouse en el plano de fase, se cálculan y grafican las
% trayectorias que describen los estados.
% El método de resolución está basado en el método de Runge-Kutta, consultar
% help de ODE45 para mayores destalles. Las ecuaciones pueden ser lineales o no.
% Como tiene una tolerancia fijada de antemano puede que algunas ecuaciones no lineales
% muy complicadas fallen en la convergencia. En la mayoría de los casos no presentan
% problemas.
%
% Para utilizarla simplemente ingrese "dfase3" desde el Command Window
%
%
% si no se ingresa opción entonces se define la GUI
if nargin<1
op=1;
end,
if op==1
% dibujo toda la GUI
% para evitar problemas de localización de objetos
h=findobj('Tag','FigFase');
if ~isempty(h)
errordlg('Ya existe una ventana Diagrama de Fase',...
'Error en Diagrama de Fase',...
'modal');
return,
end,
Hf = figure('Units','normalized',...
'Position',[0.1 0.1 0.8 0.8],...
'NumberTitle','off',...
'Name','Diagrama de Fase',...
'Menubar','none',...
'Tag','FigFase');
c=get(gcf,'Color');
% plano de fase
Ha1=axes('Units','normalized',...
'Position',[0.04 0.25 0.6 0.69],...
'FontSize',8,...
'Xlim',[-10 10],...
'Ylim',[-10 10],...
'box','on',...
'Tag','fase',... % el tag es "fase"
'NextPlot','add',...
'ButtonDownFcn','dfase(3)');
title('Diagrama de fase');
% gráfico de la velocidad (x2)
Ha2=axes('Units','normalized',...
'Position',[ 0.68 0.25 0.3 0.3 ],...
'FontSize',8,...
'box',' on',...
'NextPlot','add',...
'Tag','velocidad'); % el tag es "velocidad"
title('Velocidad (x2)');
% gráfico de la posición (x1)
Ha3=axes('Units','normalized',...
'Position',[ 0.68 0.64 0.3 0.3 ],...
'box',' on',...
'FontSize',8,...
'NextPlot','add',...
'Tag','posicion');
title('Posición (x1)');
% segunda ecuación
uicontrol('Style','text',...
'Units','normalized',...
'BackgroundColor',c,...
'ForegroundColor',[1 1 1],...
'Position',[ 0.05 0.15 0.2 0.03 ],...
'HorizontalAlignment','left',...
'String','Primer ecuación:')
uicontrol('Style','edit',...
'Units','normalized',...
'BackgroundColor',[1 1 1],...
'Position',[ 0.25 0.14 0.2 0.05 ],...
'HorizontalAlignment','left',...
'String','x2',...
'Tag','PrimerEc')
% segunda ecuación
uicontrol('Style','text',...
'Units','normalized',...
'BackgroundColor',c,...
'ForegroundColor',[1 1 1],...
'Position',[ 0.05 0.08 0.2 0.03 ],...
'HorizontalAlignment','left',...
'String','Segunda ecuación:')
uicontrol('Style','edit',...
'Units','normalized',...
'BackgroundColor',[1 1 1],...
'Position',[ 0.25 0.07 0.2 0.05 ],...
'HorizontalAlignment','left',...
'String','-x1-x2',...
'Tag','SegundaEc');
% boton vectores
uicontrol('Style','push',...
'Units','normalized',...
'Position',[ 0.5 0.14 0.12 0.05 ],...
'String','Vectores',...
'Tag','Push1',...
'Callback','dfase(2)');
% boton isoclinas
uicontrol('Style','push',...
'Units','normalized',...
'Position',[ 0.5 0.07 0.12 0.05 ],...
'String','Isoclinas',...
'Tag','Push2',...
'Callback','dfase(5)');
% boton borrar
uicontrol('Style','push',...
'Units','normalized',...
'Position',[ 0.65 0.07 0.12 0.05 ],...
'String','Borrar',...
'Tag','Push3',...
'Callback','dfase(4)');
% boton imprimir
uicontrol('Style','push',...
'Units','normalized',...
'Position',[ 0.65 0.14 0.12 0.05 ],...
'String','Imprimir',...
'Tag','Push4',...
'Callback','print');
% boton cerrar
uicontrol('Style','push',...
'Units','normalized',...
'Position',[ 0.8 0.07 0.12 0.05 ],...
'String','Cerrar',...
'Tag','Push5',...
'Callback','close(gcf)');
% grafico dos líneas que pasan por el origen
set(Hf,'CurrentAxes',Ha1);
plot([-10 0;10 0],[0 -10;0 10],...
'Color',[1 1 1],...
'LineWidth',0.1);
elseif op==2
% Para graficar los vectores
% obtengo las ecuaciones
ec1=get(findobj('Tag','PrimerEc'),'String');
ec2=get(findobj('Tag','SegundaEc'),'String');
% planteo la ecuación de la pendiente
ec=['m=(' ec2 ')./(' ec1 ');'];
% hago al axes del plano de fase el actual
Ha=findobj('Tag','fase');
set(gcf,'CurrentAxes',Ha);
% grafico los vectores
for j=1:20
for s=1:20
% calculo la pendiente y para un dado punto del plano
a=1.5;b=0.75;
x1=-10+j*a;
x2=-10+s*a;
eval(ec);
% calculo el punto final de modo que tenga una longitud fija
xd=sqrt((b^2)/(1+m^2));
x21=m*xd+x2;
x11=x1+xd;
plot([x1 x11],[x2 x21],'y')
end,
end,
elseif op==3
% Para calcular y graficar las trayectorias de los estados
% utilizo ODE45 (Runge-Kuta)
% primero necesito armar un archivo .m con las ecuaciones diferenciales
f=fopen('ectmp.m','wt+');
fprintf(f,'%s','function yd=ecuacion(t,x)');
fprintf(f,'\n\n\n\n');
% acomodo las ecuaciones ingresadas
ec1=get(findobj('Tag','PrimerEc'),'String');
ec2=get(findobj('Tag','SegundaEc'),'String');
% necesito exprezarlas como un vector para la ODE45
ec11=strrep(ec1,'x1','x(1)');
ec22=strrep(ec2,'x1','x(1)');
ec11=strrep(ec11,'x2','x(2)');
ec22=strrep(ec22,'x2','x(2)');
ec=['yd=[' ec11 ';' ec22 '];'];
fprintf(f,'%s\n',ec);
fclose(f);
% capturo las condiciones iniciales desde la posición actual del mouse
yo=get(findobj('Tag','fase'),'CurrentPoint');
% resuelvo las ecuaciones diferenciales
[t,y]=ode45('ectmp',0,10,yo(2,1:2)');
% elimino la función que tiene las ecuaciones de la memoria
% para que los cálculos sean actuales
clear ectmp
% grafico
set(gcf,'CurrentAxes',findobj('Tag','velocidad'));
hl = findobj('Parent',gca,'Type','line');
delete(hl);
plot(t,y(:,1),'w');
set(gcf,'CurrentAxes',findobj('Tag','posicion'));
hl = findobj('Parent',gca,'Type','line');
delete(hl);
plot(t,y(:,2),'w');
set(gcf,'CurrentAxes',findobj('Tag','fase'));
plot(y(:,1),y(:,2),'w');
elseif op==4
% Para borrar los vectores, isoclinas y trayectorias de estados
% hago al axes del plano de fase el actual
Ha=findobj('Tag','fase');
set(gcf,'CurrentAxes',Ha);
% busco y borro los objetos tipo líneas
Hdel=findobj('Parent',Ha,'Type','line');
delete(Hdel);
% redibujo las líneas que pasan por el origen
plot([-10 0;10 0],[0 -10;0 10],...
'Color',[1 1 1],...
'LineWidth',0.1);
elseif op==5
% Para calcular y graficar las isoclinas
% obtengo las ecuaciones que se ingresaron en forma de cadena
ec1=get(findobj('Tag','PrimerEc'),'String');
ec2=get(findobj('Tag','SegundaEc'),'String');
% trabajo las ecuaciones para trabajar punto a punto
ec=['m=(' ec2 ')/(' ec1 ')'];
ec1=strrep(ec,'*','.*');
ec1=strrep(ec1,'/','./');
ec1=strrep(ec1,'^','.^');
% calculo 20 valores de pendientes de manera que queden distribuidos
% en el palno de fase
x1=[-10*ones(1,5) -10 -6 -2 2 6 10*ones(1,5) 10 6 2 -2 -6];
x2=[-10 -6 -2 2 6 10*ones(1,5) 10 6 2 -2 -6 -10*ones(1,5)];
eval([ec1 ';']);
M=m;
% resuelvo la ecuación para poner en forma explícita x2
% SE NECESITA SYMBOLIC TOOLBOX
ecs=solve(ec,'x2');
ecs1=ecs(1,:);
ecs1=strrep(ecs1,'*','.*');
ecs1=strrep(ecs1,'/','./');
ecs1=strrep(ecs1,'^','.^');
% calculo numericamente las isoclinas
x1=-10:0.2:10;
for j=1:20;
m=M(j);
eval(['x2=' ecs1 ';']);
plot(x1,x2,...
'Color',[0.8 0.8 0.8])
end,
end
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment