..nodoctest

Bisson-Streng

x.__init__(...) initializes x; see help(type(x)) for signature

recip.bissonstreng.CM_type_to_mus(Phi, F)

Returns mu generating N_Phir(aaa) with mu*mubar in QQ for aaa ranging over generators of the ray class group mod F of the reflex field of Phi.

recip.bissonstreng.all_period_matrices_two(lst)

Find all period matrices with CM by an order of 2-power index in OK such that the field of moduli is in Kr, where K ranges over the fields given by lst.

And tests whether for all but [5,5,5] that there are no orders with non-2-power index such that the field of moduli is in Kr (by raising an error if there is such an order).

OUTPUT:

  • List of triples (K, Phi, F, Zs, orders), where Zs[k] is a period matrix has CM by orders[k] for each k, and F*OK is contained in each element of orders.

EXAMPLES:

sage: from recip import *
sage: lst = wamelen_dab_list() + [[5, 15, 45], [5, 30, 180], [5, 35, 245], [5, 105, 2205], [8, 12, 18], [17, 119, 3332], [17, 255, 15300]]
sage: Zs = all_period_matrices_two(lst) # long time, 2 minutes
sage: [len(l) for (K,Phi,F,l,orders) in Zs] # long time
[6, 3, 1, 6, 2, 1, 2, 1, 6, 2, 6, 1, 1, 4, 12, 4, 4, 6, 2, 4]

sage: matr = [two_two_matrix(l, F) for (K, Phi, F, l, orders) in Zs] # long time
sage: matr # long time, output is random
[
[0 1 1 1 0 0]                [0 1 1 0 1 0]
[1 0 0 0 1 1]                [1 0 0 1 0 1]
[1 0 0 0 1 1]                [1 0 0 1 0 1]
[1 0 0 0 1 1]  [1 1 1]       [0 1 1 0 1 0]
[0 1 1 1 0 0]  [1 1 1]       [1 0 0 1 0 1]  [0 0]       [0 0]
[0 1 1 1 0 0], [1 1 1], [0], [0 1 1 0 1 0], [0 0], [0], [0 0], [0],

[1 0 0 1 0 1]         [0 1 1 0 1 0]
[0 1 1 0 1 0]         [1 0 0 1 0 1]
[0 1 1 0 1 0]         [1 0 0 1 0 1]            [0 1 0 0]
[1 0 0 1 0 1]         [0 1 1 0 1 0]            [1 0 0 0]
[0 1 1 0 1 0]  [0 0]  [1 0 0 1 0 1]            [0 0 0 1]
[1 0 0 1 0 1], [0 0], [0 1 1 0 1 0], [0], [0], [0 0 1 0],

[0 0 1 0 1 0 1 0 0 0 0 0]
[0 0 0 1 0 1 0 1 0 0 0 0]
[1 0 0 0 0 0 0 0 1 0 1 0]
[0 1 0 0 0 0 0 0 0 1 0 1]
[1 0 0 0 0 0 0 0 1 0 1 0]
[0 1 0 0 0 0 0 0 0 1 0 1]
[1 0 0 0 0 0 0 0 1 0 1 0]                        [1 0 0 1 0 1]
[0 1 0 0 0 0 0 0 0 1 0 1]                        [0 1 1 0 1 0]
[0 0 1 0 1 0 1 0 0 0 0 0]  [0 0 0 1]  [0 0 0 0]  [0 1 1 0 1 0]
[0 0 0 1 0 1 0 1 0 0 0 0]  [0 0 1 0]  [0 0 0 0]  [1 0 0 1 0 1]
[0 0 1 0 1 0 1 0 0 0 0 0]  [0 1 0 0]  [0 0 0 0]  [0 1 1 0 1 0]  [0 0]
[0 0 0 1 0 1 0 1 0 0 0 0], [1 0 0 0], [0 0 0 0], [1 0 0 1 0 1], [0 0],

[0 0 0 0]
[0 0 0 0]
[0 0 0 0]
[0 0 0 0]
]

The output above was with an older version of Sage. We now check that the actual output agrees up to graph isomorphism, and then we apply a graph isomorphism and continue with the result after isomorphism.:

