%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
%%  module.tex      LiDIA documentation
%%
%%  This file contains the documentation of the class module
%%
%%  Copyright (c) 1995 by the LiDIA Group
%%
%%  Authors: Stefan Neis
%%

\begin{lidia_man}
\markright{\BF{module/alg\_ideal}}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\NAME
\BF{module/alg\_ideal} \DOTFILL free \MATH{\Z}--modules and ideals in algebraic number fields

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\ABSTRACT
\BF{module} is a class for doing module arithmetic in number fields or more
precisely in orders. \BF{alg\_ideal} is a class for doing ideal arithmetic. They
support for example arithmetic operations (including pseudo--division),
comparisons, and the computation of the ring of multipliers of a module.

Both classes are essentially the same, however for ideals multiplication
and divsion can use faster algorithms than for modules.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\DESCRIPTION
A \BF{module} as well as an \BF{alg\_ideal} consists of a triple \MATH{(num,
  den, O)}, where the nu\-me\-ra\-tor \MATH{num = (\UL{num}_0, \dots,
\UL{num}_{m-1})} is a \BF{bigmod\_matrix} of size \MATH{n}\TIMES\MATH{m}
(n is the degree of the number field) with coefficients from \MATH{\Z / M
  \Z} for some \MATH{M}, the denominator \MATH{den} is a \BF{bigint}, and
\MATH{O} is a pointer to the \BF{nf\_base}, that is used to represent the
module. The \BF{module}(\BF{alg\_ideal}) \MATH{(num, den, O)} represents
the module (ideal)
\latex{
\[\sum_{j=0}^{m-1}{\FRAC{1}{den}}\LEFT(\sum_{i=0}^{n-1}{num_{ij}}w_i\RIGHT)
\CDOT \Z+M O,
\]
}
\html{\begin{verbatim}
                m - 1      -  n - 1            -
                -----     /   -----             \
                \      1  |   \                 |
                 )    --- |    )   num_ij  w_i  |  Z  + M O,
                /     den |   /                 |
                -----     \   -----             /
               j = 0       -  i = 0            -
\end{verbatim}}
where \MATH{w_i} are the base elements of the \BF{nf\_base}
pointed to by \MATH{O}. The components of the numerator \MATH{num} and
the denominator \MATH{den} of a \BF{module} are always coprime,
the denominator \MATH{den} is positive.

Note that since each ideal is a module as well, \BF{alg\_ideal} inherits
from \BF{module}, so that you can use all functions described for modules
for \BF{alg\_ideals} as well. Note however, that a couple of extra
functions are available for \BF{alg\_ideals}.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\CONS
\fcode{ct}{module}{nf\_base * O1 = nf\_base::current\_base}
{
initializes with the zero ideal.}

\fcode{ct}{module}{const alg\_number \& a\k const alg\_number \& b = 0}
{
initializes with the ideal generated by the algebraic numbers \MATH{a} and
\MATH{b}. This constructor will be removed in the next release.}

\fcode{ct}{module}{const base\_matrix\TEMPL{bigint} \& A\k const bigint \&
  d = 1\k nf\_base * O1 = nf\_base::current\_base} 
{
  initializes the module with the ideal(!) generated by the columns
  of \MATH{A} divided by \MATH{d}. If the number of rows of \MATH{A} does not
  match the degree of the number field with the base O1 is pointing to, the
  \TT{lidia\_error\_handler} will be invoked. The behaviour of this
  constructor will change in the next release. Please use the class
  \BF{alg\_ideal} for representing ideals.}

\fcode{ct}{module}{const bigmod\_matrix \& A\k const bigint \& d = 1\k
  nf\_base * O1 = nf\_base::current\_base}  
{
  initializes with the \MATH{\Z}--module generated by the columns
  of \MATH{A} and the columns of \MATH{m\CDOT I} divided by \MATH{d}. Here
  \MATH{m} denotes the modulus of the \BF{bigmod\_matrix} and \MATH{I}
  denotes an identity matrix with as many rows as \MATH{A}. If the number
  of rows of \MATH{A} does not match the degree of the number field with
  the base O1 is pointing to, the \TT{lidia\_error\_handler} will be
  invoked.}

