%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
%%  quadratic_ideal.tex       LiDIA documentation
%%
%%  This file contains the documentation of the class quadratic_ideal
%%
%%  Copyright   (c)   1996   by  LiDIA-Group 
%%
%%  Author:  Michael J. Jacobson, Jr.
%%

\begin{lidia_man}
\markright{\BF{quadratic\_ideal}}

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

\NAME
	\BF{quadratic\_ideal}  \DOTFILL fractional ideals of quadratic orders

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

\ABSTRACT
	\BF{quadratic\_ideal} is a class for representing and computing with 
	fractional ideals of quadratic orders.  It supports basic operations
	like ideal multiplication as well as more complex operations such as
	computing the order of an equivalence class in the class group.

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

\DESCRIPTION
	A \BF{quadratic\_ideal} is represented as an ordered triple
	\MATH{(q,a,b)} (\MATH{a} and \MATH{b} are \BF{bigint}, \MATH{q} is
	\BF{bigrational}) representing the \MATH{\Z}-module
	\MATH{q [a\Z + (b + \SQRT{\Delta})/ 2~ \Z ]}.  In addition to 
	\MATH{a}, \MATH{b}, and \MATH{q}, a pointer to the
	\BF{quadratic\_order} to which the ideal belongs is stored with each
	instance of \BF{quadratic\_ideal}.

	This class is meant to be used for general computations with
	quadratic ideals.  The classes \BF{qi\_class} and 
	\BF{qi\_class\_real} should be used for computations specific to
	quadratic ideal equivalence classes.

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

\CONS

\fcode{ct }{quadratic\_ideal}{}{
	initializes with the zero ideal.}
\fcode{ct }{quadratic\_ideal}{const quadratic\_form \& qf}{
	initializes with the positively oriented ideal associated with
	\MATH{qf}.  If \MATH{qf} is not regular, the \BF{error\_handler} will
	be evoked.}
\fcode{ct }{quadratic\_ideal}{const qi\_class \& A}{
	initializes with the reduced ideal \MATH{A}.}
\fcode{ct }{quadratic\_ideal}{const qi\_class\_real \& A}{
	initializes with the reduced ideal \MATH{A}.}
\fcode{ct }{quadratic\_ideal}{const quadratic\_ideal \& A}{
	initializes a copy of \MATH{A}.}
\fcode{dt }{\MATH{\sim}quadratic\_ideal}{}{}

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

\ASGN

	Let \MATH{A} be of type \BF{quadratic\_ideal}.
        The  operator  \TT{=}  is   overloaded.   For  efficiency
	reasons,  the  following  functions are also implemented.
	Note that the parameter \MATH{QO2} is optional.  If it is omitted,
	the new ideal will belong to the last quadratic order that was used.

\fcode{void }{A.assign\_zero}{quadratic\_order \& QO2 = current\_order}{
	\MATH{A = (0)}, the zero ideal.}

\fcode{void }{A.assign\_one}{quadratic\_order \& QO2 = current\_order}{
	\MATH{A = (1)}, the whole order.}

\fcode{void }{A.assign\_principal}{const bigint \& x, const bigint \& y, quadratic\_order \& QO2 = current\_order}{
        sets \MATH{A} to the principal ideal
        generated by \MATH{x + y (\Delta + \SQRT{\Delta}) / 2}, where
        \MATH{\Delta} is the discriminant of \MATH{QO2}.}

\fcode{void }{A.assign}{const bigint \& a2, const bigint \& b2, const bigrational \& q2, quadratic\_order \& QO2 = current\_order}{
        if \MATH{q2 [a2\Z + (b2 + \SQRT{\Delta})/2~ \Z]} is an ideal of
	\MATH{QO2}, \MATH{A} is set to it, otherwise the \BF{error\_handler}
	will be evoked.}

\fcode{void }{A.assign}{const long a2, const long b2, const bigrational \& q2, quadratic\_order \& QO2 = current\_order}{
        if \MATH{q2 [a2\Z + (b2 + \SQRT{\Delta})/2~ \Z]} is an ideal of
	\MATH{QO2}, \MATH{A} is set to it, otherwise the \BF{error\_handler}
	will be evoked.}

