Ray Class Groups¶
Class Groups of Number Fields
Trac-ticket #15829 adds (among other things) ray class groups to SageMath. The ticket is not yet finished and included into SageMath. It does already contain this file, from Robbert Harron, implementing ray class groups in SageMath. We use this file to have ray class groups functionality available for our adèles and idèles package.
We can compute class groups, ray class groups, and \(S\)-class groups of number fields, and we do so by wrapping the functionality from the PARI C-library. Some of what can be computed includes the group structure, representative ideals, the class of a given ideal, generators of the group, and products of elements. This file also implements moduli of number fields.
AUTHORS:
Robert Harron (2016-08-15): implemented ray class groups and moduli
EXAMPLES:
Computations with a ray class group of a quadratic field:
sage: F = QuadraticField(40)
sage: m = F.ideal(3).modulus([0, 1]); m
(Fractional ideal (3)) * infinity_0 * infinity_1
sage: R = F.ray_class_group(m); R
Ray class group of order 8 with structure C4 x C2 of Number Field in a with defining polynomial x^2 - 40 of modulus (Fractional ideal (3)) * infinity_0 * infinity_1
Unlike for class groups and \(S\)-class groups, ray class group elements do not carry around a representative ideal (for reasons of efficiency). Nevertheless, one can be demanded. The returned ideal should be somewhat ‘small.’
sage: R.gens()
(c0, c1)
sage: R.gens_ideals()
(Fractional ideal (430, 1/2*a + 200), Fractional ideal (-3/2*a + 2))
sage: c = R.gens()[0]^3 * R.gens()[1]; c
c0^3*c1
sage: c.ideal()
Fractional ideal (10, a)
sage: c = R(F.ideal(2)); c
c0^2
sage: R.gen(0).ideal()^2
Fractional ideal (30*a - 470)
sage: R(R.gen(0).ideal()^2).ideal()
Fractional ideal (2)
-
class
adeles.ray_class_group.
Modulus
(finite, infinite=None, check=True)¶ Bases:
sage.structure.sage_object.SageObject
Modulus of a number field
-
equivalent_coprime_ideal_multiplier
(I, other)¶ Given
I
coprime to this modulus \(m\), return a number field element \(\beta\) such that \(\beta I\) is coprime to the modulusother
and equivalent toI
\(\mathrm{mod}^\ast m\); in particular, \(\beta\) will be \(1 \mathrm{mod}^\ast m\).EXAMPLES:
An example with two prime factors difference between this modulus and
other
.sage: F.<a> = QuadraticField(5) sage: m_small = F.modulus(3/2*a - 1/2, [0, 1]) sage: m_big = F.modulus(2*a - 30, [0, 1]) sage: m_small.equivalent_coprime_ideal_multiplier(F.ideal(6), m_big) 109/54
-
equivalent_ideal_coprime_to_other
(I, other)¶ Given
I
coprime to this modulus \(m\), return an ideal \(J\) such that \(J\) is coprime to the modulusother
and equivalent toI
\(\mathrm{mod}^\ast m\).This is useful for lowering the level of a non-primitive Hecke character.
INPUT:
I
– an ideal relatively prime to this modulus (not checked).other
– some other modulus.
OUTPUT:
an ideal coprime to
other
and equivalent toI
in the ray class group modulo this modulus.
-
fix_signs
(a)¶ Given
a
inself.number_field()
, find \(b\) congruent toa
\(mod^\ast\)self.finite_part()
such that \(b\) is positive at the infinite places dividingself
.
-
-
class
adeles.ray_class_group.
RayClassGroup
(gens_orders, names, modulus, gens, bnr, proof=True)¶ Bases:
sage.groups.abelian_gps.abelian_group.AbelianGroup_class
Ray class group of a number field
-
Element
¶ alias of
RayClassGroupElement
-
gens_ideals
()¶ EXAMPLES:
sage: class Foo: ....: def __init__(self, x): ....: self._x = x ....: @cached_method ....: def f(self): ....: return self._x^2 sage: a = Foo(2) sage: print(a.f.cache) None sage: a.f() 4 sage: a.f.cache 4
-
ray_class_field
(subgroup=None, names=None, algorithm='stark')¶ Two different algorithms are possible: pari’s bnrstark and rnfkummer. The first one uses the Stark conjecture and only deals with totally real extensions of a totally real base field. The second one uses Kummer theory and only deals with extensions of prime degree.
INPUT:
algorithm – (default:
stark
) if the value isstark
, then pari’sbnrstark
function is tried first, and if that fails,rnfkummer
will be attempted. If the value iskummer
, then pari’srnfkummer
is tried first, withbnrstark
as a backup. Usingstark_only
orkummer_only
will just raise an exception if the first attempt fails.
OUTPUT:
The class field corresponding to the given subgroup, or the ray class field if
subgroup
isNone
, as a relative number field.EXAMPLES:
Class fields of \(\QQ(\sqrt{3})\):
sage: F.<a> = QuadraticField(3) sage: m = F.ideal(7).modulus() sage: R = F.ray_class_group(m) sage: R.ray_class_field(names='b') Number Field in b with defining polynomial x^6 + a*x^5 - 4*x^4 - 4*a*x^3 + 2*x^2 + 2*a*x - 1 over its base field sage: S = R.subgroup([R.gen()^2]) sage: R.ray_class_field(S, names='b') Number Field in b with defining polynomial x^2 - a*x - 1 over its base field sage: m = F.modulus(20) sage: R = F.ray_class_group(m) sage: S = R.subgroup([R.gens()[0]^2, R.gens()[1]]) sage: R.ray_class_field(S, names='b') Number Field in b with defining polynomial x^2 + (a - 1)*x + 2*a - 4 over its base field
An example where pari’s
bnrstark
fails, butrnfkummer
saves the day:sage: F.<a> = NumberField(x^8 - 12*x^6 + 36*x^4 - 36*x^2 + 9) sage: m = F.ideal(2).modulus() sage: R = F.ray_class_group(m) sage: set_verbose(1) sage: K = R.ray_class_field(names='b'); K verbose 1 (...: class_group.py, ray_class_field) bnrstark failed; trying rnfkummer. Number Field in b with defining polynomial x^2 + (1/3*a^6 - 10/3*a^4 + 5*a^2)*x + 1/3*a^6 - 1/3*a^5 - 11/3*a^4 + 3*a^3 + 8*a^2 - 4*a - 5 over its base field sage: set_verbose(0)
-
-
class
adeles.ray_class_group.
RayClassGroupElement
(parent, exponents)¶ Bases:
sage.groups.abelian_gps.abelian_group_element.AbelianGroupElement
Element of a ray class group
-
ideal
(reduce=True)¶ Return an ideal representing this ray class.
If
reduce
isTrue
(by default) the returned ideal is reduced to ‘small’ (this can be slow on large inputs).INPUT:
reduce
– (default:True
) determine whether or not to output a ‘small’ representative.
OUTPUT:
An ideal representing this ray class. If
reduce
isTrue
, the ideal returned is made ‘small’ by the ideal’sreduce_equiv
function (andreduce_equiv
is used at each step of computing this representative). Otherwise, the output is just the appropriate product of the powers of the generators of the ray class group.EXAMPLES:
Over a real quadratic field field of class number 1:
sage: F.<a> = NumberField(x^2 - 5) sage: m = F.ideal(11).modulus([0, 1]) sage: R = F.ray_class_group(m) sage: c0, c1 = R.gens() sage: c = c0^4*c1; c.ideal() Fractional ideal (-a) sage: c.ideal(False) Fractional ideal (-6242265*a + 1268055)
Over a real quadratic field of class number 2:
sage: F = QuadraticField(40) sage: R = F.ray_class_group(F.prime_above(13).modulus([0, 1])) sage: for c in R: ... if R(c.ideal()) != c: ... print "Bug!"
-
-
adeles.ray_class_group.
pari_extended_ideal_to_sage
(K, Ix)¶ Convert an ‘extended ideal’ in pari format to an ideal in Sage.
INPUT:
K
– number field to which the ideal belongsIx
– A pair whose first entry is a pari ideal and whose second entry is a pari factorization matrix representing an algebraic number.
OUTPUT:
The ideal that is the product of the ideal
Ix[0]
and the principal ideal generated byIx[1]
.
EXAMPLES:
sage: F = NumberField(x^3 - 2, 'z') sage: I = F.ideal(27) sage: a = Matrix(0) sage: pari_extended_ideal_to_sage(F, pari([I, a])) == I True sage: factorization_matrix = pari([pari([pari([31, 0, 1]).Col(), 1]).Mat(), pari([pari([5, 1, 0]).Col(), 1]).Mat()]).Col().matconcat() sage: pari_extended_ideal_to_sage(F, pari([I, factorization_matrix])) Fractional ideal (-135*z^2 - 837*z - 4239) sage: pari_extended_ideal_to_sage(F, F.ray_class_group(I).gens_values()[0]) Fractional ideal (-8*z^2 - 9*z + 1)
-
adeles.ray_class_group.
pari_real_places_to_sage
(K)¶ Return a list converting from the ordering of real places in pari to that of Sage’s
places()
.EXAMPLES:
A totally real quartic field where the pari and Sage orderings are different.
sage: x = polygen(QQ) sage: f = x^4 - x^3 - 3*x^2 + x + 1 sage: F.<a> = NumberField(f(1-2*x)) sage: F.defining_polynomial() 16*x^4 - 24*x^3 + 8*x - 1 sage: F.pari_polynomial() x^4 - 6*x^2 - 5*x - 1 sage: pari_real_places_to_sage(F) (0, 3, 2, 1)
A quintic field with three real places.
sage: x = polygen(QQ) sage: f = x^5 - x^3 - 2 * x^2 + 1 sage: F.<a> = NumberField(f(1 - x)) sage: pari_real_places_to_sage(F) (2, 1, 0)
-
adeles.ray_class_group.
ray_class_group
(K, modulus, proof=True, names='c')¶ Return the ray class group modulo
modulus
.EXAMPLES:
Ray class group of a real quadratic field of class number 1.
sage: F = NumberField(x^2 - 5, 'a') sage: m = F.modulus(F.prime_above(5) * F.prime_above(29), [0, 1]) sage: G = F.ray_class_group(m); G Ray class group of order 8 with structure C4 x C2 of Number Field in a with defining polynomial x^2 - 5 of modulus (Fractional ideal (-11/2*a - 5/2)) * infinity_0 * infinity_1 sage: G.elementary_divisors() (2, 4) sage: G.gens_ideals() (Fractional ideal (31), Fractional ideal (12672)) sage: G.gens_orders() (4, 2)
Ray class group of an imaginary quadratic field of class number 3.
sage: F.<a> = QuadraticField(-23) sage: R = F.ray_class_group(F.ideal(3/2 + a/2)); R Ray class group of order 6 with structure C6 of Number Field in a with defining polynomial x^2 + 23 of modulus Fractional ideal (1/2*a + 3/2) sage: R.gens_ideals() (Fractional ideal (3, 1/2*a + 1/2),) sage: R.modulus().finite_part().norm() 8 sage: F.class_group().gens_ideals() (Fractional ideal (2, 1/2*a - 1/2),)
Over \(\QQ\), the ray class group modulo \((m)\infty\) is the unit group of \(\ZZ/m\ZZ\), while the ray class group modulo \((m)\) is the latter modulo \(\{\pm1\}\).
sage: Q = NumberField(x - 1, 'a') sage: Q.ray_class_group(Q.ideal(40).modulus([0])).gens_ideals() (Fractional ideal (17), Fractional ideal (31), Fractional ideal (21)) sage: Zmod(40).unit_gens() (31, 21, 17) sage: Q.ray_class_group(Q.ideal(40)).gens_ideals() (Fractional ideal (17), Fractional ideal (21))