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

\begin{lidia_man}
\markright{\BF{qi\_class\_real}}

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

\NAME
	\BF{qi\_class\_real}  \DOTFILL ideal equivalence classes of real
	quadratic orders

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

\ABSTRACT
	\BF{qi\_class\_real} is a class for representing and computing with the
	ideal equivalence classes of real quadratic orders, and in particular,
	for computing in the infrastructure of the principal class.
	It supports basic operations like multiplication as well as more
	complex operations such as equivalence and principality testing.

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

\DESCRIPTION
        A \BF{qi\_class\_real} is represented by a reduced, invertible
	quadratic ideal given in standard representation, i.e., an
        ordered pair of \BF{bigint}s \MATH{(a,b)}
        representing the \MATH{\Z}-module
        \MATH{[a\Z + (b + \sqrt{\Delta}) / 2~\Z]}, where \MATH{\Delta \GT 0} is
        the discriminant of a real quadratic order.  This representative of
	an equivalence class is not unique, but it is one of a finite set of
	representatives.  A distance \MATH{\delta} (logarithm of a minimum)
	is also stored with the ideal, so
	that computations in the infrastructure of the principal class are
	possible.  It is the user's responsibility to keep track of whether
	a specific distance is taken from the unit ideal or some other ideal.

	This class is derived from \BF{qi\_class}, and most of the functions
	work in exactly the same way.  Additional functions as well as the
	functions that work differently from \BF{qi\_class} are detailed
	below.

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

\CONS

	Constructors have the same syntax as \BF{qi\_class}.  The distance is
	always initialized to 0.  If the current quadratic order is not real,
	the \BF{error\_handler} will be evoked.

\fcode{ct }{qi\_class\_real}{}{}
\fcode{ct }{qi\_class\_real}{const quadratic\_form \& qf}{}
\fcode{ct }{qi\_class\_real}{const quadratic\_ideal \& A}{}
\fcode{ct }{qi\_class\_real}{const qi\_class \& A}{}
\fcode{ct }{qi\_class\_real}{const qi\_class\_real \& A}{}
\fcode{dt }{\MATH{\sim}qi\_class\_real}{}{}

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

\INIT

        Before any arithmetic is done with a \BF{qi\_class\_real}, the
        current quadratic order must be initialized.  Note that this quadratic
	order is the same as that used for \BF{qi\_class}.

\fcode{static void }{qi\_class\_real::set\_current\_order}{quadratic\_order \& QO}{}
\fcode{static void }{qi\_class::verbose}{int state}{}

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

\ASGN

	Let \MATH{A} be of type \BF{qi\_class\_real}.
	Assignment is the same as in \BF{qi\_class}, with the exception that
	if the current quadratic order is not real, the \BF{error\_handler}
	will be evoked.  Also, some of the functions admit an optional
	parameter specifying the distance of \MATH{A}.  If this parameter is
	omitted, the distance will be set to \MATH{0}.

\fcode{void }{A.assign\_zero}{}{}
\fcode{void }{A.assign\_one}{}{}
\fcode{void }{A.assign\_principal}{const bigint \& x, const bigint \& y, const bigfloat \& dist = 0.0}{}
\fcode{void }{A.assign}{const bigint \& a2, const bigint \& b2, const bigfloat \& dist = 0.0}{}
\fcode{void }{A.assign}{const long a2, const long b2, const bigfloat \& dist = 0.0}{}
\fcode{void }{A.assign}{const quadratic\_form \& qf, const bigfloat \& dist = 0.0}{}
\fcode{void }{A.assign}{const quadratic\_ideal \& B, const bigfloat \& dist = 0.0}{}
\fcode{void }{A.assign}{const qi\_class \& B, const bigfloat \& dist = 0.0}{}
\fcode{void }{A.assign}{const qi\_class\_real \& B}{}

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

\ACCS

	Let \MATH{A} be of type \BF{qi\_class\_real}.
	The access functions are the same as in \BF{qi\_class}, with the
	addition of the function \BF{get\_distance}.

\cfcode{bigint }{A.get\_a}{}{}
\cfcode{bigint }{A.get\_b}{}{}
\cfcode{bigint }{A.get\_c}{}{}
\cfcode{bigfloat }{A.get\_distance}{}{
	returns the distance of \MATH{A}.}
\cfcode{static quadratic\_order * }{A.get\_current\_order}{}{}
\cfcode{static bigint }{A.discriminant}{}{}

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

\ARTH

	Let \MATH{A} be of type \BF{qi\_class\_real}.
	The arithmetic operations are identical to \BF{qi\_class}, with the
	exception that the distance of the result is also computed.