\fcode{void }{A.assign}{const quadratic\_form \& qf}{
	sets \MATH{A} to the positively oriented ideal associated with
	\MATH{qf}.  If \MATH{qf} is not regular, the \BF{error\_handler} will
	be evoked.}

\fcode{void }{A.assign}{const qi\_class \& B}{
	sets \MATH{A} to the reduced ideal \MATH{B}.}

\fcode{void }{A.assign}{const qi\_class\_real \& B}{
	sets \MATH{A} to the reduced ideal \MATH{B}.}

\fcode{void }{A.assign}{const quadratic\_ideal \& B}{
	\MATH{A = B}.}

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

\ACCS

	Let \MATH{A} be of type \BF{quadratic\_ideal}.

\cfcode{bigint }{A.get\_a}{}{
        returns the coefficient \MATH{a} in the representation \MATH{(q,a,b)}
	of \MATH{A}.}
\cfcode{bigint }{A.get\_b}{}{
        returns the coefficient \MATH{b} in the representation \MATH{(q,a,b)}
	of \MATH{A}.}
\cfcode{bigrational }{A.get\_q}{}{
        returns the coefficient \MATH{q} in the representation \MATH{(q,a,b)}
	of \MATH{A}.}
\cfcode{bigint }{A.get\_c}{}{
        returns the value \MATH{c = (b^2 - \Delta) / (4a)} corresponding to
	the representation \MATH{(q,a,b)} of \MATH{A}, where \MATH{\Delta} is
	the discriminant of the quadratic order to which \MATH{A} belongs.}
\cfcode{quadratic\_order * }{A.which\_order}{}{
	returns a pointer to the \BF{quadratic\_order} of which \MATH{A}
	belongs.}
\fcode{quadratic\_order * }{which\_order}{const quadratic\_ideal \& A}{
	returns a pointer to the \BF{quadratic\_order} of which \MATH{A}
	belongs.}
\cfcode{bigint }{A.discriminant}{}{
        returns the discriminant of the quadratic order to which 
	\MATH{A} belongs.}

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

\ARTH

	Let \MATH{A} be of type \BF{quadratic\_ideal}.
	The following operators are overloaded and can be used in
	exactly  the  same  way  as in the programming language C.
	\begin{center}
	\TT{(unary) -}\\
	\TT{(binary) *, /}\\
	\TT{(binary with assignment) *=,  /=}\\
	\end{center}
	\BF{Note:} By \MATH{-A} and \MATH{A^{-1}} we denote the inverse of
	\MATH{A} if it exists, and
	by \MATH{A / B} we denote \MATH{A * B^{-1}}.

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

%\fcode{void }{add}{quadratic\_ideal \& C, const quadratic\_ideal \& A, const quadratic\_ideal \& B}{
%	\MATH{C = A + B} if \MATH{A} and \MATH{B} are of the same quadratic
%	order; otherwise the \BF{error\_handler} will be evoked.}

%\fcode{void }{intersect}{quadratic\_ideal \& C, const quadratic\_ideal \& A, const quadratic\_ideal \& B}{
%	\MATH{C} is set to the intersection of \MATH{A} and \MATH{B} if they
%	are of the same quadratic order;
%	otherwise the \BF{error\_handler} will be evoked.}

\fcode{void }{multiply}{quadratic\_ideal \& C, const quadratic\_ideal \& A, const quadratic\_ideal \& B}{
	\MATH{C = A * B}.  If \MATH{A} and \MATH{B} are not of the same
	quadratic order, the \BF{error\_handler} will be evoked.}

\fcode{void }{A.conjugate}{}{
	\MATH{A} is set to the conjugate of \MATH{A}.}

\fcode{void }{get\_conjugate}{quadratic\_ideal \& A, const quadratic\_ideal \& B}{
	\MATH{A} is set to the conjugate of \MATH{B}.}

\fcode{quadratic\_ideal }{get\_conjugate}{quadratic\_ideal \& A}{
	returns the conjugate of \MATH{A}.}

