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

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

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

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

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

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

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

\DESCRIPTION
	A \BF{qi\_class} 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} is
	the discriminant of a quadratic order.  If the quadratic order is
	imaginary, then this ideal is the unique representative of its
	equivalence class.  If not, then it is one of a finite set of
	reduced representatives.

	This class was designed to be used for computations in 
	the ideal equivalence class group of quadratic orders; the class
	\BF{quadratic\_ideal} describes general fractional quadratic ideals,
	and can be used for more general applications.

	The main difference between this class and \BF{quadratic\_ideal} is
	that a pointer to a \BF{quadratic\_order} is not stored with every
	instance of the class.  Instead, there is a global quadratic order
	to which every current \BF{qi\_class} belongs.  This strategy is
	similar to that used for the global
	modulus of the \BF{bigmod} class and is logical here,
	since most computations using this class will be related to
	only one quadratic order at a time.
	Of course, if the global order is changed, all the existing instances
	of \BF{qi\_class} are invalidated.

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

\CONS

\fcode{ct }{qi\_class}{}{}
\fcode{ct }{qi\_class}{const quadratic\_form \& qf}{
	if the discriminant of \MATH{qf} is the same as the discriminant of
	the current quadratic order, initializes with a reduced representative
	of the equivalence class to which the positively oriented ideal
	corresponding to \MATH{qf} belongs, otherwise the \BF{error\_handler}
	will be evoked.  If \MATH{qf} is not primitive,
	the \BF{error\_handler} will also be evoked.}
\fcode{ct }{qi\_class}{const quadratic\_ideal \& A}{
	if \MATH{A} is an ideal of the current quadratic order, initializes
	a \BF{qi\_class} representing the equivalence class of \MATH{A},
	otherwise the \BF{error\_handler} will be evoked.  If \MATH{A}
	is not invertible, the \BF{error\_handler} will also be evoked.}
\fcode{ct }{qi\_class}{const qi\_class\_real \& A}{
	initializes a copy of \MATH{A}}
\fcode{ct }{qi\_class}{const qi\_class \& A}{
	initializes a copy of \MATH{A}}
\fcode{dt }{\MATH{\sim}qi\_class}{}{}

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

\INIT

	Before any arithmetic is done with a \BF{qi\_class}, the 
	current quadratic order must be initialized.  If this order is real, it
	is also valid for all instances of \BF{qi\_class\_real}.

\fcode{static void }{qi\_class::set\_current\_order}{quadratic\_order \& QO}{
	sets the current quadratic order to \MATH{QO}.}
\fcode{static void }{qi\_class::verbose}{int state}{
        sets the amount of information which is printed during computations.
        If \MATH{state = 1}, then information such as elapsed CPU time is
        printed after and during some computations.  If \MATH{state = 0}, no
        extra information is printed.}

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

\ASGN

	Let \MATH{A} be of type \BF{qi\_class}.
        The  operator  \TT{=}  is   overloaded.   For  efficiency
	reasons,  the  following  functions are also implemented:

\fcode{void }{A.assign\_zero}{}{
	\MATH{A = (0)}, the zero ideal.}
\fcode{void }{A.assign\_one}{}{
	\MATH{A = (1)}, the whole order.}
\fcode{void }{A.assign\_principal}{const bigint \& x, const bigint \& y}{
	sets \MATH{A} to a reduced representative of the principal ideal
	generated by \MATH{x + y (\Delta + \SQRT{\Delta}) / 2}, where
	\MATH{\Delta} is the discriminant of the current quadratic order.}
\fcode{void }{A.assign}{const bigint \& a2, const bigint \& b2}{
	if \MATH{[a2\Z + (b2 + \SQRT{\Delta})/2 ~ \Z]} is an ideal of the
	current quadratic order,
	\MATH{A} is set to a reduced representative of its equivalence class,
	otherwise the \BF{error\_handler} will be evoked. If the resulting
	reduced representative is not invertible, the \BF{error\_handler} will
	also be evoked.}
\fcode{void }{A.assign}{const long a2, const long b2}{
	if \MATH{[a2\Z + (b2 + \SQRT{\Delta})/2~ \Z]} is an ideal of the
	current quadratic order,
	\MATH{A} is set to a reduced representative of its equivalence class,
	otherwise the \BF{error\_handler} will be evoked. If the resulting
	reduced representative is not invertible, the \BF{error\_handler} will
	also be evoked.}
\fcode{void }{A.assign}{const quadratic\_form \& qf}{
	if the discriminant of \MATH{qf} is the same as the discriminant of
	the current quadratic order, sets \MATH{A} to a reduced representative
	of the equivalence class to which the positively oriented ideal
	corresponding to \MATH{qf} belongs, otherwise the \BF{error\_handler}
	will be evoked.  If \MATH{qf} is not primitive,
	the \BF{error\_handler} will also be evoked.}