\fcode{ct}{module}{const module \& M}
{
initializes with a copy of the module \MATH{M}.}

\fcode{dt}{{\SIM module}}{}{}

\fcode{ct}{alg\_ideal}{nf\_base * O1 = nf\_base::current\_base}
{
initializes with the zero ideal.}

\fcode{ct}{alg\_ideal}{const alg\_number \& a\k const alg\_number \& b = 0}
{
initializes with the ideal generated by the algebraic numbers \MATH{a} and
\MATH{b}.}

\fcode{ct}{alg\_ideal}{const base\_matrix\TEMPL{bigint} \& A\k const bigint \&
  d = 1\k nf\_base * O1 = nf\_base::current\_base} 
{
  initializes with the ideal generated by the columns of \MATH{A}
  (interpreted as algebraic numbers) divided by \MATH{d}. If the number of
  rows of \MATH{A} does not match the degree of the number field with the
  base O1 is pointing to, the \TT{lidia\_error\_handler} will be
  invoked.}

\fcode{ct}{alg\_ideal}{const bigmod\_matrix \& A\k const bigint \& d = 1\k
  nf\_base * O1 = nf\_base::current\_base}  
{
  initializes with the \MATH{\Z}--module generated by the columns
  of \MATH{A} and the columns of \MATH{m\CDOT I} divided by \MATH{d}. Here
  \MATH{m} denotes the modulus of the \BF{bigmod\_matrix} and \MATH{I}
  denotes an identity matrix with as many rows as \MATH{A}. If the number
  of rows of \MATH{A} does not match the degree of the number field with
  the base O1 is pointing to, the \TT{lidia\_error\_handler} will be
  invoked. If the resulting module does not have full rank, we use the
  ideal generated by the numbers of the module, otherwise we assume that
  the matrix really describes an ideal. If this is not true, operations
  using this ideal may lead to wrong results!}

\fcode{ct}{alg\_ideal}{const alg\_ideal \& M}
{
initializes with a copy of the ideal \MATH{M}.}

\fcode{dt}{{\SIM alg\_ideal}}{}{}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\ASGN
Let \MATH{M} be of type \BF{module} or \BF{alg\_ideal}.  The operator
\TT{=} is overloaded. For efficiency reasons, the following functions are
also implemented:\vspace*{1ex}

\fcode{void}{M.assign\_zero}{}
{
\MATH{M = (0)}, i.e.~\MATH{M} is set to the zero ideal.}

\fcode{void}{M.assign\_one}{}
{
\MATH{M = (1)}, i.e.~\MATH{M} is set to the whole order generated by the
base elements of the \BF{nf\_base}.}

\fcode{void}{M.assign\_whole\_order}{}
{
\MATH{M = (1)}.}

\fcode{void}{M.assign}{const bigint \& b}
{
\MATH{M = (b)}, i.e.~\MATH{M} is set to the principal ideal generated by \MATH{b}.}


\fcode{void}{M.assign}{const alg\_number \& b}
{
\MATH{M = (b)}.}

\fcode{void}{M.assign}{const module \& N}
{
  if \MATH{M} is of type \BF{alg\_ideal}, then \MATH{M} is set to the ideal
  generated by the elements of \MATH{N}, otherwise \MATH{M} is set to
  \MATH{N}.}

\fcode{void}{M.assign}{const alg\_ideal \& N}
{
\MATH{M = N}.}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\ACCS
Let \MATH{M} be of type \BF{module} or \BF{alg\_ideal} with \MATH{M = (num, den,
  O)}.

\cfcode{const bigmod\_matrix \&}{M.coeff\_matrix}{}
{
returns the numerator \MATH{num} of the description of \MATH{M}.}

\fcode{const bigmod\_matrix \&}{coeff\_matrix}{const module/alg\_ideal \& M}
{
returns the numerator \MATH{num} of the description of \MATH{M}.}

