\input texinfo	@c -*-texinfo-*-
@comment Copyright (C) 1994-2003  K. Scott Hunziker.
@comment Copyright (C) 1990-1994  The Boeing Company.
@comment %**start of header (This is for running Texinfo on a region.)
@setfilename algae.info
@settitle Algae
@setchapternewpage odd
@comment %**end of header (This is for running Texinfo on a region.)

@ifinfo
@dircategory Programming Languages
@direntry
* algae: (algae).		Another Matrix Programming Language
@end direntry
@end ifinfo

@titlepage
@title The Algae Programming Language
@subtitle For algae VERSION_NUMBER; VERSION_DATE.
@author by K. Scott Hunziker
@tex
\special{papersize=8.5in,11in}
\special{psfile=algae_fig.eps hoffset=-60 voffset=-180}
@end tex
@page
@vskip 0pt plus 1filll
Algae VERSION_NUMBER; VERSION_DATE
@sp 1
Copyright @copyright{} 1994--2003  K. Scott Hunziker.@*
Copyright @copyright{} 1990--1994  The Boeing Company.
@sp 1
Algae is free software.  You may redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
@sp 1
Algae is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
License for more details.
@sp 1
You should have received a copy of the GNU General Public License
along with Algae; see the file @file{LICENSE}.  If not, write to the Free
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.@refill
@sp 1
The copyright to major portions of Algae belongs to The Boeing
Company.  The following permission notice and warranty disclaimer
pertain to those portions of the code:
@sp 1
@quotation
Permission to use, copy, modify, and distribute this software and its
documentation for any purpose is hereby granted, provided that the above
copyright notice appear in all copies, that both the copyright notice
and this permission notice and warranty disclaimer appear in supporting
documentation, and that the names of Boeing or any of its entities not
be used in advertising or publicity pertaining to distribution of the
software without specific, written, prior permission.@refill
@sp 1
BOEING DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
ALL IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS, AND NONINFRINGEMENT.
IN NO EVENT SHALL BOEING BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR
CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
USE, DATA, OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE, OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.@refill
@end quotation

@comment This is funny, but I think that the JIR has a copyright on it.
@ignore
Notice:  The entire physical universe, including this product, may one
day collapse back into an infinitesimally small space.  Should another
universe subsequently emerge, the existence of this product in that
universe cannot be guaranteed.@refill
@end ignore

@sp 1
Caution: Use of this product as a substitute for a healthy physical,
emotional, and spiritual life is not recommended and could be harmful.
@end titlepage
@page

@node Top, About Algae, (dir), (dir)

@ifhtml
@html
<h2>Another Matrix Programming Language</h2>
<h2>VERSION_NUMBER; VERSION_DATE</h2>
<i>by K. Scott Hunziker</i>
<p>
Next time you're in Seattle, visit the
<a href="http://algae.sourceforge.net/">Algae Home Page</a>.
<p>
<hr>

@end html
@end ifhtml

@ifinfo
For algae VERSION_NUMBER; VERSION_DATE.

Typing "q" exits, "?" lists all INFO commands, "h" gives an INFO
tutorial, "m" selects menu items, etc.  Items are selected by any unique
case-insensitive abbreviation of their name.  For example, type "m" and
then "prim" to select the `Primer' item in the menu below.
@end ifinfo

@ifnottex
@menu
* About Algae::			History and acknowledgments.
* Primer::			An introduction to Algae.
* Examples::			Some example programs in Algae.
* Language::			Variables, operators, and expressions.
* Data::        		Scalars, vectors, matrices, ...
* Standard Functions::  	Reference guide for the standard functions.
* Running Algae::	        Starting and running the Algae interpreter.
* Projects::			The Algae wish list.
* Bugs::			Bugs, and how to report them.
* Concept Index::		An item for each concept.
* Function Index::		An item for each standard function.
@end menu

@noindent
Copyright @copyright{} 1994--2003  K. Scott Hunziker.@*
Copyright @copyright{} 1990--1994  The Boeing Company.

Algae is free software.  You may redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

Algae is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
License for more details.

You should have received a copy of the GNU General Public License along
with Algae; see the file @file{LICENSE}.  If not, write to the Free
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.@refill

The copyright to major portions of Algae belongs to The Boeing
Company.  The following permission notice and warranty disclaimer
pertain to those portions of the code:

@quotation
Permission to use, copy, modify, and distribute this software and its
documentation for any purpose is hereby granted, provided that the above
copyright notice appear in all copies, that both the copyright notice
and this permission notice and warranty disclaimer appear in supporting
documentation, and that the names of Boeing or any of its entities not
be used in advertising or publicity pertaining to distribution of the
software without specific, written, prior permission.@refill

BOEING DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS,
AND NONINFRINGEMENT.  IN NO EVENT SHALL BOEING BE LIABLE FOR ANY
SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA, OR PROFITS,
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE, OR OTHER TORTIOUS
ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.@refill
@end quotation

Caution: Use of this product as a substitute for a healthy physical,
emotional, and spiritual life is not recommended and could be harmful.
@end ifnottex

@node About Algae, Primer, Top, Top
@chapter About Algae
@cindex Hunziker, Scott
@cindex Hunziker, Jennifer
@cindex Brennan, Mike
@cindex MATLAB
Algae is an interpreted language for numerical analysis.  Algae was
developed because we needed a fast and versatile tool, capable of
handling large problems.  Algae has been applied to interesting dynamics
problems in aerospace and related fields for more than a decade.@refill

This document describes both Algae, the programming language, and
@code{algae}, the interpreter.  Neither one of them is complete.  Even
so, they offer some unique capabilities that we hope you'll find
useful.@refill

Algae was designed and implemented by Scott Hunziker and Mike Brennan.

Algae grew up in the ``Structures Outback'' of the Boeing Aerospace
Company (now the Boeing Defense & Space Group).  Way back in 1989, Bill
Russell convinced Bob Vos, the head of Boeing's ISM project, that ISM
needed an interactive language.  With Dave Beste's help, Bill put
together a crude system (it looked a lot like MATLAB) with a recursive
descent parser.  They called it ISMLAB.  After Bill got a real job,
Scott Hunziker took over and made major changes.  ISMLAB, along with the
entire ISM project, was cancelled ignominiously in 1991.@refill

Scott Hunziker and Mike Brennan began work on a successor to ISMLAB
called AMPL (A Matrix Programming Language) with internal Boeing
funding.  (The author remembers well the first day of their
collaboration, when he inadvertently showed Mike that AMPL could
multiply two matrices and get the wrong answer.)  As AMPL took shape,
the internal funding dried up, leaving Scott to maintain it in his spare
time.  Boeing generously released AMPL to the public in 1994.  The name
was changed to Alki in 1995 because, by then, an unrelated package
called AMPL was being distributed through netlib.  That name also had a
conflict, and it was finally changed to Algae in early 1997.@refill

Thanks to Don Morris for contributing the plotting code (not to
mention countless bug reports), and Ian Searle for advice, constructive
criticism, and pizza.@refill

@node Primer, Examples, About Algae, Top
@chapter Primer
@cindex Starting algae
@cindex Interactive mode

What follows is a quick introduction to Algae.  It shows many simple
examples, but leaves out the detailed descriptions.  @xref{Language},
for more details about the Algae language.@refill

The first thing that you'll need to know is how to get Algae
started.  If your system is properly set up, it's a simple matter of
typing the command @samp{algae}.  This brings Algae up in
interactive mode; a prompt is displayed and it waits for you to start
typing statements.  Later we'll discuss other options, such as giving
Algae a file of statements to execute in ``batch'' mode.@refill

This manual is available on-line through the @code{info} function; type
@code{info()} to view it.  You can go to a specific topic by naming it
as an argument.  For example, @code{info("operators")} takes you
directly to the description of Algae's operators.@refill

@cindex Statements
@cindex Terminating statements
@cindex Statement terminators
@cindex Newline
@cindex Question mark
@cindex Semicolon
@cindex ? (statement terminator)
@cindex ; (statement terminator)
An Algae @dfn{statement} describes the operations to be performed.  For
example, the statement@refill

@example
1+sin(2)
@end example

@noindent
tells Algae to add 1 to the sine of 2.  Statements may be terminated with
a newline, a semicolon, or a question mark; the results are printed
unless a semicolon is used.@refill

The statement

@example
printf ("hello, world\n");
@end example

@noindent
prints a hopeful little ``hello, world'' message to the terminal.  This
is exactly like the C language, right down to the @samp{\n} escape
sequence to indicate a newline.  If you know C, you'll probably notice
many other similarities between its syntax and that of Algae.@refill

@cindex Variables
Like most computer languages, Algae has @dfn{variables} to which values
can be assigned.  In Algae, these variables need not be declared before
being used, and may be created or destroyed during a session.  If you
type the statement @code{x=1}, the variable @code{x} will be created if
it doesn't already exist.  If @code{x} already had a value, then
assignment to @code{x} destroys its previous contents.@refill

@cindex Entities
@cindex Class of entities
The values taken on by variables are known as @dfn{entities}, which have
various @dfn{classes} such as @samp{scalar}, @samp{vector},
@samp{matrix}, @samp{table}, etc.  A builtin function called
@code{class} returns the class of its argument, so if you make the
assignment @code{x=1} then the statement @code{class(x)} returns
@samp{"scalar"}.@refill

@cindex Converting between classes
@cindex Automatic class conversion
@cindex Class conversions
Notice that a scalar is not the same thing as a one-element vector or as
a one-by-one matrix.  The builtin functions @code{scalar},
@code{vector}, and @code{matrix} may be used to convert from one to
another.  For example, @code{matrix(7)} returns a matrix with one row
and one column, its single element having the value 7.  Algae will often
make these conversions between classes automatically.  In the
code@refill

@example
x = [ 3, 2, 1 ];
y = sort (x);
@end example

@noindent
the @code{sort} function first converts its matrix argument @code{x}
into a vector and then returns another vector with the same elements but
sorted in increasing order.  (An expression enclosed in brackets defines
a matrix, as we'll discuss later.)@refill

@cindex Members
@cindex Entity members
@cindex Dot operator
@cindex Predefined members
@cindex Creating new members
Besides its class, an entity may have other attributes which are stored
as its @dfn{members}.  For example, the number of rows in a matrix is
stored in a member called ``nr''.  Members are referenced with the ``dot''
operator, so if @code{M} is a matrix, then @code{M.nr} returns its row
size.  Most entities have one or more predefined members (such as
@code{nr} in matrices) that you cannot directly modify.  You can create
new members simply by assignment.@refill

A function called @code{show} prints information about an entity and its
members.  Another function, @code{members}, returns a vector containing
the names of all the members of its argument.

@cindex NULL
@cindex Deleting entities
@cindex Operations on NULL
When a non-existent variable or member is referenced, the special value
@code{NULL} is returned.  For example, the line@refill

@example
a = 1; a.nr
@end example

@noindent
(which consists of two statements) prints ``NULL'', since scalars do not
start life with a member @code{nr}.@refill

The NULL constant may be used on the right-hand side of assignments,
effectively deleting the previous value of an entity.  Actually, the
entity still exists, but it has the value NULL.  You can perform a
number of other operations on NULL, such as in@refill

@example
if (x != NULL) @{ x.class? @}
@end example

@cindex Types
@cindex Integer type
@cindex Real type
@cindex Complex type
@cindex Character type
@cindex Strings
All array entities (and that includes scalars) have a member called
@code{type}, which may have one of these values: ``integer'', ``real'',
``complex'', or ``character''.  The constant @code{1} is an integer, but
@code{1.0} has real type.  Algae has no complex constant like Fortran
does---you have to use an expression such as @code{sqrt(-1)}.  Users
often make the assignment @code{i=sqrt(-1)} when they first start up
Algae and then use expressions like @code{1+2*i} for their complex
numbers.@refill

The ``character'' type refers to a string of characters.  It is
specified using double-quotes as we did for @code{"hello world"} above.
A character scalar like @code{"1"} is different than an integer scalar
like @code{1}, and an expression like @code{1+"1"} is not allowed.@refill

@cindex Vectors
@cindex Element numbering in vectors
A @dfn{vector} is a one-dimensional array of values.  For example,
@code{x=1,2,3} specifies a vector with three elements.  The elements in
a vector are numbered starting at one, and the total number of elements
is given by its @code{ne} member.  All of the elements have the same
type.@refill

@cindex Append operator
@cindex Comma
@cindex , (append operator)
Actually, the comma character is Algae's ``append'' operator.  You can
put several expressions together in a vector, as in

@example
v = 1, sin(2), 3+4;
@end example

@cindex Subvector expressions
A ``subvector'' expression may be used to specify a particular element
or elements.  You do that simply by following the vector with a
@dfn{specifier} enclosed in brackets.  For example, @code{v[3]} gives a
scalar having the value of the third element of @code{v}.  If the
specifier is a scalar, then the result is a scalar; otherwise, the
result is a vector.@refill

A more complicated example is@refill

@example
aset = 3, 9, 15;
x = v[aset][2];
@end example

@cindex Subvector assignment
@noindent
Here, @code{x} gets the value of the ninth element of @code{v}.  You can
also assign to a subvector, so @code{v[1]=0} sets the first element of
@code{v} to zero.

@cindex Vector labels
@cindex Matching labels
Vectors have a member @code{eid} (it stands for @i{element id}) that
contains labels for its elements.  You don't need labels (@code{eid} may
be NULL), but they can be pretty useful.  For one thing, they can help
you to avoid errors by not allowing you to perform certain operations
unless the labels match.  If you try to add two vectors and they both
have labels, then the labels must be identical.

@cindex Labels in subvector expressions
You can also use labels instead of element numbers in a subvector
expression.  You do this by using character strings as the specifier.
For example, the code

@example
weight =        172,    216,     188;
weight.eid =  "Tom", "Dick", "Harry";
@end example

@noindent
sets up the vector @code{weight} with character string labels.  Then
@code{weight["Dick"]} gives Dick's weight of 216.@refill

@cindex Generating vectors
@cindex Vector generation
@cindex Generate operator
@cindex Colon
@cindex : (vector generation operator)
Vectors can be generated by using the colon operator.  The expression
@code{1:5:2} gives a vector whose first element is @code{1}, last
element is no more than @code{5}, and has a difference of @code{2}
between each successive element.  In other words, @code{1:5:2} is the
same as @code{1,3,5}.  If you leave off the second colon and the third
operand, then Algae infers a @code{1} for the third operand.  Thus, if
@code{n=100}, then @code{1:n} is the vector containing all the integers
from @code{1} through @code{100}.@refill

@cindex Matrices
A @dfn{matrix} is a two-dimensional array of values.  The expression
@code{[1,2;3,4;5,6]} specifies a matrix with three rows and two
columns---rows are given as vectors and are separated by semicolons.

@cindex Submatrix expressions
@cindex Element numbering in matrices
Submatrix expressions work just like subvector expressions, but with a
semicolon to separate the row specifier from the column specifier.  The
expression @code{M[3;2,3]} gives a vector containing the elements of
@code{M} in its third row and second and third columns.  If both
specifiers are scalars, then the result is a scalar.  If only one
specifier is a scalar, then the result is a vector.  Otherwise, the
result is a matrix.  The members @code{nr} and @code{nc} give the number
of rows and columns of a matrix.@refill

@cindex Matrix labels
@cindex Labels in submatrix expressions
Matrices have both row and column labels.  They're stored in the members
@code{rid} and @code{cid}, respectively.  As with vectors, character
strings used as specifiers in submatrix expressions refer to the
labels.@refill

@cindex Tables
@cindex Braces
A @dfn{table} is an entity that simply holds a collection of other
entities.  For example, the statements@refill

@example
x = 1; y = "foo", "bar";
t = @{ x; y @};
@end example

@noindent
result in a table @code{t} that contains the scalar @code{x} and the
vector @code{y}.  Instead, we could write

@example
t = @{ x = 1; y = "foo", "bar" @};
@end example

@noindent
and get the same table.  In the latter case, though, @code{x} and
@code{y} exist only inside the table.

@cindex Operations on tables
You can put any class of entity into a table, even another table.  The
members are referenced with the ``dot'' operator, just like the other
entities.  The line @code{a=@{u=1;v=2@}; a.u+a.v} prints the value 3.  You
can add two tables (the members of the right-hand table are inserted
into the left-hand table) and subtract two tables (the members of the
left-hand table having the same name as a member of the right-hand table
are removed).@refill

@cindex if statement
@cindex Control-flow statements
@cindex Statements for control-flow
Algae normally executes statements in the order that it receives them,
but the control-flow statements @code{if}, @code{for}, @code{while}, and
@code{try} can change that.  The code@refill

@example
if (x > 0) @{ y = 1/x; @}
@end example

@noindent
is an example of an @code{if} statement.  The parentheses are required
around the test expression.  If that expression is ``true'', then the
statements following it are executed.  The @code{if} statement may also
have an @code{elseif} part, an @code{else} part, or both, so@refill

@example
if (x > 0)
@{
    printf ("positive");
elseif (x < 0)
    printf ("negative");
else
    printf ("zero");
@}
@end example

@noindent
prints the sign of @code{x}.  (But you should use the @code{sign}
function, instead.)@refill

@cindex Relational operators
@cindex Equality operators
@cindex Logical operators
@cindex < (less than operator)
@cindex <= (less or equal operator)
@cindex > (greater than operator)
@cindex >= (greater or equal operator)
@cindex == (equality operator)
@cindex != (inequality operator)
@cindex And operator
@cindex & (and operator)
@cindex Or operator
@cindex | (or operator)
@cindex && (and operator)
@cindex || (or operator)
@cindex Not operator
@cindex ! (not operator)
As long as only scalars are involved, Algae's relational, equality, and
logical operators probably won't surprise you.  An expression is
@code{1} if it's true and @code{0} if it's false.  The relational
operators are @code{>}, @code{>=}, @code{<}, @code{<=}.  The equality
operators are @code{==} and @code{!=}.  The logical operators are
@code{&}, @code{|}, and @code{!}.  Two additional logical operators,
@code{&&} and @code{||}, are special; they are described later.

Where these operators might surprise you is when vectors and matrices
are involved.  Like most Algae operators, they work on an
element-by-element basis.  For example, if @code{A} and @code{B} are
both matrices, then the expression @code{A==B} has several features:

@itemize @bullet
@item
@code{A} and @code{B} must have the same size.

@item
Their labels must match.

@item
The expression returns a matrix with the same size as @code{A} and
@code{B}, every element of which is either @code{1} or @code{0}
depending on whether the corresponding elements of @code{A} and @code{B}
are equal.
@end itemize

@noindent
You can see, then, that @code{A==B} doesn't give you a simple true or
false answer but rather a matrix of answers.

@cindex True
@cindex False
The @code{if} statement, however, does need a simple true or false in
order to decide whether to execute its statements or not.  It does this
by recognizing certain entities as false---all others are true.  The
``false'' entities are as follows:

@itemize @bullet
@item
NULL.

@item
Numeric entities in which every element is zero.

@item
Character entities in which every element is @code{""}.

@item
Vectors and matrices with no elements.

@item
Tables with no members.
@end itemize

@cindex Testing for equality
What gets new users into trouble is a statement like

@example
if (A == B) @{ done = 1; @}
@end example

@noindent
If @code{A} and @code{B} are matrices, then @code{A==B} returns a matrix
of ones and zeros.  The @code{if} statement interprets that as ``true''
if even one of its elements is nonzero.  In words, the above statement
starts out ``If any element of @code{A} is equal to the corresponding
element of @code{B}, then @dots{}''  The difficulty is that the
element-by-element ``equality'' operation is not the same as a test of
the equality of two arrays.  If the latter test is what you really want,
then you should use the @code{equal} function instead.@refill

On the other hand, the statement

@example
if (A != B) @{ done = 0; @}
@end example

@noindent
does work in both senses.  The expression @code{A!=B} returns a matrix
that has nonzero elements where the corresponding elements of @code{A}
and @code{B} are unequal.  Thus this expression also serves as a test of
the inequality of the two arrays.@refill

The @code{&&} ("and") and @code{||} ("or") operators are special in two
ways:  they don't perform element-by-element like the other operators in
this section, and they "short-circuit" by skipping evaluation of the
second operand if the result is already established by the first
operand.@refill

Each operand of @code{&&} and @code{||} is evaluated for "truth" in the
same way that the @code{if} test does.  For @code{&&}, if the first
operand evaluates to "false" then the second operand is not evaluated
and the result of the operation is 0.  For @code{||}, if the first
operand evaluates to "true" then the second operand is not evaluated and
the result of the operation is 1.@refill

For example, in the expression

@example
x != NULL && x.type == "integer"
@end example

@noindent
@code{x} is first checked to see if it's NULL.  If it is, then the first
operand of @code{&&} is 0 and that's also the result of the entire
expression.  In that case, the member reference @code{x.type} is never
evaluated.  This is convenient, since that would otherwise be an
error.@refill

An @code{if} statement such as

@example
if (x < tol) @{ x = tol; @}
@end example

@noindent
could be written instead as

@example
x < tol && (x = tol);
@end example

The parentheses are required in the second version, since the precedence
of @code{=} is lower than that of @code{&&}.  Although they accomplish
the same thing, the first version is recommended; it is easier to read
and executes a bit faster.@refill

@cindex while statement
@cindex Loops
Algae has two control-flow statements that perform looping:
@code{while} and @code{for}.  The @code{while} statement executes a set
of statements over and over, as long as a given condition is true.  For
example, the code@refill

@example
a=0; b=1;
while (b < 10000)
@{
  c = b;
  b = a+b;
  a = c;
@}
c?
@end example

@noindent
computes and prints the largest Fibonacci number less than 10000.  The
interpreter checks to make sure that @code{b<10000}, executes the
statements in the @code{while} block, and then repeats.  The first time
that the expression @code{b<10000} evaluates false, the loop
terminates.@refill

@cindex for statement
@cindex Loops
@cindex in keyword
The @code{for} statement also causes looping, but in a different way.
Assuming that @code{v} is a numeric vector, the code@refill

@example
for (i in 1:v.ne) @{ v[i] = 1 / v[i]; @}
@end example

@noindent
inverts each of its members.  Inside the parentheses, the keyword
@code{in} separates an identifier on the left and a vector expression on
the right.  In this example, the vector expression is @code{1:v.ne}
which contains the integers from 1 to the length of @code{v}.  The
@code{for} loop sets @code{i} equal to the first element, 1, and then
executes the statement @code{v[i]=1.0/v[i];}.  Then @code{i} is set
equal to the second element, and the statement is executed again.  This
cycle repeats until all of the elements of @code{1:v.ne} are used.@refill

@cindex Efficiency of loops
The previous example also illustrates an important topic concerning both
@code{while} loops and @code{for} loops.  Essentially the same results
would be obtained with the statement @code{v=1/v}.  This obviously takes
less typing and is easier to read.  The really important difference,
though, is that it is far more efficient.  With the @code{for} loop, all
of the operations (assignment, division, etc.) are performed by the
interpreter.  Although Algae is fast, it can't possibly compete
with doing the same job in C, as @code{v=1/v} is.  On my computer, it's
about 60 times faster.@refill

@cindex Interrupting loops
@cindex continue statement
Sometimes it's convenient to interrupt the execution of @code{while} and
@code{for} loops.  The @code{continue} statement causes another
iteration of the loop to begin immediately.  If we wanted to invert the
nonzero elements of a vector, we could write@refill

@example
for (i in 1:v.ne)
@{
  if (v[i] == 0) @{ continue; @}
  v[i] = 1 / v[i];
@}
@end example

@cindex break statement
The @code{break} statement goes even further, exiting the loop
altogether.  For example, we could have written our Fibonacci routine
as@refill

@example
a=0; b=1;
while (1)
@{
  c = b;
  if ((b = a+b) > 10000) @{ break; @}
  a = c;
@}
c?
@end example

@noindent
The @code{continue} and @code{break} statements affect execution of only
the innermost enclosing loop.@refill

It's important to note that @code{continue} and @code{break} are
statements, not expressions.  The code@refill

@example
x < 0 && break;
@end example

@noindent
is not valid, since the operands of @code{&&} must be expressions.@refill

@cindex try
@cindex exceptions
@cindex raise an exception
The @code{try} statement is the remaining control-flow statement.  It is
used to modify Algae's response to something called an @dfn{exception}.
When an exception occurs, we say that it has been ``raised''.  Many
error conditions (dividing by zero, running out of memory, etc.) cause
an exception to be raised.  You may also raise an exception directly
by calling the @code{exception} function.@refill

When an exception is raised, Algae's default action is to stop
execution.  If it's running interactively, it returns to the command
line prompt; otherwise it exits completely.  This action can be modified
by using the @code{try} statement.  If an exception is raised within the
@code{try} block, execution continues at the point immediately following
that block.  For example, the statement@refill

@example
try @{ i += 1; @}
@end example

@noindent
increments @code{i} by one if possible.  If an error occurs (say
@code{i} was NULL), then Algae just moves on to execute the next line.
Although it's probably not a good idea, we could use this instead of
@code{break} in the previous Fibonacci example:@refill

@example
a=0; b=1;
try
@{
  while (1)
  @{
    c = b;
    if ((b = a+b) > 10000) @{ exception (); @}
    a = c;
  @}
@}
c?
@end example

@noindent
There's a real difference between these approaches, though.  In the
version using the @code{break} statement, the result is printed only
when the correct value is reached.  In the @code{try} version, the
result is printed regardless of why the exception was raised---if Algae
received an interrupt signal while in the middle of the loop, it would
jump out of the @code{try} block and then print an incorrect value.@refill

@cindex catch
The @code{try} statement has an optional @code{catch} clause, which is
something like the @code{else} clause of an @code{if} statement.  Any
statements that follow @code{catch} are executed only if an exception is
raised while in the preceding part of the @code{try} block.  Also,
exceptions that occur within the @code{catch} block are not handled
specially.  For example,@refill

@example
try
@{
  v = 1/v;
catch
  message ("I can't do that, Dave.");
  exception ();
@}
@end example

would print a message if it had trouble performing the inverse and then
stop execution.  If no exception occurs prior to the @code{catch}
clause, then execution continues following the end of the @code{try}
statement.@refill

The language syntax does not allow a @code{break} or @code{continue}
statement to be positioned such that it would cause execution to jump
out of the @code{try} block.@refill

@cindex Functions
@cindex Builtin functions
@cindex User functions
@cindex Arguments of functions
@cindex Separating arguments
@cindex Passing arguments by value
@cindex Call by value
Like other computer languages, Algae has @dfn{functions}.  Some functions
(like @code{sin} and @code{printf}) are @dfn{builtin}, meaning that they
are part of the Algae executable file.  Others, called @dfn{user
functions}, are those written in the Algae language.  A function is
called by giving its name followed by a parenthesized list of
@dfn{arguments}.  The arguments are separated by semicolons, and their
values are passed to the function.  Since only the values are passed,
the function cannot modify the variables that you pass it.@refill

For example, let's assume that you're calling the function @code{shady}.

@example
x = 1;
y = shady (x);
@end example

@noindent
The value returned by @code{shady} is assigned to @code{y}.  You can't
tell by looking at it what class of entity (scalar, matrix, etc.)
@code{shady} returns.  In fact, that might even change from one call to
the next.  Rest assured, though, the value of @code{x} is still 1, no
matter what happened in @code{shady}.@refill

@cindex Operations on functions
Algae functions are entities---just like scalars and matrices.  That
means that you can perform operations on them as you do with other
entities.  For example, the statement@refill

@example
my_sin = sin
@end example

@noindent
creates a new function called @code{my_sin} that works just like the
original @code{sin} function.  Of course,

@example
sin = NULL;
@end example

@noindent
gets rid of the @code{sin} function completely---probably not a very
good idea in most cases.@refill

@cindex Defining functions
Functions may be defined during an interactive session or simply
included from files.  As an example, consider writing a function called
``findit'' that will look through the elements of a vector for a given
value, returning the locations where it found it.  The following
function should do the job:@refill

@example
findit = function (s; v)
@{
  local (w; i);
  w = vector ();
  for (i in 1:v.ne)
  @{
    if (v[i] == s) @{ w = w, i; @}
  @}
  return w;
@}
@end example

@noindent
@cindex local statement
@cindex Scope of variables
@cindex Global scope
(The builtin function @code{find} does this job much more efficiently.)
The @code{local} statement declares its arguments as having local scope.
For example, the assignment to @code{w} would have no effect outside
this function.  Without the @code{local} declaration, the assignment
would change the value of @code{w} globally.@refill

@cindex return statement
@cindex Recursion
The @code{return} statement causes execution of the function to
terminate and passes it's expression as the function's return value.
Recursive calls to a function are no problem.  For example, we could
write a function to compute factorials as@refill

@example
fact = function (n)
@{
  if (n < 2) @{ return 1.0; else return n * fact (n-1); @}
@}
@end example

@cindex self
This function has one slight problem.  (Several, really, if you consider
that it does no error checking.)  If we later decide to change its name
by typing @code{factorial=fact}, it still calls function @code{fact}
internally.  Now if we're really mean-spirited we can change @code{fact}
as in @code{fact=sin}; now @code{factorial} gives wrong answers.  The
way to handle this is to call the function @code{self} when you make a
recursive function call, as in@refill

@example
fact = function (n)
@{
  if (n < 2) @{ return 1.0; else return n * self (n-1); @}
@}
@end example

The @code{self} keyword refers to the current function.  Besides
recursive function calls, it's also useful for keeping data local to a
function.  For example, consider a function that returns the ``shape''
of its argument:@refill

@example
shape = function (x)
@{
  return self.(class(x)) (x);
@};

shape.scalar = function (x) @{ return NULL; @};
shape.vector = function (x) @{ return x.ne; @};
shape.matrix = function (x) @{ return x.nr, x.nc; @};
@end example

This @code{shape} function determines the class of its argument and then
calls the appropriate member function.  (The standard @code{shape}
function additionally provides some error checking.)@refill

@node Examples, Language, Primer, Top
@chapter Example Programs

Following are several examples designed to show off Algae's capabilities
as well as to give you a feel for how it is used.  The @file{examples}
directory in the source distribution of Algae contains some
additional code for perusal.@refill

@menu
* Temperatures::        Fahrenheit to Celsius conversions
* Reading Numbers::     Reading and summing numbers
* Powers::              Integer powers
@end menu

@node Temperatures, Reading Numbers, Examples, Examples
@section Temperature Conversion
@cindex Temperature conversion program
@cindex Program, temperature conversions

This Algae program prints a table of Fahrenheit temperatures and their
Celsius equivalents:

@example
# Print temperature conversions
fahr = sort (0:300:20, 32, 212);
celsius = (5/9)*(fahr-32);
[fahr;celsius]'?
@end example

@noindent
Its output looks like this:

@example
[         0.000       -17.78 ]
[         20.00       -6.667 ]
[         32.00        0.000 ]
[         40.00        4.444 ]
[         60.00        15.56 ]
[         80.00        26.67 ]
[         100.0        37.78 ]
[         120.0        48.89 ]
[         140.0        60.00 ]
[         160.0        71.11 ]
[         180.0        82.22 ]
[         200.0        93.33 ]
[         212.0        100.0 ]
[         220.0        104.4 ]
[         240.0        115.6 ]
[         260.0        126.7 ]
[         280.0        137.8 ]
[         300.0        148.9 ]
@end example

This program does quite a bit in only four lines.  The entire first line
is a @dfn{comment} (because it starts with @code{#}) and is ignored by
Algae.@refill

In the second line we define the Fahrenheit temperatures for our table.
The expression @code{0:300:20} gives a vector that goes from 0 to 300 in
steps of 20.  We add two more elements, 32 and 212, to that vector by
using the comma operator.  Then we use the @code{sort} function to sort
it in increasing order.  Finally, our vector of Fahrenheit temperatures
is assigned to the variable @code{fahr}.  Nothing is printed by this
statement, since it ends with a semicolon.@refill

The third line computes the Celsius equivalents using the familiar
conversion formula.  First 32 is subtracted from each element of
@code{fahr}.  Then each element is multiplied by 5/9.  The result is
assigned to the variable @code{celsius}.  Here, again, nothing is
printed.@refill

Even though all of the terms so far have been integers, @code{celsius}
is a real-valued vector.  Unlike some programming languages, integer
division in Algae does not result in truncation---the expression
@code{5/9} returns a real value that is approximately 0.556.@refill

The last line prints the temperatures out as a matrix, with the
Fahrenheit temperatures in the first column and their Celsius
equivalents in the second column.  We do that by using brackets to form
a matrix with @code{fahr} in the first row and @code{celsius} in the
second row and then transposing the matrix with the @code{'} operator.
The question mark on the end is not necessary, since the matrix would
also be printed without it, but it does call attention to the line as
one that prints.@refill

@node Reading Numbers, Powers, Temperatures, Examples
@section Reading and Summing Numbers
@cindex Number reading program
@cindex Program, number reading

This Algae program reads a bunch of numbers, adds them up, and prints the
result:

@example
# Read and sum some numbers
sum = 0;
$read = 1;
while ($read) @{ sum += readnum(); @}
sum?
@end example

The program reads numbers one at a time and adds them to @code{sum}, so
in the first line @code{sum} is initialized to zero.  The @code{readnum}
function is used to read the numbers.  This function is one of the few
standard functions that has a side effect:  it assigns to the variable
@code{$read} the number of values that it read.  It will be less than
the number you asked for if @code{readnum} runs out of data.@refill

The @code{while} loop executes its statements repeatedly until its
condition tests true.  We set @code{$read} to 1 (true) first, so we know
that the @code{while} loop will execute at least once.  After that, the
@code{while} loop continues until @code{$read} is eventually set to 0 by
the @code{readnum} function.  When the @code{while} loop is done, the last
line prints @code{sum}.@refill

Usually, we give the @code{readnum} function two arguments: a ``shape''
vector and a file name.  The ``shape'' vector describes the number of
values to read and in what form (vector, matrix, etc.) they should be
returned.  The values are read from the named file.  Since the program
above gives neither argument, @code{readnum} simply reads one value from
the standard input device.@refill

The @code{+=} operator adds the value on the right to the variable on
the left; the expression @code{sum+=readnum()} does the same thing as
@code{sum=sum+readnum()}.  Every time the @code{while} loop repeats,
@code{sum} is increased by the value returned by @code{readnum}.  When
@code{readnum} runs out of data, it returns 0 (so @code{sum} isn't changed)
and sets @code{$read} to 0 (so the @code{while} loop quits
looping).@refill

@cindex End of file
Unless you redirect standard input, this program will quietly read what
you type until you signal an end-of-file (@kbd{C-d} on UNIX systems and
@kbd{C-z} on VMS).@refill

@node Powers, , Reading Numbers, Examples
@section Integer Powers
@cindex Integer power program
@cindex Program, integer powers

This program illustrates the use of a function.  In it, we define the
function @code{power} that computes integer powers of its argument.  We
also show some Algae code that calls @code{power}.@refill

@example
# power:  raise `x' to the `n'-th power
power = function (x; n)
@{
  local (y);
  y = x;
  while (n > 1)
  @{
    y = y * x;
    n -= 1;
  @}
  return y;
@};

