function output = analyzer(action) global ocheck eqStrCur eqStrMat indepVar noOfPoints global newFig noOfPlots curFigure maxPlotNo eqEvalStr % ANALYZER equation plotting function. % User specifies limits on axes, and inputs the equation. % % Original programmatic layout is adapted from dfield written by John C. Polking, Rice University % % Modified and updated version of written program. % Modified and updated by Il-Joong Kil, November 2001 % Finalised to version 2.0 on 20 Febuary 2002 format long; if nargin < 1 action ='initialize'; end % Initialization sequences if strcmpi(action,'initialize') % Closes all the opened analyzer windows figs = get(0,'children'); for (figno = 1:length(figs)) nn = get(figs(figno),'name'); TTT = findstr(nn,'ANALYZER'); SSS = findstr(nn,'WARNING!!'); if (~isempty(TTT)|~isempty(SSS)) delete(figs(figno)); end; end % The default differential equation, and Display window. Tname = 't'; equation = 't^2 - 1'; WINvect = [-5 5 -5 5]; % Main window properties dfset = figure('pos',[30 70 470 320],'color',[0.95 0.85 0.75],'CloseRequestFcn','analyzer(''quit'')',... 'resize','off','name','ANALYZER PLOT DETAILS','numb','off','visible','off','menu','none'); figure(dfset) % Equation field frame(1) = uicontrol('style','frame','backgroundcolor',[0.8 0.8 0.9],... 'pos',[25,205,420,90],'visible','off'); % Call sequence for the independent variable text field tname = [ 'sh = get(gcf,''user'');','sm = get(sh(1),''user'');'... 'eq = sh(3:7);','wind =sh(8:16);'... 'Tname=deblank2(get(eq(5),''string''));'... 'set(eq(5),''string'',Tname);'... 'set(eq(2),''string'',[''x('', Tname, '') = '']);'... 'set(wind(2),''string'',[''lower '',Tname,'' = '']);'... 'set(wind(6),''string'',[''upper '',Tname,'' = '']);'... 'sm = str2mat(Tname,sm(2,:));','set(sh(1),''user'',sm);']; % Call sequence for the equation text field xeqn =[ 'sh = get(gcf,''user'');','sm = get(sh(1),''user'');'... 'eq=sh(3:7);','equation = deblank2(get(eq(3),''string''));'... 'set(eq(3),''string'',equation);'... 'sm = str2mat(sm(1,:),equation);','set(sh(1),''user'',sm);']; % Label "Enter the equation:" eq(1)=uicontrol('style','text','pos',[30 268 410 20],'backgroundcolor',[0.8 0.8 0.9],... 'horizon','center','string','Enter the equation:','visible','off','fontweight','bold'); % Label "x(tname) = " eq(2) = uicontrol('style','text','pos',[30 245 100 20],'backgroundcolor',[0.8 0.8 0.9],... 'horizon','right','string',['x(', Tname, ') = '],'visible','off'); % Text field for eq(2) eq(3)=uicontrol('pos',[140 245 270 20],'backgroundcolor','w',... 'string',equation,'horizon','left','style','edit','call',xeqn,'visible','off'); % Label "The independent variable is " eq(4)=uicontrol('pos',[30 210 200 20],'style','text','backgroundcolor',[0.8 0.8 0.9],... 'horizon','right','string','The independent variable is ','visible','off'); % Text field for eq(4) eq(5)=uicontrol('pos',[230 210 80 20],'string',Tname,'backgroundcolor','w',... 'horizon','center','style','edit','call',tname,'visible','off'); % Other information field frame(2) = uicontrol('style','frame','pos',[25 62 420 127],'visible','off','backgroundcolor',[0.8 0.8 0.9]); % Call sequences for 4 text fields showing axis limits for i = 1:4 w(i,:) = [ 'sh = get(gcf,''user'');','wind = sh(8:16);'... 'text = deblank2(get(wind(' num2str(i*2+1) '),''string''));'... 'sh(' num2str(19+i) ')=str2num(text);','set(wind(' num2str(i*2+1) '),''string'',text);'... 'set(gcf,''user'',sh);']; end % Label "Axis limits:" wind(1)=uicontrol('style','text','fontweight','bold','backgroundcolor',[0.8 0.8 0.9],... 'pos',[30 135 410 20],'horizon','left','string','Axis limits:','visible','off'); % Label "lower tname = " wind(2) = uicontrol('style','text','backgroundcolor',[0.8 0.8 0.9],'pos',[105 132 80 20],... 'horizon','right','string',['lower ',Tname,' = '],'visible','off'); % Text field for wind(2) wind(3) = uicontrol('style','edit','backgroundcolor','w',... 'pos',[185 132 50 20],'string',num2str(WINvect(1)),'call',w(1,:),'visible','off'); % Label "lower x = " wind(4) = uicontrol('style','text','backgroundcolor',[0.8 0.8 0.9],... 'pos',[235 132 125 20],'horizon','right','string',['lower x = '],'visible','off'); % Text field for wind(4) wind(5)=uicontrol('style','edit','backgroundcolor','w',... 'pos',[185 109 50 20],'string',num2str(WINvect(2)),'call',w(2,:),'visible','off'); % Label "upper tname = " wind(6) = uicontrol('style','text','backgroundcolor',[0.8 0.8 0.9],... 'pos',[30 109 155 20],'horizon','right','string',['upper ',Tname,' = '],'visible','off'); % Text field for wind(6) wind(7) = uicontrol('style','edit','backgroundcolor','w',... 'pos',[360 132 50 20],'string',num2str(WINvect(3)),'call',w(3,:),'visible','off'); % Label "upper x = " wind(8) = uicontrol('style','text','backgroundcolor',[0.8 0.8 0.9],... 'pos',[235 109 125 20],'horizon','right','string',['upper x = '],'visible','off'); % Text field for wind(8) wind(9)=uicontrol('style','edit','backgroundcolor','w',... 'pos',[360 109 50 20],'string',num2str(WINvect(4)),'call',w(4,:),'visible','off'); % Label "Overlay on current plot : " over_text = uicontrol('style','text','pos',[80 164 155 15],'horizon','center',... 'string','Overlay on current plot : ','backgroundcolor',[0.8 0.8 0.9],'visible','off'); % Checkbox for over_text ocheck = uicontrol('Style','Checkbox','pos',[230 161 20 20],'Value',1,'backgroundcolor',[0.8 0.8 0.9]); % Button "Quit" butt(1) = uicontrol('style','push','pos',[82 23 70 20],'fontweight','bold',... 'string','Quit','call','analyzer(''quit'')','visible','off'); % Button "Proceed" butt(2) = uicontrol('style','push','pos',[317 23 70 20],'fontweight','bold',... 'string','Proceed','call','analyzer(''proceed'')','visible','off'); % Button "Close Plots" butt(3) = uicontrol('style','push','pos',[200 23 70 20],'fontweight','bold',... 'string','Close Plots','call','analyzer(''closeplot'')','visible','off'); % Label "No. of points to be plotted : " stepText = uicontrol('style','text','pos',[220 72 150 20],'backgroundcolor',[0.8 0.8 0.9],... 'string','No. of points to be plotted : '); % Default number of points (degree of accuracy) noPoints = 100; % Call sequence for number of points to be drawn no = [ 'sh = get(gcf,''user'');','noPoints = deblank2(get(sh(25),''string''));'... 'sh(24)=str2num(noPoints);','set(sh(25),''string'',noPoints);'... 'set(gcf,''user'',sh);']; % Text field for stepText stepEdit = uicontrol('style','edit','pos',[360 75 50 20],'backgroundcolor','w',... 'string',num2str(noPoints),'horizon','center','call',no); % Label "Version number" v_name = uicontrol('style','text','pos',[400 300 70 20],'foregroundcolor',[0.4 0.4 0.4],... 'string','Version 2.0','backgroundcolor',[0.95 0.85 0.75]); % Record the handles in the User Data of the Set Up figure. sh = [frame,eq,wind,butt,WINvect,noPoints,stepEdit]; set(gcf,'user',sh); set(get(gcf,'child'),'vis','on'); % Record the equation and independent variable in the User Data sm = str2mat(Tname,equation); set(frame(1),'user',sm); % Setting up some initial conditions newFig = -1; eqStrCur = []; noOfPlots = []; eqStrMat = [cellstr('')]; curFigure = 0; maxPlotNo = 0; indepVar = [cellstr('')]; noOfPoints = []; % Proceed sequences elseif strcmpi(action,'proceed') % Proceed connects Setup with the Display window. sh = get(gcf,'user'); sm = get(sh(1),'user'); % Obtain the current independent variable and equation Tname = deblank(sm(1,:)); equation = deblank(sm(2,:)); % Checks whether the equation is solvable (checking syntax also) findIfEquationGood( Tname, equation ); % Checking whether to overlay on the same plot window overlap = get(ocheck,'Value'); % Obtain the current number of points noPoints = sh(24); % Call sequences for zoom menu in plot window zoomCmd1 = ['h = findobj(gcf,''Label'',''Zoom &in'');',... 'if strcmp(get(h,''checked''),''off'') ','zoom on;',... 'set(h,''Checked'',''on'');','else zoom off;',... 'set(h,''Checked'',''off''); end;']; zoomCmd2 = ['zoom off;' 'zoom out;' 'h = findobj(gcf,''Label'',''Zoom &in'');',... 'set(h,''Checked'',''off'');']; % Setting up the window for the plot to be drawn % Drawing the graph on new plot window if (overlap == 0 | newFig == -1) % Information required for the equations list printed in Command window plotCase = 1; curFigure = curFigure + 1; indepVar(curFigure) = cellstr(Tname); noOfPlots(curFigure) = 1; noOfPoints = sh(24); eqStrCur = cellstr(equation); % Plot window properties newFig = figure('name',['ANALYZER PLOT No. ' num2str(curFigure)],'numb','off','color',[0.8 0.9 0.9],... 'CloseRequestFcn',['warndlg(cellstr({''You can only close this plot from'',',... '''main interface by clicking ''''Close Plots'''' button''}))'],'MenuBar','none'); % Customised menu f = uimenu('Label','&Menu'); uimenu(f,'Label','&Copy to clipboard','Callback','print -dbitmap',... 'Accelerator','C'); uimenu(f,'Label','&Print...','Callback','printdlg','Accelerator','P'); uimenu(f,'Label','&Quit ANALYZER','Separator','on','Callback','analyzer(''quit'')','Accelerator','Q'); uimenu('Label','&Grid on/off','Callback','grid'); g = uimenu('Label','&Zoom'); uimenu(g,'Label','Zoom &in','checked','off','callback',zoomCmd1); uimenu(g,'Label','Zoom to &original size','callback',zoomCmd2); % Overlay the graph on current plot window else plotCase = 2; if (strcmp(strvcat(indepVar(curFigure)),Tname)) noOfPlots(curFigure) = noOfPlots(curFigure) + 1; noOfPoints = [noOfPoints sh(24)]; newFig = figure(newFig); set(newFig,'name',['ANALYZER PLOT No. ' num2str(curFigure)],'numb','off'); eqStrCur = [eqStrCur ; cellstr(equation)]; end end tempNo = size(eqStrCur); if tempNo(1) > maxPlotNo maxPlotNo = tempNo(1); end lineColor = 'bgkrmcy'; % Convert all the equations into the matrix form of size % (row,col) = (number of windows, maximum number of graphs in one window) tempSt = eqStrMat; tempNo2 = size(tempSt); for i = 1:curFigure for j = 1:maxPlotNo eqStrMat(i,j) = cellstr(''); end end for i = 1:tempNo2(1) for j = 1:tempNo2(2) eqStrMat(i,j) = tempSt(i,j); end end for i = 1:tempNo(1) eqStrMat(curFigure,i) = eqStrCur(i); end % Display all the plotted equations in the Command window clc; disp('Analyzer Plotted Equations'); disp('============================'); for i = 1:curFigure s = ['Plot ' num2str(i) ': ']; for j = 1:noOfPlots(i) if j == 1 disp([s, 'x',num2str(j),'(',strvcat(indepVar(i)),') = ',strvcat(eqStrMat(i,j))]); else disp([blanks(length(s)) 'x',num2str(j),'(',strvcat(indepVar(i)),') = ',strvcat(eqStrMat(i,j))]); end end disp(sprintf('\r')); end % In the case of overlaying plots, sends an error if any two graphs % have different independent variables if (plotCase == 2) if (~strcmp(strvcat(indepVar(curFigure)),Tname)) error(sprintf('Independent variables to be drawn on \nthe same plot window must be identical.')); end end % Drawing plot onto the dedicated plot window plots = []; c_ind = 1; s_ind = 1; for ind = 1:tempNo(1) t=linspace(sh(20),sh(21),noOfPoints(ind)); eval( strcat( Tname, '=t;')); eqEvalStr = places(strvcat(eqStrMat(curFigure,ind))); if s_ind == 1 lineStyle = '-'; s_ind = s_ind+1; elseif s_ind == 2 lineStyle = '--'; s_ind = s_ind+1; elseif s_ind == 3 lineStyle = 'x-'; s_ind = s_ind+1; elseif s_ind == 4 lineStyle = '-.'; s_ind = s_ind+1; else lineStyle = '.-'; s_ind = 1; end if (strcmp(strvcat(indepVar(curFigure)),Tname)) plots(ind) = plot(t,eval(strcat(eqEvalStr,'+t-t')),[lineColor(c_ind),lineStyle]); hold on; end if (s_ind == 1) c_ind = c_ind + 1; if (c_ind > 7) c_ind = 1; end end end if (strcmp(strvcat(indepVar(curFigure)),Tname)) axis([sh(20),sh(21),sh(22),sh(23)]) title(['Output Plot No.' num2str(curFigure)]) xlabel(Tname); ylabel('x'); lstr = []; for i = 1:length(plots) lstr = strvcat(lstr,char(eqStrMat(curFigure,i))); end legend(plots,lstr,0); end % Closing plot windows sequences elseif strcmpi(action,'closeplot') % this looks for any opened plot windows and % forces to close all found. figs = get(0,'children'); for (figno = 1:length(figs)) nn = get(figs(figno),'name'); TTT = findstr(nn,'ANALYZER PLOT No.'); SSS = findstr(nn,'WARNING!!'); if (~isempty(TTT)|~isempty(SSS)) delete(figs(figno)) end end newFig = -1; eqStrCur = []; noOfPlots = []; eqStrMat = [cellstr('')]; curFigure = 0; maxPlotNo = 0; noOfPoints = []; % Quitting sequences elseif strcmpi(action,'quit') % 'quit' is the callback of the Quit buttons on the ANALYZER Setup and % Display windows. It provides for an orderly exit, deleting all % associated windows. selection = questdlg(strvcat('This will quit Analyzer and close all the',... 'corresponding plots, do you wish to continue?'),... 'Quit Analyzer','Yes','No','Yes'); if strcmp(selection, 'Yes') figs = get(0,'children'); for (figno = 1:length(figs)) nn = get(figs(figno),'name'); TTT = findstr(nn,'ANALYZER'); SSS = findstr(nn,'WARNING!!'); if (~isempty(TTT)|~isempty(SSS)) delete(figs(figno)) end end end end; % We wish to do this in a separate function to ensure a separate scope % which MATLAB will automagically create for us on a function invokation. % Function algorithm and idea was implemented by Kelsey Grant. function findIfEquationGood( TName, equation ) eval( strcat( TName,'= 0;')); eval( equation ); % Small function to put in . after the "*","^" and "/" % in an equation, so it can be solved vector-wise function t=places(t) placestimes=find(t=='*'); placespower=find(t=='^'); placesdiv=find(t=='/'); place=sort([placespower,placesdiv,placestimes]); many=length(place); for i=1:many t=[t(1:place(i)-1),'.',t(place(i):length(t))]; place=place+1; end