
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
%%  multi\_bigmod.tex       LiDIA documentation
%%
%%  This file contains the documentation of the class multi\_bigmod
%%
%%  Copyright   (c)   1995   by  LiDIA-Group
%%
%%  Authors: Thomas Papanikolaou, Oliver Morsch
%%  

\begin{lidia_man}
\markright{\BF{multi\_bigmod}}

\NAME
\BF{multi\_bigmod}      \DOTFILL       multiprecision modular integer arithmetic

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

\ABSTRACT
\BF{multi\_bigmod} is a class for doing multiprecision modular
arithmetic over \MATH{\Z/m\Z}. It supports for example arithmetic
operations, comparisons and exponentiation.

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

\DESCRIPTION
A \BF{multi\_bigmod} is a pair of two \BF{bigints} \BF{(man, m)}, where \MATH{man} is called 
\BF{mantissa} and \MATH{m}  \BF{modulus}. Each \BF{multi\_bigmod} has got its own modulus
which can be set by a constructor or by
\begin{center}
\TT{a.set\_modulus(const bigint \& m)}
\end{center}
where \MATH{a} is of type \BF{multi\_bigmod}.

Each equivalence class modulo \MATH{m} is represented by its least non-negative
representative, i.e. the mantissa of a \BF{multi\_bigmod} is chosen in the interval
\MATH{[ 0,\LDOTS,|m|-1 ]}. 

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

\CONS
If \MATH{m=0}, the \TT{lidia\_error\_handler} will be invoked.

\fcode{ct}{multi\_bigmod}{}
{
initializes the mantissa and the modulus with 0.}

\fcode{ct}{multi\_bigmod}{int i\k const bigint \& m}
{
initializes the mantissa with \MATH{i} and the modulus with \MATH{|m|}.
}

\fcode{ct}{multi\_bigmod}{long l\k const bigint \& m}
{
initializes the mantissa with \MATH{l} and the modulus with \MATH{|m|}.
}

\fcode{ct}{multi\_bigmod}{unsigned long ul\k const bigint \& m}
{
initializes the mantissa with \MATH{ul} and the modulus with \MATH{|m|}.
}

\fcode{ct}{multi\_bigmod}{double d\k const bigint \& m}
{
initializes the mantissa with \MATH{d} and the modulus with \MATH{|m|}.
}

\fcode{ct}{multi\_bigmod}{const bigint \& a\k const bigint \& m}
{
initializes the mantissa with \MATH{a} and the modulus with \MATH{|m|}.
}

\fcode{ct}{multi\_bigmod}{const multi\_bigmod \&}{}

\fcode{dt}{\SIM multi\_bigmod}{}{}

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

\INIT
\fcode{void}{a.set\_modulus}{const bigint \& m}
{
sets the modulus of the \BF{multi\_bigmod}
\MATH{a} to \MATH{|m|}; if \MATH{m=0}, the \TT{lidia\_error\_handler} will be invoked.
The mantissa of \MATH{a} will not automatically be reduced modulo \MATH{m}.
You have to call one of the two following normalization functions to
reduce the mantissa.}

\fcode{void}{a.normalize}{}
{
normalizes the \BF{multi\_bigmod}
\MATH{a} such that the mantissa of \MATH{a} is in the range \MATH{[0,\LDOTS, m-1]},
where \MATH{m} is the modulus of \MATH{a}.}

\fcode{void}{normalize}{multi\_bigmod \& a\k const multi\_bigmod \& b}
{
sets the modulus of \MATH{a}
to the modulus of \MATH{b}, the mantissa of \MATH{a} to the mantissa of \MATH{b} and normalizes
\MATH{a} such that the mantissa of \MATH{a} is in the range \MATH{[0,\LDOTS, m-1]},
where \MATH{m} is the modulus of \MATH{b}.}

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

\TYPE
Before assigning a \BF{multi\_bigmod} (i.e.~the mantissa of a \BF{multi\_bigmod}) to a
machine type (e.g.~int) it is often useful to perform a test
which checks whether the assignment could be done without overflow. The
following functions return \TRUE\ if the assignment would be
successful, \FALSE\ otherwise.

