@c end concepts Equations
@menu
* Definitions for Equations::
@end menu
@node Definitions for Equations, , Equations, Equations
@section Definitions for Equations
@c @node %RNUM_LIST
@c @unnumberedsec phony
@defvar %RNUM_LIST
default: [] - When %R variables are introduced in solutions
by the ALGSYS command, they are added to %RNUM_LIST in the order they
are created. This is convenient for doing substitutions into the
solution later on. It's recommended to use this list rather than
doing CONCAT('%R,J).
@end defvar
@c @node ALGEXACT
@c @unnumberedsec phony
@defvar ALGEXACT
default: [FALSE] affects the behavior of ALGSYS as follows:
If ALGEXACT is TRUE, ALGSYS always calls SOLVE and then uses REALROOTS
on SOLVE's failures. If ALGEXACT is FALSE, SOLVE is called only if
the eliminant was not univariate, or if it was a quadratic or
biquadratic. Thus ALGEXACT:TRUE doesn't guarantee only exact
solutions, just that ALGSYS will first try as hard as it can to give
exact solutions, and only yield approximations when all else fails.
@end defvar
@c @node ALGSYS
@c @unnumberedsec phony
@defun ALGSYS ([exp1, exp2, ...], [var1, var2, ...])
solves the list of
simultaneous polynomials or polynomial equations (which can be
non-linear) for the list of variables. The symbols %R1, %R2, etc.
will be used to represent arbitrary parameters when needed for the
solution (the variable %RNUM_LIST holds these). In the process
described below, ALGSYS is entered recursively if necessary.
The method is as follows:
(1) First the equations are FACTORed and split into subsystems.
(2) For each subsystem Si, an equation E and a variable var are
selected (the var is chosen to have lowest nonzero degree). Then the
resultant of E and Ej with respect to var is computed for each of the
remaining equations Ej in the subsystem Si. This yields a new
subsystem S'i in one fewer variables (var has been eliminated). The
process now returns to (1).
(3) Eventually, a subsystem consisting of a single equation is
obtained. If the equation is multivariate and no approximations in
the form of floating point numbers have been introduced, then SOLVE is
called to find an exact solution. (The user should realize that SOLVE
may not be able to produce a solution or if it does the solution may
be a very large expression.)
If the equation is univariate and is either linear, quadratic, or
bi-quadratic, then again SOLVE is called if no approximations have
been introduced. If approximations have been introduced or the
equation is not univariate and neither linear, quadratic, or
bi-quadratic, then if the switch REALONLY[FALSE] is TRUE, the function
REALROOTS is called to find the real-valued solutions. If
REALONLY:FALSE then ALLROOTS is called which looks for real and
complex-valued solutions. If ALGSYS produces a solution which has
fewer significant digits than required, the user can change the value
of ALGEPSILON[10^8] to a higher value. If ALGEXACT[FALSE] is set to
TRUE, SOLVE will always be called.
(4) Finally, the solutions obtained in step (3) are re-inserted into
previous levels and the solution process returns to (1).
The user should be aware of several caveats:
When ALGSYS encounters a multivariate equation which contains
floating point approximations (usually due to its failing to find
exact solutions at an earlier stage), then it does not attempt to
apply exact methods to such equations and instead prints the message:
"ALGSYS cannot solve - system too complicated."
Interactions with RADCAN can produce large or complicated
expressions. In that case, the user may use PICKAPART or REVEAL to
analyze the solution. Occasionally, RADCAN may introduce an apparent
%I into a solution which is actually real-valued. Do EXAMPLE(ALGSYS);
for examples.
@end defun
@c @node ALLROOTS
@c @unnumberedsec phony
@defun ALLROOTS (poly)
finds all the real and complex roots of the real
polynomial poly which must be univariate and may be an equation, e.g.
poly=0. For complex polynomials an algorithm by Jenkins and Traub is
used (Algorithm 419, Comm. ACM, vol. 15, (1972), p. 97). For real
polynomials the algorithm used is due to Jenkins (Algorithm 493, TOMS,
vol. 1, (1975), p.178). The flag POLYFACTOR[FALSE] when true causes
ALLROOTS to factor the polynomial over the real numbers if the
polynomial is real, or over the complex numbers, if the polynomial is
complex. ALLROOTS may give inaccurate results in case of multiple
roots. (If poly is real and you get inaccurate answers, you may want
to try ALLROOTS(%I*poly);) Do EXAMPLE(ALLROOTS); for an example.
ALLROOTS rejects non-polynomials. It requires that the numerator
after RATting should be a polynomial, and it requires that the
denominator be at most a complex number. As a result of this ALLROOTS
will always return an equivalent (but factored) expression, if
POLYFACTOR is TRUE.
@end defun
@c @node BACKSUBST
@c @unnumberedsec phony
@defvar BACKSUBST
default: [TRUE] if set to FALSE will prevent back
substitution after the equations have been triangularized. This may
be necessary in very big problems where back substitution would cause
the generation of extremely large expressions. (On MC this could cause
storage capacity to be exceeded.)
@end defvar
@c @node BREAKUP
@c @unnumberedsec phony
@defvar BREAKUP
default: [TRUE] if FALSE will cause SOLVE to express the
solutions of cubic or quartic equations as single expressions rather
than as made up of several common subexpressions which is the default.
BREAKUP:TRUE only works when PROGRAMMODE is FALSE.
@end defvar
@c @node DIMENSION
@c @unnumberedsec phony
@defun DIMENSION (equation or list of equations)
The file "share1/dimen.mc"
contains functions for automatic dimensional analysis. LOAD(DIMEN);
will load it up for you. There is a demonstration available in
share1/dimen.dem. Do DEMO("dimen"); to run it.
@end defun
@c @node DISPFLAG
@c @unnumberedsec phony
@defvar DISPFLAG
default: [TRUE] if set to FALSE within a BLOCK will inhibit
the display of output generated by the solve functions called from
within the BLOCK. Termination of the BLOCK with a dollar sign, $, sets
DISPFLAG to FALSE.
@end defvar
@c @node FUNCSOLVE
@c @unnumberedsec phony
@defun FUNCSOLVE (eqn,g(t))
gives [g(t) = ...] or [], depending on whether
or not there exists a rational fcn g(t) satisfying eqn, which must be
a first order, linear polynomial in (for this case) g(t) and g(t+1).
@example
(C1) FUNCSOLVE((N+1)*FOO(N)-(N+3)*FOO(N+1)/(N+1) =
(N-1)/(N+2),FOO(N));
N
(D1) FOO(N) = ---------------
(N + 1) (N + 2)
@end example
Warning: this is a very rudimentary implementation--many safety checks
and obvious generalizations are missing.
@end defun
@c @node GLOBALSOLVE
@c @unnumberedsec phony
@defvar GLOBALSOLVE
default: [FALSE] if set to TRUE then variables which are
SOLVEd for will be set to the solution of the set of simultaneous
equations.
@end defvar
@c @node IEQN
@c @unnumberedsec phony
@defun IEQN (ie,unk,tech,n,guess)
Integral Equation solving routine. Do
LOAD(INTEQN); to access it. CAVEAT: To free some storage, a
KILL(LABELS) is included in this file. Therefore, before loading the
integral equation package, the user should give names to any
expressions he wants to keep.
ie is the integral equation; unk is the unknown function; tech is the
technique to be tried from those given above (tech = FIRST means: try
the first technique which finds a solution; tech = ALL means: try all
applicable techniques); n is the maximum number of terms to take for
TAYLOR, NEUMANN, FIRSTKINDSERIES, or FREDSERIES (it is also the
maximum depth of recursion for the differentiation method); guess is
the initial guess for NEUMANN or FIRSTKINDSERIES.
Default values for the 2nd thru 5th parameters are:
unk: P(X), where P is the first function encountered in an integrand
which is unknown to MACSYMA and X is the variable which occurs as an
argument to the first occurrence of P found outside of an integral in
the case of SECONDKIND equations, or is the only other variable
besides the variable of integration in FIRSTKIND equations. If the
attempt to search for X fails, the user will be asked to supply the
independent variable;
tech: FIRST;
n: 1;
guess: NONE, which will cause NEUMANN and FIRSTKINDSERIES to use F(X)
as an initial guess.
@end defun
@c @node IEQNPRINT
@c @unnumberedsec phony
@defvar IEQNPRINT
default: [TRUE] - governs the behavior of the result
returned by the IEQN command (which see). If IEQNPRINT is set to
FALSE, the lists returned by the IEQN function are of the form
[SOLUTION, TECHNIQUE USED, NTERMS, FLAG]
where FLAG is absent if the solution is exact. Otherwise, it is the
word APPROXIMATE or INCOMPLETE corresponding to an inexact or
non-closed form solution, respectively. If a series method was used,
NTERMS gives the number of terms taken (which could be less than the n
given to IEQN if an error prevented generation of further terms).
@end defvar
@c @node LHS
@c @unnumberedsec phony
@defun LHS (eqn)
the left side of the equation eqn.
@end defun
@c @node LINSOLVE
@c @unnumberedsec phony
@defun LINSOLVE ([exp1, exp2, ...], [var1, var2, ...])
solves the list of
simultaneous linear equations for the list of variables. The expi
must each be polynomials in the variables and may be equations.
If GLOBALSOLVE[FALSE] is set to TRUE then variables which are SOLVEd
for will be set to the solution of the set of simultaneous equations.
BACKSUBST[TRUE] if set to FALSE will prevent back substitution after
the equations have been triangularized. This may be necessary in very
big problems where back substitution would cause the generation of
extremely large expressions. (On MC this could cause the storage
capacity to be exceeded.)
LINSOLVE_PARAMS[TRUE] If TRUE, LINSOLVE also generates the %Ri symbols
used to represent arbitrary parameters described in the manual under
ALGSYS. If FALSE, LINSOLVE behaves as before, i.e. when it meets up
with an under-determined system of equations, it solves for some of
the variables in terms of others.
@example
(C1) X+Z=Y$
(C2) 2*A*X-Y=2*A**2$
(C3) Y-2*Z=2$
(C4) LINSOLVE([D1,D2,D3],[X,Y,Z]),GLOBALSOLVE:TRUE;
SOLUTION
(E4) X : A + 1
(E5) Y : 2 A
(E6) Z : A - 1
(D6) [E4, E5, E6]
@end example
@end defun
@c @node LINSOLVEWARN
@c @unnumberedsec phony
@defvar LINSOLVEWARN
default: [TRUE] - if FALSE will cause the message
"Dependent equations eliminated" to be suppressed.
@end defvar
@c @node LINSOLVE_PARAMS
@c @unnumberedsec phony
@defvar LINSOLVE_PARAMS
default: [TRUE] - If TRUE, LINSOLVE also generates
the %Ri symbols used to represent arbitrary parameters described in
the manual under ALGSYS. If FALSE, LINSOLVE behaves as before, i.e.
when it meets up with an under-determined system of equations, it
solves for some of the variables in terms of others.
@end defvar
@c @node MULTIPLICITIES
@c @unnumberedsec phony
@defvar MULTIPLICITIES
default: [NOT_SET_YET] - will be set to a list of the
multiplicities of the individual solutions returned by SOLVE or
REALROOTS.
@end defvar
@c @node NROOTS
@c @unnumberedsec phony
@defun NROOTS (poly, low, high)
finds the number of real roots of the real
univariate polynomial poly in the half-open interval (low,high]. The
endpoints of the interval may also be MINF,INF respectively for minus
infinity and plus infinity. The method of Sturm sequences is used.
@example
(C1) POLY1:X**10-2*X**4+1/2$
(C2) NROOTS(POLY1,-6,9.1);
RAT REPLACED 0.5 BY 1/2 = 0.5
(D2) 4
@end example
@end defun
@c @node NTHROOT
@c @unnumberedsec phony
@defun NTHROOT (p,n)
where p is a polynomial with integer coefficients and
n is a positive integer returns q, a polynomial over the integers, such
that q^n=p or prints an error message indicating that p is not a perfect
nth power. This routine is much faster than FACTOR or even SQFR.
@end defun
@c @node PROGRAMMODE
@c @unnumberedsec phony
@defvar PROGRAMMODE
default: [TRUE] - when FALSE will cause SOLVE, REALROOTS,
ALLROOTS, and LINSOLVE to print E-labels (intermediate line labels) to
label answers. When TRUE, SOLVE, etc. return answers as elements in a
list. (Except when BACKSUBST is set to FALSE, in which case
PROGRAMMODE:FALSE is also used.)
@end defvar
@c @node REALONLY
@c @unnumberedsec phony
@defvar REALONLY
default: [FALSE] - if TRUE causes ALGSYS to return only
those solutions which are free of %I.
@end defvar
@c @node REALROOTS
@c @unnumberedsec phony
@defun REALROOTS (poly, bound)
finds all of the real roots of the real
univariate polynomial poly within a tolerance of bound which, if less
than 1, causes all integral roots to be found exactly. The parameter
bound may be arbitrarily small in order to achieve any desired
accuracy. The first argument may also be an equation. REALROOTS sets
MULTIPLICITIES, useful in case of multiple roots. REALROOTS(poly) is
equivalent to REALROOTS(poly,ROOTSEPSILON). ROOTSEPSILON[1.0E-7] is a
real number used to establish the confidence interval for the roots.
Do EXAMPLE(REALROOTS); for an example.
@end defun
@c @node RHS
@c @unnumberedsec phony
@defun RHS (eqn)
the right side of the equation eqn.
@end defun
@c @node ROOTSCONMODE
@c @unnumberedsec phony
@defvar ROOTSCONMODE
default: [TRUE] - Determines the behavior of the
ROOTSCONTRACT command. Do DESCRIBE(ROOTSCONTRACT); for details.
@end defvar
@c @node ROOTSCONTRACT
@c @unnumberedsec phony
@defun ROOTSCONTRACT (exp)
converts products of roots into roots of products.
For example,
@example
ROOTSCONTRACT(SQRT(X)*Y^(3/2)) ==> SQRT(X*Y^3)
@end example
When
RADEXPAND is TRUE and DOMAIN is REAL (their defaults), ROOTSCONTRACT
converts ABS into SQRT, e.g.
@example
ROOTSCONTRACT(ABS(X)*SQRT(Y)) ==> SQRT(X^2*Y)
@end example
There is an option ROOTSCONMODE (default value TRUE),
affecting ROOTSCONTRACT as follows:
@example
Problem Value of Result of applying
ROOTSCONMODE ROOTSCONTRACT
X^(1/2)*Y^(3/2) FALSE (X*Y^3)^(1/2)
X^(1/2)*Y^(1/4) FALSE X^(1/2)*Y^(1/4)
X^(1/2)*Y^(1/4) TRUE (X*Y^(1/2))^(1/2)
X^(1/2)*Y^(1/3) TRUE X^(1/2)*Y^(1/3)
X^(1/2)*Y^(1/4) ALL (X^2*Y)^(1/4)
X^(1/2)*Y^(1/3) ALL (X^3*Y^2)^(1/6)
@end example
The above examples and more may be tried out by typing
@example
EXAMPLE(ROOTSCONTRACT);
@end example
When ROOTSCONMODE is FALSE, ROOTSCONTRACT contracts only wrt rational
number exponents whose denominators are the same. The key to the
ROOTSCONMODE:TRUE$ examples is simply that 2 divides into 4 but not
into 3. ROOTSCONMODE:ALL$ involves taking the lcm (least common multiple)
of the denominators of the exponents.
ROOTSCONTRACT uses RATSIMP in a manner similar to LOGCONTRACT (see the
manual).
@end defun
@c @node ROOTSEPSILON
@c @unnumberedsec phony
@defvar ROOTSEPSILON
default: [1.0E-7] - a real number used to establish the
confidence interval for the roots found by the REALROOTS function.
@end defvar
@c @node SOLVE
@c @unnumberedsec phony
@defun SOLVE (exp, var)
solves the algebraic equation exp for the variable
var and returns a list of solution equations in var. If exp is not an
equation, it is assumed to be an expression to be set equal to zero.
Var may be a function (e.g. F(X)), or other non-atomic expression
except a sum or product. It may be omitted if exp contains only one
variable. Exp may be a rational expression, and may contain
trigonometric functions, exponentials, etc. The following method is
used:
Let E be the expression and X be the variable. If E is linear in X
then it is trivially solved for X. Otherwise if E is of the form
A*X**N+B then the result is (-B/A)**(1/N) times the Nth roots of
unity.
If E is not linear in X then the gcd of the exponents of X in E (say
N) is divided into the exponents and the multiplicity of the roots is
multiplied by N. Then SOLVE is called again on the result.
If E factors then SOLVE is called on each of the factors. Finally
SOLVE will use the quadratic, cubic, or quartic formulas where
necessary.
In the case where E is a polynomial in some function of the variable
to be solved for, say F(X), then it is first solved for F(X) (call the
result C), then the equation F(X)=C can be solved for X provided the
inverse of the function F is known.
BREAKUP[TRUE] if FALSE will cause SOLVE to express the solutions of
cubic or quartic equations as single expressions rather than as made
up of several common subexpressions which is the default.
MULTIPLICITIES[NOT_SET_YET] - will be set to a list of the multiplicities of
the individual solutions returned by SOLVE, REALROOTS, or ALLROOTS.
Try APROPOS(SOLVE) for the switches which affect SOLVE. DESCRIBE may
then by used on the individual switch names if their purpose is not
clear.
SOLVE([eq1, ..., eqn], [v1, ..., vn]) solves a system of simultaneous
(linear or non-linear) polynomial equations by calling LINSOLVE or
ALGSYS and returns a list of the solution lists in the variables. In
the case of LINSOLVE this list would contain a single list of
solutions. It takes two lists as arguments. The first list (eqi,
i=1,...,n) represents the equations to be solved; the second list is a
list of the unknowns to be determined. If the total number of
variables in the equations is equal to the number of equations, the
second argument-list may be omitted. For linear systems if the given
equations are not compatible, the message INCONSISTENT will be
displayed (see the SOLVE_INCONSISTENT_ERROR switch); if no unique
solution exists, then SINGULAR will be displayed. For examples, do
EXAMPLE(SOLVE);
@end defun
@c @node SOLVEDECOMPOSES
@c @unnumberedsec phony
@defvar SOLVEDECOMPOSES
default: [TRUE] - if TRUE, will induce SOLVE to use
POLYDECOMP (see POLYDECOMP) in attempting to solve polynomials.
@end defvar
@c @node SOLVEEXPLICIT
@c @unnumberedsec phony
@defvar SOLVEEXPLICIT
default: [FALSE] - if TRUE, inhibits SOLVE from
returning implicit solutions i.e. of the form F(x)=0.
@end defvar
@c @node SOLVEFACTORS
@c @unnumberedsec phony
@defvar SOLVEFACTORS
default: [TRUE] - if FALSE then SOLVE will not try to
factor the expression. The FALSE setting may be desired in some cases
where factoring is not necessary.
@end defvar
@c @node SOLVENULLWARN
@c @unnumberedsec phony
@defvar SOLVENULLWARN
default: [TRUE] - if TRUE the user will be warned if he
calls SOLVE with either a null equation list or a null variable list.
For example, SOLVE([],[]); would print two warning messages and return
[].
@end defvar
@c @node SOLVERADCAN
@c @unnumberedsec phony
@defvar SOLVERADCAN
default: [FALSE] - if TRUE then SOLVE will use RADCAN
which will make SOLVE slower but will allow certain problems
containing exponentials and logs to be solved.
@end defvar
@c @node SOLVETRIGWARN
@c @unnumberedsec phony
@defvar SOLVETRIGWARN
default: [TRUE] - if set to FALSE will inhibit printing
by SOLVE of the warning message saying that it is using inverse
trigonometric functions to solve the equation, and thereby losing
solutions.
@end defvar
@c @node SOLVE_INCONSISTENT_ERROR
@c @unnumberedsec phony
@defvar SOLVE_INCONSISTENT_ERROR
default: [TRUE] - If TRUE, SOLVE and
LINSOLVE give an error if they meet up with a set of inconsistent
linear equations, e.g. SOLVE([A+B=1,A+B=2]). If FALSE, they return []
in this case. (This is the new mode, previously gotten only by
calling ALGSYS.)
@end defvar
@c @node ZRPOLY
@c @unnumberedsec phony
@defun ZRPOLY
- The IMSL ZRPOLY routine for finding the zeros of simple
polynomials (single variable, real coefficients, non-negative integer
exponents), using the Jenkins-Traub technique.
To use it, do: LOADFILE("imsl");
The command is POLYROOTS(polynomial);
For more info, do: PRINTFILE("zrpoly.usg");
For a demo do: DEMO("zrpoly.dem");
For general info on MACSYMA-IMSL packages, PRINTFILE(IMSL,USAGE,SHARE2);
@end defun
@c @node ZSOLVE
@c @unnumberedsec phony
@defun ZSOLVE
- For those who can make use of approximate numerical
solutions to problems, there is a package which calls a routine which
has been translated from the IMSL fortran library to solve N
simultaneous non-linear equations in N unknowns. It uses black-box
techniques that probably aren't desirable if an exact solution can be
obtained from one of the smarter solvers (LINSOLVE, ALGSYS, etc). But
for things that the other solvers don't attempt to handle, this can
probably give some very useful results. For documentation, do
PRINTFILE("zsolve.usg");. For a demo do
batch("zsolve.mc")$
@end defun