                  >> Matrix Manipulator Monkey  V1.0 <<

Help is Available on the Following Topics.  Simply Type 'HELP topic' for
the particular information you need.  The Capital Letters are the minimum
abbreviation for both the help information and the Command itself.

In all of the help entries, a [] will indicate an option part of a command.
The symbols used are:
    m, m1, m2, ...        ---  A Matrix Name
    r                     ---  A Row Specification
    c                     ---  A Column Specification
    s                     ---  A Scaler
    filename              ---  Refers to a filename

>> General Info on the Program and How to Use it
General_info      Information on Monkey, How to Get Started, Read this First
Objects           How Scalers, Matrix Names, Memory, Row/Column specs are used
SOurce            Information on how to Get the Source, and Compile it
DOcumentation     Generation of Printable Documentation on Monkey

>> System Commands
Load              Load a Matrix (keyboard -> memory).
Print             Output a Matrix (memory -> screen).
Z                 Set Default Matrix.
DUmp              Print all Matrices currently in Memory.
LIst              List all Matrices currently in Memory.
Copy              Copy a Matrix (matrix -> matrix).
Get               Copy another Matrix into the Default Matrix.
PUt               Copy the Default Matrix into another Matrix.
Kill              Kill a Matrix (Remove it from Memory).
Swap              Swap Two Matrices.
Quit              Leave Monkey.
Help [?]          Help System (This Message).

>> File Commands
FDump             Dump all the Matrices in Memory into a File.
FLoad             Load a Matrix from a File.
FPrint            Print a single Matrix to a File.
FMacro            Read Commands from a Macro File.

