**LESSSPACE** _ _ _ _ _ _ _ _ _ _ _ _ **switch**

You can turn on the switch *lessspace* if you want fewer
blank lines in your output.

**LIMITEDFACTORS** _ _ _ _ _ _ _ _ _ _ _ _ **switch**

To get limited factorization in cases where it is too expensive to use
full multivariate polynomial factorization, the switch
*limitedfactors* can be turned on. In that case, only ``inexpensive''
factoring operations, such as square-free factorization, will be used
when
factorize is called.

a := (y-x)^2*(y^3+2x*y+5)*(y^2-3x*y+7)$ factorize a; 2 {- 3*X*Y + Y + 7,1} 3 {2*X*Y + Y + 5,1}, {X - Y,2}} on limitedfactors; factorize a; 2 2 4 3 5 3 2 {- 6*X *Y - 3*X*Y + 2*X*Y - X*Y + Y + 7*Y + 5*Y + 35,1}, {X - Y,2}}

**LIST** _ _ _ _ _ _ _ _ _ _ _ _ **switch**

The *list* switch causes REDUCE to print each term in any sum on
separate lines.

x**2*(y**2 + 2*y) + x*(y**2 + z)/(2*a); 2 2 X*(2*A*X*Y + 4*A*X*Y + Y +Z) ------------------------------ 2*A on list; ws; 2 (X*(2*A*X*Y + 4*A*X*Y 2 + Y + Z))/(2*A)

**LISTARGS** _ _ _ _ _ _ _ _ _ _ _ _ **switch**

If an operator other than those specifically defined for lists is given a
single argument that is a list, then the result of this operation will be
a list in which that operator is applied to each element of the list.
This process can be inhibited globally by turning on the switch
*listargs*.

log {a,b,c}; LOG(A),LOG(B),LOG(C) on listargs; log {a,b,c}; LOG(A,B,C)

It is possible to inhibit such distribution for a specific operato
r by
using the declaration
listargp. In addition, if an operator has
more than one argument, no such distribution occurs, so *listargs*
has no effect.

**MCD** _ _ _ _ _ _ _ _ _ _ _ _ **switch**

When *mcd* is on, sums and differences of rational expressions are put
on a common denominator. Default is *on*.

a/(x+1) + b/5; 5*A + B*X + B ------------- 5*(X + 1) off mcd; a/(x+1) + b/5; -1 (X + 1) *A + 1/5*B 1/6 + 1/7; 13/42

Even with *mcd* off, rational expressions involving only nu
mbers are still
put over a common denominator.

Turning *mcd* off is useful when explicit negative powers are needed,
or if no greatest common divisor calculations are desired, or when
differentiating complicated rational expressions. Results when *mcd*
is off are no longer in canonical form, and expressions equivalent to zero
may not simplify to 0. Some operations, such as factoring cannot be done
while *mcd* is off. This option should therefore be used with some
caution. Turning *mcd* off is most valuable in intermediate parts of
a complicated calculation, and should be turned back on for the last stage.

**MODULAR** _ _ _ _ _ _ _ _ _ _ _ _ **switch**

When *modular* is on, polynomial coefficients are reduced by the
modulus set by
setmod. If no modulus has been set, *modul
ar*
has no effect.

setmod 2; 1 on modular; (x+y)**2; 2 2 X + Y 145*x**2 + 20*x**3 + 17 + 15*x*y; 2 X + X*Y + 1

Modular operations are only conducted on the coefficients, not the exponents. The modulus is not restricted to being prime. When the modulus is prime, division by a number not relatively prime to the modulus results in a <Zero divisor> error message. When the modulus is a composite number, division by a power of the modulus results in an error message, but division by an integer which is a factor of the modulus does not. The representation of modular number can be influenced by balanced_mod.

**MSG** _ _ _ _ _ _ _ _ _ _ _ _ **switch**

When *msg* is off, the printing of warning messages is suppressed. Error
messages are still printed.

