%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
%%  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{bigint},polynomial\TEMPL{bigrational},\\
  polynomial\TEMPL{bigfloat},polynomial\TEMPL{bigcomplex}}  \DOTFILL
specializations of the polynomials


\ABSTRACT
\BF{polynomial\TEMPL{bigint}}, \BF{polynomial\TEMPL{bigrational}},
\BF{polynomial\TEMPL{bigfloat}}, and \BF{polynomial\TEMPL{bigcomplex}} are
classes for computations with polynomials over bigints, bigfloats,
bigrationals and bigcomplexes. These classes are spezializations of the
general \BF{polynomial\TEMPL{T}}, and you can apply all the functions and
operators of the general class \BF{polynomial\TEMPL{T}}. Moreover these
classes support some  additional functionality; especially functions
involving division (or pseudo--division for bigints) are offered.

In the following we will describe the additional functions of the classes
\BF{polynomial\TEMPL{bigint}}, \BF{polynomial\TEMPL{bigrational}},
\BF{polynomial\TEMPL{bigfloat}}, and \BF{polynomial\TEMPL{bigcomplex}}
We will use the parameter \BF{type} to describe the fact that the
corresponding function exists in all four classes and has the same
functionality in each case. Differences in the classes will be explained
separately.

\DESCRIPTION

The specializations use the same representation as the general class
\BF{polynomial\TEMPL{T}}.

\CONS

The specializations support the same constructors as the general type.


\BASIC
        
There are automatic upcasts, which convert a \BF{polynomial\TEMPL{bigint}}
to a \BF{polynomial\TEMPL{bigrational}}, a \BF{polynomial\TEMPL{bigfloat}} or
a \BF{polynomial\TEMPL{bigcomplex}}. In the same way conversions from a
\BF{polynomial\TEMPL{bigrational}} to a \BF{polynomial\TEMPL{bigfloat}} or
a \BF{polynomial\TEMPL{bigcomplex}} and from a
\BF{polynomial\TEMPL{bigfloat}} to a
\BF{polynomial\TEMPL{bigcomplex}} are supported. Thus it is possible to
compute e.g.~the complex roots of a \BF{polynomial\TEMPL{bigint}} without
having to convert it to a \BF{polynomial\TEMPL{bigcomplex}} explicitly.


\ARTH

In addition to the operators of \BF{polynomial\TEMPL{T}} the following
operators are overloaded:

\begin{tabular}{|c|rcl|l|}\hline
binary & polynomial\TEMPL{type} & \MATH{op} & polynomial\TEMPL{type} 
& \MATH{op\IN\{\TT{/},\TT{\%}\}}\\\hline
binary with & polynomial\TEMPL{type} & \MATH{op} & polynomial\TEMPL{type}
& \MATH{op\IN\{\TT{/=},\TT{\%=}\}}\\
assignment & & & &\\\hline
binary & polynomial\TEMPL{type} & \MATH{op} & type
& \MATH{op \IN\{\TT{/}\}}\\\hline
binary with & polynomial\TEMPL{type} & \MATH{op} & type
& \MATH{op \IN\{\TT{/=}\}}\\
assignment & & & &\\\hline
\end{tabular}

Note that over the bigints these operators involve pseudo--division. So do
the following functions which can be used instead of the operators to avoid
copying. (Let \MATH{f} be of type \BF{polynomial\TEMPL{type}}.):

\fcode{void }{div\_rem}{polynomial\TEMPL{type} \& q\k const
        polynomial\TEMPL{type} \& r\k const polynomial\TEMPL{type} \& f\k
        const polynomial\TEMPL{type} \& g}{ 
        \MATH{f = q \CDOT g + r}, where \MATH{r.\TT{degree}() <
        g.\TT{degree}()}.} 

\fcode{void }{divide}{polynomial\TEMPL{type} \& q\k const polynomial\TEMPL{type} \& f\k const polynomial\TEMPL{type} \& g}{
        Computes a polynomial \MATH{q}, such that \MATH{(f - q \CDOT
        g).\TT{degree}() < g.\TT{degree}()}.}

\fcode{void }{divide}{polynomial\TEMPL{type} \& q\k const
        polynomial\TEMPL{type} \& f\k const type \& a}{ 
        \MATH{q = f/a}; for \BF{polynomial\TEMPL{bigint}} the
        lidia\_error\_handler is invoked, if \MATH{a} does not divide every
        coefficient of \MATH{f}.}
        
\fcode{void }{remainder}{polynomial\TEMPL{type} \& r\k const polynomial\TEMPL{type} \& f\k const polynomial\TEMPL{type} \& g}{
        Computes \MATH{r} with \MATH{r \equiv f \pmod{g} } and
        \MATH{r.\TT{degree}() < g.\TT{degree}()}.}

\fcode{void }{power\_mod}{polynomial\TEMPL{type} \& x\k const
  polynomial\TEMPL{type} \& a\k const bigint \& e\k const
  polynomial\TEMPL{type} \& f}{  
  \MATH{x \equiv a^e \pmod{f}}. For \BF{polynomial\TEMPL{bigint}} the
  result may be a multiple of \MATH{x}, since pseudo--division is used to
  reduce a given polynomial mod \MATH{f}.}

