Definitions for Equations
=========================

 -- Variable: %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).

 -- Variable: 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.

 -- Function: 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.

 -- Function: 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.

 -- Variable: 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.)

 -- Variable: 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.

 -- Function: 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.

 -- Variable: 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.

 -- Function: 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).

          (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)

     Warning: this is a very rudimentary implementation--many safety checks and obvious generalizations are missing.

 -- Variable: 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.

 -- Function: 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.

 -- Variable: 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).

 -- Function: LHS (eqn)
     the left side of the equation eqn.

 -- Function: 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.

          (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]

 -- Variable: LINSOLVEWARN
     default: [TRUE] - if FALSE will cause the message "Dependent equations eliminated" to be suppressed.

 -- Variable: 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.

 -- Variable: MULTIPLICITIES
     default: [NOT_SET_YET] - will be set to a list of the multiplicities of the individual solutions returned by SOLVE or REALROOTS.

 -- Function: 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.

          (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

 -- Function: 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.

 -- Variable: 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.)

 -- Variable: REALONLY
     default: [FALSE] - if TRUE causes ALGSYS to return only those solutions which are free of %I.

 -- Function: 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.

 -- Function: RHS (eqn)
     the right side of the equation eqn.

 -- Variable: ROOTSCONMODE
     default: [TRUE] - Determines the behavior of the ROOTSCONTRACT command.  Do DESCRIBE(ROOTSCONTRACT); for details.

 -- Function: ROOTSCONTRACT (exp)
     converts products of roots into roots of products. For example,

          ROOTSCONTRACT(SQRT(X)*Y^(3/2)) ==> SQRT(X*Y^3)

     When RADEXPAND is TRUE and DOMAIN is REAL (their defaults), ROOTSCONTRACT converts ABS into SQRT, e.g.

          ROOTSCONTRACT(ABS(X)*SQRT(Y)) ==> SQRT(X^2*Y)

     There is an option ROOTSCONMODE (default value TRUE), affecting ROOTSCONTRACT as follows:

          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)

     The above examples and more may be tried out by typing

          EXAMPLE(ROOTSCONTRACT);

     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).

 -- Variable: ROOTSEPSILON
     default: [1.0E-7] - a real number used to establish the confidence interval for the roots found by the REALROOTS function.

 -- Function: 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);

 -- Variable: SOLVEDECOMPOSES
     default: [TRUE] - if TRUE, will induce SOLVE to use POLYDECOMP (see POLYDECOMP) in attempting to solve polynomials.

 -- Variable: SOLVEEXPLICIT
     default: [FALSE] - if TRUE, inhibits SOLVE from returning implicit solutions i.e. of the form F(x)=0.

 -- Variable: 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.

 -- Variable: 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 [].

 -- Variable: 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.

 -- Variable: 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.

 -- Variable: 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.)

 -- Function: 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);

 -- Function: 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")$