Warning messages include those about redimensioning an array or declaring an operator where one is expected.

**MULTIPLICITIES** _ _ _ _ _ _ _ _ _ _ _ _ **switch**

When
solve is applied to a set of equations with m
ultiple roots,
solution multiplicities are normally stored in the global variable
root_multiplicities rather than the solution
list. If you want
the multiplicities explicitly displayed, the switch *multiplicities*
should be turned on. In this case, *root_multiplicities* has no value.

solve(x^2=2x-1,x); X=1 root_multiplicities; 2 on multiplicities; solve(x^2=2x-1,x); X=1,X=1 root_multiplicities;

**NAT** _ _ _ _ _ _ _ _ _ _ _ _ **switch**

When *nat* is on, output is printed to the screen in natural form, with
raised exponents. *nat* should be turned off when outputting expressions
to a file for future input. Default is *on*.

(x + y)**3; 3 2 2 3 X + 3*X *Y + 3*X*Y + Y off nat; (x + y)**3; X**3 + 3*X**2*Y + 3*X*Y**2 + Y**3$ on fort; (x + y)**3; ANS=X**3+3.*X**2*Y+3.*X*Y**2+Y**3

With *nat* off, a dollar sign is printed at the end of each
expression.
An output file written with *nat* off is ready to be read into REDUCE
using the command
in.

**NERO** _ _ _ _ _ _ _ _ _ _ _ _ **switch**

When *nero* is on, zero assignments (such as matrix elements) are not
printed.

matrix a; a := mat((1,0),(0,1)); A(1,1) := 1 A(1,2) := 0 A(2,1) := 0 A(2,2) := 1 on nero; a; MAT(1,1) := 1 MAT(2,2) := 1 a(1,2);

nothing is printed.

b := 0;

nothing is printed.

off nero; b := 0; B := 0

*nero*is often used when dealing with large sparse matrices, to avoid
being overloaded with zero assignments.

**NOARG** _ _ _ _ _ _ _ _ _ _ _ _ **switch**

When
dfprint is on, expressions in the differentia
tion operator
df are printed in a more ``natural'' notation
, with the
differentiation variables appearing as subscripts. When *noarg*
is on (the default), the arguments of the differentiated operator are also
suppressed.

operator f; df(f x,x); DF(F(X),X); on dfprint; ws; F X off noarg; ws; F(X) X

**NOLNR** _ _ _ _ _ _ _ _ _ _ _ _ **switch**

When *nolnr* is on, the linear properties of the integration operator
int are suppressed if the integral cannot be
found in closed terms.

REDUCE uses the linear properties of integration to attempt to break down
an integral into manageable pieces. If an integral cannot be found in
closed terms, these pieces are returned. When the *nolnr* switch is off,
as many of the pieces as possible are integrated. When it is on, if any piece
fails, the rest of them remain unevaluated.

**NOSPLIT** _ _ _ _ _ _ _ _ _ _ _ _ **switch**

Under normal circumstances, the printing routines try to break an expression
across lines at a natural point. This is a fairly expensive process. If
you are not overly concerned about where the end-of-line breaks come, you
can speed up the printing of expressions by turning off the switch
*nosplit*. This switch is normally on.

**NUMVAL** _ _ _ _ _ _ _ _ _ _ _ _ **switch**

With
rounded on, elementary functions with numeric
al arguments
will return a numerical answer where appropriate. If you wish to inhibit
this evaluation, *numval* should be turned off. It is normally on.

on rounded; cos 3.4; - 0.966798192579 off numval; cos 3.4; COS(3.4)

**OUTPUT** _ _ _ _ _ _ _ _ _ _ _ _ **switch**

When *output* is off, no output is printed from any REDUCE calculation.
The calculations have their usual effects other than printing. Default is
*on*.

Turn output *off* if you do not wish to see output when executing
large files, or to save the time REDUCE spends formatting large expressions
for display. Results are still available with
ws, or in their
assigned variables.