\fcode{void }{A.invert}{}{
	If \MATH{A} is invertible, \MATH{A = A^{-1}}, otherwise \MATH{A} is
	set to its conjugate.}

\fcode{void }{inverse}{quadratic\_ideal \& A, const quadratic\_ideal \& B}{
	If \MATH{B} is invertible, \MATH{A = B^{-1}}, otherwise \MATH{A} is
	set to the conjugate of \MATH{B}.}

\fcode{quadratic\_ideal }{inverse}{quadratic\_ideal \& A}{
	If \MATH{A} is invertible, \MATH{A^{-1}} is returned, otherwise 
	the conjugate of \MATH{A} is returned.}

\fcode{void }{divide}{quadratic\_ideal \& C, const quadratic\_ideal \& A, const quadratic\_ideal \& B}{
	\MATH{C = A * B^{-1}}.  If \MATH{A} and \MATH{B} are not of the same
	quadratic order or if \MATH{B = (0)}, the \BF{error\_handler} will be
	evoked.  If \MATH{B} is not invertible, \MATH{C} is set to the
	product of \MATH{A} and the conjugate of \MATH{B}.}

\fcode{void }{square}{quadratic\_ideal \& C, const quadratic\_ideal \& A}{
	\MATH{C = A^2}.}

\fcode{void }{power}{quadratic\_ideal \& C, const quadratic\_ideal \& A, const bigint \& i}{
	\MATH{C = A^i}.  If \MATH{i < 0}, \MATH{B^i} is computed where
	\MATH{B = A^{-1}} or the conjugate of \MATH{A} if \MATH{A} is not
	invertible.}

\fcode{void }{power}{quadratic\_ideal \& C, const quadratic\_ideal \& A, const long i}{}

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

\COMP

	The  binary operators \TT{==}, \TT{!=}, \TT{<=}, \TT{<} (true subset),
	\TT{>=}, \TT{>} and the unary operator \TT{!} (comparison with
	\MATH{(0)}) are overloaded and can be used in exactly the same way as
	in the programming language C.
	The binary operators are only successful if both operands have the
	same quadratic order, otherwise the \BF{error\_handler} will be
	invoked.
	Let \MATH{A} be an instance of type \BF{quadratic\_ideal}.

\cfcode{bool }{A.is\_zero}{}{
	returns \TRUE\ if \MATH{A = (0)}, \FALSE\ otherwise.}
\cfcode{bool }{A.is\_one}{}{
	returns \TRUE\ if \MATH{A = (1)}, \FALSE\ otherwise.}
\cfcode{bool }{A.is\_equal}{const quadratic\_ideal \& B}{
	returns \TRUE\ if \MATH{A} and \MATH{B} are equal, \FALSE\ otherwise.}
\cfcode{bool }{A.is\_subset}{const quadratic\_ideal \& B}{
	returns \TRUE\ if \MATH{A} is a subset of \MATH{B}, \FALSE\ otherwise.}
\cfcode{bool }{A.is\_proper\_subset}{const quadratic\_ideal \& B}{
	returns \TRUE\ if \MATH{A} is a proper subset of \MATH{B},
	\FALSE\ otherwise.}

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

\BASIC

\cfcode{operator}{quadratic\_form}{}{
        cast operator which implicitly converts a \BF{quadratic\_ideal} to a
        \BF{quadratic\_form}.}
\cfcode{operator}{qi\_class}{}{
        cast operator which implicitly converts a \BF{quadratic\_ideal} to a
        \BF{qi\_class}.}
\cfcode{operator}{qi\_class\_real}{}{
        cast operator which implicitly converts a \BF{quadratic\_ideal} to a
        \BF{qi\_class\_real}.}
\fcode{void }{swap}{quadratic\_ideal \& A, quadratic\_ideal \& B}{
	exchanges the values of \MATH{A} and \MATH{B}.}

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

\HIGH

	Let \MATH{A} be of type \BF{quadratic\_ideal}.

\cfcode{bigrational }{A.smallest\_rational}{}{
	returns the smallest rational number in \MATH{A}.  This is simply the
	value of \MATH{qa}, where \MATH{q} and \MATH{a} are coefficients in
	the representation of \MATH{A}.}

