%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
%%  gf_p_element       LiDIA documentation
%%
%%  This file contains the documentation of the class gf_p_element
%%
%%  Copyright   (c)   1995   by  LiDIA-Group 
%%
%%  Author:  Detlef Anton
%%

\begin{lidia_man}

\markright{\BF{gf\_p\_element}}

\NAME
	\BF{gf\_p\_element} \dotfill an element over a \BF{gf\_p\_base}

\ABSTRACT
	\BF{gf\_p\_element} is a class that provides arithmetics over a polynomial 
	base in a finite field. A variable of type \BF{gf\_p\_element} 
	holds an element over a \BF{gf\_p\_base} represented by a polynomial and
	the corresponding base.

\DESCRIPTION
	A variable of type gf\_p\_element consists of a polynomial \MATH{pol},
	which is of type \linebreak
	\BF{Fp\_polynomial}, and of a reference \MATH{pb} to
	a variable of type \BF{gf\_p\_base}.\\
	If \MATH{f} denotes the polynomial \MATH{pb}\TT{.polynomial()}, then
	\MATH{pol}\TT{.modulus()}\MATH{ = f}\TT{.modulus()} and
	\linebreak
	\MATH{pol}\TT{.degree()}\MATH{ < f}\TT{.degree()}, so that
	\MATH{pol} can be seen as an
	element of \linebreak
	\MATH{(\Z/p\Z[X])/(f \cdot \Z/p\Z[X])}, which is the
	representation a finite field given by \MATH{pb}.


   \CONS

	\fcode{\hfill}{gf\_p\_element}{}{
		initializes only a structure of a \BF{gf\_p\_element}.}
	\fcode{\hfill}{gf\_p\_element}{const gf\_p\_base \& PB}{
		constructs an element by giving a polynomial base \TT{PB}. The
		element is initialized with zero.}
	\fcode{\hfill}{gf\_p\_element}{const gf\_p\_element \& elem}{
		constructs a copy of \TT{elem}.}
	\fcode{\hfill}{\MATH{\sim}gf\_p\_element}{}{}

   \ACCS 

        Let \TT{pe} be an instance of type \BF{gf\_p\_element}.

	\cfcode{const gf\_p\_base \&}{pe.base}{}{
                returns a reference to the variable of type 
		\BF{gf\_p\_base}, which \TT{pe} is element over.}
	\cfcode{const Fp\_polynomial \&}{pe.polynomial\_rep}{}{
		returns the polynomial of the element \TT{pe}.}
        \cfcode{const math\_vector\TEMPL{multi\_bigmod} \&}{pe.vector}{}{
                returns a vector of size and capacity
		\TT{pe.base().field().degree()} consisting of the coefficients
		of \TT{pe.polynomial\_rep()} modulo \MATH{p}, the characteristic of
		the corresponding field.}

   \ASGN

        Let \TT{pe} be an instance of type \BF{gf\_p\_element}.

	\fcode{void}{pe.set\_base}{const gf\_p\_base \& PB}{
		sets the base which \TT{pe} is defined over. \TT{pe} is
		assigned zero.}
	\fcode{void}{pe.set\_polynomial}{const Fp\_polynomial \& p}{
		sets \TT{pe} by assigning \TT{p} to \TT{pe.pol}.\\
		\TT{p} will be reduced modulo \TT{pe.base().irred\_polynomial()}.}
	\fcode{void}{pe.set\_vector}{const math\_vector\TEMPL{multi\_bigmod} \& v}{
		sets \TT{pe} by assigning
		\MATH{\sum\limits_{i=0}^{v.size()} v[i] X^i} to \TT{pe.pol}.\\
		If \TT{v.size()} does not equal
		\TT{pe.base().field().degree()} or if any of the moduli does
		differ, the \TT{lidia\_error\_handler} is invoked.}
	\fcode{void}{pe.assign\_zero}{}{
		\TT{pe $= 0$}.
		If \TT{pe.base()} is undefined, the \TT{lidia\_error\_handler}
		is invoked.}
	\fcode{void}{pe.assign\_one}{}{
		\TT{pe $= 1$}.
		If \TT{pe.base()} is undefined, the \TT{lidia\_error\_handler}
		is invoked.}
	\fcode{void}{pe.assign\_zero}{const gf\_p\_base \& PB}{
		\TT{pe $= 0$}. The polynomial base is set to \TT{PB}.}
	\fcode{void}{pe.assign\_one}{const gf\_p\_base \& PB}{
		\TT{pe $= 1$}. The polynomial base is set to \TT{PB}.}

	The operator $=$ is overloaded. For efficiency reasons, the following
	function is also implemented:

	\fcode{void}{pe.assign}{const gf\_p\_element \& a}{
		\TT{pe $=$ a}.}

   \ARTH

        Let \TT{pe} be an instance of type \BF{gf\_p\_element}.

	The following operators are overloaded and can be used in exactly the same way
	as for machine types in C (e.g.~int) :

	\begin{center}
	\TT{(binary) +, -, *, /, +=, -=, *=, /=}\\ 
	\end{center}

	To avoid copying, these operations can also be performed by
	the following functions:

	\fcode{void}{add}{gf\_p\_element \& c\k const gf\_p\_element \& a\k const gf\_p\_element \& b}{
		\TT{c $=$ a $+$ b}.}
	\fcode{void}{add}{gf\_p\_element \& c\k const multi\_bigmod \& a\k const gf\_p\_element \& b}{
		\TT{c $=$ a $+$ b}, where \TT{a} is considered as \BF{gf\_p\_element}.}
	\fcode{void}{add}{gf\_p\_element \& c\k const gf\_p\_element \& a\k const multi\_bigmod \& b}{
		\TT{c $=$ a $+$ b}, where \TT{b} is considered as \BF{gf\_p\_element}.}
	\fcode{void}{subtract}{gf\_p\_element \& c\k const gf\_p\_element \& a\k const gf\_p\_element \& b}{
		\TT{c $=$ a $-$ b}.}
	\fcode{void}{subtract}{gf\_p\_element \& c\k const multi\_bigmod \& a\k const gf\_p\_element \& b}{
		\TT{c $=$ a $-$ b}, where \TT{a} is considered as \BF{gf\_p\_element}.}
	\fcode{void}{subtract}{gf\_p\_element \& c\k const gf\_p\_element \& a\k const multi\_bigmod \& b}{
		\TT{c $=$ a $-$ b}, where \TT{b} is considered as \BF{gf\_p\_element}.}
	\fcode{void}{multiply}{gf\_p\_element \& c\k const gf\_p\_element \& a\k const gf\_p\_element \& b}{
		\TT{c $=$ a $*$ b}.}
	\fcode{void}{multiply}{gf\_p\_element \& c\k const multi\_bigmod \& a\k const gf\_p\_element \& b}{
		\TT{c $=$ a $*$ b}, where \TT{a} is considered as \BF{gf\_p\_element}.}
	\fcode{void}{multiply}{gf\_p\_element \& c\k const gf\_p\_element \& a\k const multi\_bigmod \& b}{
		\TT{c $=$ a $*$ b}, where \TT{b} is considered as \BF{gf\_p\_element}.}
	\fcode{void}{divide}{gf\_p\_element \& c\k const gf\_p\_element \& a\k const gf\_p\_element \& b}{
		\TT{c $=$ a $/$ b}, if \TT{b $\NEQ$ $0$}. Otherwise the \TT{lidia\_error\_handler} will be invoked.}
	\fcode{void}{divide}{gf\_p\_element \& c\k const multi\_bigmod \& a\k const gf\_p\_element \& b}{
		\TT{c $=$ a $/$ b}, where \TT{a} is considered as \BF{gf\_p\_element}, if \TT{b $\NEQ$ $0$}.
		Otherwise the \TT{lidia\_error\_handler} will be invoked.}
	\fcode{void}{divide}{gf\_p\_element \& c\k const gf\_p\_element \& a\k const multi\_bigmod \& b}{
		\TT{c $=$ a $/$ b}, where \TT{b} is considered as \BF{gf\_p\_element}, if \TT{b $\NEQ$ $0$}.
		Otherwise the \TT{lidia\_error\_handler} will be invoked.}

	\fcode{void}{pe.negate}{}{
		\TT{pe $=$ $-$pe}.}
  	\fcode{void}{negate}{gf\_p\_element \& a\k const gf\_p\_element \& b}{
		\TT{a $=$ $-$b}.}
	\fcode{void}{pe.invert}{}{
		\TT{pe $=$ pe$^{-1}$}.}
	\fcode{void}{invert}{gf\_p\_element \& a\k const gf\_p\_element \& b}{
		\TT{a $=$ b$^{-1}$}.}
	\fcode{gf\_p\_element}{inverse}{const gf\_p\_element \& a}{
		returns \TT{a$^{-1}$}.}
	\fcode{void}{square}{gf\_p\_element \& a\k const gf\_p\_element \& b}{
		\TT{a $=$ b$^{2}$}.}
	\fcode{void}{pe.power}{const gf\_p\_element \& a\k const bigint \& e}{
		\TT{pe $=$ a$^{\tt e}$}.}
	\fcode{void}{power}{gf\_p\_element \& c\k const gf\_p\_element \& a\k const bigint \& e}{
		\TT{c $=$ a$^{\tt e}$}.}
	\fcode{void}{pth\_power}{gf\_p\_element \& c\k const gf\_p\_element \& a\k lidia\_size\_t e}{
                \TT{c $=$ a$^{({\tt p}^{{\tt e}})}$}, where \TT{p} is the characteristic of the 
		corresponding field.}

   \COMP

        Let \TT{pe} be an instance of type \BF{gf\_p\_element}.

	The  binary operators $==$,  $!\! =$ are overloaded.

	\cfcode{bool}{pe.is\_zero}{}{
		returns \TT{true} if \TT{pe} is zero, \TT{false} otherwise.}
	\cfcode{bool}{pe.is\_one}{}{
		returns \TT{true} if \TT{pe} is one, \TT{false} otherwise.}

   \BASIC

        Let \TT{pe} be an instance of type \BF{gf\_p\_element}.

	\fcode{void}{pe.randomize}{}{
		let \TT{pe} be a random element over the polynomial base
		\TT{pe.base()}.	If the latter is not defined, the
		\TT{lidia\_error\_handler} is invoked.}
	\fcode{void}{swap}{gf\_p\_element \& a\k gf\_p\_element \& b}{
		exchanges the values of \TT{a} and \TT{b}.}


   \HIGH

        Let \TT{pe} be an instance of type \BF{gf\_p\_element}.

        \cfcode{bigint}{pe.compute\_order}{}{
		returns the order of \TT{pe}.}
	\fcode{bigint}{compute\_order}{const gf\_p\_element \& a}{
		returns the order of \TT{a}.}
        \cfcode{multi\_bigmod}{pe.compute\_trace}{}{
		returns the trace of \TT{pe}.}
	\fcode{multi\_bigmod}{compute\_trace}{const gf\_p\_element \& a}{
		returns the trace of \TT{a}.}
        \cfcode{multi\_bigmod}{pe.compute\_norm}{}{
		returns the norm of \TT{pe}.}
	\fcode{multi\_bigmod}{compute\_norm}{const gf\_p\_element \& a}{
		returns the norm of \TT{a}.}
	\cfcode{bool}{pe.is\_primitive\_element}{}{
		checks whether the order of \TT{pe} in the multiplicative
		group is $p^{n}-1$, where $p$ is the characteristic and
		$n$ is the degree of the corresponding field.}
	\fcode{bool}{is\_primitive\_element}{const gf\_p\_element \& a}{
		checks whether the order of \TT{a} in the multiplicative
                group is $p^{n}-1$, where $p$ is the characteristic and
                $n$ is the degree of the corresponding field.}
        \cfcode{bool}{pe.is\_free\_element}{}{
		checks whether \TT{pe} is a free element, 
		that means a normal base generator.}
	\fcode{bool}{is\_free\_element}{const gf\_p\_element \& a}{
                checks whether \TT{a} is a free element,
                that means a normal base generator.}
