\input texinfo
@c makeinfo linearalgebra.texi         to make .info
@c texi2html linearalgebra.texi        to make .html
@c texi2pdf linearalgebra.texi         to make .pdf

@setfilename linearalgebra.info
@settitle linearalgebra

@ifinfo 
@macro var {expr}
<\expr\>
@end macro
@end ifinfo

@node Top, Introduction to linearalgebra, (dir), (dir)
@top
@menu
* Introduction to linearalgebra::
* Definitions for linearalgebra::
* Function and variable index::
@end menu

@node Introduction to linearalgebra, Definitions for linearalgebra, Top, Top
@section Introduction to linearalgebra

@code{linearalgebra} is a collection of functions for linear algebra.

Example:

@c ===beg===
@c load (linearalgebra)$
@c M : matrix ([1, 2], [1, 2]);
@c nullspace (M);
@c columnspace (M);
@c ptriangularize (M - z*ident(2), z);
@c M : matrix ([1, 2, 3], [4, 5, 6], [7, 8, 9]) - z*ident(3);
@c MM : ptriangularize (M, z);
@c algebraic : true;
@c tellrat (MM [3, 3]);
@c MM : ratsimp (MM);
@c nullspace (MM);
@c M : matrix ([1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]);
@c columnspace (M);
@c apply ('orthogonal_complement, args (nullspace (transpose (M))));
@c ===end===
@example
(%i1) load (linearalgebra);
Warning - you are redefining the Maxima function require_list
Warning - you are redefining the Maxima function matrix_size
Warning - you are redefining the Maxima function rank
(%o1) /usr/local/share/maxima/5.9.2/share/linearalgebra/linearalgebra.mac
(%i2) M : matrix ([1, 2], [1, 2]);
                            [ 1  2 ]
(%o2)                       [      ]
                            [ 1  2 ]
(%i3) nullspace (M);
                               [  1  ]
                               [     ]
(%o3)                     span([   1 ])
                               [ - - ]
                               [   2 ]
(%i4) columnspace (M);
                                [ 1 ]
(%o4)                      span([   ])
                                [ 1 ]
(%i5) ptriangularize (M - z*ident(2), z);
                         [ 1   2 - z   ]
(%o5)                    [             ]
                         [           2 ]
                         [ 0  3 z - z  ]
(%i6) M : matrix ([1, 2, 3], [4, 5, 6], [7, 8, 9]) - z*ident(3);
                     [ 1 - z    2      3   ]
                     [                     ]
(%o6)                [   4    5 - z    6   ]
                     [                     ]
                     [   7      8    9 - z ]
(%i7) MM : ptriangularize (M, z);
              [ 4  5 - z            6            ]
              [                                  ]
              [                2                 ]
              [     66        z    102 z   132   ]
              [ 0   --      - -- + ----- + ---   ]
(%o7)         [     49        7     49     49    ]
              [                                  ]
              [               3        2         ]
              [           49 z    245 z    147 z ]
              [ 0    0    ----- - ------ - ----- ]
              [            264      88      44   ]
(%i8) algebraic : true;
(%o8)                         true
(%i9) tellrat (MM [3, 3]);
                         3       2
(%o9)                  [z  - 15 z  - 18 z]
(%i10) MM : ratsimp (MM);
               [ 4  5 - z           6           ]
               [                                ]
               [                2               ]
(%o10)         [     66      7 z  - 102 z - 132 ]
               [ 0   --    - ------------------ ]
               [     49              49         ]
               [                                ]
               [ 0    0             0           ]
(%i11) nullspace (MM);
                        [        1         ]
                        [                  ]
                        [   2              ]
                        [  z  - 14 z - 16  ]
                        [  --------------  ]
(%o11)             span([        8         ])
                        [                  ]
                        [    2             ]
                        [   z  - 18 z - 12 ]
                        [ - -------------- ]
                        [         12       ]
(%i12) M : matrix ([1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]);
                       [ 1   2   3   4  ]
                       [                ]
                       [ 5   6   7   8  ]
(%o12)                 [                ]
                       [ 9   10  11  12 ]
                       [                ]
                       [ 13  14  15  16 ]
(%i13) columnspace (M);
                           [ 1  ]  [ 2  ]
                           [    ]  [    ]
                           [ 5  ]  [ 6  ]
(%o13)                span([    ], [    ])
                           [ 9  ]  [ 10 ]
                           [    ]  [    ]
                           [ 13 ]  [ 14 ]
(%i14) apply ('orthogonal_complement, args (nullspace (transpose (M))));
                           [ 0 ]  [  1  ]
                           [   ]  [     ]
                           [ 1 ]  [  0  ]
(%o14)                span([   ], [     ])
                           [ 2 ]  [ - 1 ]
                           [   ]  [     ]
                           [ 3 ]  [ - 2 ]
@end example

@node Definitions for linearalgebra, Function and variable index, Introduction to linearalgebra, Top
@section Definitions for linearalgebra

@deffn {Function} addmatrices (@var{f}, @var{M_1}, ..., @var{M_n})

@c REWORD -- THE RESULT IS NOT GENERALLY THE SUM OF M_1, ..., M_N
Using the function @var{f} as the addition function, return the sum of
the matrices @var{M_1}, ..., @var{M_n}. The function @var{f} must accept any number of
arguments (a Maxima nary function).

Examples:

@c ===beg===
@c m1 : matrix([1,2],[3,4])$
@c m2 : matrix([7,8],[9,10])$
@c addmatrices('max,m1,m2);
@c addmatrices('max,m1,m2,5*m1);
@c ===end===
@example
(%i1) m1 : matrix([1,2],[3,4])$
(%i2) m2 : matrix([7,8],[9,10])$
(%i3) addmatrices('max,m1,m2);
(%o3) matrix([7,8],[9,10])
(%i4) addmatrices('max,m1,m2,5*m1);
(%o4) matrix([7,10],[15,20])
@end example

@end deffn

@deffn {Function} blockmatrixp (@var{M})

Return true if and only if @var{M} is a matrix and every entry of 
@var{M} is a matrix.

@end deffn

@deffn {Function} columnop (@var{M}, @var{i}, @var{j}, @var{theta})

If @var{M} is a matrix, return the matrix that results from doing the  
column operation @code{C_i <- C_i - @var{theta} * C_j}. If @var{M} doesn't have a row
@var{i} or @var{j}, signal an error.

@end deffn

@deffn {Function} columnswap (@var{M}, @var{i}, @var{j})

If @var{M} is a matrix, swap columns @var{i} and @var{j}.  If @var{M} doesn't have a column
@var{i} or @var{j}, signal an error.

@end deffn

@deffn {Function} columnspace (@var{M})

If @var{M} is a matrix, return @code{span (v_1, ..., v_n)}, where the set
@code{@{v_1, ..., v_n@}} is a basis for the column space of @var{M}.  The span 
of the empty set is @code{@{0@}}. Thus, when the column space has only 
one member, return @code{span ()}.

@end deffn

@deffn {Function} copy (@var{e})

Return a copy of the Maxima expression @var{e}. Although @var{e} can be any
Maxima expression, the copy function is the most useful when @var{e} is either 
a list or a matrix; consider:
@c ===beg===
load (linearalgebra);
m : [1,[2,3]]$
mm : m$
mm[2][1] : x$
m;
mm;
@c ===end===
@example 
(%i1) load("linearalgebra")$
(%i2) m : [1,[2,3]]$
(%i3) mm : m$
(%i4) mm[2][1] : x$
(%i5) m;
(%o5) [1,[x,3]]
(%i6) mm;
(%o6) [1,[x,3]]
@end example
Let's try the same experiment, but this time let @var{mm} be a copy of @var{m}
@c ===beg===
m : [1,[2,3]]$
mm : copy(m)$
mm[2][1] : x$
m;
mm;
@c ===end===
@example
(%i7) m : [1,[2,3]]$
(%i8) mm : copy(m)$
(%i9) mm[2][1] : x$
(%i10) m;
(%o10) [1,[2,3]]
(%i11) mm;
(%o11) [1,[x,3]]
@end example
This time, the assignment to @var{mm} does not change the value of @var{m}.

@end deffn

@deffn {Function} cholesky (@var{M})
@deffnx {Function} cholesky (@var{M}, @var{field})

Return the Cholesky factorization of the matrix selfadjoint (or hermitian) matrix 
@var{M}. The second argument defaults to 'generalring.' For a description of the
possible values for @var{field}, see @code{lu_factor}.

@end deffn

@deffn {Function} ctranspose (@var{M})

Return the complex conjugate transpose of the matrix @var{M}. The function
@code{ctranspose} uses @code{matrix_element_transpose} to transpose each matrix element.

@end deffn

@deffn {Function} diag_matrix (@var{d_1}, @var{d_2},...,@var{d_n})

Return a diagonal matrix with diagonal entries @var{d_1}, @var{d_2},...,@var{d_n}.
When the diagonal entries are matrices, the zero entries of the returned matrix
are zero matrices of the appropriate size; for example:
@c ===beg===
@c load(linearalgebra)$
@c diag_matrix(diag_matrix(1,2),diag_matrix(3,4));
@c diag_matrix(p,q);
@c ===end===
@example
(%i1) load(linearalgebra)$

(%i2) diag_matrix(diag_matrix(1,2),diag_matrix(3,4));

			    [ [ 1  0 ]  [ 0  0 ] ]
			    [ [      ]  [      ] ]
			    [ [ 0  2 ]  [ 0  0 ] ]
(%o2) 			    [ 			 ]
			    [ [ 0  0 ]  [ 3  0 ] ]
			    [ [      ]  [      ] ]
			    [ [ 0  0 ]  [ 0  4 ] ]
(%i3) diag_matrix(p,q);

				   [ p  0 ]
(%o3) 				   [ 	  ]
				   [ 0  q ]
@end example
@end deffn

@deffn {Function} dotproduct (@var{u}, @var{v})

Return the dotproduct of vectors @var{u} and @var{v}.  This is the same
as @code{conjugate (transpose (@var{u})) . @var{v}}.  The arguments @var{u} and @var{v} must be
column vectors.

@end deffn

@deffn {Function} get_lu_factors (@var{x}) 

When @code{@var{x} = lu_factor (@var{A})}, then @code{get_lu_factors} returns a list of the 
form @code{[P, L, U]}, where @var{P} is a permutation matrix, @var{L} is lower triangular with
ones on the diagonal, and @var{U} is upper triangular, and @code{@var{A} = @var{P} @var{L} @var{U}}.

@end deffn

@deffn {Function} hankel (@var{col})
@deffnx {Function} hankel (@var{col}, @var{row})

Return a Hankel matrix @var{H}. The first first column of @var{H} is @var{col};
except for the first entry, the last row of @var{H} is @var{row}. The
default for @var{row} is the zero vector with the same length as @var{col}.

@end deffn

@deffn {Function} hessian (@var{f},@var{vars})

Return the hessian matrix of @var{f} with respect to the variables in the list
@var{vars}.  The @var{i},@var{j} entry of the hessian matrix is 
@var{diff(f vars[i],1,vars[j],1)}.

@end deffn

@deffn {Function} hilbert_matrix (@var{n})

Return the @var{n} by @var{n} Hilbert matrix. When @var{n} isn't a positive
integer, signal an error.

@end deffn

@deffn {Function} identfor (@var{M})
@deffnx {Function} identfor (@var{M}, @var{fld})

Return an identity matrix that has the same shape as the matrix
@var{M}.  The diagonal entries of the identity matrix are the 
multiplicative identity of the field @var{fld}; the default for
@var{fld} is @var{generalring}.

The first argument @var{M} should be a square matrix or a 
non-matrix. When @var{M} is a matrix, each entry of @var{M} can be a
square matrix -- thus @var{M} can be a blocked Maxima matrix. The
matrix can be blocked to any (finite) depth.

See also @code{zerofor}

@end deffn

@deffn {Function} invert_by_lu (@var{M}, @var{(rng generalring)})

Invert a matrix @var{M} by using the LU factorization.  The LU factorization
is done using the ring @var{rng}.

@end deffn

@deffn {Function} kronecker_product (@var{A}, @var{B})

Return the Kronecker product of the matrices @var{A} and @var{B}.

@end deffn


@deffn {Function} locate_matrix_entry (@var{M}, @var{r_1}, @var{c_1}, @var{r_2}, @var{c_2}, @var{f}, @var{rel})

The first argument must be a matrix; the arguments
@var{r_1} through @var{c_2} determine a sub-matrix of @var{M} that consists of
rows @var{r_1} through @var{r_2} and columns @var{c_1} through @var{c_2}. 

Find a entry in the sub-matrix @var{M} that satisfies some property. 
Three cases:

(1) @code{@var{rel} = 'bool} and @var{f} a predicate: 

Scan the sub-matrix from left to right then top to bottom,
and return the index of the first entry that satisfies the 
predicate @var{f}. If no matrix entry satisfies @var{f}, return false.

(2) @code{@var{rel} = 'max} and @var{f} real-valued:

Scan the sub-matrix looking for an entry that maximizes @var{f}.
Return the index of a maximizing entry.

(3) @code{@var{rel} = 'min} and @var{f} real-valued:

Scan the sub-matrix looking for an entry that minimizes @var{f}. 
Return the index of a minimizing entry.

@end deffn

@deffn {Function} lu_backsub (@var{M}, @var{b})

When @code{@var{M} = lu_factor (@var{A}, @var{field})},
then @code{lu_backsub (@var{M}, @var{b})} solves the linear
system @code{@var{A} @var{x} = @var{b}}.

@end deffn

@deffn {Function} lu_factor (@var{M}, @var{field})

Return a list of the form @code{[@var{LU}, @var{perm}, @var{fld}]}, 
or @code{[@var{LU}, @var{perm}, @var{fld}, @var{lower-cnd} @var{upper-cnd}]}, where

  (1) The matrix @var{LU} contains the factorization of @var{M} in a packed form. Packed
      form means three things: First, the rows of @var{LU} are permuted according to the 
      list @var{perm}.  If, for example, @var{perm} is the list @code{[3,2,1]}, the actual first row 
      of the @var{LU} factorization is the third row of the matrix @var{LU}. Second,
      the lower triangular factor of m is the lower triangular part of @var{LU} with the
      diagonal entries replaced by all ones. Third, the upper triangular factor of 
      @var{M} is the upper triangular part of @var{LU}.  

  (2) When the field is either @code{floatfield} or @code{complexfield},
      the numbers @var{lower-cnd} and @var{upper-cnd} are lower and upper bounds for the 
      infinity norm condition number of @var{M}.  For all fields, the condition number 
      might not be estimated; for such fields, @code{lu_factor} returns a two item list.
      Both the lower and upper bounds can differ from their true values by 
      arbitrarily large factors. (See also @code{mat_cond}.)
   
  The argument @var{M} must be a square matrix.

  The optional argument @var{fld} must be a symbol that determines a ring or field. The pre-defined 
  fields and rings are:

    (a) @code{generalring} -- the ring of Maxima expressions,
    (b) @code{floatfield} --  the field of floating point numbers of the type double,
    (c) @code{complexfield} --  the field of complex floating point numbers of the 
        type double,
    (d) @code{crering}  -- the ring of Maxima CRE expressions,
    (e) @code{rationalfield} -- the field of rational numbers,
    (f) @code{runningerror} -- track the all floating point rounding errors,
     (g) @code{noncommutingring} -- the ring of Maxima expressions where multiplication is the
        non-commutative dot operator.       

When the field is @code{floatfield}, @code{complexfield}, or
@code{runningerror}, the algorithm uses partial pivoting; for all
other fields, rows are switched only when needed to avoid a zero
pivot.

Floating point addition arithmetic isn't associative, so the meaning
of 'field' differs from the mathematical definition.

A member of the field @code{runningerror} is a two member Maxima list
of the form @code{[x,n]},where @var{x} is a floating point number and
@code{n} is an integer. The relative difference between the 'true'
value of @code{x} and @code{x} is approximately bounded by the machine
epsilon times @code{n}. The running error bound drops some terms that
of the order the square of the machine epsilon.

There is no user-interface for defining a new field. A user that is
familiar with Common Lisp should be able to define a new field.  To do
this, a user must define functions for the arithmetic operations and
functions for converting from the field representation to Maxima and
back. Additionally, for ordered fields (where partial pivoting will be
used), a user must define functions for the magnitude and for
comparing field members.  After that all that remains is to define a
Common Lisp structure @code{mring}.  The file @code{mring} has many
examples.
 
To compute the factorization, the first task is to convert each matrix
entry to a member of the indicated field. When conversion isn't
possible, the factorization halts with an error message. Members of
the field needn't be Maxima expressions.  Members of the
@code{complexfield}, for example, are Common Lisp complex numbers. Thus
after computing the factorization, the matrix entries must be
converted to Maxima expressions.

See also  @code{get_lu_factors}.


Examples:

@c ===beg===
@c load (linearalgebra);
@c w[i,j] := random (1.0) + %i * random (1.0);
@c showtime : true$
@c M : genmatrix (w, 100, 100)$
@c lu_factor (M, complexfield)$
@c lu_factor (M, generalring)$
@c showtime : false$
@c M : matrix ([1 - z, 3], [3, 8 - z]); 
@c lu_factor (M, generalring);
@c get_lu_factors (%);
@c %[1] . %[2] . %[3];
@c ===end===
@example
(%i1) load (linearalgebra);
Warning - you are redefining the Maxima function require_list
Warning - you are redefining the Maxima function matrix_size
Warning - you are redefining the Maxima function rank
(%o1) /usr/local/share/maxima/5.9.2/share/linearalgebra/linearalgebra.mac
(%i2) w[i,j] := random (1.0) + %i * random (1.0);
(%o2)          w     := random(1.) + %i random(1.)
                i, j
(%i3) showtime : true$
Evaluation took 0.00 seconds (0.00 elapsed)
(%i4) M : genmatrix (w, 100, 100)$
Evaluation took 7.40 seconds (8.23 elapsed)
(%i5) lu_factor (M, complexfield)$
Evaluation took 28.71 seconds (35.00 elapsed)
(%i6) lu_factor (M, generalring)$
Evaluation took 109.24 seconds (152.10 elapsed)
(%i7) showtime : false$

(%i8) M : matrix ([1 - z, 3], [3, 8 - z]); 
                        [ 1 - z    3   ]
(%o8)                   [              ]
                        [   3    8 - z ]
(%i9) lu_factor (M, generalring);
               [ 1 - z         3        ]
               [                        ]
(%o9)         [[   3            9       ], [1, 2]]
               [ -----  - z - ----- + 8 ]
               [ 1 - z        1 - z     ]
(%i10) get_lu_factors (%);
                  [   1    0 ]  [ 1 - z         3        ]
        [ 1  0 ]  [          ]  [                        ]
(%o10) [[      ], [   3      ], [                9       ]]
        [ 0  1 ]  [ -----  1 ]  [   0    - z - ----- + 8 ]
                  [ 1 - z    ]  [              1 - z     ]
(%i11) %[1] . %[2] . %[3];
                        [ 1 - z    3   ]
(%o11)                  [              ]
                        [   3    8 - z ]
@end example

@end deffn

@deffn {Function} mat_cond (@var{M}, 1)
@deffnx {Function} mat_cond (@var{M}, inf)

Return the @var{p}-norm matrix condition number of the matrix
@var{m}. The allowed values for @var{p} are 1 and @var{inf}.  This
function uses the LU factorization to invert the matrix @var{m}. Thus
the running time for @code{mat_cond} is proportional to the cube of
the matrix size; @code{lu_factor} determines lower and upper bounds
for the infinity norm condition number in time proportional to the
square of the matrix size.

@end deffn

@deffn {Function} mat_norm (@var{M}, 1)
@deffnx {Function} mat_norm (@var{M}, inf)
@deffnx {Function} mat_norm (@var{M}, frobenius)

Return the matrix @var{p}-norm of the matrix @var{M}.  The allowed values for @var{p} are
1, @code{inf}, and @code{frobenius} (the Frobenius matrix norm). The matrix @var{M} should be
an unblocked matrix.

@end deffn


@deffn {Function} matrix_size (@var{M})

Return a two member list that gives the number of rows and columns, respectively
of the matrix @var{M}.

@end deffn

@deffn {Function} mat_fullunblocker (@var{M})

If @var{M} is a block matrix, unblock the matrix to all levels. If @var{M} is a matrix,
return @var{M}; otherwise, signal an error.  

@end deffn

@deffn {Function} mat_trace (@var{M})

Return the trace of the matrix @var{M} If @var{M} isn't a matrix, return a
noun form. When @var{M} is a block matrix, @code{mat_trace(M)} returns
the same value as does @code{mat_trace(mat_unblocker(m))}.

@end deffn

@deffn {Function} mat_unblocker (@var{M})

If @var{M} is a block matrix, unblock @var{M} one level. If @var{M} is a matrix, 
@code{mat_unblocker (M)} returns @var{M}; otherwise, signal an error.

Thus if each entry of @var{M} is matrix, @code{mat_unblocker (M)} returns an 
unblocked matrix, but if each entry of @var{M} is a block matrix, @code{mat_unblocker (M)} 
returns a block matrix with on less level of blocking.

If you use block matrices, most likely you'll want to set @code{matrix_element_mult} to 
@code{"."} and @code{matrix_element_transpose} to @code{'transpose}. See also @code{mat_fullunblocker}.

Example:

@c ===beg===
@c load (linearalgebra);
@c A : matrix ([1, 2], [3, 4]);
@c B : matrix ([7, 8], [9, 10]);
@c matrix ([A, B]);
@c mat_unblocker (%);
@c ===end===
@example
(%i1) load (linearalgebra);
Warning - you are redefining the Maxima function require_list
Warning - you are redefining the Maxima function matrix_size
Warning - you are redefining the Maxima function rank
(%o1) /usr/local/share/maxima/5.9.2/share/linearalgebra/linearalgebra.mac
(%i2) A : matrix ([1, 2], [3, 4]);
                            [ 1  2 ]
(%o2)                       [      ]
                            [ 3  4 ]
(%i3) B : matrix ([7, 8], [9, 10]);
                            [ 7  8  ]
(%o3)                       [       ]
                            [ 9  10 ]
(%i4) matrix ([A, B]);
                     [ [ 1  2 ]  [ 7  8  ] ]
(%o4)                [ [      ]  [       ] ]
                     [ [ 3  4 ]  [ 9  10 ] ]
(%i5) mat_unblocker (%);
                         [ 1  2  7  8  ]
(%o5)                    [             ]
                         [ 3  4  9  10 ]
@end example

@end deffn

@deffn {Function} nonnegintegerp (@var{n})

Return @code{true} if and only if @code{@var{n} >= 0} and @var{n} is an integer.

@end deffn

@deffn {Function} nullspace (@var{M})

If @var{M} is a matrix, return @code{span (v_1, ..., v_n)}, where the set @code{@{v_1, ..., v_n@}}
is a basis for the nullspace of @var{M}.  The span of the empty set is @code{@{0@}}.  
Thus, when the nullspace has only one member, return @code{span ()}.

@end deffn

@deffn {Function} nullity (@var{M})

If @var{M} is a matrix, return the dimension of the nullspace of @var{M}.

@end deffn

@deffn {Function} orthogonal_complement (@var{v_1}, ..., @var{v_n})

Return @code{span (u_1, ..., u_m)}, where the set @code{@{u_1, ..., u_m@}} is a 
basis for the orthogonal complement of the set @code{(v_1, ..., v_n)}.

Each vector @var{v_1} through @var{v_n} must be a column vector.

@end deffn

@deffn {Function} polynomialp (@var{p}, @var{L}, @var{coeffp}, @var{exponp})
@deffnx {Function} polynomialp (@var{p}, @var{L}, @var{coeffp})
@deffnx {Function} polynomialp (@var{p}, @var{L})

Return true if @var{p} is a polynomial in the variables in the list @var{L},
The predicate @var{coeffp} must evaluate to @code{true} for each
coefficient, and the predicate @var{exponp} must evaluate to @code{true} for all 
exponents of the variables in @var{L}. If you want to use a non-default
value for @var{exponp}, you must supply @var{coeffp} with a value even if you want
to use the default for @var{coeffp}.

@c WORK THE FOLLOWING INTO THE PRECEDING
@code{polynomialp (@var{p}, @var{L}, @var{coeffp})} is equivalent to
@code{polynomialp (@var{p}, @var{L}, @var{coeffp}, 'nonnegintegerp)}.

@code{polynomialp (@var{p}, @var{L})} is equivalent to
@code{polynomialp (@var{p}, L@var{,} 'constantp, 'nonnegintegerp)}.

The polynomial needn't be expanded:

@c ===beg===
@c load (linearalgebra);
@c polynomialp ((x + 1)*(x + 2), [x]);
@c polynomialp ((x + 1)*(x + 2)^a, [x]);
@c ===end===
@example
(%i1) load (linearalgebra);
Warning - you are redefining the Maxima function require_list
Warning - you are redefining the Maxima function matrix_size
Warning - you are redefining the Maxima function rank
(%o1) /usr/local/share/maxima/5.9.2/share/linearalgebra/linearalgebra.mac
(%i2) polynomialp ((x + 1)*(x + 2), [x]);
(%o2)                         true
(%i3) polynomialp ((x + 1)*(x + 2)^a, [x]);
(%o3)                         false
@end example

An example using non-default values for coeffp and exponp:

@c ===beg===
@c load (linearalgebra);
@c polynomialp ((x + 1)*(x + 2)^(3/2), [x], numberp, numberp);
@c polynomialp ((x^(1/2) + 1)*(x + 2)^(3/2), [x], numberp, numberp);
@c ===end===
@example
(%i1) load (linearalgebra);
Warning - you are redefining the Maxima function require_list
Warning - you are redefining the Maxima function matrix_size
Warning - you are redefining the Maxima function rank
(%o1) /usr/local/share/maxima/5.9.2/share/linearalgebra/linearalgebra.mac
(%i2) polynomialp ((x + 1)*(x + 2)^(3/2), [x], numberp, numberp);
(%o2)                         true
(%i3) polynomialp ((x^(1/2) + 1)*(x + 2)^(3/2), [x], numberp, numberp);
(%o3)                         true
@end example

Polynomials with two variables:

@c ===beg===
@c load (linearalgebra);
@c polynomialp (x^2 + 5*x*y + y^2, [x]);
@c polynomialp (x^2 + 5*x*y + y^2, [x, y]);
@c ===end===
@example
(%i1) load (linearalgebra);
Warning - you are redefining the Maxima function require_list
Warning - you are redefining the Maxima function matrix_size
Warning - you are redefining the Maxima function rank
(%o1) /usr/local/share/maxima/5.9.2/share/linearalgebra/linearalgebra.mac
(%i2) polynomialp (x^2 + 5*x*y + y^2, [x]);
(%o2)                         false
(%i3) polynomialp (x^2 + 5*x*y + y^2, [x, y]);
(%o3)                         true
@end example

@end deffn

@deffn {Function} polytocompanion (@var{p}, @var{x})

If @var{p} is a polynomial in @var{x}, return the companion matrix of @var{p}. For
a monic polynomial @var{p} of degree @var{n},
we have @code{@var{p} = (-1)^@var{n} charpoly (polytocompanion (@var{p}, @var{x}))}.

When @var{p} isn't a polynomial in @var{x}, signal an error.

@end deffn

@deffn {Function} ptriangularize (@var{M}, @var{v})

If @var{M} is a matrix with each entry a polynomial in @var{v}, return 
a matrix @var{M2} such that

(1) @var{M2} is upper triangular,

(2) @code{@var{M2} = @var{E_n} ... @var{E_1} @var{M}},
where @var{E_1} through @var{E_n} are elementary matrices 
whose entries are polynomials in @var{v},

(3) @code{|det (@var{M})| = |det (@var{M2})|},

Note: This function doesn't check that every entry is a polynomial in @var{v}.  

@end deffn

@deffn {Function} rowop (@var{M}, @var{i}, @var{j}, @var{theta})

If @var{M} is a matrix, return the matrix that results from doing the  
row operation @code{R_i <- R_i - theta * R_j}. If @var{M} doesn't have a row
@var{i} or @var{j}, signal an error.

@end deffn

@deffn {Function} rank (@var{M})

Return the rank of that matrix @var{M}. The rank is the dimension of the
column space. Example:
@c ===beg===
@c load (linearalgebra);
@c 
@c ===end===
@example
(%i1) load(linearalgebra)$
(%i2) rank(matrix([1,2],[2,4]));
(%o2) 1
(%i3) rank(matrix([1,b],[c,d]));
Proviso:  @{d-b*c # 0@}
(%o3) 2
@end example

@end deffn


@deffn {Function} rowswap (@var{M}, @var{i}, @var{j})

If @var{M} is a matrix, swap rows @var{i} and @var{j}. If @var{M} doesn't have a row
@var{i} or @var{j}, signal an error.

@end deffn

@deffn {Function} toeplitz (@var{col})
@deffnx {Function} toeplitz (@var{col}, @var{row})

Return a Toeplitz matrix @var{T}. The first first column of @var{T} is @var{col};
except for the first entry, the first row of @var{T} is @var{row}. The
default for @var{row} is complex conjugate of @var{col}. Example:
@c ===beg===
@c load(linearalgebra)$
@c toeplitz([1,2,3],[x,y,z]);
@c toeplitz([1,1+%i]);
@c ==end===
@example
(%i1) load(linearalgebra)$

(%i2)  toeplitz([1,2,3],[x,y,z]);

				  [ 1  y  z ]
				  [	    ]
(%o2) 				  [ 2  1  y ]
				  [	    ]
				  [ 3  2  1 ]
(%i3)  toeplitz([1,1+%i]);

			      [	  1     1 - %I ]
(%o3) 			      [ 	       ]
			      [ %I + 1	  1    ]
@end example

@end deffn

@deffn {Function} vandermonde_matrix ([@var{x_1}, ..., @var{x_n}])

Return a @var{n} by @var{n} matrix whose @var{i}-th row is 
@code{[1, @var{x_i}, @var{x_i}^2, ... @var{x_i}^(@var{n}-1)]}. 

@end deffn

@deffn {Function} zerofor (@var{M})
@deffnx {Function}  zerofor (@var{M}, @var{fld})

Return a zero  matrix that has the same shape as the matrix
@var{M}.  Every entry of the zero matrix matrix is the
additive identity of the field @var{fld}; the default for
@var{fld} is @var{generalring}.

The first argument @var{M} should be a square matrix or a
non-matrix. When @var{M} is a matrix, each entry of @var{M} can be a
square matrix -- thus @var{M} can be a blocked Maxima matrix. The
matrix can be blocked to any (finite) depth.

See also @code{identfor}

@end deffn

@deffn {Function} zeromatrixp (@var{M})

If @var{M} is not a block matrix, return @code{true} if @code{is (equal (@var{e}, 0))} 
is true for each element @var{e} of the matrix @var{M}.  If @var{M} is a block matrix, return
@code{true} if @code{zeromatrixp} evaluates to true for each element of @var{e}.

@end deffn

@node Function and variable index,  , Definitions for linearalgebra, Top
@appendix Function and variable index
@printindex fn
@printindex vr

@bye
