Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
# -*- coding: utf-8 -*- r""" Class Groups of Number Fields
An element of a class group is stored as a pair consisting of both an explicit ideal in that ideal class, and a list of exponents giving that ideal class in terms of the generators of the parent class group. These can be accessed with the ``ideal()`` and ``exponents()`` methods respectively.
EXAMPLES::
sage: K.<a> = NumberField(x^2 + 23) sage: I = K.class_group().gen(); I Fractional ideal class (2, 1/2*a - 1/2) sage: I.ideal() Fractional ideal (2, 1/2*a - 1/2) sage: I.exponents() (1,)
sage: I.ideal() * I.ideal() Fractional ideal (4, 1/2*a + 3/2) sage: (I.ideal() * I.ideal()).reduce_equiv() Fractional ideal (2, 1/2*a + 1/2) sage: J = I * I; J # class group multiplication is automatically reduced Fractional ideal class (2, 1/2*a + 1/2) sage: J.ideal() Fractional ideal (2, 1/2*a + 1/2) sage: J.exponents() (2,)
sage: I * I.ideal() # ideal classes coerce to their representative ideal Fractional ideal (4, 1/2*a + 3/2)
sage: O = K.OK(); O Maximal Order in Number Field in a with defining polynomial x^2 + 23 sage: O*(2, 1/2*a + 1/2) Fractional ideal (2, 1/2*a + 1/2) sage: (O*(2, 1/2*a + 1/2)).is_principal() False sage: (O*(2, 1/2*a + 1/2))^3 Fractional ideal (1/2*a - 3/2) """ from six.moves import range
from sage.groups.abelian_gps.values import AbelianGroupWithValues_class, AbelianGroupWithValuesElement from sage.groups.abelian_gps.abelian_group_element import AbelianGroupElement from sage.structure.sequence import Sequence from sage.structure.element import MonoidElement from sage.groups.old import Group from sage.arith.all import LCM from sage.rings.all import ZZ
class FractionalIdealClass(AbelianGroupWithValuesElement): r""" A fractional ideal class in a number field.
EXAMPLES::
sage: G = NumberField(x^2 + 23,'a').class_group(); G Class group of order 3 with structure C3 of Number Field in a with defining polynomial x^2 + 23 sage: I = G.0; I Fractional ideal class (2, 1/2*a - 1/2) sage: I.ideal() Fractional ideal (2, 1/2*a - 1/2)
EXAMPLES::
sage: K.<w>=QuadraticField(-23) sage: OK=K.ring_of_integers() sage: C=OK.class_group() sage: P2a,P2b=[P for P,e in (2*OK).factor()] sage: c = C(P2a); c Fractional ideal class (2, 1/2*w - 1/2) sage: c.gens() (2, 1/2*w - 1/2) """ def __init__(self, parent, element, ideal=None): """ Returns the ideal class of this fractional ideal.
EXAMPLES::
sage: K.<a> = NumberField(x^2 + 23,'a'); G = K.class_group() sage: G(K.ideal(13, a + 4)) Fractional ideal class (13, 1/2*a + 17/2) """
def _repr_(self): r""" Return string representation of this fractional ideal class.
EXAMPLES::
sage: K.<a> = NumberField(x^2 + 23,'a'); G = K.class_group() sage: G(K.ideal(13, a + 4))._repr_() 'Fractional ideal class (13, 1/2*a + 17/2)' sage: G(K.ideal(59, a+6))._repr_() 'Trivial principal fractional ideal class' """
def _mul_(self, other): r""" Multiplication of two (S-)ideal classes.
EXAMPLES::
sage: G = NumberField(x^2 + 23,'a').class_group(); G Class group of order 3 with structure C3 of Number Field in a with defining polynomial x^2 + 23 sage: I = G.0; I Fractional ideal class (2, 1/2*a - 1/2) sage: I*I # indirect doctest Fractional ideal class (2, 1/2*a + 1/2) sage: I*I*I # indirect doctest Trivial principal fractional ideal class
sage: K.<a> = QuadraticField(-14) sage: I = K.ideal(2,a) sage: S = (I,) sage: CS = K.S_class_group(S) sage: G = K.ideal(3,a+1) sage: CS(G)*CS(G) Trivial S-ideal class """
def _div_(self, other): r""" Division of two ideal classes.
EXAMPLES::
sage: G = NumberField(x^2 + 23,'a').class_group(); G Class group of order 3 with structure C3 of Number Field in a with defining polynomial x^2 + 23 sage: I = G.0; I Fractional ideal class (2, 1/2*a - 1/2) sage: I*I # indirect doctest Fractional ideal class (2, 1/2*a + 1/2) sage: I*I*I # indirect doctest Trivial principal fractional ideal class """ m = AbelianGroupElement._div_(self, other) m._value = (self.ideal() / other.ideal()).reduce_equiv() return m
def __pow__(self, n): r""" Raise this element to the power n.
EXAMPLES::
sage: K.<a> = NumberField(x^3 - 3*x + 8) sage: C=K.class_group() sage: c = C(2, a) sage: c^2 Fractional ideal class (2, a^2 + 2*a - 1) sage: c^3 Trivial principal fractional ideal class sage: c^1000 Fractional ideal class (2, a) sage: (c^2)^2 Fractional ideal class (2, a) """ # We use MonoidElement's __pow__ routine, since that does # repeated squaring, and hence the ideal gets reduced as # we go along; actually computing self._value ** n would # be disastrous.
def inverse(self): r""" Return the multiplicative inverse of this ideal class.
EXAMPLES::
sage: K.<a> = NumberField(x^3 - 3*x + 8); G = K.class_group() sage: G(2, a).inverse() Fractional ideal class (2, a^2 + 2*a - 1) sage: ~G(2, a) Fractional ideal class (2, a^2 + 2*a - 1) """
__invert__ = inverse
def is_principal(self): r""" Returns True iff this ideal class is the trivial (principal) class
EXAMPLES::
sage: K.<w>=QuadraticField(-23) sage: OK=K.ring_of_integers() sage: C=OK.class_group() sage: P2a,P2b=[P for P,e in (2*OK).factor()] sage: c=C(P2a) sage: c.is_principal() False sage: (c^2).is_principal() False sage: (c^3).is_principal() True """
def reduce(self): r""" Return representative for this ideal class that has been reduced using PARI's idealred.
EXAMPLES::
sage: k.<a> = NumberField(x^2 + 20072); G = k.class_group(); G Class group of order 76 with structure C38 x C2 of Number Field in a with defining polynomial x^2 + 20072 sage: I = (G.0)^11; I Fractional ideal class (41, 1/2*a + 5) sage: J = G(I.ideal()^5); J Fractional ideal class (115856201, 1/2*a + 40407883) sage: J.reduce() Fractional ideal class (57, 1/2*a + 44) sage: J == I^5 True """
def ideal(self): r""" Return a representative ideal in this ideal class.
EXAMPLES::
sage: K.<w>=QuadraticField(-23) sage: OK=K.ring_of_integers() sage: C=OK.class_group() sage: P2a,P2b=[P for P,e in (2*OK).factor()] sage: c=C(P2a); c Fractional ideal class (2, 1/2*w - 1/2) sage: c.ideal() Fractional ideal (2, 1/2*w - 1/2) """
def representative_prime(self, norm_bound=1000): r""" Return a prime ideal in this ideal class.
INPUT:
``norm_bound`` (positive integer) -- upper bound on the norm of primes tested.
EXAMPLES::
sage: K.<a> = NumberField(x^2+31) sage: K.class_number() 3 sage: Cl = K.class_group() sage: [c.representative_prime() for c in Cl] [Fractional ideal (3), Fractional ideal (2, 1/2*a + 1/2), Fractional ideal (2, 1/2*a - 1/2)]
sage: K.<a> = NumberField(x^2+223) sage: K.class_number() 7 sage: Cl = K.class_group() sage: [c.representative_prime() for c in Cl] [Fractional ideal (3), Fractional ideal (2, 1/2*a + 1/2), Fractional ideal (17, 1/2*a + 7/2), Fractional ideal (7, 1/2*a - 1/2), Fractional ideal (7, 1/2*a + 1/2), Fractional ideal (17, 1/2*a + 27/2), Fractional ideal (2, 1/2*a - 1/2)] """ # otherwise we just search: raise RuntimeError("No prime of norm less than %s found in class %s" % (norm_bound, c))
def gens(self): r""" Return generators for a representative ideal in this (S-)ideal class.
EXAMPLES::
sage: K.<w>=QuadraticField(-23) sage: OK = K.ring_of_integers() sage: C = OK.class_group() sage: P2a,P2b=[P for P,e in (2*OK).factor()] sage: c = C(P2a); c Fractional ideal class (2, 1/2*w - 1/2) sage: c.gens() (2, 1/2*w - 1/2) """
class SFractionalIdealClass(FractionalIdealClass): r""" An S-fractional ideal class in a number field for a tuple of primes S.
EXAMPLES::
sage: K.<a> = QuadraticField(-14) sage: I = K.ideal(2,a) sage: S = (I,) sage: CS = K.S_class_group(S) sage: J = K.ideal(7,a) sage: G = K.ideal(3,a+1) sage: CS(I) Trivial S-ideal class sage: CS(J) Trivial S-ideal class sage: CS(G) Fractional S-ideal class (3, a + 1)
EXAMPLES::
sage: K.<a> = QuadraticField(-14) sage: I = K.ideal(2,a) sage: S = (I,) sage: CS = K.S_class_group(S) sage: J = K.ideal(7,a) sage: G = K.ideal(3,a+1) sage: CS(I).ideal() Fractional ideal (2, a) sage: CS(J).ideal() Fractional ideal (7, a) sage: CS(G).ideal() Fractional ideal (3, a + 1)
EXAMPLES::
sage: K.<a> = QuadraticField(-14) sage: I = K.ideal(2,a) sage: S = (I,) sage: CS = K.S_class_group(S) sage: G = K.ideal(3,a+1) sage: CS(G).inverse() Fractional S-ideal class (3, a + 2)
TESTS::
sage: K.<a> = QuadraticField(-14) sage: I = K.ideal(2,a) sage: S = (I,) sage: CS = K.S_class_group(S) sage: J = K.ideal(7,a) sage: G = K.ideal(3,a+1) sage: CS(I).order() 1 sage: CS(J).order() 1 sage: CS(G).order() 2 """
def _repr_(self): r""" Returns a string representation of the S-ideal class of this fractional ideal.
EXAMPLES::
sage: K.<a> = QuadraticField(-14) sage: I = K.ideal(2,a) sage: J = K.ideal(3, a + 2) sage: S = (I,) sage: CS = K.S_class_group(S) sage: CS(J) Fractional S-ideal class (3, a + 2) sage: CS(J^2) Trivial S-ideal class """
class ClassGroup(AbelianGroupWithValues_class): r""" The class group of a number field.
EXAMPLES::
sage: K.<a> = NumberField(x^2 + 23) sage: G = K.class_group(); G Class group of order 3 with structure C3 of Number Field in a with defining polynomial x^2 + 23 sage: G.category() Category of finite enumerated commutative groups
Note the distinction between abstract generators, their ideal, and exponents::
sage: C = NumberField(x^2 + 120071, 'a').class_group(); C Class group of order 500 with structure C250 x C2 of Number Field in a with defining polynomial x^2 + 120071 sage: c = C.gen(0) sage: c # random Fractional ideal class (5, 1/2*a + 3/2) sage: c.ideal() # random Fractional ideal (5, 1/2*a + 3/2) sage: c.ideal() is c.value() # alias True sage: c.exponents() (1, 0) """ Element = FractionalIdealClass
def __init__(self, gens_orders, names, number_field, gens, proof=True): r""" Create a class group.
TESTS::
sage: K.<a> = NumberField(x^2 + 23) sage: G = K.class_group() sage: TestSuite(G).run() """ values_group=number_field.ideal_monoid())
def _element_constructor_(self, *args, **kwds): r""" Create an element of this class group from the given data. This may be: an ideal class in this number field; an ideal class in a subfield; or anything from which an ideal in this number field can be constructed.
EXAMPLES::
sage: K.<b> = NumberField(x^2 + 389) sage: C = K.class_group() sage: C(K.ideal(b)) # indirect doctest Trivial principal fractional ideal class sage: C(K.ideal(59049, b + 35312)) # indirect doctest Fractional ideal class (59049, b + 35312) sage: C((59049, b + 35312)) # indirect doctest Fractional ideal class (59049, b + 35312) sage: C(59049, b + 35312) # indirect doctest Fractional ideal class (59049, b + 35312)
sage: K.<a> = QuadraticField(-23) sage: L.<b> = K.extension(x^2 - 2) sage: CK = K.class_group() sage: CL = L.class_group() sage: [CL(I).exponents() for I in CK] [(0,), (4,), (2,)] """ else:
def _ideal_log(self, ideal): """ Compute the exponents from the ``ideal``.
Used by the element constructor if necessary.
EXAMPLES::
sage: K.<a> = NumberField(x^2 + 23,'a') sage: G = K.class_group() sage: g = G.an_element() sage: G._ideal_log(g.ideal()) (1,) sage: g.exponents() (1,) """
def gens_ideals(self): r""" Return generating ideals for the (S-)class group.
This is an alias for :meth:`gens_values`.
OUTPUT:
A tuple of ideals, one for each abstract Abelian group generator.
EXAMPLES::
sage: K.<a> = NumberField(x^4 + 23) sage: K.class_group().gens_ideals() # random gens (platform dependent) (Fractional ideal (2, 1/4*a^3 - 1/4*a^2 + 1/4*a - 1/4),)
sage: C = NumberField(x^2 + x + 23899, 'a').class_group(); C Class group of order 68 with structure C34 x C2 of Number Field in a with defining polynomial x^2 + x + 23899 sage: C.gens() (Fractional ideal class (7, a + 5), Fractional ideal class (5, a + 3)) sage: C.gens_ideals() (Fractional ideal (7, a + 5), Fractional ideal (5, a + 3)) """
def __iter__(self): r""" Return an iterator of all ideal classes in this class group.
EXAMPLES::
sage: K.<a> = NumberField(x^4 + 23) sage: G = K.class_group() sage: G Class group of order 3 with structure C3 of Number Field in a with defining polynomial x^4 + 23 sage: list(G) [Trivial principal fractional ideal class, Fractional ideal class (2, 1/4*a^3 - 1/4*a^2 + 1/4*a - 1/4), Fractional ideal class (2, 1/2*a^2 + 1/2)] sage: G.list() (Trivial principal fractional ideal class, Fractional ideal class (2, 1/4*a^3 - 1/4*a^2 + 1/4*a - 1/4), Fractional ideal class (2, 1/2*a^2 + 1/2))
TESTS::
sage: K.<a> = NumberField(x^2 + 1) sage: G = K.class_group() sage: G Class group of order 1 of Number Field in a with defining polynomial x^2 + 1 sage: list(G) [Trivial principal fractional ideal class] sage: G.list() (Trivial principal fractional ideal class,) """
def _iter_inner(self, i0, k): r""" Yield all elements of the coset `i0 * \{h in H_k\}`, where `H_k` is the subgroup of ``self`` generated by ``self.gens()[k:]``.
Each new element provided costs exactly one group operation, and is not necessarily reduced.
EXAMPLES::
sage: x = ZZ['x'].gen() sage: K.<v> = NumberField(x^4 + 90*x^2 + 45) sage: OK = K.maximal_order() sage: G = OK.class_group() sage: iter = G._iter_inner(G.gen(0)^2,1) sage: all(next(iter) in G for _ in range(4)) True """
def _repr_(self): r""" Return string representation of self.
EXAMPLES::
sage: C = NumberField(x^2 + 23, 'a').class_group() sage: C._repr_() 'Class group of order 3 with structure C3 of Number Field in a with defining polynomial x^2 + 23' """
def number_field(self): r""" Return the number field that this (S-)class group is attached to.
EXAMPLES::
sage: C = NumberField(x^2 + 23, 'w').class_group(); C Class group of order 3 with structure C3 of Number Field in w with defining polynomial x^2 + 23 sage: C.number_field() Number Field in w with defining polynomial x^2 + 23
sage: K.<a> = QuadraticField(-14) sage: CS = K.S_class_group(K.primes_above(2)) sage: CS.number_field() Number Field in a with defining polynomial x^2 + 14 """
class SClassGroup(ClassGroup): r""" The S-class group of a number field.
EXAMPLES::
sage: K.<a> = QuadraticField(-14) sage: S = K.primes_above(2) sage: K.S_class_group(S).gens() # random gens (platform dependent) (Fractional S-ideal class (3, a + 2),)
sage: K.<a> = QuadraticField(-974) sage: CS = K.S_class_group(K.primes_above(2)); CS S-class group of order 18 with structure C6 x C3 of Number Field in a with defining polynomial x^2 + 974 sage: CS.gen(0) # random Fractional S-ideal class (3, a + 2) sage: CS.gen(1) # random Fractional S-ideal class (31, a + 24) """ Element = SFractionalIdealClass
def __init__(self, gens_orders, names, number_field, gens, S, proof=True): r""" Create an S-class group.
EXAMPLES::
sage: K.<a> = QuadraticField(-14) sage: I = K.ideal(2,a) sage: S = (I,) sage: K.S_class_group(S) S-class group of order 2 with structure C2 of Number Field in a with defining polynomial x^2 + 14 sage: K.<a> = QuadraticField(-105) sage: K.S_class_group([K.ideal(13, a + 8)]) S-class group of order 4 with structure C2 x C2 of Number Field in a with defining polynomial x^2 + 105 """ values_group=number_field.ideal_monoid())
def S(self): r""" Return the set (or rather tuple) of primes used to define this class group.
EXAMPLES::
sage: K.<a> = QuadraticField(-14) sage: I = K.ideal(2,a) sage: S = (I,) sage: CS = K.S_class_group(S);CS S-class group of order 2 with structure C2 of Number Field in a with defining polynomial x^2 + 14 sage: T = tuple([]) sage: CT = K.S_class_group(T);CT S-class group of order 4 with structure C4 of Number Field in a with defining polynomial x^2 + 14 sage: CS.S() (Fractional ideal (2, a),) sage: CT.S() () """
def _ideal_log(self, ideal): """ Compute the exponents from the ``ideal``.
Used by the element constructor if necessary.
EXAMPLES::
sage: K.<a> = QuadraticField(-14) sage: I = K.ideal(2,a) sage: S = (I,) sage: CS = K.S_class_group(S) sage: s = CS.an_element() sage: CS._ideal_log(s.ideal()) (1,) sage: s.exponents() (1,) """
def _element_constructor_(self, *args, **kwds): r""" Create an element of this class group from the given data.
EXAMPLES::
sage: K.<a> = QuadraticField(-14) sage: I = K.ideal(2,a) sage: S = (I,) sage: CS = K.S_class_group(S) sage: J = K.ideal(7,a) sage: G = K.ideal(3,a+1) sage: CS(I) Trivial S-ideal class sage: CS(J) Trivial S-ideal class sage: CS(G) Fractional S-ideal class (3, a + 1) """ return self.element_class(self, None, args[0].ideal()) else: raise TypeError("The zero ideal is not a fractional ideal")
def _repr_(self): r""" Return string representation of this S-class group.
EXAMPLES::
sage: K.<a> = QuadraticField(-14) sage: CS = K.S_class_group(K.primes_above(2)) sage: CS._repr_() 'S-class group of order 2 with structure C2 of Number Field in a with defining polynomial x^2 + 14' """ |