**OVERVIEW** _ _ _ _ _ _ _ _ _ _ _ _ **switch**

When *overview* is on, the amount of detail reported by the factorizer
switches
trfac and
trallfac is reduced.

**PERIOD** _ _ _ _ _ _ _ _ _ _ _ _ **switch**

When *period* is on, periods are added after integers in
Fortran-compatible output (when
fort is on). There is no effect
when *fort* is off. Default is *on*.

**PRECISE** _ _ _ _ _ _ _ _ _ _ _ _ **switch**

When the *precise* switch is on, simplification of roots of even
powers returns absolute values, a more precise answer mathematically.
Default is *on*.

sqrt(x**2); X (x**2)**(1/4); SQRT(X) on precise; sqrt(x**2); ABS(X) (x**2)**(1/4); SQRT(ABS(X))

In many types of mathematical work, simplification of powers and s
urds can
proceed by the fastest means of simplifying the exponents arithmetically.
When it is important to you that the positive root be returned, turn
*precise* on. One situation where this is important is when graphing
square-root expressions such as sqrt(x^2+y^2) to
avoid a spike caused by REDUCE simplifying
sqrt(y^2) to y when x is
zero.

**PRET** _ _ _ _ _ _ _ _ _ _ _ _ **switch**

When *pret* is on, input is printed in standard REDUCE format and then
evaluated.

on pret; (x+1)^3; (x + 1)**3; 3 2 X + 3*X + 3*X + 1 procedure fac(n); if not (fixp(n) and n>=0) then rederr "Choose nonneg. integer only" else for i := 0:n-1 product i+1; procedure fac n; if not (fixp n and n>=0) then rederr "Choose nonneg. integer only" else for i := 0:n - 1 product i + 1; FAC fac 5; fac 5; 120

Note that all input is converted to lower case except strings (whi
ch keep
the same case) all operators with a single argument have had the
parentheses removed, and all infix operators have had a space added on each
side. In addition, syntactical constructs like
*if*...*then*...*else* are printed in a standard format.

**PRI** _ _ _ _ _ _ _ _ _ _ _ _ **switch**

When *pri* is on, the declarations
order and
factor can
be used, and the switches
allfac,
div,
rat,
and
revpri take effect when they are on. Default
is *on*.

Printing of expressions is faster with *pri* off. The expressions are
then returned in one standard form, without any of the display options that
can be used to feature or display various parts of the expression. You can
also gain insight into REDUCE's representation of expressions with
*pri* off.

**RAISE** _ _ _ _ _ _ _ _ _ _ _ _ **switch**

When *raise* is on, lower case letters are automatically converted to
upper case on input. *raise* is normally on.

This conversion affects the internal representation of the letter, and is independent of the case with which a letter is printed, which is normally lower case.

**RAT** _ _ _ _ _ _ _ _ _ _ _ _ **switch**

When the *rat* switch is on, and kernels have been selected to display
with the
factor declaration, the denominator is printe
d with each
term rather than one common denominator at the end of an expression.

(x+1)/x + x**2/sin y; 3 SIN(Y)*X + SIN(Y) + X ---------------------- factor x; SIN(Y)*X (x+1)/x + x**2/sin y; 3 X + X*SIN(Y) + SIN(Y) ---------------------- on rat; X*SIN(Y) (x+1)/x + x**2/sin y; 2 X -1 ------ + 1 + X SIN(Y)

The *rat* switch only has effect when the
pri switch is on.
When *pri* is off, regardless of the setting of *rat*, the
printing behavior is as if *rat* were off. *rat* only has
effect upon the display of expressions, not their internal form.

**RATARG** _ _ _ _ _ _ _ _ _ _ _ _ **switch**

When *ratarg* is on, rational expressions can be given to operators
such as
coeff and
lterm that normally require
polynomials in one of their arguments. When *ratarg* is off, rational
expressions cause an error message.

