..nodoctest
Orders¶
x.__init__(...) initializes x; see help(type(x)) for signature
-
recip.orders.
additive_gens_to_basis
(gens, K)¶ Given generators of a lattice L in K, returns a basis of L.
-
recip.orders.
are_nn_isogenous
(Z1, Z2, n, F1, F2, transformation=False, double_check=False)¶ Given two CM period matrices with the same CM-type, returns True if and only if there is an (n,n)-isogeny between them. Assumes the orders Oi of Zi to satisfy Fi*OK subset Oi.
If double_check, also checks whether there is an isogeny the other way (which should be equivalent). Raises an error if there is an isogeny in only one direction.
EXAMPLES:
sage: from recip import * sage: K = CM_Field([5,5,5]) sage: Phi = K.CM_types()[0] sage: alpha = K.gen() sage: orders = [K.order([1/2*alpha^3 + 1/2, 1/2*alpha^3 + 5/2*alpha^2 + 5/2*alpha, 5*alpha^2, alpha^3]), K.order([1, 2*alpha, 2*alpha^2, alpha^3]), K.order([3/2*alpha^3 + 1/2, 3/2*alpha^3 + 1/2*alpha^2 + 3/2*alpha, alpha^2, 3*alpha^3])] sage: OK = K.maximal_order() sage: O = orders[0] sage: O.index_in(OK) 25 sage: s = superorders_stable_under_complex_conjugation(O) sage: len(s) 3 sage: F = 5 sage: [ideal_contains(A.basis(), [F*b for b in OK.basis()]) for A in s] [True, True, True] sage: Zs = [period_matrices(A, F, Phi) for A in s] # long time, half a minute sage: len(Zs[0]) == 1 and s[0] == OK # long time True sage: Zmax = Zs[0][0] # long time sage: len(Zs[2]) == 0 and len(Zs[1]) == 1 # long time True sage: Zother = Zs[1][0] # long time sage: are_nn_isogenous(Zmax, Zother, 5, 1, F, transformation=True) # long time (True, 1/10*alpha^3 - 1/2) sage: b, t = _ # long time sage: ideal_index([b*t for b in Zmax.basis()], Zother.basis()) # long time 25 sage: cc = K.complex_conjugation() # long time sage: Zother.xi()*t*cc(t)*5 == Zmax.xi() # long time True
Some checks for the are_nn_isogenous function:
sage: are_nn_isogenous(Zmax, Zmax, 5, 5, 5, transformation=True) # long time (True, -1/5*alpha^3 - 1/10*alpha^2 - 1/2*alpha - 1/2) sage: are_nn_isogenous(Zmax, Zmax, 1, 1, 1, transformation=True) # long time (True, 1) sage: are_nn_isogenous(Zother, Zother, 1, F, F, transformation=True) # long time (True, 1) sage: are_nn_isogenous(Zmax, Zother, 3, 1, F) # long time False sage: are_nn_isogenous(Zmax, 7*Zmax, 7, 1, 7) # todo, multiplication of period matrices by integers is not implemented True
Another example:
sage: O = orders[2] sage: O.index_in(OK) 9 sage: s = superorders_stable_under_complex_conjugation(O) sage: len(s) 2 sage: F = 3 sage: [ideal_contains(A.basis(), [F*b for b in OK.basis()]) for A in s] [True, True] sage: Zs = [period_matrices(A, F, Phi) for A in s] sage: len(Zs[0]) == 1 and s[0] == OK True sage: Zmax = Zs[0][0] sage: len(Zs[1]) == 2 True sage: Zothers = Zs[1] sage: are_nn_isogenous(Zmax, Zothers[0], 3, 1, F, transformation=True) (True, 1) sage: are_nn_isogenous(Zmax, Zothers[1], 3, 1, F, transformation=True) (True, 1)
The 2-part will be dealt with for all fields together.
-
recip.orders.
class_polynomials_order
(O, F, Phi, prec, include_period_matrices=False)¶ Returns the class polynomials of an order in a cyclic quartic CM-field K.
TODO: more general fields, examples
-
recip.orders.
ideal_contains
(B, A)¶ Given bases of two lattices B and A in K, returns true if and only if the lattice B contains the lattice A.
-
recip.orders.
ideal_divide
(basis1, basis2, K)¶ Given bases of ideals A1 and A2, returns a basis of (A1 : A2) = {a in K : a*A2 subset A1}.
EXAMPLES:
sage: from recip import * sage: K.<a> = QuadraticField(15) sage: basis1 = [1, a] # Maximal order OK sage: basis2 = [2, 2*a] # 2OK sage: basis3 = [1, 2*a] # Another order, O sage: basis4 = [2, a] # Fractional ideal. Note: 4*basis4 is an ideal of basis3. sage: ideal_divide(basis1, basis2, K) # OK / 2OK = (1/2)OK [1/2, 1/2*a] sage: ideal_divide(basis1, basis3, K) # contains OK as OK*O = OK, and is contained in OK as it multiplies 1 into OK [1, a] sage: ideal_divide(basis2, basis3, K) # twice the above [2, 2*a] sage: ideal_divide(basis4, basis3, K) # ideal divided by its own order [2, a] sage: ideal_divide(basis4, basis4, K) # endomorphism ring of ideal 4 [1, 2*a]
-
recip.orders.
ideal_index
(B, A, check_included=True)¶ Given two ideals B and A, assuming B contains A, returns the index of A in B.
Here A and B are given by their bases, which are sequences of n elements of K, where n=[K:QQ] and A and B are lattices in K.
If check_included is False, then B does not have to contain A, and the output is the quotient of the indices in B+A.
-
recip.orders.
ideal_inverse
(basis, K, O=None)¶ Given a basis of an ideal A, returns a basis of (O : A) = {a in K : a*A subset O}.
If O is not specified, use ideal_order(basis, K).
EXAMPLES:
sage: from recip import * sage: K.<a> = QuadraticField(15) sage: basis1 = [1, a] # Maximal order OK sage: basis2 = [2, 2*a] # 2OK sage: basis3 = [1, 2*a] # Another order, O sage: basis4 = [2, a] # Fractional ideal. Note: 2*basis4 is an ideal of basis3. sage: ideal_inverse(basis1, K) # The order itself [1, a] sage: ideal_inverse(basis2, K) # (1/2)OK [1/2, 1/2*a] sage: ideal_inverse(basis3, K) # the order itself [1, 2*a] sage: basis5 = ideal_inverse(basis4, K); basis5 # happens to be self-inverse [2, a] sage: mult_ideals(basis4, basis5, K) [1, 2*a] sage: ideal_order(basis4, K).basis() [1, 2*a] sage: ideal_is_invertible(basis2, O = K.order(basis3)) False sage: ideal_is_invertible(basis2, O = K.order(basis1)) True sage: bases = [basis1, basis2, basis3, basis4] sage: all([ideal_is_invertible(b) for b in bases]) # quadratic ring, hence all invertible for some ring True
Special case of Exercise 2.20 of http://websites.math.leidenuniv.nl/algebra/ant.pdf
sage: from recip import * sage: K.<a> = NumberField(x^3+x+1) sage: A = K.order([1, a, a^2]) sage: p = 7 sage: R = K.order([1, p*a, p*a^2]) sage: I = additive_gens_to_basis([1, p*a, p*a^2, a, p*a^2, p*a^3], K); I [1, a, 7*a^2] sage: ideal_order(I, K) == R True sage: Isq = mult_ideals(I, I, K); Isq [1, a, a^2] sage: ideal_order(Isq, K) == A True
The final part of the exercise is to show that the above implies that I is a proper, but non-invertible R-ideal. In particular, it is for all orders non-invertible. We compute the ``inverse’’ of this non-invertible ideal:
sage: Iinv = ideal_inverse(I, K); Iinv [7, 7*a, 7*a^2] sage: mult_ideals(I, Iinv, K) [7, 7*a, 7*a^2] sage: ideal_is_invertible(I) False sage: ideal_is_invertible(Isq, O=A) True sage: ideal_is_invertible(Isq, O=R) False sage: ideal_is_invertible(Isq) True
Something from work with Sorina Ionica, Chloe Martindale and Damien Robert:
sage: from recip import * sage: K = CM_Field([40, 20, 90]) sage: alpha = K.gen() sage: I1 = [2*alpha^3 + 2, 220/3*alpha^3 + 2/3*alpha, 3*alpha^3 + 3*alpha^2, 111*alpha^3] sage: xi1 = -1/5328*alpha^3 - 31/26640*alpha sage: I2 = [28*alpha^3 + 2*alpha^2 + 10, 61/3*alpha^3 + 2*alpha^2 + 2/3*alpha, 15*alpha^3 + 6*alpha^2, 39*alpha^3] sage: xi2 = -1/93600*alpha^3 + 1/9360*alpha sage: I3 = [2*alpha^3 + 2, 4/3*alpha^3 + 2*alpha^2 + 2/3*alpha, 6*alpha^2, 3*alpha^3] sage: xi3 = 1/1440*alpha^3 + 7/720*alpha sage: O = ideal_order(I1, K) sage: O == ideal_order(I2, K) True sage: O == ideal_order(I3, K) True sage: O.index_in(K.maximal_order()) 27 sage: I1inv = ideal_inverse(I1, K) sage: P1 = mult_ideals(I1, I1inv, K); P1 [3, 2*alpha^3 + alpha, 3*alpha^2, 3*alpha^3] sage: O1 = ideal_order(P1, K); O1 == O False sage: O1.index_in(K.maximal_order()) 1 sage: I2inv = ideal_inverse(I2, K) sage: P2 = mult_ideals(I2, I2inv, K); P2 [3, 2*alpha^3 + alpha, 3*alpha^2, 3*alpha^3] sage: O2 = ideal_order(P2, K) sage: O2 == O1 True sage: I3inv = ideal_inverse(I3, K) sage: P3 = mult_ideals(I3, I3inv, K); P3 [3, 2*alpha^3 + alpha, 3*alpha^2, 3*alpha^3] sage: O3 = ideal_order(P3, K) sage: O3 == O1 True
-
recip.orders.
ideal_is_invertible
(basis, K=None, O=None)¶ Returns True if and only if the ZZ-lattice I spanned by basis is an invertible O-ideal.
If O is not specified, returns True if and only if there is an order O such that I is an invertible O-ideal. Equivalently, it then returns True if and only if it is an invertible ideal of its endomorphism order.
See
ideal_inverse()
for examples.
-
recip.orders.
ideal_order
(basis, K)¶ Given a basis of an ideal, returns the endomorphism ring inside K of this ideal, as an order.
EXAMPLES:
sage: from recip import * sage: K.<a> = QuadraticField(15) sage: basis1 = [1, a] # Maximal order OK sage: basis2 = [2, 2*a] # 2OK sage: basis3 = [1, 2*a] # Another order, O sage: basis4 = [2, a] # Fractional ideal. Note: 4*basis4 is an ideal of basis3. sage: O1 = ideal_order(basis1, K); O1 Order in Number Field in a with defining polynomial x^2 - 15 sage: O1.basis() [1, a] sage: ideal_order(basis2, K) == O1 True sage: O3 = ideal_order(basis3, K) sage: O3.basis() [1, 2*a] sage: O1 == O3 False sage: ideal_order(basis4, K) == O3 True sage: is_ideal(O3, basis3) True sage: is_ideal(O1, basis3) False sage: is_ideal(O1, basis1) True sage: is_ideal(O3, basis1) True
-
recip.orders.
ideals_equal
(A, B, K=None)¶ Given bases of two lattices A and B in K, returns true if and only if the lattices are equal.
-
recip.orders.
intersect_ideals
(basis1, basis2, K)¶ Given bases of lattices in K, returns a basis of their intersection.
EXAMPLES:
sage: from recip import * sage: K.<a> = QuadraticField(15) sage: basis1 = [1, a] # Maximal order OK sage: basis2 = [2, 2*a] # 2OK sage: basis3 = [1, 2*a] # Another order, O sage: basis4 = [2, a] # Fractional ideal. Note: 4*basis4 is an ideal of basis3. sage: intersect_ideals(basis1, basis2, K) # ideal2 intersected with an ambient ring, hence unchanged [2, 2*a] sage: intersect_ideals(basis1, basis3, K) # Two orders intersected, hence the smallest is obtained [1, 2*a] sage: intersect_ideals(basis2, basis3, K) # ideal2 intersected with an ambient ring, hence unchanged [2, 2*a] sage: intersect_ideals(basis4, basis3, K) # intersection [2, 2*a] sage: intersect_ideals(basis4, basis4, K) # intersection with itself [2, a]
-
recip.orders.
is_ideal
(O, B)¶ Given a basis B of a lattice L in a field K, and an order O in K, return True if and only if \(O L \subset L\).
-
recip.orders.
is_trivial_in_shimura_group
(A, alpha, O, cc=None)¶ Given an integral ideal A of the maximal order O_K of O coprime to F = [O_K : O] and given an element alpha of O with A*Abar = alpha*O_K, returns True if and only if there exists mu in K^* with mu*mubar = alpha and mu*O coprime to F*O as ideals of O and mu*O_K = A.
cc is complex conjugation (if not given, assumes K is a CM-field object).
Assumes K is a non-biquadratic quartic CM-field (TODO: does not warn for biquadratic fields).
Assumes O is stable under complex conjugation.
EXAMPLES:
We first create a suitable order, and standard things like reflex fields etcetera:
sage: from recip import * sage: P.<x> = QQ[] sage: CM_Field(x^4+2*x^3+16*x^2+15*x+19).minimal_DAB() [149, 13, 5] sage: K = CM_Field([149,13,5]) sage: Phi = K.CM_types()[0] sage: Psi = Phi.reflex() sage: Kr = Phi.reflex_field() sage: [alpha1,alpha2]=(x^4+2*x^3+16*x^2+15*x+19).roots(K, multiplicities=False) sage: cc = K.complex_conjugation() sage: cc(alpha1) == alpha2 True sage: O = K.order(alpha1) sage: alpha2 in O True sage: OK = K.maximal_order() sage: O.index_in(OK) 7
Now let’s compute lots of ideal classes to try:
sage: ideal_classes = [c.ideal() for c in Kr.class_group()] sage: idealstar = Kr.ideal(7).idealstar(flag=2).list() sage: ray_classes = [a*b for a in idealstar for b in ideal_classes] sage: len(ray_classes) 2304 sage: type_norms = [(Psi.type_norm(I), I.norm()) for I in ray_classes] # long time, 20 seconds
Here we test the current function:
sage: all([is_trivial_in_shimura_group(A, alpha, OK) for (A, alpha) in type_norms]) # long time, 30 seconds *** Warning: precision too low for generators, not given. ... *** Warning: precision too low for generators, not given. True sage: len([A for (A, alpha) in type_norms if is_trivial_in_shimura_group(A, alpha, O)]) # long time, 25 seconds 384 sage: 2304/384 6
1/6 of ideals maps to a principal ideal, so the image has order 6.
-
recip.orders.
minimal_F
(O)¶ Given an order O in a number field K, returns the smallest integer F such that F*O_K subset O.
-
recip.orders.
mult_ideals
(basis1, basis2, K)¶ Given bases of lattices in K, returns a basis of their product.
EXAMPLES:
sage: from recip import * sage: K.<a> = QuadraticField(15) sage: basis1 = [1, a] # Maximal order OK sage: basis2 = [2, 2*a] # 2OK sage: basis3 = [1, 2*a] # Another order, O sage: basis4 = [2, a] # Fractional ideal. Note: 4*basis4 is an ideal of basis3. sage: mult_ideals(basis1, basis2, K) # basis2 multiplied by its endomorphism ring, hence unchanged [2, 2*a] sage: mult_ideals(basis1, basis3, K) # Two orders multiplied, hence the largest is obtained [1, a] sage: mult_ideals(basis2, basis3, K) # Twice the above [2, 2*a] sage: mult_ideals(basis4, basis3, K) # basis4 multiplied by its endomorphism ring, hence unchanged [2, a] sage: mult_ideals(basis4, basis4, K) # the square of basis4, generated by 4, 2a and a^2 = 15. [1, 2*a]
-
recip.orders.
period_matrices
(O, F, Phi=None, reduced=True)¶ Returns all isomorphism classes of principally polarized abelian surfaces with CM by O of type Phi. Here F is such that F*OK is contained in O.
If Phi is None, use all CM-types and gives all elements up to complex conjugation of the CM type.
EXAMPLES:
Here is a bug, some numbers are close to zero and apparently CLF’s > 0 is not to be trusted.:
sage: from recip import * sage: K = CM_Field([1837, 81, 1181]) sage: Phi = K.CM_types()[0] sage: len(period_matrices(K.maximal_order(), 1, Phi)) # long time, half a minute 66
-
recip.orders.
polarized_ideal_classes
(O, F)¶ On input an order O of a quartic CM-field, returns all principally polarized ideal classes up to
- changing (aaa, xi) into (aaa, -xi),
- changing (aaa, xi) into (x*aaa, xi/x/xbar) for x in K.
In the primitive quartic case, this is either the empty set or half of a torsor for the group CCC(O) in the article of Bisson and Streng. (Half of, because only one of (aaa, xi) and (aaa, -xi) is given.) If O is the maximal order of a primtive quartic CM-field, then the output is non-empty.
INPUT:
- \(O\) – order in a quartic \(CM_Field\) object
- \(F\) – positive integer such that F*OK is contained in O (not checked)
EXAMPLES:
sage: from recip import * sage: K = CM_Field([5,5,5]) sage: Phi = K.CM_types()[0] sage: alpha = K.gen() sage: O = K.order([1/2*alpha^3 + 1/2, 1/2*alpha^3 + 5/2*alpha^2 + 5/2*alpha, 5*alpha^2, alpha^3]) sage: OK = K.maximal_order() sage: O.index_in(OK) 25 sage: s = superorders_stable_under_complex_conjugation(O) sage: len(s) 3 sage: F = 5 sage: [ideal_contains(A.basis(), [F*b for b in OK.basis()]) for A in s] [True, True, True] sage: polarized_ideal_classes(s[0], 1) [([1/2*alpha^3 + 1/2, 1/2*alpha^3 + 1/2*alpha^2 + 1/2*alpha, alpha^2, alpha^3], 1/5*alpha), ([1/2*alpha^3 + 1/2, 1/2*alpha^3 + 1/2*alpha^2 + 1/2*alpha, alpha^2, alpha^3], -1/5*alpha^3 - 3/5*alpha)] sage: polarized_ideal_classes(s[0], 5) == _ # long time True sage: polarized_ideal_classes(s[1], 5) # long time [([1/2*alpha^3 + 1/2, 1/2*alpha^3 + 1/2*alpha^2 + 5/2*alpha, alpha^2, alpha^3], 2/25*alpha^3 + 1/5*alpha), ([1/2*alpha^3 + 1/2, 1/2*alpha^3 + 1/2*alpha^2 + 5/2*alpha, alpha^2, alpha^3], 1/25*alpha^3 + 1/5*alpha)] sage: polarized_ideal_classes(s[2], 5) # long time []
-
recip.orders.
proper_ideal_classes
(O, F)¶ Input: O an order, F non-zero in ZZ and a multiple of the conductor.
Output: representatives of all classes of proper ideals of O modulo principal ideals.
Warning: not tested much except for primitive quartic CM-fields.
sage: from recip import * sage: K = CM_Field([5,5,5]) sage: Phi = K.CM_types()[0] sage: alpha = K.gen() sage: O = K.order([1/2*alpha^3 + 1/2, 1/2*alpha^3 + 5/2*alpha^2 + 5/2*alpha, 5*alpha^2, alpha^3]) sage: OK = K.maximal_order() sage: O.index_in(OK) 25 sage: s = superorders_stable_under_complex_conjugation(O) sage: len(s) 3 sage: F = 5 sage: [ideal_contains(A.basis(), [F*b for b in OK.basis()]) for A in s] [True, True, True] sage: proper_ideal_classes(s[0], 1) ([[1/2*alpha^3 + 1/2, 1/2*alpha^3 + 1/2*alpha^2 + 1/2*alpha, alpha^2, alpha^3]], [[1/2*alpha^3 + 1/2, 1/2*alpha^3 + 1/2*alpha^2 + 1/2*alpha, alpha^2, alpha^3]], [[1/2*alpha^3 + 1/2, 1/2*alpha^3 + 1/2*alpha^2 + 1/2*alpha, alpha^2, alpha^3]]) sage: proper_ideal_classes(s[0], 5) == _ # long time True sage: proper_ideal_classes(s[1], 5) # long time ([[1/2*alpha^3 + 1/2, 1/2*alpha^3 + 1/2*alpha^2 + 5/2*alpha, alpha^2, alpha^3]], [[1/2*alpha^3 + 1/2, 5/2*alpha^3 + 5/2*alpha^2 + 5/2*alpha, alpha^2, alpha^3]], [[1/2*alpha^3 + 1/2, 1/2*alpha^3 + 1/2*alpha^2 + 5/2*alpha, alpha^2, alpha^3]]) sage: proper_ideal_classes(s[2], 5) # long time ([[1/2*alpha^3 + 1/2, 1/2*alpha^3 + 1/2*alpha^2 + 1/2*alpha, 5*alpha^2, alpha^3], [1/2*alpha^3 + 1/2, 1/2*alpha^3 + 5/2*alpha^2 + 5/2*alpha, 5*alpha^2, alpha^3]], [[1/2*alpha^3 + 1/2, 1/2*alpha^3 + 1/2*alpha^2 + 1/2*alpha, 5*alpha^2, alpha^3], [1/2*alpha^3 + 1/2, 5/2*alpha^3 + 5/2*alpha^2 + 5/2*alpha, 5*alpha^2, alpha^3]], [[1/2*alpha^3 + 1/2, 1/2*alpha^3 + 5/2*alpha^2 + 5/2*alpha, 5*alpha^2, alpha^3]])
-
recip.orders.
superorders
(O)¶ Given an order O in a number field K, returns all orders in K containing O.
NOTE: this implementation is probably not optimal, as it uses all subgroups of OK/O and tests whether they yield rings.
EXAMPLES:
sage: from recip import * sage: K = CM_Field([5,5,5]) sage: OK = K.maximal_order() sage: O = K.order([5*b for b in OK.basis()]) sage: s = superorders(O) sage: [A.index_in(OK) for A in s] [1, 5, 25, 25, 25, 25, 25, 25, 125]
-
recip.orders.
superorders_stable_under_complex_conjugation
(O, c=None)¶ Given an order O in a number field K, and an automorphism c of K, returns all orders of K containing O and fixed under c.
If c is omitted and K has a method complex_conjugation, then use that for c.
EXAMPLES:
sage: from recip import * sage: K = CM_Field([5,5,5]) sage: OK = K.maximal_order() sage: O = K.order([5*b for b in OK.basis()]) sage: s = superorders_stable_under_complex_conjugation(O) sage: [A.index_in(OK) for A in s] [1, 5, 25, 25, 125]
-
recip.orders.
trace_dual_complex_conjugate
(A, cc=None)¶ Given a basis A of a lattice, returns the trace dual of cc(A). If cc is not specified and K has a complex_conjugation method, use that.