\cfcode{module/alg\_ideal}{M.numerator}{}
{
Depending on the type of \MATH{M}, this returns either the \BF{module} or
the \BF{alg\_ideal} \MATH{(num, 1, O)}.} 

\fcode{module/alg\_ideal}{numerator}{const module/alg\_ideal \& M}
{
Depending on the type of \MATH{M}, this returns either the \BF{module} or
the \BF{alg\_ideal} \MATH{(num, 1, O)}.} 

\cfcode{const bigint \&}{M.denominator}{}
{
returns the denominator \MATH{den} of the description of \MATH{M}.}

\fcode{const bigint \&}{denominator}{const module/alg\_ideal \& M}
{
returns the denominator \MATH{den} of the description of \MATH{M}.}

\cfcode{nf\_base *}{M.which\_base}{}
{
returns the pointer \MATH{O} of the description of \MATH{M}.}

\fcode{nf\_base *}{which\_base}{const module/alg\_ideal \& M}
{
returns the pointer \MATH{O} of the description of \MATH{M}.}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\ARTH
The following operators are overloaded and can be used in exactly the same way 
as in the programming language C. If you use these operators on
two modules/ideals \MATH{a} and \MATH{b}, this is only successful if
\TT{a.which\_base() = b.which\_base()}, otherwise the
\TT{lidia\_error\_handler} will be invoked.

\begin{center}
\TT{(binary) +, \&, *, / }\\
\TT{(bin.~with assignment) +=, \&=, *=, /= }
\end{center}
\BF{Note:} By \MATH{M}\&\MATH{N} we denote the intersection of the modules \MATH{M}
and \MATH{N}.

To avoid copying all operators also exist as functions:\vspace*{1ex}

\fcode{void}{add}{module \& c\k const          module \& a\k const module \& b}
{
\MATH{c = a + b}, if \MATH{a} and \MATH{b} are over the same
order. Otherwise the \TT{lidia\_error\_handler}
will be invoked.}

\fcode{void}{intersect}{module \& c\k const module \& a\k const module \& b}
{
\latex{\MATH{c = a \CAP b}}\html{c = Intersection(a,b)}, if
\MATH{a} and \MATH{b} are over the same order. Otherwise the
\TT{lidia\_error\_handler} will be invoked.}

\fcode{void}{multiply}{module \& c\k const module \& a\k const module \& b}
{
\MATH{c = a \cdot b}, if \MATH{a} and \MATH{b} are over the same
order. Otherwise the \TT{lidia\_error\_handler} will be invoked.}

\fcode{void}{multiply}{module \& c\k const module \& a\k const bigint \& i}
{
\MATH{c = a \cdot i}.}

\fcode{void}{multiply}{module \& c\k const bigint \& i\k const module \& b}
{
\MATH{c = i \cdot b}.}

\fcode{void}{multiply}{alg\_ideal \& c\k const alg\_ideal \& a\k const
  alg\_ideal \& b}{
\MATH{c = a \cdot b}, if \MATH{a} and \MATH{b} are over the same
order. Otherwise the \TT{lidia\_error\_handler} will be invoked.
Note that the result will be the same if the multiply function for modules
is used, however this special case should be faster.}

\fcode{void}{multiply}{alg\_ideal \& c\k const alg\_ideal \& a\k const
  alg\_number \& b}{
\MATH{c = a \cdot b}, if \MATH{a} and \MATH{b} are over the same
order. Otherwise the \TT{lidia\_error\_handler} will be invoked.}

\fcode{void}{multiply}{alg\_ideal \& c\k const alg\_number \& b\k
  const alg\_ideal \& a}{
\MATH{c = a \cdot b}, if \MATH{a} and \MATH{b} are over the same
order. Otherwise the \TT{lidia\_error\_handler} will be invoked.}

