% Math 32a   Fall 2003  Richard Palais  Brandeis Univ.

%       Topic for Today:   Programming with M-Files.
%
% 1)  Review of Script M-Files
% 2)  Review of Function M-Files
% 3)  More Advanced Features of Function M-Files
%      ¥ Variable number of input and output parameters (nargin and nargout)
%      ¥ Global Variables---Workspaces and their Relation to each other
%      ¥ Sub-functions
%      ¥ Functions as parameters	(using feval)					
%      ¥ Introduction to De-bugging										
%       
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%- Script M-Files (review)
%		-They are just a shorthand way to enter commands
%		- should be a list of commands (and comments)
%		- Variables introduced in a script file continue 
%		   to live in the Matlab basic Workspace after the 
%		   script finishes executing
%
%    - Example of a script M-file (IterateCosScript.m )
%
 t=0;
for i = 1:N  
   t = cos(t); 
 end 
 t

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% - Function M-Files (review)
%		- must begin with the keyword function,  
%		- followed by the list of output variables and an = (if there are any output variables)
%		- followed by the name of the function (which must be the same as the name 
%		     of the M-file without the .m),
%		- followed by list of input arguments (in parentheses),
%		-  followed by the list of commands to be executed.
%		- So here is the general schema for a function M-File with the name FcnName.m,  
%		   output variable x, y,..., and input variables a,b,...
%		   
%  function     [x,y,...] = FcnName(a,b,...)    
%  <command> 
%  <command> 
%  ... 
%
% EXAMPLE: filename   PolarToRect.m   

function     [x,y] = PolarToRect(r,theta)
% This function takes two real input parameters, r and theta, that 
% represent the polar coordinates of a point on the plane, and
% returns two real output parameters, x and y, representing the 
% cartesian coordinates of the same point.
  x = r*cos(theta);
  y = r*sin(theta);
