%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
%%  polynomial.tex       LiDIA documentation
%%
%%  This file contains the documentation of the template class polynomial
%%
%%  Copyright   (c)   1996   by  LiDIA-Group 
%%
%%  Authors: Stefan Neis, adding some own code to rewritten code of 
%%  Victor Shoup, Thomas Papanikolaou, Nigel Smart, Damian Weber who each
%%  contributed some part of the original code. 
%%

\markright{\BF{polynomial}}
\begin{lidia_man}

\NAME
\BF{polynomial\TEMPL{T}}  \DOTFILL parameterized polynomials


\ABSTRACT
\BF{polynomial\TEMPL{T}} is a class for doing elementary polynomial
computations. A variable of type \BF{polynomial\TEMPL{T}} can hold
polynomials of arbitrary degree.

\DESCRIPTION

A variable \MATH{f} of type \BF{polynomial\TEMPL{T}} is internally
represented as a coefficient array with entries of type \BF{T}. The
zero polynomial is a zero length array; otherwise, \MATH{f[0]} is the
constant-term, and \MATH{f[f.degree()]} is the leading coefficient, which
must always be non-zero.

\CONS

\fcode{ct}{polynomial\TEMPL{T}}{}{
  initializes a zero polynomial.}

\fcode{ct}{polynomial\TEMPL{T}}{T x}{
  initializes with the constant polynomial \MATH{x}.}

\fcode{ct}{polynomial\TEMPL{T}}{const T * v, lidia\_size\_t d}{
  initializes with the polynomial \MATH{\SUM{i=0}{d}{v_ix^i}}.
  The behaviour of this constructor is undefined if the array \MATH{v} has
  less than \MATH{d + 1} elements.}
  
\fcode{ct}{polynomial\TEMPL{T}}{const vector\TEMPL{T} v}{
  initializes with the polynomial
  \MATH{\SUM{i=0}{v.\TT{get\_size()}-1}{v_ix^i}}} 

\fcode{ct}{polynomial\TEMPL{T}}{const polynomial\TEMPL{T} \& f}{
    initializes with a copy of the polynomial \MATH{f}.}

\fcode{dt}{\MATH{\sim}polynomial\TEMPL{T}}{}{}



\ASGN

Let \MATH{f} be of type \BF{polynomial\TEMPL{T}}.
        
The operator \TT{=} is overloaded. For efficiency reasons, the following
functions are also implemented:

\fcode{void }{f.assign\_zero}{}{
  sets \MATH{f} to the zero polynomial.}

\fcode{void }{f.assign\_one}{}{
  sets \MATH{f} to the polynomial \MATH{1 \CDOT x^0}.}

\fcode{void }{f.assign\_x}{}{
  sets \MATH{f} to the polynomial \MATH{1 \CDOT x^1+0 \CDOT x^0}.}

\fcode{void }{f.assign}{const T \& a}{
  \MATH{f = a \CDOT x^0}.}

\fcode{void }{f.assign}{const polynomial\TEMPL{T} \& g}{
        \MATH{f = g}.}


\BASIC
        
Let \MATH{f} be of type \BF{polynomial\TEMPL{T}}.

\fcode{void }{f.remove\_leading\_zeros}{}{
  removes leading zeros. Afterwards, if \MATH{f} is not the zero
  polynomial, \MATH{f.}\TT{lead\_coeff()} \MATH{\NEQ\; 0}.}


\ACCS

Let \MATH{f} be of type \BF{polynomial\TEMPL{T}}.

\cfcode{lidia\_size\_t }{f.degree}{}{
  returns the degree of \MATH{f}. For the zero polynomial we return
  \MATH{-1}.} 

\fcode{void }{f.set\_degree}{lidia\_size\_t n}{
  sets the degree of the polynomial to \MATH{n}. If the polynomial is not
  modified (by one of the following functions) in such a way that it really
  has this pretended degree before doing computations with the polynomial,
  this leads to undefined behaviour. The value of \MATH{f} is always
  unchanged.}

\fcode{bigint \& }{f.operator[]}{lidia\_size\_t i}{
  returns a reference to the coefficient of \MATH{x^{i}} of \MATH{f}.
  \MATH{i} must be non-negative and less than or equal to the degree of
  \MATH{f}. This operator may be used to assign a value to a coefficient.}

\fcode{int }{f.set\_data}{const T * d\k lidia\_size\_t l}{
  sets \MATH{f} to the polynomial \MATH{\SUM{i=0}{l-1}{v_ix^i}}.
  The behaviour of this function is undefined if the array \MATH{v} has
  less than \MATH{l} elements.}