\fcode{bool}{is\_char}{const multi\_bigmod \&}{}
\fcode{bool}{is\_uchar}{const multi\_bigmod \&}{}
\fcode{bool}{is\_short}{const multi\_bigmod \&}{}
\fcode{bool}{is\_ushort}{const multi\_bigmod \&}{}
\fcode{bool}{is\_int}{const multi\_bigmod \&}{}
\fcode{bool}{is\_uint}{const multi\_bigmod \&}{}
\fcode{bool}{is\_long}{const multi\_bigmod \&}{}
\fcode{bool}{is\_ulong}{const multi\_bigmod \&}{}

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

\ASGN
The operator \TT{=} is overloaded. For efficiency reasons the following 
functions are also implemented (let \MATH{a} be of type \BF{multi\_bigmod}):


\fcode{void}{a.assign\_zero}{}
{
\MATH{\mbox{mantissa}(a) = 0}.}

\fcode{void}{a.assign\_one}{}
{
\MATH{\mbox{mantissa}(a) = 1}.}

\fcode{void}{a.assign\_zero}{const bigint \& m}
{
\MATH{\mbox{mantissa}(a) = 0, \mbox{modulus}(a) = {|m|}}.
If \MATH{m=0}, the \TT{lidia\_error\_handler} will be invoked.}

\fcode{void}{a.assign\_one}{const bigint \& m}
{
\MATH{\mbox{mantissa}(a) = 1, \mbox{modulus}(a) = {|m|}}.
If \MATH{m=0}, the \TT{lidia\_error\_handler} will be invoked.}

\fcode{void}{a.assign}{int i, const bigint \& m}
{
\MATH{\mbox{mantissa}(a) = i, \mbox{modulus}(a) = {|m|}}.
If \MATH{m=0}, the \TT{lidia\_error\_handler} will be invoked.}

\fcode{void}{a.assign}{long i, const bigint \& m}
{
\MATH{\mbox{mantissa}(a) = i, \mbox{modulus}(a) = {|m|}}.
If \MATH{m=0}, the \TT{lidia\_error\_handler} will be invoked.}

\fcode{void}{a.assign}{unsigned long i, const bigint \& m}
{
\MATH{\mbox{mantissa}(a) = i, \mbox{modulus}(a) = {|m|}}.
If \MATH{m=0}, the \TT{lidia\_error\_handler} will be invoked.}

\fcode{void}{a.assign}{const bigint \& b, const bigint \& m}
{
\MATH{\mbox{mantissa}(a) = b, \mbox{modulus}(a) = {|m|}}.
If \MATH{m=0}, the \TT{lidia\_error\_handler} will be invoked.}

\fcode{void}{a.assign}{const multi\_bigmod \& b}
{
\MATH{a = b}.}


\fcode{void}{a.set\_mantissa}{int i}
{
\MATH{\mbox{mantissa}(a) = i} and the mantissa of \MATH{a} will be reduced modulo
the modulus of \MATH{a}.}

\fcode{void}{a.set\_mantissa}{long i}
{
\MATH{\mbox{mantissa}(a) = i} and the mantissa of \MATH{a} will be reduced modulo
the modulus of \MATH{a}.}

\fcode{void}{a.set\_mantissa}{unsigned long i}
{
\MATH{\mbox{mantissa}(a) = i} and the mantissa of \MATH{a} will be reduced modulo
the modulus of \MATH{a}.}

\fcode{void}{a.set\_mantissa}{const bigint \& b}
{
\MATH{\mbox{mantissa}(a) = b} and the mantissa of \MATH{a} will be reduced modulo
the modulus of \MATH{a}.}


\fcode{double}{dbl}{const multi\_bigmod \& a}
{
returns the mantissa of \MATH{a} as a double approximation.}

\cfcode{bool}{a.intify}{int \& i}
{
performs the assignment \TT{i = mantissa(a)} provided the
assignment can be done without overflow. In that case
the function returns \FALSE, otherwise it returns \TRUE\ and
the value of \MATH{i} will be unchanged.}

\cfcode{bool}{a.longify}{long \& i}
{
performs the assignment \TT{i = mantissa(a)} provided the
assignment can be done without overflow. In that case
the function returns \FALSE, otherwise it returns \TRUE\ and
the value of \MATH{i} will be unchanged.}

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

\ACCS
\fcode{bigint}{mantissa}{const multi\_bigmod \& a}
{
returns the mantissa of the \BF{multi\_bigmod} \MATH{a}. The mantissa is
chosen in the interval \MATH{[0,\LDOTS , m-1]}, where \MATH{m} is the
modulus of \MATH{a}.}