aa := x/y**2 + 1/x + y/x**2; 3 2 3 X + X*Y + Y AA := -------------- 2 2 X *Y coeff(aa,x); 3 2 3 X + X*Y + Y ***** -------------- invalid as POLYNOMIAL 2 2 X *Y on ratarg; coeff(aa,x); Y 1 1 {--,--,0,-----} 2 2 2 2 X X X *Y

**RATIONAL** _ _ _ _ _ _ _ _ _ _ _ _ **switch**

When *rational* is on, polynomial expressions with rational coefficients
are produced.

x/2 + 3*y/4; 2*X + 3*Y --------- 4 (x**2 + 5*x + 17)/2; 2 X + 5*X + 17 ------------- 2 on rational; x/2 + 3y/4; 1 3 -*(X + -*Y) 2 2 (x**2 + 5*x + 17)/2; 1 2 -*(X + 5*X + 17) 2

By using *rational*, polynomial expressions with rational
coefficients can be used in some commands that expect polynomials. With
*rational* off, such a polynomial becomes a rational expression, with
denominator the least common multiple of the denominators of the rational
number coefficients.

**RATIONALIZE** _ _ _ _ _ _ _ _ _ _ _ _ **switch**

When the *rationalize* switch is on, denominators of rational expressions
that contain complex numbers or root expressions are simplified by
multiplication by their conjugates.

qq := (1+sqrt(3))/(sqrt(3)-7); SQRT(3) + 1 QQ := ----------- SQRT(3) - 7 on rationalize; qq; - 4*SQRT(3) - 5 --------------- 23 2/(4 + 6**(1/3)); 2/3 1/3 6 - 4*6 + 16 ------------------ 35 (i-1)/(i+3); 2*I - 1 ------- 5 off rationalize; (i-1)/(i+3); I - 1 ------ I + 3

**RATPRI** _ _ _ _ _ _ _ _ _ _ _ _ **switch**

When the *ratpri* switch is on, rational expressions and fractions are
printed as two lines separated by a fraction bar, rather than in a linear
style. Default is *on*.

3/17; 3 -- 17 2/b + 3/y; 3*B + 2*Y --------- B*Y off ratpri; 3/17; 3/17 2/b + 3/y; (3*B + 2*Y)/(B*Y)

**REVPRI** _ _ _ _ _ _ _ _ _ _ _ _ **switch**

When the *revpri* switch is on, terms are printed in reverse order from
the normal printing order.

x**5 + x**2 + 18 + sqrt(y); 5 2 SQRT(Y) + X + X + 18 a + b + c + w; A + B + C + W on revpri; x**5 + x**2 + 18 + sqrt(y); 2 5 17 + X + X + SQRT(Y) a + b + c + w; W + C + B + A

Turn *revpri* on when you want to display a polynomial in a
scending
rather than descending order.

**RLISP88** _ _ _ _ _ _ _ _ _ _ _ _ **switch**