\fcode{void}{divide}{module \& c\k const module \& a\k const module \& b}
{
\MATH{c = a / b}, if \MATH{b \NEQ 0} and if \MATH{a} and
\MATH{b} are over the same order \MATH{O}. Otherwise the
\TT{lidia\_error\_handler} will be invoked. If \MATH{b} is not
invertible, we compute the maximal module \MATH{c} with \MATH{b\CDOT 
c\SUBSET a}. Note that although this may seem a bit strange,
it is a natural way to extend the notion of ideal division.}

\fcode{void}{divide}{module \& c\k const module \& a\k const bigint \& i}
{
\MATH{c = a / i}, if \MATH{i \NEQ 0}. Otherwise the
\TT{lidia\_error\_handler} will be invoked.}

\fcode{void}{divide}{alg\_ideal \& c\k const alg\_ideal \& a\k const alg\_ideal \& b}
{
\MATH{c = a / b}, if \MATH{b \NEQ 0} and if \MATH{a} and
\MATH{b} are over the same order \MATH{O}. Otherwise the
\TT{lidia\_error\_handler} will be invoked. If \MATH{b} is not
invertible, we compute the maximal module \MATH{c} with \MATH{b\CDOT 
c\SUBSET a}. Note that although this may seem a bit strange,
it is a natural way to extend the notion of ideal division.}

\fcode{void}{divide}{alg\_ideal \& c\k const alg\_ideal \& a\k const alg\_number \& b}{
\MATH{c = a / b}, if \MATH{b \NEQ 0}. Otherwise the
\TT{lidia\_error\_handler} will be invoked.}