\cfcode{const bigint \&}{a.mantissa}{}
{
returns the mantissa of the \BF{multi\_bigmod} \MATH{a}. The mantissa is
chosen in the interval \MATH{[0,\LDOTS , m-1]}, where \MATH{m} is the
modulus of \MATH{a}.}


\cfcode{const bigint \&}{a.modulus}{}
{
returns the modulus of the \BF{multi\_bigmod} \MATH{a}.}

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

\ARTH
The binary operations require that the operands have the same modulus;
in case of different moduli, the \TT{lidia\_error\_handler} will be invoked.
Binary operations that obtain an operand \MATH{a \IN \Z/m\Z}, where
\MATH{m} is the modulus of \MATH{a}, and an operand \MATH{b \IN \Z},
i.e. \MATH{b} of type int, long, \BF{bigint}, map \MATH{b} to \MATH{\Z/m\Z}.

The following operators are overloaded and can be used in exactly the same way 
as in C:

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

The operators \TT/ and \TT{/=} denote ``multiplication with the 
inverse''. If the inverse does not exist, the \TT{lidia\_error\_handler}
will be invoked.  To avoid copying all operators also exist 
as functions. 


\fcode{void}{add}{multi\_bigmod \& c\k const multi\_bigmod \& a\k const multi\_bigmod \& b}
{
\MATH{c = a + b}.}

\fcode{void}{add}{multi\_bigmod \& c\k const multi\_bigmod \& a\k const bigmod \& b}
{
\MATH{c = a + b}.}

\fcode{void}{add}{multi\_bigmod \& c\k const bigmod \& a\k const multi\_bigmod \& b}
{
\MATH{c = a + b}.}

\fcode{void}{add}{multi\_bigmod \& c\k const multi\_bigmod \& a\k const bigint \& i}
{
\MATH{c = a + i}.}

\fcode{void}{add}{multi\_bigmod \& c\k const bigint \& i\k const multi\_bigmod \& b}
{
\MATH{c = i + b}.}

\fcode{void}{add}{multi\_bigmod \& c\k const multi\_bigmod \& a\k long i}
{
\MATH{c = a + i}.}

\fcode{void}{add}{multi\_bigmod \& c\k long i\k const multi\_bigmod \& b}
{
\MATH{c = i + b}.}


\fcode{void}{subtract}{multi\_bigmod \& c\k const multi\_bigmod \& a\k const multi\_bigmod \& b}
{
\MATH{c = a - b}.}

\fcode{void}{subtract}{multi\_bigmod \& c\k const multi\_bigmod \& a\k const bigmod \& b}
{
\MATH{c = a - b}.}

\fcode{void}{subtract}{multi\_bigmod \& c\k const bigmod \& a\k const multi\_bigmod \& b}
{
\MATH{c = a - b}.}

\fcode{void}{subtract}{multi\_bigmod \& c\k const multi\_bigmod \& a\k const bigint \& i}
{
\MATH{c = a - i}.}

\fcode{void}{subtract}{multi\_bigmod \& c\k const bigint \& i\k const multi\_bigmod \& b}
{
\MATH{c = i - b}.}

\fcode{void}{subtract}{multi\_bigmod \& c\k const multi\_bigmod \& a\k long i}
{
\MATH{c = a - i}.}

\fcode{void}{subtract}{multi\_bigmod \& c\k long i\k const multi\_bigmod \& b}
{
\MATH{c = i - b}.}


\fcode{void}{multiply}{multi\_bigmod \& c\k const multi\_bigmod \& a\k const multi\_bigmod \& b}
{
\MATH{c = a * b}.}

\fcode{void}{multiply}{multi\_bigmod \& c\k const multi\_bigmod \& a\k const bigmod \& b}
{
\MATH{c = a * b}.}

\fcode{void}{multiply}{multi\_bigmod \& c\k const bigmod \& a\k const multi\_bigmod \& b}
{
\MATH{c = a * b}.}

\fcode{void}{multiply}{multi\_bigmod \& c\k const multi\_bigmod \& a \k const bigint \& i}
{
\MATH{c = a * i}.}

\fcode{void}{multiply}{multi\_bigmod \& c\k const bigint \& i\k const multi\_bigmod \& b}
{
\MATH{c = i * b}.}

\fcode{void}{multiply}{multi\_bigmod \& c\k const multi\_bigmod \& a \k long i}
{
\MATH{c = a * i}.}