\fcode{void }{multiply}{qi\_class\_real \& C, const qi\_class\_real \& A, const qi\_class\_real \& B}{}
\fcode{void }{multiply\_real}{qi\_class\_real \& C, const qi\_class\_real \& A, const qi\_class\_real \& B}{}
\fcode{void }{A.invert}{}{}
\fcode{void }{inverse}{qi\_class\_real \& A, const qi\_class\_real \& B}{}
\fcode{qi\_class\_real }{inverse}{qi\_class\_real \& A}{}
\fcode{void }{divide}{qi\_class\_real \& C, const qi\_class\_real \& A, const qi\_class\_real \& B}{}
\fcode{void }{square}{qi\_class\_real \& C, const qi\_class\_real \& A}{}
\fcode{void }{square\_real}{qi\_class\_real \& C, const qi\_class\_real \& A}{}
\fcode{void }{power}{qi\_class\_real \& C, const qi\_class\_real \& A, const bigint \& i}{}
\fcode{void }{power}{qi\_class\_real \& C, const qi\_class\_real \& A, const long i}{}
\fcode{void }{power\_real}{qi\_class\_real \& C, const qi\_class\_real \& A, const bigint \& i}{}
\fcode{void }{power\_real}{qi\_class\_real \& C, const qi\_class\_real \& A, const long i}{}

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

\COMP

	Comparisons are identical to \BF{qi\_class}.
	Let \MATH{A} be an instance of type \BF{qi\_class\_real}.

\cfcode{bool }{A.is\_zero}{}{}
\cfcode{bool }{A.is\_one}{}{}
\cfcode{bool }{A.is\_equal}{const qi\_class\_real \& B}{}

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

\BASIC

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

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

\HIGH

	Let \MATH{A} be of type \BF{qi\_class\_real}.  The following two
	functions are the same as the corresponding \BF{qi\_class} functions.

\fcode{bool }{prime\_ideal}{qi\_class\_real A, const bigint \& p}{
	the distance of \MATH{A} is set to \MATH{0}.}

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

\SSTITLE{Reduction operator}

\fcode{void }{A.rho}{}{
        applies the reduction operator \MATH{rho} once to A, resulting in 
	another reduced representative of the same equivalence class.  The
	distance of \MATH{A} is adjusted appropriately.}

\fcode{void }{apply\_rho}{qi\_class\_real \& C, const qi\_class\_real \& A}{
        sets \MATH{C} to the result of the reduction operator \MATH{rho} being
        applied once to A.  The distance of \MATH{C} is set appropriately.}

\fcode{qi\_class\_real }{apply\_rho}{qi\_class\_real \& A}{
        returns a \BF{qi\_class\_real} corresponding to the result of the
	reduction operator \MATH{rho} being applied once to A.  The distance
	of the return value is set appropriately.}

\fcode{void }{A.inverse\_rho}{}{
        applies the inverse reduction operator \MATH{rho^{-1}} once to A,
	resulting in another reduced representative of the same equivalence
	class.  The distance of \MATH{A} is adjusted appropriately.}

\fcode{void }{apply\_inverse\_rho}{qi\_class\_real \& C, const qi\_class\_real \& A}{
        sets \MATH{C} to the result of the inverse reduction operator
	\MATH{rho^{-1}} being
        applied once to A.  The distance of \MATH{C} is set appropriately.}

\fcode{qi\_class\_real }{apply\_inverse\_rho}{qi\_class\_real \& A}{
        returns a \BF{qi\_class\_real} corresponding to the result of the
	inverse reduction operator \MATH{rho^{-1}} being applied once to A.
	The distance of the return value is set appropriately.}

\fcode{qi\_class\_real }{nearest}{qi\_class\_real \& S, const bigfloat \& E}{
	returns the \BF{qi\_class\_real} in the same class as \MATH{S} whose
	distance from \MATH{S} is as close to \MATH{E} in value as possible.}

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

\SSTITLE{Equivalence and principality testing}

	The parameter \MATH{dist} is optional in all the equivalence and
	principality testing functions.

\cfcode{bool }{A.is\_equivalent}{const qi\_class\_real \& B, bigfloat \& dist}{
	returns \TRUE\ if \MATH{A} and \MATH{B} are in the same ideal
	equivalence class, \FALSE\ otherwise.
	If \MATH{A} and \MATH{B} are equivalent, \MATH{dist} is set to the
	distance from \MATH{B} to \MATH{A}, otherwise it is set to the
	regulator of the current quadratic order.
	At the moment, \BF{is\_equivalent\_buch} is the only 
	algorithm that is implemented, and this function simple calls it.}

\cfcode{bool }{A.is\_equivalent\_buch}{const qi\_class\_real \& B, bigfloat \& dist}{
	tests whether \MATH{A} and \MATH{B} are equivalent using the 
	unconditional method
	of \cite{BBQuadOrd} assuming that the regulator is not known.}