sage: L = [[[0, 1, 1, 1, 0, 0],
....:   [1, 0, 0, 0, 1, 1],
....:   [1, 0, 0, 0, 1, 1],
....:   [1, 0, 0, 0, 1, 1],
....:   [0, 1, 1, 1, 0, 0],
....:   [0, 1, 1, 1, 0, 0]],
....:  [[1, 1, 1], [1, 1, 1], [1, 1, 1]],
....:  [[0]],
....:  [[0, 1, 1, 0, 1, 0],
....:   [1, 0, 0, 1, 0, 1],
....:   [1, 0, 0, 1, 0, 1],
....:   [0, 1, 1, 0, 1, 0],
....:   [1, 0, 0, 1, 0, 1],
....:   [0, 1, 1, 0, 1, 0]],
....:  [[0, 0], [0, 0]],
....:  [[0]],
....:  [[0, 0], [0, 0]],
....:  [[0]],
....:  [[1, 0, 0, 1, 0, 1],
....:   [0, 1, 1, 0, 1, 0],
....:   [0, 1, 1, 0, 1, 0],
....:   [1, 0, 0, 1, 0, 1],
....:   [0, 1, 1, 0, 1, 0],
....:   [1, 0, 0, 1, 0, 1]],
....:  [[0, 0], [0, 0]],
....:  [[0, 1, 1, 1, 0, 0],
....:   [1, 0, 0, 0, 1, 1],
....:   [1, 0, 0, 0, 1, 1],
....:   [1, 0, 0, 0, 1, 1],
....:   [0, 1, 1, 1, 0, 0],
....:   [0, 1, 1, 1, 0, 0]],
....:  [[0]],
....:  [[0]],
....:  [[0, 1, 0, 0], [1, 0, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0]],
....:  [[0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0],
....:   [0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0],
....:   [1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0],
....:   [0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1],
....:   [1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0],
....:   [0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1],
....:   [1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0],
....:   [0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1],
....:   [0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0],
....:   [0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0],
....:   [0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0],
....:   [0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0]],
....:  [[0, 0, 0, 1], [0, 0, 1, 0], [0, 1, 0, 0], [1, 0, 0, 0]],
....:  [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]],
....:  [[1, 0, 0, 1, 0, 1],
....:   [0, 1, 1, 0, 1, 0],
....:   [0, 1, 1, 0, 1, 0],
....:   [1, 0, 0, 1, 0, 1],
....:   [0, 1, 1, 0, 1, 0],
....:   [1, 0, 0, 1, 0, 1]],
....:  [[0, 0], [0, 0]],
....:  [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]]
sage: matrL = [Matrix(c) for c in L]
sage: matr == matrL # exact equality, was False at latest Sage version, long time
False
sage: t = [(Graph(matrL[c]).is_isomorphic(Graph(matr[c]), certificate=True), matr[c]) for c in range(len(L))] # long time
sage: all([a[0] for (a,b) in t]) # here is what matters, long time
True
sage: matr = [Matrix([[c[a[1][i],a[1][j]] for j in range(c.ncols())] for i in range(c.nrows())]) for (a,c) in t] # long time
sage: matr == matrL # now we do have the same graph as before (when forgetting the orders, so still doctests can fail at later stages in later versions of Sage). long time
True
sage: matr # long time
[
[0 1 1 1 0 0]                [0 1 1 0 1 0]
[1 0 0 0 1 1]                [1 0 0 1 0 1]
[1 0 0 0 1 1]                [1 0 0 1 0 1]
[1 0 0 0 1 1]  [1 1 1]       [0 1 1 0 1 0]
[0 1 1 1 0 0]  [1 1 1]       [1 0 0 1 0 1]  [0 0]       [0 0]
[0 1 1 1 0 0], [1 1 1], [0], [0 1 1 0 1 0], [0 0], [0], [0 0], [0],

[1 0 0 1 0 1]         [0 1 1 1 0 0]
[0 1 1 0 1 0]         [1 0 0 0 1 1]
[0 1 1 0 1 0]         [1 0 0 0 1 1]            [0 1 0 0]
[1 0 0 1 0 1]         [1 0 0 0 1 1]            [1 0 0 0]
[0 1 1 0 1 0]  [0 0]  [0 1 1 1 0 0]            [0 0 0 1]
[1 0 0 1 0 1], [0 0], [0 1 1 1 0 0], [0], [0], [0 0 1 0],

[0 0 1 0 1 0 1 0 0 0 0 0]
[0 0 0 1 0 1 0 1 0 0 0 0]
[1 0 0 0 0 0 0 0 1 0 1 0]
[0 1 0 0 0 0 0 0 0 1 0 1]
[1 0 0 0 0 0 0 0 1 0 1 0]
[0 1 0 0 0 0 0 0 0 1 0 1]
[1 0 0 0 0 0 0 0 1 0 1 0]                        [1 0 0 1 0 1]
[0 1 0 0 0 0 0 0 0 1 0 1]                        [0 1 1 0 1 0]
[0 0 1 0 1 0 1 0 0 0 0 0]  [0 0 0 1]  [0 0 0 0]  [0 1 1 0 1 0]
[0 0 0 1 0 1 0 1 0 0 0 0]  [0 0 1 0]  [0 0 0 0]  [1 0 0 1 0 1]
[0 0 1 0 1 0 1 0 0 0 0 0]  [0 1 0 0]  [0 0 0 0]  [0 1 1 0 1 0]  [0 0]
[0 0 0 1 0 1 0 1 0 0 0 0], [1 0 0 0], [0 0 0 0], [1 0 0 1 0 1], [0 0],

[0 0 0 0]
[0 0 0 0]
[0 0 0 0]
[0 0 0 0]
]

