function fixedpoint(action)
%FIXEDPOINT  Explore the behavior of one point iterations
%
% Call simply as fixedpoint with no arguments.
%
% This program explores graphically the iteration x(n+1) = g(x(n)).
% To use it type "fixedpoint" and then click the "Help" button.
%
% By default the function g(x) = c x (1-x) defined in the file
% iterfun.m is used.  To change this, see the customization section
% below.
%
% author: Douglas N. Arnold, 9/96, 12/96


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%  customization section
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Set limits of axes and give name of m-file containing function
% to iterate.  The latter should be a function of one vector
% variable returning a vector of the same length.  It may
% depend on the global parameter c which is set interactively
% by the user.
xmin=0;
xmax=1;
iterfunfile='iterfun';
title='Successive substitution for  g(x) = c x (1-x)';
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%  end customization section
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


% The routine works by establishing a bunch of callbacks which are all
% to fixedpoint(action) for different actions.  A lot of variables
% have to be declared global to be shared by the different calls.

global c cbox fixedfig stairaxes iteraxes xframe xbox xprompt
global ibutton y x n nmax helpfig helpfigup

if nargin == 0,
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%  initialize
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% open window
  fixedfig = figure(...
    'Name',title,...
    'NumberTitle','off',...
    'Position',[50,50,500,800]);
  % set up control widgets
  %  c text entry box
  cframe = uicontrol(gcf,...
    'Style','frame',...
    'Position',[5 5 115 30]);
  cprompt = uicontrol(gcf,...
    'Style','text',...
    'String','Enter c: ',...
    'Position',[10 10 60 20]);
  cbox = uicontrol(gcf,...
    'Style','edit',...
    'String','    ',...
    'Position',[75 10 40 20],...
    'CallBack','fixedpoint(''setc'')');
  %  x0 text entry box
  xframe = uicontrol(gcf,...
    'Style','frame',...
    'Position',[125 5 115 30],...
    'Visible','off');
  xprompt = uicontrol(gcf,...
    'Style','text',...
    'String','Enter x0:',...
   'Position',[130 10 60 20],...
    'Visible','off');
  xbox = uicontrol(gcf,...
    'Style','edit',...
    'String','    ',...
   'Position',[195 10 40 20],...
   'CallBack','fixedpoint(''setx0'')',...
   'Visible','off'); 
  %  "Iterate" button, "Reset" button, "Help" button
  ibutton = uicontrol(gcf,...
    'Style','push',...
    'String','Iterate',...
    'Position',[250 10 55 20],...
    'CallBack','fixedpoint(''iterate'')',...
    'Visible','off');
  rbutton  = uicontrol(gcf,...
    'Style','push',...
    'String','Reset',...
    'Position',[314 10 55 20],...
    'CallBack','fixedpoint(''clearall'')',...
    'Visible','on'); 
  hbutton = uicontrol(gcf,...
    'Style','push',...
    'String','Help',...
    'Position',[378 10 55 20],...
    'CallBack','fixedpoint(''help'')',...
    'Visible','on');
  qbutton = uicontrol(gcf,...
    'Style','push',...
    'String','Quit',...
    'Position',[442 10 55 20],... 
    'CallBack','fixedpoint(''quit'')');
  % set up axes for the stairstep plot
  stairaxes = axes('Position',[.1 .55 .85 .4],'Box','on','Visible','off');
  % set up axes for the iteration plot
  iteraxes = axes('Position',[ .1 .15 .85 .35],...
    'XLim',[xmin xmax],...
    'YLim',[0,20],...
    'Box','on',...
    'XLimMode','manual',...
    'YLimMode','manual',...
    'Visible','off');
  % help figure initially not up
  helpfigup=0;