%	\fcode{void}{transform\_n\_to\_p}{gf\_p\_element \& a\k const gf\_n\_element \& b}{
%		transforms \TT{b} into \TT{a} by using \TT{b} $\! $.$\! $ base() $\rightarrow$ \TT{matrix\_n\_to\_p()}.}
%	\fcode{void}{transform\_p\_to\_n}{gf\_n\_element \& a\k const gf\_p\_element \& b}{
%               transforms \TT{b} into \TT{a} by using \TT{a} $\! $.$\! $ base() $\rightarrow$ \TT{matrix\_p\_to\_n()}.}



\IO

    The \BF{istream} operator $>\! >$ and the \BF{ostream} operator $<\! <$ are overloaded.

    \fcode{istream \&}{operator $>\! >$}{istream \& in\k gf\_p\_element \& pe}{
	reads an element over a polynomial base from \BF{istream}
	\TT{in}. The input must be of the form ``(f)'', where \TT{f} is a
	polynomial of type \BF{Fp\_polynomial}. \TT{f} will be reduced modulo
	\TT{pe.base().irred\_polynomial()}. If either the polynomial base
	of \TT{pe} is undefined or \TT{f.modulus()} does not equal the
	characteristic of the corresponding field, the
	\TT{lidia\_error\_handler} is invoked.}

    \fcode{ostream \&}{operator $<\! <$}{ostream \& out\k const gf\_p\_element \& pe}{
	writes the element \TT{pe} over a polynomial base to \BF{ostream}
	\TT{out} in form of ``(f)'', where \TT{f = pe.polynomial\_rep()}.}

\SEEALSO
	class \BF{galois\_field}

        class \BF{gf\_p\_base}

%        class \BF{gf\_n\_base}
%
%        class \BF{gf\_n\_element}
\EXAMPLES
\begin{verbatim}
 #include <LiDIA/gf_p_element.h>

 int main()
 {

    bigint p;
    lidia_size_t d;
    cout << "Please enter the characteristic "
    cout << "of the finite field : "; cin >> p;
    cout << "Please enter the degree of the "
    cout << "finite field : "; cin >> d;

    galois_field field(p, d);
    cout << "This field has " << field.number_of_elements();
    cout <<" elements.\n";

    gf_p_base base(field);
    cout << "The polynomial base is ";
    base.irred_polynomial().pretty_print();
    cout << "\n";

    gf_p_element elem = base.gen_primitive_element();
    cout << elem << " is a primitive element in this field.\n";
 }
\end{verbatim}


\AUTHOR
        Detlef Anton, Franz-Dieter Berger, Stefan Neis, Thomas Pfahler

\end{lidia_man}