The matrices above correspond to the (2,2)-isogeny graphs, one matrix for every order, one row/column for every period matrix. Next, we look at the orders corresponding to these period matrices. An entry a in row i and column j means that a is non-zero if and only if period matrices i and j have the same endomorphism ring, and a is the index of that endomorphism ring in the maximal order.:

sage: vis = [visualize_orders(orders) for (K, Phi, F, l, orders) in Zs] # long time
sage: flatten([[Matrix(lst[k]),Matrix([[vis[k][t[k][0][1][i],t[k][0][1][j]] for j in range(vis[k].ncols())] for i in range(vis[k].nrows())]), matr[k]] for k in range(len(matr))]) # long time
[
         [ 1  0  0  0  0  0]  [0 1 1 1 0 0]
         [ 0  4  0  0  0  0]  [1 0 0 0 1 1]
         [ 0  0  8  8  0  0]  [1 0 0 0 1 1]
         [ 0  0  8  8  0  0]  [1 0 0 0 1 1]           [1 0 0]  [1 1 1]
         [ 0  0  0  0 16 16]  [0 1 1 1 0 0]           [0 2 2]  [1 1 1]
[5 5 5], [ 0  0  0  0 16 16], [0 1 1 1 0 0], [8 4 2], [0 2 2], [1 1 1],

                                  [1 1 0 0 0 0]  [0 1 1 0 1 0]
                                  [1 1 0 0 0 0]  [1 0 0 1 0 1]
                                  [0 0 4 4 4 4]  [1 0 0 1 0 1]
                                  [0 0 4 4 4 4]  [0 1 1 0 1 0]
                                  [0 0 4 4 4 4]  [1 0 0 1 0 1]
[13 13 13], [1], [0], [ 5 10 20], [0 0 4 4 4 4], [0 1 1 0 1 0],

               [1 1]  [0 0]
[  5  65 845], [1 1], [0 0], [29 29 29], [1], [0], [   5   85 1445],

                                                   [1 1 0 0 0 0]
                                                   [1 1 0 0 0 0]
                                                   [0 0 2 2 2 2]
                                                   [0 0 2 2 2 2]
[1 1]  [0 0]                                       [0 0 2 2 2 2]
[1 1], [0 0], [ 37  37 333], [1], [0], [ 8 20 50], [0 0 2 2 2 2],

[1 0 0 1 0 1]                                           [1 1 0 0 0 0]
[0 1 1 0 1 0]                                           [1 1 0 0 0 0]
[0 1 1 0 1 0]                                           [0 0 4 4 4 4]
[1 0 0 1 0 1]                                           [0 0 4 4 4 4]
[0 1 1 0 1 0]                 [1 1]  [0 0]              [0 0 4 4 4 4]
[1 0 0 1 0 1], [ 13  65 325], [1 1], [0 0], [13 26 52], [0 0 4 4 4 4],

[0 1 1 1 0 0]
[1 0 0 0 1 1]
[1 0 0 0 1 1]
[1 0 0 0 1 1]
[0 1 1 1 0 0]
[0 1 1 1 0 0], [53 53 53], [1], [0], [ 61  61 549], [1], [0],

            [1 1 1 1]  [0 1 0 0]
            [1 1 1 1]  [1 0 0 0]
            [1 1 1 1]  [0 0 0 1]
[ 5 15 45], [1 1 1 1], [0 0 1 0], [  5  30 180],

[1 1 1 1 0 0 0 0 0 0 0 0]  [0 0 1 0 1 0 1 0 0 0 0 0]
[1 1 1 1 0 0 0 0 0 0 0 0]  [0 0 0 1 0 1 0 1 0 0 0 0]
[1 1 1 1 0 0 0 0 0 0 0 0]  [1 0 0 0 0 0 0 0 1 0 1 0]
[1 1 1 1 0 0 0 0 0 0 0 0]  [0 1 0 0 0 0 0 0 0 1 0 1]
[0 0 0 0 4 4 4 4 4 4 4 4]  [1 0 0 0 0 0 0 0 1 0 1 0]
[0 0 0 0 4 4 4 4 4 4 4 4]  [0 1 0 0 0 0 0 0 0 1 0 1]
[0 0 0 0 4 4 4 4 4 4 4 4]  [1 0 0 0 0 0 0 0 1 0 1 0]
[0 0 0 0 4 4 4 4 4 4 4 4]  [0 1 0 0 0 0 0 0 0 1 0 1]
[0 0 0 0 4 4 4 4 4 4 4 4]  [0 0 1 0 1 0 1 0 0 0 0 0]
[0 0 0 0 4 4 4 4 4 4 4 4]  [0 0 0 1 0 1 0 1 0 0 0 0]
[0 0 0 0 4 4 4 4 4 4 4 4]  [0 0 1 0 1 0 1 0 0 0 0 0]
[0 0 0 0 4 4 4 4 4 4 4 4], [0 0 0 1 0 1 0 1 0 0 0 0], [  5  35 245],

[1 1 1 1]  [0 0 0 1]                    [1 1 1 1]  [0 0 0 0]
[1 1 1 1]  [0 0 1 0]                    [1 1 1 1]  [0 0 0 0]
[1 1 1 1]  [0 1 0 0]                    [1 1 1 1]  [0 0 0 0]
[1 1 1 1], [1 0 0 0], [   5  105 2205], [1 1 1 1], [0 0 0 0],

            [1 1 0 0 0 0]  [1 0 0 1 0 1]
            [1 1 0 0 0 0]  [0 1 1 0 1 0]
            [0 0 2 2 2 2]  [0 1 1 0 1 0]
            [0 0 2 2 2 2]  [1 0 0 1 0 1]
            [0 0 2 2 2 2]  [0 1 1 0 1 0]                    [1 1]
[ 8 12 18], [0 0 2 2 2 2], [1 0 0 1 0 1], [  17  119 3332], [1 1],

                            [1 1 1 1]  [0 0 0 0]
                            [1 1 1 1]  [0 0 0 0]
[0 0]                       [1 1 1 1]  [0 0 0 0]
[0 0], [   17   255 15300], [1 1 1 1], [0 0 0 0]
]