\fcode{void }{A.assign}{const quadratic\_ideal \& B}{
	if \MATH{B} is an ideal of the current quadratic order, sets \MATH{A}
	to a reduced representative of the equivalence class to which \MATH{B}
	belongs, otherwise the \BF{error\_handler} will be evoked.
	If \MATH{B} is not invertible, the \BF{error\_handler} will also be
	evoked.}
\fcode{void }{A.assign}{const qi\_class\_real \& B}{
	\MATH{A = B}.}
\fcode{void }{A.assign}{const qi\_class \& B}{
	\MATH{A = B}.}

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

\ACCS

	Let \MATH{A} be of type \BF{qi\_class}.

\cfcode{bigint }{A.get\_a}{}{
        returns the coefficient \MATH{a} in the representation 
	\MATH{A = [a\Z + (b + \SQRT{\Delta})/2~\Z]}, where \MATH{\Delta} is
	the discriminant of the current quadratic order.}
\cfcode{bigint }{A.get\_b}{}{
        returns the coefficient \MATH{b} in the representation 
	\MATH{A = [a\Z + (b + \SQRT{\Delta})/2~ \Z]}, where \MATH{\Delta} is
	the discriminant of the current quadratic order.}
\cfcode{bigint }{A.get\_c}{}{
        returns the value \MATH{c = (b^2 - \Delta) / (4a)} corresponding to
	the representation \MATH{A = [a\Z + (b + \SQRT{\Delta})/2~ \Z]}, where
	\MATH{\Delta} is the discriminant of the current quadratic order.}
\cfcode{static bigint }{A.discriminant}{}{
        returns the discriminant of the current quadratic order.}
\cfcode{static quadratic\_order * }{A.get\_current\_order}{}{
        returns a pointer to the current quadratic order.}

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

\ARTH

	Let \MATH{A} be of type \BF{qi\_class}.
	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} 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 }{multiply}{qi\_class \& C, const qi\_class \& A, const qi\_class \& B}{
	\MATH{C} is set to a reduced representative of \MATH{A * B}.  The
	appropriate function \BF{multiply\_imag} or \BF{multiply\_real} is
	used, depending on whether the current order is imaginary or real.}

\fcode{void }{multiply\_imag}{qi\_class \& C, const qi\_class \& A, const qi\_class \& B}{
	\MATH{C} is set to a reduced representative of \MATH{A * B}.  In the
	interest of efficiency, no checking is done to ensure that the
	current order is actually imaginary.}

%\fcode{void }{nucomp}{qi\_class \& C, const qi\_class \& A, const qi\_class \& B}{
%	\MATH{C} is set to a reduced representative of \MATH{A * B} using the
%	NUCOMP algorithm of Shanks \cite{CCourse}.  In the
%	interest of efficiency, no checking is done to ensure that the
%	current order is actually imaginary.}

\fcode{void }{multiply\_real}{qi\_class \& C, const qi\_class \& A, const qi\_class \& B}{
	\MATH{C} is set to a reduced representative of \MATH{A * B}.  In the
	interest of efficiency, no checking is done to ensure that the
	current order is actually real.}
	
\fcode{void }{A.invert}{}{
	\MATH{A = A^{-1}}.}

\fcode{void }{inverse}{qi\_class \& A, const qi\_class \& B}{
	\MATH{A = B^{-1}}.}

\fcode{qi\_class }{inverse}{qi\_class \& A}{
	\MATH{A^{-1}} is returned.}

\fcode{void }{divide}{qi\_class \& C, const qi\_class \& A, const qi\_class \& B}{
	\MATH{C} is set to a reduced representative of \MATH{A * B^{-1}} unless
	\MATH{B = (0)}, in which case the \BF{error\_handler} will be evoked.}

\fcode{void }{square}{qi\_class \& C, const qi\_class \& A}{
	\MATH{C} is set to a reduced representative of \MATH{A^2}.  The
        appropriate function \BF{square\_imag} or \BF{square\_real} is
        used, depending on whether the current order is imaginary or real.}

\fcode{void }{square\_imag}{qi\_class \& C, const qi\_class \& A}{
        \MATH{C} is set to a reduced representative of \MATH{A^2}.  In the
        interest of efficiency, no checking is done to ensure that the
        current order is actually imaginary.}

%\fcode{void }{nudupl}{qi\_class \& C, const qi\_class \& A}{
%        \MATH{C} is set to a reduced representative of \MATH{A^2} using the
%	NUDUPL algorithm of Shanks \cite{CCourse}.  In the
%        interest of efficiency, no checking is done to ensure that the
%        current order is actually imaginary.}

