\chapter{Programming}
\label{ch4}
\index{programming}

	One of the most useful features of $\Psi$lab is its ability
to create and use functions.  This allows the development of specialized
programs which can be integrated into the $\Psi$lab package in a simple and
modular way through the use of libraries.  In this chapter we 
treat the following subjects.
\begin{itemize}
	\item Programming Tools
	\item Defining and Using Functions
        \item Definition of Operators for New Data Types
	\item{Debbuging}
\end{itemize}	
Creation of libraries is discussed in a later chapter.

\section{Programming Tools}

	$\Psi$lab supports a full list of programming tools
including looping, conditional branching, case selection,
and creation of new environments.  Most programming tasks
should be accomplished in the environment of a function.
Here we explain what programming tools are available.

\subsection{Comparison Operators}\index{programming!comparison operators}
There exists five methods for making comparisons between the
values of data objects in $\Psi$lab. These comparisons are listed
in the following table.

\begin{center}
\begin{tabular}{|c|c|}
\hline
{\tt == } or {\tt =} & equal to \\ \hline
{\tt < } & smaller than \\ \hline
{\tt > } &  greater than \\ \hline
{\tt <= } & smaller or equal to \\ \hline
{\tt >= } & greater or equal to \\ \hline
{\tt <> } or {\verb!~=!} & not equal to \\ \hline
\end{tabular}
\end{center}

These comparison operators are used for evaluation
of conditionals and for looping.

\subsection{Loops}\index{programming!loops}
Two types of looping exist in $\Psi$lab: the 
{\tt for}\index{for@{\tt for}} loop
and the 
{\tt while}\index{while@{\tt while}} loop.  The {\tt for} loop
steps through a vector of indices each time performing the
commands delimited by and {\tt end}.  
\begin{verbatim}
 
--> x=1;for k=1:4,x=x*k,end
 x         =
 
    1.  
 x         =
 
    2.  
 x         =
 
    6.  
 x         =
 
    24.  
\end{verbatim}
The {\tt for} loop can iterate on any vector or matrix taking for values
the elements of the vector or the columns of the matrix.
\begin{verbatim}
 
--> x=1;for k=[-1 3 0],x=x+k,end
 x         =
 
    0.  
 x         =
 
    3.  
 x         =
 
    3.  
\end{verbatim}
The {\tt for} loop can also iterate on lists. The syntax is the same as for
matrices.

	The {\tt while} loop repeatedly performs a sequence of commands 
until a condition is satisfied.
\begin{verbatim}
--> x=1; while x<14,x=2*x,end
 x         =
 
    2.  
 x         =
 
    4.  
 x         =
 
    8.  
 x         =
 
    16.  

\end{verbatim}

\subsection{Conditionals}\index{programming!conditionals}
Two types of conditionals exist in $\Psi$lab: the 
{\tt if}-{\tt then}-{\tt else}-{\tt elseif}\index{if-then-else@{\tt if-then-else}}
conditional and the 
{\tt select}-{\tt case}\index{select-case@{\tt select}-{\tt case}} 
conditional.  The 
{\tt if}-{\tt then}-{\tt else} conditional
evaluates an expression and if true executes the
instructions between the {\tt then} statement and the {\tt else} statement
(or {\tt end} statement).
If false the statements between the {\tt else} and the {\tt end}
statement are executed.  The {\tt else} is not required. The {\tt elseif}
has the usual meaning and is a also a keyword recognized by the interpreter.
\begin{verbatim}
 
--> x=1
 x         =
 
    1.  
 
--> if x>0 then,y=-x,else,y=x,end
 y         =
 
  - 1.  
 
--> x=-1
 x         =
 
  - 1.  
 
--> if x>0 then,y=-x,else,y=x,end
 y         =
 
  - 1.  
\end{verbatim}


	The {\tt select}-{\tt case} conditional
compares an expression to several possible expressions and performs the
instructions following the first case which equals the initial expression.
\begin{verbatim}
 
--> x=-1
 x         =
 
  - 1.  
 
--> select x,case 1,y=x+5,case -1,y=sqrt(x),end
 y         =
 
    i    
\end{verbatim}
It is possible to include an {\tt else} statement for the condition
where none of the cases are satisfied.

\section{Defining and Using Macros (functions)}
\label{s4.2}
\index{programming!macros}
\index{macros}
\index{macros!definition}

	It is possible to define a function directly in
the $\Psi$lab environment, however, the most convenient mode
is to create a file containing the function
with a text editor.  In this section we describe the
structure of a function and several $\Psi$lab commands which are
used almost exclusively in a function environment.

\subsection{Function Structure}
Function structure must obey the following format
\begin{verbatim}
function [y1,...,yn]=foo(x1,...,xm)
   .
   .
   .