The first matrix is for \(\QQ[\zeta_5]\), and from the others, we conclude Lemma 6.6. For \(\QQ[\zeta_5]\), we see that the graph is connected.

recip.bissonstreng.is_S_O_equal_S_OK(O)

Given an order O in a non-biquadratic quartic CM-field O, returns True if and only if S_O = S_{O_K}, in the notation of Bisson-Streng.

EXAMPLES:

The same example as in is_trivial_in_shimura_group, but much faster:

sage: from recip import *
sage: K = CM_Field([149,13,5])
sage: P.<x> = QQ[]
sage: [alpha1,alpha2]=(x^4+2*x^3+16*x^2+15*x+19).roots(K, multiplicities=False)
sage: O = K.order(alpha1)
sage: is_S_O_equal_S_OK(O)
False
recip.bissonstreng.minimal_order_cl_nr_one_F(Phi, F=None, output_type='order', Ostart=None)

Returns an order O in the domain K of Phi such that for any order O’ in K containing ZZ+F*OK, if the image of I_Kr(F) in CCC(O) is trivial, then O contains O’.

Returns None every O’ satisfies this property, i.e., if O does not exist.

If K is not QQ(zeta_5), then actually the “if” in the first paragraph is an “if and only if”.

Here F is an integer.

recip.bissonstreng.minimal_orders_of_class_number_one(Phi, output_type='order')