elseif strcmp(action,'setc'),
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%  setc callback
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  c=str2num(get(cbox,'String'));
  % initialize the stair step plot:
  % plot the parabola y=g(x) and the line y=x; freeze the axis limits
  % and set next plot to overwrite
  x=linspace(xmin,xmax,100);
  y=feval(iterfunfile,x);
  axes(stairaxes);
  plot(x,y,'y',x,x,'g');
  drawnow
  set(gca,'XLimMode','manual','YLimMode','manual','NextPlot','add')
  % draw a legend
  linex = [.05 .15];
  liney = (get(stairaxes,'YLim')*[.05 .95]')*[1 1];
  line('XData',linex,'YData',liney,'Color','yellow');
  text('Position',[.175 liney(1)],'Color','yellow','String','y = g(x)');
  liney = (get(stairaxes,'YLim')*[.1 .9]')*[1 1];
  line('XData',linex,'YData',liney,'Color','green');
  text('Position',[.175 liney(1)],'Color','green','String','y = x');
  % make axes and x0 text entry widget visible
  set(stairaxes,'Visible','on')
  axes(stairaxes)
  ylabel('g(x)')
  set(iteraxes,'Visible','on')
  axes(iteraxes)
  xlabel('x')
  ylabel('iteration number')
  set(xframe,'Visible','on')
  set(xprompt,'Visible','on')
  set(xbox,'Visible','on')
elseif strcmp(action,'setx0'),
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%  setx0 callback
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  % set x0 from user entry; initialize n (iteration number), and
  % nmax (n rounded up to next multiple of 20, top value on y-axis
  % of iteration plot)
  x=str2num(get(xbox,'String'));
  n=0;
  nmax=20;
  % plot the initial point on the stair step plot
  axes(stairaxes)
  y=feval(iterfunfile,x);
  line(x,y,'LineStyle','.','MarkerSize',20,'Color','red',...
    'erasemode','background')
  % and on the iteration plot
  axes(iteraxes)
  line(x,0,'LineStyle','.','MarkerSize',20,'Color','red',...
    'erasemode','background')
  set(iteraxes,'XLim',[xmin xmax],'YLim',[0,nmax])
  xlabel('x')
  ylabel('iteration number')
  hold on;
  % and display it numerically
  numdisplay=text(...
    'Position',[1,-.15],...
    'Units','normalized',...
    'HorizontalAlignment','right',...
    'VerticalAlignment','top',...
    'Color','yellow',...
    'String',sprintf('x =%8.5f',x));
  % make the "Iterate" button visible
  set(ibutton,'Visible','on')

elseif strcmp(action,'iterate'),
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%  iterate callback
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  % find next iterate
  z=feval(iterfunfile,y);
  % add it to the stair step plot
  axes(stairaxes);
  line([x,y,y],[y,y,z],'Color','red',...
    'erasemode','background')
  line(y,z,'LineStyle','.','MarkerSize',20,'Color','red',...
    'erasemode','background')
  % add it to the iteration plot
  axes(iteraxes);
  line([x,y],[n,n+1],'LineStyle','-','Color','red',...
    'erasemode','background')
  line(y,n+1,'LineStyle','.','MarkerSize',20,'Color','red',...
    'erasemode','background')
  % update the numerical display
  set(numdisplay,'String',sprintf('x =%8.5f',y))
  % update the iteration
  x=y;
  y=z;
  n=n+1;
  % every 20 iterates increase scale of the n axis
  if  rem(n,20) == 0
    nmax=nmax+20;
    set(iteraxes,'XLim',[xmin xmax],'YLim',[0,nmax])
  end

elseif strcmp(action,'clearall'),
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%  clearall callback
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  % reset the c entry box
  set(cbox,'String','    ')
  % erase the other boxes and the iterate button
  set(xframe,'Visible','off')
  set(xprompt,'Visible','off')
  set(xbox,'Visible','off','String','    ')
  set(ibutton,'Visible','off')
  % clear both axes
  axes(stairaxes)
  cla
  axes(iteraxes)
  cla

elseif strcmp(action,'help'),
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%  help callback
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  % Open the help window.
  helpfig = figure('Position',[560,450,420,400],...
    'Name','Help','NumberTitle','off');
  % Define the help string to display.
  helpstr=[
  '                                                                '
  '                         fixedpoint.m by Douglas N. Arnold, 9/96'
  '                                                                '
  '     This program demonstrates the behavior of the iteration    '
  '                                                                '
  '                    x(n+1) = g( x(n) )                          '
  '                                                                '
  '     where by default  g(x)  is the quadratic function          '
  '                                                                '
  '                     g(x) = c x (1-x).                          '
  '                                                                '
  '     To run enter the parameter c and the initial iterate       '
  '     x(0), and then press the "Iterate" button as many times    '
  '     as desired.  The top plot shows the construction of the    '
  '     successive iterates x(n), and the bottom plots x(n) on     '
  '     the x-axis versus n on the y-axis.  The value of the       '
  '     current iterate is shown in the lower right hand corner.   '
  '                                                                '
  '     Hit the "Reset" button to start over with new values for c '
  '     and x(0).                                                  '
  '                                                                '
  '     Suggested values: c in the interval (1,4], x(0) in [0,1].  '
  ];
  % Display it.
  uicontrol(...
     'Style','edit',...
     'Units','normalized',...
     'BackGroundColor',[1 1 .9],...
     'ForeGroundColor',[.2 0 .6],...
     'String',helpstr,...
     'Position',[0 0 1 1],'Max',20);
  % Button to destroy the help window and return to the main fixedpoint.m window.
  uicontrol(...
     'Style','push',...
     'String','Dismiss',...
     'Position',[180 5 60 20],...
     'CallBack','fixedpoint(''deletehelp'')')
   helpfigup=1;

elseif strcmp(action,'deletehelp'),
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%  deletehelp callback
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  if helpfigup,
    delete(helpfig);
  end
  helpfigup=0;
  figure(fixedfig);

elseif strcmp(action,'quit'),
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%  quit callback
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  if helpfigup,
    delete(helpfig);
  end
  delete(fixedfig);
  return;
end