\end{verbatim}
where {\tt foo} is the function name, the {\tt xi} are the m input arguments
to the function,  the {\tt yj} are the n output arguments from the function, and
the three vertical dots represent the list of instructions performed by
the function.  An example of a function
which calculates $k!$ is as follows\index{macros!{\tt getf}}\index{getf@{\tt getf}}
\begin{verbatim}
function [x]=fact(k)
  k=int(k);
  if k<1 then, 
     k=1; 
  end,
  x=1;
  for j=1:k,
     x=x*j;
  end,
\end{verbatim}
If this function is contained in a file called {\tt fact.sci} the function
is loaded into the $\Psi$lab environment and is used as follows.
\begin{verbatim}
--> exists('fact')
 ans       =
 
    0.  
 
--> getf('../macros/fact.sci')
 
--> exists('fact')
 ans       =
 
    1.  
 
--> x=fact(5)
 x         =
 
    120.  
 
--> comp(fact)
\end{verbatim}
In the above $\Psi$lab session the commands 
{\tt exists}\index{macros!{\tt exists}}\index{exists@{\tt exists}} indicates that
{\tt fact} is not in the environment (by the $0$ response).  The
function is loaded into the environment using {\tt getf} and now {\tt exists}
indicates that the function is there (the $1$ response).  The example 
calculates $5!$. Finally, the function
is compiled using {\tt comp} for faster execution.

\subsection{Special Function Commands}
$\Psi$lab has several special commands which are used almost exclusively
in functions.  These are the commands 
{\tt argn}\index{argn@{\tt argn}}, 
{\tt error}\index{error@{\tt error}}, 
{\tt warning}\index{warning@{\tt warning}}, 
{\tt pause}\index{pause@{\tt pause}},
{\tt break}\index{break@{\tt braek}}, and
{\tt return}\index{return@{\tt return}}.  
The command {\tt argn} yields the number of input
and output arguments for the function.  The command {\tt error}
is used to suspend the operation of a function, to print an error message,
and to return to the
previous level of environment when an error is detected.  
The command {\tt pause} temporarily suspends the operation of a function.
The {\tt resume} or {\tt return} command is used to return to 
the calling environment and to pass local
variables from the function environment to the calling environment. 
The following example loads a function called {\tt foo} into $\Psi$lab which 
illustrates these commands.
\begin{verbatim}
 
-->getf('../macros/foo.sci')
 
-->foo
 foo       =
 
[z]=foo(x,y)
 
--> z=foo(0,1)
error('division by zero');
                          !--error 10000 
division by zero                                                                
at line       4 of function    foo      called by :  
 z=foo(0,1)
 
 
--> z=foo(2,1)
 
-1-> resume
 z         =
 
    0.7071068  
 
--> s
 s         =
 
    0.5  
 
\end{verbatim}
In the example we load {\tt foo.sci} and display the contents of the
function.  The first call to {\tt foo} passes an argument which cannot
be used in the calculation of the function.  The function discontinues operation
and indicates the nature of the error to the user.  The second call
to the function suspends operation after the calculation of {\tt slope}.
Here the user can examine values calculated inside of the function,
perform plots, and, in fact perform any operations desired which are
allowed by $\Psi$lab.  The {\tt -1->} prompt indicates that the current
environment created by the {\tt pause} command is the environment 
of the function and not that of the calling environment.  Control is 
returned to the function by the command {\tt return}.  Operation of the
function can be discontinued by the command {\tt quit} or {\tt abort}.
Finally the function terminates its calculation returning the
value of {\tt z}.  Also available in the environment is the variable
{\tt s} which is a local variable from the function which is passed to
the global environment.

\section{Definition of Operations on New Data Types}
\label{s4.3}
\index{operations!for new data types}

	It is possible to transparently define fundamental operations 
for new data types in $\Psi$lab.
That is, the user can give a sense to multiplication, division, addition, etc.
on any two data types which exist in $\Psi$lab.  As an example, two linear
systems (represented by lists)
can be added together to represent their parallel inter-connection
or can be multiplied together to represent their series inter-connection.
$\Psi$lab performs these user defined operations by searching for functions
(written by the user) which follow a special naming convention described
below.

	The naming convention $\Psi$lab uses to recognize operators 
defined by the user is determined by the following conventions.  The name
of the user defined function is composed of four (or possibly three)
fields.  The first field is always the symbol {\tt \%}.  
The third field is one of the characters in the following table
which represents the type of operation to be performed between the
two data types.

\begin{center}
\begin{tabular}{|c|c|}
\hline 
\multicolumn{2}{|c|}{Third field}
\\ \hline \hline
SYMBOL & OPERATION 
\\ \hline \hline
\verb!a! & \verb!+!  \\ \hline

\verb!b! & \verb!;!  (row separator)\\ \hline

\verb!c! & \verb![ ]! (matrix definition) \\ \hline

\verb!d! & \verb!./!  \\ \hline

\verb!e! & \verb!()! extraction: \verb!m=a(k)!  \\ \hline

\verb!i! & \verb!()! insertion:  \verb!a(k)=m!  \\ \hline

\verb!k! & \verb!.*.!  \\ \hline

\verb!l! & \verb!\!  left division \\ \hline

\verb!m! & \verb!*!  \\ \hline