Let K be the domain of the input CM-type Phi. If K is not \(\QQ(\zeta_5)\), returns the list of tuples (p, k, i, O), where p ranges over all primes such that there is an order that is not p-maximal, but does have Shimura class number one. Here O is the smallest such order of index a power i of p, and \(p^k\) is the exponent of the additive group OK/O.

If K is \(\QQ(\zeta_5)\), then the output is as above, except that the list may contain too many primes p, and the orders O may be too small (in other words, for a classification, the output will be on the safe side).

EXAMPLES:

sage: from recip import *
sage: lst = wamelen_dab_list()

sage: K = CM_Field([5,5,5])
sage: Phi = K.CM_types()[0]
sage: minorders = minimal_orders_of_class_number_one(Phi); minorders # long time 1 second
[(2, 2, 16, Order in CM Number Field in alpha with defining polynomial x^4 + 5*x^2 + 5), (3, 1, 9, Order in CM Number Field in alpha with defining polynomial x^4 + 5*x^2 + 5), (5, 3, 15625, Order in CM Number Field in alpha with defining polynomial x^4 + 5*x^2 + 5)]

sage: Phi = CM_Field(lst[1]).CM_types()[0]
sage: m = minimal_orders_of_class_number_one(Phi); m
[(2, 1, 4, Order in CM Number Field in alpha with defining polynomial x^4 + 4*x^2 + 2)]
recip.bissonstreng.orders_proven_with_wamelen(latex_output=False)

Compute the orders O’‘’ in the article, and prove that the non-maximal O’‘’ have index 2 in the maximal order and no proper polarized ideal classes. Then output Table 1 of the article.

EXAMPLES:

sage: from recip import *
sage: orders_proven_with_wamelen()
[([5, 5, 5], 1, 1, 1, 1, 1), ([8, 4, 2], 1, x^4 + 4*x^2 + 2, 1, 1, 1), ([13, 13, 13], 1, x^4 - x^3 + 2*x^2 + 4*x + 3, 3, 1, 1), ([5, 10, 20], 2, x^4 + 10*x^2 + 20, 4, 4, 2), ([5, 65, 845], 2, x^4 - x^3 + 16*x^2 - 16*x + 61, 19, 1, 1), ([29, 29, 29], 1, x^4 - x^3 + 4*x^2 - 20*x + 23, 7, 1, 1), ([5, 85, 1445], 2, x^4 - x^3 + 21*x^2 - 21*x + 101, 29, 1, 1), ([37, 37, 333], 1, x^4 - x^3 + 5*x^2 - 7*x + 49, 21, 3, 1), ([8, 20, 50], 2, x^4 + 20*x^2 + 50, 25, 25, 1), ([13, 65, 325], 2, x^4 - x^3 + 15*x^2 + 17*x + 29, 23, 1, 1), ([13, 26, 52], 2, x^4 + 26*x^2 + 52, 36, 36, 2), ([53, 53, 53], 1, x^4 - x^3 + 7*x^2 + 43*x + 47, 13, 1, 1), ([61, 61, 549], 1, x^4 - x^3 + 8*x^2 - 42*x + 117, 39, 3, 1)]
recip.bissonstreng.two_two_matrix(Zs, F)

Returns an n x n matrix A (where n=len(Zs)) with A[k,l] = 1 if Zs[k] and Zs[l] are (2,2)-isogenous, and A[k,l] = 0 otherwise

recip.bissonstreng.visualize_orders(orders)

Returns an n x n matrix A (where n=len(Zs)) with A[k,l] = [OK:orders[k]] if orders[k]=orders[l], and A[k,l] = 0 otherwise