\cfcode{bool }{A.is\_integral}{}{
	returns \TRUE\ if \MATH{A} is an integral ideal, \FALSE\ otherwise.}

\cfcode{bigint }{A.conductor}{}{
	returns the conductor of \MATH{A}.}

\cfcode{bool }{A.is\_invertible}{}{
	returns \TRUE\ if \MATH{A} is invertible, \FALSE\ otherwise.}

\cfcode{bigrational }{A.norm}{}{
	returns the norm of \MATH{A}.}

\fcode{quadratic\_order }{A.ring\_of\_multipliers}{}{
	returns the ring of multipliers of \MATH{A}.}

\fcode{bool }{prime\_ideal}{quadratic\_ideal A, const bigint \& p, quadratic\_order \& QO2 = current\_order}{
        attempts to set \MATH{A} to the prime ideal lying over the
        prime \MATH{p}.  If successful
        (the Kronecker symbol \MATH{(\Delta/p) \NEQ -1}),
        \TRUE\ is returned, otherwise \FALSE\ is returned.  Note that the
	parameter \MATH{QO2} is optional.  If it is omitted, the new ideal
	will belong to the last quadratic order that was used.}

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

\SSTITLE{Reduction}

\cfcode{bool }{A.is\_reduced}{}{
	returns \TRUE\ if \MATH{A} is reduced, \FALSE\ otherwise.}

\fcode{void }{A.reduce}{}{
	reduces A.}

\fcode{void }{A.rho}{}{
	applies the reduction operator \MATH{rho} once to A.}

\fcode{void }{apply\_rho}{quadratic\_ideal \& C, const quadratic\_ideal \& A}{
        sets \MATH{C} to the result of the reduction operator \MATH{rho} being
        applied once to A.}

\fcode{qi\_class }{apply\_rho}{quadratic\_ideal \& A}{
        returns a \BF{qi\_class} corresponding to the result of the reduction
        operator \MATH{rho} being applied once to A.}

\fcode{void }{A.inverse\_rho}{}{
	applies the inverse reduction operator once to A.}

\fcode{void }{apply\_inverse\_rho}{quadratic\_ideal \& C, const quadratic\_ideal \& A}{
        sets \MATH{C} to the result of the inverse reduction operator
	\MATH{rho^{-1}} being applied once to A.}

\fcode{qi\_class }{apply\_inverse\_rho}{quadratic\_ideal \& A}{
        returns a \BF{qi\_class} corresponding to the result of the inverse 
	reduction operator \MATH{rho^{-1}} being applied once to A.}

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

\SSTITLE{Equivalence and principality testing}

\cfcode{bool }{A.is\_equivalent}{const quadratic\_ideal \& B}{
	returns \TRUE\ if \MATH{A} and \MATH{B} are in the same ideal
	equivalence class, \FALSE\ otherwise.  The function uses
	the \BF{qi\_class} function of the same name.  If either ideal is not
	invertible, \FALSE\ is returned.}

\cfcode{bool }{A.is\_principal}{}{
	returns \TRUE\ if \MATH{A} is principal, \FALSE\ otherwise.  The
	function  uses the \BF{qi\_class} function of the same name.  If
	\MATH{A} is not invertible, \FALSE\ is returned.}

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

\SSTITLE{Orders, discrete logarithms, and subgroup structures}

\fcode{bigint }{A.order\_in\_CL}{}{
	returns the order of \MATH{A} in the ideal class group of its
	quadratic order, i.e. the
	least positive integer \MATH{x} such that \MATH{A^x \SIM (1)}.  It
	uses the \BF{qi\_class} function of the same name.  If \MATH{A} is
	not invertible, \MATH{0} is returned.}