\cfcode{T* }{f.get\_data}{}{
  returns a pointer to a copy of the array of coefficients of \MATH{f}.
  If \MATH{f} is the zero polynomial it returns a pointer to an array with
  one element which is zero.}

\cfcode{bigint }{f.lead\_coeff}{}{
  returns \MATH{f[f.}\TT{degree()}\MATH{]}, i.e.~the leading coefficient of
  \MATH{f}; returns zero if \MATH{f} is the zero polynomial.}

\cfcode{bigint }{f.const\_term}{}{
  returns \MATH{f[0]}, i.e.~the constant term of \MATH{f};
  returns zero if \MATH{f} is the zero polynomial.}

\ARTH

The following operators are overloaded:

\begin{tabular}{|c|rcl|l|}\hline
unary & & \MATH{op} & polynomial\TEMPL{T} & \MATH{op\IN\{\TT{-}\}} \\\hline
binary & polynomial\TEMPL{T} & \MATH{op} & polynomial\TEMPL{T} 
& \MATH{op\IN\{\TT{+},\TT{-},\TT{*}\}}\\\hline
binary with & polynomial\TEMPL{T} & \MATH{op} & polynomial\TEMPL{T}
& \MATH{op\IN\{\TT{+=},\TT{-=},\TT{*=}\}}\\
assignment & & & &\\\hline
binary & polynomial\TEMPL{T} & \MATH{op} & T
& \MATH{op \IN\{\TT{+},\TT{-},\TT{*}\}}\\\hline
binary & T & \MATH{op} & polynomial\TEMPL{T}
& \MATH{op \IN\{\TT{+},\TT{-},\TT{*}\}}\\\hline
binary with & polynomial\TEMPL{T} & \MATH{op} & T
& \MATH{op \IN\{\TT{+=},\TT{-=},\TT{*=}\}}\\
assignment & & & &\\\hline
\end{tabular}

To avoid copying, these operations can also be performed by
the following functions (Let \MATH{f} be of type \BF{polynomial\TEMPL{T}}).

%\fcode{void }{f.negate}{}{
%       \MATH{f = -f}.}
\fcode{void }{negate}{polynomial\TEMPL{T} \& g\k const polynomial\TEMPL{T} \& h}{
        \MATH{g = -h}.}

\fcode{void }{add}{polynomial\TEMPL{T} \& f\k const polynomial\TEMPL{T} \& g\k const polynomial\TEMPL{T} \& h}{
        \MATH{f = g + h}.}
\fcode{void }{add}{polynomial\TEMPL{T} \& f\k const polynomial\TEMPL{T} \& g\k const T \& a}{
        \MATH{f = g + a}.}
\fcode{void }{add}{polynomial\TEMPL{T} \& f\k const T \& a\k const polynomial\TEMPL{T} \& g}{
        \MATH{f = g + a}.}

\fcode{void }{subtract}{polynomial\TEMPL{T} \& f\k const polynomial\TEMPL{T} \& g\k const polynomial\TEMPL{T} \& h}{
        \MATH{f = g - h}.}
\fcode{void }{subtract}{polynomial\TEMPL{T} \& f\k const polynomial\TEMPL{T} \& g\k const T \&a}{
        \MATH{f = g - a}.}
\fcode{void }{subtract}{polynomial\TEMPL{T} \& f\k const T \& a\k const polynomial\TEMPL{T} \& g}{
        \MATH{f = a - g}.}

\fcode{void }{multiply}{polynomial\TEMPL{T} \& f\k const polynomial\TEMPL{T} \& g\k const polynomial\TEMPL{T} \& h}{
        \MATH{f = g \CDOT h}.}
\fcode{void }{multiply}{polynomial\TEMPL{T} \& f\k const polynomial\TEMPL{T} \& g\k const T \& a}{
        \MATH{f = g \CDOT a}.}
\fcode{void }{multiply}{polynomial\TEMPL{T} \& f\k const T \& a\k const polynomial\TEMPL{T} \& g}{
        \MATH{f = g \CDOT a}.}

\fcode{void }{power}{polynomial\TEMPL{T} \& f\k const polynomial\TEMPL{T}
  \& g\k const bigint \& e}{ 
  \MATH{f = g^e}.}

\COMP

The  binary operators \TT{==}, \TT{!=} are overloaded.

Let \MATH{f} be an instance of type \BF{polynomial\TEMPL{T}}.

