%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% %% quadratic_order.tex LiDIA documentation %% %% This file contains the documentation of the class quadratic_order %% %% Copyright (c) 1996 by LiDIA-Group %% %% Author: Michael J. Jacobson, Jr. %% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \NAME \CLASS{quadratic_order} \dotfill class describing quadratic orders %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \ABSTRACT \code{quadratic_order} is a class for representing quadratic orders and computing many related invariants and functions, such as the ideal class number, regulator, $L$-function, Littlewood indices, etc \dots %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \DESCRIPTION A \code{quadratic_order} $\Or$ is represented simply by a \code{bigint} $\D$, which is a quadratic discriminant, i.e., a non-square integer congruent to 0 or 1 modulo 4. Unlike the case of higher degree orders (see the description of \code{order}), we do not require a multiplication table to perform arithmetic with elements in the order since we can represent any element in $\Or$ as $a + b(\D + \sqrt{\D})/2$ where $a,b \in \bbfZ$. Several invariants related to a specific quadratic order are stored along with the discriminant, since some of them can be very time-consuming to compute, and knowledge of them often simplifies other computations. We store the following invariants once they have been computed: \begin{itemize} \item factorization of $\D$ (\code{rational_factorization}) \item ideal class number (\code{bigint}) \item approximation of the regulator (\code{bigfloat}) \item elementary divisors of the ideal class group (\code{base_vector< bigint >}) \item generators of each cyclic subgroup in the decomposition of the ideal class group (\code{base_vector} of \code{qi_class}) \item approximation of $L(1,\chi )$ (\code{bigfloat}) \item approximation of $C(\D )$ (\code{bigfloat}) \end{itemize} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \CONS \begin{fcode}{ct}{quadratic_order}{} initializes an empty quadratic order ($\D = 0$)). \end{fcode} \begin{fcode}{ct}{quadratic_order}{long $\D$} if $\D$ is a quadratic discriminant, initializes a \code{quadratic_order} of discriminant $\D$, otherwise an empty quadratic order ($\D = 0$) is initialized. \end{fcode} \begin{fcode}{ct}{quadratic_order}{const bigint & $\D$} if $\D$ is a quadratic discriminant, initializes a \code{quadratic_order} of discriminant $\D$, otherwise an empty quadratic order ($\D = 0$) is initialized. \end{fcode} \begin{fcode}{ct}{quadratic_order}{const quadratic_order & $\Or$} initializes a copy of $\Or$. \end{fcode} \begin{fcode}{dt}{~quadratic_order}{} \end{fcode} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \INIT Let $\Or$ be of type \code{quadratic_order}. \begin{fcode}{static void}{quadratic_order::verbose}{int $\mathit{state}$} sets the amount of information which is printed during computations. If $\mathit{state} = 1$, then the elapsed CPU time of some computations is printed. If $\mathit{state} = 2$, then extra run-time data is printed during the execution of the subexponential class group algorithm and verifications. If $\mathit{state} = 0$, no extra information is printed. The default is $\mathit{state} = 0$. \end{fcode} \begin{fcode}{static void}{quadratic_order::verification}{int $\mathit{level}$} sets the level of post-computation verification performed. If $\mathit{level} = 0$ no extra verification is performed, otherwise, the following levels of verification are used: \begin{itemize} \item $\mathit{level} = 1$ --- regulator is verified, orders of generators of the class group are verified \item $\mathit{level} = 2$ --- same as $1$, plus all prime ideals not in the factor base with norm less than Bach's bound are factored over the factor base (only for the subexponential algorithm) \item $\mathit{level} = 3$ --- same as $2$, plus all prime ideals with norm less than Bach's bound are represented over a system of generators (only for the subexponential algorithm) %\item $\mathit{level} = 4$ --- same as $2$, but all primes less than %Minkowski's bound are factored over the factor base %\item $\mathit{level} = 5$ --- same as $3$, but all primes less than %Minkowski's bound are represented over a system of generators \end{itemize} Note that level $2$ is sufficient to provide a conditional verification of the output of the subexponential algorithm under the Extended Riemann Hypothesis (ERH). %and level $5$ provides an unconditional verification. Naturally, an %unconditional verification is rather time-consuming, and is not recommended %for large discriminants. The success of the verification will be output only if the verbose mode is set to a non-zero value, but any failures are always output. The default is $\mathit{level} = 0$. \end{fcode} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \ASGN Let $\Or$ be of type \code{quadratic_order}. The operator \code{=} is overloaded. For efficiency reasons, the following functions are also implemented: \begin{fcode}{bool}{$\Or$.assign}{long $\D$} if $D$ is a quadratic discriminant, $\Or$ is set to the quadratic order of discriminant $D$ and \TRUE is returned, otherwise $\Or$ is set to an empty quadratic order ($\D = 0$) and \FALSE is returned. \end{fcode} \begin{fcode}{bool}{$\Or$.assign}{const bigint & $\D$} if $D$ is a quadratic discriminant, $\Or$ is set to the quadratic order of discriminant $D$ and \TRUE is returned, otherwise $\Or$ is set to an empty quadratic order ($\D = 0$) and \FALSE is returned. \end{fcode} \begin{fcode}{void}{$\Or$.assign}{const quadratic_order & $\Or_2$} $\Or \assign \Or_2$. \end{fcode} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \ACCS Let $\Or$ be of type \code{quadratic_order}. \begin{cfcode}{bigint}{$\Or$.discriminant}{} returns the discriminant $\D$ of $\Or$. \end{cfcode} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \COMP The binary operators \code{==}, \code{!=}, \code{<=}, \code{<} (true subset), \code{>=}, \code{>} and the unary operator \code{!} (comparison with $(0)$) are overloaded and can be used in exactly the same way as in the programming language C++. Let $\Or$ be of type \code{quadratic_order}. \begin{cfcode}{bool}{$\Or$.is_zero}{} returns \TRUE if the discriminant is zero, \FALSE otherwise. \end{cfcode} \begin{cfcode}{bool}{$\Or$.is_equal}{const quadratic_order & $\Or_2$} returns \TRUE if $\Or = \Or_2$, \FALSE otherwise. \end{cfcode} \begin{fcode}{bool}{$\Or$.is_subset}{quadratic_order & $\Or_2$} returns \TRUE if $\Or$ is a subset of $\Or_2$, \FALSE otherwise. The discriminant is factored if necessary. \end{fcode} \begin{fcode}{bool}{$\Or$.is_proper_subset}{quadratic_order & $\Or_2$} returns \TRUE if $\Or$ is a proper subset of $\Or_2$, \FALSE otherwise. The discriminant is factored if necessary. \end{fcode} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \BASIC \begin{fcode}{bool}{is_quadratic_discriminant}{const long $\D$} returns \TRUE if $D$ is a quadratic discriminant, \FALSE otherwise. \end{fcode} \begin{fcode}{bool}{is_quadratic_discriminant}{const bigint & $\D$} returns \TRUE if $D$ is a quadratic discriminant, \FALSE otherwise. \end{fcode} \begin{cfcode}{bool}{$\Or$.is_imaginary}{} returns \TRUE if $\Or$ is an imaginary quadratic order (negative discriminant), \FALSE otherwise. \end{cfcode} \begin{cfcode}{bool}{$\Or$.is_real}{} returns \TRUE if $\Or$ is a real quadratic order (positive discriminant), \FALSE otherwise. \end{cfcode} \begin{fcode}{void}{swap}{quadratic_order & $A$, quadratic_order & $B$} exchanges $A$ and $B$. \end{fcode} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \HIGH Let $\Or$ be of type \code{quadratic_order}. \begin{fcode}{int}{$\Or$.bach_bound}{} returns a constant such that the prime ideals of norm less than this constant generate the class group (under the ERH). This function assumes that $\Or$ is not maximal. \end{fcode} \begin{fcode}{int}{$\Or$.bach_bound}{bool $\mathit{is\uscore max}$} returns a constant such that the prime ideals of norm less than this constant generate the class group (under the ERH). If the parameter is \TRUE, $\Or$ will be assumed to be maximal, otherwise non-maximal. \end{fcode} \begin{fcode}{bigint}{$\Or$.conductor}{} returns the conductor of $\Or$, i.e., the integer $f$ such that $\D = f^2 \D_0$ where $\D_0$ is a fundamental discriminant (the discriminant of a maximal order). The factorization of the discriminant is computed if it has not been already. \end{fcode} \begin{fcode}{bool}{$\Or$.is_maximal}{} returns \TRUE if $\Or$ is a maximal order, \FALSE otherwise. The factorization of the discriminant is computed if it has not been already. \end{fcode} \begin{fcode}{quadratic_order}{$\Or$.maximize}{} returns the maximal order in which $\Or$ is contained. The factorization of the discriminant is computed if it has not been already. \end{fcode} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \SSTITLE{$L$-functions, Littlewood indices, $C$-function} The function $L(s,\chi ) = \sum_{n=1}^{\infty} \frac{\chi (n)}{n^s}$, where $\chi$ is taken to be the Kronecker symbol, is intimately related to computations in class groups of quadratic orders, especially at $s=1$, due to the analytic class number formula of Dirichlet. The Littlewood indices \cite{Littlewood:1928,Shanks:1973} are values which test the accuracy of Littlewood's bounds on $L(1,\chi )$ and a related function $L_{\D}(1) = (2 - \kronecker{\D}{2})/2 \,L(1,\chi )$ defined by Shanks \cite{Shanks:1973}. Under the ERH, we expect the lower Littlewood indices to be greater than 1 for all discriminants $\D$ (with a few exceptions of very small discriminants) and that they should come close to 1 for discriminants with exceptionally small values of $L(1,\chi )$ or $L_D(1)$. Similarly, we expect the upper Littlewood indices to be less than 1 and to approach 1 for discriminants with exceptionally large values of $L(1,\chi )$ or $L_{\D}(1)$. The function $C(\D) = \prod_{p \geq 3} 1 - \kronecker{\D}{p} / (p-1)$ provides an indication of whether a related quadratic polynomial will have an asymptotically large number of prime values, based on a conjecture of Hardy and Littlewood \cite{Hardy/Littlewood:1923,Fung/Williams:1990}. If $\D$ is odd, then for $A = (1-\D)/4$ the polynomial $x^2 + x + A$ will have a large asymptotic density of prime values when $C(\D )$ is large. If $\D$ is even, then for $A = \D / 4$ the corresponding polynomial is $x^2 + A$. \begin{fcode}{int}{kronecker}{const bigint & $D$, const bigint & $p$} computes the value of the Kronecker symbol $\kronecker{D}{p}$, where $p$ is prime. \end{fcode} \begin{fcode}{long}{$\Or$.generate_optimal_Q}{} generates the optimal value of $Q$ for the function \code{estimate_L1} to compute a sufficiently accurate estimate from which a value $h^*$ can be computed satisfying $h^* < h < 2h^*$ for imaginary orders and $h^* < hR < 2h^*$ for real orders. \end{fcode} \begin{fcode}{long}{$\Or$.get_optimal_Q}{} returns, from a precomputed list, a value of Q that is sufficiently large to satisfy the conditions given above. \end{fcode} \begin{fcode}{long}{$\Or$.generate_optimal_Q_cnum}{const bigfloat & $h_2$, const bigfloat & $t$} generates the optimal value of $Q$ for the function \code{estimate_L1} to compute a sufficiently accurate estimate to prove that $h = h_2$ when the fractional part of the approximation of $h$ is less that $t$. See \cite{Mollin/Williams:1992} for more details. \end{fcode} \begin{fcode}{long}{$\Or$.get_optimal_Q_cnum}{} returns, from a precomputed list, a value of Q that is sufficiently large to satisfy the conditions given above. \end{fcode} \begin{fcode}{bigfloat}{$\Or$.estimate_L}{const int $s$, const long $Q$} computes a truncated product approximation of $L(s, \chi)$ using primes less than $Q$. \end{fcode} \begin{fcode}{bigfloat}{$\Or$.estimate_L1}{const long $Q$} computes an approximation of $L(1, \chi)$ using Bach's averaging method \cite{Bach:1995} with primes less than $2 Q$. \end{fcode} \begin{fcode}{bigfloat}{$\Or$.estimate_L1_error}{const long $Q$} computes an estimate of the error (conditional on EHR) in the approximation of $L(1, \chi)$ using Bach's method \cite{Bach:1995} with primes less than $2Q$. \end{fcode} \begin{fcode}{bigfloat}{$\Or$.Lfunction}{} computes an approximation of $L(1, \chi)$ via the analytic class number formula. The class number and regulator are computed if they have not been already. \end{fcode} \begin{fcode}{bigfloat}{$\Or$.LDfunction}{} returns an approximation of $L_{\D}(1)$. The class number and regulator are computed if they have not been already. \end{fcode} \begin{fcode}{bigfloat}{$\Or$.LLI}{} returns an approximation of the lower Littlewood index related to a lower bound on $L(1, \chi)$ due to Littlewood. The class number and regulator are computed if they have not been already. \end{fcode} \begin{fcode}{bigfloat}{$\Or$.LLI_D}{} returns an approximation of the lower Littlewood index related to a lower bound on $L_{\D}(1)$ due to Shanks. The class number and regulator are computed if they have not been already. \end{fcode} \begin{fcode}{bigfloat}{$\Or$.ULI}{} returns an approximation of the upper Littlewood index related to an upper bound on $L(1, \chi)$ due to Littlewood. The class number and regulator are computed if they have not been already. \end{fcode} \begin{fcode}{bigfloat}{$\Or$.ULI_D}{} returns an approximation of the upper Littlewood index related to an upper bound on $L_{\D}(1)$ due to Shanks. The class number and regulator are computed if they have not been already. \end{fcode} \begin{fcode}{bigfloat}{$\Or$.Cfunction}{} returns an approximation of the function $C(\D)$ accurate to 8 significant digits. The class number, regulator, and the prime factorization of $\D$ are computed if they have not been already. \end{fcode} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \SSTITLE{Regulator, class number, and class group} The regulator is defined as the natural logarithm of the fundamental unit and the class number is the order of the group of ideal equivalence classes. We denote the regulator by $R$, the class group by $\Cl$ and the class number by $h$. By the structure of the class group, we mean the unique positive integers $m_1, \dots, m_k$ with $m_1 > 1$, $m_i \mid m_{i+1}$ for $1 \leq i \leq k$ such that there is an isomorphism $\phi : \Cl \rightarrow \bbfZ /m_1 \bbfZ \times \dots \times \bbfZ /m_k \bbfZ$. The integers $m_i$ are called the elementary divisors of the class group. The following general functions are provided, which intelligently select an appropriate algorithm based on the size of the discriminant. \begin{fcode}{bigfloat}{$\Or$.regulator}{} returns an approximation of the regulator of $\Or$. If the regulator has not already been computed, either \code{regulator_BJT}, \code{regulator_shanks}, or \code{regulator_subexp} is used, depending on the size of the discriminant. If $\Or$ is imaginary, the regulator is set to $1$. \end{fcode} \begin{fcode}{bigint}{$\Or$.class_number}{} returns the ideal class number of $\Or$. If the class number has not already been computed, either \code{class_number_shanks} or \code{class_group_subexp} is used, depending on the size of the discriminant. \end{fcode} \begin{fcode}{base_vector< bigint >}{$\Or$.class_group}{} returns the vector of invariants representing the structure of the ideal class group of $\Or$. If the class group has not already been computed, either \code{class_group_BJT}, \code{class_group_shanks}, \code{class_group_randexp}, \code{class_group_mpqs}, or \code{class_group_siqs} depending on the size of the discriminant. \end{fcode} The following functions all make use of a specific algorithm. \begin{fcode}{bigfloat}{$\Or$.regulator_BJT}{} computes an unconditionally correct approximation of the regulator of $\Or$ using a variation of the algorithm of \cite{Biehl/Buchmann:1995} which has unconditional complexity $\Omikron(\sqrt{R})$. If $\Or$ is not real, the regulator is set to $1$. If the regulator has already been computed, the function simply returns this value. \end{fcode} \begin{fcode}{bigfloat}{$\Or$.regulator_shanks}{} computes an unconditionally correct approximation of the regulator of $\Or$ using the algorithm of \cite{Jacobson/Lukes/Williams:1995} based on the baby-step giant-step method in \cite{Mollin/Williams:1992}, which has complexity $\Omikron(\D ^{1/5})$ under the ERH. If $\Or$ is not real, the regulator is set to $1$. If the regulator has already been computed, the function simply returns this value. \end{fcode} %\begin{fcode}{bigfloat}{$\Or$.regulator_subexp}{} %computes an approximation of the regulator of $\Or$ using the %subexponential algorithm of \cite{Jacobson:1999}. %If $\Or$ is not real, the regulator is set to %$1$. If the regulator has already been computed, the %function simply returns this value. The computation is done by calling %the function \code{class_group_subexp}, so the structure of the class group %is computed simultaneously. %\end{fcode} \begin{fcode}{bool}{$\Or$.verify_regulator}{} returns true if the regulator is correct, as determined by a polynomial-time verification. \end{fcode} \begin{fcode}{bigint}{$\Or$.class_number_shanks}{} computes the ideal class number of $\Or$ using the algorithm of \cite{Fung/Williams:1990} based on the ideas of \cite{LenstraHW:1982} for imaginary quadratic orders, and the algorithm of \cite{Jacobson/Lukes/Williams:1995} based on the ideas in \cite{Mollin/Williams:1992} for real quadratic orders. Both algorithms have complexity $\Omikron(|\D |^(1/5))$, and the correctness and the complexity are both conditional on the truth of the ERH. If the class number has already been computed, the function simply returns this value. \end{fcode} \begin{fcode}{base_vector< bigint >}{$\Or$.class_group_BJT}{} computes the structure of the ideal class group of $\Or$ using the method of \cite{Buchmann/Jabobson/Teske:1997} for imaginary orders and \cite{Jacobson:1998} for real orders, which have complexity $\Omikron(\sqrt{h})$ and $\Omikron(\sqrt{h R})$ respectively. The correctness of both algorithms is conditional on the truth of the ERH but the complexity results are not. If the class group has already been computed, the function simply returns this value. \end{fcode} \begin{fcode}{base_vector< bigint >}{$\Or$.class_group_shanks}{} computes the structure of the ideal class group of $\Or$ using variations of the methods of \cite{Schoof:1982} which have complexity $\Omikron(|\D|^(1/4))$. The correctness and complexity of both algorithms are conditional on the truth of the ERH. If the class group has already been computed, the function simply returns this value. \end{fcode} \begin{fcode}{base_vector< bigint >}{$\Or$.class_group_randexp}{} computes the structure of the ideal class group of $\Or$ using a practical variation of the sub-exponential method of Hafner and McCurley \cite{Hafner/McCurley:1989} due to D\"ullmann \cite{Duellmann_Thesis:1991} for imaginary orders and Cohen, Diaz y Diaz, and Olivier \cite{Cohen/Diaz/Olivier:1993} for real orders, as presented in \cite{Jacobson_Thesis:1999}. Note that if $\Or$ is real, this function also computes the regulator. If the class group has already been computed, the function simply returns this value. Turning the verification off with \code{quadratic_order::verification($0$)} will result in much faster execution of this algorithm, but the result is no longer certifiably correct under the ERH since a smaller factor-base is used than is theoretically necessary. However, as experimental results show \cite{Jacobson:1998}, it is extremely unlikely that the computed result will be false. \end{fcode} \begin{fcode}{base_vector< bigint >}{$\Or$.class_group_mpqs}{} computes the structure of the ideal class group of $\Or$ using the algorithm of \cite{Jacobson:1999} as presented in \cite{Jacobson_Thesis:1999}, in which the relation generation strategy is based on the MPQS factoring algorithm. Note that if $\Or$ is real, this function also computes the regulator. If the class group has already been computed, the function simply returns this value. Turning the verification off with \code{quadratic_order::verification($0$)} will result in much faster execution of this algorithm, but the result is no longer certifiably correct under the ERH since a smaller factor-base is used than is theoretically necessary. However, as experimental results show \cite{Jacobson:1998}, it is extremely unlikely that the computed result will be false. \end{fcode} \begin{fcode}{base_vector< bigint >}{$\Or$.class_group_siqs}{} computes the structure of the ideal class group of $\Or$ using an algorithm from \cite{Jacobson_Thesis:1999}, in which the relation generation strategy is based on the self-initializing MPQS factoring algorithm. Note that if $\Or$ is real, this function also computes the regulator. If the class group has already been computed, the function simply returns this value. Turning the verification off with \code{quadratic_order::verification($0$)} will result in much faster execution of this algorithm, but the result is no longer certifiably correct under the ERH since a smaller factor-base is used than is theoretically necessary. However, as experimental results show \cite{Jacobson:1998}, it is extremely unlikely that the computed result will be false. \end{fcode} \begin{fcode}{base_vector< bigint >}{$\Or$.class_group_lp}{} computes the structure of the ideal class group of $\Or$ using an algorithm from \cite{Jacobson_Thesis:1999}, in which the relation generation strategy is based on the self-initializing MPQS factoring algorithm with large prime variant. Note that if $\Or$ is real, this function also computes the regulator. If the class group has already been computed, the function simply returns this value. Turning the verification off with \code{quadratic_order::verification($0$)} will result in much faster execution of this algorithm, but the result is no longer certifiably correct under the ERH since a smaller factor-base is used than is theoretically necessary. However, as experimental results show \cite{Jacobson:1998}, it is extremely unlikely that the computed result will be false. \end{fcode} \begin{fcode}{bool}{$\Or$.verify_class_group}{int level} returns true if the class group is correct as determined by a polynomial-time verification, using the given verification level \end{fcode} \begin{fcode}{bool}{$\Or$.verify_class_group}{} returns true if the class group is correct as determined by a polynomial-time verification, using the global verification level. \end{fcode} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \SSTITLE{Additional functions} \begin{fcode}{rational_factorization}{$\Or$.factor_h}{} returns a \code{rational_factorization} of the class number. The class number is computed if it has not been already. \end{fcode} \begin{fcode}{bigint}{$\Or$.exponent}{} returns the exponent of the class group, i.e., the largest cyclic factor. The class group is computed if it has not been already. \end{fcode} \begin{fcode}{int}{$\Or$.p_rank}{const bigint & $p$} returns the p-rank of the ideal class group. The class group is computed if it has not been already. \end{fcode} \begin{fcode}{base_vector< qi_class >}{$\Or$.generators}{} returns a vector of generators of the cyclic subgroups of the ideal class group of $\Or$. The class group is computed if it has not been already. \end{fcode} \begin{fcode}{rational_factorization}{$\Or$.factor_discriminant}{} returns the prime factorization of the discriminant of $\Or$ using the 2-Sylow subgroup of the class group. The class group and a set of generators are computed if they have not been already. At present, this function is only implemented for imaginary orders. If $\Or$ is real, the discriminant is simply factored with the \code{rational_factorization} function \code{factor}. \end{fcode} \begin{fcode}{math_vector < bigint >}{$\Or$.represent_over_generators}{qi_class & $A$} returns an exponent vector corresponding to the representation of $A$ over the system of generators of the class group. \end{fcode} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \IO Let $\Or$ be of type \code{quadratic_order}. The \code{istream} operator \code{>>} and the \code{ostream} operator \code{<<} are overloaded. Input consists of reading a \code{bigint} value for the discriminant. Output of a \code{quadratic_order} has the following format: \begin{verbatim} Quadratic Order: Delta = (discriminant of QO) (decimal digits) = (prime factorization of the discriminant of QO) R = (regulator) h = (class number) CL = (vector of class group invariants) generators = (vector of generators of the cyclic subgroups) L(1,X) = (L function) C(Delta) = (C function) \end{verbatim} The discriminant is always displayed, while the other invariants are displayed only if they have been computed. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \SEEALSO \SEE{qi_class}, \SEE{qi_class_real}, \SEE{order} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %\NOTES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \EXAMPLES \begin{quote} \begin{verbatim} #include int main() { bigint D; quadratic_order QO; do { cout << "Please enter a quadratic discriminant: "; cin >> D; } while (!QO.assign(D)); cout << endl; QO.class_group(); QO.generators(); QO.Lfunction(); cout << QO; cout << " ULI = " << QO.ULI() << endl; cout << " LLI = " << QO.LLI() << endl; return 0; } \end{verbatim} \end{quote} Example: \begin{quote} \begin{verbatim} Please enter a quadratic discriminant: -501510767 Quadratic Order: Delta = -501510767 (9) h = 18522 CL = [ 7 7 378 ] generators = [ (3286, 1657) (1144, 439) (2934, 61) ] L(1,X) = 2.5983498285787 ULI = 0.243356600232444 LLI = 16.865670804095 \end{verbatim} \end{quote} For further examples please refer to \path{LiDIA/src/packages/quadratic_order/quadratic_order_appl.cc}. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \AUTHOR Michael J.~Jacobson, Jr.