\fcode{void }{square\_real}{qi\_class \& C, const qi\_class \& A}{
        \MATH{C} is set to a reduced representative of \MATH{A^2}.  In the
        interest of efficiency, no checking is done to ensure that the
        current order is actually real.}

\fcode{void }{power}{qi\_class \& C, const qi\_class \& A, const bigint \& i}{
	\MATH{C} is set to a reduced representative of \MATH{A^i}.  If 
	\MATH{i < 0}, \MATH{B^i} is computed where \MATH{B = A^{-1}}.
	The appropriate function
	\BF{power\_imag} of \BF{power\_real} is used, depending on whether the
	current order is imaginary or real.}

\fcode{void }{power}{qi\_class \& C, const qi\_class \& A, const long i}{}

\fcode{void }{power\_imag}{qi\_class \& C, const qi\_class \& A, const bigint \& i}{
        \MATH{C} is set to a reduced representative of \MATH{A^i}.  If 
        \MATH{i < 0}, \MATH{B^i} is computed where \MATH{B = A^{-1}}.
	In the interest of efficiency, no checking is done to ensure that the
        current order is actually imaginary.}

\fcode{void }{power\_imag}{qi\_class \& C, const qi\_class \& A, const long i}{}

\fcode{void }{power\_real}{qi\_class \& C, const qi\_class \& A, const bigint \& i}{
        \MATH{C} is set to a reduced representative of \MATH{A^i}.  If 
        \MATH{i < 0}, \MATH{B^i} is computed where \MATH{B = A^{-1}}.
	In the interest of efficiency, no checking is done to ensure that the
        current order is actually real.}

\fcode{void }{power\_real}{qi\_class \& C, const qi\_class \& A, const long i}{}

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

\COMP

	The  binary operators \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.
	Let \MATH{A} be an instance of type \BF{qi\_class}.

\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 qi\_class \& B}{
	returns \TRUE\ if \MATH{A} and \MATH{B} are equal, \FALSE\ otherwise.}

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

\BASIC

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

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

\HIGH

	Let \MATH{A} be of type \BF{qi\_class}.

\fcode{bool }{prime\_ideal}{qi\_class A, const bigint \& p}{
	attempts to set \MATH{A} to a reduced representative of the prime ideal
	lying over the prime \MATH{p}.  If successful, i.e. the Kronecker
	symbol \MATH{(\Delta/p) \NEQ -1}, and the prime ideal is invertible,
	\TRUE\ is returned, otherwise \FALSE\.}

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

\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.  If the
	current quadratic order is not real, the \BF{error\_handler} will be
	evoked.}

\fcode{void }{apply\_rho}{qi\_class \& C, const qi\_class \& A}{
        sets \MATH{C} to the result of the reduction operator \MATH{rho} being
	applied once to A.  If the current quadratic order is not real, the
	\BF{error\_handler} will be evoked.}

\fcode{qi\_class }{apply\_rho}{qi\_class \& A}{
        returns a \BF{qi\_class} corresponding to the result of the reduction
	operator \MATH{rho} being
	applied once to A.  If the current quadratic order is not real, the
	\BF{error\_handler} will be evoked.}

\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.  If the current quadratic order is not real, the
	\BF{error\_handler} will be evoked.}

\fcode{void }{apply\_inverse\_rho}{qi\_class \& C, const qi\_class \& A}{
        sets \MATH{C} to the result of the inverse reduction operator
	\MATH{rho^{-1}} being applied once to A.  If the current quadratic
	order is not real, the \BF{error\_handler} will be evoked.}

\fcode{qi\_class }{apply\_inverse\_rho}{qi\_class \& A}{
        returns a \BF{qi\_class} corresponding to the result of the inverse 
	reduction operator \MATH{rho^{-1}} being
	applied once to A.  If the current quadratic order is not real, the
	\BF{error\_handler} will be evoked.}

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

\SSTITLE{Equivalence and principality testing}

\cfcode{bool }{A.is\_equivalent}{const qi\_class \& B}{
	returns \TRUE\ if \MATH{A} and \MATH{B} are in the same ideal
	equivalence class, \FALSE\ otherwise.
	If the current quadratic order is imaginary, this
	is simply an equality test.
	If the current order is real, the \BF{qi\_class\_real} function of the
	same name is used.}

\cfcode{bool }{A.is\_principal}{}{
	returns \TRUE\ if \MATH{A} is principal, \FALSE\ otherwise.
	If the current quadratic order is imaginary, this is simply an
	equality test with \MATH{(1)}.
	If the current order is real, the \BF{qi\_class\_real} function of the
	same name is used.}

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