\cfcode{bool }{f.is\_zero}{}{
  returns \TRUE\  if \MATH{f} is the zero polynomial; \FALSE\  otherwise.}

\cfcode{bool }{f.is\_one}{}{
  returns \TRUE\  if \MATH{f} is a constant polynomial and the
  constant coefficient equals \MATH{1}; \FALSE\  otherwise.}

\cfcode{bool }{f.is\_x}{}{
  returns \TRUE\  if \MATH{f} is a polynomial of degree \MATH{1}, the
  leading coefficient equals \MATH{1} and the constant coefficient equals
  \MATH{0}; \FALSE\  otherwise.}

%\cfcode{bool }{f.is\_monic}{}{
%       returns \TRUE\  if \MATH{f} is a monic polynomial, i.e.~if \MATH{f} is not
%       the zero polynomial and \MATH{f.lead\_coeff() = 1}.}
%
%
\HIGH

        Let \MATH{f} be an instance of type \BF{polynomial\TEMPL{T}}.

\fcode{void }{derivative}{polynomial\TEMPL{T} \& f\k const
  polynomial\TEMPL{T} \& g}{
  \MATH{f = g'}\ , i.e.~the (formal) derivative of \MATH{g}.}
\fcode{base\_polynomial\TEMPL{T}}{derivative}{const base\_polynomial\TEMPL{T}
  \& g}{
  returns \MATH{g'}, i.e.~the (formal) derivative of \MATH{g}.}

\cfcode{bigint }{f.operator()}{const bigint \& a}{
        returns \MATH{\SUM{i=0}{f.\TT{degree()}}f_{i} \CDOT a^{i}}, where
        \MATH{f = \SUM{i=0}{f.\TT{degree()}}f_{i} \CDOT x^{i}}.}
%
% \fcode{void }{swap}{polynomial\TEMPL{T} \& f\k polynomial\TEMPL{T} \& g}{
%    swaps the values of \MATH{f} and \MATH{g}.}

\IO

The \BF{istream}  operator  \TT{>>}  and  the \BF{ostream}  operator \TT{<<}
are overloaded.\\
Let \MATH{f = \SUM{i=0}{n}{f_{i} \CDOT x^{i}}} where \MATH{n}
denotes the degree of the polynomial \MATH{f}.
        
We support two different I/O-formats:
\begin{itemize}
\item
  The more simple format is 
\begin{verbatim} [ f_0 f_1 ... f_n ] \end{verbatim}
with elements f\_i of type \BF{T}. Leading zeros will be removed at input.

\item
  The more comfortable format (especially for sparse polynomials) is

\begin{verbatim} f_n * x^n + ... + f_2 * x^2 + f_1 * x + f_0 \end{verbatim} 
At output, zero coefficients are omitted, as well as you may omit them at
input. 
In fact the input is even much less restrictive: you may ommit the ``*''
and you also may permute the monomials, writing e.g.~\MATH{a_0 + a_n x^n +
  a_1*x +\cdots}.
\end{itemize}
Both formats may be used as input - they are distiguished automatically by the 
first character of the input, being `[' or not `['.
The \BF{ostream}  operator \TT{<<} always uses the second format.
% The second output format can be obtained using the member function
% \cfcode{void}{f.pretty\_print}{ostream \& os}{}

\medskip

\SEEALSO
        \BF{polynomial\TEMPL{bigint}}, \BF{polynomial\TEMPL{bigrational}},
        \BF{polynomial\TEMPL{bigfloat}},\\
        \BF{polynomial\TEMPL{bigcomplex}}, \BF{Fp\_polynomial}

\NOTES
  Special thanks to Victor Shoup and Thomas Papanikolaou, who gave
  permission to rewrite and include their code.

\BUGS
Since this is a template class, I have to rely on other classes for reading
input and producing output. Therefore I don't see, how to prevent ``ugly''
output like \begin{verbatim} 3 * x^4 + -5 * x^2 + -7 .\end{verbatim}

\EXAMPLES
\begin{verbatim}
      #include <LiDIA/polynomial.h>

      main()
      {
        polynomial<bigfloat> f, g, h;

        cout << "Please enter f : "; cin >> f;
        cout << "Please enter g : "; cin >> g;

        h = f * g;

        cout << "f * g   =  "<<h<<endl;;
      }
\end{verbatim}

\AUTHOR
Stefan Neis, Thomas Papanikolaou, Victor Shoup
\end{lidia_man}
