\chapter[RANDPOLY: Random polynomials]%
{RANDPOLY: A random polynomial generator}
\label{RANDPOLY}
\typeout{{RANDPOLY: A random polynomial generator}}

{\footnotesize
\begin{center}
Francis J. Wright \\
School of Mathematical Sciences, Queen Mary and Westfield College \\
University of London \\
Mile End Road \\
London E1 4NS, England \\[0.05in]
e--mail: F.J.Wright@QMW.ac.uk
\end{center}
}
\ttindex{RANDPOLY}

The operator {\tt RANDPOLY}\ttindex{RANDPOLY} requires at least one
argument corresponding to the polynomial variable or variables, which
must be either a single expression or a list of expressions.
In effect, {\tt RANDPOLY} replaces each input expression by an
internal variable and then substitutes the input expression for the
internal variable in the generated polynomial (and by default expands
the result as usual).  The rest of this document
uses the term ``variable'' to refer to a general input expression or
the internal variable used to represent it, and all references to the
polynomial structure, such as its degree, are with respect to these
internal variables.  The actual degree of a generated polynomial might
be different from its degree in the internal variables.

By default, the polynomial generated has degree 5 and contains 6
terms.  Therefore, if it is univariate it is dense whereas if it is
multivariate it is sparse.

\section{Optional arguments}

Other arguments can optionally be specified, in any order, after the
first compulsory variable argument.  All arguments receive full
algebraic evaluation, subject to the current switch settings etc.  The
arguments are processed in the order given, so that if more than one
argument relates to the same property then the last one specified
takes effect.  Optional arguments are either keywords or equations
with keywords on the left.

In general, the polynomial is sparse by default, unless the keyword
{\tt dense}\index{randpoly ! {\tt dense}} is specified as an optional
argument.  (The keyword {\tt sparse}\index{randpoly ! {\tt sparse}} is
also accepted, but is the default.)  The default degree can be changed
by specifying an optional argument of the form\index{randpoly
! {\tt degree}}
\begin{center}
  {\tt degree = {\it natural number}}.
\end{center}
In the multivariate case this is the total degree, {\em i.e.\ }the sum of
the degrees with respect to the individual variables.
More complicated monomial degree bounds can be constructed by using
the coefficient function described below to return a monomial or
polynomial coefficient expression.  Moreover, {\tt randpoly} respects
internally the \REDUCE\ ``asymptotic'' commands {\tt let}, {\tt weight}
{\em etc.\ }described in section~\ref{sec-asymp}, which can be used
to exercise additional control over the polynomial generated.

In the sparse case (only), the default maximum number of terms
generated can be changed by specifying an optional argument of the
form\index{randpoly ! {\tt terms}}
\begin{center}
  {\tt terms = {\it natural number}}.
\end{center}
The actual number of terms generated will be the minimum of the value
of {\tt terms} and the number of terms in a dense polynomial of the
specified degree, number of variables, {\em etc.}


\section{Advanced use of RANDPOLY}

The default order (or minimum or trailing degree) can be changed by
specifying an optional argument of the form\index{randpoly ! {\tt ord}}
\begin{center}
  {\tt ord = {\it natural number}}.
\end{center}
The order normally defaults to 0.

The input expressions to {\tt randpoly} can also be
equations, in which case the order defaults to 1 rather than 0.  Input
equations are converted to the difference of their two sides before
being substituted into the generated polynomial.  This makes it easy
to generate polynomials with a specified zero -- for example
\begin{center}\tt
  randpoly(x = a);
\end{center}
generates a polynomial that is guaranteed to vanish at $x = a$, but is
otherwise random.

The operator {\tt randpoly} accepts two further optional arguments in
the form of equations with the keywords {\tt coeffs}
\index{randpoly ! {\tt coeffs}} and {\tt expons}\index{randpoly ! {\tt expons}}
on the left.  The right sides of each of these equations must evaluate
to objects that can be applied as functions of no variables.  These
functions should be normal algebraic procedures; the {\tt coeffs}
procedure may return any algebraic expression, but the {\tt expons}
procedure must return an integer.  The values returned by
the functions should normally be random, because it is the randomness
of the coefficients and, in the sparse case, of the exponents that
makes the constructed polynomial random.

A convenient special case is to use the function {\tt rand} on the
right of one or both of these equations; when called with a single
argument {\tt rand} returns an anonymous function of no variables that
generates a random integer.  The single argument of {\tt rand} should
normally be an integer range in the form $a~..~b$, where $a$, $b$ are
integers such that $a < b$.   For example, the {\tt expons} argument might
take the form
\begin{center}\tt
  expons = rand(0~..~n)
\end{center}
where {\tt n} will be the maximum degree with respect to each variable
{\em independently}.  In the case of {\tt coeffs} the lower limit will
often be the negative of the upper limit to give a balanced
coefficient range, so that the {\tt coeffs} argument might take the
form
\begin{center}\tt
  coeffs = rand(-n~..~n)
\end{center}
which will generate random integer coefficients in the range $[-n,n]$.

Further information on the the auxiliary functions of RANDPOLY can be
found in the extended documentation and examples.

\section{Examples}
\label{sec:Examples}

\begin{verbatim}
randpoly(x);

       5       4       3       2
 - 54*x  - 92*x  - 30*x  + 73*x  - 69*x - 67


randpoly({x, y}, terms = 20);

    5       4         4       3  2       3         3
31*x  - 17*x *y - 48*x  - 15*x *y  + 80*x *y + 92*x

       2  3      2         2         4         3         2
 + 86*x *y  + 2*x *y - 44*x  + 83*x*y  + 85*x*y  + 55*x*y

                       5       4      3       2
 - 27*x*y + 33*x - 98*y  + 51*y  - 2*y  + 70*y  - 60*y - 10
\end{verbatim}
\newpage
\begin{verbatim}
randpoly({x, sin(x), cos(x)});

                   4            3              3
sin(x)*( - 4*cos(x)  - 85*cos(x) *x + 50*sin(x)

                    2
         - 20*sin(x) *x + 76*sin(x)*x + 96*sin(x))
\end{verbatim}