\fcode{void}{a.invert}{}
{
\MATH{a = 1 / a}, if \MATH{a} is an invertible ideal. Otherwise we
set \MATH{a} to the module \MATH{a':=\{x \IN \K | x \CDOT a \SUBSETEQ O \}}.}

\fcode{void}{invert}{module \& a\k const module \& b}
{
\MATH{a = 1 / b}, if \MATH{b} is an invertible
ideal. Otherwise \MATH{a} is set to \MATH{b':=\{x \IN \K | x \CDOT b
\SUBSETEQ O \}}.}

\fcode{module}{inverse}{const module \& a}
{
returns \MATH{1 / a}, if \MATH{a} is an invertible ideal. Otherwise we
return the module \MATH{a':=\{x \IN \K | x \CDOT a \SUBSETEQ O \}}.}

\fcode{alg\_ideal}{inverse}{const alg\_ideal \& a}
{
returns \MATH{1 / a}, if \MATH{a} is an invertible ideal. Otherwise we
return the ideal \MATH{a':=\{x \IN \K | x \CDOT a \SUBSETEQ O \}}.}

\fcode{void}{square}{module \& c\k const module \& a}
{
\MATH{c = a^2}.}

\fcode{void}{power}{module \& c\k const module \& a\k const bigint \& i}
{
\MATH{c = a^i}.}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\COMP 
The binary operators \TT{==}, \TT{!=}, \TT{<=}, \TT{<} (true subset),
\TT{>=}, \TT{>}, and the unary operator \TT{!} (comparison with zero)
are overloaded and can be used in exactly the same way as in the
programming language C if the modules/ideals to be compared are given
relative to the same basis. Otherwise the \TT{lidia\_error\_handler} will
be invoked. The operators may also be used to compare modules with ideals.

Let \MATH{M} be an instance of type \BF{module} or
\BF{alg\_ideal}.\vspace*{1ex} 


\cfcode{bool}{M.is\_zero}{}
{
returns \TRUE\ if \MATH{M = (0)}, \FALSE\ otherwise.}

\cfcode{bool}{M.is\_one}{}
{
returns \TRUE\ if \MATH{M = (1)}, \FALSE\ otherwise.}

\cfcode{bool}{M.is\_whole\_order}{}
{
returns \TRUE\ if \MATH{M = (1)}, \FALSE\ otherwise.}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\BASIC
Let \MATH{M = (num, den, O)} be an instance of type \BF{module} or
\BF{alg\_ideal}.\vspace*{1ex}

\cfcode{bigint\_matrix}{M.z\_basis}{}{
  returns a \MATH{\Z}--basis of the module or ideal \MATH{M}.}

\cfcode{bigint\_matrix}{z\_basis}{const module/alg\_ideal \& M}{
  returns a \MATH{\Z}--basis of the module or ideal \MATH{M}.}

\cfcode{long}{M.degree}{}
{
returns the rank of the order pointed to by \MATH{O} as module over
\MATH{\Z}.}

\fcode{long}{degree}{const module/alg\_ideal \& M}
{
returns the rank of the order pointed to by \MATH{O} as module over
\MATH{\Z}.}

\fcode{void}{M.normalize}{}
{
normalizes the \BF{module} or \BF{alg\_ideal} \MATH{M} such that the \MATH{\gcd} of the elements representing the numerator
and the denominator is \MATH{1} and that the denominator is positive.}

\fcode{void}{swap}{module/alg\_ideal \& M\k module/alg\_ideal \& N}
{
exchanges the values of \MATH{M} and \MATH{N}. Note that using swap on
parameters of different type will lead to unpredictable results, i.e.~the
compiler does not (yet) complain.}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\HIGH
Let \MATH{M} be an instance of type \BF{module} or \BF{alg\_ideal}.\vspace*{1ex}


\fcode{bigrational}{norm}{const module/alg\_ideal \& M}
{
returns the norm of \MATH{M}.}

\fcode{bigrational}{exp}{const module/alg\_ideal \& M}
{
returns the exponent of \MATH{M}, i.e.~if \MATH{M=(num,den,O)} it
computes the smallest integer \MATH{e}, such that \MATH{e\CDOT (*O)
\SUBSETEQ den \CDOT M} and then it returns \FRAC{e}{den}.}

\cfcode{order}{M.ring\_of\_multipliers}{const bigint \& p}
{
returns the ring of multipliers of the module \MATH{M} modulo
\MATH{p}. Note that it is not necessary, that \MATH{p} is prime.}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\IO
\BF{istream} operator \TT{>>} and \BF{ostream} operator \TT{<<} are
overloaded. Input and output of a \BF{module} or an \BF{alg\_ideal} have
the following format:
\MATH{\mbox{[\BF{bigint\_matrix}]} / den,}
where [\BF{bigint\_matrix}] denotes a matrix given in any format
understood by the class \BF{bigint\_matrix}.
If the denominator is \MATH{1}, we omit it, i.e.~in this case the
formats are the same as for the class \BF{bigint\_matrix}.

Note that you have to manage by yourself that a \BF{module} or an
\BF{alg\_ideal} may have to be separated by blanks from other input or
output.

Since we didn't want to read the \MATH{O}--component of each module/ideal,
we always assume, that we are reading a representation with coefficients
relative to the base pointed to by \MATH{nf\_base::current\_base}. By
default, \MATH{nf\_base::current\_base} points to the basis of the last
number field or order that was read or constructed, but you may set it to
previously defined bases e.g.~by calling a constructor of the class
\BF{order} with suitable arguments.
If \MATH{nf\_base::current\_base} was not set before, the module will
use some useless dummy base, which will produce unpredictable results, if
you use such a module in a computation before assigning a meaningful value
to it.
(Note: Exactly the same mechanism using the same variables is used for
reading and writing algebraic numbers).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\WARNINGS

For backward compatibility some of the constructors do not yet behave as
one would expect, for example \TT{module(a,b)} with to \BF{alg\_numbers}
\MATH{a} and \MATH{b} should construct the module \MATH{a\Z + b\Z}, but in
fact it does construct the ideal generated by \MATH{a} and \MATH{b},
i.e.~the module \MATH{a O + b O}. However we do recommend to use the new
class \BF{alg\_ideal} for this purpose, which will support this constructor
also in the future (\BF{module} will not !!).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\SEEALSO
\BF{bigint}, \BF{vector}, \BF{bigmod\_matrix}, \BF{alg\_number}, \BF{order}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\EXAMPLES
For further references please refer\\
\TT{LiDIA/src/packages/alg\_number/module\_appl.c}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\AUTHOR
Stefan Neis
\end{lidia_man}

