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() """ AbelianGroupWithValues_class.__init__(self, gens_orders, names, gens, values_group=number_field.ideal_monoid()) self._proof_flag = proof self._number_field = number_field
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() """ AbelianGroupWithValues_class.__init__(self, gens_orders, names, gens, values_group=number_field.ideal_monoid()) self._proof_flag = proof self._number_field = number_field
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 with a = 3.741657386773942?*I 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 with a = 10.24695076595960?*I """ AbelianGroupWithValues_class.__init__(self, gens_orders, names, gens, values_group=number_field.ideal_monoid()) self._proof_flag = proof self._number_field = number_field self._S = S
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 """ AbelianGroupWithValues_class.__init__(self, gens_orders, names, gens, values_group=number_field.ideal_monoid()) self._proof_flag = proof self._number_field = number_field self._S = S
def __init__(self, number_field, proof=True, S=None): """ Create a unit group of a number field. INPUT: - ``number_field`` - a number field - ``proof`` - boolean (default True): proof flag - ``S`` - tuple of prime ideals, or an ideal, or a single ideal or element from which an ideal can be constructed, in which case the support is used. If None, the global unit group is constructed; otherwise, the S-unit group is constructed. The proof flag is passed to pari via the ``pari_bnf()`` function which computes the unit group. See the documentation for the number_field module. EXAMPLES:: sage: x = polygen(QQ) sage: K.<a> = NumberField(x^2-38) sage: UK = K.unit_group(); UK Unit group with structure C2 x Z of Number Field in a with defining polynomial x^2 - 38 sage: UK.gens() (u0, u1) sage: UK.gens_values() [-1, 6*a - 37] sage: K.<a> = QuadraticField(-3) sage: UK = K.unit_group(); UK Unit group with structure C6 of Number Field in a with defining polynomial x^2 + 3 sage: UK.gens() (u,) sage: UK.gens_values() [-1/2*a + 1/2] sage: K.<z> = CyclotomicField(13) sage: UK = K.unit_group(); UK Unit group with structure C26 x Z x Z x Z x Z x Z of Cyclotomic Field of order 13 and degree 12 sage: UK.gens() (u0, u1, u2, u3, u4, u5) sage: UK.gens_values() # random [-z^11, z^5 + z^3, z^6 + z^5, z^9 + z^7 + z^5, z^9 + z^5 + z^4 + 1, z^5 + z] sage: SUK = UnitGroup(K,S=2); SUK S-unit group with structure C26 x Z x Z x Z x Z x Z x Z of Cyclotomic Field of order 13 and degree 12 with S = (Fractional ideal (2),) """ proof = get_flag(proof, "number_field") K = number_field pK = K.pari_bnf(proof) self.__number_field = K self.__pari_number_field = pK # process the parameter S: if not S: S = self.__S = () else: if isinstance(S, list): S = tuple(S) if not isinstance(S, tuple): try: S = tuple(K.ideal(S).prime_factors()) except (NameError, TypeError, ValueError): raise ValueError("Cannot make a set of primes from %s" % (S, )) else: try: S = tuple(K.ideal(P) for P in S) except (NameError, TypeError, ValueError): raise ValueError("Cannot make a set of primes from %s" % (S, )) if not all([P.is_prime() for P in S]): raise ValueError( "Not all elements of %s are prime ideals" % (S, )) self.__S = S self.__pS = pS = [P.pari_prime() for P in S] # compute the fundamental units via pari: fu = [K(u) for u in pK.bnfunit()] self.__nfu = len(fu) # compute the additional S-unit generators: if S: self.__S_unit_data = pK.bnfsunit(pS) su = [K(u) for u in self.__S_unit_data[0]] else: su = [] self.__nsu = len(su) self.__rank = self.__nfu + self.__nsu # compute a torsion generator and pick the 'simplest' one: n, z = pK.nfrootsof1() n = ZZ(n) self.__ntu = n z = K(z) # If we replaced z by another torsion generator we would need # to allow for this in the dlog function! So we do not. # Store the actual generators (torsion first): gens = [z] + fu + su values = Sequence(gens, immutable=True, universe=self, check=False) # Construct the abtract group: gens_orders = tuple([ZZ(n)] + [ZZ(0)] * (self.__rank)) AbelianGroupWithValues_class.__init__(self, gens_orders, 'u', values, number_field)
def __init__(self, number_field, proof=True, S=None): """ Create a unit group of a number field. INPUT: - ``number_field`` - a number field - ``proof`` - boolean (default True): proof flag - ``S`` - tuple of prime ideals, or an ideal, or a single ideal or element from which an ideal can be constructed, in which case the support is used. If None, the global unit group is constructed; otherwise, the S-unit group is constructed. The proof flag is passed to pari via the ``pari_bnf()`` function which computes the unit group. See the documentation for the number_field module. EXAMPLES:: sage: x = polygen(QQ) sage: K.<a> = NumberField(x^2-38) sage: UK = K.unit_group(); UK Unit group with structure C2 x Z of Number Field in a with defining polynomial x^2 - 38 sage: UK.gens() (u0, u1) sage: UK.gens_values() [-1, 6*a - 37] sage: K.<a> = QuadraticField(-3) sage: UK = K.unit_group(); UK Unit group with structure C6 of Number Field in a with defining polynomial x^2 + 3 with a = 1.732050807568878?*I sage: UK.gens() (u,) sage: UK.gens_values() [1/2*a + 1/2] sage: K.<z> = CyclotomicField(13) sage: UK = K.unit_group(); UK Unit group with structure C26 x Z x Z x Z x Z x Z of Cyclotomic Field of order 13 and degree 12 sage: UK.gens() (u0, u1, u2, u3, u4, u5) sage: UK.gens_values() # random [-z^11, z^5 + z^3, z^6 + z^5, z^9 + z^7 + z^5, z^9 + z^5 + z^4 + 1, z^5 + z] sage: SUK = UnitGroup(K,S=2); SUK S-unit group with structure C26 x Z x Z x Z x Z x Z x Z of Cyclotomic Field of order 13 and degree 12 with S = (Fractional ideal (2),) TESTS: Number fields defined by non-monic and non-integral polynomials are supported (:trac:`252`); the representation depends on the PARI version:: sage: K.<a> = NumberField(7/9*x^3 + 7/3*x^2 - 56*x + 123) sage: K.unit_group() Unit group with structure C2 x Z x Z of Number Field in a with defining polynomial 7/9*x^3 + 7/3*x^2 - 56*x + 123 sage: UnitGroup(K, S=tuple(K.primes_above(7))) S-unit group with structure C2 x Z x Z x Z of Number Field in a with defining polynomial 7/9*x^3 + 7/3*x^2 - 56*x + 123 with S = (Fractional ideal (...),) sage: K.primes_above(7)[0] in (7/225*a^2 - 7/75*a - 42/25, 28/225*a^2 + 77/75*a - 133/25) True Conversion from unit group to a number field and back gives the right results (:trac:`25874`):: sage: K = QuadraticField(-3).composite_fields(QuadraticField(2))[0] sage: U = K.unit_group() sage: tuple(U(K(u)) for u in U.gens()) == U.gens() True sage: US = K.S_unit_group(3) sage: tuple(US(K(u)) for u in US.gens()) == US.gens() True """ proof = get_flag(proof, "number_field") K = number_field pK = K.pari_bnf(proof) self.__number_field = K self.__pari_number_field = pK # process the parameter S: if not S: S = self.__S = () else: if isinstance(S, list): S = tuple(S) if not isinstance(S, tuple): try: S = tuple(K.ideal(S).prime_factors()) except (NameError, TypeError, ValueError): raise ValueError("Cannot make a set of primes from %s" % (S, )) else: try: S = tuple(K.ideal(P) for P in S) except (NameError, TypeError, ValueError): raise ValueError("Cannot make a set of primes from %s" % (S, )) if not all(P.is_prime() for P in S): raise ValueError( "Not all elements of %s are prime ideals" % (S, )) self.__S = S self.__pS = pS = [P.pari_prime() for P in S] # compute the fundamental units via pari: fu = [K(u, check=False) for u in pK.bnfunit()] self.__nfu = len(fu) # compute the additional S-unit generators: if S: self.__S_unit_data = pK.bnfsunit(pS) su = [K(u, check=False) for u in self.__S_unit_data[0]] else: su = [] self.__nsu = len(su) self.__rank = self.__nfu + self.__nsu # compute a torsion generator and pick the 'simplest' one: n, z = pK[7][ 3] # number of roots of unity and bnf.tu as in pari documentation n = ZZ(n) self.__ntu = n z = K(z, check=False) # If we replaced z by another torsion generator we would need # to allow for this in the dlog function! So we do not. # Store the actual generators (torsion first): gens = [z] + fu + su values = Sequence(gens, immutable=True, universe=self, check=False) # Construct the abtract group: gens_orders = tuple([ZZ(n)] + [ZZ(0)] * (self.__rank)) AbelianGroupWithValues_class.__init__(self, gens_orders, 'u', values, number_field)
def __init__(self, number_field, proof=True, S=None): """ Create a unit group of a number field. INPUT: - ``number_field`` - a number field - ``proof`` - boolean (default True): proof flag - ``S`` - tuple of prime ideals, or an ideal, or a single ideal or element from which an ideal can be constructed, in which case the support is used. If None, the global unit group is constructed; otherwise, the S-unit group is constructed. The proof flag is passed to pari via the ``pari_bnf()`` function which computes the unit group. See the documentation for the number_field module. EXAMPLES:: sage: x = polygen(QQ) sage: K.<a> = NumberField(x^2-38) sage: UK = K.unit_group(); UK Unit group with structure C2 x Z of Number Field in a with defining polynomial x^2 - 38 sage: UK.gens() (u0, u1) sage: UK.gens_values() [-1, 6*a - 37] sage: K.<a> = QuadraticField(-3) sage: UK = K.unit_group(); UK Unit group with structure C6 of Number Field in a with defining polynomial x^2 + 3 sage: UK.gens() (u,) sage: UK.gens_values() [-1/2*a + 1/2] sage: K.<z> = CyclotomicField(13) sage: UK = K.unit_group(); UK Unit group with structure C26 x Z x Z x Z x Z x Z of Cyclotomic Field of order 13 and degree 12 sage: UK.gens() (u0, u1, u2, u3, u4, u5) sage: UK.gens_values() # random [-z^11, z^5 + z^3, z^6 + z^5, z^9 + z^7 + z^5, z^9 + z^5 + z^4 + 1, z^5 + z] sage: SUK = UnitGroup(K,S=2); SUK S-unit group with structure C26 x Z x Z x Z x Z x Z x Z of Cyclotomic Field of order 13 and degree 12 with S = (Fractional ideal (2),) """ proof = get_flag(proof, "number_field") K = number_field pK = K.pari_bnf(proof) self.__number_field = K self.__pari_number_field = pK # process the parameter S: if not S: S = self.__S = () else: if type(S)==list: S = tuple(S) if not type(S)==tuple: try: S = tuple(K.ideal(S).prime_factors()) except (NameError, TypeError, ValueError): raise ValueError("Cannot make a set of primes from %s"%(S,)) else: try: S = tuple(K.ideal(P) for P in S) except (NameError, TypeError, ValueError): raise ValueError("Cannot make a set of primes from %s"%(S,)) if not all([P.is_prime() for P in S]): raise ValueError("Not all elements of %s are prime ideals"%(S,)) self.__S = S self.__pS = pS = [P.pari_prime() for P in S] # compute the fundamental units via pari: fu = [K(u) for u in pK.bnfunit()] self.__nfu = len(fu) # compute the additional S-unit generators: if S: self.__S_unit_data = pK.bnfsunit(pS) su = [K(u) for u in self.__S_unit_data[0]] else: su = [] self.__nsu = len(su) self.__rank = self.__nfu + self.__nsu # compute a torsion generator and pick the 'simplest' one: n, z = pK.nfrootsof1() n = ZZ(n) self.__ntu = n z = K(z) # If we replaced z by another torsion generator we would need # to allow for this in the dlog function! So we do not. # Store the actual generators (torsion first): gens = [z] + fu + su values = Sequence(gens, immutable=True, universe=self, check=False) # Construct the abtract group: gens_orders = tuple([ZZ(n)]+[ZZ(0)]*(self.__rank)) AbelianGroupWithValues_class.__init__(self, gens_orders, 'u', values, number_field)
def __init__(self, number_field, proof=True, S=None): """ Create a unit group of a number field. INPUT: - ``number_field`` - a number field - ``proof`` - boolean (default True): proof flag - ``S`` - tuple of prime ideals, or an ideal, or a single ideal or element from which an ideal can be constructed, in which case the support is used. If None, the global unit group is constructed; otherwise, the S-unit group is constructed. The proof flag is passed to pari via the ``pari_bnf()`` function which computes the unit group. See the documentation for the number_field module. EXAMPLES:: sage: x = polygen(QQ) sage: K.<a> = NumberField(x^2-38) sage: UK = K.unit_group(); UK Unit group with structure C2 x Z of Number Field in a with defining polynomial x^2 - 38 sage: UK.gens() (u0, u1) sage: UK.gens_values() [-1, -6*a + 37] sage: K.<a> = QuadraticField(-3) sage: UK = K.unit_group(); UK Unit group with structure C6 of Number Field in a with defining polynomial x^2 + 3 with a = 1.732050807568878?*I sage: UK.gens() (u,) sage: UK.gens_values() [-1/2*a + 1/2] sage: K.<z> = CyclotomicField(13) sage: UK = K.unit_group(); UK Unit group with structure C26 x Z x Z x Z x Z x Z of Cyclotomic Field of order 13 and degree 12 sage: UK.gens() (u0, u1, u2, u3, u4, u5) sage: UK.gens_values() # random [-z^11, z^5 + z^3, z^6 + z^5, z^9 + z^7 + z^5, z^9 + z^5 + z^4 + 1, z^5 + z] sage: SUK = UnitGroup(K,S=2); SUK S-unit group with structure C26 x Z x Z x Z x Z x Z x Z of Cyclotomic Field of order 13 and degree 12 with S = (Fractional ideal (2),) TESTS: Number fields defined by non-monic and non-integral polynomials are supported (:trac:`252`); the representation depends on the PARI version:: sage: K.<a> = NumberField(7/9*x^3 + 7/3*x^2 - 56*x + 123) sage: K.unit_group() Unit group with structure C2 x Z x Z of Number Field in a with defining polynomial 7/9*x^3 + 7/3*x^2 - 56*x + 123 sage: UnitGroup(K, S=tuple(K.primes_above(7))) S-unit group with structure C2 x Z x Z x Z of Number Field in a with defining polynomial 7/9*x^3 + 7/3*x^2 - 56*x + 123 with S = (Fractional ideal (...),) sage: K.primes_above(7)[0] in (7/225*a^2 - 7/75*a - 42/25, 28/225*a^2 + 77/75*a - 133/25) True Conversion from unit group to a number field and back gives the right results (:trac:`25874`):: sage: K = QuadraticField(-3).composite_fields(QuadraticField(2))[0] sage: U = K.unit_group() sage: tuple(U(K(u)) for u in U.gens()) == U.gens() True sage: US = K.S_unit_group(3) sage: tuple(US(K(u)) for u in US.gens()) == US.gens() True """ proof = get_flag(proof, "number_field") K = number_field pK = K.pari_bnf(proof) self.__number_field = K self.__pari_number_field = pK # process the parameter S: if not S: S = self.__S = () else: if isinstance(S, list): S = tuple(S) if not isinstance(S, tuple): try: S = tuple(K.ideal(S).prime_factors()) except (NameError, TypeError, ValueError): raise ValueError("Cannot make a set of primes from %s" % (S, )) else: try: S = tuple(K.ideal(P) for P in S) except (NameError, TypeError, ValueError): raise ValueError("Cannot make a set of primes from %s" % (S, )) if not all(P.is_prime() for P in S): raise ValueError( "Not all elements of %s are prime ideals" % (S, )) self.__S = S self.__pS = pS = [P.pari_prime() for P in S] # compute the fundamental units via pari: fu = [K(u, check=False) for u in pK.bnf_get_fu()] self.__nfu = len(fu) # compute the additional S-unit generators: if S: self.__S_unit_data = pK.bnfunits(pS) else: self.__S_unit_data = pK.bnfunits() # TODO: converting the factored matrix representation of bnfunits into polynomial # form is a *big* waste of time su_fu_tu = [ pK.nfbasistoalg(pK.nffactorback(z)) for z in self.__S_unit_data[0] ] self.__nfu = len(pK.bnf_get_fu()) # number of fundamental units self.__nsu = len(su_fu_tu) - self.__nfu - 1 # number of S-units self.__ntu = pK.bnf_get_tu()[0] # order of torsion self.__rank = self.__nfu + self.__nsu # Move the torsion unit first, then fundamental units then S-units gens = [K(u, check=False) for u in su_fu_tu] gens = [gens[-1]] + gens[self.__nsu:-1] + gens[:self.__nsu] # Construct the abstract group: gens_orders = tuple([ZZ(self.__ntu)] + [ZZ(0)] * (self.__rank)) AbelianGroupWithValues_class.__init__(self, gens_orders, 'u', gens, number_field)
def __init__(self, number_field, proof=True): """ Create a unit group of a number field. INPUT: - ``number_field`` - a number field - ``proof`` - boolean (default True): proof flag The proof flag is passed to pari via the ``pari_bnf()`` function which computes the unit group. See the documentation for the number_field module. EXAMPLES:: sage: x = polygen(QQ) sage: K.<a> = NumberField(x^2-38) sage: UK = K.unit_group(); UK Unit group with structure C2 x Z of Number Field in a with defining polynomial x^2 - 38 sage: UK.gens() (u0, u1) sage: UK.gens_values() [-1, 6*a - 37] sage: K.<a> = QuadraticField(-3) sage: UK = K.unit_group(); UK Unit group with structure C6 of Number Field in a with defining polynomial x^2 + 3 sage: UK.gens() (u,) sage: UK.gens_values() [-1/2*a + 1/2] sage: K.<z> = CyclotomicField(13) sage: UK = K.unit_group(); UK Unit group with structure C26 x Z x Z x Z x Z x Z of Cyclotomic Field of order 13 and degree 12 sage: UK.gens() (u0, u1, u2, u3, u4, u5) sage: UK.gens_values() # random [-z^11, z^5 + z^3, z^6 + z^5, z^9 + z^7 + z^5, z^9 + z^5 + z^4 + 1, z^5 + z] """ proof = get_flag(proof, "number_field") K = number_field pK = K.pari_bnf(proof) self.__number_field = K # compute the units via pari: fu = [K(u) for u in pK.bnfunit()] # compute a torsion generator and pick the 'simplest' one: n, z = pK.nfrootsof1() n = ZZ(n) self.__ntu = n z = K(z) # If we replaced z by another torsion generator we would need # to allow for this in the dlog function! So we do not. # Store the actual generators (torsion first): gens = [z] + fu values = Sequence(gens, immutable=True, universe=self, check=False) # Construct the abtract group: gens_orders = tuple([ZZ(n)] + [ZZ(0)] * len(fu)) AbelianGroupWithValues_class.__init__(self, gens_orders, 'u', values, number_field)
def __init__(self, number_field, proof=True): """ Create a unit group of a number field. INPUT: - ``number_field`` - a number field - ``proof`` - boolean (default True): proof flag The proof flag is passed to pari via the ``pari_bnf()`` function which computes the unit group. See the documentation for the number_field module. EXAMPLES:: sage: x = polygen(QQ) sage: K.<a> = NumberField(x^2-38) sage: UK = K.unit_group(); UK Unit group with structure C2 x Z of Number Field in a with defining polynomial x^2 - 38 sage: UK.gens() (u0, u1) sage: UK.gens_values() [-1, 6*a - 37] sage: K.<a> = QuadraticField(-3) sage: UK = K.unit_group(); UK Unit group with structure C6 of Number Field in a with defining polynomial x^2 + 3 sage: UK.gens() (u,) sage: UK.gens_values() [-1/2*a + 1/2] sage: K.<z> = CyclotomicField(13) sage: UK = K.unit_group(); UK Unit group with structure C26 x Z x Z x Z x Z x Z of Cyclotomic Field of order 13 and degree 12 sage: UK.gens() (u0, u1, u2, u3, u4, u5) sage: UK.gens_values() # random [-z^11, z^5 + z^3, z^6 + z^5, z^9 + z^7 + z^5, z^9 + z^5 + z^4 + 1, z^5 + z] """ proof = get_flag(proof, "number_field") K = number_field pK = K.pari_bnf(proof) self.__number_field = K # compute the units via pari: fu = [K(u) for u in pK.bnfunit()] # compute a torsion generator and pick the 'simplest' one: n, z = pK.nfrootsof1() n = ZZ(n) self.__ntu = n z = K(z) # If we replaced z by another torsion generator we would need # to allow for this in the dlog function! So we do not. # Store the actual generators (torsion first): gens = [z] + fu values = Sequence(gens, immutable=True, universe=self, check=False) # Construct the abtract group: gens_orders = tuple([ZZ(n)]+[ZZ(0)]*len(fu)) AbelianGroupWithValues_class.__init__(self, gens_orders, 'u', values, number_field)