\STITLE{Greatest Common Divisor}

\fcode{polynomial\TEMPL{type} }{gcd}{const polynomial\TEMPL{type} \& f\k
  const polynomial\TEMPL{type} \& g}{
  \MATH{d = gcd(f, g)}. Note that these implementations are simply using
  the euclidean algorithm and thus are far from being very efficient
  (especially for \BF{polynomial\TEMPL{bigint}} and
  \BF{polynomial\TEMPL{bigrational}}). For \BF{polynomial\TEMPL{bigint}}
  the euclidean algorithm uses pseudo--division thus possibly producing a
  multiple of the ``real'' gcd, which one would obtain over the
  bigrationals.}

\fcode{polynomial\TEMPL{type} }{xgcd}{polynomial\TEMPL{type} \& s\k
  polynomial\TEMPL{type} \& t\k const polynomial\TEMPL{type} \& f\k
  const polynomial\TEMPL{type} \& g}{
  returns \MATH{gcd(f, g) = s \CDOT f + t \CDOT g}. This function has the
  same efficiency problems as ``gcd''.}

\HIGH

\fcode{bigint }{cont}{const polynomial\TEMPL{bigint} \& f}{
  returns the content of the polynomial \MATH{f}, i.e.~the gcd of all
  coefficients.}

\fcode{polynomial\TEMPL{bigint} }{pp}{const polynomial\TEMPL{bigint} \& f}{
  returns the primitive part of the polynomial \MATH{f}, i.e.~\MATH{f}
  divided by its content.}

\fcode{lidia\_size\_t }{no\_of\_real\_roots}{const polynomial\TEMPL{bigint} \&
  f}{
  return the number of real roots of the polynomial \MATH{f}.}

\STITLE{Integration}

\fcode{void }{integral}{polynomial\TEMPL{type} \& f\k const polynomial\TEMPL{type} \& g}{
  computes \MATH{f}, such that \MATH{f'=g}.}

\fcode{polynomial\TEMPL{type}}{integral}{const
  polynomial\TEMPL{type} \& g}{
  returns a polynomial \MATH{f}, such that \MATH{f'=g}.}

\fcode{bigcomplex }{integral}{const bigfloat \& a\k const bigfloat \& b\k
  const polynomial\TEMPL{bigcomplex} \& f}{
  computes \MATH{\int_{a}^{b}f(x)dx}. Note that this function may also
  be applied to a \BF{polynomial\TEMPL{type}} since there are
  automatic casts to \BF{polynomial\TEMPL{bigcomplex}}.}

\STITLE{Computation of Complex Roots}

Note that the following functions may also be applied to a
\BF{polynomial\TEMPL{type}} since there are automatic casts to
\BF{polynomial\TEMPL{bigcomplex}}.

\fcode{bigcomplex }{root }{const polynomial\TEMPL{bigcomplex} \& f\k
  const bigcomplex \& s}{
  returns an arbitrary root of \MATH{f}, using \MATH{s} as a first
  approximation to the root.}

\fcode{void }{cohen }{const polynomial\TEMPL{bigcomplex} \& f\k bigcomplex
  * w\k int r\k int \& c}{
  computes the zeros of a squarefree polynomial \MATH{f} and stores them in
  the array \MATH{w} starting at position \MATH{c}. If less than \MATH{c +
  }deg(\MATH{f}) elements are allocated for \MATH{w} before calling this
  routine, this results in undefined behaviour. The flag \MATH{r} may be
  set, if all coefficients of the polynomial are real numbers (This will
  speed up the computation). The function will return with \MATH{w[c]}
  being the first unused element of the array \MATH{w}.}

\fcode{void }{roots}{const polynomial\TEMPL{bigcomplex} \& f\k bigcomplex *
  w}{ computes the zeros of an arbitrary polynomial \MATH{f} and stores
  them in the array \MATH{w}. If less than deg(\MATH{f}) elements are
  allocated for \MATH{w} before calling this routine, this results in
  undefined behaviour.}

\IO

The \BF{istream}  operator  \TT{>>}  and  the \BF{ostream}  operator \TT{<<}
are overloaded. The input formats and the output format are the same as for
the general class.

\medskip

\SEEALSO

        \BF{bigint},
        \BF{polynomial\TEMPL{T}}

\NOTES
  Special thanks to all the people who contributed code to these classes,
  i.e.~to Thomas Papanikolaou (polynomial\TEMPL{bigcomplex}), Nigel Smart
  (part of polynomial\TEMPL{bigint}), and Damian Weber (modular computations in
  polynomial\TEMPL{bigint}).

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

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

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

        h = f * g;

        cout << "f * g = "<<h<<endl;

        bigcomplex * zeros = new bigcomplex[h.degree()+1];

        roots (h, zeros);
        cout << "Zeros of "<< h <<"are :"<<endl;
        for (long int i = 0; i< h.degree(); i++)
          cout <<"\n\t"<<zeros[i];
      }
\end{verbatim}

\AUTHOR
        Stefan Neis, Thomas Papanikolaou, Nigel Smart, Damian Weber
\end{lidia_man}