\verb!p! & \verb!^!  exponent \\ \hline

\verb!q! & \verb!.\!  \\ \hline

\verb!r! & \verb!/!  right division \\ \hline

\verb!s! & \verb!-!  \\ \hline

\verb!t! & \verb!'!  (transpose) \\ \hline

\verb!u! & \verb!*.!  \\ \hline

\verb!v! & \verb!/.!  \\ \hline

\verb!w! & \verb!\.!  \\ \hline

\verb!x! & \verb!.*!  \\ \hline

\verb!y! & \verb!./.!  \\ \hline

\verb!z! & \verb!.\.!  \\ \hline
\end{tabular}
\end{center}

The second
and fourth fields represent the type of the first and second data objects,
respectively, 
to be treated by the function and are represented by the symbols given
in the following table.

\begin{center}
\begin{tabular}{|c|c|}
\hline  
\multicolumn{2}{|c|}{Second and Fourth fields}
\\ \hline \hline
SYMBOL & VARIABLE TYPE
\\ \hline \hline

\verb!s! & scalar  \\ \hline

\verb!p! & polynomial \\ \hline

\verb!l! & list (untyped)  \\ \hline

\verb!c! & character chain   \\ \hline

\verb!m! & macro (function) \\ \hline

\verb!xxx! & list (typed)  \\ \hline 
\end{tabular}
\end{center}

A typed list is one in which the first
entry of the list is a character chain where the first
three characters of the chain are represented by the 
{\tt xxx} in the above table.  For example a list
representing a linear system has the form 
{\tt list('lss',a,b,c,d,x0,'c')} and, thus, the {\tt xxx}
above is {\tt lss}.

	An example of the function name which multiplies two
linear systems together (to represent their series inter-connection)
is {\tt \%lssmlss}.  Here the first field is \%, the second field is 
{\tt lss} (linear state-space), the third field is {\tt m} ``multiply''
and the fourth one is {\tt lss}. A possible user function which performs
this multiplication is as follows
\begin{verbatim}
function [s]=%lssmlss(s1,s2)
[A1,B1,C1,D1,x1,dom1]=s1(2:7),
[A2,B2,C2,D2,x2]=s2(2:6),
B1C2=B1*C2,
s=list('lss',[A1,B1C2;0*B1C2' ,A2],...
       [B1*D2;B2],[C1,D1*C2],D1*D2,[x1;x2],dom1),
\end{verbatim}
An example of the use of this function after having loaded it into
$\Psi$lab (using for example {\tt getf} or inserting it in a library) 
is illustrated in the following $\Psi$lab session
\begin{verbatim}
 
-->A1=[1 2;3 4];B1=[1;1];C1=[0 1;1 0];
 
-->A2=[1 -1;0 1];B2=[1 0;2 1];C2=[1 1];D2=[1,1];
 
-->s1=syslin('c',A1,B1,C1);
 
-->s2=syslin('c',A2,B2,C2,D2);
 
-->ssprint(s1)
 
.   | 1  2 |    | 1 |    
x = | 3  4 |x + | 1 |u   
 
    | 0  1 |    
y = | 1  0 |x   
 
-->ssprint(s2)
 
.   | 1 -1 |    | 1  0 |    
x = | 0  1 |x + | 2  1 |u   
 
y = | 1  1 |x + | 1  1 |u   
 
-->s12=s1*s2;   //This is equivalent to s12=\%lssmlss(s1,s2)
 
-->ssprint(s12)
 
    | 1  2  1  1 |    | 1  1 |    
.   | 3  4  1  1 |    | 1  1 |    
x = | 0  0  1 -1 |x + | 1  0 |u   
    | 0  0  0  1 |    | 2  1 |    
 
    | 0  1  0  0 |    
y = | 1  0  0  0 |x   
\end{verbatim}
Notice that the use of {\tt \%lssmss} is totally transparent in
that the multiplication of the two lists {\tt s1} and {\tt s2}
is performed using the usual multiplication operator, {\tt *}.

The directory {\tt SCIDIR/macros/percent} contains all the functions
(a very large number...) which perform operations on linear systems
and transfer matrices. Conversions are automatically performed.
For example the code for the function {\tt \%lssmlss} is there (note
that it is much more complicated that the code given here!).
\section{Debbuging}
The simplest way to debug a $\Psi$lab function is to introduce
a {\tt pause} command in the function.
When executed the function stops at this point and prompts {\tt -1->}.
The user can then display all the current variables present in $\Psi$lab,
which are inside or outside the function i.e. local in the function
or belonging to the calling environment. The execution of the function
is resumed by the command {\tt return} or {\tt resume}.
The execution of the function can be interrupted by {\tt abort}.
%and the current loop is terminated by {\tt break}.

It is also possible to insert breakpoints in functions. See the commands
{\tt setbpt}, {\tt delbpt}, {\tt disbpt}.
Finally, note that it is also possible to trap errors during the 
execution of a function: 
see the commands {\tt errclear} and {\tt errcatch}.