>> Matrix Manipulations
Add [+]           Add Matrices, Rows/Columns.
Multiply [*]      Multiply Matrices, Matrix by Scaler, Row/Column by Scaler.
IDentity          Make an Identity Matrix
Invert [`]        Invert a Matrix.
Transpose [']     Transpose a Matrix.
Upper_Triangular  Use Basic Operations to Satisfy Upper Triangular Property.
Lower_Triangular  Use Basic Operations to Satisfy Lower Triangular Property.
Determinant       Calculate Determinant of Matrix.
SOlve             Solve Matrix (Solution Space in Vector Form).

>> Basic Row/Column Manipulations
Swap              Swap Rows/Columns, Matrices.
Reduce            Reduce one Row/Column by Scaler*Row/Column.
Multiply          Multiply Row/Column by Scaler.
@g?@ General Information

                  >> Matrix Manipulator Monkey  V1.0 <<

Purpose:

    Monkey is a Linear Algebra calculator.  It will add, multiply, invert,
    solve, etc. any number of matrices, as well as the simple elementary
    row/column manipulations.  Monkey is designed to be used by anyone,
    not just computer science people and mathematicians.  To this end, a
    full help system has been included, with all commands explained, and
    examples provided.

    Monkey uses a unique method of doing math.  It uses fractions to
    represent numbers, instead of converting everything to floating point.
    This allows precise calculations on numbers, with no loss of precision.
    But since floating point is suited for very large (and small) numbers,
    this options is included, and if a calculation can not be done with
    fractions, the floating point will take over.

How to Use it:

    At the command line, type:

        % monkey

    This will get you into the system.  At this point, you will be stared at
    by something like:

        (default) answer:

        > _

    This is telling you that the default matrix to be worked on is 'answer'
    and if it had anything in it, it would have shown it to you.  The '> _'
    is your prompt and your cursor.  At this point you can enter any of
    monkey's commands (help, load, eval, quit, etc.)  After every operation,
    the screen will show you any matrices which have been changed, and the
    default matrix.  So, let's try something:

        > load
        1> _

    Our prompt has been changed by the load command.  The '1' is now telling
    you that the first row of the matrix is to be typed in.  Since we did
    not specify a matrix to load, it will go in the default matrix.

        1> 1 2 3
        2> 9 8 2
        3> 7 1 3
        4>

        (default) answer:
           1    2    3
           9    8    2
           7    1    3

        > _

    The blank like on '4>' indicates that you are done with this matrix,
    and it repeated the matrix back to you.  Your prompt is back so we can
    play with this matrix:

        > reduce r3 5 r1

        (default) answer:
           1    2    3
           9    8    2
          12   11   18

        > _

    We just added 5 times row 1 to row 3.  And from here you could do any
    number of commands.

    Almost all of the commands take the form of:

           > command   matrix_to_act_on    what_to_do_to_it

    If no matrix name is given in 'matrix_to_act_on', the default matrix is
    assumed.

    After you are done with monkey, simply type 'quit':

        > quit

        % _

    and you will return to the operating system.

    This has been a short run through a simple example.  All of the
    commands are listed in the HELP index, simple type 'help' at your
    monkey prompt.  There are many features to keep in mind, and many things
    monkey can and can't do.  But it can do a great many of the rudimentary,
    mechanical operations of linear algebra.

If you Have Problems:

    Simply consult the help system, by using the 'help' command:

        > help

    This will provide you with a list of possible other places to go for
    further help, as well as a listing of what monkey can do for you.
@so@ Source Information

This program is distributed as a binary program, with no sources included.
As for the binaries, feel free to give copies to others, so long as nothing
has been changed in the original files.  The binaries of this program are
hereby placed in the public domain.

This version of the IBM binary was compiled under the Small Memory Model.
If you begin to run out of dynamic memory, the source can be compiled
into the compact model without any problem (obviously, you must have the
source to do this).

The source is written completely in ANSI standard C (as closely as I could),
and compiles without modification under MSC 4.0, Turbo C 1.5, Sun C,
Unix 4.2/4.3 C Compilers, and probably many more.  The code is a
standard form for C programs, and is commented to some extent.  The
very low level add and multiply routines (only three) are written in
assembly code for the IBM PC (80x86) and Suns (68020), but a C equivalent
is included for any machine (the assembly is just a great deal faster,
it's very hard to get C to determine if an integer operation has overflowed).

This project is ongoing with me.  The next additions will have to be
eigenvalues, eigenvectors, adjuncts, and perhaps symbolic math; but for
now I just wanted to get what I had out.

If you would like a copy of the source code, I only ask a small donation
to the Monkey cause, of perhaps $20.  I will send you an MS-DOS disk
(5-1/4 inch) with the full sources and the latest binaries.  If you are
using a unix machine, I could send you a TAR tape (either sun cartridge or
a mag tape, but you must supply the tape), or I could send it to you
through the E-Mail.

The address:

@#

In any case, I hope you enjoy the program.  If you find any bugs, or
have any suggestions, PLEASE let me know.

--- greg, january 1988

Disclaimer:
I make no warranty of any kind for this package, it is distributed "as is"
and I shall not be liable for any damages or losses due to its use.
@o?@ Objects

There are four basic data types that Monkey can understand.  These data
types may be entered in any order, at any time while using Monkey, but
context does govern which data types make sense, and where.  White space
is used to separate arguments.

Scalers:

    Scalers are the entries in a matrix, constants times matrices, etc.
    In Monkey, they are stored as fractions, that is a numerator and
    denominator is kept for all numbers, as in:

        5/4    3/2     12     13/1234     1/999999

    Normally, a numerical program would convert these to floating point,
    and then proceed with the calculation, often losing precision
    (as in 1/3, which can not be expressed precisely as a finite decimal).
    But, if the numbers can be kept in fractions, the calculations become
    precise.  Of course, not all numbers can be stored conveniently on a
    computer in this way (ie, 1e30 would be a very large number), thus, if
    monkey sees that a number will overflow this scheme, it will revert to
    floating point (depending on the machine be run on, a 32 bit floating
    point number may be able to span a range of 1e300 to 1e-300).  Thus,
    monkey uses the best of both worlds.  All calculations derived from a
    floating point number will then be carried out in floating point.

    As for input, any algebraic expression may be used consisting of:

        '('   ')'   '+'    '-'    '*'    '/'

    Thus, during a load operation on a matrix, the following line might
    be entered:

        (5+6/2)*1/32*(((9/2+1/2)*8*1.234)/12)

    which would be evaluated to 617/600.  ANYWHERE a scaler would be entered,
    an algebraic expression may be used.

    Numbers may be integers, or floating point, or exponential.  Output is
    controlled by the set variable 'display', and the set variable 'width'.
    If a number drops into floating point, all representations from then
    on will be in exponential.  To force entry of a floating point number,
    use exponential notation (a decimal number such as '1.3' would be
    converted into 13/10, while 1.3e0 will stay in floating point).


Rows and Columns:

    Rows and columns are specified by giving the letter 'r' or 'c' before
    a row or column number.  As in:

        r1     c12      r23

    which specified 'row 1', 'column 12', 'row 23' respectively.


Matrix Names:

    The first character of a matrix name may be any letter or the underscore
    ('_') character.  Subsequent characters can be any letter, number, or
    the underscore, and are significant to 32 characters.  If an 'r' or 'c' was
    used as the first character, a digit may NOT be in the second character
    (which would interfere with the row/column specification syntax).

    Matrices are formed out of dynamic memory, and come and go as needed.
    When specifying a matrix to work on, or a target matrix, call it by
    name.  A listing of the current matrices can be displayed with the
    'list' command.


File Names:

     Any valid file name on the machine in use may be used (that includes
     any kind of a path specification).
@do@ Documentation: Abbreviation 'DO'

This command will output a copy of the Help file for printing purposes.
The output file will contain all information in the Help system, nicely
paginated, and sorted.  The idea is that this command will output a
printable file, which can then be sent to a line printer.

Options to the command are:

     -lnum             --- Sets Number of Lines per Page (default: 66)
     -tnum             --- Sets Top Margin (default: 3)
     -bnum             --- Sets Bottom Margin (default: 3)
     -p                --- Use a '^L' for page breaks instead of padding
     -ffilename        --- Sets file name for output (default: 'monkey.doc')

Form:
    > documentation [-lnum] [-tnum] [-bnum] [-p] [-ffilename]

Examples:
    > documentation -flpt1   --- Sends Documentation to 'lpt1'
                                 (most PC users have a parallel printer here)

See Also:
    HELP
@li@ LIST: Abbreviation 'LI'

LIST will provide a list of all the matrices currently in memory.  The
matrices themselves will not be shown, just their name.  All matrices which
are currently empty (0x0 Matrix) and all system matrices (starting with '__')
will not be shown.  After the list is displayed, individual matrices can
be displayed with the PRINT command, and all matrices can be dumped with the
DUMP command.

Form:
    > list

Examples:
    > list                 -- Displays List of all Current Matrices in Memory
    Current Matrices:
      happy
      e1
      answer

See Also:
    DUMP, FDUMP, PRINT, FPRINT, Objects.
@l?@ LOWER_TRIANGULAR: Abbreviation 'LT'

This command will attempt to make the given matrix into a matrix which
has only one entry per column that is non-zero.  This is done through the
use of basic row operations.  Normally, if the matrix is upper triangular,
and the diagonal is completely non-zero, this will place the matrix
very close to a row echelon matrix (the only difference being that the
pivot points will not be ideally 1).  In other words, the matrix will
be reduced as far as possible (or nearly).  The command is governed
by the set variable 'lower_triangular_swap' and 'triangular_seek'.

In a technical sense, this is what it does:
    for column := last_column to first_row do
       find a non-zero entry (searches from last_row to first_row)
       reduce all other rows by this row (the reduce command)

Form:
    > ltriangular [m]                   -- Make matrix lower triangular

Examples:
    happy:                              -- From the Upper Triangular Command
        2   -3   -1    2    3    4
        0    2    1    0    5   -4
        0    0    0    0    1    1
        0    0    0    0    0    0
    > ltriangular happy
    happy:
        2    0   1/2   2    0  -25/2    -- Reduce the matrix, note that
        0    2    1    0    0    -9     -- not every row has only one entry,
        0    0    0    0    1    1      -- since this matrix can not satisfy
        0    0    0    0    0    0      -- that property.
    > load another
    1> 0 -1 1 3
    2> 1 -1 -1 0
    3> -1 0 -1 -3
    4>
    > utriangular another               -- Take the Upper Triangular
    another:
        1   -1   -1    0
        0   -1    1    3
        0    0   -3   -6
    > ltriangular another               -- Take the Lower Triangular
    another:                            -- The values for the solution
        1    0    0    1                -- can now be read directly off
        0   -1    0    1                -- the matrix.
        0    0   -3   -6

See Also:
    UPPER_TRIANGULAR, SOLVE, Objects.
@l?@ LOAD: Abbreviation 'L'

The Load command allows the user to enter a matrix into memory, which can
later be manipulated.  There are two basic forms of this command, one in
which the user explicitly specifies the size of the matrix, and another
in which it is read implicitly from the input.  In most cases the implicit
version is fine, but it has limitations (less than 50 rows).  A blank line
in the input when using the implicit form will finish the matrix.  When
the matrix is being input, the first number is the Next Row to be Input, and
the second number (if present) is the column location to be input.

Form:
    > load [m] [r c]
        Note: "[r c]" specifies explicitly the number of rows and columns.
        Note: "[r c]" can also be given as "[c r]", order is not important.

Examples:
    > load                -- Loads the Default Matrix, Implicitly
    1> 1 3
    2> 4 5
    3>
    > load happy r2 c2    -- Loads the Matrix 'Happy', a 2x2 Matrix
    1,1> 1/2
    1,2> 3/4 5/8
    2,2> 9/89

See Also:
    Objects.
@pu@ PUT: Abbreviation 'PU'

PUT allows the user to store the default matrix away in some memory location.
It works much like a calculators store key.  A copy of the default matrix
is made, and placed in the named memory location.  This copy is a completely
independent copy, and will not be effected by changes to the default matrix
(or vice versa, changes to the copy will not affect the default).  PUT is
the opposite of GET.  PUT accomplishes the same effect as the copy command in
'> copy destination_matrix default_matrix'.

Form:
   > put m               -- Makes a copy of the default matrix in 'm'

Examples:
   > put happy           -- Make a copy of the default matrix in 'happy'

See Also:
    COPY, GET, SWAP, Objects.
@p?@ PRINT: Abbreviation 'P'

PRINT will output a matrix that is in memory.  If the matrix is undefined,
nothing will happen.  Since after every command, the matrix that was changed
is output; and before every command, the default matrix is output, this
command is really only used when working with multiple matrices.

Form:
    > print [m]

Examples:
    > print               -- Output the Default Matrix
    > print happy         -- Output the Matrix 'happy'
    happy:
    1   2   3
    4   5   6
    7   8   9

See Also:
    DUMP, FDUMP, LIST, Objects.
@z?@ Change Default Matrix: Abbreviation 'Z'

The 'Z' command will change the current default matrix.  From this point on,
all subsequent commands which do NOT contain an explicit matrix name will
refer to this matrix, and this matrix will be displayed before each command
(unless the 'z_print' option has been set to 'no', see 'set' for more info).
Initially, the program starts up with the 'answer' matrix as the default.
If the current default matrix is cleared (either 'killed' or has 0 columns
or rows), the 'answer' matrix will again become the default.

Form:
    > z m

Examples:
    > z happy             -- Make the Matrix 'happy' the Default

See Also:
    Objects, Set.
@g?@ GET: Abbreviation 'G'

GET allows the user to retrieve a matrix from memory and place it in the
default.  It works in much the same way as a calculator with a recall memory
key.  The name of the default matrix remains the same, and the source
matrix is unaffected.  This command does exactly the same thing as the
COPY command in the form '> copy default_matrix source_matrix', or more simply
as '> copy source_matrix'.  GET is the opposite of PUT.

Form:
    > get m               -- Makes a copy of 'm' in the default matrix

Examples:
    > get happy           -- Make a copy of 'happy' in the Default Matrix

See Also:
    COPY, PUT, SWAP, Objects.
@du@ DUMP: Abbreviation 'DU'

DUMP will display all of the matrices that are currently in memory.  All
matrices which have nothing in them (0x0 Matrix) and all system matrices
(starting with '__') will not be displayed.  The default matrix will be
displayed after the others have been displayed, as it normally would be.
This command is equivalent to do a standard PRINT on all of the matrices
in memory.

Form:
    > dump

Examples:
    > dump                -- Outputs All Matrices Currently in Memory

See Also:
    PRINT, LIST, FDUMP, Objects.
@d?@ DETERMINANT: Abbreviation 'D'

This function will calculate the Determinant of a given matrix.  As usual,
the given matrix must be square.  The method by which this calculation is
done, is to form an Upper Triangular (just as if it had been done by the
user, with the set attributes in effect) and to multiply together the
diagonal.  The determinant is displayed on the screen, and is NOT stored
anywhere.

Form:
    > determinant [m]      -- Calculates Determinant of Matrix 'm'

Examples:
    > load happy                             -- Load a Matrix
    1> 1/2 3/4 5/6
    2> 9.23 4/3 1/2
    3> 3/4 45/2 3
    4>
    > determinant happy                      -- Calculate Determinant
    Determinant of 'happy': 355483/2400

See Also:
    UPPER_TRIANGULAR, Objects.
@t?' TRANSPOSE: Abbreviation 'T', '''

Transpose will swap the A[i][j] with the A[j][i] of a given matrix.  Thus,
an M x N matrix will have the size N x M, and all the columns will be
swapped with the rows, and the rows with the columns.  Obviously, the
transpose of the transpose will result in the original matrix.

Form:
    > transpose [m]             -- Transpose Matrix 'm'

Examples:
    > print happy               -- The Original 'happy'
    happy:
      1    2    3
      4    5    6
    > transpose happy           -- After Being Transposed
    happy:
      1    4
      2    5
      3    6

See Also:
    Objects
@u?@ UPPER_TRIANGULAR: Abbreviation 'U'

The given matrix will be manipulated (with basic row operations) until
the upper triangular property is satisfied.  This property is:

    1. Any row consisting only of zeros is below any row that
       contains at least one non-zero entry.
    2. The first (reading from left to right) non-zero entry of any row
       is to the left of the first non-zero entry of any lower row.

Two set variables control the behavior of the basic row operations.  The
Upper_Triangular_Swap allows for swapping as one of the possible basic
operations (normally, this is fine, and the default is to allow it).  If
Swaps are allowed, non-zero entries (in each column) are always favored;
between these, the Triangular_Seek variable controls if high or low numbers
are favored at the top of the matrix (normally, this is small; but it has
been shown that seeking for larger numbers may give better results).

By using this command with the lower triangular command, row-reduced
echelon form may be obtained.

Form:
    > utriangular [m]                     -- Satisfy Upper Triangular

Examples:
    > set upper_triangular_swap yes       -- OK to swap (the default)
    > set triangular_seek small           -- Go for the Small Guys
    > load happy                          -- Load up a matrix
    1> 2 -3 -1 2 3 4
    2> 4 -4 -1 4 11 4
    3> 2 -5 -2 2 -1 9
    4> 0 2 1 0 4 -5
    5>
    happy:                                -- Display of the Matrix Entered
        2   -3   -1    2    3    4
        4   -4   -1    4   11    4
        2   -5   -2    2   -1    9
        0    2    1    0    4   -5
    > utriangular happy                   -- Make it Upper Triangular
    happy:
        2   -3   -1    2    3    4
        0    2    1    0    5   -4
        0    0    0    0    1    1
        0    0    0    0    0    0
    >

See Also:
    SOLVE, LOWER_TRIANGULAR, SET, Objects
@se@ SET: Abbreviation 'SE'

The set command sets certain attributes of the commands.  Alone, the set
command will display the current settings, which by default are:

        > set
        upper_triangular_swap = yes
        lower_triangular_swap = no
        triangular_seek = small
        solve_type = augmented
        display_mode = fraction
        z_print = yes
        width = 4.4
        num_lines = 24                    (varies from machine to machine)
        print_separation = ' '

To change one of these items, use the command in the form:
[the item and the value may be abbreviated by their first letter]

        > set item = value

The set items and their valid values are:

        upper_triangular_swap = yes | no

            This variable controls wether swapping is permitted when
            calculating the upper triangular version of a matrix.  Normally,
            it is desireable to have this set to 'yes', so that if a number
            can be moved (which is also depends on the 'triangular_seek' item,
            and the ordering of the values in the column being processed),
            the program will go ahead and do it.  Since the determinant
            function also uses upper triangular, this set variable may effect
            the values for the determinants (as well as solves).

        lower_triangular_swap = yes | no

            This variable controls wether swapping is permitted when
            calculating the lower triangular version of a matrix.  When
            used after an upper_triangular command, it would be desired
            to have this value 'no', so as a row-echelon matrix results.

        triangular_seek = big | small

            This determines which values are most desirable at the top of
            the column (row) when doing upper_triangular (lower_triangular)
            operations.  It has been shown that better results are obtained
            with bigger numbers at the top, while smaller numbers keep the
            values in the matrix down as far as possible.

        solve_type = homogeneous | augmented

            The matrix to be solved is described by this variable.  If the
            matrix is homogeneous (all equations equal to zero, with this
            column not being represented), then use this value.  Otherwise,
            it will expect the last column to be equal to the values of the
            equations.

        display_type = fraction | mixed | decimal | exponential

            All output to the terminal, and to the files, is controlled through
            this set value.  The actual numbers inside the matrix are not
            changed by a change to this set variable, only how they are output.

            As an example, assume the numbers are entered in the following way:
            [see 'help scalers' for more information on internal
            representations of the numbers]

                    1/2       27/5       -.43       1.234e10

            fraction:     Display the number as a numerator and denominator

                    1/2       27/5      -43/100     1.234e10

            mixed:        Display the number as a whole number and a fraction

                    1/2       5+2/5     -43/100     1.234e10

            decimal:      Display the numbers in floating point

                    .5         5.4       -.43       1.234e10

            exponential:  Display the numbers in scientific notation

                    5e-1      5.4e0     -4.3e-1     1.234e10

        z_print = yes | no

            Normally, before each command, the default matrix is printed.
            With this variable set to 'no', the default matrix will not be
            printed, only its name will appear.

        width = num1.num2, num1 and num2 are arbitrary (>=0)

            Width controls how the numbers are output, how much space is
            dedicated to each of the numbers, so that if each number will fit
            in a particular width, then the numbers will line up vertically
            quite nicely.

        num_lines = num, num is arbitrary (>=0)

            Num_lines controls how many lines there are on your terminal.
            Normally, this is filled in for you.  An entry of '0' means that
            your terminal has infinite number of lines, and no page pausing
            will take place.

        print_separation = 'c', c is an arbitrary character

            This is the character which is placed between entries across
            on the matrix.  Normally, it is ok to use a '<space>', but
            sometimes, numbers may start to collide with one another, in
            which case a '|' might be nice to resolve which column things
            are in.
@so@ SOLVE: Abbreviation 'SO'

Solves a Matrix (or rather the linear system represented by the matrix).
It will solve the matrix, and return the result as a linear combination
of vectors which represent the solution's sub-space.  Depending on the
SET variable 'solve_type', a homogeneous or augmented matrix may be solved.
The matrix is solved by using Upper Triangular, and then Back Substitution,
where appropriate adding parameters as it goes.  The result is returned to
the screen and NOT stored.  If it is an augmented matrix, a inconsistent
system will be reported to the user.  Parameters are assigned the letters
's' through 'z', then 'a' through 'z', etc.

For those not familiar with the vector solution:  If you just want the
solution, it will appear as the first vector.  If there is more than one
vector, than there are an infinite number of solutions, and the parameters
govern the qualifications for a valid solution.  But, if you just need
one solution, take the top vector (the one without a parameter); it
should always be a valid solution.

Form:
    > solve [m]

Examples:
    > set solve_type augmented  -- We are going to solve an augmented equation
    > load happy                -- Load the Matrix to Solve
    1>1 2 3 4
    2>5 6 7 8
    3>9 10 11 12
    4>
    > solve happy               -- Solve Matrix 'Happy'
    Vector Solution to 'happy':
     (  -2,  3,  0 )+
    s(   1, -2,  1 )

See Also:
    UPPER_TRIANGULAR, SET, Objects.
@id@ IDENTITY: Abbreviation 'ID'

Identity will build an identity matrix into a matrix of the specified
size.  If no matrix name is given, the current default matrix is used.
If no size is given, the current default matrix's size is used (allowing
an identity matrix to be built of the same size in another matrix).

Form:
    > identity [m] [r c]

Examples:
    > identity r5 c5            -- Build a 5x5 identity into current matrix
    (default) happy:
      1  0  0  0  0
      0  1  0  0  0
      0  0  1  0  0
      0  0  0  1  0
      0  0  0  0  1
    > identity howdy            -- Build 5x5 identity into howdy
    > identity spam r3 c3       -- Build 3x3 identity into spam

See Also:
    Objects
@i?` INVERSE: Abbreviation 'I', '`'

Inverse will calculate the inverse of a matrix.  The Matrix specified will be
inverted, and will replace that matrix.  Thus, if you still need a copy of
the original matrix, store it in another memory location before invoking this
command.  The matrix must be invertible, which implies that it must be
square and it's determinant not equal to zero.  The procedure used is the
standard concatenation with the identity matrix [A|I], where an upper
triangular is made, and then a lower, and then subsequent divisions until
the matrix is on the left is the identity matrix [I|A`].  The calls to
Upper_Triangular are controlled by the set variable (for swaps).  Obviously,
the inverse of the inverse is the original matrix.

Form:
    > inverse [m]

Examples:
    > load happy                    -- Load the Matrix to be Inverted
    1> 9 8 3
    2> 4 5 2
    3> 2 3 1
    > put copy_happy                -- Make a Copy, so We can Multiply Later
    > inverse happy                 -- Invert the Matrix 'Happy'
    > print happy                   -- Display the Inverse Matrix
    happy:
      1/3    -1/3    -1/3
      0      -1       2
     -2/3    11/3   -13/3
    > multiply happy copy_happy     -- Multiply by Original, Have ID Matrix
    happy:
      1       0       0
      0       1       0
      0       0       1

See Also:
    UPPER_TRIANGULAR, SET, MULTIPLY, Objects.
@e?@ EVAL: Abbreviation 'E'

Eval will evaluate a matrix expression.  This expression can consist of any
previously loaded matrices, operators (*, +, -, ', `, =), scalers, or
parenthesis.  The valid operators, and their level of precedence are (the
horizontal bars separate these levels):

    FORM        EXAMPLES            COMMENTS
    Highest Level of Precedence
    ()          A*(B+C)             Multiply A by the sum of B and C
                (A+(B*D*E)')`       Multiply A by the transpose of the product
                                    of B, D, and E.  Then Invert it.
    ----------------------------
    '           A'                  Transpose of A
    `           B`                  Inverse of B
                C'`                 Inverse of the Transpose of C
    ----------------------------
    -           A * -B              Product of A and -B (B * -1)
    ----------------------------
    *           A * B               Produce of A and B
                A + B * C           Sum of A and the Product of B and C
    ----------------------------
    +           A + B               Sum of A and B
    Lowest Level of Precedence

All operators evaluate from left to right, and all operators on the same
level evaluate from left to right.  If the equal sign is missing, the default
matrix is used to hold the answer.  If an equal sign is present, it must
appear behind a matrix name, and before the expression, as in:

    > eval A = ((B * C)' + (C * U)`) * E

If an error occurs in the processing, the matrix that the result would have
been stored in will be unchanged.  All the different operations map directly
into the standard commands themselves.  Thus, the answer received should be
the same as the answer received by the user using all of the basic commands.

Form:
    > eval [m =] expression         -- Evaluate Expression

See Also:
    MULTIPLY, ADD, TRANSPOSE, INVERSE, Objects
@fd@ FDUMP: Abbreviation 'FD'

FDUMP stands for File Dump, and basically the same thing that occurs when
one does a DUMP to the screen will be done, except that output will be sent
to a file that you name.  This file can then be looked at outside of the the
program (with a standard text editor) or later FLOADed back into the program.
The matrices in the file will also contain their appropriate sizes (r? and c?).
All information in the file prior to this command will be lost.

Form:
    > fdump filename            -- Dumps all matrices in memory to FileName

Examples:
    > fdump happy.out           -- Write to File 'happy.out', all of memory

See Also:
    DUMP, FLOAD, FPRINT, LIST, Objects
@fp@ FPRINT: Abbreviation 'FP'

FPRINT stands for File Print, and basically will save the contents of a matrix
into the designated file.  Only one matrix will be saved, as opposed to
FDUMP, in which all of memory is saved.  The form of the output is exactly the
same as the form of a PRINT, except that the size is included on the output
(that is, the size of the matrix, in r? and c?).  All information in the
file prior to this command will be lost.  Matrices saved can be read by
FLOAD, or any text editor.  Note that the standard matrix conventions
concerning the default matrix act differently for this command.

Form:
    > fprint filename [m]    -- Dumps matrix 'm' into FileName

Examples:
    > fprint howdy.out       -- Write the default matrix into 'howdy.out'
    > fprint fox.out fox     -- Write the matrix 'fox' to the file 'fox.out'

See Also:
    FDUMP, DUMP, FLOAD, Objects
@fl@ FLOAD: Abbreviation 'FL'

FLOAD stands for File Load, and basically will load matrices from a File.
It reads the same format as the FPRINT and FDUMP commands, which consists of
one or more matrices of the following format:

        === Top of File ===

        name_of_the_matrix: [r? c?]
           matrix[1][1]   matrix[1][2]  ....
           matrix[2][1]   ....
           ....

        name_of_second_matrix  [r? c?]
           matrix2[1][1]   ....
           ....

        === Bottom of File ===

Basically it is the same as a Load command, and the same type of scalers can
be input here.  The row and column specification is not necessary, but it
is output by the FPRINT and FDUMP commands, and is generally a good idea.
It is not mandatory; if they are not there, then the implicit load will be
assumed.

All matrices in the file will be restored back into memory.  Matrices in the
file must be separated by at least one blank line.

Form:
    > fload filename            -- Load matrices from Filename

Examples:
    > fload happy.out           -- Load all matrices from 'happy.out'

See Also:
    FDUMP, FPRINT, LOAD, Objects
@fm@ FMACRO: Abbreviation 'FM'

File Macro will read subsequent commands from 'filename' until the end of
that file is reached.  These commands will be echoed on the screen, as each
one is executed.  Unfortunately, at this time, there is no way to nest
file macros.  All commands are just as if you had typed them at the keyboard.
At the end of file, control is returned to the keyboard.

Form:
    > fmacro FileName               -- Read Commands from FileName
@m?* MULTIPLY: Abbreviation 'M', '*'

Multiply will multiply two matrices together, a row/column by a scaler, or
a matrix by a scaler (which is solely defined by the input).  If two matrices
are to be multiplied, the number of columns of the first matrix must equal
the number of rows of the second matrix.

Form:
    > multiply m            -- Multiply Default Matrix by another Matrix
    > multiply m1 m2        -- Multiply Two Matrices, Answer back in 'm1'
    > multiply [m] s        -- Multiply Matrix by a Scaler
    > multiply [m] r/c s    -- Multiply Row/Column by a Scaler

Examples:
    > multiply -3/45        -- Multiplies Default Matrix by -3/45
    > multiply happy        -- Multiplies Default Matrix by Matrix 'Happy'
    > multiply tiger fox    -- Multiplies Matrix 'Tiger' by Matrix 'Fox'
    > multiply snake 98/3   -- Multiplies Matrix 'Snake' by 98/3
    > multiply r4 -87/2     -- Multiplies Row 4 of the Default Matrix by -87/2
    > multiply heart c6 5/2 -- Multiply Column 6 of 'heart' by 5/2

See Also:
    DIVIDE, ADD, SUBTRACT, Objects
@a?+ ADD: Abbreviation 'A', '+'

Add will add two matrices or two rows/columns.  If two matrices are to be
added, the sizes of the matrices (both in rows and columns) must be equal.

Form:
    > add m                 -- Add another matrix to the default matrix
    > add m1 m2             -- Add two matrices, Result in 'm1'
    > add [m] r/c1 r/c2     -- Add 'r/c2' to 'r/c1'

Examples:
    > add happy             -- Add matrix 'happy' to the default matrix
    > add fox trot          -- Add matrix 'trot' to matrix 'fox'
    > add r3 r4             -- Add Row 4 to Row 3 in the default matrix
    > add hi c3 c1          -- Add Column 1 to Column 3 in matrix 'hi'

See Also:
    REDUCE, SUBTRACT, MULTIPLY, DIVIDE, Objects
@r?@ REDUCE: Abbreviation 'R'

Reduce will multiply a scaler by a row/column and then add the result to
another row/column.  Operations are from rows to rows, or columns to columns.
Algebraically it looks something like:

    row/column[i] := row/column[i] + (row/column[j] * s)

Form:
    > reduce [m] r/c1 r/c2 s    -- Both of these forms do the same thing,
    > reduce [m] r/c1 s r/c2    -- namely, r/c1 := r/c1 + (r/c2 * s)

Examples:
    > load                      -- Load the Default Matrix
    1> 1 2 3
    2> 4 5 6
    3> 7 8 9
    4>
    > reduce r2 r1 3            -- Add to r2, r1 * 3
    (default):
      1    2    3
      7   11   15
      7    8    9
    > reduce c3 c1 1/2          -- Add to c3, c1 / 2
    (default):
      1    2    7/2
      7   11   37/2
      7    8   25/2

See Also:
    ADD, MULTIPLY, SUBTRACT, DIVIDE, Objects
@c?@ COPY: Abbreviation 'C'

Copy will copy a Matrix from one Matrix name to another.  The original matrix
will be unaltered, and the contents that were in the destination matrix will
be lost.  Copy does not simply bind one matrix name to another, it will make
a literal copy.  The two matrices can then be used independently of one
another.  If the default is specified as the destination matrix, then this
command works just like a 'get' command.

Form:
    > copy [m1] m2              -- Copies from 'm2' to 'm1' (or default)

Examples:
    > copy happy                -- Makes a copy of 'happy' in default (GET)
    > copy fox trot             -- Makes a copy of 'trot' in 'fox'

See Also:
    GET, PUT, Objects
@s?@ SWAP: Abbreviation 'S'

Swap will swap two rows/columns or two matrices.  If two rows/columns are
to be swapped, each element on the row/column will be swapped with the
corresponding element on the other row/column.  Rows can be swapped with
Rows, and Columns can be swapped with Columns.  If two matrices are swapped,
the effect is if the two names had been swapped, the data is left alone.

Form:
    > swap [m] r/c1 r/c2        -- Swap r/c1 with r/c2 in matrix 'm'
    > swap [m1] m2              -- Swap m1 with m2

Examples:
    > load happy
    1> 1 2 3
    2> 4 5 6
    3> 7 8 9
    > swap happy r1 r3
    happy:
      7   8   9
      4   5   6
      1   2   3
    > z happy
    > swap c2 c1
    (default) happy:
      7   9   8
      4   6   5
      1   3   2
    > swap happy howdy

See Also:
    MULTIPLY, ADD, REDUCE, COPY, GET, PUT, Objects
@k?@ KILL: Abbreviation 'K'

Kill will remove a matrix from memory.  Once this is done, the data will
be unrecoverable, so use this command with care.  Note that the default
matrix can not be specified implicitly, simply as a safety measure.

Form:
    > kill m                    -- Kills matrix 'm', Removes it from Memory

Examples:
    > kill happy                -- Kills matrix 'happy'

See Also:
    GET, PUT, Objects
@q?@ QUIT: Abbreviation 'Q'

Quit will exit the Monkey program, and get back to the operating system.
It will first prompt you to insure that indeed you wish to leave (an answer
beginning with a 'y' or 'Y' is considered a yes).  Obviously, any matrices
in memory will be lost (you may want to FDUMP prior to doing this).

Form:
    > quit

See Also:
    FDUMP, FLOAD, Objects
@@