power (2; 8)?
power ([ 1, 2; 2, 3 ]; 4)?
@end example

The first line of this program is an ordinary assignment statement,
which assigns the function on its right side to the variable
@code{power}.  The function's arguments are defined in the parentheses
that follow the @code{function} keyword.  In this case, there are two
arguments:  @code{x} and @code{n}.@refill

In Algae, all function arguments are called ``by value''.  When a
function is called, it gets copies of what the calling program gave as
arguments and can modify them without changing the values retained by
the calling program.  In the @code{power} function we decrement
@code{n} each time through the @code{while} loop, but this has no effect
on the calling program.@refill

The @code{local} statement defines its argument, the variable @code{y},
as having local scope.  This means that @code{power} has its own
temporary variable called @code{y} that is defined only within that
function.  This @code{y} is first given the value of @code{x} and then,
inside the @code{while} loop, repeatedly multiplied by @code{x} until
@code{n} is no longer greater than 1.@refill

The value that @code{power} computes is returned to its caller by the
@code{return} statement.  Any expression may follow @code{return}, and
any number of @code{return} statements may appear in a function.  If the
function has no return statement, it returns NULL to its caller.@refill

The first time we call @code{power}, it returns (and the calling program
prints) the value 256.  In this case @code{power} is really not very
useful, since we could have obtained the same result with the expression
@code{2^8} using Algae's exponentiation operator.@refill

The @code{power} function does have a use, though, as the second call to
it shows.  Algae's exponentiation operator performs in an
element-by-element sense, so @code{[1,2;2,3]^4} returns@refill

@example
[           1         16 ]
[          16         81 ]
@end example

@noindent
In contrast, @code{power} performs in a matrix sense.  In the program
above, it returns@refill

@example
[          89        144 ]
[         144        233 ]
@end example

The algorithm used in the @code{power} function above can be improved
upon by using successive squaring:

@example
power = function (x; n)
@{
  if (n == 1)
  @{
    return x;
  elseif (n%2)
    return x * self (x; n-1);
  else
    x = self (x; n/2);
    return x * x;
  @}
@};
@end example

This @code{power} function might be useful, but it's certainly not ready
for prime-time.  Notice that it gives wrong answers if @code{n} is 0 or
a negative integer.  What happens for the expression
@code{power(4;1/2)}, in which @code{n} is not an integer?  To make
@code{power} more robust you'd probably want to add some @code{if}
statements to check for illegal arguments.@refill

@node Language, Data, Examples, Top
@comment  node-name,  next,  previous,  up
@chapter The Algae Language
@cindex Expressions
@cindex Statements

In Algae, variables and operators combine to form expressions and
statements.  The rules for this are mostly conventional; for example,
the statement @code{a=b+c} means that the sum of @code{b} and @code{c}
is assigned to the variable @code{a}.  In Algae, however, the concept
of addition (as well as many other operations) is expanded to include
operations between a variety of data classes.@refill

@menu
* Entities::
* Variables::
* Operators::
* Expressions::
* Statements::
* Functions::
@end menu

@node Entities, Variables, Language, Language
@comment  node-name,  next,  previous,  up
@section Entities
@cindex Entities
@cindex Class of entities

The basic unit of data in Algae is the @dfn{entity}.  Every entity has
an attribute called its @dfn{class} which describes it as a ``scalar'',
``vector'', ``matrix'', etc.  The built-in function @code{class} returns
the class of its argument as a character string.  Thus@refill

@example
x = 1.2E3; class(x)?
@end example

@noindent
prints ``scalar'' and

@example
class (cos)?
@end example

@noindent
prints ``function''.  Naturally, the statement

@example
class (class (log))?
@end example

@noindent
prints ``scalar'', since @code{class} returns a scalar character string.

@cindex Members of entities
@cindex Entity members
Entities also contain @dfn{members}, in which various additional
attributes of the entity are stored.  For example, matrix entities have
members such as @code{type}, @code{density}, and @code{symmetry}.  These
members are themselves entities, so it is not unusual to have several
levels of membership (a member of a member of a member).  @xref{Data},
for a description of the various classes.@refill

@cindex Dot operator
The ``dot'' operator is used to refer to members.  The statements

@example
x = 1; x.type?
@end example

@noindent
print ``integer'', the value of the @code{type} member in @code{x}.  The
line@refill

@example
foo = 1492; foo.bar?
@end example

@noindent
prints ``NULL'', since scalars don't contain a @code{bar} member when
they're created.  You could give it one, of course:@refill

@example
foo.bar = "Columbus"
@end example

@node Variables, Operators, Entities, Language    
@comment  node-name,  next,  previous,  up
@section Variables
@cindex Variables
@cindex Defining variables

A @dfn{variable} is a symbol that refers to a named entity; the entity
is known as the symbol's @dfn{value}.  A variable comes into being when
a value is assigned to it; there are no explicit declarations.@refill

@menu
* Variable Names::
* Evaluation::
* Scope::
* Predefined Variables::
@end menu

@node Variable Names, Evaluation, Variables, Variables
@comment  node-name,  next,  previous,  up
@subsection Variable Names
@cindex Variable names
@cindex Names of variables

@cindex Case of variable names
Variables have names consisting of letters, digits, dollar signs
(@kbd{$}) and underscores (@kbd{_}).  A variable name cannot begin with
a digit.  Variable names are case sensitive, so the variables @code{foo}
and @code{Foo} are distinct.@refill

@cindex Global variables
We generally use names that begin with @kbd{$} to refer to global
variables that are set at startup or that have some kind of side effect.
For example, the variable @code{$beep} acts like any other variable, but
also control's Algae's sound effects.  The @code{who} function
does not report variables that begin with @kbd{$} unless you give it the
argument @code{"$"}.@refill

@cindex Symbol table
@cindex $$
@cindex Global symbol table
One variable name is special---the variable @code{$$} refers to the
global symbol table.  For example,@refill

@example
a = "x";
$$.(a)
@end example

@noindent
prints the value of the global variable @code{x}.  You can use @code{$$}
like any other variable, except that you cannot reassign its value.@refill

@cindex Length of variable names
The only limitation on the length of a variable name is that it must
have at least one character.  Short names are convenient for interactive
work, but longer, descriptive names have advantages in functions and
scripts.@refill

@node Evaluation, Scope, Variable Names, Variables
@subsection Evaluation of Variables
@cindex Evaluation of variables
@cindex Variable evaluation

When a variable name is encountered in an expression, it is evaluated by
replacing the variable name with the corresponding named entity.  If it
is an argument to a function, then a copy is made (conceptually, if not
in fact) and passed to the function.  Thus, in a function call like
@code{func(a)} (@pxref{Functions}), the function @code{func} only gets a
copy of @code{a} and can't modify the @code{a} belonging to its
caller.@refill

There is one exceptional case, involving the ``dot'' operator, in which
an identifier is not evaluated as a variable name.  An identifier on the
right side of a member expression is taken literally as the name of the
member.  For example, the statement@refill

@example
v.type
@end example

@noindent
prints the value of @code{v}'s member called @code{type}.  You could
well have a variable named @code{type}, but it would not affect the
member expression above.@refill

Alternatively, the statement

@example
v.(type)
@end example

has an expression to the right of the ``dot'' operator, not a simple
identifier, and so prints the value of the member of @code{v} named by
the variable @code{type}.

@node Scope, Predefined Variables, Evaluation, Variables
@comment  node-name,  next,  previous,  up
@subsection Scope of Variables
@cindex Scope of variables
@cindex Variables, scope
@cindex local statement

Variables referenced from within functions are global in scope unless
they are arguments to the function or are declared local with the
@code{local} statement.  For example, the function@refill

@example
init = function ()
@{
  i = sqrt (-1);
  e = exp (1);
  pi = acos (-1);
@};
@end example

@noindent
could be used to initialize some commonly used variables.  Once you
executed @code{init()}, the variables @code{i}, @code{e}, and @code{pi}
would be globally defined.

At the same time, you could have another function

@example
egg_hunt = function (v)
@{
  local (i);
  for (i in 1:v.ne)
  @{
    if (v[i] == 0) @{ return i; @}
  @}
@}
@end example

@noindent
in which @code{i} has local scope.  Here, you can't modify or even get
the value of the global variable @code{i}.@refill

The form of the @code{local} statement is similar to a function call,
and multiple variables may be specified by separating them by
semicolons.@refill

The @code{local} statement is unusual, in that it is a directive to
the parser rather than something that is coded.  This means that it
takes effect when the parser sees it, not when it's executed.  In the
code@refill

@example
f = function ()
@{
  a = 1;
  if (0) @{ local (a); @}
  a = 2;
@}
@end example

@noindent
the global variable @code{a} gets set to 1.  Even though the code in
the @code{if} block is not executed, after seeing it the parser
considers @code{a} to be a local variable.  Normally, one simply puts
@code{local} statements at the beginning of a function.@refill

@cindex veil statement
The @code{veil} statement allows you to make a temporary change to a
global variable which will remain active from that point until the end
of the current dynamic scope, typically until the function ends.  For
example, the function@refill

@example
prt = function (x)
@{
  veil (pi);
  pi = "apple";
  bake ();
@};
@end example

@noindent
changes the value of the global variable @code{pi} while it's
executing, but @code{pi} reverts to its previous value when @code{prt}
finishes.  If the function @code{bake} referred to @code{pi}, it would
use or modify the temporary value.@refill

By dynamic scope, we refer to the current execution unit.  Within a
function, that lasts as long as the function is executing.  Otherwise,
the dynamic scope is the current file, except that for the @code{eval}
and @code{exec} functions it is the argument string itself.  Also, if
executing in interactive mode and not in a function, then the dynamic
scope extends only to the end of the last statement on a line.@refill

Unlike the @code{local} statement, the effect of the @code{veil}
statement takes place at the time it is executed.  Once a variable is
veiled (and before you set it to something else), it has the same
value as the associated global variable.@refill

@node Predefined Variables, , Scope, Variables
@subsection Predefined Variables
@cindex Predefined variables
@cindex Variables, predefined

Several variables are already defined for you when Algae starts
up.  Some of these are used to control Algae, and some provide you
information.  The predefined variables are:@refill

@table @code
@cindex Beep
@item $beep
If this variable is ``true'' (that is, @code{test($beep)} returns 1),
then error messages include a BEL character.  This causes most terminals
to beep.  On startup, @code{$beep} is 0.@refill

@cindex Digits to print
@item $digits
This variable specifies the number of significant digits that
Algae prints for real and complex numbers.  On startup,
@code{$digits} is 4.@refill

@cindex PID
@item $pid
On startup, @code{$pid} contains the ``process id'' of the Algae
process.@refill

@item $program
On startup, @code{$program} gives the name of the current Algae
program.  This will normally be @code{"algae"}.  It would be different
if, for example, you had changed the name of the Algae executable.@refill

@cindex Prompt
@item $prompt
This variable controls Algae's interactive prompt.  It is expected
to be a character vector with two elements---on startup it is@refill

@example
(  "> ", "  " )
@end example

@noindent
The first element is Algae's first-level prompt.  When Algae
is waiting for another line of input before it executes what it has
already seen, it presents its second-level prompt.  The second element
of @code{$prompt} defines this second-level prompt.  If Algae
can't make sense of @code{$prompt}'s value, it does without a
prompt.@refill

@item $read
The @code{$read} variable is set as a side-effect of the @code{readnum}
function.  It reports the number of values read in the last call to
@code{readnum}.@refill

@cindex Terminal, width
@cindex Width of terminal
@cindex Wrapping lines
@item $term_width
This variable tells Algae the width of your terminal in
characters.  Algae will attempt to adjust its display to fit
within this width.  On startup, Algae will attempt
to sense this on its own.  If @code{term_width} is set to 0,
Algae will not wrap lines.@refill

@item help
This is simply a character scalar that provides a few basic instructions
for using Algae.@refill
@end table

You may wish to set some of these variables (like @code{$beep} or
@code{$prompt}) every time you use Algae.  This is conveniently
done by putting the assignments in the @file{.algae} file in your home
directory.@refill

@node Operators, Expressions, Variables, Language
@section Operators
@cindex Operators

