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 describe the function to iterate (either by
% giving the name of an m-file, a Matlab built-in function, an inline
% function object, or a subfunction defined below.  The iteration
% function 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;
iterfun='itfun';
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 cprompt
global ibutton y x n nmax numdisplay

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

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
  axes(iteraxes)
  cla
  axes(stairaxes)
  cla
  xx=linspace(xmin,xmax,100);
  yy=feval(iterfun,xx);
  line(xx,yy,'Color','yellow');
  line(xx,xx,'Color','green');
  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');
  % which blue highlight from c0 prompt to x0 prompt and enable
  % x0 text entry widget
  set(cprompt,'ForegroundColor','black')
  set(xprompt,'ForegroundColor','blue')
  set(ibutton,'ForegroundColor','black')
  set(xframe,'Enable','on')
  set(xprompt,'Enable','on')
  set(xbox,'Enable','on')
  set(xbox,'String','')
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;
  % redraw the plots from scratch (in case x0 was previously set
  % to a different value)
  axes(iteraxes)
  cla
  axes(stairaxes)
  cla
  xx=linspace(xmin,xmax,100);
  yy=feval(iterfun,xx);
  line(xx,yy,'Color','yellow');
  line(xx,xx,'Color','green');
  drawnow
  set(gca,'XLimMode','manual','YLimMode','manual','NextPlot','add')
  % plot the initial point on the stair step plot
  axes(stairaxes)
  y=feval(iterfun,x);
  line(x,y,'Marker','.','MarkerSize',20,'Color','red')
  % and on the iteration plot
  axes(iteraxes)
  line(x,0,'Marker','.','MarkerSize',20,'Color','red')
  set(iteraxes,'XLim',[xmin xmax],'YLim',[0,nmax])
  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));
  % switch blue hightlight from x0 prompt to Iterate button and enable
  % button
  set(cprompt,'ForegroundColor','black')
  set(xprompt,'ForegroundColor','black')
  set(ibutton,'ForegroundColor','blue')
  set(ibutton,'Enable','on')

elseif strcmp(action,'iterate'),
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%  iterate callback
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  % find next iterate
  z=feval(iterfun,y);
  % add it to the stair step plot
  axes(stairaxes);
  line([x,y,y],[y,y,z],'Color','red')
  line(y,z,'Marker','.','MarkerSize',20,'Color','red')
  % add it to the iteration plot
  axes(iteraxes);
  line([x,y],[n,n+1],'LineStyle','-','Color','red')
  line(y,n+1,'Marker','.','MarkerSize',20,'Color','red')
  % 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','    ')
  % disable the other boxes and the iterate button
  set(xframe,'Enable','off')
  set(xprompt,'Enable','off')
  set(xbox,'Enable','off','String','    ')
  set(ibutton,'Enable','off')
  % clear both axes
  axes(stairaxes)
  cla
  axes(iteraxes)
  cla
  set(cprompt,'ForegroundColor','blue')
  set(xprompt,'ForegroundColor','black')
  set(ibutton,'ForegroundColor','black')

elseif strcmp(action,'help'),
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%  help callback
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  % Define the help string to display.
  helpstr={
  '                                                           '
  '              fixedpoint.m by Douglas N. Arnold, 9/96, 9/97'
  '                                                           '
  '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 [0,4], x(0) in [0,1].  '
  };
  % Display it.
  helpdlg(helpstr,'Help on fixedpoint')

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

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%  the iteration function
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function y=itfun(x)
global c
y=c*x.*(1-x);