%\cfcode{bool }{A.is\_equivalent\_subexp}{const qi\_class\_real \& B, bigfloat \& dist}{
%	tests whether \MATH{A} and \MATH{B} are equivalent using the 
%	sub-exponential method of \cite{CAbel} whose complexity is conditional
%	on the ERH.}

\cfcode{bool }{A.is\_principal}{bigfloat \& dist}{
	returns \TRUE\ if \MATH{A} is principal, \FALSE\ otherwise.
	If \MATH{A} is principal, \MATH{d} is set to the distance from
	\MATH{(1)}, otherwise it is set to the regulator of the current
	quadratic order.  At the moment, \BF{is\_principal\_buch} is the
	only algorithm that is implemented, and this function simply calls it.}

\cfcode{bool }{A.is\_principal\_buch}{bigfloat \& dist}{
	tests whether \MATH{A} is principal using the unconditional method of
	\cite{BBQuadOrd} assuming that the regulator is not known.}

%\cfcode{bool }{A.is\_principal\_subexp}{bigfloat \& dist}{
%	tests whether \MATH{A} is principal using the sub-exponential method of
%	\cite{CAbel} whose complexity is conditional on the ERH. }

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

\SSTITLE{Orders of elements in the class group}

	These functions work in exactly the same way as \BF{qi\_class}.

\cfcode{bigint }{A.order\_in\_CL}{}{}

\cfcode{bigint }{A.order\_BJT}{long v}{}

\cfcode{bigint }{A.order\_h}{}{}

\cfcode{bigint }{A.order\_mult}{bigint \& h, rational\_factorization \& hfact}{}

\cfcode{bigint }{A.order\_shanks}{}{}

%\cfcode{bigint }{A.order\_subexp}{}{}

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

\SSTITLE{Discrete logarithms in the class group}

	These functions work in exactly the same way as \BF{qi\_class}.

\cfcode{bool }{A.DL}{const qi\_class\_real \& G, bigint \& x}{}

\cfcode{bool }{A.DL\_BJT}{const qi\_class\_real \& G, bigint \& x, long v}{}

%\cfcode{bool }{A.DL\_h}{const qi\_class\_real \& G, bigint \& x}{}

%\cfcode{bool }{A.DL\_subexp}{const qi\_class\_real \& G, bigint \& x}{}

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

\SSTITLE{Structure of a subgroup of the class group}

	These functions work in exactly the same way as \BF{qi\_class}.

\fcode{base\_vector<bigint> }{subgroup}{base\_vector<qi\_class\_real> \& G, base\_vector<qi\_class\_real> \& factor\_base, bigint\_matrix \& U}{}

\fcode{base\_vector<bigint> }{subgroup\_BJT}{base\_vector<qi\_class\_real> \& G, base\_vector<qi\_class\_real> \& factor\_base, bigint\_matrix \& U, base\_vector<long> \& v}{}

%\fcode{base\_vector<bigint> }{subgroup\_h}{base\_vector<qi\_class\_real> \& G, base\_vector<qi\_class\_real> \& factor\_base, bigint\_matrix \& U}{}

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

\IO

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

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

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

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

%\NOTES

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

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

main()
{
  quadratic_order QO;
  qi_class_real A,B,C,U;
  bigint D,p,x;
  bigfloat dist;

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

  qi_class_real::set_current_order(QO);

  /* compute 2 prime ideals */
  p = 3;
  while (!prime_ideal(A,p))
    p = next_prime(p);
  p = next_prime(p);
  while (!prime_ideal(B,p))
    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";

  cout << "A principal? - " << A.is_principal(dist) << "\n";
  cout << "distance = " << dist << "\n";
  U.assign_one();
  C = nearest(U,dist);
  cout << C << "\n\n";

  cout << "A equivalent to B? - " << A.is_equivalent(B,dist) << "\n";
  cout << "distance = " << dist << "\n";
  C = nearest(B,dist);
  cout << C << "\n";
}
\end{verbatim}

example:

\begin{verbatim}
Please enter a quadratic discriminant: 178936222537081

A = (3, 13376701, 0)
B = (5, 13376701, 0)
C = (A^-1*B^3)^2 = (140625, 13334741, 2.1972245773362194)
|<C>| = 65
A principal? - 0
distance = 905318.66551222335
(1, 13376703, 905318.66551222335)

A equivalent to B? - 0
distance = 905318.66551222335
(5, 13376701, 905318.66551222335)
\end{verbatim}

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

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

\AUTHOR
	Michael J. Jacobson, Jr.

\end{lidia_man}