Rlisp '88 is a superset of the Rlisp that has been traditionally used for
the support of REDUCE. It is fully documented in the book Marti, J.B.,
``RLISP '88: An Evolutionary Approach to Program Design and Reuse'',
World Scientific, Singapore (1993). It supports different looping
constructs from the traditional Rlisp, and treats ``-'' as a letter unless
separated by spaces. Turning on the switch *rlisp88* converts to
Rlisp '88 parsing conventions in symbolic mode, and enables the use of
Rlisp '88 extensions. Turning off the switch reverts to the traditional
Rlisp and the previous mode ( (
symbolic or
algebraic)
in force before *rlisp88* was turned on.

**ROUNDALL** _ _ _ _ _ _ _ _ _ _ _ _ **switch**

In
rounded mode, rational numbers are normally c
onverted to a
floating point representation. If *roundall* is off, this conversion
does not occur. *roundall* is normally *on*.

on rounded; 1/2; 0.5 off roundall;

**ROUNDBF** _ _ _ _ _ _ _ _ _ _ _ _ **switch**

When
rounded is on, the normal defaults cause unde
rflows to be
converted to zero. If you really want the small number that results in
such cases, *roundbf* can be turned on.

on rounded; exp(-100000.1^2); 0 on roundbf; exp(-100000.1^2); 1.18441281937E-4342953505

If a polynomial is input in
rounded mode at the default
precision into any
roots function, and it is not possible to
represent any of the coefficients of the polynomial precisely in the
system floating point representation, the switch *roundbf* will be
automatically turned on. All rounded computation will use the internal
bigfloat representation until the user subsequently turns *roundbf*
off. (A message is output to indicate that this condition is in effect.)

**ROUNDED** _ _ _ _ _ _ _ _ _ _ _ _ **switch**

When *rounded* is on, floating-point arithmetic is enabled, with
precision initially at a system default value, which is usually 12 digits.
The precise number can be found by the command
precision(0).

pi; PI 35/217; 5 -- 31 on rounded; pi; 3.14159265359 35/217; 0.161 sqrt(3); 1.73205080756

If more than the default number of decimal places are required, use the precision command to set the required number.

**SAVESTRUCTR** _ _ _ _ _ _ _ _ _ _ _ _ **switch**

When *savestructr* is on, results of the
structr command are
returned as a list whose first element is the representation for the
expression and the remaining elements are equations showing the
relationships of the generated variables.

off exp; structr((x+y)^3 + sin(x)^2); ANS3 where 3 2 ANS3 := ANS1 + ANS2 ANS2 := SIN(X) ANS1 := X + Y ans3; ANS3 on savestructr; structr((x+y)^{3} + sin(x)^{2}); 3 2 ANS3,ANS3=ANS1 + ANS2 ,ANS2=SIN(X),ANS1=X + Y ans3 where rest ws; 3 2 (X + Y) + SIN(X)

In normal operation,
structr is only a display command. With
*savestructr* on, you can access the various parts of the expression
produced by *structr*.

The generic system names use the stem *ANS*. You can change this to your
own stem by the command
varname. REDUCE adds integers to this stem
to make unique identifiers.

**SOLVESINGULAR** _ _ _ _ _ _ _ _ _ _ _ _ **switch**

When *solvesingular* is on, singular or underdetermined systems of
linear equations are solved, using arbitrary real, complex or integer
variables in the answer. Default is *on*.

solve({2x + y,4x + 2y},{x,y}); ARBCOMPLEX(1) {{X= - -------------,Y=ARBCOMPLEX(1)}} 2 solve({7x + 15y - z,x - y - z},{x,y,z}); 8*ARBCOMPLEX(3) {{X=---------------- 11 3*ARBCOMPLEX(3) Y= - ---------------- 11 Z=ARBCOMPLEX(3)}} off solvesingular; solve({2x + y,4x + 2y},{x,y}); ***** SOLVE given singular equations solve({7x + 15y - z,x - y - z},{x,y,z}); ***** SOLVE given singular equations

The integer following the identifier arbcomplex above is assigned by the system, and serves to identify the variable uniquely. It has no other significance.

**TIME** _ _ _ _ _ _ _ _ _ _ _ _ **switch**

When *time* is on, the system time used in executing each REDUCE
statement is printed after the answer is printed.

on time; Time: 4940 ms df(sin(x**2 + y),y); 2 COS(X + Y ) Time: 180 ms solve(x**2 - 6*y,x); {X= - SQRT(Y)*SQRT(6), X=SQRT(Y)*SQRT(6)} Time: 320 ms

When *time* is first turned on, the time since the beginnin
g of the
REDUCE session is printed. After that, the time used in computation,
(usually in milliseconds, though this is system dependent) is printed after
the results of each command. Idle time or time spent typing in commands is
not counted. If *time* is turned off, the first reading after it is
turned on again gives the time elapsed since it was turned off. The time
printed is CPU or wall clock time, depending on the system.

**TRALLFAC** _ _ _ _ _ _ _ _ _ _ _ _ **switch**

When *trallfac* is on, a more detailed trace of factorizer calls is
generated.

The *trallfac* switch takes precedence over
trfac if they are
both on. *trfac* gives a factorization trace with less detail in it.
When the
factor switch is on also, all input polynomia
ls are sent to
the factorizer automatically and trace information is generated. The
out command saves the results of the factorin
g, but not the trace.

**TRFAC** _ _ _ _ _ _ _ _ _ _ _ _ **switch**

When *trfac* is on, a narrative trace of any calls to the factorizer is
generated. Default is *off*.

When the switch
factor is on, and *trfac* is on, every
input
polynomial is sent to the factorizer, and a trace generated. With
*factor* off, only polynomials that are explicitly factored with the
command
factorize generate trace information.

The out command saves the results of the factorin g, but not the trace. The trallfac switch gives trace information to a greater level of detail.

**TRIGFORM** _ _ _ _ _ _ _ _ _ _ _ _ **switch**

When
fullroots is on,
solve will compute the
roots of a cubic or quartic polynomial is closed form. When
*trigform* is on, the roots will be expressed by trigonometric
forms. Otherwise nested surds are used. Default is *on*.

**TRINT** _ _ _ _ _ _ _ _ _ _ _ _ **switch**

When *trint* is on, a narrative tracing various steps in the
integration process is produced.

The out command saves the results of the integrat ion, but not the trace.

**TRNONLNR** _ _ _ _ _ _ _ _ _ _ _ _ **switch**

When *trnonlnr* is on, a narrative tracing various steps in
the process for solving non-linear equations is produced.

*trnonlnr*can only be used after the solve package has been loaded
(e.g., by an explicit call of
load_package). The
out
command saves the results of the equation solving, but not the trace.

**VAROPT** _ _ _ _ _ _ _ _ _ _ _ _ **switch**

When *varopt* is on, the sequence of variables is optimized by
solve with respect to execution speed. Otherw
ise, the sequence
given in the call to
solve is preserved. Default is *on*.

In combination with the switch
arbvars, *varopt* can be used
to control variable elimination.

off arbvars; solve({x+2z,x-3y},{x,y,z}); x x {{y=-,z= - -}} 3 2 solve({x*y=1,z=x},{x,y,z}); 1 {{z=x,y=-}} x off varopt; solve({x+2z,x-3y},{x,y,z}); 2*z {{x= - 2*z,y= - ---}} 3 solve({x*y=1,z=x},{x,y,z}); 1 {{y=-,x=z}} z

**General Switches**

**COFACTOR** _ _ _ _ _ _ _ _ _ _ _ _ **operator**

The operator *cofactor* returns the cofactor of the element in row
<row> and column <column> of a
matrix. Errors occur
if <row> or <column> do not evaluate to integer expressions or if
the matrix is not square.

cofactor(mat((a,b,c),(d,e,f),(p,q,r)),2,2); A*R - C*P cofactor(mat((a,b,c),(d,e,f)),1,1); ***** non-square matrix

**DET** _ _ _ _ _ _ _ _ _ _ _ _ **operator**

The *det* operator returns the determinant of its
(square
matrix) argument.

<expression> must evaluate to a square matrix.

matrix m,n; m := mat((a,b),(c,d)); M(1,1) := A M(1,2) := B M(2,1) := C M(2,2) := D det m; A*D - B*C n := mat((1,2),(1,2)); N(1,1) := 1 N(1,2) := 2 N(2,1) := 1 N(2,2) := 2 det(n); 0 det(5); 5

Given a numerical argument, *det* returns the number. Howev
er, given a
variable name that has not been declared of type matrix, or a non-square
matrix, *det* returns an error message.

**MAT** _ _ _ _ _ _ _ _ _ _ _ _ **operator**

The *mat* operator is used to represent a two-dimensional
matrix.

*mat*((<expr>{,<expr>}*) {(<expr>{*,*<expr
>}*)}*)

<expr> may be any valid REDUCE scalar expression.

mat((1,2),(3,4)); MAT(1,1) := 1 MAT(2,3) := 2 MAT(2,1) := 3 MAT(2,2) := 4 mat(2,1); ***** Matrix mismatch Cont? (Y or N) matrix qt; qt := ws; QT(1,1) := 1 QT(1,2) := 2 QT(2,1) := 3 QT(2,2) := 4 matrix a,b; a := mat((x),(y),(z)); A(1,1) := X A(2,1) := Y A(3,1) := Z b := mat((sin x,cos x,1)); B(1,1) := SIN(X) B(1,2) := COS(X) B(1,3) := 1

Matrices need not have a size declared (unlike arrays). *mat
*
redimensions a matrix variable as needed. It is necessary, of course,
that all rows be the same length. An anonymous matrix, as shown in the
first example, must be named before it can be referenced (note error
message). When using *mat* to fill a 1 x n
matrix, the row of values must be inside a second set of parentheses, to
eliminate ambiguity.

**MATEIGEN** _ _ _ _ _ _ _ _ _ _ _ _ **operator**

The *mateigen* operator calculates the eigenvalue equation and the
corresponding eigenvectors of a
matrix.

*mateigen*(<matrix-id>,<tag-id>)

<matrix-id> must be a declared matrix of values, and <tag-id> must b e a legal REDUCE identifier.

aa := mat((2,5),(1,0))$ mateigen(aa,alpha); 2 {{ALPHA - 2*ALPHA - 5, 1, 5*ARBCOMPLEX(1) MAT(1,1) := ---------------, ALPHA - 2 MAT(2,1) := ARBCOMPLEX(1) }} charpoly := first first ws; 2 CHARPOLY := ALPHA - 2*ALPHA - 5 bb := mat((1,0,1),(1,1,0),(0,0,1))$ mateigen(bb,lamb); {{LAMB - 1,3, [ 0 ] [ARBCOMPLEX(2)] [ 0 ] }}

The *mateigen* operator returns a list of lists of three
elements. The first element is a square free factor of the characteristic
polynomial; the second element is its multiplicity; and the third element
is the corresponding eigenvector. If the characteristic polynomial can be
completely factored, the product of the first elements of all the sublists
will produce the minimal polynomial. You can access the various parts of
the answer with the usual list access operators.

If the matrix is degenerate, more than one eigenvector can be produced for
the same eigenvalue, as shown by more than one arbitrary variable in the
eigenvector. The identification numbers of the arbitrary complex variables
shown in the examples above may not be the same as yours. Note that since
*lambda* is a reserved word in REDUCE, you cannot use it as a
tag-id for this operator.

**MATRIX** _ _ _ _ _ _ _ _ _ _ _ _ **declaration**

Identifiers are declared to be of type *matrix*.

*matrix*<identifier> _ _ _ option (<index>,<index>)

{,<identifier> _ _ _ option (<index>,<index>)}*

<identifier> must not be an already-defined operator or array or the name of a scalar variable. Dimensions are optional, and if used appear inside parentheses. <index> must be a positive integer.

matrix a,b(1,4),c(4,4); b(1,1); 0 a(1,1); ***** Matrix A not set a := mat((x0,y0),(x1,y1)); A(1,1) := X0 A(1,2) := Y0 A(2,1) := X0 A(2,2) := X1 length a; {2,2} b := a**2; 2 B(1,1) := X0 + X1*Y0 B(1,2) := Y0*(X0 + Y1) B(2,1) := X1*(X0 + Y1) 2 B(2,2) := X1*Y0 + Y1

When a matrix variable has not been dimensioned, matrix elements c annot be referenced until the matrix is set by the mat operator. When a matrix is dimensioned in its declaration, matrix elements are set to 0. Matrix elements cannot stand for themselves. When you use let on a matrix element, there is no effect unless the element contains a constant, in which case an error message is returned. The same behavior occurs with clear. Do <not> use clear to try to set a matrix element to 0. let statements can be applied to matrices as a whole, if the right-hand side of the expression is a matrix expression, and the left-hand side identifier has been declared to be a matrix.

Arithmetical operators apply to matrices of the correct dimensions. The
operators *+* and *-* can be used with matrices of the same
dimensions. The operator *** can be used to multiply
m x n matrices by n x p
matrices. Matrix multiplication is non-commutative. Scalars can also be
multiplied with matrices, with the result that each element of the matrix
is multiplied by the scalar. The operator */* applied to two
matrices computes the first matrix multiplied by the inverse of the
second, if the inverse exists, and produces an error message otherwise.
Matrices can be divided by scalars, which results in dividing each element
of the matrix. Scalars can also be divided by matrices when the matrices
are invertible, and the result is the multiplication of the scalar by the
inverse of the matrix. Matrix inverses can by found by *1/A* or
*/A*, where *A* is a matrix. Square matrices can be raised to
positive integer powers, and also to negative integer powers if they are
nonsingular.

When a matrix variable is assigned to the results of a calculation, the matrix is redimensioned if necessary.

**NULLSPACE** _ _ _ _ _ _ _ _ _ _ _ _ **operator**

<nullspace> calculates for its
matrix argument,
*a*, a list of
linear independent vectors (a basis) whose linear combinations satisfy the
equation a x = 0. The basis is provided in a form such that as many
upper components as possible are isolated.

nullspace mat((1,2,3,4),(5,6,7,8)); { [ 1 ] [ ] [ 0 ] [ ] [ - 3] [ ] [ 2 ] , [ 0 ] [ ] [ 1 ] [ ] [ - 2] [ ] [ 1 ] }

Note that with *b := nullspace a*, the expression *lengt
h b* is
the nullity/ of A, and that *second length a - length b*
calculates the rank/ of A. The rank of a matrix expression can
also be found more directly by the
rank operator.

In addition to the REDUCE matrix form, *nullspace* accepts as input a
matrix given as a
list of lists, that is interpreted as a row m
atrix. If
that form of input is chosen, the vectors in the result will be
represented by lists as well. This additional input syntax facilitates
the use of *nullspace* in applications different from classical linear
algebra.

**RANK** _ _ _ _ _ _ _ _ _ _ _ _ **operator**

*rank*calculates the rank of its matrix argument.

rank mat((a,b,c),(d,e,f)); 2

The argument to *rank* can also be a
list of lists, interpreted
either as a row matrix or a set of equations. If that form of input is
chosen, the vectors in the result will be represented by lists as well.
This additional input syntax facilitates the use of *rank* in
applications different from classical linear algebra.

**TP** _ _ _ _ _ _ _ _ _ _ _ _ **operator**

The *tp* operator returns the transpose of its
matrix
argument.

*tp*<identifier> or *tp*(<identifier>)

<identifier> must be a matrix, which either has had its dimensions set
in its declaration, or has had values put into it by *mat*.

matrix m,n; m := mat((1,2,3),(4,5,6))$ n := tp m; N(1,1) := 1 N(1,2) := 4 N(2,1) := 2 N(2,2) := 5 N(3,1) := 3 N(3,2) := 6

In an assignment statement involving *tp*, the matrix ident
ifier on the
left-hand side is redimensioned to the correct size for the transpose.

**TRACE** _ _ _ _ _ _ _ _ _ _ _ _ **operator**

The *trace* operator finds the trace of its
matrix argument.

*trace*(<expression>) or *trace* <simple\_expression>

<expression> or <simple\_expression> must evaluate to a square matrix.

matrix a; a := mat((x1,y1),(x2,y2))$ trace a; X1 + Y2

The trace is the sum of the entries along the diagonal of a square
matrix.
Given a non-matrix expression, or a non-square matrix, *trace* returns
an error message.