\fcode{void}{multiply}{multi\_bigmod \& c\k long i\k const multi\_bigmod \& b}
{
\MATH{c = i * b}.}


\fcode{void}{divide}{multi\_bigmod \& c\k const multi\_bigmod \& a\k const multi\_bigmod \& b}
{
\MATH{c = a * b^{-1}}, if the inverse of \MATH{b} does not exist, 
        the \TT{lidia\_error\_handler} will be invoked.}

\fcode{void}{divide}{multi\_bigmod \& c\k const multi\_bigmod \& a\k const bigmod \& b}
{
\MATH{c = a * b^{-1}}, if the inverse of \MATH{b} does not exist, 
        the \TT{lidia\_error\_handler} will be invoked.}

\fcode{void}{divide}{multi\_bigmod \& c\k const bigmod \& a\k const multi\_bigmod \& b}
{
\MATH{c = a * b^{-1}}, if the inverse of \MATH{b} does not exist, 
        the \TT{lidia\_error\_handler} will be invoked.}

\fcode{void}{divide}{multi\_bigmod \& c\k const multi\_bigmod \& a\k const bigint \& i}
{
\MATH{c = a * i^{-1}}, if the inverse of \MATH{i} does not exist, 
        the \TT{lidia\_error\_handler} will be invoked.}

\fcode{void}{divide}{multi\_bigmod \& c\k const bigint \& i\k const multi\_bigmod \& b}
{
\MATH{c = i * b^{-1}}, if the inverse of \MATH{b} does not exist, 
        the \TT{lidia\_error\_handler} will be invoked.}

\fcode{void}{divide}{multi\_bigmod \& c\k const multi\_bigmod \& a\k long i}
{
\MATH{c = a * i^{-1}}, if the inverse of \MATH{i} does not exist, 
        the \TT{lidia\_error\_handler} will be invoked.}

\fcode{void}{divide}{multi\_bigmod \& c\k long i\k const multi\_bigmod \& b}
{
\MATH{c = i * b^{-1}}, if the inverse of \MATH{b} does not exist, 
        the \TT{lidia\_error\_handler} will be invoked.}

Let \MATH{a} be of type \BF{multi\_bigmod}.


\fcode{void}{a.negate}{}
{
\MATH{a = -a}.}

\fcode{void}{negate}{multi\_bigmod \& a\k const multi\_bigmod \& b}
{
\MATH{a = -b}.}

\fcode{bigint}{a.invert}{int verbose=0}
{
sets \MATH{a = a^{-1}}, if the inverse of \MATH{a} exists. 
        If the inverse does not exist and \MATH{verbose=0}, 
        the \TT{lidia\_error\_handler} will be invoked.
        If the inverse does not exist and \MATH{verbose\NEQ 0},
        then the function prints a warning and returns
        the gcd of \MATH{a} and its modulus. In this case \MATH{a} remains
        unchanged and the program does not exit.}

\fcode{void}{invert}{multi\_bigmod \& a\k const multi\_bigmod \& b}
{
sets \MATH{a = b^{-1}}, if the inverse of \MATH{b} exists.
        Otherwise the \TT{lidia\_error\_handler} will be invoked.}

\fcode{multi\_bigmod}{inverse}{const multi\_bigmod \& a}
{
returns \MATH{a^{-1}}, if the inverse of \MATH{a} exists. Otherwise
        the \TT{lidia\_error\_handler} will be invoked.}


\fcode{void}{a.multiply\_by\_2}{}
{
\MATH{a = 2 * a} (using shift-operations).}



\fcode{void}{a.divide\_by\_2}{}
{
computes a number \MATH{b\IN
[0,\LDOTS, m-1]} such that \MATH{2 b\EQUIV \mbox{mantissa}(a)\bmod m}, 
where \MATH{m} is the modulus of \MATH{a}, and sets 
\MATH{\mbox{mantissa}(a)=b} (note: this is not
equivalent to the multiplication of \MATH{a} with the inverse of 2). 
The lidia\_error\_handler will be invoked if the operation is impossible, 
i.e. if the mantissa of \MATH{a} is odd and \MATH{m} is even.}


\fcode{void}{inc}{multi\_bigmod \& c}
{
\MATH{c = c + 1}.}

\fcode{void}{dec}{multi\_bigmod \& c}
{
\MATH{c = c - 1}.}

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