Algae has unary, binary, and ternary operators to perform a variety of
operations.  The standard arithmetic operators (@samp{+}, @samp{-},
@samp{*}, @samp{/}, etc.) are available and have the usual precedence.
The caret @samp{^} is for exponentiation: 8^2 equals 64.  The single
quote character @samp{'} denotes the conjugate transpose.@refill

With a few exceptions, all operators work in the ``element by element''
sense.  For example, if @code{A} and @code{B} are matrices with the same
size, then @code{A/B} returns a matrix, each element of which is the
quotient of the corresponding elements of @code{A} and @code{B}.
The @samp{*} operator works in an ``inner product'' sense, so @code{A*B}
is a matrix multiplication.  The @samp{@@} operator is Algae's ``element
by element'' multiplication operator.@refill

@cindex Type conversions
@cindex Conversions between types
@cindex Automatic type conversion
When an operator has array operands of different types, one will be
automatically converted so that they have a common type, if possible.
An @code{integer} may be converted to @code{real} or @code{complex}, and
a @code{real} may be converted to @code{complex}.  No conversion to or
from @code{character} type is possible.@refill

Unlike some other languages, the result of an operation in Algae may have
a type that is different than its operands.  For example, the result of
@code{1/2} has @code{real} type, even though its operands have type
@code{integer}.  Another example is @code{(-1)^0.5}, which returns a
complex number.@refill

@cindex Class conversions
@cindex Conversions between classes
@cindex Automatic class conversion
With the exception of @code{*}, if a binary operator has both a
@code{vector} and a @code{matrix} as its operands the @code{vector} is
converted to a @code{matrix} before the operation is performed.  Upon
conversion, a vector becomes a matrix with one row.  For example, in the
statement@refill

@example
( 1, 2 ) + [ 3, 4 ]
@end example

the left-hand operand of @code{+} is the vector @code{(1,2)}.  This is
converted to a @code{matrix} before being added to @code{[3,4]}.@refill

@cindex Precedence of operators
@cindex Associativity of operators
@cindex Operators, precedence
@cindex Operators, associativity
The following table summarizes the precedence and associativity of
Algae's operators.  Those shown on the same line have equal precedence,
and the rows are in order of decreasing precedence.

@table @asis
@item @strong{operators}
@strong{associativity}

@item @code{()}  @code{[]}  @code{.}
left to right

@item @code{'}
right to left

@item @code{^}
right to left

@item @code{!}  @code{+}  @code{-}
(unary) left to right

@item @code{*}  @code{/}  @code{%}  @code{@@}
left to right

@item @code{+}  @code{-}
(binary) left to right

@item @code{<}  @code{>}  @code{<=}  @code{>=}  @code{==}  @code{!=}
left to right

@item @code{&}
left to right

@item @code{|}
left to right

@item @code{&&}
left to right

@item @code{||}
left to right

@item @code{:}
left to right

@item @code{,}
left to right

@item @code{=}  @code{+=}  @code{-=}  @code{*=}  @code{/=}  @code{@@=}  @code{%=}
right to left
@end table

@menu
* Call::		@samp{()}
* Element::		@samp{[]}
* Member::		@samp{.}
* Transpose::		@samp{'}
* Power::		@samp{^}
* Not::			@samp{!}
* Negation::		@samp{+} and @samp{-} (unary)
* Multiplication::	@samp{*}, @samp{/}, @samp{%}, and @samp{@@}
* Addition::		@samp{+} and @samp{-} (binary)
* Relation::		@samp{<}, @samp{>}, @samp{<=}, @samp{>=}, @samp{==}, and @samp{!=}
* And::			@samp{&}
* Or::			@samp{|}
* Short And::		@samp{&&}
* Short Or::		@samp{||}
* Generate::		@samp{:}
* Append::		@samp{,}
* Assign::		@samp{=}, @samp{+=}, @samp{-=}, @samp{*=}, @samp{/=}, @samp{@@=}, and @samp{%=}
@end menu

@node Call, Element, Operators, Operators
@subsection Function Calls
@cindex Function calls
@cindex Calling functions
@cindex () function calls

Functions are called in the usual way:  the function reference is
followed by a list of arguments.  For example,@refill

@example
w = union (u; v);
@end example

@noindent
calls the function @code{union}, passing it the values of @code{u} and
@code{v} for arguments.  The value returned by the function's
@code{return} statement (or NULL if it doesn't have one) is the value of
the function call.@refill

@cindex Arguments of functions
The arguments may be any expressions, and are separated by semicolons.
The called function gets only the values of the expressions you give it
as arguments, so it can't modify the variables that you give it.@refill

From its definition, the function knows how many arguments to expect.
Passing too many arguments is an error.  If you pass fewer arguments
than the function definition calls for, NULL's are passed in place of
the missing ones.@refill

@cindex Parentheses
Besides their use in function calls, parentheses are used for several
other purposes, including grouping expressions, @code{if}, @code{for},
and @code{while} conditions, function definitions, etc.@refill

@node Element, Member, Call, Operators
@subsection Element References
@cindex Element references
@cindex Referencing elements
@cindex Brackets
@cindex [ ] (element reference)

The element reference operation returns specified vector elements or
matrix rows and columns.  Applied to a table, the operation is performed
on each of the table's members.

Elements are referenced by following a vector or matrix expression with
a bracket-enclosed list of the desired elements.  For vector @code{v},
the expression @code{v[w]} gives the elements specified by @code{w}.
The expression within the brackets is expected to be a scalar or a
vector---if it's a matrix, it will be converted into a vector if
possible.  So, for example,@refill

@example
v[3:8]
@end example

@noindent
prints the third through eighth elements of @code{v}.  If the vector
inside the brackets has a numeric type, then it is converted to integer
if necessary (by taking the real part and rounding) and then used to
refer to the element numbers.@refill

The class of the element reference expression is determined by the class
of the specifiers.  Once any matrix specifiers are converted to vectors,
the dimension of the result is equal to the sum of the dimensions of the
specifiers.  For example, @code{M[1;2]} is a scalar, @code{M[[1];2]} and
@code{M[1;[2]]} are vectors, and @code{M[[1];[2]]} is a matrix.  Notice
that the class of the result does not depend on the class of the
original entity.@refill

If the vector inside the brackets has character type, then it is taken
to refer to the element labels instead of the element numbers.  For
example, if you set @code{x} as@refill

@example
x = 1:3;
x.eid = "this", "that", "other";
@end example

@noindent
then @code{x["that"]} returns 2, the value of the element of @code{x}
having the label @code{"that"}.  If the labels do not have character
type, they are temporarily converted to character type for the
comparison.@refill

Element references work the same way for matrices, except that both rows
and columns are specified.  For example,@refill

@example
M[ 1,3; 7:12 ]
@end example

@noindent
specifies rows 1 and 3, columns 7 through 12, of the matrix @code{M}.

The specifiers need not be irredundant.  For example, @code{M[1,1,1;]}
returns three copies of the first row of @code{M}.@refill

Besides their use for element references, brackets are also used to form
matrices.@refill

@node Member, Transpose, Element, Operators
@subsection Member References
@cindex Member references
@cindex Referencing members
@cindex Dot operator
@cindex . (member reference operator)

Members of an entity are referenced with the ``dot'' operator.  For
example, @code{x.type} returns the value of @code{x}'s member
@code{type}.  Notice that, if the right-hand operand is an identifier,
then it is taken literally as the name of the desired member.  You might
have a variable called @code{type}, but that is irrelevant when it comes
to evaluating @code{x.type}.@refill

On the other hand, if the right-hand operand is an expression, then its
value (converted to a character scalar) is taken as the desired member
name.  Since you can change an identifier into an expression simply by
enclosing it in parentheses, the expression @code{x.(type)} does use the
value of the variable @code{type} as the name of the member.@refill

@cindex Member names
@cindex Names of members
Member names do not share the same limitations as variable names.  In
fact, any string of ASCII characters (excluding NUL) will work.  This
can be pretty useful.  For example, you could set up a ``vector'' of
entities (of any class) as in

@example
V = @{@};
V.(1) = A;
V.(2) = B;
V.(3) = C;
V.(4) = D;
@end example

@noindent
and then refer to the individual ``elements'' (that is, the members of
@code{V}) by number.  You could handle multiple dimensions by referring
to element @code{"3,2,4"}, for example.

@node Transpose, Power, Member, Operators
@subsection Transpose
@cindex Transpose operator
@cindex Conjugate transpose operator
@cindex Apostrophe
@cindex ' (conjugate transpose operator)

The transpose operator applies the conjugate transpose operation to a
matrix.  For integer, real, and character types, this means moving every
element from row @code{i} and column @code{j} to row @code{j} and column
@code{i}.  If the matrix has complex type, the complex conjugate
operation is applied as well.@refill

If you want the transpose of a complex matrix @code{M}, and not its
conjugate transpose, then use the expression @code{conj(M')}.@refill

If transpose is applied to a scalar or vector, the entity is first
converted to a matrix and then transposed.  For example, @code{(1,2)'}
is the same as @code{[1;2]}---the vector is first converted into a
matrix with one row and then transposed to form a matrix with one
column.@refill

If this operator is applied to a table, then the operation is performed
on each member of that table.@refill

@node Power, Not, Transpose, Operators
@subsection Power
@cindex Power operator
@cindex Circumflex
@cindex ^ (power operator)

The ``power'' operator @samp{^} is a binary operator that raises its
left operand to the power of its right operand.  Thus @code{2^3} gives
8.  It associates right-to-left, so the expressions @code{x^y^z} and
@code{x^(y^z)} are equivalent.@refill

When vectors and matrices are involved, the ``power'' operator performs
in an ``element-by-element'' sense.  For example, if @code{M} is a
matrix, then @code{M^2} squares each element of @code{M}.  This is
definitely not the same thing as @code{M*M}!@refill

In an expression such as @code{2^M}, where the left operand is scalar
and the right operand is a vector or matrix, the result has each element
@code{i} of @code{M} replaced by @code{2^M[i]}.  For example,@refill

@example
2^(0:3)
@end example

@noindent
prints the vector @code{(1,2,4,8)}.

Notice that the precedence of @samp{^} is higher than @samp{-}, so the
expression @code{-1^2} returns @code{-1}.@refill

In mathematical usage, @code{0^0} is undefined---it yields an error in
Algae.@refill

If both left and right operands are arrays, then they must have
matching dimensions and labels.@refill

If this operator is applied to a table, then the operation is performed
on each member of that table.@refill

@node Not, Negation, Power, Operators
@subsection Not
@cindex Not operator
@cindex Exclamation mark
@cindex ! (not operator)

The @samp{!} operator is a unary, prefix operator that returns 1 if its
operand is considered ``false'', and 0 otherwise.  The ``false''
operands are:@refill

@itemize @bullet
@item
NULL.

@item
Numeric entities in which every element is zero.

@item
Character entities in which every element is @code{""}.

@item
Vectors and matrices with no elements.

@item
Tables with no elements.
@end itemize

If this operator is applied to a table, then the operation is performed
on each member of that table.@refill

@node Negation, Multiplication, Not, Operators
@subsection Negation
@cindex Negation operator
@cindex Unary minus operator
@cindex Unary plus operator
@cindex Affirmation operator
@cindex Minus sign
@cindex Plus sign
@cindex -- (negation operator)
@cindex + (affirmation operator)

The unary negation operator @samp{-} multiplies its numeric argument by
@code{-1}.  The @samp{+} operator is for user convenience---Algae ignores
it in its unary context.  For example, @code{+-1} gives a negative one.
On the other hand, @code{1+-1} and @code{1-+1} both return 0.@refill

If one of these operators is applied to a table, then that operation is
performed on each member of the table.@refill

@node Multiplication, Addition, Negation, Operators
@subsection Multiplication
@cindex Multiplication operators
@cindex * (multiplication operator)
@cindex @@ (element-by-element multiplication operator)

Both the @samp{*} and the @samp{@@} operators perform multiplication.
The difference is that @samp{@@} performs in an element-by-element sense,
while @samp{*} performs in an inner product sense.  The operands of
@samp{@@} must have matching dimensions and labels; each element of its
left operand is multiplied by the corresponding element of the right
operand.  For example,@refill

@example
( 1, 2, 3 ) @@ ( 4, 5, 6 )
@end example

@noindent
returns the vector @code{(4,10,18)}.

When @samp{*} is applied to matrices, the number of columns of the left
operand must equal the number of rows of the right operand, and the
corresponding labels must match.  The result is a matrix that has the
same number of rows as the left operand and the same number of columns
as the right operand.@refill

If one of the operands of @samp{*} is a vector and the other is a
matrix, the vector is (conceptually) converted to a matrix before the
multiplication is performed.  If on the left, it is converted to a
matrix with one row; if on the right, it is converted to a matrix with
one column.@refill

Multiplication of two vectors gives their inner product.

@cindex Division operator
@cindex / (division operator)
The @samp{/} operator performs division.  Like @samp{@@}, it performs in
an element-by-element sense.@refill

If either operand of any of these operators is a scalar, then the
operation is performed in an element-by-element sense.  For example@refill

@example
2*(1,2,3)
@end example

@noindent
gives @code{(2,4,6)}---every element of the vector is multiplied by the
scalar.@refill

@cindex Modulus operator
@cindex % (modulus operator)
The @samp{%} operator performs the modulus operation, producing the
remainder when the left operand is divided by the right operand.  For
example, @code{(2,2.5,3)%2} returns the vector @code{(0,0.5,1)}.@refill

The result has the same sign as the left operand.
If this operator is applied to a table, then the operation is
performed on each member of the table.@refill

@node Addition, Relation, Multiplication, Operators
@subsection Addition
@cindex Addition operator
@cindex Subtraction operator
@cindex + (addition operator)
@cindex -- (subtraction operator)

The ``addition'' operators are the binary operators @samp{+} and
@samp{-}.  If their operands are numeric, then they perform the normal
addition and subtraction operations.

@cindex Catenation, string
@cindex Concatenation, string
@cindex String concatenation
When the @samp{+} operator is applied to character strings, it catenates
them.  The @samp{-} operator is not defined for character strings.

Between two tables, @samp{+} combines their members in the resulting
table.  Conceptually, the members of the left operand are inserted in
this new table first, followed by the members of the right operand.
This means that if the operands have a member with the same name, the
value of that member in the resulting table comes from the right
operand.  For example, if @code{t} is a table that contains the member
``foo'', then the result of@refill

@example
t + @{ foo = NULL @}
@end example

@noindent
is identical to @code{t} except that its member ``foo'' has the value
NULL.@refill

When the @samp{-} operator is applied to tables, the result is a table
that has all the members of the left operand except those that are also
in the right operand.  For example@refill

@example
@{x;y;z@}-@{x;y@}
@end example

@noindent
returns a table that has the single member ``z''.@refill

If just one of the operands is a table, then the operation is performed
between the other operand and each member of the table.@refill

@node Relation, And, Addition, Operators
@subsection Relation
@cindex Relational operators
@cindex < (less than operator)
@cindex <= (less or equal operator)
@cindex > (greater than operator)
@cindex >= (greater or equal operator)
@cindex == (equality operator)
@cindex != (inequality operator)

The relation operators @samp{<}, @samp{>}, @samp{<=}, @samp{>=},
@samp{==}, and @samp{!=} return ``true'' (1) or ``false'' (0) to reflect
the truth of the expression.  For example,@refill

@example
(1:5) < 3
@end example

@noindent
returns @code{(1,1,0,0,0)}.

If both operands are arrays, then their dimensions and labels must
match.@refill

Unlike most of the operators, @samp{==} and @samp{!=} allow NULL as an
operand.  In that case, the other operand is simply checked to see if
it is or is not a NULL.@refill

If one of these operators is applied to a table, then that operation is
performed on each member of the table.@refill

@node And, Or, Relation, Operators
@subsection And
@cindex And operator
@cindex & (and operator)

The @samp{&} operator performs the logical ``and'' operation in an
element-by-element sense.  For example,@refill

@example
x = 1:5;
x > 2 & x < 4
@end example

@noindent
prints @code{(0,0,1,0,0)}.

If this operator is applied to a table, then the operation is performed
on each member of that table.@refill

@node Or, Short And, And, Operators
@subsection Or
@cindex Or operator
@cindex | (or operator)

The @samp{|} operator performs the logical ``or'' operation in an
element-by-element sense.  For example,@refill

@example
x = 1:5;
x < 2 | x > 4
@end example

@noindent
prints @code{(1,0,0,0,1)}.

If this operator is applied to a table, then the operation is performed
on each member of that table.@refill

@node Short And, Short Or, Or, Operators
@subsection Short And
@cindex And operator
@cindex Short And
@cindex && (and operator)

The @samp{&&} operator performs the ``short-circuit'' logical ``and''
operation.  Both operands are evaluated for ``truth'' as if they were
the test of an @code{if} statement.  If the left operand is ``false'',
then the right operand is not evaluated.  If both operands are ``true'',
the result of the operation is 1; otherwise the result is 0.  Note that
this operation is quite different from that of the @samp{&} operator,
which works element-by-element.@refill

The following example code is from the @code{solve} function:

@example
if (options != NULL && members (options) == "pos")
@{
  A = chol (A);
else
  A = factor (A);
@}
@end example

@noindent
The variable @code{options} is first checked to see if it's NULL.  Only
if it is not NULL is the @code{member} function called.  That's just
what we want, since it would be an error to call @code{member} with a
NULL argument.@refill

@node Short Or, Generate, Short And, Operators
@subsection Short Or
@cindex Or operator
@cindex Short Or
@cindex || (or operator)

The @samp{||} operator performs the ``short-circuit'' logical ``or''
operation.  Both operands are evaluated for ``truth'' as if they were
the test of an @code{if} statement.  If the left operand is ``true'',
then the right operand is not evaluated.  If either operand is ``true'',
the result of the operation is 1; otherwise the result is 0.  Note that
this operation is quite different from that of the @samp{|} operator,
which works element-by-element.@refill

In the statement

@example
if (options == NULL || options.tol == NULL) @{ tol = 1e-6; @}
@end example

@noindent
the variable @code{options} is first checked to see if it's NULL.  Only
if it is not NULL is the member reference @code{options.tol}
evaluated.@refill

@node Generate, Append, Short Or, Operators
@subsection Generate
@cindex Generate operator
@cindex Vector generation
@cindex Colon
@cindex : (vector generation operator)

Numeric vectors may be generated with the @samp{:} operator.  An
expression like @code{i:j} generates a vector that starts with the value
of @code{i}.  If @code{j} is greater than @code{i}, each successive
element is 1 greater than the previous one, with the last element less
than or equal to @code{j}.  If @code{j} is less than @code{i}, each
successive element is 1 less than the previous one, with the last
element greater than or equal to @code{j}.@refill

The @samp{:} operator also has a ternary form, as in @code{i:j:k}.  This
does the same thing as @code{i:j} except that successive elements differ
by @code{k} instead of 1.@refill

For complex operands, the operation can be described conceptually in the
complex plane.  A line is drawn between the points @code{i} and
@code{j}.  Then the resulting vector contains the points located on that
line segment beginning at @code{i}, proceeding toward @code{j}, spaced a
distance @code{k} (or 1, if @code{k} is not given) apart.@refill

@node Append, Assign, Generate, Operators
@subsection Append
@cindex Append operator
@cindex Comma
@cindex , (append operator)

The @samp{,} operator ``appends'' its operands.  If the operands are
vectors, then the result is a new vector containing both the operands.
If the operands are matrices, then the result is a new matrix containing
the left operand on the left and the right operand on the right.@refill

If this operator is applied to a table, then the operation is performed
on each member of that table.@refill

@node Assign, , Append, Operators
@subsection Assign
@cindex Assignment operators
@cindex = (assignment operator)
@cindex += (assignment operator)
@cindex --= (assignment operator)
@cindex *= (assignment operator)
@cindex /= (assignment operator)
@cindex @@= (assignment operator)
@cindex %= (assignment operator)

The assignment operators are @samp{=}, @samp{+=}, @samp{-=}, @samp{*=},
@samp{/=}, @samp{@@=}, and @samp{%=}.  The @samp{=} operator returns the
value of the right operand, setting the left operand to that value in
the process.  For example,@refill

@example
a = b = c = 1;
@end example

@noindent
assigns 1 to the variables @code{a}, @code{b}, and @code{c}.  The
assignment operators associate right to left, so first @code{c} is given
the value 1.  The result of that expression, @code{c = 1}, is 1, so that
value is used with @code{b} as if it read @code{b = 1}.@refill

Notice that a test like

@example
if (i = j) ...
@end example

@noindent
is entirely different than

@example
if (i == j) ...
@end example

@noindent
In the first example, @code{i} is assigned the value of @code{j} and
then that value is tested by the @code{if} statement.  In the second
example, the @code{if} statement tests the equality of @code{i} and
@code{j}.  So if @code{i} is 1 and @code{j} is 2, the first example
tests true (as well as changing the value of @code{i}) and the second
one tests false.@refill

Individual elements of an array may be changed; for example

@example
x[3;4:6] = 0, 0, 0;
@end example

@noindent
sets to 0 the elements of @code{x} in row 3 and columns 4 through 6.
The right operand is converted to the same type as the left operand, if
possible, and the dimensions must agree.  However, if the right operand
is a scalar, then it is filled to the appropriate size.  Thus, the
previous example could just as well be written@refill

@example
x[3;4:6] = 0;
@end example

One more thing about array assignments: If the variable on the left is a
vector, but you specify two dimensions for it, then that variable will
be converted into a matrix.  Likewise, if the variable on the left is a
matrix, but you specify only one dimension, then it will be converted
into a vector.  For example, in the code@refill

@example
A = B = [ 1, 2, 3 ];
A[2] = B[;2] = 9;
@end example

@noindent
@code{A} and @code{B} both begin as matrices.  The second element of
each array is then changed to 9.  In the end, though, @code{A} is
changed to a vector because only one dimension was given for it.
@code{B} remains as a matrix.@refill

The other assignment operators (@samp{+=}, @samp{-=}, etc.) are simply
for convenience.  The expression @code{i+=j} means the same thing as
@code{i=i+j}, and @code{i-=j} means the same thing as @code{i=i-j}.  If
the left-hand side is an expression, you should keep in mind that it
will be evaluated twice.  For example,@refill

@example
x[ func() ] += 1
@end example

@noindent
will actually make two calls to the function @code{func}.@refill

@node Expressions, Statements, Operators, Language
@comment  node-name,  next,  previous,  up
@section Expressions
@cindex Expressions
@cindex Assignments

Assignments are made in the normal fashion: @code{a=5} sets the variable
@samp{a} to contain the scalar 5.  Variables are not declared prior to
use, but rather take on the structure and type of whatever is assigned
to them.  You could, for example, enter@refill

@example
a=1;
a=[a,a];
@end example

@noindent
in which case the variable @samp{a} is first a scalar and then a matrix.
A list of the previously defined variables (except functions) is given by
the @samp{who()} function, and a variable can be deleted by assigning
NULL to it.@refill

In addition to simple variables, elements and members can also be specified on
the left hand side of an assignment. For example, the statement@refill

@example
A[ 1:4; 1:4 ] = 3;
@end example

@noindent
assigns 3 to all of the elements of the first 4-by-4 partition of matrix
@samp{A}, leaving the other elements of @code{A} unchanged.  Values can
be assigned to members in the same way.  For example, the
statements@refill

@example
A = [ 1,2,3; 4,5,6 ];
time = [ 1.1, 2.2, 3.3 ];
A.rid = [ "first"; "second" ]
A.cid = time
@end example

@noindent
assign the row and column labels of @samp{A}.

@node Statements, Functions, Expressions, Language
@comment  node-name,  next,  previous,  up
@section Statements
@cindex Statements
@cindex Terminating statements
@cindex Statement terminators
@cindex ? (statement terminator)
@cindex ; (statement terminator)
@cindex Question mark
@cindex Newline
@cindex Semicolon

Statements are terminated by a question mark, a semicolon, or a newline.
Using a question mark or newline causes the value of the statement to be
printed; with a semicolon the printing is suppressed.  A newline
terminates a statement only if it does not occur within parentheses,
brackets, or braces.@refill

Statement termination is implied by the closing brace of an ``if'',
``for'', or ``while'' statement or ``function'' expression.  Printing is
enabled when the terminator is implied.  For example,@refill

@example
for (i in 1:10) @{ i @}
@end example

@noindent
prints all of the integers from 1 to 10.

@cindex Significant digits
@cindex Digits, significant
@cindex Format, real or complex number
When real or complex numbers are printed, Algae prints 4
significant digits by default.  This can be changed with the
@code{digits} function, or just by setting the global variable
@code{$digits}.@refill

@cindex Comments
@cindex # (begin comment)
Comments are introduced with the @samp{#} character.  That character and
any that follow it on the same line are ignored (excluding the
newline).@refill

@node Functions, , Statements, Language
@section Functions
@cindex Functions
@cindex Defining functions

Functions are defined by a function expression, which consists of the
keyword ``function'', followed by a parenthesized list of arguments,
followed by a set of statements enclosed by braces.  For example, Algae's
@code{max} function is defined by something like@refill

@example
max = function (x) @{ return x[imax(x)]; @};
@end example

@noindent
Functions are just another class of entity; the statement above defines
a function and then assigns it to the variable @code{max}.

@cindex Arguments of functions
The arguments are variables that are local to the function.  On entry,
they take on the values of the formal arguments in the calling
expression.  Passing more arguments than are in the function's definition
is an error.  If fewer arguments are passed, then NULL's are passed in
place of the missing arguments.@refill

@cindex Function expressions
The function reference needn't be an identifier---a function expression
works just fine.  For example,@refill

@example
child = (his_functions + her_functions).reproduce();
@end example

@noindent
would combine the tables @code{his_functions} and @code{her_functions},
reference the member @code{reproduce}, call it with no arguments, and
then assign the result to @code{child}.  Notice that, since @samp{.} and
@samp{()} have the same precedence, their left-to-right associativity
causes the member reference to occur first and then the function call.
In an expression like @code{sin(1).type}, the function call is performed
first.@refill

When a function is compiled, information is included that relates its
operations to the file name and line numbers of the source code.  If an
error occurs, this information is useful in tracking down its cause.  In
some cases, this information is undesirable and may be removed with the
@code{strip} function.  The @code{message} function is such a case.@refill

@node Data, Standard Functions, Language, Top
@comment  node-name,  next,  previous,  up
@chapter Data
@cindex Class of entities
@cindex Entities

Entities are the basic objects (constants and variables) in Algae.
They contain members and elements.  Members contain information about
the entity, such as the number of rows in a matrix.  An entity's
elements, if it has any, contain the data such as the value of a scalar.
There are five classes:@refill

@table @samp
@item scalar
@cindex Scalars
@cindex Members of scalars
The @samp{scalar} data structure contains a single element, its value, which
may have any of the data types described above.  Its members are:@refill

@table @samp
@item class
The string @samp{"scalar"}.

@item type
The type (like @samp{"integer"} or @samp{"real"}).
@end table

Notice that a scalar is not the same as a one-element vector or
matrix.@refill

@item vector
@cindex Vectors
The @samp{vector} entity contains a one-dimensional array of elements.
Its members are:@refill

@cindex Members of vectors
@table @samp
@item class
The string @samp{"vector"}.

@item type
The type (like @samp{"integer"} or @samp{"real"}).

@item density
Either @samp{"dense"} or @samp{"sparse"}.

@item ne
The number of elements.

@item nn
The number of non-zero elements.

@item eid
The element labels.
@end table

The element labels of a vector are themselves a vector.

@item matrix
@cindex Matrices
The @samp{matrix} data structure contains two-dimensional arrays of
elements.  It contains zero or more rows and columns.  The members of a
matrix are:@refill

@cindex Members of matrices
@table @samp
@item class
The string @samp{"matrix"}.

@item type
The type (like @samp{"integer"} or @samp{"real"}).

@item symmetry
One of @samp{"general"}, @samp{"symmetric"}, or @samp{"hermitian"}.

@item density
One of @samp{"dense"}, @samp{"sparse"} or @samp{"sparse_upper"}.

@item nr
The number of rows.

@item nc
The number of columns.

@item nn
The number of nonzero elements.  For matrices with ``sparse_upper''
density, this number does not include the elements on the diagonal, all
of which are stored.  Sorry.

@item rid
The row labels.

@item cid
The column labels.
@end table

The row and column labels of a matrix are vectors.  The row label vector
has the same number of elements as its matrix has rows, and likewise for
the column label.@refill

@cindex Tables
@item table
The @samp{table} object is like a bucket that can contain any number of
other objects.@refill

Several functions return tables.  For example, the @code{eig} function
returns a table that contains the matrices @code{values} and
@code{vectors}.@refill

The entities contained in a table are members of it, so they can be
extracted using the @kbd{.} operator.  Thus @code{eig(A).values} returns
the eigenvalues of @samp{A}.@refill

@cindex Functions
@item function
Functions are entities just like scalars and matrices, and can be
operated on in the same manner.  Functions have two members:
@samp{class}, which is @code{"function"}, and @samp{ilk}, which is
either @code{"user"} or @code{"builtin"}.
@end table

@cindex Arrays
@cindex Data types
@cindex Types
The @code{scalar}, @code{vector}, and @code{matrix} classes are known
collectively as @dfn{arrays}.  These are the only classes that contain
elements, and all have the member @code{type} that specifies the data
type.  There are four types:@refill

@table @samp
@item integer
@cindex Integer type
On most machines this is a 32-bit integer, like 42 or -273.

@item real
@cindex Real type
This is a floating point number like 3.1415.  It is stored in 64 bits on
most machines.

@item complex
@cindex Complex type
This is a complex number having both real and imaginary
parts.

@item character
@cindex Character type
This is a character string like @samp{"Hello"}.
@end table

@cindex Constants
@cindex Scalar constants
@cindex Numeric constants
Scalar constants are specified in a manner similar to that used in other
programming languages.  Numeric constants can be given in decimal form,
such as @samp{32} or @samp{32.0}, or in scientific notation, such as
@samp{3.2E1}.  In the latter notation, the letters @samp{e} and @samp{E}
may be used interchangeably to prefix the exponent.  White space (space,
tab, etc.) is significant in that context, of course, so that @samp{1.2e+3}
(1200.0) is definitely not the same as @samp{1.2e +3} (4.2).@refill

@cindex Character constants
@cindex Strings
@cindex Double quotes
@cindex " (quote character)
@cindex \ (backslash character)
@cindex Backslash character
@cindex Escape sequences
@cindex Quote character
A @samp{character} constant is a sequence of one or more characters
surrounded by matching double-quotes.  Within the quotes, the backslash
character may be used to introduce ``escape sequences'' for unusual
characters like @key{newline}.  For example, the string @samp{"\""} is a
string containing a single character (the right double-quote).  The
following escape sequences may be used:@refill

@table @code
@item \a
bell
@item \b
backspace
@item \e
escape
@item \f
formfeed
@item \n
newline
@item \r
carriage return
@item \t
tab
@item \v
vertical tab
@item \ooo
octal number
@item \xhh
hexadecimal number
@end table

@noindent
The escape sequence @code{\ooo} consists of a backslash followed by one,
two, or three octal digits, which are taken to specify the value of the
desired character.  For example, @code{\33} is the ASCII ``escape''
character (which is also given by @code{\e}).  Likewise, the sequence
@code{\xhh} consists of a backslash followed by @samp{x}, followed by
one or two hexadecimal digits, which specify the value of the desired
character.  For example, @code{\x1b} also specifies the ASCII ``escape''
character.@refill

If the character following the backslash is not one of those specified
above, then that character is taken literally.  For example, @code{\"}
specifies the double-quote character---not the end of the character
constant.@refill

@cindex Matrix constants
Matrices may be generated by specifying their elements within brackets.
Commas separate elements within rows and semicolons separate the rows.
Thus @code{[1,2;3,4]} specifies the matrix@refill

@display
[ 1  2 ]
[ 3  4 ]
@end display

@cindex Vector constants
@cindex MATLAB
A vector may be generated by using either of the forms @samp{i:j} or
@samp{i:j:k}.  It is obtained by starting with the value @samp{i} and
incrementing by @samp{k} (or 1 if the first form is used) while
remaining between @samp{i} and @samp{j}, inclusive.  (Notice that this
is not the same format used by MATLAB.)  For example, @code{[1:8:2]} is
the same as @code{[1,3,5,7]}.  All elements within a matrix have the
same type (@samp{integer}, @samp{real}, etc.); conversion will be
performed automatically if possible.@refill

The terms within the brackets may be constants, variables, or
expressions.  For example, @code{[1+2,3]} is the same as @code{[3,3]}.
Matrices may be involved, as long as their dimensions are appropriate.
For example, if the variable @samp{A} is defined to be equal to the
square matrix @samp{[1,2;3,4]}, then a new column could be appended to
it with the expression @code{[A,[5;6]]} to yield@refill

@display
[ 1  2  5 ]
[ 3  4  6 ]
@end display

Matrices may be partitioned by specifying the desired row and column
numbers within brackets.  For example, if @samp{A} is a previously
defined matrix then @code{A[1;1]} specifies a scalar having the value of
the element in the first row and the first column of @samp{A}.  The
semicolon within the parentheses separates the row specifiers from the
column specifiers.@refill

Members of data structures are referred to by using the member operator
@samp{.}.  For example, the number of rows in a matrix is stored in the
member @code{nr}, so @code{A.nr} returns the number of rows in the
matrix @code{A}.  The member operator associates left to right, so that
@code{A.type.type} returns the string @code{"character"}.@refill

@node Standard Functions, Running Algae, Data, Top
@comment  node-name,  next,  previous,  up
@chapter The Standard Functions
@cindex Standard functions

Functions are called by giving their name followed by a parenthesized
list of their arguments.  For example, @code{sqrt(a)} computes the
square root of its argument @samp{a}.  The parentheses are required,
whether they contain any arguments or not.  Functions may take more than
one number and kind of argument.@refill

@menu
* Basic Math::		abs, sin, sqrt, ...
* Arrays::		fill, sparse, zero, ...
* Sets::		union, intersection, ...
* Linear Algebra::	solve, factor, fft, ...
* Numerical Analysis::	ode4, brent, ...
* Basic I/O::		read, printf, ...
* Entity I/O::		get, put, ...
* Execution::		source, system, ...
* Special Tools::	plot, npsol, ...
* Miscellaneous::	who, what, time, ...
@end menu

@node Basic Math, Arrays, Standard Functions, Standard Functions
@section Basic Math

@ifinfo
@menu
* abs::		absolute value
* acos::	arc cosine
* acosh::	arc cosine hyperbolic
* arg::         argument (phase)
* asin::	arc sine
* asinh::	arc sine hyperbolic
* atan::	arc tangent
* atanh::	arc tangent hyperbolic
* atan2::	arc tangent (y/x)
* ceil::        ceiling
* conj::	complex conjugate
* cos::		cosine
* cosh::	hyperbolic cosine
* exp::		exponential
* floor::       floor
* imag::	imaginary part
* integer::	round to nearest integer
* log::		natural logarithm
* log10::       base-10 logarithm
* real::	real part
* round::       round to nearest whole number
* sin::		sine
* sinh::	hyperbolic sine
* sqrt::	square root
* tan::		tangent
* tanh::	hyperbolic tangent
@end menu
@end ifinfo

@node abs, acos, Basic Math, Basic Math

@cindex Absolute value
@cindex Magnitude
@defun abs ( x )
The @code{abs} function returns the absolute value of its numeric
argument.  ``Absolute value'' is synonymous with ``magnitude'' for
complex types.  If @var{x} is non-scalar, every element is replaced by
its absolute value.@refill

@code{x} must be a numeric scalar, vector, or matrix.
@end defun

@node acos, acosh, abs, Basic Math

@cindex Arc cosine
@cindex Inverse cosine
@defun acos ( x )
The @code{acos} function returns the arc cosine of its numeric
argument.  If it's argument is complex or has a magnitude greater than
one, then the result is complex.  Otherwise, the result is real.  If
@var{x} is non-scalar, every element is replaced by its arc
cosine.@refill

The argument @var{x} must be a numeric scalar, vector, or matrix.@refill
@end defun

@node acosh, arg, acos, Basic Math

@cindex Arc cosine hyperbolic
@cindex Hyperbolic arc cosine
@cindex Inverse hyperbolic cosine
@defun acosh ( x )
The @code{acosh} function returns the hyperbolic arc cosine of its
numeric argument.  If it's argument is complex or is less than 1.0, then
the result is complex.  Otherwise, the result is real.  If @var{x} is
non-scalar, every element is replaced by its hyperbolic arc cosine.@refill

The argument @var{x} must be a numeric scalar, vector, or matrix.  Note
that @code{acosh(0)} is not zero, so if @code{acosh} is applied to a
sparse vector or matrix, then a dense array is the result.@refill
@end defun

@node arg, asin, acosh, Basic Math

@cindex Phase
@cindex Argument
@defun arg ( z )
The @code{arg} function returns the argument (phase angle) of its
numeric argument.@refill

See also @code{abs}.
@end defun

@node asin, asinh, arg, Basic Math

@cindex Arc sine
@defun asin ( x )
The @code{asin} function returns the arc sine of its numeric argument.
If it's argument is complex or has a magnitude greater than one, then
the result is complex.  Otherwise, the result is real.  If @var{x} is
non-scalar, every element is replaced by its arc sine.@refill

The argument @var{x} must be a numeric scalar, vector, or matrix.@refill
@end defun

@node asinh, atan, asin, Basic Math

@cindex Arc sine hyperbolic
@cindex Hyperbolic arc sine
@cindex Inverse hyperbolic sine
@defun asinh ( x )
The @code{asinh} function returns the hyperbolic arc sine of its numeric
argument.  If @var{x} is non-scalar, every element is replaced by its
hyperbolic arc sine.@refill

The argument @var{x} must be a numeric scalar, vector, or matrix.@refill
@end defun

@node atan, atanh, asinh, Basic Math

@cindex Arc tangent
@cindex Inverse tangent
@defun atan ( x )
The @code{atan} function returns the arc tangent of its numeric
argument.  If it's argument is complex, then the result is complex.
Otherwise, the result is real.  If @var{x} is non-scalar, every element
is replaced by its arc tangent.@refill

The argument @var{x} must be a numeric scalar, vector, or matrix.
@end defun

@node atanh, atan2, atan, Basic Math

@cindex Arc tangent hyperbolic
@cindex Hyperbolic arc tangent
@cindex Inverse hyperbolic tangent
@defun atanh ( x )
The @code{atanh} function returns the hyperbolic arc tangent of its
numeric argument.  If it's argument is complex or has magnitude greater
than 1.0, then the result is complex.  Otherwise, the result is real.
If @var{x} is non-scalar, every element is replaced by its hyperbolic
arc tangent.@refill

The argument @var{x} must be a numeric scalar, vector, or matrix.
@end defun

@node atan2, ceil, atanh, Basic Math

@defun atan2 ( y; x )
The @code{atan2} function computes an angle corresponding to @var{y} and
@var{x}, the lengths of the opposite and adjacent sides.  This is
similar to @code{atan(y/x)}, but with these differences:@refill

@itemize @bullet
@item
The signs of @var{y} and @var{x} are used to determine the quadrant in
which the angle lies.  The angle returned is in the range -pi to
pi.@refill

@item
The argument @var{x} may be zero, as long as @var{y} is nonzero.  This
is different than @code{atan(y/x)}, because it avoids division by
zero.@refill

@item
Complex type for either argument is not allowed.
@end itemize

The arguments must be scalars, vectors, or matrices, with either integer
or real type.@refill
@end defun

@node ceil, conj, atan2, Basic Math

@cindex Ceiling
@defun ceil ( x )
The @code{ceil} function returns the ceiling of its numeric argument.
The ceiling of @var{x} is the smallest integer that is not less than
@var{x}.  If @var{x} is complex, the ceiling is applied to both real and
imaginary parts.  If @var{x} is non-scalar, every element is replaced by
its ceiling.  The type of @var{x} is not changed by @code{ceil}.@refill

@var{x} must be a numeric scalar, vector, or matrix.
@end defun

@node conj, cos, ceil, Basic Math

@cindex Complex conjugate
@cindex Conjugate, complex
@defun conj ( x )
The @code{conj} function returns the complex conjugate of its numeric
argument.  If @var{x} is non-scalar, every element is replaced by its
complex conjugate.@refill

@var{x} must be a numeric scalar, vector, or matrix.
@end defun

@node cos, cosh, conj, Basic Math

@cindex Cosine
@defun cos ( x )
The @code{cos} function returns the cosine of its numeric argument.  If
@var{x} is non-scalar, every element is replaced by its cosine.@refill

@var{x} must be a numeric scalar, vector, or matrix.
@end defun

@node cosh, exp, cos, Basic Math

@cindex Hyperbolic cosine
@defun cosh ( x )
The @code{cosh} function returns the hyperbolic cosine of its numeric
argument.  If @var{x} is non-scalar, every element is replaced by its
hyperbolic cosine.@refill

@var{x} must be a numeric scalar, vector, or matrix.
@end defun

@node exp, floor, cosh, Basic Math

@cindex Exponential
@defun exp ( x )
The @code{exp} function returns the exponential of its numeric argument.
If @var{x} is non-scalar, every element is replaced by its
exponential.@refill

@var{x} must be a numeric scalar, vector, or matrix.
@end defun     

@node floor, imag, exp, Basic Math

@cindex Floor
@defun floor ( x )
The @code{floor} function returns the floor of its numeric argument.
The floor of @var{x} is the largest integer that is not greater than
@var{x}.  If @var{x} is complex, the floor is applied to both real and
imaginary parts.  If @var{x} is non-scalar, every element is replaced by
its floor.  The type of @var{x} is not changed by @code{floor}.@refill

@var{x} must be a numeric scalar, vector, or matrix.
@end defun

@node imag, integer, floor, Basic Math

@cindex Imaginary value
@defun imag ( x )
The @code{imag} function returns the imaginary part of its numeric
argument.  If @var{x} is non-scalar, every element is replaced by its
imaginary part.  The value returned by @code{imag} has real type.@refill

See also @code{real}.
@end defun

@node integer, log, imag, Basic Math

@defun integer ( x )
The @code{integer} function converts the real part of its numeric
argument to integer type, rounding it if necessary.@refill

See also @code{round}.
@end defun

@node log, log10, integer, Basic Math

@cindex Logarithm
@defun log ( x )
The @code{log} function returns the natural logarithm of its numeric
argument.  If @var{x} is non-scalar, every element is replaced by its
logarithm.@refill

@var{x} must be a numeric scalar, vector, or matrix.
@end defun

@node log10, real, log, Basic Math

@defun log10 ( x )
The @code{log10} function returns the base-10 logarithm of its numeric
argument.  If @var{x} is non-scalar, every element is replaced by its
base-10 logarithm.@refill

@var{x} must be a numeric scalar, vector, or matrix.
@end defun

@node real, round, log10, Basic Math

@cindex Real value
@defun real ( x )
This function returns the real part of @var{x}.  The value returned by
@code{real} has real type.@refill

See also @code{imag}.
@end defun

@node round, sin, real, Basic Math

@cindex Rounding
@defun round ( x )
The @code{round} function rounds its numeric argument to the nearest
whole number.  If @var{x} is complex, both real and imaginary parts are
rounded.  If @var{x} is non-scalar, every element is rounded.  The type
of @var{x} is not changed by @code{round}.@refill

If Algae has been compiled to use the system's rint(3m) function, then
arguments with a fractional part of exactly 1/2 are rounded to the
nearest even whole number.  Otherwise, such arguments are rounded
towards +infinity.@refill

See also @code{integer}.
@end defun

@node sin, sinh, round, Basic Math

@cindex Sine
@defun sin ( x )
The @code{sin} function returns the sine of its numeric argument.  If
@var{x} is non-scalar, every element is replaced by its sine.@refill
@end defun

@node sinh, sqrt, sin, Basic Math

@cindex Hyperbolic sine
@defun sinh ( x )
The @code{sinh} function returns the hyperbolic sine of its numeric
argument.  If @var{x} is non-scalar, every element is replaced by its
hyperbolic sine.@refill
@end defun

@node sqrt, tan, sinh, Basic Math

@cindex Square root
@defun sqrt ( x )
The @code{sqrt} function returns the square root of its numeric
argument.  If @var{x} is complex or negative, then the result is
complex.  Otherwise, the result is real.  If @var{x} is non-scalar,
every element is replaced by its square root.@refill
@end defun

@node tan, tanh, sqrt, Basic Math

@cindex Tangent
@defun tan ( x )
The @code{tan} function returns the tangent of its numeric argument.  If
@var{x} is non-scalar, every element is replaced by its tangent.@refill
@end defun

@node tanh, , tan, Basic Math

@cindex Hyperbolic tangent
@defun tanh ( x )
The @code{tanh} function returns the hyperbolic tangent of its numeric
argument.  If @var{x} is non-scalar, every element is replaced by its
hyperbolic tangent.@refill
@end defun

@node Arrays, Sets, Basic Math, Standard Functions
@section Arrays

@ifinfo
@menu
* band::	bandwidth reduction
* bdiag::	block diagonal
* btrans::	block transpose
* circshift::   circular shift of array
* combine::     union, but in original order
* cram::	form an array, possibly sparse
* dense::	dense storage
* diag::	matrix diagonal
* dice::        individual characters of a string
* diff::	difference between elements
* exsparse::    disassemble a sparse matrix
* fill::	fill an array
* find::	find elements in a vector
* first::       first "true" element in a vector
* form::	form an array
* full::	full storage
* gpskca::      profile or bandwidth reduction
* grep::        search using regular expression
* hermitian::	hermitian part of a matrix
* ident::       identity matrix
* imax::        find maximum element
* imin::        find minimum element
* isort::       sorted index
* label::       add labels
* last::        last "true" element in a vector
* linspace::    uniformly spaced vector
* logspace::    logarithmically spaced vector
* lose::	lose elements in a vector
* magic::	magic squares
* matrix::	convert to a matrix
* max::		maximum value
* merge::	merge arrays
* min::		minimum value
* mksparse::    sparse matrix from coordinate data
* norm::	vector and matrix norms
* pick::        pick non-zero elements
* product::     product of array elements
* rand::	uniform random numbers
* randn::       normal random numbers
* reverse::     reverse elements of a vector
* scalar::	convert to scalar
* select::      select an element at random
* seq::         integer sequence
* shape::       array dimensions
* sign::        signum function
* sort::	sort a vector
* sparse::	sparse storage
* srand::	seed random numbers
* sum::		sum elements
* surprise::    random arrays with given properties
* symmetric::	symmetric part of a matrix
* tril::        lower triangle
* triu::        upper triangle
* unlabel::     remove labels
* vector::	convert to a vector
* zero::	make a zero array
@end menu
@end ifinfo

@node band, bdiag, Arrays, Arrays

@cindex Bandwidth
@cindex Profile
@defun band ( m )
The @code{band} function computes the upper and lower bandwidths and
profiles of the square matrix @var{m}.  The row bandwidth of a
particular row is the number of elements to the left of the diagonal in
that row, but not including any consecutive zero elements at the
beginning of that row.  Likewise, the column bandwidth of a particular
column is the number of elements above the diagonal in that column, but
not including any consecutive zero elements at the beginning of that
column.  Notice that, for a diagonal matrix, all row and column
bandwidths are zero.  The lower bandwidth is the largest of all the row
bandwidths, and the upper bandwidth is the largest of all the column
bandwidths.  The lower profile is the sum of all the row bandwidths, and
the upper profile is the sum of all the column bandwidths.@refill

This function returns a real vector with four elements.  In order,
these elements are as follows:  lower bandwidth, lower profile, upper
bandwidth, and upper profile.@refill

Profile reduction can be very effective in reducing the time and memory
required to factor a matrix.  The function @code{gpskca} provides one
approach for doing this.@refill

See also @code{gpskca}.
@end defun

@node bdiag, btrans, band, Arrays

@cindex Block diagonal
@defun bdiag ( x; m; n )
The @code{bdiag} function mimics the @code{diag} function, but in a
``block'' sense.  The matrix @var{x} is taken to be comprised of
@var{m} rows and @var{n} columns of blocks that are themselves matrices.
If either @var{m} or @var{n} is 0, then the matrix returned has the
blocks of @var{x} on its diagonal and is elsewhere zero.  Otherwise,
the blocks of the diagonal of @var{x} are appended together.@refill

An example of the former case is:

@example
> M = magic (4)
        [  9   7   6  12 ]
        [  4  14  15   1 ]
        [ 16   2   3  13 ]
        [  5  11  10   8 ]
> bdiag (M; 0; 2)
        [           9          7          .          . ]
        [           4         14          .          . ]
        [          16          2          .          . ]
        [           5         11          .          . ]
        [           .          .          6         12 ]
        [           .          .         15          1 ]
        [           .          .          3         13 ]
        [           .          .         10          8 ]
@end example

An example of the latter case is:

@example
> bdiag ( M; 2; 2 )
        [  9   7   3  13 ]
        [  4  14  10   8 ]
@end example

@var{x} must be scalar, vector, or matrix.  After being converted to a
matrix, if necessary, the number of rows of @var{x} must be evenly
divisible by @var{m} (unless @var{m} is 0) and the number of columns of
@var{x} must be evenly divisible by @var{n} (unless @var{n} is 0).@refill

See also @code{btrans} and @code{diag}.
@end defun

@node btrans, circshift, bdiag, Arrays

@cindex Block transpose
@defun btrans ( x; m; n )
The @code{btrans} function mimics the transpose operator, but in a
``block'' sense.  The matrix @var{x} is taken to be comprised of @var{m}
rows and @var{n} columns of blocks that are themselves matrices.  The
blocks themselves are not transposed, but are simply moved across the
diagonal.@refill

For example:

@example
> M = magic (4)
        [  9   7   6  12 ]
        [  4  14  15   1 ]
        [ 16   2   3  13 ]
        [  5  11  10   8 ]
> btrans (M; 2; 2)
        [  9   7  16   2 ]
        [  4  14   5  11 ]
        [  6  12   3  13 ]
        [ 15   1  10   8 ]
@end example

@var{x} must be scalar, vector, or matrix.  After being converted to a
matrix, if necessary, the number of rows of @var{x} must be evenly
divisible by @var{m} and the number of columns of @var{x} must be evenly
divisible by @var{n}.@refill

See also @code{bdiag}.
@end defun

@node circshift, combine, btrans, Arrays

@cindex Circular shift
@cindex Shift, circular
@defun circshift ( x; s )

The @code{circshift} function shifts the elements of the array @var{x}.
The arg @var{s} is a vector---each of its elements specifies the shift
distance for the corresponding dimension of @var{x}.  A positive shift is
down or right; a negative shift is up or left.  If unspecified, the
shift distance is zero (meaning no shift).  If @var{x} is a table, the
function is applied to each of its members.@refill

For example:

@example
> x = fill (3,3; 1:9)
        [ 1   2   3 ]
        [ 4   5   6 ]
        [ 7   8   9 ]
> circshift (x; 1)
        [ 7   8   9 ]
        [ 1   2   3 ]
        [ 4   5   6 ]
> circshift (x; 0,1)
        [ 3   1   2 ]
        [ 6   4   5 ]
        [ 9   7   8 ]
> circshift (x; 1,1)
        [ 9   7   8 ]
        [ 3   1   2 ]
        [ 6   4   5 ]
@end example

@end defun

@node combine, cram, circshift, Arrays

@defun combine ( u; v )
The @code{combine} function appends the vectors @var{u} and @var{v},
removing all but the first of any redundant elements.  This is exactly
like the @code{union} function, except that the result is not sorted.@refill
@end defun

@node cram, dense, combine, Arrays

@defun cram ( shape; x )
This function uses the elements of @var{x} to make an entity described
by the vector @var{shape}.  If @var{shape} is NULL or has no elements, a
scalar is returned.  If @var{shape} has one element, then a vector of
length @code{shape[1]} is returned.  If @var{shape} has two elements,
then a matrix with @code{shape[1]} rows and @code{shape[2]} columns is
returned.@refill

The elements of @var{x} are used, in order, to fill the new entity.  For
matrices, this proceeds by rows.  If the entity returned has more
elements than @var{x}, it is padded with zeros or null strings.  For
example, @code{cram( 5; 1,2 )} returns the vector
@code{(1,2,0,0,0)}.@refill

If the return value is an array, it may be either dense or sparse.  The
code will try to make a reasonable choice, but avoids spending much time
in deciding.  For example, @code{cram( 1000; 1 )} returns a sparse
vector since it is immediately apparent that most of its elements are
zero.  On the other hand, @code{cram( 1000; (1:1000)<2 )} is dense even
though it would be more efficient to store it sparse; since its second
argument is a dense vector, @code{cram} would need to check most of its
elements to realize that.@refill

The @code{form} function is identical to this function except that the
arrays it returns are always dense.@refill

See also @code{fill}, @code{form}, and @code{zero}.
@end defun

@node dense, diag, cram, Arrays

@cindex Dense storage
@defun dense ( x )
The @code{dense} function converts its argument array to dense storage.
See also @code{sparse}.@refill
@end defun

@node diag, dice, dense, Arrays

@cindex Diagonal of a matrix
@cindex Matrix, diagonal
@defun diag ( x )
The @code{diag} function performs two different tasks, depending on the
class of @var{x}.  If @var{x} is a matrix, then its diagonal is returned
as a vector.  If @var{x} is a vector, then a matrix is returned which
has @var{x} as its diagonal and is zero elsewhere.  (If @var{x} is a
scalar, it is returned intact.)@refill

See also @code{bdiag}.
@end defun

@node dice, diff, diag, Arrays

@defun dice ( s )
The @code{dice} function takes a character scalar @var{s} and returns a
character vector, each element of which is a single character from
@var{s}.  For example, the expression @code{dice("Go dawgs!")}
yields@refill

@example
(  "G", "o", " ", "d", "a", "w", "g", "s", "!" )
@end example

See also @code{split}.
@end defun

@node diff, exsparse, dice, Arrays

@defun diff ( v )
The @code{diff} function takes a numeric vector @var{v} and returns a
vector of differences between its elements.  If @var{v} has @code{n}
elements, then the return vector is@refill

@example
v[2]-v[1], v[3]-v[2], ..., v[n]-v[n-1]
@end example

The return vector has one less element than @var{v}.  If @var{v} has
labels, then the return vector contains all but the last one.@refill

One simple use for @code{diff} is to compute forward-difference
approximations for the slope of a curve.  If @code{c} is a vector
containing ordinates of the curve in its elements and abscissae in its
labels, then the expression@refill

@example
diff (c) / diff (unlabel (c.eid))
@end example

@noindent
returns an approximation to its slope.  (The call to @code{unlabel} is
probably unnecessary in most cases, but it avoids trouble when the
labels of @code{c} themselves have labels.)@refill
@end defun

@node exsparse, fill, diff, Arrays

@defun exsparse ( x )
This function disassembles a matrix, returning it in its ``coordinate''
form, suitable for reassembly by the @code{mksparse} function.  A table
is returned, containing the members @var{shape}, @var{rows}, @var{cols},
and @var{values}.  The argument matrix @var{x} must be numeric.  Despite
the name of the function, it need not be sparse.@refill

See also @code{mksparse}.
@end defun

@node fill, find, exsparse, Arrays

@defun fill ( shape; x )
This function uses the elements of @var{x} to make an entity described
by the vector @var{shape}.  If @var{shape} is NULL or has no elements, a
scalar is returned.  If @var{shape} has one element, then a vector of
length @code{shape[1]} is returned.  If @var{shape} has two elements,
then a matrix with @code{shape[1]} rows and @code{shape[2]} columns is
returned.@refill

The elements of @var{x} are used, in order, to fill the new entity.  For
matrices, this proceeds by rows.  If the entity returned has more
elements than @var{x}, then the elements of @var{x} are reused.  For
example, @code{fill( 5; "a","b" )} returns the vector
@code{("a","b","a","b","a")}.@refill

When the return value from @code{fill} is a vector or matrix, it will
always be dense.  See the @code{cram} function for sparse return arrays.

The @code{form} function differs from this function only in that it
pads with zeros rather than reusing elements of @var{x}.@refill

See also @code{form}, @code{cram}, and @code{zero}.
@end defun

@node find, first, fill, Arrays

@defun find ( a; b )
The @code{find} function locates the elements of @var{b} that have the
values given by @var{a} and returns a vector containing their element
numbers.  For example, @code{find( 2,3; 0,1,2,3,4 )} returns the vector
@code{(3,4)}.  One common use is in an expression like
@code{A[find(77;A.rid);]}, which returns the row (or rows) of @var{a}
having the row label 77.@refill

If @var{a} is a scalar, then @code{find(a;b)} returns the element
numbers of @var{b}, sorted from smallest to largest, for which the
corresponding element of @var{b} is equal to @var{a}.  If @var{a} is a
vector, then @code{find(a;b)} returns the same as
@code{find(a[1];b),find(a[2];b),...}.@refill

See also @code{grep} and @code{lose}.
@end defun

@node first, form, find, Arrays

@defun first ( v )
The @code{first} function returns the index of the first ``true''
element in the vector @var{v}.  If none are found, 0 is returned.@refill

See also @code{find} and @code{last}.
@end defun

@node form, full, first, Arrays

@defun form ( shape; x )
This function uses the elements of @var{x} to make an entity described
by the vector @var{shape}.  If @var{shape} is NULL or has no elements, a
scalar is returned.  If @var{shape} has one element, then a vector of
length @code{shape[1]} is returned.  If @var{shape} has two elements,
then a matrix with @code{shape[1]} rows and @code{shape[2]} columns is
returned.@refill

The elements of @var{x} are used, in order, to fill the new entity.  For
matrices, this proceeds by rows.  If the entity returned has more
elements than @var{x}, it is padded with zeros or null strings.  For
example, @code{form( 5; "a","b" )} returns the vector
@code{("a","b","","","")}.@refill

When the return value from @code{form} is a vector or matrix, it will
always be dense.  See the @code{cram} function for sparse return arrays.

The @code{fill} function differs from this function only in that it
reuses the elements of @var{x} rather than padding with zeros.@refill

See also @code{fill}, @code{cram}, and @code{zero}.
@end defun

@node full, gpskca, form, Arrays

@cindex Full storage
@defun full ( x )
The @code{full} function converts a matrix stored in ``sparse_upper''
form to the ``sparse'' form.@refill
@end defun

@node gpskca, grep, full, Arrays

@cindex Bandwidth reduction
@cindex Gibbs-Poole-Stockmeyer
@cindex Gibbs-King
@cindex Lewis, John
@cindex Profile reduction
@cindex Reduction, bandwidth
@cindex Reduction, profile
@defun gpskca ( m; flag )
The @code{gpskca} function attempts to find a symmetric permutation of
the rows and columns of matrix @var{m} to reduce either its bandwidth or
its profile.  If the @var{flag} argument is ``true'' (in the sense of
the @code{test} function, then the Gibbs-Poole-Stockmeyer algorithm is
used for bandwidth reduction; otherwise, the Gibbs-King algorithm is
used for profile reduction.  See the description of the @code{band}
function for a definition of these terms.@refill

The return value is the permutation, given as an integer vector with
length equal to the order of @var{m}.  Consider the following example
interaction:@refill

@example
> a = symmetric (magic(6) > 25);
> band (a)
    ( 4, 13, 4, 13 )
> v = gpskca (a);
> b = a[v;v];
> band (b)
    ( 2, 9, 2, 9 )
@end example

@noindent
First, the sparse, symmetric matrix @var{a} is created.  The
@code{band} function shows that it has a bandwidth of 4 and a profile of
13.  Next, @code{gpskca} provides a permutation to reduce the profile.
The matrix @var{b} is set to equal @var{a} but with this permutation
applied.  Finally, @code{band} shows that this permutation reduces both
the bandwidth (to 2) and the profile (to 9).

The matrix @var{m} must be either symmetric or hermitian.  This function
uses the GPSKCA subroutine written by John Lewis.@refill

See also @code{band}.
@end defun

@node grep, hermitian, gpskca, Arrays

@cindex grep
@cindex Searching
@cindex Regular expressions
@defun grep ( expr; v )
The @code{grep} function finds the elements of the vector @var{v} which
match the pattern @code{expr}.  The pattern is an extended regular
expression which is given to the UNIX function @code{egrep} to do the
searching.@refill

The character strings in @var{v} must not contain a newline, or the
results will generally be wrong.@refill

Here are some examples (user input is preceded by the @samp{>} prompt):

@example
> grep ("a"; "ab", "ac", "bc")
    ( 1, 2 )

> grep ("9$"; 1:40)
    ( 9, 19, 29, 39 )

> m = magic (3)
    [ 8  1  6 ]
    [ 3  5  7 ]
    [ 4  9  2 ]
> m.rid = "top", "middle", "bottom";
> m[ grep ("top|bottom"; m.rid); ]
    [ 8  1  6 ]
    [ 4  9  2 ]
@end example

This is a terribly inefficient implementation (maybe someday Algae will
have builtin regular expressions), but maybe you'll find it useful.@refill

See also @code{find} and @code{lose}.
@end defun

@node hermitian, ident, grep, Arrays

@defun hermitian ( x )
This function returns the hermitian part of the square, numeric matrix
@var{x}.  A hermitian matrix has complex-conjugate symmetry.  It's
diagonal must necessarily be real.  The returned matrix is complex only
if @var{x} is complex.@refill

If @var{x} has both row and column labels, they must match.@refill

See also @code{symmetric}.@refill
@end defun

@node ident, imax, hermitian, Arrays

@cindex Identity matrix
@defun ident ( n )
The @code{ident} function returns an identity matrix with @var{n} rows
and columns.@refill
@end defun

@node imax, imin, ident, Arrays

@cindex Maximum
@defun imax ( v )
If @var{v} is a vector, this function returns the number of the
element with the greatest value.  If multiple elements qualify, then
the number of the first one is returned.@refill

If @var{v} is a matrix, then a vector is returned, each element giving
the row number of the greatest value in the corresponding column.
Again, if more than one element qualifies, the first one is
given.@refill

If @var{v} is a table, then the @code{imax} function is applied to each
of its members.@refill

The argument @var{v} may not be a scalar, and must not have complex
type.  Note that @code{imax(v)} is not necessarily equal to
@code{imin(-v)}.@refill

See also @code{imin}, @code{max}, @code{min}, @code{isort}, and @code{sort}.
@end defun

@node imin, isort, imax, Arrays

@cindex Minimum
@defun imin ( v )
If @var{v} is a vector, this function returns the number of the
element with the least value.  If multiple elements qualify, then
the number of the last one is returned.@refill

If @var{v} is a matrix, then a vector is returned, each element giving
the row number of the least value in the corresponding column.
Again, if more than one element qualifies, the last one is
given.@refill

If @var{v} is a table, then the @code{imin} function is applied to each
of its members.@refill

The argument @var{v} may not be a scalar, and must not have complex
type.  Note that @code{imin(v)} is not necessarily equal to
@code{imax(-v)}.@refill

See also @code{imax}, @code{max}, @code{min}, @code{isort}, and @code{sort}.
@end defun

@node isort, label, imin, Arrays

@cindex Sorting vectors
@defun isort ( v )
This function sorts the elements of vector @var{v} in increasing order,
and returns a vector containing the corresponding indices.  For example,
@code{sort(20,40,10,30)} returns the vector @code{(3,1,4,2)}.  The
expression @code{v[isort(v)]} actually returns the sorted vector
@var{v}, although the builtin function @code{sort} does this more
efficiently.  Complex numbers are sorted primarily by real value and
secondarily by imaginary value.@refill

See also @code{sort}, @code{max}, @code{min}, and @code{set}.
@end defun

@node label, last, isort, Arrays

@defun label ( x; a; b )
The @code{label} function assigns labels to vectors and matrices.  If
@var{x} is a vector, @var{a} is assigned as its element labels.  If
@var{x} is a matrix, @var{a} and @var{b} are assigned as its row and
column labels, respectively.  If @var{x} has any other class, an
exception is raised.@refill

See also @code{unlabel}.
@end defun

@node last, linspace, label, Arrays

@defun last ( v )
The @code{last} function returns the index of the last ``true''
element in the vector @var{v}.  If none are found, 0 is returned.@refill

See also @code{find} and @code{first}.
@end defun

@node linspace, logspace, last, Arrays

@cindex Linear spacing
@defun linspace ( a; b; n )
The @code{linspace} function generates a vector of @var{n} elements,
spaced uniformly between @var{a} and @var{b}.  All three arguments must
be (or be convertible to) scalars.  The argument @var{n} must be (or
round to) an integer greater than one.@refill

The vector generation operator @samp{:} also generates uniformly spaced
vectors.  With the operator, the number of elements is determined from
the specified spacing; with the @code{linspace} function, the spacing is
determined from the number of elements specified.  Also notice that the
last element of the vector returned by @code{linspace} is equal to
@var{b}, which is not necessarily the case with the @samp{:} operator.@refill

See also @code{logspace}.
@end defun

@node logspace, lose, linspace, Arrays

@cindex Logarithmic spacing
@defun logspace ( a; b; n )
The @code{logspace} function generates a vector of @var{n} elements,
spaced logarithmically between @var{a} and @var{b}.  All three arguments must
be (or be convertible to) scalars.  Both @var{a} and @var{b} must be
nonzero, and @var{n} must be (or round to) an integer greater than one.@refill

Logarithmic spacing means that the logarithm of the result vector is a
uniformly spaced vector.  This also means that the ratio between any two
adjacent elements is constant.  Note that even if both @var{a} and
@var{b} are real, the result will be complex if they have opposite
signs, and that a complex result will not necessarily form a straight
line in the complex plane.

See also @code{linspace}.
@end defun

@node lose, magic, logspace, Arrays

@defun lose ( a; b )
The @code{lose} function locates elements of @var{b} that do not have
the values given by @var{a} and returns a vector containing their
element numbers.  For example, @code{lose( 2,3; 0,1,2,3,4 )} returns the
vector @code{(1,2,5)}.  One common use is in an expression such as
@code{A[lose(77;A.rid);]}, which returns all of the rows of @var{a} that
don't have the row label 77.@refill

If @var{a} is a scalar, then @code{lose(a;b)} returns the element
numbers of @var{b}, sorted from smallest to largest, for which the
corresponding element of @var{b} is not equal to @var{a}.  If @var{a} is
a vector, then @code{lose(a;b)} returns the intersection of the results of
@code{lose(a[1];b)}, @code{lose(a[2];b)}, etc.@refill

See also @code{find}.
@end defun

@node magic, matrix, lose, Arrays

@cindex Magic squares
@defun magic ( n )
The @code{magic} function returns a magic square of order @var{n}.
(What system would be complete without it?)  The elements of a magic
square consist of all the integers 1 through @var{n^2}, arranged so
that the row, column, and the two diagonal sums are equal.@refill

@var{n} must be greater than 0.  No magic square exists for order
2.@refill
@end defun

@node matrix, max, magic, Arrays

@defun matrix ( x )
This function converts its argument @var{x} to a matrix if possible.
Scalars become one-by-one matrices, vectors become matrices with one
row, and matrices are unchanged.  If @var{x} is NULL, @code{matrix}
returns a real matrix with zero rows and zero columns.@refill

See also @code{scalar} and @code{vector}.
@end defun

@node max, merge, matrix, Arrays

@cindex Maximum
@defun max ( v )
If @var{v} is a vector, this function returns its greatest value.
If @var{v} is a matrix, then a vector is returned, each element giving
the greatest value of any element in the corresponding column.@refill

If @var{v} is a table, then the @code{max} function is applied to each
of its members.@refill

The argument @var{v} may not be a scalar, and must not have complex
type.@refill

See also @code{min}, @code{imax}, @code{imin}, @code{isort}, and @code{sort}.
@end defun

@node merge, min, max, Arrays

@defun merge ( x; y )
This function merges two entities, @var{x} and @var{y}, with respect to
their labels.  The result has labels that consist of the union of the
labels of @var{x} and @var{y}.  Its elements come from the corresponding
elements in @var{x} and @var{y}; they are summed when the same element
occurs in both.@refill

This is demonstrated by the following interactive session:

@example
> A = fill (3,3; 1:9)
        [  1   2   3 ]
        [  4   5   6 ]
        [  7   8   9 ]
> A.rid = A.cid = 1:3;
> B = fill (3,3; 10:90:10)
        [ 10  20  30 ]
        [ 40  50  60 ]
        [ 70  80  90 ]
> B.rid = B.cid = 2:4;
> merge (A; B)
        [  1   2   3   0 ]
        [  4  15  26  30 ]
        [  7  48  59  60 ]
        [  0  70  80  90 ]
@end example

If @var{x} and @var{y} are not vectors or matrices, they are simply
summed.@refill
@end defun

@node min, mksparse, merge, Arrays

@cindex Minimum
@defun min ( v )
If @var{v} is a vector, this function returns its least value.
If @var{v} is a matrix, then a vector is returned, each element giving
the least value of any element in the corresponding column.@refill

If @var{v} is a table, then the @code{min} function is applied to each
of its members.@refill

The argument @var{v} may not be a scalar, and must not have complex
type.@refill

See also @code{max}, @code{imax}, @code{imin}, @code{isort}, and @code{sort}.
@end defun

@node mksparse, norm, min, Arrays

@defun mksparse ( t )
This function returns a sparse matrix with dimensions and elements given
by the members of table @var{t}.  If the member @var{shape} exists, it
should be a vector with two elements specifying the number of rows and
columns of the matrix.  If it does not exist, the matrix is sized just
large enough to include all of the given elements.  The members
@var{rows}, @var{cols}, and @var{values} must all exist; these are
vectors, all with the same length, corresponding elements of which
specify respectively the row number, column number, and value of each
specified element of the matrix.  If an element is not specified, it is
zero.  If an element is given more than once, its value is the sum of
the given values.@refill

The following interactive session provides an example:

@example
> mksparse (@{shape=3,4; rows=1,2,3; cols=1,3,2; values=10,11,12@})
	[          10          .          .          . ]
	[           .          .         11          . ]
	[           .         12          .          . ]
@end example

The @var{values} vector must have numeric type.  If @var{t} is NULL, a
real matrix with 0 rows and 0 columns is returned.@refill

See also @code{sparse} and @code{exsparse}.
@end defun

@node norm, pick, mksparse, Arrays

@cindex Norm
@cindex Matrix norm
@cindex Vector norm
@defun norm ( x; p )
The @code{norm} function computes the @var{p}-norm of @var{x}, where
@var{p} is 1, 2, ``frobenius'', or ``infinity''.  (The latter two may be
abbreviated as ``frob'' and ``inf''.)  If @var{p} is not specified, the
2-norm is used.@refill

For complex @var{x}, the 1 and ``infinity'' norms deal not with the
magnitude of each element, but with the sum of the absolute values of
the real and imaginary parts.@refill
@end defun

@node pick, product, norm, Arrays

@defun pick ( x )
This function returns a vector containing the indices of the non-zero
elements of the numeric input vector @var{x}.  For example, the
expression@refill

@example
V [ pick (V < 0) ]
@end example

returns all of the negative elements of @code{V}.

See also @code{find}.
@end defun

@node product, rand, pick, Arrays

@defun product ( x )
The @code{product} function computes the product of the elements of an
array.  If @var{x} is a scalar, it is returned unchanged.  If @var{x} is
a vector, the product of all of its elements is returned.  If @var{x} is a
matrix, a vector is returned, each element of which is the product of the
elements in the corresponding columns of @var{x}.  If @var{x} is a
table, the @code{product} function is applied to each of its members.@refill
@end defun

@node rand, randn, product, Arrays

@cindex Random numbers
@defun rand ( shape )
This function generates pseudo-random numbers with a uniform
distribution in the range from 0 to 1.  Called with no arguments, it
returns a scalar.  Otherwise, the vector @var{shape} specifies a vector
or matrix; see the @code{readnum} function for more information.@refill

The random number generator may be ``seeded'' with the @code{srand}
function.  If you don't call @code{srand}, the seed is based on the
system's clock.  Note that @code{rand} and @code{randn} share the same
seed.@refill

See also @code{randn} and @code{srand}.
@end defun

@node randn, reverse, rand, Arrays

@cindex Random numbers
@defun randn ( shape )
This function generates pseudo-random numbers from a normal distribution
with zero mean and unit variance.  Called with no arguments, it returns a
scalar.  Otherwise, the vector @var{shape} specifies a vector or matrix;
see the @code{readnum} function for more information.@refill

The random number generator may be ``seeded'' with the @code{srand}
function.  If you don't call @code{srand}, the seed is based on the
system's clock.  Note that @code{rand} and @code{randn} share the same
seed.@refill

See also @code{rand} and @code{srand}.
@end defun

@node reverse, scalar, randn, Arrays

@defun reverse ( v )
The @code{reverse} function simply reverses the order of the elements in
vector @var{v}.  For example, @code{reverse(1,2,3)} returns the vector
@code{(3,2,1)}.@refill
@end defun

@node scalar, select, reverse, Arrays

@defun scalar ( x )
This function converts its argument @var{x} to a scalar if possible.
See also @code{matrix} and @code{vector}.@refill
@end defun

@node select, seq, scalar, Arrays

@defun select ( x )
The @code{select} function selects one element at random from the given
vector.  The result is a scalar.  The vector @var{x} must have at least
one element.@refill
@end defun

@node seq, shape, select, Arrays

@defun seq ( n )
The @code{seq} function returns a vector of consecutive integers from 1
to @var{n}.  The argument @var{n} is first rounded to the nearest
integer; if it is less than 1, a zero-length vector is returned.@refill
@end defun

@node shape, sign, seq, Arrays

@defun shape ( x )
This function returns the ``shape'' (that is, the dimensions) of its
argument @var{x}.  This return value has the same form as is used for
the @var{shape} arguments of functions like @var{readnum} and @var{rand}.
If @var{x} is a scalar, NULL is returned.  If @var{x} is a vector, a
scalar is returned having the length of @var{x} as its value.  If
@var{x} is a matrix, a vector is returned having the number of rows and
the number of columns as its first and second elements, respectively.
If @var{x} has any other class, an exception is raised.
@end defun

@node sign, sort, shape, Arrays

@cindex Signum
@cindex Sign
@defun sign ( v )
The @code{sign} function returns an array with the same size as
@var{v}.  Each element of the returned array is either -1, 0, or +1,
depending on whether the corresponding element of @var{v} is negative,
zero, or positive, respectively.  The argument @var{v} must be a numeric
scalar or array.@refill
@end defun

@node sort, sparse, sign, Arrays

@cindex Sorting vectors
@defun sort ( v )
This function sorts the elements of vector @var{v} in increasing order.
For example, @code{sort(20,40,10,30)} returns the vector
@code{(10,20,30,40)}.  Complex numbers are sorted primarily by real
value and secondarily by imaginary value.@refill

See also @code{isort}, @code{max}, @code{min}, and @code{set}.
@end defun

@node sparse, srand, sort, Arrays

@cindex Sparse storage
@defun sparse ( x )
This function converts its argument @var{x} to sparse storage.@refill
@end defun

@node srand, sum, sparse, Arrays

@cindex Random numbers
@defun srand ( s )
The @code{srand} function is used to ``seed'' the random number
generator @code{rand}.  (OK, they're really pseudo-random numbers.)  The
seed @var{s} determines the sequence of numbers returned by @code{rand}.
If @var{s} is NULL (or if @code{srand} is never called at all), then the
seed is taken from the system's clock.  See also @code{rand}.@refill
@end defun

@node sum, surprise, srand, Arrays

@defun sum ( x )
The @code{sum} function sums elements of arrays.  If @var{x} is a
scalar, it is returned unchanged.  If @var{x} is a vector, the sum of
all of its elements is returned.  If @var{x} is a matrix, a vector is
returned, each element of which is the sum of the elements in the
corresponding columns of @var{x}.@refill
@end defun

@node surprise, symmetric, sum, Arrays

@defun surprise ( rows; cols; type; density; symmetry; other )
The @code{surprise} function returns a more-or-less random matrix with
characteristics given by the input arguments.  It may be useful for
testing or timing purposes.@refill

Each of the arguments to @code{surprise} may be a vector, in which case
one of its members is chosen at random for that characteristic.  For
example, if @var{rows} is the vector @code{4,5,6} then the resulting
array will have either 4, 5, or 6 rows.@refill

The @var{rows} and @var{cols} arguments specify the number of rows and
columns in the array.  The choice of dimensions has a lower priority
than the other characteristics, so any dimensions that are incompatible
with other choices are discarded.  For example, consider the call@refill

@example
surprise (3,4; 4,5; "real"; ; "general","symmetric")
@end example

@noindent
This specifies a real matrix that is either general or symmetric.  If
general symmetry is chosen, then the array will have either 3 or 4 rows
and either 4 or 5 columns.  However, if a symmetric array is chosen,
then it must be square and the result will have 4 rows and 4
columns.@refill

On the other hand, the specified dimensions can affect the choice of the
other characteristics.  For example, in the call@refill

@example
surprise (3; 4; "real"; ; "general","symmetric")
@end example

@noindent
the result will not be symmetric, because the dimensions preclude
it.@refill

The @var{type} argument may contain any or all of the character strings
@code{"integer"}, @code{"real"}, or @code{"complex"}.  Only numeric
types are supported.  The default is @code{"real"}.@refill

The @var{density} argument specifies the approximate ratio of nonzero to
total array elements.  For diagonal arrays, only the diagonal elements
are considered.  The default is 1.0.@refill

The @var{symmetry} argument may be @code{"general"}, @code{"symmetric"},
or @code{"hermitian"}.  The default is @code{"general"}.@refill

The @var{other} argument may be @code{"none"}, @code{"diagonal"}, or
@code{"positive_definite"}.  The default is @code{"none"}.@refill
@end defun

@node symmetric, tril, surprise, Arrays

@defun symmetric ( x )
This function returns the symmetric part of the square, numeric matrix
@var{x}.  If @var{x} has both row and column labels, they must match.@refill

See also @code{hermitian}.@refill
@end defun

@node tril, triu, symmetric, Arrays

@cindex Triangle
@cindex Lower triangle
@defun tril ( a; k )
The @code{tril} function returns the lower ``triangular'' part of the
matrix @var{a}.  The return matrix is identical to @var{a} except that,
for any @code{i}, all elements @code{a[i;i+k+1]}, @code{a[i;i+k+2]},
etc. are zero.  If @var{k} is NULL, it defaults to zero.  Here is an
example:@refill

@example
> tril (magic (4); 1)
        [  9   7   0   0 ]
        [  4  14  15   0 ]
        [ 16   2   3  13 ]
        [  5  11  10   8 ]
@end example
@end defun

@node triu, unlabel, tril, Arrays

@cindex Triangle
@cindex Upper triangle
@defun triu ( a; k )
The @code{triu} function returns the upper ``triangular'' part of the
matrix @var{a}.  The return matrix is identical to @var{a} except that,
for any @code{i}, all elements @code{a[i;i+k-1]}, @code{a[i;i+k-2]},
etc. are zero.  If @var{k} is NULL, it defaults to zero.  Here is an
example:@refill

@example
> triu (magic (4); 1)
        [  0   7   6  12 ]
        [  0   0  15   1 ]
        [  0   0   0  13 ]
        [  0   0   0   0 ]
@end example
@end defun

@node unlabel, vector, triu, Arrays

@defun unlabel ( x )
The @code{unlabel} function removes the labels from its argument.  If
@var{x} is a vector or a matrix, it sets the labels to NULL and returns
the result.  If @var{x} has any other class, it is returned
unchanged.@refill
@end defun

@node vector, zero, unlabel, Arrays

@defun vector ( x )
This function converts its argument @var{x} to a vector if possible.
Scalars become one-element vectors.  If @var{x} is a matrix with either
one row or one column, then it is converted to a vector.@refill

See also @code{scalar} and @code{matrix}.
@end defun

@node zero, , vector, Arrays

@defun zero ( shape )
This function generates an integer scalar, vector, or matrix, all the
elements of which are zero.  The vector @var{shape} specifies the
dimensions of the entity returned; see the @code{readnum} function for more
information.@refill

If a vector or matrix is returned, it is stored in sparse form.  This
may or may not be the most efficient storage for your application; use
the @code{dense} function to convert it if desired.@refill

See also @code{dense}.
@end defun

@node Sets, Linear Algebra, Arrays, Standard Functions
@section Sets

@ifinfo
@menu
* complement::		complement
* intersection::	intersection
* set::			make a set
* union::		union
@end menu
@end ifinfo

@node complement, intersection, Sets, Sets

@cindex Complement
@defun complement ( a; b )
The @code{complement} function returns the relative complement of
@var{a} in @var{b}; that is, the set of elements of @var{b} which are
not in @var{a}.  The return value is a set, which we define as a sorted,
irredundant vector.  ``Sorted'' means sorted by increasing value;
character strings are sorted by ASCII values and complex numbers
are sorted with the real values as the primary key and the imaginary
values as the secondary key.@refill

See also @code{intersection}, @code{set}, and @code{union}.
@end defun

@node intersection, set, complement, Sets

@cindex Intersection
@defun intersection ( a; b )
The @code{intersection} function returns the intersection of set @var{a}
in @var{b}; that is, the set of elements that are in both @var{a} and
@var{b}.  The return value is a set, which we define as a sorted,
irredundant vector.  ``Sorted'' means sorted by increasing value;
character strings are sorted by ASCII values and complex numbers
are sorted with the real values as the primary key and the imaginary
values as the secondary key.@refill

See also @code{complement}, @code{set}, and @code{union}.
@end defun

@node set, union, intersection, Sets

@cindex Sets
@defun set ( x )
This function changes @var{x} into a set, if possible.  A ``set'' is
defined as a sorted, irredundant vector.  ``Sorted'' means sorted by
increasing value; character strings are sorted by ASCII values and
complex numbers are sorted with the real values as the primary key and
the imaginary values as the secondary key.  ``Irredundant'' means that
no two elements have the same value.@refill

If @var{x} has labels, then the returned vector also has labels that
correspond to the retained elements.  If @var{x} has no labels, the
labels of the returned vector give the index of the corresponding
element in @var{x}.  If @var{x} has redundant elements, the element
retained is not necessarily the first.  For example,
@code{set(1,1,1).eid} might be 1, 2, or 3.@refill

See also @code{complement}, @code{intersection}, and @code{union}.
@end defun

@node union, , set, Sets

@cindex Union of two sets
@defun union ( a; b )
The @code{union} function returns the union of sets @var{a} and @var{b}.
The return value is a set, which we define as a sorted, irredundant
vector.  ``Sorted'' means sorted by increasing value; character strings
are sorted by ASCII values and complex numbers are sorted with the
real values as the primary key and the imaginary values as the secondary
key.@refill

See also @code{complement}, @code{intersection}, and @code{set}.
@end defun

@node Linear Algebra, Numerical Analysis, Sets, Standard Functions
@section Linear Algebra

@ifinfo
@menu
* backsub::     back substitution
* chol::        Cholesky factorization
* eig::		eigenvalues and eigenvectors
* equilibrate:: matrix equilibration
* factor::	triangular factorization
* fft::		fast Fourier transform
* filter::      digital filter
* ifft::	inverse fast Fourier transform
* inv::		matrix inverse
* iram::        Arnoldi method for eigenvalue problems
* leastsq::     least squares solver
* mult::        efficient matrix products
* solve::	solve a linear system
* ssi::		subspace iteration for eigenvalues
* svd::		singular value decomposition
* transform::	linear transformation
@end menu
@end ifinfo

@node backsub, chol, Linear Algebra, Linear Algebra

@cindex Back substitution
@cindex Forward substitution
@cindex Solving linear equations
@cindex Linear equations
@defun backsub ( afac; b )
The @code{backsub} function solves the set of linear equations
@code{A*x=b} for @var{x}.  (Despite the name, it does both forward and
backward substitution.)  The argument @var{afac} must contain the
factorization of @code{A} returned as a table from either of the
functions @code{factor} or @code{chol}.  The argument @var{b} provides
the right-hand side.@refill

@cindex SuperLU
@cindex LAPACK
This function handles both LAPACK (dense) and SuperLU (sparse) factors.
It determines the appropriate solution method based on the members in
the @var{afac} table.@refill

@cindex BCSLIB-EXT
@cindex Boeing Computer Services
If @sc{bcslib-ext} (a sparse math library produced by Boeing Computer
Services) is available on your system and Algae has been compiled
for it, then the @code{backsub} function can use it.  If @var{afac}
contains factors computed by @sc{bcslib-ext} routines (in @code{factor}
or @code{chol}), then @code{backsub} will call the corresponding
routines to perform the back substitution.@refill

See also @code{chol}, @code{factor}, and @code{solve}.
@end defun

@node chol, eig, backsub, Linear Algebra

@cindex Cholesky factorization
@cindex Matrix factorization
@defun chol ( m )
The @code{chol} function computes the Cholesky factorization of the
symmetric, positive definite matrix @var{m}.  The factors are returned
in a table, which may contain a variety of members depending on the type
and density of @var{m}.  For example, if @var{m} is a real, dense
matrix, then @code{"L"} (the output of the @sc{lapack} routine
@code{DSYTRF} routine) and @code{"RCOND"} are returned.  For now, you'll
have to go digging in the code if you really want to understand the
output.  The idea, though, is that functions like @code{backsub} can
make sense of them so that you don't have to.@refill

Although its other members vary, the table returned by @code{chol}
always contains a member named @code{"RCOND"}.  This non-negative real
scalar is an estimate of the reciprocal of the condition number of
@var{m}.  If @code{"RCOND"} is very small (that is, the condition number
is very large), then the matrix @var{m} is ill-conditioned.  A warning
message is produced if @code{"RCOND"} is less than 1.0E-8.@refill

The key difference between the @code{chol} and @code{factor} functions
is that @code{chol} requires that the matrix be symmetric and positive
definite.  In that case, no pivoting is required; this generally results
in a savings in execution time over the @code{factor} function.@refill

Unless the matrix @var{m} happens to be diagonal (or BCSLIB-EXT is
used), @code{chol} uses a dense method from LAPACK.  Consequently,
@code{factor} is preferred over @code{chol} for large, sparse
systems.@refill

@cindex BCSLIB-EXT
@cindex Boeing Computer Services
If @sc{bcslib-ext} (a sparse math library produced by Boeing Computer
Services) is available on your system and Algae has been compiled
for it, then @code{chol} may use its routines to factor sparse matrices.
In turn, the @code{backsub} and @code{solve} functions can use these
factors to solve linear equations.  It is often useful to compute the
factors of a matrix and then save them (using @code{put}) for later use.
Keep in mind, however, that if these factors were computed with the
@sc{bcslib-ext} routines, then the Algae version with which you
intend to use them must also support @sc{bcslib-ext}.  The table
returned by @code{chol} contains the member @code{HOLD} iff a
@sc{bcslib-ext} routine was used to produce it.  @sc{bcslib-ext} is
never used on dense matrices.@refill

See also @code{backsub}, @code{factor}, and @code{solve}.
@end defun

@node eig, equilibrate, chol, Linear Algebra

@cindex Eigenvalues and eigenvectors
@defun eig ( a; b; opts )
The @code{eig} function computes eigenvalues and eigenvectors for the
standard and generalized eigenvalue problems@refill
@example
A * x = lambda * x
@end example
@noindent
and
@example
A * x = lambda * B * x
@end example

@noindent
If @var{a} is the only matrix argument, then both @var{lambda} and
@var{x} are computed for the standard problem.  If a matrix @var{b} is
given as the second argument, then the generalized problem is solved.@refill

A table of options @var{opts} may be given as the last argument.  If it
contains the member @code{no_right}, then the right eigenvectors @var{x}
are not computed.  If it contains the member @code{left}, then the
corresponding left eigenvectors are computed.@refill

This function returns a table containing the eigenvalues in a member
called @code{values} and, if appropriate, the (right) eigenvectors in a
member called @code{vectors}.  If the @code{left} option was given and
the problem is unsymmetric, then the left eigenvectors are returned in a
member called @code{left_vectors}.@refill

The solution method used depends on the type and symmetry of the
coefficient arrays.  Some of these methods entail strict requirements,
such as positive definiteness, on the matrices.  Each case is described
below, along with the LAPACK routine called to solve it.  See the
@cite{LAPACK Users' Guide} for more information.@refill

For real, symmetric, standard problems, DSYEV is used.  The eigenvalues
are real and in ascending order; the eigenvectors are orthonormal.@refill

For complex, hermitian, standard problems, ZHEEV is used.  The
eigenvalues are real and in ascending order; the eigenvectors are
orthonormal.@refill

For nonsymmetric, standard problems, DGEEV is used for real type and
ZGEEV for complex type.  The eigenvalues are complex, and complex
conjugate pairs appear consecutively with the eigenvalue having the
positive imaginary part first.  The eigenvectors are normalized to have
Euclidean norm equal to 1 and largest component real.@refill

For real, symmetric, generalized problems, DSYGV is used.  This method
requires that @var{a} be symmetric and that @var{b} be symmetric and
positive definite.  The eigenvalues are real and in ascending order.
The eigenvectors are @var{b}-orthonormal.@refill

For real, nonsymmetric, generalized problems, DGGEV is used.  This
method performs full balancing on @var{a} and @var{b}.  The eigenvalues
are complex, and complex conjugate pairs appear consecutively with the
eigenvalue having the positive imaginary part first.  Note, however,
that the eigenvalues are returned in a table; the member @code{num}
contains their numerators and member @code{denom} contains their
denominators.  The quotients may easily overflow or underflow, and the
denominator (and maybe the numerator, too) may be zero.  A good
beginning reference is the book @cite{Matrix Computations} by G. Golub
and C. Van Loan.  Each eigenvector is scaled so that the sum of the
absolute values of the real and imaginary parts of the largest component
is 1, except that for eigenvalues with numerator and denominator both
zero, the corresponding eigenvector is zero.@refill

For complex, hermitian, generalized problems, ZHEGV is used.  This method
requires that @var{a} be hermitian and that @var{b} be hermitian and
positive definite.  The eigenvalues are real and in ascending order.
The eigenvectors are @var{b}-orthonormal.@refill

For complex, nonsymmetric, generalized problems, ZGGEV is used.  The
eigenvalues and eigenvectors are complex.  Note, however, that the
eigenvalues are returned in a table; the member @code{num} contains
their numerators and member @code{denom} contains their denominators.
The quotients may easily overflow or underflow, and the denominator (and
maybe the numerator, too) may be zero.  A good beginning reference is
the book @cite{Matrix Computations} by G. Golub and C. Van Loan.  Each
eigenvector is scaled so that the sum of the absolute values of the real
and imaginary parts of the largest component is 1, except that for
eigenvalues with numerator and denominator both zero, the corresponding
eigenvector is zero.@refill

See also @code{iram}.
@end defun

@node equilibrate, factor, eig, Linear Algebra

@cindex Equilibration
@cindex Condition number
@defun equilibrate ( A )
The @code{equilibrate} function computes row and column scalings
intended to equilibrate a matrix and reduce its condition
number.  The input matrix @var{A} need not be square, but it must be
numeric and both dimensions must be nonzero.  If @var{A} is hermitian or
real symmetric, it must be positive definite.@refill

If @code{equilibrate} succeeds, it returns a table containing the
following members:

@table @var
@item r
A vector containing the row scale factors.

@item c
A vector containing the column scale factors.

@item rowcnd
The (scalar) ratio of the smallest to the largest of the row scale
factors.

@item colcnd
The (scalar) ratio of the smallest to the largest of the column scale
factors.

@item amax
The (scalar) absolute value of the largest matrix element.
@end table

Even if the matrix @var{A} is symmetric or hermitian, the row and column
scale factors may or may not be identical.  If not, the resulting
equilibrated matrix would no longer be symmetric or hermitian.  You will
have to decide whether the improvement in matrix condition is worth the
loss of symmetry.  The row and column scale factors will be identical
for dense, real, symmetric matrices and for dense, complex, hermitian
matrices (both of which must also be positive definite); otherwise,
there's no guarantee.@refill

Oftentimes, going on to apply the equilibration scale factors is not
worth the effort.  Roughly speaking, if @var{amax} is not close to
overflow or underflow and both @var{rowcnd} and @var{colcnd} are greater
than 0.1, it probably isn't worth doing.@refill

If @code{equilibrate} is unsuccessful, it returns a scalar integer
instead of a table.  If this value is positive, it indicates the row
causing the problem.  If it is negative, its absolute value indicates
the column causing the problem.@refill

To apply the equilibration, the matrix must be pre- and post-multiplied
by the scale factors.  If @var{r} and @var{c} are identical, you'll
probably want to use the @code{transform} function to preserve symmetry.
Here is an example usage:

@example
e = equilibrate (A);
if (equal (e.r; e.c))
@{
  Ae = transform (A; diag (e.r));
else
  Ae = diag (e.r) * A * diag (e.c);
@}
@end example

@noindent
Notice, though, that this example does not check the result of
@code{equilibrate} to determine if it succeeded, it applies the scale
factors without checking to see if it's worth it, and it assumes that
@var{A} obeys the requirement regarding positive definiteness.@refill
@end defun

@node factor, fft, equilibrate, Linear Algebra

@cindex Matrix factorization
@defun factor ( m )
The @code{factor} function computes a triangular factorization of the
matrix @var{m}.  The factors are returned in a table, which may contain
a variety of members depending on the type, density, and definition of
@var{m}.  For example, if @var{m} is a real, dense, symmetric matrix,
then @code{"LD"} and @code{"IPIV"} (the output of the @sc{lapack}
routine @code{DSYTRF} routine) are returned.  For now, you'll have to go
digging in the code if you really want to understand the output.  The
idea, though, is that functions like @code{backsub} can make sense of them
so that you don't have to.@refill

For sparse systems, the SuperLU package is used.  These routines reorder
the columns of the matrix to increase its sparsity, and perform dynamic
pivoting of the rows for numerical stability.  (No advantage is taken of
symmetry.)  For the column ordering, the Multiple Minimum Degree (MMD)
algorithm is used if the matrix is symmetric; otherwise, the Column
Approximate Minimum Degree (COLAMD) algorithm is used.  Currently, there
is no provision to supply your own ordering.@refill

Although its other members vary, the table returned by @code{factor}
always contains a member named @code{"RCOND"}.  This non-negative real
scalar is an estimate of the reciprocal of the condition number of
@var{m}.  If @code{"RCOND"} is very small (that is, the condition number
is very large), then the matrix @var{m} is ill-conditioned.  A warning
message is produced if @code{"RCOND"} is less than 1.0E-8.@refill

@cindex BCSLIB-EXT
@cindex Boeing Computer Services
If @sc{bcslib-ext} (a sparse math library produced by Boeing Computer
Services) is available on your system and Algae has been compiled
for it, then @code{factor} may use its routines to factor sparse matrices.
In turn, the @code{backsub} and @code{solve} functions can use these
factors to solve linear equations.  It is often useful to compute the
factors of a matrix and then save them (using @code{put}) for later use.
Keep in mind, however, that if these factors were computed with the
@sc{bcslib-ext} routines, then the Algae version with which you
intend to use them must also support @sc{bcslib-ext}.  The table
returned by @code{factor} contains the member @code{HOLD} iff a
@sc{bcslib-ext} routine was used to produce it.  @sc{bcslib-ext} is
never used on dense matrices.@refill

The key difference between the @code{chol} and @code{factor} functions
is that @code{chol} requires that the matrix be symmetric and positive
definite.  In that case, no pivoting is required; this generally results
in a savings in execution time over the @code{factor} function.@refill

See also @code{backsub}, @code{chol}, and @code{solve}.
@end defun

@node fft, filter, factor, Linear Algebra

@cindex Fourier transform
@defun fft ( x; opts )
The @code{fft} function computes the complex discrete Fourier
transform of the vector (or matrix---see below) @var{x} using the fast
Fourier transform method.  The result is ordered such that the
corresponding frequencies are increasing (from negative to positive).
Note that this is a different order than that returned by many FFT
routines.@refill

If @var{x} has @code{N} elements, the transform is a complex vector with
the same length.  If @code{N} is even, then element @code{k} of the
transform is equal to@refill
@example
sum (x @@ exp (-2*i*pi*(k-N/2)*((1:N)-1)/N))
@end example
If @code{N} is odd, then element @code{k} is equal to
@example
sum (x @@ exp (-2*i*pi*(k-(N+1)/2)*((1:N)-1)/N))
@end example

The method is most efficient when the number of elements in @var{x} is
the product of small primes.  For example, a vector with 1021 elements
(a large prime number) takes roughly 100 times longer to transform than
a vector with 1024 elements (a power of 2).  On the other hand, 1152
elements (with prime factors of 2 and 3) is almost as fast as
1024.@refill

If @var{x} has integer or real labels, they are taken to be the
corresponding abscissae (i.e., time or distance) and are transformed
accordingly to form labels for the results vector.  In that case, the
label values must be evenly spaced.@refill

If @var{x} is a matrix, the transform is computed for each row or
column.  By default this is done by column, but you can change it to
work by rows by supplying the @code{row} option, as described below.@refill

The argument @var{opts} is an options table; it may contain any or all
of the following members.  (The values of these members are
irrelevant; only their existence is signficant.)@refill

@table @code
@item row
If @var{x} is a matrix, this option causes the transform of each row
to be computed.  By default, the columns are transformed.

@cindex FFTW
@item estimate
When planning the transform, use a simple heuristic to pick a
(probably sub-optimal) plan quickly.  This is the default rigor.  This
and the following options have an effect only if Algae has been
linked with the FFTW package.

@item measure
Find an optimized plan by actually computing several FFTs and
measuring their execution time.

@item patient
Like @code{measure}, but considers a wider range of algorithms.  This
may produce a ``more optimal'' plan, but at the expense of a longer
planning time.

@item exhaustive
Like @code{patient}, but with an even wider range of algorithms and
substantially increased planning time.

@item forget
Plans are kept for use on subsequent FFTs with the same size and
characteristics.  The @code{forget} option causes this accumulated
information to be discarded.
@end table

See also @code{ifft}.
@end defun

@node filter, ifft, fft, Linear Algebra

@cindex Digital filter
@defun filter ( b; a; x; z )
The @code{filter} function computes a digital filter from the standard
difference equation@refill
@example
y[n] = b[1]*x[n] + b[2]*x[n-1] + b[3]*x[n-2] + ...
                 - a[2]*y[n-1] - a[3]*y[n-2] - ...
@end example

This filter is implemented using the "direct form II transposed"
method.  For more information, see Chapter 6 of the book "Discrete-Time
Signal Processing" by Oppenheim and Schafer.@refill
@end defun

@node ifft, inv, filter, Linear Algebra

@cindex Inverse fourier transform
@defun ifft ( x )
The @code{ifft} function computes the complex inverse discrete Fourier
transform of the vector (or matrix---see below) @var{x} using the fast
Fourier transform method.  The input is ordered such that the
corresponding frequencies are increasing (from negative to positive).
Note that this is a different order than that required by many inverse
FFT routines.@refill

If @var{x} has @code{N} elements, the transform is a complex vector with
the same length.  If @code{N} is even, then element @code{n} of the
transform is equal to@refill
@example
(1/N) * sum (x @@ exp (2*i*pi*((1:N)-N/2)*(n-1)/N))
@end example
If @code{N} is odd, then element @code{n} is equal to
@example
(1/N) * sum (x @@ exp (2*i*pi*((1:N)-(N+1)/2)*(n-1)/N))
@end example

The method is most efficient when the number of elements in @var{x} is the
product of small primes.  For example, a vector with 1021 elements
(a prime number) takes roughly 100 times longer to transform than a
vector with 1024 elements (a power of 2).  On the other hand, 1152
elements (with prime factors of 2 and 3) is almost as fast as
1024.@refill

If @var{x} has integer or real labels, they are taken to be the
corresponding abscissae (i.e., frequencies) and are transformed
accordingly to form labels for the results vector.  In that case, the
label values must be evenly spaced.@refill

If @var{x} is a matrix, the transform is computed for each row or
column.  By default this is done by column, but you can change it to
work by rows by supplying the @code{row} option.@refill

For a description of the valid options and their effects, see the
@code{fft} function.@refill

See also @code{fft}.
@end defun

@node inv, iram, ifft, Linear Algebra

@cindex Inverse, matrix
@cindex Matrix inverse
@defun inv ( a; opts )
The @code{inv} function computes the inverse of a matrix.  This is
sometimes useful, but you should be aware that an alternative approach
using @code{factor} (or @code{chol}) and @code{solve} is usually more
efficient and accurate.  (See below for more details.)@refill

The @code{inv} function is implemented simply by calling the
@code{solve} function with an identity matrix as the second argument.
The argument @var{opts} is optional and is passed as the third argument
to @code{solve}.  For example,@refill

@example
inv (A; @{pos@});
@end example

@noindent
computes the inverse of the positive-definite matrix @code{A}.@refill

The matrix inverse is often used to solve systems of linear equations.
If @code{Ax=b} is such a system, where @code{A} is a square matrix with
full rank, then its solution may be computed as@refill

@example
x = inv (A) * b;
@end example

@noindent
A more efficient and accurate approach, though, is to use the
@code{solve} function as@refill

@example
x = solve (A; b);
@end example

The use of @code{solve} is appropriate even when several right-hand
sides are to be considered separately.  For example, the code@refill

@example
x = @{@};
A_inv = inv (A);
for (b in members (blist))
@{
  x.(b) = A_inv * blist.(b);
@}
@end example

@noindent
would be better written as

@example
x = @{@};
A_fac = factor (A);
for (b in members (blist))
@{
  x.(b) = solve (A_fac; blist.(b));
@}
@end example

See also @code{backsub}, @code{chol}, @code{factor}, and @code{solve}.@refill
@end defun

@node iram, leastsq, inv, Linear Algebra

@cindex Eigenvalues and eigenvectors
@cindex Arnoldi method
@cindex Lanczos method
@cindex ARPACK
@defun iram ( n; op_func; b_func; params; options )
This function is an interface to the ARPACK routines for solving
algebraic eigenvalue problems.  It is based on the implicitly restarted
Arnoldi method.  For hermitian problems, this is a Lanczos
method.  This code is particularly well suited to large, sparse
problems.@refill

The @code{iram} function provides almost all of the capability of
ARPACK.  However, it is a relatively low-level function and requires
very careful use.  Because of it's design, many simple input errors
cannot be detected by the function and may well result in incorrect
results.  I hope to soon see a high-level function written, perhaps
called @code{arnoldi}, that calls @code{iram} but trades off some of its
flexibility in exchange for a simplified and less error-prone
interface.@refill

To use @code{iram} effectively, you will need more information regarding
the various solution modes than can be included here.  Please consult
the ARPACK users manual.@refill

The most general problem solved by @code{iram} is to compute a few
eigenvalues (@code{lambda}) and eigenvectors (@code{x}) for@refill

@example
A * x = M * x * lambda
@end example

@noindent
where @var{A} and @var{B} are real or complex square matrices and
@var{M} is hermitian (symmetric when real).  This is a standard
eigenvalue problem if @var{M} is the identity matrix; otherwise it is a
generalized problem.@refill

The argument @var{n} specifies the dimension of the problem.  This
should be an integer scalar, or at least able to be cast to one.@refill

Rather than providing @var{A} and @var{B} directly, @code{iram} requires
input functions that perform certain operations on those matrices.  This
allows numerous solution approaches (called ``modes''), which are
described in detail below.  The two user-supplied functions are called
as@refill

@example
op_func (v; params)
b_func (v; params)
@end example

The operations required of the @var{op_func} function differ depending
on the solution mode.  In the simplest case (mode 1), it is just the
matrix-vector multiplication @code{A*v}.  The argument @var{params} is
passed unchanged from the @var{params} argument to @code{iram}---it is
commonly a table containing the coefficient arrays @var{A} and
@var{B}.@refill

The requirements for the @var{b_func} function also depend on the
solution mode.  It is not used at all for some modes, in which case it
may be NULL.  As with @var{op_func}, the @var{params} argument is passed
unchanged from the @code{iram} input.@refill

The @var{options} argument is a table; its members specify various
problem and solution options:@refill

@table @code
@item mode
The integer solution mode, which defaults to 1.

@table @code
@item 1
This is the ``regular'' mode, for standard problems only.  Function
@var{op_func} should return @code{A*v}, and @var{b_func} should be NULL.
This mode is mostly suited to finding a few of the eigenvalues with
largest magnitude.  It may be used with any problem type.@refill

@item 2
This is the ``regular inverse'' mode for generalized problems.  Function
@var{op_func} should return @code{inv(B)*A*v} (conceptually, but you
should use @code{factor} and @code{solve} rather than @code{inv}), and
@var{b_func} should return @code{B*v}.  This mode may not be used with
real, symmetric problems.@refill

@item 3
This is the ``shift-invert'' mode for standard or generalized problems.
Function @var{op_func} should return @code{inv(A-sigma*B)*B*v}
(concepturally, but you should use @code{factor} and @code{solve} rather
than @code{inv}), and @var{b_func} should return @code{B*v}.  This mode
may be used with any problem type.  Convergence is enhanced to
eigenvalues that are near the value of @var{sigma}.  For this mode, the
@code{which} option refers to the inverted problem, so use ``LM'' to
refer to the eigenvalues closest to @var{sigma}.@refill

@item 4
This is the ``buckling'' mode for generalized problems.  Function
@var{op_func} should return @code{inv(A-sigma*B)*A*v} (concepturally,
but you should use @code{factor} and @code{solve} rather than
@code{inv}), and @var{b_func} should return @code{A*v}.  This mode may
only be used for real, symmetric problems.  Convergence is enhanced to
eigenvalues that are near the value of @var{sigma}.  For this mode, the
@code{which} option refers to the inverted problem, so use ``LM'' to
refer to the eigenvalues closest to @var{sigma}.@refill

@item 5
This is the ``Cayley'' mode for generalized problems.  Function
@var{op_func} should return @code{inv(A-sigma*B)*(A+sigma*B)*v}
(concepturally, but you should use @code{factor} and @code{solve} rather
than @code{inv}), and @var{b_func} should return @code{B*v}.  This mode
may only be used for real, symmetric problems.  Convergence is enhanced
to eigenvalues that are near the value of @var{sigma}.  For this mode,
the @code{which} option refers to the inverted problem, so use ``LM'' to
refer to the eigenvalues closest to @var{sigma}.@refill
@end table

@item bmat
A character scalar:  @code{"I"} for standard problems or @code{"G"} for
generalized problems.  The default is @code{"I"}.@refill

@item which
A character scalar that specifies which of the eigenvalues to compute.
For other than ``regular'' mode (mode 1), this is with respect to the
transformed problem.  For example, with the ``shift-invert'' mode (mode
3), one usually wants the eigenvectors nearest the shift point.  In the
transformed problem, they are the eigenvalues with largest magnitude
(@code{"LM"}).  For real, symmetric problems, @var{which} must be one of
the following: @code{"LA"} (largest amplitude), @code{"SA"} (smallest
amplitude), @code{"LM"} (largest magnitude), @code{"SM"} (smallest
magnitude), or @code{"BE"} (both ends of the spectrum).  For
non-symmetric or complex problems, @var{which} must be one of these:
@code{"LM"} (largest magnitude), @code{"SM"} (smallest magnitude), or
@code{"LR"} (largest real), @code{"SA"} (smallest real), @code{"LI"}
(largest imaginary), or @code{"SI"} (smallest imaginary).  The default
is @code{"LA"} for symmetric problems and @code{"LR"} for the
others.@refill

@item nev
The number of eigenvalues to be computed.  This must be greater than
zero and less than @var{n}.  The default is the lesser of 10 and
@code{n/2}.  For non-symmetric and complex problems, @var{nev} must be
less than @code{n-1}.@refill

@item ncv
Controls the number of Arnoldi vectors generated at each iteration.  For
real, symmetric problems, this must be less than or equal to @var{n},
must exceed @var{nev}, and defaults to the lesser of @code{2*nev} and
@code{n}.  For real, non-symmetric problems, @var{ncv} must be less than
or equal to @var{n}, must exceed @code{nev+1}, and defaults to the
lesser of @code{2*nev+1} and @code{n}.  For complex problems, @var{ncv}
must be less than or equal to @var{n}, must exceed @var{nev}, and
defaults to the lesser of @code{2*nev} and @code{n}.@refill

@item mxiter
The maximum number of Arnoldi update iterations allowed.  The default is
100.@refill

@item basis
If ``true'' (in the sense of the @code{test} function), then @code{iram}
returns, along with its other results, an orthonormal basis for the
associated approximate invariant subspace.@refill

@item vectors
If ``true'' (in the sense of the @code{test} function), then @code{iram}
returns the eigenvectors along with its other results.@refill

@item tol
The stopping criterion.  If @var{tol} is NULL or less than or equal to
zero, then machine precision is used.@refill

@item resid
If present, this is an n-length vector that provides the initial
residual vector.  Otherwise, a random initial vector is used.@refill

@item shift
A real scalar providing the shift point (@var{sigma}) for a spectral
transformation.  This is used in modes 3, 4, and 5.  The default is
0.0.@refill
@end table
@end defun

@node leastsq, mult, iram, Linear Algebra

@cindex Least squares
@cindex Overdetermined systems
@cindex Underdetermined systems
@defun leastsq ( A; b )
This function solves full-rank overdetermined and underdetermined linear
systems using a QR or LQ factorization.  The inputs are the coefficient
array @var{A} and the RHS @var{b}.  The return value is the solution
array @var{x}.@refill

An underdetermined system is one for which @var{A} has fewer rows than
columns.  The rank of @var{A} must be equal to the number of rows of
@var{A}.  The return value is the minimum norm solution.@refill

An overdetermined system is one for which @var{A} has more rows than
columns.  This function treats a square @var{A} as if it were an
overdetermined system.  The rank of @var{A} must be equal to the number
of columns of @var{A}.  The return value is the solution to the least
squares problem@refill

@example
minimize || B - A*X ||
@end example

See also @code{solve}.
@end defun

@node mult, solve, leastsq, Linear Algebra

@cindex Matrix products
@cindex Matrix multiplication
@cindex Efficient matrix products
@defun mult ( @dots{} )
This function multiplies together a series of matrices, performing
the multiplications in an order so as to minimize the total number
of operations.@refill

Only the leftmost non-NULL arguments are used, and at most 10
arguments are allowed.  They will be converted to matrices if
necessary (and possible), but in a context-free manner.  A scalar
becomes a 1x1 matrix, and a vector becomes a matrix with 1 row.  This
is in contrast to Algae's multiplication operator, which makes
different conversions according to the context.@refill

As an example, consider an NxN matrix @code{A} and an N vector
@code{b}.  If you give Algae the product @code{A'*A*b}, it first
multiplies @code{A'*A} which involves an order of N^3 operations.  But
if you do it as @code{A'*(A*b)}, there are only an order of N^2
operations.  The difference can be huge!  With this function, you'd do
it as @code{mult(A';A;b')}.  (Note that we have to explicitly convert
@code{b} to a matrix with the right shape.)@refill
@end defun

@node solve, ssi, mult, Linear Algebra

@cindex Solving linear equations
@cindex Linear equations
@defun solve ( A; b; opts )
This function solves the linear equations @code{A*x=b} for @var{x}.
Conceptually it returns @code{inv(A)*b}, except that @code{solve} is
generally much more efficient and accurate.  If @var{A} has already been
factored by the @code{factor} or @code{chol} functions, then its factors
(in the form of a table returned by those functions) may be given in the
place of @var{A}.  If the optional argument @var{opts} contains the
member ``pos'', then the Cholesky method is used to factor
@var{A}.@refill

See also @code{backsub}, @code{chol}, and @code{factor}.
@end defun

@node ssi, svd, solve, Linear Algebra

@cindex Subspace iteration
@defun ssi ( A; B; V; eps )
The @code{ssi} function uses subspace iteration to compute the first few
eigenvalues and vectors for a real, symmetric, generalized eigenvalue
problem @code{A*v=B*v*w}.  The terms @var{w} and @var{v} are the
eigenvalues and eigenvectors, respectively.@refill

Subspace iteration is an effective approach for large, sparse problems
and for problems for which good estimates of the eigenvectors are
available.  Otherwise, it sucks.@refill

Both @var{A} and @var{B} must be real, symmetric, non-singular matrices.
The matrix @var{V} contains a set of starting vectors, one to a column.
A convergence tolerance may be specified with @var{eps}; 1.0E-6 is used
if @var{eps} is NULL.  A table is returned, containing the members
``values'' and ``vectors''.@refill

See also @code{eig}.
@end defun

@node svd, transform, ssi, Linear Algebra

@cindex Singular value decomposition
@defun svd ( A; opts )
This function computes the singular value decomposition (SVD) of the
matrix @var{A}.  In the full case, the SVD is written @code{A=U*S*V'},
where @var{S} is a real matrix with the same dimensions as @var{A} and
@var{U} and @var{V} are the orthogonal (unitary) left and right singular
vectors.  The matrix @var{S} contains the singular values on its
diagonal and is zero elsewhere.@refill

When @var{A} is not square, one or more rows or columns of @var{S} are
known @i{a priori} to be zero.  By default, @code{svd} then returns a
``compact'' form of the singular vectors, in which the corresponding
columns of @var{U} or @var{V} are not included.  This behavior may be
modified by using the @code{full} option, as described below.@refill

The argument @var{opts} is an options table; it may contain the members
@code{novectors} and @code{full}.  (The values of these members are
irrelevant; only their existence is signficant.)  If @var{opts} contains
the member @code{novectors}, then only the singular values are computed.
If @var{opts} contains only the member @code{full}, then the full
singular vectors are computed.@refill

The results of @code{svd} are returned in a table.  The member
@code{sigma} contains the vector of singular values, sorted in
decreasing order.  Unless the @code{novectors} option is specified, the
members @code{U} and @code{V} contain the corresponding left and right
singular vectors.@refill

This function calls the LAPACK routines DGESVD and ZGESVD.@refill
@end defun

@node transform, , svd, Linear Algebra

@defun transform ( A; P )
The @code{transform} function performs the linear coordinate
transformation @code{P'*A*P}, where @var{A} is a square matrix.  In
fact, there are only two differences between the operator expression
@code{P'*A*P} and the function expression @code{transform(A;P)}:@refill

@itemize @bullet
@item
The @code{transform} function results in the most appropriate symmetry.
For example if @var{A} and @var{P} are both real, and @var{A} is
symmetric, then the result is a symmetric matrix.  With the operator
expression this would not be the case; the result would be exactly the
same (neglecting any roundoff errors) except that it would be marked
with general symmetry.@refill

@item
The @code{transform} function is considerably faster than the operator
expression for some matrix combinations.  In particular, it may be two
or three times faster when @var{P} is dense and @var{A} is large,
sparse, and either hermitian or real symmetric.@refill
@end itemize
@end defun

@node Numerical Analysis, Basic I/O, Linear Algebra, Standard Functions
@section Numerical Analysis

@ifinfo
@menu
* brent::	zeros of a nonlinear equation
* monte::       Monte Carlo integration
* ode4::        ordinary differential equation solver
* roots::	roots of a polynomial
* spline::	natural cubic splines
@end menu
@end ifinfo

@node brent, monte, Numerical Analysis, Numerical Analysis

@cindex Root finding
@cindex Solving nonlinear equations
@cindex Nonlinear equations
@defun brent ( f; a; b; tol; param )
This function uses Brent's method to find a single root of the function
@var{f}; that is, a solution to @code{f(x)=0}.  The ordinates @var{A}
and @var{B} must bracket a root, meaning that @code{f(A)*f(B)} must be
negative.  If @var{param} is given, it is passed as the second argument
to the function @var{f}.@refill
@end defun

@node monte, ode4, brent, Numerical Analysis

@cindex Monte Carlo integration
@defun monte ( f; limits; tol )
This function uses the Monte Carlo method to integrate a function.  The
function values are obtained by calling the function @var{f} with one
vector argument.  The matrix @var{limits} describes the rectangular
region over which the function is integrated.  It has two columns and as
many rows as @var{f} has dimensions.  Each row specifies the extremes of
the region for the corresponding dimension.@refill

The @var{tol} argument specifies an error tolerance.  (This argument
is required: there is no default.)  There is no limit to the number of
points chosen; @code{monte} continues to pick points until its one
standard deviation error estimate is less than @var{tol}.  Generally,
the accuracy increases only as the square root of the number of points
evaluated.@refill

The Monte Carlo method provides a simple, easy approach for solving
(numerically) even complicated, multi-dimensional integrals.  However,
it is notoriously inefficient.  Each additional digit of accuracy
requires 100 times more effort.@refill

Here is a simple example, in which we compute the area of a circle
with unit radius.  With @var{domain}, we specify a square centered on
the origin within which to integrate.  The number of independent
variables in the problem (2 in this case) is determined by the number
of rows of @var{domain}.  The function @var{f} takes as its argument a
vector of the independent variables and returns the function value at
that point.  It will be called repeatedly, with the independent
variables spread randomly within the domain.  For this problem,
@var{f} returns 1 if the point is inside the circle, and 0
otherwise.@refill

@example
domain = [-1,1; -1,1];
f = function (x) @{ return norm(x) < 1; @};
monte (f; domain; 0.1)?
        3.040
monte (f; domain; 0.01)?
        3.120
monte (f; domain; 0.001)?
        3.142
@end example

As you can see from the results, the third call to @code{monte} gave
a more accurate result, but it took 10,000 times the effort used in
the first call.@refill
@end defun

@node ode4, roots, monte, Numerical Analysis

@cindex Ordinary differential equations
@cindex Runge-Kutta
@cindex Initial value problems
@defun ode4 ( f; t0; tf; x0; y; tol; h; s )
The @code{ode4} function uses fourth and fifth order Runge-Kutta
formulas to solve an initial value problem involving a system of
ordinary differential equations.  The function @var{f}, called as
@code{f( t; x )}, is expected to return the first derivative of the
state vector @var{x} with respect to the independent variable @var{t}.
The arguments @var{t0} and @var{tf} are the initial and final values of
the independent variable, and @var{x0} is the initial state vector.  The
argument @var{y} may be a function, called as @code{y( t; x )}, that
returns a vector of output values.  If @var{y} is NULL, the output
vector is the state vector itself.@refill

The optional argument @var{tol} specifies the desired accuracy; we use
0.001 if @var{tol} is NULL.  An initial stepsize may be suggested with
@var{h}.  The @var{s} argument may be used to provide better control
over the accuracy---if @var{s} is not NULL, then a step is accepted if
the estimated error in each state, divided by the corresponding term of
@var{s}, is not greater than @var{tol}.@refill  

The return value is a matrix containing the output history.  Each column
contains the output from @var{y} for the particular value of the
independent variable given by the column label.@refill
@end defun

@node roots, spline, ode4, Numerical Analysis

@cindex Polynomial roots
@cindex Roots of a polynomial
@defun roots ( c )
This function computes the roots of the polynomial having the
coefficients given by the vector @var{c}.  If @var{c} has @code{n+1}
elements, the equation solved (for @code{x}) is@refill

@example
c[1]*x^n + c[2]*x^(n-1) + ... + c[n]*x + c[n+1] = 0
@end example

A vector with zero elements is returned if the equation has no solution
(@code{roots(1)}, for example).  NULL is returned if it has an infinite
number of solutions (@code{roots(0)}, for example).  Otherwise, the
vector returned contains all of the solutions.@refill
@end defun

@node spline, , roots, Numerical Analysis

@cindex Cubic splines
@cindex Spline interpolation
@cindex Interpolation
@defun spline ( a; x )
This function computes or evaluates natural cubic spline interpolations
for given data.  If called with one argument, @var{a}, a spline for the
points in the vector @var{a} is computed.  The elements of @var{a} give
the ordinates; the labels of @var{a} give the abscissae.  If @var{a} has
no numeric labels, then the natural numbers from one to the length of
@var{a} are assumed.  In any case, the vector @var{a} is sorted with
respect to its labels; they must be unique.@refill

If @code{spline} is called with two arguments, @var{a} and @var{x}, then
the spline @var{a} (or a spline interpolation of @var{a}, if @var{a} is
not a spline) is evaluated at the abscissa values given by the vector
@var{x}.@refill
@end defun

@node Basic I/O, Entity I/O, Numerical Analysis, Standard Functions
@section Basic I/O

@ifinfo
@menu
* close::	close a file
* digits::	specify numeric print format
* fread::       read a binary file
* fprintf::	formatted print to a file
* fwrite::      write a binary file
* message::	print an error message
* print::	print to a file
* printf::	formatted print to standard output
* read::	read a line from a file
* readnum::     read numbers from a file
* sprintf::	formatted write to a character scalar
* tmp_file::    create a temporary file
@end menu
@end ifinfo

@node close, digits, Basic I/O, Basic I/O

@cindex Closing a file
@cindex File closing
@defun close ( file )
The @code{close} function closes the specified file.  The file name
@var{file} must be given exactly as it was when the file was opened.
(Whitespace is significant.)  Any buffered data is flushed.
@end defun

@node digits, fread, close, Basic I/O

@cindex Digits to print
@cindex Print format
@cindex Format for printing
@defun digits ( n )
The @code{digits} function may be used to specify the number of digits
that Algae uses when printing real and complex numbers.  This
applies to the @code{print} function and to ``printing statements''
(those with question mark or newline terminators).  The argument @var{n}
specifies the number of digits.  If @var{n} is NULL, no action is
taken.@refill

The function returns the number of digits being used.  By default,
Algae uses 4 digits.@refill

Here's an example interaction, with user input preceded by the ``>''
prompt:@refill

@example
> digits ()      # the default
        4
> acos (-1)      # pi, to 4 significant digits
        3.142
> digits (20);   # set to 20 digits
> acos (-1)      # pi, to 20 digits (but only accurate to 17)
        3.1415926535897931000
@end example

This function simply sets the global variable @code{$digits}, so you
can do the same thing by assigning to it directly.@refill

See also @code{print}.
@end defun

@node fread, fprintf, digits, Basic I/O

@cindex Binary input
@cindex Input, binary
@defun fread ( file; length; type )
The @code{fread} function reads data from a binary file into a numeric
array.  This is a low-level routine, and it requires that you know
precisely the format of the data that is being read.  To read Algae's own
binary files (those written with @code{put}), see @code{get}.@refill

The @var{file} argument (a character scalar) is the file name.  As with
any file name, if its first character is an exclamation mark then the
rest of the string is given to the shell as a filter.  If @var{file} is
NULL, then standard input is read.@refill

The @var{length} argument (an integer scalar) gives the number of items
to read.  If it's NULL, the entire file is read.  Otherwise, it should
be a non-negative integer.  A vector is returned that contains the data
that was read.  If @code{fread} reaches the end of the file before
having read @var{length} elements, then the vector it returns will
contain fewer than @var{length} elements.@refill

The @var{type} argument is an optional table; its member's names specify
the type of data to read and, implicitly, the type of the returned
array.  (The values of this table's members are inconsequential; only
their names are important.)  These names may include any of the C
language types:
@table @code
@item char
Each is cast to an Algae @code{integer}.
@item int
Same as an Algae @code{integer}.
@item float
Each is cast to an Algae @code{real}.
@item double
Same as an Algae @code{real}.
@end table

The C language type qualifiers are also accepted in @var{type}:
@table @code
@item long
A qualifier for @code{int} and @code{double} types.  Both are cast
to @code{real}.@refill
@item short
A qualifier for @code{int}.  Casts to @code{integer}.
@item signed
A qualifier for @code{char} and @code{int}.  Casts to @code{integer}.
@item unsigned
A qualifier for @code{char} and @code{int}.  An @code{unsigned char}
casts to @code{integer}, while an @code{unsigned int} casts to
@code{real}.@refill
@end table
Combinations that are disallowed in C (such as @code{unsigned double})
are disallowed here, too.  If @var{type} is NULL or empty, @code{double}
is assumed.@refill

Besides the C language type qualifiers just described, the following
special qualifiers are also accepted:
@table @code
@item big
Specifies the so-called "big endian" byte order.
@item little
Specifies the so-called "little endian" byte order.
@item ieee
Specifies the IEEE 754 binary floating point format.
@end table
@end defun

@node fprintf, fwrite, fread, Basic I/O

@cindex Printing formatted output
@cindex Formatted output
@cindex Output, formatted
@defun fprintf ( file; format; @dots{} )
The @code{fprintf} function prints formatted output to @var{file}.  The
@var{format} argument is a character string that contains two types of
objects: characters and conversion specifications.  Characters are
printed directly; conversion specifications cause the next argument to
be formatted and printed.@refill

Conversion specifications are introduced using the percent sign
@samp{%}.  Although extensions are planned, the conversion
specifications are currently identical to those for the ``fprintf''
function of the ANSI C language.@refill

@cindex Pipes
@cindex Exclamation mark
@cindex Input filters
@cindex Output filters
If the first character of @var{file} is an exclamation mark, then the
rest of @var{file} is given to the shell as a filter to which the
printed output of @code{fprintf} is sent.  For example, the command
@code{fprintf("!sort";"a\nc\nb\n");close("!sort");} sends ``a'', ``c'',
and ``b'', each on a separate line, to the system's sort function, which
then presumably sorts and prints it.  If @var{file} is NULL, stdout is
used.@refill

See also @code{message}, @code{print}, @code{printf}, @code{sprintf},
and @code{put}.@refill
@end defun

@node fwrite, message, fprintf, Basic I/O

@cindex Binary output
@cindex Output, binary
@defun fwrite ( file; v; type )
The @code{fwrite} function writes binary data to a file from a numeric
array.  This is a low-level routine, and it requires that you specify
precisely the format of the data being written.  To write an entity for
use in Algae, you'll probably want to use @code{put} instead.@refill

The @var{file} argument (a character scalar) is the file name.  As with
any file name, if its first character is an exclamation mark then the
rest of the string is given to the shell as a filter.  If @var{file} is
NULL, then the data is written to standard output.@refill

The data to be written is given in the argument @var{v}, a numeric
vector.@refill

The @var{type} argument is an optional table; its member's names specify
the type of data to write.  (The values of this table's members are
inconsequential; only their names are important.)  These names may
include any of the C language types and qualifiers, and a few others.
See @code{fread} for details.@refill
@end defun

@node message, print, fwrite, Basic I/O

@cindex Error messages
@cindex stderr
@defun message ( fmt; @dots{} )
The @code{message} function is used to write error messages to stderr.
Its arguments are exactly like @code{printf}, except that a maximum of
10 arguments is allowed.  The message written includes the program and
file names as well as the line number.@refill

See also @code{printf}.
@end defun

@node print, printf, message, Basic I/O

@defun print ( x; file )
The @code{print} function prints its argument @var{x} to a file named by
@var{file}.  This output goes through the same formatting that
Algae uses to print entities to the screen.  In particular, the
variable @code{$term_width} controls the width of this output, and the
@code{$digits} variable specifies the number of significant digits
printed for real and complex numbers.@refill

If @var{file} is NULL, then the output is written to stdout.

See also @code{digits}, @code{fprintf}, @code{printf}, @code{sprintf},
and @code{put}.@refill
@end defun

@node printf, read, print, Basic I/O

@cindex Printing formatted output
@cindex Formatted output
@cindex Output, formatted
@defun printf ( format; @dots{} )
The @code{printf} function prints formatted output to stdout.  It is
exactly the same as calling @code{fprintf} with NULL as the first
argument.@refill

See also @code{fprintf}, @code{message}, @code{print}, @code{put}, and
@code{sprintf}.@refill
@end defun

@node read, readnum, printf, Basic I/O

@cindex Reading text
@cindex Input, character
@defun read ( file )
This function reads a line of text and returns it as a character string.
The argument @var{file} may be a file name or a pipe; see @code{fprintf}
for details.  If @var{file} is NULL, the text is read from standard
input.@refill

When @code{read} reaches the end of file, it returns NULL.@refill

See also @code{get} and @code{readnum}.@refill
@end defun

@node readnum, sprintf, read, Basic I/O

@cindex Reading numbers
@cindex Input, numeric
@defun readnum ( shape; file )
This function reads real numbers from a file named @var{file}.  The vector
@var{shape} specifies the form of the output.  If @var{shape} is NULL or
has zero length, a scalar is returned.  If @var{shape} has length one,
then a vector with @code{shape[1]} elements is returned.  If @var{shape}
has two elements, then a matrix is returned with @code{shape[1]} rows and
@code{shape[2]} columns.@refill

The values are read from @var{file}, or from stdin if @var{file} is NULL
or not given.  The @samp{#} symbol is special---it and all remaining
characters on a line are ignored.  If the end of file is reached before
the specified number of values is read, then the result is filled out
with zeros.  After a call to @code{readnum}, the number of values actually
read is contained in the variable @code{$read}.@refill

For example, let's say you have a file called @file{jnk} that contains
the following:@refill

@example
# this line is ignored -- numbers like 1.23 are skipped
the first two numbers are 42 and 99.
3.14 is the next one
@end example

In the following interaction we read the numbers from the file into a
matrix:@refill

@example
> x = readnum (2,4; "jnk")?
        [         42.00        99.00        3.140        0.000 ]
        [         0.000        0.000        0.000        0.000 ]
> $read?
        3
> readnum (3; "jnk")?
        (        0.000,       0.000,       0.000 )
@end example

As you can see, anything that doesn't look like a number is simply
skipped.  The @code{readnum} function found three numbers and filled in
the rest of the matrix with zeros.  The global variable @code{$read} was
set to 3 -- the number of values actually read.@refill

Subsequent calls to @code{readnum} with the same file name simply
continue reading from the last position in the file.  In the last
statement of the previous example, no more numbers were found so the
vector was filled with zeros.  To read again from the start of the file,
you must first close the file with the @code{close} function.@refill

The @code{readnum} function recognizes integers and floating point
numbers.  A floating point number consists of an optionally signed
integer part, a decimal point, a fraction part, an @samp{e} or @samp{E},
and an optionally signed integer exponent.  All of the following
examples are recognized as numbers: @samp{1}, @samp{-1.2}, @samp{1e2},
@samp{-1.e2}, @samp{.1e2}, @samp{-1.2e3}, and @samp{1.2e-3}.@refill

Fortran users take note!  A Fortran double precision number such as
@samp{1.23D4} will not be read by @code{readnum} as a single number.
The character @samp{D} is not recognized as part of a floating point
number, so @code{readline} will read this as the two numbers @samp{1.23}
and @samp{4}.@refill
@end defun

@node sprintf, tmp_file, readnum, Basic I/O

@defun sprintf ( format; @dots{} )
The @code{sprintf} function writes formatted output to a character
scalar.  It works the same as @code{printf}, except that the output is
returned instead of printed.  For example, @code{x=sprintf("y=%d";1)}
puts the string ``y=1'' in the scalar @var{x}.@refill

See also @code{fprintf}, @code{printf}, and @code{put}.@refill
@end defun

@node tmp_file, , sprintf, Basic I/O

@cindex Temporary files
@defun tmp_file ( )
The @code{tmp_file} function creates a temporary file and returns its
name.  This file will be deleted automatically when Algae
exits.@refill

By default, Algae writes temporary files in the directory
@file{/tmp}.  You can override that with an environment variable called
@code{TMPDIR}.  For example, if you use the Bourne shell and put the
lines@refill

@example
TMPDIR=/usr/tmp
export TMPDIR
@end example

@noindent
in your @file{~/.profile} file, then Algae will put its temporary
files in the @file{/usr/tmp} directory.@refill

This function not only creates the file, but opens it for output.  If
you want to read from the temporary file, then you should close it
first.  (Of course, you'll need to arrange to get something in it,
first.)  Notice that temporary files are not deleted when closed, but
only when Algae exits.@refill
@end defun

@node Entity I/O, Execution, Basic I/O, Standard Functions
@section Entity I/O

@ifinfo
@menu
* get::		get an entity from a binary file
* getdyn::	get a matrix from a DYNASTY file
* getmat::	get a matrix from a MATLAB file
* load::	load variables from file
* put::		put an entity to a binary file
* putdyn::	put a matrix to a DYNASTY file
* putmat::	put a matrix to a MATLAB file
* save::	save variables to file
@end menu
@end ifinfo

@node get, getdyn, Entity I/O, Entity I/O

@cindex Reading entities
@defun get ( file )
The @code{get} function reads an Algae entity from a binary file named
@var{file}.  If no argument is given, standard input is used.  Use this
function to read files written with @code{put}.  The file name can
specify a pipe; see @code{fprintf} for more details.@refill

NULL is returned if an error occurs in reading the file; otherwise
@code{get} returns the entity it read.@refill
@end defun

@node getdyn, getmat, get, Entity I/O

@defun getdyn ( fname )
This function reads matrices from the DYNASTY file @var{fname}.
(DYNASTY is the name of a software package used at Boeing for dynamic
analysis.)  A table is returned, containing the matrices as
members.@refill

The file name can specify a pipe; see @code{fprintf} for more
details.@refill
@end defun

@node getmat, load, getdyn, Entity I/O

@cindex MATLAB
@defun getmat ( fname )
The @code{getmat} function reads matrices from a MATLAB binary file
named @var{fname}.  It returns the matrices in a table.@refill

The file name can specify a pipe; see @code{fprintf} for more
details.@refill

Notice that @code{getmat} doesn't assign the matrices to the global
symbol table as MATLAB's ``load'' function does.  To do that, you might
use something like the following:@refill

@example
Load = function (fname)
@{
  local (t; n);
  t = getmat (fname);
  for (n in members (t))
  @{
    $$.(n) = t.(n);
  @}
@};
@end example

The @code{getmat} function reads the MATLAB v.4 "Level-1 MAT-file"
format.  MATLAB can read and write in this format, but its default for
writing is now Level-2.  Using the newer format would require us to link
to their libraries, meaning that you'd need to actually have MATLAB on
that machine.  We'll stick with the older format.@refill

One unfortunate consequence of using the older file format is that
matrices cannot be written in sparse form.  To get around this, convert
the matrix to coordinate form (which is dense) within MATLAB and then
change it back to sparse form in Algae with the @code{mksparse}
function.@refill

See also @code{get}, @code{put}, and @code{putmat}.@refill
@end defun

@node load, put, getmat, Entity I/O

@defun load ( fname )
The @code{load} function reads a table from a file named @var{fname} and
assigns its members as global variables.  This can be used, for example,
to restore an Algae session that was saved with the @code{save}
function.@refill

If an error occurs in reading the file, @code{load} returns 0; otherwise
it returns 1.@refill

See also @code{get}, @code{put}, and @code{save}.@refill
@end defun

@node put, putdyn, load, Entity I/O

@cindex Writing entities
@defun put ( x; fname )
The @code{put} function writes @var{x} to a binary file named
@var{fname} (or standard output if @var{fname} is NULL).  This binary
file can be read with @code{get}.  The file name can specify a pipe; see
@code{fprintf} for more details.@refill

NULL is returned if an error occurs in writing the file; otherwise a 1
is returned.@refill
@end defun

@node putdyn, putmat, put, Entity I/O

@defun putdyn ( x; fname )
This function writes the members of the table @var{x} to a DYNASTY file
named @var{fname}.  (DYNASTY is the name of a software package used at
Boeing for dynamic analysis.)  The file name may specify a pipe; see
@code{fprintf} for more details.@refill

The file is not closed when @code{putdyn} finishes, so subsequent writes
to the same file will append data to the end of it unless you close it
first.  On some machines, this could be used to build a complete DYNASTY
file with several different calls to @code{putdyn}.  The disadvantage,
though, is that the DYNASTY file format doesn't allow this on all
machines.@refill
@end defun

@node putmat, save, putdyn, Entity I/O

@cindex MATLAB
@defun putmat ( t; fname )
The @code{putmat} function writes a table of matrices @var{t} to a
MATLAB binary file named @var{fname}.  The file name can specify a pipe;
see @code{fprintf} for more details.@refill

NULL is returned if an error occurs in writing the file; otherwise a 1
is returned.@refill

NULL members in @var{t} are skipped; otherwise each member is converted
to a matrix if necessary and then written to the file.@refill

The @code{putmat} function writes in the MATLAB v.4 "Level-1 MAT-file"
format.  MATLAB can read and write in this format, but its default for
writing is now Level-2.  Using the newer format would require us to link
to their libraries, meaning that you'd need to actually have MATLAB on
that machine.  We'll stick with the older format.@refill

One unfortunate consequence of using the older file format is that
matrices cannot be written in sparse form.  To get around this, use the
@code{exsparse} function to convert the matrix to coordinate form (which
is dense) and then change it back to sparse form within MATLAB.@refill

See also @code{get}, @code{getmat}, and @code{put}.@refill
@end defun

@node save, , putmat, Entity I/O

@defun save ( fname )
The @code{save} function writes all non-NULL global variables as a table
to a file named @var{fname}.  This can be used, for example, to save an
Algae session that you wish to start again later using the
@code{load} function.@refill

NULL is returned if an error occurs in writing the file; otherwise
@code{save} returns 1.@refill

See also @code{get}, @code{load}, and @code{put}.
@end defun

@node Execution, Special Tools, Entity I/O, Standard Functions
@section Execution

@ifinfo
@menu
* autosrc::     define an autosrc function
* builtin::	link a new builtin function
* cd::          change directory
* eval::        evaluate a string as an expression
* exception::	raise an exception
* exec::        parse and execute a string
* exit::        terminate Algae
* file::        current file name
* get_path::    get a path list
* getenv::      get the value of an environment variable
* line::        current line number
* provide::     provide a feature
* require::     require a feature
* search_path:: search for a file
* source::	read source file (low level)
* sources::	read source files, with file name generation
* src::         read source file
* strip::       strip line and file info from a function
* system::	execute a shell command
@end menu
@end ifinfo

@node autosrc, builtin, Execution, Execution

@cindex Autosrc functions
@defun autosrc ( name; file )
This function creates an @dfn{autosrc} function named @var{name}.  When
this new function is later called, it replaces itself with a definition
that it reads by calling the @code{src} function with the file name
@var{file}.  In this way, you can put off reading a function's
definition until it is actually called.@refill

If @var{file} is @code{NULL}, then @code{autosrc} uses the value of
@var{name} for the file name.@refill

For example, consider the following code:@refill

@example
autosrc ("yow");
yow ();
@end example

@noindent
The first line defines an autosrc function named @code{yow}.  When
@code{yow} is called on the second line, it reads the real definition of
@code{yow} by calling @code{src} with the file name @code{"yow"}.  It
then calls its replacement (with the same arguments, of course).@refill

The current implementation of @code{autosrc} restricts the number of
arguments to 10.  (It's an ugly restriction, but if you need that many
arguments perhaps you should be using a table, instead.)  A zero
returned indicates success.@refill
@end defun

@node builtin, cd, autosrc, Execution

@cindex Dynamic linking
@cindex Linking, dynamic
@cindex Shared objects
@defun builtin ( file; symbol )
On machines that support dymamic linking, this function creates a new
builtin function by linking to a shared object named by @var{file} and
locating the symbol named by @var{symbol}.@refill

Suppose you have some old Fortran code that computes your chances of
being hit by a comet.  You can write a C wrapper for it, link them as a
shared object, use @code{builtin} to attach it, and, voila!, it's a
builtin function.@refill

Unlike other functions in Algae that deal with files, @code{builtin} does
not accept the special ``bang'' type file names.  (These are file names
that begin with an exclamation point and are given to the shell as a
command.)@refill

It isn't hard to create shared objects for @code{builtin}, but currently
there's no documentation for it.  Perhaps you can find some code to
imitate.@refill
@end defun

@node cd, eval, builtin, Execution

@cindex Directory, changing
@cindex Change directory
@defun cd ( path )
The @code{cd} function changes the current default directory to that
specified by the character scalar @var{path}.  If @var{path} is NULL,
the directory is changed to that given by the @code{HOME} environment
variable.@refill

An exception is raised if an error occurs; otherwise, @code{cd} returns
the integer 1.@refill
@end defun

@node eval, exception, cd, Execution

@cindex Evaluation
@defun eval ( s )
The @code{eval} function evaluates the string @var{s} as an expression
and returns its value.  Variable references, if any, have global scope.
For example, consider the following interaction:@refill

@example
> x = 0.5;
> str = "sin(x)";
> eval (str)
        0.4794
> x = 1.0;
> eval (str)
        0.8415
@end example

@noindent
Although the value of @code{str} remains @code{"sin(x)"}, the result of
@code{eval(str)} changes when the value of @code{x} changes.@refill

Unlike its prominent place in some matrix programming languages,
@code{eval} is rarely necessary in Algae.  Most examples of its use are
rather contrived.  Here's some code which evaluates an expression typed
in by the user:@refill

@example
x = eval (read ("!echo -n \"expression?  \" 1>&2 ; head -1"))
@end example

One use for @code{eval} that may not be quite so contrived involves
building a function within a function---something that you can't do
directly in Algae.  Here's an example:@refill

@example
add_const = function (c)
@{
  return eval (sprintf ("function (x) @{ return x+%g; @}"; c));
@};
@end example

@noindent
This could then be used as follows:@refill

@example
> ten_more = add_const( 10 );
> ten_more(1)?
        11
@end example

Probably the most common mistake made with @code{eval} is giving it a
statement instead of an expression.  If that's really what you want to
do, use the @code{exec} function instead.@refill

Remember, too, that all variable references are at global scope.  For
example, the function@refill

@example
function( a; b ) @{ return eval( "a + b" ); @}
@end example

@noindent
returns the sum of the global variables @code{a} and @code{b}; it
completely ignores the function's arguments, as they are local
variables.@refill

See also @code{exec}.
@end defun

@node exception, exec, eval, Execution

@cindex Exceptions
@defun exception ( )
This function ``raises an exception'', meaning that Algae makes an error
return.  If execution is interactive, control returns to the user.
Otherwise, Algae exits.@refill
@end defun

@node exec, exit, exception, Execution

@cindex Evaluation
@defun exec ( s )
The @code{exec} function causes Algae to parse and execute the
Algae statements contained in the character string @var{s}.  Execution
begins at global scope, even if @code{exec} is called from a function.
It returns a negative integer if an error occurs, and zero otherwise.@refill

See also @code{eval} and @code{source}.
@end defun

@node exit, file, exec, Execution

@cindex Terminating Algae
@cindex Exiting
@defun exit ( status )
This function terminates Algae.  The optional argument @var{status}
specifies the exit status that Algae returns.  On most computer
platforms, the exit status is expected to be a small, positive integer.
The @var{status} argument to @code{exit} should be numeric scalar.  If
@code{exit} is called with anything else, Algae returns 0 as its exit
status.@refill

A call to @code{exit} is not mandatory in your Algae programs.  Algae
terminates when it reaches the end of its input, returning exit status
0.  If an error causes Algae to terminate, exit status 1 is returned.@refill
@end defun

@node file, get_path, exit, Execution

@defun file ( )
The @code{file} function returns the name of the file from which
statements are currently being executed.@refill
@end defun

@node get_path, getenv, file, Execution

@cindex Path lists
@defun get_path ( env; def )
The @code{get_path} function returns a path list, for use in file
searching.  The argument @var{env}, if it isn't NULL, gives the name of
an environment variable containing a colon-separated list of paths.  The
@var{def} argument gives a default value, in case @var{env} isn't given
or doesn't exist.@refill

See also @code{search_path} and @code{src}.
@end defun

@node getenv, line, get_path, Execution

@cindex Environment variables
@cindex Variables, environment
@defun getenv ( ename )
The @code{getenv} function returns a character scalar that contains the
value of the environment variable named by @var{ename}.  If no such
variable exists, NULL is returned.@refill
@end defun

@node line, provide, getenv, Execution

@defun line ( )
The @code{line} function returns the line number from which it is
called.@refill
@end defun

@node provide, require, line, Execution

@cindex Features
@defun provide ( feature )
A @dfn{feature} is simply a name that stands for a particular collection
of functions or other entities.  A program announces that a feature is
present by calling the @code{provide} function with @var{feature}, the
name of that feature.  This means that the facilities associated with
@var{feature} have been made available for other Algae programs.@refill

Programs that require a particular feature can source the appropriate
file with the @code{require} function.@refill

The argument @var{feature} must be a character scalar.  It is added to
the global variable @code{$features} if it is not already present in
that vector.  The @code{provide} function returns @var{feature}.@refill
@end defun

@node require, search_path, provide, Execution

@defun require ( feature; filename )
A @dfn{feature} is simply a name that stands for a particular collection
of functions or other entities.  A program that needs the collection may
ensure that they are defined by calling @code{require} with the name of
that feature.  The use of named features simplifies the task of
determining whether required assignments have been made.@refill

The @code{require} function checks for the feature named @var{feature}
in the current Algae session; if it isn't present, then @code{require}
reads the source file @var{filename} with @code{src}.  If @var{filename}
is @code{NULL}, then the value of @var{feature} is used as the file
name.@refill

Before it finishes, the source file read by @code{require} is expected
to call the @code{provide} function, indicating that the desired feature
has been provided.  An exception is raised if the source file cannot be
read or does not provide the feature named @var{feature}.@refill
@end defun

@node search_path, source, require, Execution

@defun search_path ( fn; suffices; path )
The @code{search_path} function searches for a file in the directories
named in @var{path}.  The file name begins with the string given by
@var{fn}, with one of the suffices given by @var{suffices}.@refill
@end defun

@node source, sources, search_path, Execution

@defun source ( fname )
This function causes Algae to parse and execute the file named
@var{fname}.  Execution begins at global scope, even if @code{source} is
called from a function.  It returns NULL if it has a problem opening
@var{fname}, a negative integer if a parse or run time error occurs, and
zero otherwise.@refill

The file is closed after it is read.@refill

See also @code{exec} and @code{sources}.
@end defun

@node sources, src, source, Execution

@defun sources ( fname )
The @code{sources} function causes Algae to parse and execute
specified files.  The character scalar @var{fname} is passed through
sh(1) to ls(1), so file name generation is available and multiple names
may be given.  For example,@refill

@example
sources( "*.A" );
@end example

@noindent
sources all of the files ending with @file{.A} in your working
directory.  Although you could use the @code{source} function to do this
as@refill

@example
source( "!cat *.A" );
@end example

@noindent
using @code{sources} is preferable because it maintains the correct file
and line information for the interpreter.@refill

The ``pipe'' capability normally available to Algae I/O functions is not
permitted in @code{sources}.  Command substitution works, though, as
demonstrated here:@refill

@example
sources( "`find $HOME -name '*.A' -print`" );
@end example

@noindent
This example sources every file ending with @file{.A} found in any
subdirectory under your home directory.@refill
@end defun

@node src, strip, sources, Execution

@cindex Source files
@defun src ( filename )
The @code{src} function finds and opens a file of Algae code, executes
the statements within it at global scope, and then closes the file.
This function, rather than @code{source} or @code{sources}, is intended
to be the normal way to source files directly.  Other functions that may
be used to source files are @code{require} and @code{autosrc}.@refill

To find the file, @code{src} looks first for a file named
@file{@var{filename}.A}, that is, it appends @samp{.A} to the name given
by the argument @var{filename}.  If a file with that name exists, it is
sourced; otherwise, @code{src} looks for a file named @var{filename}
with nothing appended, and sources it if it exists.@refill

@cindex File searching
@cindex Relative file name
If @var{filename} is a relative file name, such as @file{foo} or
@file{foo/bar.A}, @code{src} searches for the file using the variable
@code{$src_path}.  It appends @var{filename} to each of the directories
listed in the character vector @code{$src_path} (both with and without
the @samp{.A}), and sources the first file it finds whose name matches.
The current default directory is tried only if it is specified in
@code{$src_path}.@refill

@cindex Absolute file name
No directory searching is performed if @var{filename} is an absolute
file name.  File names that begin with @samp{/}, @samp{./}, @samp{../},
or @samp{~/} are absolute.  If the file name begins with @samp{~/}, the
tilde is replaced with the value of the @code{HOME} environment
variable.@refill

@cindex Pipes
@cindex Input filters
@cindex Output filters
A file name that begins with the @samp{!} character is a pipe; the rest
of the file name is given as a command line to the shell, the standard
output of which is then read by @code{src}.  For example,@refill

@example
src("!m4 foo.A")
@end example

@noindent
runs the file @file{foo.A} through the @code{m4} macro preprocessor
first before @code{src} reads it.@refill

@cindex @code{ALGAE_SRC_PATH} environment variable
The @code{$src_path}
vector is initialized from the environment variable
@code{ALGAE_SRC_PATH}, if it exists.  It may be modified in either of
the startup files @file{/usr/local/lib/algae/VERSION_NUMBER/algae.A} or
@file{$HOME/.algae}.  (@xref{Startup Files}.)@refill

The syntax of @code{ALGAE_SRC_PATH} is the same as that of @code{PATH} for
the shell; fields are separated by @samp{:}, and @samp{.} is used for
the current default directory.  To set @code{ALGAE_SRC_PATH} in the Bourne
shell, type something like the following:@refill

@example
export ALGAE_SRC_PATH
ALGAE_SRC_PATH=.:~/algae:/usr/local/lib/algae
@end example

Execution of the Algae code in @var{filename} begins at global scope.
For example, if the source file contains the single statement
@code{x=1}, the assignment is made to the global variable @var{x}
regardless of whether @code{src} was called from within a function or
not.@refill

The @code{src} function raises an exception if @var{filename} cannot be
found. It returns @code{NULL} if it cannot be opened, a negative integer
if a parse or run-time error occurs, and 0 otherwise.@refill
@end defun

@node strip, system, src, Execution

@defun strip ( f )
The @code{strip} function removes all file and line information from the
given function @var{f}.  The parser ordinarily includes this information
so that, for example, run-time error messages can identify the line on
which they occurred.  If an error occurs in a function that has been
stripped, then the error is attributed instead to the calling
expression.@refill

This function may also be useful in conjunction with profiling.  Any
time spent in a call to a stripped function gets charged to the file and
line from which it was called.@refill

All members of @var{f} are left unchanged as members of the return value.
@end defun

@node system, , strip, Execution

@defun system ( s )
This function passes the string @var{s} to the command processor for
execution.  On a UNIX system, for example, the statement
@code{system("ls")} lists the files in the current directory.  If the
call succeeds, the exit status is returned; otherwise a --1 is returned.@refill
@end defun

@node Special Tools, Miscellaneous, Execution, Standard Functions
@section Special Tools

@ifinfo
@menu
* npsol::	nonlinear optimization
* plot::	plot curves
* replot::      modify a plot
* splot::       plot surfaces
* umin::        unconstrained minimization
* unplot::      terminate plots
@end menu
@end ifinfo

@node npsol, plot, Special Tools, Special Tools

@defun npsol ( objective; start; constraints; options; state )
The @code{npsol} function uses a sequential quadratic programming method
to minimize a given objective function subject to given constraints.
The domain of the objective function is called the ``design space'', and
the coordinates of the design space are called ``design
variables''.@refill

This function uses the NPSOL package of Fortran routines developed and
sold by Stanford University.  Your version of Algae might not have the
@code{npsol} builtin function; if not, it probably means that you don't
have a license for NPSOL or that there was some problem installing it on
your computer.@refill

The @code{npsol} function may not be called recursively.@refill

The @var{objective} argument may be either a function or a table.  If a
function, then it's assumed to take one argument, a vector of design
variables, and return the value of the objective at that point.  If
@var{objective} is a table, it may have the following members:@refill

@table @code
@item objf
A function that returns the value of the objective function for the
vector of design variables given as its first argument.  If the member
@code{params} exists in @var{objective}, then it is passed as a second
argument to @code{objf}.@refill

@item objgrd
A function that returns the sensitivities of the objective function;
that is, the first derivatives with respect to the design variables.
Its arguments are the same as for @code{objf}.@refill

@item params
This member, if it exists, is passed as the second argument to
@code{objf} and @code{objgrd}, providing a means for passing additional
parameters to those functions.@refill
@end table

Only the @code{objf} member is required.  If the objective derivatives
are not provided, you must ensure that @code{derivative_level} is set
accordingly.@refill

The @var{start} argument is a vector that specifies the starting
point.@refill

The @var{constraints} argument is a table that may contain any of all of
the following members:@refill

@table @code
@item side_constraints
A matrix that specifies upper and lower constraints on values of the
design variables.  This matrix has two columns, the first column giving
lower bounds and the second column giving upper bounds.  If this member
is not given, then a default is provided using 1.0E10 as ``infinity''.
In that case, you should be aware that NPSOL will take these values
literally if you also use the ``infinite_bound'' option (in
@var{options}) with a value greater than 1.0E10.@refill

@item linear_constraints
A table that may contain any or all of the following members:@refill

@table @code
@item coefficients
A matrix of the linear constraint coefficients.  The i-th row contains
the coefficients for the i-th linear constraint.@refill

@item bounds
A matrix, like @code{side_constraints}, that gives the upper and lower
bounds for the linear constraints.  If not given, defaults are provided
as with @code{side_constraints}.@refill
@end table

@item nonlinear_constraints
A table that may contain any or all of the following members:

@table @code
@item values
Either a function that computes the vector of nonlinear constraint
function values at the given point, or a table in which member
@code{conf} is a function returning the values and @code{congrd} is a
function returning the gradients.  The constraint gradients, if
provided, should be given as a matrix in which the rows correspond to
the constraints and the columns correspond to the design variables.  As
in @var{objectives}, a member called @code{params} may also be
included.@refill

@item bounds
A matrix, like @code{side_constraints}, that gives the upper and lower
bounds for the nonlinear constraints.  If not given, defaults are
provided as with @code{side_constraints}.@refill
@end table

If the constraint derivatives are not provided, you must ensure that
@code{derivative_level} is set accordingly.@refill

The @var{options} argument is a table that may contain any of the valid
NPSOL options.  For example, @code{@{ hessian = "yes" @}} specifies the
corresponding option in NPSOL.  Use an underscore instead of blanks
between words, as in @code{@{ major_print_level = 1 @}}.  The valid
options are:@refill

@table @code
@item central_difference_interval
If the algorithm switches to central differences because the
forward-difference approximation is not sufficiently accurate, this value
is used as the difference interval for every variable.@refill

@item cold_start
@itemx warm_start
These flags control the specification of the initial working set in
both the procedure for finding a feasible point for the linear
constraints and bounds, and in the first QP subproblem thereafter.  With
a @code{cold_start}, the first working set is chosen by @code{npsol}
based on the values of the variables and constraints at the initial
point.  Broadly speaking, the initial working set will include equality
constraints and bounds or inequality constraints that violate or
``nearly'' satisfy their bounds within @code{crash_tolerance}.  With a
@code{warm_start}, the user must provide the @code{state} table.  A warm
start will be advantageous if a good estimate of the initial working set
is available---for example, when @code{npsol} is called repeatedly to
solve related problems.@refill

@item crash_tolerance
This value is used in conjunction with the optional parameter
@code{cold_start}, which is the default.  When making a cold start, the
QP algorithm in @code{npsol} must select an initial working set.  The
initial working set will include, if possible, bounds or general
inequality constraints that lie within @code{crash_tolerance} of their
bounds.  The default value is 0.01.  If @code{crash_tolerance} is less
than zero or greater than one, the default value is used.@refill

@item derivative_level
This value indicates which objective and constraint derivatives are
provided by the user.  The choices are as follows:

@table @code
@item 0
Neither objective nor constraint derivatives are provided.@refill

@item 1
The objective derivatives are provided by the @code{objgrd} function in
argument @var{objective}.  Constraint derivatives are not
provided.@refill

@item 2
The nonlinear constraint derivatives are provided by the @code{congrd}
function in argument @var{constraints}.  Objective derivatives are not
provided.@refill

@item 3
The objective derivatives are provided by the @code{objgrd} function in
argument @var{objective}, and the nonlinear constraint derivatives are
provided by the @code{congrd} function in argument @var{constraints}.@refill
@end table

The value 3 is the default, and should be used whenever possible, since
@code{npsol} is more reliable and will usually be more efficient when
all derivatives are exact.@refill

If @code{derivative_level} is 0 or 2, @code{npsol} will estimate the
objective gradients using finite differences.  The computation of
finite-difference approximations usually increases the total run time,
since a call to the objective function is required for each constraint.
Furthermore, less accuracy can be attained in the solution.@refill

If @code{derivative_level} is 0 or 1, @code{npsol} will approximate the
constraint gradients.  One call to the constraint function is required
for each variable.  At times, central differences are used rather than
forward differences, in which case twice as many calls to the objective
and constraint functions are needed.  The switch to central differences
is not under the user's control.@refill

@item difference_interval
This value defines an interval used to estimate gradients by finite
differences in the following circumstances: (1) for verifying the
objective and constraint gradients, and (2) for estimating the objective
or constraint derivatives.  If a difference interval is not specified by
the user, a finite difference interval will be computed automatically
for each variable by a procedure that requires up to six calls of the
objective and constraint functions for each component.  This option is
recommended if the function is badly scaled or the user wishes to have
@code{npsol} determine constant elements in the objective and constraint
gradients.@refill

@item feasibility_tolerance
This value defines the maximum acceptable absolute violations in linear
and nonlinear constraints at a ``feasible'' point; i.e., a constraint is
considered satisfied if its violation does not exceed this value.  The
default value is the square root of machine precision.@refill

@item function_precision
This value is intended to be a measure of the accuracy with which the
objective and constraint functions can be computed.  It acts as a
relative precision when the magnitude is large, and as an absolute
precision when the magnitude is small.  For example, if the objective
function is typically on the order of 1000 and the first 6 digits are
known to be correct, then @code{function_precision} should be set to
1.0E--6. In contrast, if the objective function is typically on the
order of 1.0E--4 and the first 6 digits are known to be correct, then
@code{function_precision} should be set to 1.0E--10.  The choice of
@code{function_precision} can be quite complicated for badly scaled
problems.  The default value is machine precision raised to the 0.9
power; this is appropriate for most simple functions that are computed
with full accuracy.  However, when the accuracy of the computed function
values is known to be significantly worse than full precision, then
@code{function_precision} should be large enough that @code{npsol} will
not attempt to distinguish between function values that differ by less
than the error inherent in the calculation.@refill

@item hessian
This option must be either @code{"yes"} or @code{"no"}.  (The default is
@code{"no"}).  This option controls the contents of the @code{R} matrix
in @var{state}.  The user should set @code{hessian} to @code{"yes"} if
the @code{state} table returned is to be used for a subsequent warm
start.@refill

@item infinite_bound_size
If this value is greater than zero, it defines the ``infinite'' bound
in the definition of the problem constraints.  Any upper bound greater
than or equal to this value will be regarded as positive infinity.  Any
lower bound less than or equal to the negative of this value will be
regarded as negative infinity.  The default value is 1.0E10.@refill

@item infinite_step_size
This value specifies the magnitude of the change in variables that is
treated as a step to an unbounded solution.  If the change in any
variable during an iteration would exceed the value of
@code{infinite_step_size}, the objective function is considered to be
unbounded below in the feasible region.  The default is the greater of
@code{infinite_bound_size} and 1.0E10.@refill

@item iteration_limit
This value specifies the maximum number of major iterations allowed
before termination.@refill

@item linear_feasibility_tolerance
@itemx nonlinear_feasibility_tolerance
These values define the maximum acceptable absolute violations in linear
and nonlinear constraints at a ``feasible'' point.  A constraint is
considered satisfied if its violation does not exceed this value.  The
default value for both options is the square root of machine
precision.@refill

On entry to @code{npsol}, an iterative procedure is executed in order to
find a point that satisfies the linear constraints and bounds on the
variables to within @code{linear_feasibility_tolerance}.  All subsequent
iterates will satisfy the linear constraints to within the same
tolerance, unless this value is comparable to the finite difference
interval.@refill

For nonlinear constraints, @code{nonlinear_feasibility_tolerance}
defines the largest constraint violation that is acceptable at an
optimal point.  Since nonlinear constraints are generally not satisfied
until the final iterate, this value acts as a partial termination
criterion for the iterative sequence.@refill

These tolerances should reflect the precision of the corresponding
constraints.  for example, if the variables and the coefficients in the
linear constraints are of order unity, and the latter are correct to
about 6 decimal digits, it would be appropriate to specify
@code{linear_feasibility_tolerance} as 1.0E--6.@refill

@item linesearch_tolerance
This value controls the accuracy with which a step taken during each
iteration approximates a minimum of the merit function along the search
direction.  The smaller the value, the more accurate the line search.
The default value is 0.9; it requests an inaccurate search that is
appropriate for most problems, particularly those with any nonlinear
constraints.@refill

If there are non nonlinear constraints, a more accurate search may be
appropriate when it is desirable to reduce the number of major
iterations---for example, if the objective function is cheap to evaluate
or if the gradients are not specified.@refill

@item list
If this flag is given, all of the options and their values are
printed.@refill

@item print_level
This value controls the amount of printed output produced by the major
iterations of @code{npsol}.  The levels are as follows:@refill

@table @code
@item 0
No output.  This is the default.

@item 1
The final solution only.

@item 5
One line of output for each major iteration, but no final
solution.@refill

@item 10
The final solution and one line of output for each iteration.@refill

@item 20
At each major iteration, the objective function, the Euclidean norm of
the nonlinear constraint violations, the value of the nonlinear
constraints, the values of the linear constraints, and the current
values of the variables.@refill
@end table

@item minor_iteration_limit
This value specifies the maximum number of iterations for the optimality
phase of each QP subproblem.@refill

@item minor_print_level
This value controls the amount of printout produced by the minor
iterations of @code{npsol}.  The levels are as follows:@refill

@table @code
@item 0
No output.  This is the default.@refill

@item 1
The final QP solution.

@item 5
One line of output for each minor iteration, but no final QP
solution.@refill

@item 10
The final QP solution and one line of output for each minor iteration.

@item 20
At each minor iteration, the current estimates of the QP multipliers,
the current estimate of the QP search direction, the QP constraint
values, and the status of each QP constraint.@refill
@end table

@item optimality_tolerance
This value specifies the accuracy to which the user wishes the final
iterate to approximate a solution of the problem.  Broadly speaking, it
indicates the number of correct figures desired in the objective
function at the solution.  For example, if @code{optimality_tolerance}
is 1.0E--6 and @code{npsol} terminates successfully, the final value of
the objective function should have approximately 6 correct figures.  The
@code{npsol} function will terminate successfully if the iterative
sequence is judged to have converged and the final point satisfies the
first-order optimality conditions.@refill

@item verify_level
This value refers to finite-difference checks on the gradients computed
by the user function @code{objgrd} and @code{congrd}.  It may take on
one of the following values:@refill

@table @code
@item -1
No checks are made.

@item 0
Perform only a very inexpensive check, involving one call to the
objective function and one call to the constraint function.@refill

@item 1
Perform a reliable but expensive check on the objective
gradients.@refill

@item 2
Perform a reliable but expensive check on the constraint
gradients.@refill

@item 3
Perform reliable but expensive checks on both the objective and the
constraint gradients.@refill
@end table

@noindent
These checks are recommended whenever a new function routine is being
developed.@refill
@end table

The @var{state} argument is used only when the NPSOL ``warm_start''
option is requested.  It may be obtained from the return of a previous
call to @code{npsol}.  Its members are:@refill

@table @code
@item ISTATE
A vector describing the status of the constraints.

@item CLAMDA
The Lagrange multiplier estimates for the nonlinear constraints.

@item R
The factored Hessian of the Lagrangian function.
@end table

The @code{npsol} function returns a table containing the following
members:@refill

@table @code
@item objective
The value of the objective function at the final iterate.

@item solution
The solution vector (or final estimate) for the problem.

@item inform
The INFORM value (success/error indicator) returned by NPSOL.  The
possibilities are:@refill

@table @code
@item 0
The iterates have converged to a point that satisfies the first-order
optimality conditions to the accuracy requested by the optional
parameter @code{optimality_tolerance}, i.e., the projected gradient and
active constraint residuals are negligible.  (Success.)@refill

@item 1
The final iterate satisfies the first-order optimality conditions to the
accuracy requested, but the sequence of iterates has not yet converged.
NPSOL was terminated because no further improvement could be made in the
merit function.  (Probable success.)@refill

@item 2
No feasible point could be found for the linear constraints and bounds.
The problem has no feasible solution.@refill

@item 3
No feasible point could be found for the nonlinear constraints.  The
problem may have no feasible solution.@refill

@item 4
The limiting number of iterations, determined by the optional parameter
@code{major_iteration_limit}, has been reached.@refill

@item 6
The current point does not satisfy the first-order optimality
conditions, and no improved point for the merit function could be found
during the final line search.@refill

@item 7
The user-provided derivatives of the objective function and/or nonlinear
constraints appear to be incorrect.@refill

@item 9
An input parameter is invalid.
@end table

@item iter
The number of major iterations performed.

@item state
The @code{state} table described above.
@end table
@end table
@end defun

@node plot, replot, npsol, Special Tools

@defun plot ( @dots{} )
The @code{plot}, @code{splot}, @code{replot}, and @code{unplot}
functions provide an interface to the gnuplot program for plotting
data.  Use @code{plot} for plotting lines in two or three dimensions;
@code{splot} is for plotting surfaces in three dimensions.@refill

To use these plotting functions effectively, you will probably need some
familiarity with the gnuplot commands.  For example, to add a title to an
existing plot, you'd type something like @code{replot("set title 'Good
Stuff'")}.  Read the gnuplot manual or its on-line help for more
information.@refill

The @code{plot} function accepts as many as three arguments.  If either
or both of the first two arguments are (or can be converted to)
character vectors, then their elements are sent, each on a separate
line, to gnuplot as commands.  For example, @code{plot("set term X11")}
causes gnuplot to generate X11 output.  Even commands that request
information from gnuplot, like @code{plot("show term")} are acceptable
(although you might temporarily lose sight of Algae's prompt).  Don't use
the ``exit'' or ``quit'' commands of gnuplot---they cause gnuplot to
exit without Algae knowing about it.@refill

If more than one argument is given to @code{plot} and the last one is an
integer scalar, then it is taken to be an identifier for the plot
process.  This allows you to have more than one plot open at a time.  If
no identifier is given, then the active plot is killed and replaced by a
new one with the same identifier.  The ``active'' plot is the one last
referenced, or 1 if there are no plots open.  The @code{replot} function
may be used to modify an open plot.@refill

Any other arguments given to @code{plot} are taken to be data to be
plotted.  Vectors are plotted using their element values as ordinates
and their labels for the abscissae.  Matrices with 2 columns are plotted
using the second column for ordinates and the first column for
abscissae.  A matrix with 3 columns is plotted as a curve in three
dimensions, with the third column specifying the ordinates.  Surface
plots are obtained using the @code{splot} function.@refill

If the data given to @code{plot} is a vector, but has no labels, then
the element indices are used instead of the labels.@refill

Multiple curves may be shown on the same plot, either by giving
@code{plot} two data arguments or (better yet) supplying the data in a
table.  When data is given in a table (even if it contains only one
member), the member name is used in the plot legend.  Otherwise,
@code{plot} uses the names ``y_1'' and ``y_2''.@refill

If the data is given in a table, any members that are tables themselves
are given to gnuplot in a single data file.  This means that the same
line and point type is used.  For example, if @code{x} and @code{y} are
vectors to be plotted, then @code{plot(@{x;y@})} plots the two, each
with a different line and point type and described by name in the
legend.  On the other hand, @code{plot(@{z=@{x;y@}@})} plots them with
the same line and point type and names the combination ``z'' in the
legend.@refill

If @code{plot} is called with no arguments, it returns a vector of the
open plot identifiers.  This vector is sorted from most to least
recently referenced, so the ``active'' plot is first.@refill

Here's an example that simulates the Van der Pol system and plots the
results:@refill

@example
xdot = function( t; x ) @{
    return x[1]*(1-x[2]^2)-x[2], x[1];
@}
x = ode4( xdot; 0; 20; 0,.25 );
plot( "set data style lines"; @{ x1=x[1;]; x2=x[2;] @} );
@end example

See also @code{splot}, @code{replot}, and @code{unplot}.
@end defun

@node replot, splot, plot, Special Tools

@defun replot ( @dots{} )
The @code{replot} function is used to modify or redisplay plots created
with either the @code{plot} or @code{splot} functions.  It takes at most
2 arguments.  If the first argument has character type, it is passed to
gnuplot as commands.@refill

The last argument is the optional plot identifier.  If not given, the
active plot is used by default.@refill

See also @code{plot}, @code{splot}, and @code{unplot}.
@end defun

@node splot, umin, replot, Special Tools

@defun splot ( @dots{} )
The @code{splot} function is used to plot surfaces in three dimensions.
Except for the form of the data, its input is identical to that of the
@code{plot} function.  The data is specifed as a matrix of ordinates.
The labels of the matrix, or the corresponding indices if the labels
don't exist, are used for the abscissae.@refill

See also @code{plot}, @code{replot}, and @code{unplot}.
@end defun

@node umin, unplot, splot, Special Tools

@defun umin ( objective; start; options )
The @code{umin} function performs unconstrained minimization using the
Nelder-Mead direct search method.  It does not have the features or
sophistication of @code{npsol}, but it works well for some
cases---particularly when the objective surface is not smooth.@refill

The @var{objective} argument is a function that takes one or two
arguments and returns the value of the objective at that point.  The
first argument is a vector of design variables.  The second
argument, which is optional, is passed unchanged from the @var{params}
member of the @var{options} argument to @code{umin} itself.@refill

The @var{start} argument is an integer or real vector that specifies the
starting point.@refill

The @var{options} augument may be either NULL or a table containing
convergence and other specifications.  The meaningful options are:@refill

@table @code
@item bound
The minimum value permitted for the objective function.  The default is
--1e32.@refill

@item display
A function called at each ``successful'' iteration with the current design
point as its only argument.  This may be used, for example, to plot the
design as it changes.@refill

@item evals
The maximum number of objective function evaluations permitted.  The
default value is 1000.@refill

@item iter
The maximum number of iterations permitted.  The default value is
100.@refill

@item params
The value of this member is passed as the second argument to the
objective function.@refill

@item right
If this member exists, then the initial simplex has right angles.  By
default, the initial simplex has sides of equal length.@refill

@item size
The initial size of the simplex.  By default, this is the greater of 1
and the infinity norm of the starting vector.@refill

@item tol
The relative size of the simplex, below which the iteration is taken to
have converged.  The tolerance is 1e--6 by default.@refill

@item verbose
If this member exists, then information is printed at each ``successful''
iteration.@refill
@end table

The return value from @code{umin} is a table with the following
members:@refill

@table @code
@item evals
The number of objective function evaluations.@refill

@item inform
A return code specifying success or failure:@refill

@table @code
@item 0
success

@item 1
failure, objective bound reached

@item 2
failure, function evaluation limit exceeded

@item 3
failure, iteration limit exceeded
@end table

@item iter
The number of iterations performed.@refill

@item msg
A message corresponding to the inform code.@refill

@item obj
The final objective value.@refill

@item sol
The final design point.@refill
@end table

This code is based on @code{nmsmax}, a MATLAB function by Nick
Higham.@refill

See also @code{npsol}.
@end defun

@node unplot, , umin, Special Tools

@defun unplot ( id )
The @code{unplot} function is used to terminate plots created with the
@code{plot} or @code{splot} functions.  The integer scalar or vector
argument @var{id} specifies the identifiers of the plots to be
terminated.  If no @var{id} is given, the active plot is terminated.
You can terminate all open plots with @code{unplot(plot())}.@refill

See also @code{plot}, @code{replot}, and @code{splot}.
@end defun

@node Miscellaneous, , Special Tools, Standard Functions
@section Miscellaneous

@ifinfo
@menu
* all::         test all elements
* atof::        convert string to number
* char::        vector to character string
* class::	entity class
* equal::	test for equality
* members::	members of a table
* info::        documentation browsing system
* prof::        summarize profiler output
* show::	show entity information
* split::       split string into fields
* string::      convert to character type
* substr::      return a substring
* test::	truth test
* time::        user time
* tolower::     convert strings to lower case
* toupper::     convert strings to upper case
* what::	list functions
* who::		list variables
@end menu
@end ifinfo

@node all, atof, Miscellaneous, Miscellaneous

@defun all ( x )
The @code{all} function evaluates the ``truth'' of its argument @var{x}
in the same way that the function @code{test} does, except that vectors
and matrices are ``true'' only if all of their elements are ``true''.
For example, @code{all(1,0)} returns 0 while @code{test(1,0)} returns
1.  If @var{x} has no elements, @code{all} returns 0.@refill

See also @code{test} and @code{equal}.
@end defun

@node atof, char, all, Miscellaneous

@defun atof ( s )
The @code{atof} function converts character strings to real numbers.
The argument @var{s} may be a scalar, vector, or matrix.  The function
reads only up to the first unrecognized character of each string, and
ignores anything that remains.  If the first character of a string is
unrecognized, then the value is taken to be zero.@refill
@end defun

@node char, class, atof, Miscellaneous

@defun char ( v )
The @code{char} function converts the vector @var{v} into a character
string; each element of @var{v} contributes a single character according
to its ASCII value.  For example, @code{char(65,66,67)} returns the
string @code{"ABC"}.@refill

If an element of @var{v} is less than 0 or greater than 255, then it
will ``wrap'' (modulo 256).  Thus @code{char(65)} and
@code{char(65+256)} both return the string @code{"A"}.@refill

Algae's character strings are terminated with a NUL (0) character.  For
the @code{char} function, that means that if an element of @var{v} is
zero (or a multiple of 256) then the string is terminated at that
point.  For example, @code{char(65,0,66)} yields the string
@code{"A"}.@refill
@end defun

@node class, equal, char, Miscellaneous

@defun class ( x )
The @code{class} function returns a character string (such as ``scalar''
or ``table'') that describes the class of @var{x}.@refill
@end defun

@node equal, members, class, Miscellaneous

@defun equal ( a; b )
This function tests @var{a} and @var{b} for equality.  For vectors and
matrices, it returns true (1) only if every pair of corresponding
elements is equal, and false (0) otherwise.  For all other classes, this
function returns the same value as the expression @code{a==b}
would.@refill

See also @code{test}.
@end defun

@node members, info, equal, Miscellaneous

@defun members ( e )
This function returns a vector containing the names of the members of
@var{e}.@refill
@end defun

@node info, prof, members, Miscellaneous

@defun info ( topic )
This function starts up an interactive browser for Algae's
documentation.  The optional argument @var{topic} (a character scalar)
takes you directly to that topic.  For example, @code{info("sort")}
takes you directly to the description of the @code{sort}
function.@refill

If possible, @code{info} uses an X-based html browser (like netscape
or mosaic).  Otherwise, a character-based html browser (like lynx)
will be tried.  As a final resort, the GNU Info browser is called.@refill

The names of the available browsers are assigned by the startup code
(@pxref{Startup Files}) as members @code{xhtml}, @code{html}, and
@code{info} of the global table @code{$programs}.  To prevent
Algae from using a particular browser, simply set the
appropriate member of @code{$programs} to a zero-length string.  If
you prefer to use Info, for example, you could simply put the
line@refill

@example
$programs.xhtml = $programs.html = "";
@end example

in your @file{.algae} file.
@end defun

@node prof, show, info, Miscellaneous

@cindex Execution profiling
@cindex Profiling
@cindex algae.out
@defun prof ( infile; outfile; threshold )
The @code{prof} function reads an @file{algae.out} file produced by
Algae's execution profiler (the @samp{-p} option), and summarizes
it by file and by line number.  The @var{infile} argument specifies the
file name.  @var{outfile} specifies the output file; if it's NULL,
stdout is used.@refill

The @var{threshold} argument may be used to truncate the summary
listings.  The truncation occurs after enough entries have been printed
to account for @var{threshold} percent of the total number of hits.  If
@var{threshold} is NULL, no truncation is performed.@refill

Below is an example of @code{prof} output, obtained with the command
@code{prof("algae.out";;50);}.@refill

@example
Algae execution profile listing.

628 total hits

--- by file ---

      hits   % hits    cum %   file
       201    32.01    32.01   lqrtest.A
       127    20.22    52.23   /usr/local/lib/algae/ode.A

--- by line ---

      hits   % hits    cum %   line   file
       130    20.70    20.70     88   lqrtest.A
        42     6.69    27.39      1   /usr/local/lib/algae/plot.A
        40     6.37    33.76     38   lqrtest.A
        21     3.34    37.10      1   /usr/local/lib/algae/ode.A
        17     2.71    39.81     44   /usr/local/lib/algae/ode.A
        15     2.39    42.20     42   /usr/local/lib/algae/ode.A
        15     2.39    44.59     41   /usr/local/lib/algae/ode.A
        14     2.23    46.82      1   /usr/local/lib/algae/ode4.A
        12     1.91    48.73      1   /usr/local/lib/algae/spline.A
        10     1.59    50.32      1   lqrtest.A
@end example

First, notice that the number of hits counted in this example was only
628.  Four digits of precision in the statistics are clearly unjustifed
with such a small sample.  The first column reports the number of
profiler hits counted toward each particular file or line number.  The
second column restates that as a percentage of the total number of hits.
The third column gives the cumulative percentage.@refill

All profiler hits that occur while Algae is parsing a file are
counted toward its first line.  This is normally insignificant compared
to execution, but it explains why line 1 shows up so often in the ``by
line'' report in the example above.@refill

No files are closed in @code{prof}.  Normally, this means that you must
close them yourself if @code{prof} is to be called more than
once.@refill
@end defun

@node show, split, prof, Miscellaneous

@defun show ( e )
This function prints information about the entity @var{e} and its
members.@refill
@end defun

@node split, string, show, Miscellaneous

@cindex Splitting into tokens
@cindex Tokens, splitting
@defun split ( s; w )
The @code{split} function takes a character scalar argument @var{s},
splits it into tokens, and returns the tokens in a character vector.
Each token is delimited by one or more characters from @var{w}.  For
example, @code{split("/bin:/usr/bin";":")} returns the vector@refill

@example
(  "/bin"    , "/usr/bin" )
@end example

If @var{w} is NULL, the string @code{" \t\n"} is used.  Thus
@code{split("This is a test.")} returns the vector@refill

@example
(  "This" , "is"   , "a"    , "test." )
@end example
@end defun

@node string, substr, split, Miscellaneous

@cindex Strings
@cindex Character strings
@defun string ( e )
The @code{string} function converts its argument @var{e} to character
type.  If @var{e} is NULL, a zero-length character scalar is returned.
For example, @code{string(1/(1:3))} returns the vector@refill

@example
(  "1"       , "0.5"     , "0.333333" )
@end example

Currently, the output format cannot be changed.
@end defun

@node substr, test, string, Miscellaneous

@cindex Substrings
@cindex Character strings
@defun substr ( c; start; length )
The @code{substr} function returns the substring of the character string
@var{c}, beginning at index @var{start}, with length @var{length}.  The
integer @var{start} must be greater than zero; if it exceeds the length
of @var{c}, then a zero-length string is returned.  If @var{length} is
NULL, then all of the remaining characters of @var{c} are returned;
otherwise, @var{length} must not be negative.@refill

See also @code{dice}, @code{split}, and @code{string}.@refill
@end defun

@node test, time, substr, Miscellaneous

@defun test ( e )
The @code{test} function evaluates the ``truth'' of @var{e} in the same
way that Algae's @code{if} statement would, returning 1 for true and 0
for false.  The following entities are false:@refill

@itemize @bullet
@item
NULL.

@item
Numeric arrays in which every element is zero.

@item
Character arrays in which every element is @code{""}.

@item
Vectors and matrices with no elements.

@item
Tables with no members.
@end itemize

@noindent
All others are true.  Notice that if @var{e} is an array
(@code{scalar}, @code{vector}, or @code{matrix}), then @code{test}
returns true if any element of @var{e} is nonzero (or has nonzero
length, for character type).@refill

An example of the use of @code{test} is Algae's @code{equal} function,
which is written as@refill

@example
equal = function( a; b ) @{ return !test( a != b ); @}
@end example

@noindent
If @code{a} and @code{b} are both matrices, then @code{a!=b} returns a
matrix that is all zeros only if every element pair is equal.  In that
case, @code{test} returns 0 and @code{!} changes that to 1.@refill

See also @code{equal} and @code{all}.
@end defun

@node time, tolower, test, Miscellaneous

@defun time ( )
The @code{time} function returns the number of seconds of user time that
the current process has used.  On most machines, its precision is not
much more than 1/10 of a second.@refill
@end defun

@node tolower, toupper, time, Miscellaneous

@cindex Lower case
@cindex Case
@defun tolower ( s )
The @code{tolower} function converts strings to lower case.  Every
letter is converted as appropriate for the current locale.  The argument
@var{S} may be a character scalar, vector, or matrix.@refill

See also @code{toupper}.
@end defun

@node toupper, what, tolower, Miscellaneous

@cindex Upper case
@cindex Case
@defun toupper ( s )
The @code{toupper} function converts strings to upper case.  Every
letter is converted as appropriate for the current locale.  The argument
@var{S} may be a character scalar, vector, or matrix.@refill

See also @code{tolower}.
@end defun

@node what, who, toupper, Miscellaneous

@defun what ( )
The @code{what} function returns a table containing all of the global
functions.  See also @code{who}.@refill
@end defun

@node who, , what, Miscellaneous

@defun who ( opt )
The @code{who} function returns a table containing all global variables
that are neither functions nor NULL.  Variables with names that begin
with @samp{$} are excluded, unless the optional argument @var{opt}
equals @code{"$"}.  See also @code{what}.@refill
@end defun

@node Running Algae, Projects, Standard Functions, Top
@comment  node-name,  next,  previous,  up
@chapter Running Algae
@cindex Interpreter

The Algae interpreter assembles your Algae statements into its own
opcodes and then executes them.  When you are working interactively,
it does this one statement (or one block of statements) at a time.  When
its input comes from a file, the entire file is assembled before
execution of it begins.@refill

@menu
* Startup Files::
* Command Line::
* Errors::
* Prompt::
* Signals::
@end menu

@node Startup Files, Command Line, Running Algae, Running Algae
@section Startup Files
@cindex Startup files
@cindex Beginning execution

When Algae begins execution, it normally tries to read and
execute two startup files.  The first one it tries is the file in
which it expects some of its standard functions to be defined.  A
default name for this file is given when Algae is
compiled---usually it's something like
@file{/usr/local/lib/algae/VERSION_NUMBER/algae.A}.  That name can be
overridden with an environment variable called @code{ALGAE_RC0}.@refill

Without this file, some of Algae's standard functions will be
missing.  For this reason, Algae will emit an error message and
quit if it can't find the file.  (That is, unless the @samp{-S} option
is specified on the command line.)@refill

After Algae reads its standard functions, it looks for the file
@file{.algae} in your home directory and executes it if it's there.  This
file's name can be overridden with the @code{ALGAE_RC1} environment
variable.  Execution of this file is inhibited by the @samp{-s} command
line option.  No startup files at all are read if the @samp{-S} option
is given.@refill

@node Command Line, Errors, Startup Files, Running Algae
@section The Command Line
@cindex Command line arguments
@cindex Arguments, command line
@cindex Options on the command line
@cindex Files on the command line

Algae supports command line arguments to request various actions.
Arguments starting with @samp{-} are @dfn{options}.  Other arguments
specify files to execute.@refill

Option flags always begin with a hyphen.  Algae supports both traditional
single-letter options and mnemonic long option names.  Long option names
are indicated with @samp{--} instead of @samp{-}.  Abbreviations for
option names are allowed as long as they are unique.@refill

Options which change Algae's behavior take effect before any files are
executed.  The order of the arguments is unimportant, with the following
two exceptions:@refill
@enumerate
@item
Any input scripts given (with the @samp{-e} or @samp{--script} option)
are executed in the order that they appear on the command line.  This
occurs after the startup files are executed and before any other files
are executed.@refill

@item
Any input files named on the command line are executed in the order in
which they appear.@refill
@end enumerate

Below is a list of options accepted by Algae.  Both the short and long
option names are indicated.@refill

@table @samp
@item -D
@itemx --disassemble
@cindex Disassembler
This option turns on the disassembler, which prints Algae's
opcodes to stderr in a form like assembly language.  You'll probably
want to combine this with the @samp{-S} option; otherwise, you'll get
more than 800 lines of opcodes from the standard functions.@refill

@item -d @var{i}
@itemx --debug @var{i}
@cindex Debug level
This option sets the debug level to @var{i}, where @var{i} is an
integer.  It is normally of use only for debugging the Algae
implementation.@refill

@item -e @var{commands}
@itemx --script @var{commands}
This option allows you to provide a script for Algae to execute
from the command line, rather than from a file or from standard input.
Such a script is executed after any startup files but before any other
files are executed.  Any number of @samp{-e} (or @samp{--script})
options may be given, and the specified scripts are executed in the
order in which they appear on the command line.@refill

@item -h
@itemx --help
Print a brief description of the command line arguments.

@item -i
@itemx --interactive
@cindex Standard input
@cindex stdin
@cindex Interactive mode
This option causes Algae to use interactive mode when reading from
the standard input device ``stdin''.  Without this option, Algae
uses interactive mode only when its input appears to be from a terminal.
In interactive mode, input is parsed a line at a time and exceptions do
not cause Algae to exit.@refill

@item -n
@itemx --nowhite
This option changes the way that scalars are displayed.  The printing
statements (that is, statements that are terminated by either a newline
or a @samp{?} character) normally precede the scalar's value with a tab,
and follow it with a newline.  With this option set, neither the tab nor
the newline is printed.  (For character scalars, the quotation marks are
also omitted.)  This option affects the printing statements only, and
has no effect on the functions like @code{printf}.@refill

@item -p
@itemx --profile
@cindex Execution profiling
@cindex Profiling
@cindex algae.out
This option enables execution profiling---a means for determining the
execution time characteristics of your Algae program.  When profiling is
enabled, the profiler periodically interrupts Algae and records
the line that is currently being executed.  When Algae exits, it
records this data in the file @file{algae.out} in the current
directory.@refill

Use the @code{prof} function to read the @file{algae.out} file and
summarize it by file and by line number.@refill

You may wish to use the @code{strip} function in conjunction with
profiling.  Since @code{strip} removes the line and file information
from a function, any time spent in a call to that function gets charged
to the line from which it was called.@refill

We've encountered several systems on which operating system bugs prevent
the execution profiler from working correctly.  These include a
DECstation and a Titan, both with MIPS architectures.  If you have such
a system, then Algae should have been installed with the execution
profiler disabled.  In that case, you'll get an error message if you try
to use the @samp{-p} option.@refill

@item -R
@itemx --restrict
@cindex Restricted execution
@cindex Pipes
@cindex Input filters
@cindex Output filters
This option causes Algae to run in restricted mode.  The
@code{system} function is disabled, as are "pipes" (i.e., file names
that begin with the @samp{!} character).@refill

Restricted mode should be used whenever you deal with untrusted Algae
code.  Without it, a malicious provider of such code could cause major
damage.@refill

@item -r
@itemx --noreadline
@cindex Readline facility
@cindex Emacs
@cindex vi
If the GNU Readline facility is available, Algae normally uses it
for interactive command line editing and history.  The @samp{-r} option
forces Algae to skip Readline processing.  Readline's editing
commands are similar to emacs: @kbd{C-f} forward, @kbd{C-b} backward,
@kbd{C-p} up, and @kbd{C-n} down.  You can change to @code{vi} style by
typing @kbd{M-C-j}.@refill

@item -S
@itemx --nostartup
If this option is given, none of Algae's startup files are read.
This means that many of the standard functions will be unavailable.@refill

@item -s
@itemx --norc
This option skips reading the user's startup file.

@item -V
@itemx --version
@cindex Version
This option prints version and date information.

@item -x
@itemx --nostdin
@cindex stdin
This option causes Algae not to read stdin by default when no
file names are given on the command line.
@end table

Any file names given on the command line are executed as input to Algae.
If no file names are given (and the @code{-x} option is not present),
input comes from stdin.  You can specify stdin explicitly with a single
hyphen, so a command line like@refill

@example
algae init.A -
@end example

@noindent
has Algae execute @file{init.A} first and then read from standard
input.@refill

@node Errors, Prompt, Command Line, Running Algae
@section Errors
@cindex Error messages
@cindex Messages, error

Several types of errors may be encountered when running Algae.
The two most common are @dfn{parse} errors and @dfn{run time} errors.
Parse errors occur while Algae is parsing its input statements.
Run time errors occur while Algae is executing its code.  In both
cases, Algae prints a file name and line number associated with
the error.@refill

@node Prompt, Signals, Errors, Running Algae
@section The algae Prompt
@cindex Prompt

When executing interactively, Algae displays the primary prompt
when it is ready to read a command, and the secondary prompt when it
needs more input to complete a command.  You can customize the prompt
simply by assigning a character vector to the global variable
@code{$prompt}.  Its first two elements specify the primary and
secondary prompts.  By default, @code{$prompt} is @code{( "> ", " " )}.
Assigning something other than a character vector to @code{$prompt} is
not an error---Algae just won't give you a prompt.  (Wouldn't it
be fun to accept a function?  Hmm, maybe someday.)@refill

If the GNU Readline facility is available (that is, linked with
Algae during installation), Algae normally uses it for
interactive command line editing and history.  Readline's editing
commands are similar to emacs: @kbd{C-f} forward, @kbd{C-b} backward,
@kbd{C-p} up, and @kbd{C-n} down.  You can change to @code{vi} style by
typing @kbd{M-C-j}.  The @samp{-r} command line option forces
Algae to skip Readline processing.@refill

@node Signals, , Prompt, Running Algae
@section Signals
@cindex Signals

@cindex SIGINT
@cindex Interrupt signal
@cindex Killing Algae
If Algae receives an interrupt signal (because you pressed a
@kbd{C-c} on the keyboard, for example), it stops what it's doing and
returns to the prompt.  (If it isn't running interactively, it simply
exits.)  On Unix systems, you can also use the @code{kill} command to
send a signal to a process.@refill

The implementation of interrupt signal handling in Algae is
necessarily a compromise.  We want it to respond promptly, but not at
the expense of our performance.  As a result, it sometimes happens that
Algae does not respond promptly to an interrupt signal.  (If you
find a case like this; please report it.  Sometimes it's the result of
an oversight.)@refill

@cindex SIGQUIT
@cindex Quit signal
Sending Algae a quit signal causes an immediate, clean exit.
There are various other signals which will cause Algae to
terminate, but this is the one to use if you want your files closed
properly, etc.@refill

@node Projects, Bugs, Running Algae, Top
@comment  node-name,  next,  previous,  up
@chapter Projects
@cindex Projects
@cindex Future of Algae

Below is a list of improvements that we'd like to make to Algae.  These
items run the gamut from specific changes that would take only an hour
or so to implement to vague, half-baked ideas that might take months.
The items are in no particular order---we haven't identified priorities
on most of them.  We'd be very happy to have some help.@refill

@itemize @bullet
@comment Done in version 3.7.1
@ignore
@item
Algae should incorporate the ARPACK sparse matrix routines.  This will
be a bit of work, but pretty straightforward.  I consider this a high
priority.@refill
@end ignore

@item
Algae's FFT routines are old and crusty, but they work well.  Still, we
ought to take a look at the FFTW code and consider using it.@refill

@item
The @code{atan} and @code{atanh} functions need improvement for complex
arguments.  They are based on simple formulas, but better algorithms are
available that are faster, more accurate, and less prone to
overflow.@refill

@item
In the old days, getting Readline to do context-based completion (as on
variable names) was nearly impossible.  This may have changed -- we
ought to take a new look at it.@refill

@item
The @code{printf} and related functions should be given additional
capabilities to accept array arguments.@refill

@item
I'm interested in exploring a better arrangement for the help system.
Users should be able to tie in documentation for their own code.@refill

@comment Done in version 2.2.0.
@ignore
@item
We should fix up the @code{get} and @code{put} functions to maintain
their own internal references.  For example, the statement @code{A=B=C}
results in three variables that point to the same entity in memory.  But
if you then type @code{put(@{A;B;C@})}, that entity winds up being written
three times.@refill
@end ignore

@comment Done in version 3.0.3.
@ignore
@item
We ought to provide a capability for reporting the global variables used
or modified by functions.  A simple implementation would be very
easy.@refill
@end ignore

@item
With the @code{builtin} function, Algae has dynamic linking
capability.  To make this useful, though, we have to document the
interface and reorganize the header files.@refill

@item
Wouldn't a @uref{http://www.gtk.org/, GTK+} interface be nice?@refill

@item
We need to complete the @code{fread} and @code{fwrite} implementation,
and we'll probably want an @code{fseek} function as well.@refill

@item
Symbolic debugging of Algae code would be very helpful.

@comment Hmm, now this seems like a dumb idea.
@ignore
@item
We've considered implicit operations on array elements.  For example,
@code{A[+;]} would sum each row of the matrix @code{A}.  Likewise,
@code{V[cos]} would apply the @code{cos} function to each element of the
vector @code{V}.@refill
@end ignore

@comment What's wrong with `pick'?
@ignore
@item
A couple of additional operators would be useful for making
``selections''; that is, partition one array based on boolean values of
a selection vector.@refill
@end ignore
@end itemize

@node Bugs, Concept Index, Projects, Top
@comment  node-name,  next,  previous,  up
@chapter Bugs
@cindex Bugs

Your bug reports play an essential role in making Algae reliable.
By reporting a bug, you may or may not get a timely solution to your
problem.  Either way, bug reports help us to make the next version of
Algae better.  In addition, your comments or criticisms on
Algae or the Algae language are also welcomed.@refill

@cindex Detours
The Algae interpreter is incomplete.  There are several operations
that it should be able to perform but that have not yet been
implemented.  These cases elicit a ``detour'' message from Algae.
Since they're not bugs, you don't need to tell us about them.  Still,
complaining about them might get them fixed.@refill

@menu
* Reporting Bugs::
* Reported Bugs::
@end menu

@node Reporting Bugs, Reported Bugs, Bugs, Bugs
@section Reporting Bugs
@cindex Reporting bugs

In order for a bug report to serve its purpose, you must include the
information we need to fix it.  As the GNU people say, ``report all the
facts''.  But never mind Joe Friday---the more information the better.
It usually doesn't pay to explore the ``envelope'' of the bug; that is,
changes to the input that affect it.  Providing a simple example is the
best way to get a bug fixed.@refill

You should include the following information with your bug report:

@itemize @bullet
@item
The version of Algae.  You can get this by running it with the
@samp{-V} option.@refill

@item
A complete input file that will reproduce the bug.  A single statement
is generally not sufficient.@refill

@item
The type of machine you are using, and the operating system name and
version number.@refill

@item
A description of what behavior you observe that you believe is
incorrect.@refill
@end itemize

Send bug reports to:

@example
ksh@@sideslip.org
@end example

@noindent
or, as a last resort, mail them to:

@example
Algae Bugs
Attn: Scott Hunziker
The Boeing Company
P.O. Box 3707, MC 8K-26
Seattle, WA  98124-2207
@end example

@node Reported Bugs, , Reporting Bugs, Bugs
@section Reported Bugs
@cindex Known bugs
@cindex Reported bugs

Below is a list of bugs that are known to exist in the current version
of Algae and are waiting to be fixed.@refill

@table @asis
@item 1
Recurse deep enough, and Algae dumps core.  For example, the
expression@refill

@example
function () @{ return self(); @} ()
@end example

@noindent
will not return gracefully.  (I just tried it, and I had to reboot my
machine!)  It usually takes more than 500 levels of recursion to hit
this bug, though, so you'll probably only encounter it with runaway
functions.@refill

@comment Fixed, in the sense that we no longer say anything about $print.
@ignore
@item 2
The @code{$print} variable doesn't control printing as it is said to.
@end ignore

@comment Fixed (at least I don't know any others that are wrong). 6/26/92
@ignore
@item 3
Many of the builtin functions don't play by the rules when it comes to
variable length argument lists.  For example, the @code{union} function
works fine on @code{union(v)} and @code{union(v;w)}, but raises an
exception on @code{union(v;NULL)}.  Since @code{union} takes at least
two arguments, @code{union(v)} and @code{union(v;NULL)} are supposed to
be equivalent.@refill
@end ignore

@comment Fixed, 8/31/93.
@ignore
@item 4
The @samp{+=} and @samp{-=} operators give a syntax error when their
left operand contains an element reference.  For example, @code{x[1]+=1}
doesn't work.@refill
@end ignore

@comment Fixed 5/7/92.
@ignore
@item 5
A @code{local} declaration outside a function dumps core.
@end ignore

@comment Fixed 8/31/93 by claiming that it's a feature instead of a bug.
@ignore
@item 6
The @samp{+=} and @samp{-=} operators screw up when member references
are on the right-hand side.  For example,@refill

@example
a.(b+=1) += c;
@end example

@noindent
is coded exactly like

@example
a.(b+=1) = a.(b+=1) + c;
@end example

@noindent
which results in @code{b} getting incremented twice.  Instead, it should
code as@refill

@example
b+=1; a.(b) = a.(b) + c;
@end example
@end ignore

@comment Fixed (9/3/93), in that we no longer read two startup files.
@ignore
@item 7
Initialization file reading should be smart enough not to read the same
file more than once.@refill
@end ignore

@comment Fixed 7/5/93.
@ignore
@item 8
This is more like a phylum than a bug, but right now we don't handle
floating point exceptions.@refill
@end ignore

@comment Fixed 6/23/92.
@ignore
@item 9
Normalization in @code{fft} and @code{ifft} is not done the way the
documentation says it is.  The expression @code{ifft(fft(v))} returns
@code{v} divided by two pi.
@end ignore

@comment Fixed (as far as I know) 5/11/93.
@ignore
@item 10
The ``pile'' operations (and doubtless many others) do not check for fat
sparse arrays.
@end ignore

@comment Fixed 5/11/93.
@ignore
@item 11
The random number code is botched.  It's supposed to allow you to
specify which generator to use (like "rand" or "random") when you
install Algae.  Problem is, they have different return types.
@end ignore

@comment Fixed, 8/31/93.
@ignore
@item 12
An expression like @code{$$.(x)=0}, which would set to zero the global
variable named by @code{x}, currently gives a parse error.  This would
be a useful thing to have, and should be fixed.@refill
@end ignore

@comment Fixed, 11/5/94.
@ignore
@item 13
The @code{solve} function should warn about ill-conditioning.  The
@code{factor} function does this now, but @code{solve} uses LAPACK
``driver'' routines which don't estimate the condition number.  We
should use the ``expert'' routines, instead.
@end ignore

@comment Fixed, at long last, 3/22/97.
@ignore
@item 14
The parser has trouble with comments that are on the last line of a file
and are not followed by a newline.@refill
@end ignore

@comment Fixed 7/25/93.
@ignore
@item 15
Though I doubt that it's a very useful feature, Algae does support
sparse, character arrays.  They're buggy, though, so you should avoid
them.  For example, `sparse(fill(5,5);"")' dumps core.@refill
@end ignore

@item 16
We have problems when a parse error occurs in a recursive call to the
parser.  Local variables created in the recursive call are left in an
invalid state.  This happens, for example, if you call the @code{source}
function from an interactive session and encounter a parse error in the
process.@refill

@comment Fixed, by calling it a feature.
@ignore
@item 17
The @code{return} statement never prints its result.
@end ignore

@comment Fixed 6/24/96.
@ignore
@item 18
The execution profiler appears to have trouble with the line numbers
that it reports.  File charging looks OK, but hits are occasionally
charged to the wrong line.  We're looking into it.@refill
@end ignore

@comment Moved to Projects, 3/29/94.
@ignore
@item 19
The ``submatrix assignment'' code (for handling statements like
@code{A[u;v]=B}) is terribly inefficient.  It's not a matter of
how many percent faster it could be, but more like how many orders of
magnitude.@refill
@end ignore

@comment Unfortunate, but not a bug.  (10/24/94)
@ignore
@item 20
If @code{x} is a hermitian matrix, then @code{x+real(x)} should also be
hermitian.  Presently, it goes to general symmetry.@refill
@end ignore

@comment Fixed 10/25/01.
@ignore
@item 21
The logical operations don't keep matrices sparse when they could.  For
example, @code{a&a} should be sparse if @code{a} is sparse; instead,
it's converted to dense.@refill
@end ignore

@item 22
Every time Algae parses a file, it leaks the memory in which the name of
that file is stored.  The names are kept around because user functions
refer to them.  Instead, we should arrange for the names to be stored
with each user function so that they get deleted when the function is
deleted.@refill

@item 23
When Algae reads a binary file that contains a user function, it
allocates memory for every string constant in that function.  If you
then delete that function, this memory is leaked.@refill

@item 24
We use the texi2html program to make Algae's HTML documentation from the
texinfo source.  Among its numerous deficiencies, it sometimes splits an
anchor from the text with which it is supposed to be associated.  For
example (from algae-3.5.0), the anchor for the section named ``Running
Algae'' is put at the bottom of the file @file{algae_6.html} instead of
at the top of @file{algae_7.html} where it belongs.  For this reason,
the Algae @code{info} function may not take you to the right place in
the document.@refill
@end table

@node Concept Index, Function Index, Bugs, Top
@comment  node-name,  next,  previous,  up
@unnumbered Concept Index

If you can't find what you're looking for here, please send us a bug
report.  We'll try to include an entry for it in the next release of
this manual.@refill

@printindex cp

@node Function Index, , Concept Index, Top
@comment  node-name,  next,  previous,  up
@unnumbered Function Index

@printindex fn

@contents
@bye