%
%   
% - Variables introduced in function M-files are "local" to the function---that is 
%   they are not part of the basic Workspace, but rather they belong to a special
%   Workspace belonging to the M-File, and they disappear after the script finishes
%   executing. Workspaces, and their inter-relations are discussed in more detail
%   below.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%   
%
%- More Advanced Features of Function M-Files
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%  Variable number of input and output parameters (nargin and nargout)
%
%- The variable nargin:   It is possible to define a Matlab functions that  
%  take a variable number of input arguments. When the user calls the function
%  with a particular mumber of arguments, say n, then a standard Matlab variable 
%  called nargin (for "number of arguments in" gets the value n which then can 
%  be used in the program code to do different things depending on n. Here is the 
%  way it works in a rather artificial example. Suppose we want to be able to add 
%  a variable number of arguments, say up to four. We create a file MyAdd.m containing 
%  the following:
%		   
function    theSum = MyAdd(x,y,z,w)   
 if nargin == 0
   theSum = 0;
elseif  nargin == 1      
   theSum = x ;                
elseif  nargin == 2;     
   theSum = x + y           
elseif  nargin == 3 ;
   theSum = x + y + z ;                   
elseif  nargin == 4;      
   theSum = x + y + z + w ;                                
end
 theSum

% - There is a similar variable nargout that gives the number of output variables actually 
%  used in a given call of a function with several output parameters.
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% -  Global Variables---Workspaces and their Relation to each other
%
%  A Matlab program that does something reasonably complex will often use
%  many different functions that are either built in Matlab functions or 
%  else user defined functions defined in some M-File. It is important to
%  be able to communicate information (e.g., the current values of variables)
%  between these functions. Now remember that each M-File has its own private 
%  Workspace which is different from the base Workspaceof the command window.
%  Suppose you declare a variable named X in the command window and also declare  
%  variables named X in two different function M-Files. If you now call these 
%  functions in the command window, or if you call one of these functions from 
%  the other, then the different variables named X are unrelated, and changing 
%  the value of one of them does not effect the others. So how can you communicate
%  information back and forth between M-Files and the command window. You can 
%  probably guess the answer---the best way to do this is to use the input and
%  output variables of the functions as we have been doing. However, this is 
%  sometime inconvenient and Matlab does have anothr mechanism (which should 
%  be used sparingly) and this is the so-called global Workspace. You can declare
%  a variable, say Z to be global as follows:
  global Z
%  and then it belongs to the global Workspace. If you declare a variable to 
%  be global in the command window and again in several M-Files, then they 
%  are all the same variable, and if you change the value in any of these places
%  it will change it in the others. 
%  NOTE: It is conventional to use all capital letters for global variables!
%  
%  Example: Create an M-file called TestGlobal.m containing the following:

function     outVar = TestGlobal(inVar)
%  This function demonstrates passing values with parameters and 
%  using global variables
 outVar = inVar;
 inVar = 2;
 X = 0;
 global Y
 Y = 0;
 
 %  Now in the command window, suppose we enter the following:
 %
 a = 1;
 b = 0;
 X = 1;
 global Y
 Y = 1;
 a = TestGlobal(b)
 b
 X
 Y
 %
 % Can you guess what the output will be?
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% -  Sub-functions									
%   
%  It is a good idea in programming to break up a complicated 
%  algorithm into a sequence of smaller sub-algorithms. In Matlab,
%  this means that we will often create a function M-File by calling a 
%  lot of other functions, either built in or defined in M-Files.
%  However, if you are ONLY going to use some simple function as a 
%  sub-routine in defining some other "main" function, then Matlab 
%  permits you to define the simple function in the same M-File 
%  as the main function. These so-called sub-functions are defined 
%  just as if they were a normal function, except they are placed at 
%  the end of the M-File in which they will be used (and cannot be used
%  outside that file).
%
%  Example   Create an M-file called TestSubFunction.m containing the following:

function      y = TestSubFunction(x)

    y = Double(Square(x));   % so y = 2 * x * x

%%%%%%%%%%%%%%  Sub Functions  %%%%%%%%%%%%%%%%%%%%%
function   y = Double(x)
   y = 2*x;
   
function    y = Square(x)
   y = x * x;
   
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% -  Functions as Parameters  	(using feval)	

%  Very frequently we want to create functions whose arguments are
%  other functions---integration is a typical example, as are its
%  approximating quadrature rules. Usually we will want to substitute
%  for such a function argument a function that is either defined in an
%  M-File or is a "built-in" function like sin.  Matlab has a function 
%  called feval to make this possible. If MyFcn is the name of a function 
%  of n variables, then  feval('MyFcn',a1,a2,...,an) is the same as
%  MyFcn(a1,a2,...,an).   Here is an example of how this gets used.
%  Suppose we want to define a Matlab function called Trapezoidal with 
%  parameters a function f, and two real numbers a, and b, that we want 
%  to return the trapezoidal estimate of the integral of f from a to b, 
%  namely 0.5*(f(a) + f(b)). In Matlab version 5 and earlier it is NOT 
%  possible to have a function as the parameter of a Matlab function 
%  BUT it is possible to have a string as a parameter, so we define 
%  Trapezoidal in a Matlab M-file called Trapezoidal.m as follows:
%
 function        A = Trapezoidal(f,a,b)
     A = 0.5*(b-a)*(feval(f,a) + feval(f,b));
%  
%  Notice that this assumes that the parameter f is a string that will
%  hold the NAME of some function.
%   Now suppose that in an M-File  afcn.m we define a function afcn
%   as follows:
%
function   z = afcn(x)
  z = x^2 + 2*x + 4;
%  Then to estimate the integral of afcn from 0 to 1  and put the result
%  in a variable z, we would use the function call:
%
   z = Trapezoidal('afcn',0,1);
%
%   Note carefully the quotes around afcn. 
%   The same thing works for a built-in function like sin
%
   z = Trapezoidal('sin',0,1);
   %
%   We can also use Trapezoidal on a function F defined using inline. 
%   For example if we define the same unction as above using inline 
%   and call it afcni: 
%
   afcni = inline('x^2 + 2*x + 4', 'x')
%
%  then the Trapezoidal approximation to the integral is given by    
%
   z = Trapezoidal(afcni,0,1);
%
%  THAT'S RIGHT---without the quotes! That is because the inline 
%  function actually returns a string. In fact we can do the above
%  evaluation more simply in one step, without defining MyFcnI as follows: 
%
   z = Trapezoidal(inline('x^2 + 2*x + 4', 'x'),0,1);
%
%  Of course this is NOT very elegant---it is both inconsistent and 
%  non-intuitive and so leads to lots of programming errors. In the 
%  most recent version of Matlab (version 6) this problem has been 
%  fixed. It now IS possible to have as a parameter of a Matlab 
%  function another Matlab function (rather than the string that is
%  its name, so in Matlab version 6 we could define the Trapezoidal
%  function by 
%
 function        A = Trapezoidal(f,a,b)
     A = 0.5*(b-a)*(f(a) + f(b));
%  
%  avoiding the use of feval. Then we would call it consistently  
%  as
%
  z = Trapezoidal(afcn,0,1);
  
%  or
%
   z = Trapezoidal(sin,0,1);
%
%  or
%
  z = Trapezoidal(inline('x^2 + 2*x + 4', 'x'),0,1);
%
%  However for this course, I would pefer for you to 
%  stick with the Matlab version 5 conventions.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% - Introduction to De-bugging										
%       
%  No matter how experience you become or how careful 
%  you are, you will always make errors, i.e., bugs
%  are a fact of programming life, and you will have 
%  to learn to live with that fact. That does not mean 
%  that you have to live with the bugs---it means that
%  you must learn how to test for them and how to 
%  eliminate them when you find them. This is a very 
%  big topic and we can only scratch the surface here.
%
%  There is one basic, time-tested strategy for debugging,
%  which is to stop the program at various points (so-called)
%  breakpoints) and then test the values of variables to 
%  see if they have the values you expect them to. In Matlab
%  if you put the word "keyboard" into an M-File, then any
%  time the programm reaches that point, the program stops 
%  running and you can type various commands to check the 
%  values of variables (or change them). To restart the execution
%  of the M-File, type the six letters "RETURN" and then 
%  the return key
%  