\SSTITLE{Orders of elements in the class group}

\cfcode{bigint }{A.order\_in\_CL}{}{
	returns the order of \MATH{A} in the ideal class group of the
	current quadratic order, i.e. the
	least positive integer \MATH{x} such that \MATH{A^x \SIM (1)}.  It
	uses one of the following order functions depending on whether the
	class number is known and the size of the discriminant.}

\cfcode{bigint }{A.order\_BJT}{long v}{
	computes the order of \MATH{A} using the unconditional method of
	\cite{BJTAb} for imaginary orders and a variation for real orders,
	assuming that the class number is not known.
	The parameter \MATH{v} is the size of the initial step-width.  This
	parameter is ignored if the corresponding quadratic order is real.}

\cfcode{bigint }{A.order\_h}{}{
	computes the order of \MATH{A} using the method of 
	\cite{Sclass} where the class number is known.  The class number of
	the current quadratic order is computed if it has not been already.}

\cfcode{bigint }{A.order\_mult}{bigint \& h, rational\_factorization \& hfact}{
	computes the order of \MATH{A} using the method of 
	\cite{Sclass} where \MATH{h} is a multiple of the order and
	\MATH{hfact} is a \BF{rational\_factorization} of \MATH{h}.}

\cfcode{bigint }{A.order\_shanks}{}{
	computes the order of \MATH{A} using the baby-step giant-step method
	of \cite{Sclass} of complexity \MATH{O(|\Delta|^{(1/5)}}.  The result
	is correct, but the complexity result is conditional on the ERH.}

\cfcode{bigint }{A.order\_subexp}{}{
	computes the order of \MATH{A} using a sub-exponential method
	conditional on the ERH.
	The algorithms for both real and imaginary
	orders simply compute the class number with the appropriate 
	sub-exponential algorithm and then use \BF{order\_h}.}

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

\SSTITLE{Discrete logarithms in the class group}

\cfcode{bool }{A.DL}{const qi\_class \& 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}.
	At the moment, \BF{DL\_BJT} is the only algorithm that is implemented,
	and this function simply calls it.}

\cfcode{bool }{A.DL\_BJT}{const qi\_class \& G, bigint \& x, long v}{
	computes the discrete logarithm of \MATH{A} to the base \MATH{G}
	using the unconditional method of \cite{BJTAb} for imaginary orders
	and a variation for real orders, assuming that the class number is
	not known.}

%\cfcode{bool }{A.DL\_h}{const qi\_class \& G, bigint \& x}{
%	computes the discrete logarithm of \MATH{A} to the base \MATH{G} using
%	the method of \cite{BJTordgiven} where the class number is known.}

%\cfcode{bool }{A.DL\_subexp}{const qi\_class \& G, bigint \& x}{
%	computes the discrete logarithm of \MATH{A} to the base \MATH{G} using
%	the sub-exponential method of \cite{BDDL}, whose complexity is
%	conditional on the ERH.}

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

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

\fcode{base\_vector<bigint> }{subgroup}{base\_vector<qi\_class> \& G, base\_vector<qi\_class> \& factor\_base, bigint\_matrix \& U}{
	returns the vector of invariants representing the structure of the
	subgroup generated by the classes contained in \MATH{G} and a 
	matrix representing the corresponding isomorphism.
	The vector \MATH{factor\_base} contains the elements of \MATH{G} that
	enlarge \MATH{S} during the computation.  
	At the moment, \BF{subgroup\_BJT} is the only algorithm that is
	implemented, and this function simply calls it.}


\fcode{base\_vector<bigint> }{subgroup\_BJT}{base\_vector<qi\_class> \& G, base\_vector<qi\_class> \& factor\_base, bigint\_matrix \& U, base\_vector<long> \& v}{
	computes the structure of the subgroup generated by \MATH{G} using the
	unconditional methods of \cite{BJTAb} for imaginary orders and 
	a variation for real orders, assuming that the class number is not
	known.}

%\fcode{base\_vector<bigint> }{subgroup\_h}{base\_vector<qi\_class> \& G, base\_vector<qi\_class> \& factor\_base, bigint\_matrix \& U}{
%	computes the structure of the subgroup generated by \MATH{G} using
%	the method of \cite{BJTordgiven} where the class number is known.}

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

\IO

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

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

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

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

%\NOTES

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

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

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

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

  qi_class::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";

  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 = (3, 1)
B = (5, 1)
C = (A^-1*B^3)^2 = (2856, -271)
|<C>| = 20299
log_B A = 17219
\end{verbatim}

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

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

\AUTHOR
	Michael J. Jacobson, Jr.

\end{lidia_man}