\fcode{void}{power}{multi\_bigmod \& c\k const multi\_bigmod \& a\k const bigint \& b}
{
\MATH{c = a^b} (done with right-to-left binary exponentiation).}

\fcode{void}{power}{multi\_bigmod \& c\k const multi\_bigmod \& a\k long i}
{
\MATH{c = a^i} (done with right-to-left binary exponentiation).}

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

\COMP
\BF{multi\_bigmod} supports the binary operators \TT{==}, \TT{!=}
and additionally the unary operator \TT! (comparison with zero).
Let \MATH{a} be an instance of type \BF{multi\_bigmod}.


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

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

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

\BASIC
Let \MATH{a} be of type \BF{multi\_bigmod}.


\cfcode{lidia\_size\_t}{a.bit\_length}{}
{
returns the bit-length of \MATH{a}'s mantissa (see class \BF{bigint}, page
\pageref{bigint_class}).}

\cfcode{lidia\_size\_t}{a.length}{}
{
returns the word-length of \MATH{a}'s mantissa (see class \BF{bigint}, page
\pageref{bigint_class}).}

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

\HIGH
\fcode{void}{swap}{multi\_bigmod \& a\k multi\_bigmod \& b}
{
exchanges the mantissa and the modulus of \MATH{a} and \MATH{b}.}

\fcode{void}{seed}{const multi\_bigmod \& a}
{
initializes the random number generator function defined in the kernel with \MATH{a}.}

\fcode{multi\_bigmod}{randomize}{const multi\_bigmod \& a}
{
returns a random \BF{multi\_bigmod} \MATH{b} with random mantissa in the
        range \MATH{[0,\LDOTS,\mbox{mantissa}(b)-1]}, \MATH{\mbox{modulus}(b) = \mbox{modulus}(a)}.}

\fcode{void}{a.randomize}{const bigint \& m}
{
computes a random mantissa of \MATH{a} in the
        range \MATH{[0,\LDOTS,\ABS{m}\mbox{-1]}}, \MATH{\mbox{modulus}(a) = \ABS{m}}.}

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

\IO
Let \MATH{a} be of type \BF{multi\_bigmod}.

The \BF{istream} operator \TT{>>} and the \BF{ostream} operator \TT{<<} are
overloaded. Furthermore, you can use the following member functions
for writing to and reading from a file in binary or ASCII
format, respectively. The input and output format of a 
\BF{multi\_bigmod} are
\begin{center}
\TT{(mantissa,modulus)}.
\end{center}


\fcode{int}{x.read\_from\_file}{FILE *fp}
{
reads \MATH{x} from the binary file \MATH{f\!p} using fread.}

\fcode{int}{x.write\_to\_file}{FILE *fp}
{
writes \MATH{x} to the binary file \MATH{f\!p} using fwrite.}

\fcode{int}{x.scan\_from\_file}{FILE *fp}
{
scans \MATH{x} from the ASCII file \MATH{f\!p} using fscanf.}

\fcode{int}{x.print\_to\_file}{FILE *fp}
{
prints \MATH{x} to the ASCII file \MATH{f\!p} using fprintf.}

\fcode{int}{string\_to\_multi\_bigmod}{char *s\k multi\_bigmod \& a}
{
converts the string \MATH{s} to a \BF{multi\_bigmod} \MATH{a} and returns the 
number of converted characters.}

\fcode{int}{multi\_bigmod\_to\_string}{const multi\_bigmod \& a\k char *s}
{
converts the \BF{multi\_bigmod} \MATH{a} to a string \MATH{s} and returns the 
number of used characters.}

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

\SEEALSO
\BF{bigint}, \BF{bigmod}

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

\EXAMPLES

\begin{verbatim}
 #include <LiDIA/multi_bigmod.h>
 
 int main()
 {
   multi_bigmod a, b, c;

    a.set_modulus(10);
    b.set_modulus(10);

    cout << "Please enter a : "; cin >> a ; 

    cout << "Please enter b : "; cin >> b ;

    cout << "\n";

    c = a + b;

    cout << "a + b = " << c << "\n";

 } 

\end{verbatim}

For further reference please refer to\\
\TT{LiDIA/src/simple\_classes/multi\_bigmod\_appl.c 
}

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

\AUTHOR
Markus Maurer, Thomas Papanikolaou
\end{lidia_man}