\cfcode{bool }{A.DL}{const quadratic\_ideal \& G, bigint \& x}{
	returns \TRUE\ if \MATH{A} belongs to the cyclic subgroup generated
	by \MATH{G}, \FALSE\ otherwise.  If so, \MATH{x} is set to
	the discrete logarithm of \MATH{A} to the base \MATH{G},
	i.e., the least non-negative integer \MATH{x} such that
	\MATH{G^x \SIM A}.  If not, \MATH{x} is set to the order of \MATH{G}.
	The function uses the \BF{qi\_class} function of the same name.  If
	either \MATH{A} or \MATH{G} is not invertible, \FALSE\ is returned and
	\MATH{x} is set to \MATH{0}.}

\fcode{base\_vector<bigint> }{subgroup}{base\_vector<quadratic\_ideal> \& G, base\_vector<quadratic\_ideal> \& factor\_base, bigint\_matrix \& U}{
	returns the vector of invariants representing the structure of the
	subgroup generated by the classes corresponding to the invertible
	ideals contained in \MATH{G}.  The
	function uses the \BF{qi\_class} function of the same name.}

\fcode{bigfloat }{A.regulator}{}{
        returns an approximation of the regulator of the quadratic order to
	which \MATH{A} belongs.  If \MATH{A} belongs to an imaginary quadratic
	order, \MATH{1} is returned.}

\fcode{bigint }{A.class\_number}{}{
	returns the order of the ideal class group of the quadratic order to
	which \MATH{A} belongs.}

\fcode{base\_vector<bigint> }{A.class\_group}{}{
        returns the vector of invariants representing the structure of the
        ideal class group of the quadratic order to which \MATH{A} belongs.}


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

\IO

	Let \MATH{A} be of type \BF{quadratic\_ideal}.
	The \BF{istream}  operator  \TT{>>}  and  the \BF{ostream}  operator
	\TT{<<} are overloaded.  The input of a \BF{quadratic\_ideal}
        consists of \TT{(q a b QO)}, where \MATH{q} is a \BF{bigrational} and
	\MATH{a} and \MATH{b} are integers corresponding to the
        representation \MATH{A = q [a\Z + (b + \SQRT{\Delta})/2~ \Z]}, and
	\MATH{QO} is a \BF{quadratic\_order}.
	The output has the format \MATH{((q),a,b)}.  
        For input, the current quadratic order must be set first, otherwise
        the \BF{error\_handler} will be evoked.

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

\SEEALSO
	quadratic\_order, qi\_class, qi\_class\_real, quadratic\_form

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

%\NOTES

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

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

main()
{
  quadratic_order QO;
  quadratic_ideal A,B,C;
  bigint D,p,x;

  do {
    cout << "Please enter a quadratic discriminant: "; cin >> D;
  } while (!QO.assign(D));
  cout << "\n";

  /* compute 2 prime ideals */
  p = 3;
  while (!prime_ideal(A,p,QO))
    p = next_prime(p);
  p = next_prime(p);
  while (!prime_ideal(B,p,QO))
    p = next_prime(p);

  cout << "A = " << A << "\n";
  cout << "B = " << B << "\n";

  power(C,B,3);
  C *= -A;
  square(C,C);
  cout << "C = (A^-1*B^3)^2 = " << C << "\n";

  cout << "|<C>| = " << C.order_in_CL() << "\n";

  C.reduce();
  cout << "C reduced = " << C << "\n";

  cout << "ring of multipliers of C:\n";
  cout << C.ring_of_multipliers() << "\n";

  if (A.DL(B,x))
    cout << "log_B A = " << x << "\n" << flush;
  else
    cout << "no discrete log:  |<B>| = " << x << "\n" << flush;
}
\end{verbatim}

example:

\begin{verbatim}
Please enter a quadratic discriminant: -82636319

A = ((1), 3, 1)
B = ((1), 5, 1)
C = (A^-1*B^3)^2 = ((1/9), 140625, 103541)
|<C>| = 20299
C reduced = ((1), 2856, -271)
ring of multipliers of C:
Quadratic Order:
   Delta = -82636319 (8)

log_B A = 17219
\end{verbatim}

        For further examples please refer to \\
        \TT{LiDIA/src/packages/quadratic\_order/quadratic\_ideal\_appl.c}.

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

\AUTHOR
	Michael J. Jacobson, Jr.

\end{lidia_man}
