Contact
CoCalc Logo Icon
StoreFeaturesDocsShareSupport News AboutSign UpSign In
| Download

All published worksheets from http://sagenb.org

Views: 168759
Image: ubuntu2004

We choose an elliptic curve E:

E=EllipticCurve('37a'); E
Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field
E.galois_representation().is_surjective(2)
True
rho=E.galois_representation(); rho
Compatible family of Galois representations associated to the Elliptic Curve defined by y^2 + y = x^3 - x over Rational Field

We choose a Heegner discriminant for E:

E.heegner_discriminants(100)
[-3, -4, -7, -11, -40, -47, -67, -71, -83, -84, -95]

With the choice of a Heegner discriminant, -3, we list possible Kolyvagin primes:

KolyPrimes=[ell for ell in prime_range(1000) if GF(ell)(E.conductor())!=0 and E.heegner_point(-3,ell).satisfies_kolyvagin_hypothesis(3)]; KolyPrimes
[17, 29, 41, 47, 71, 83, 101, 107, 113, 131, 137, 167, 173, 179, 197, 233, 239, 257, 269, 281, 311, 359, 401, 431, 449, 461, 521, 557, 563, 569, 653, 659, 683, 701, 719, 743, 773, 857, 863, 929, 947, 983]

We define the field L=Q(E[2]):

L.<a>=NumberField(x^6 - 3*x^5 - 2*x^4 + 9*x^3 - 5*x + 1); L
Number Field in a with defining polynomial x^6 - 3*x^5 - 2*x^4 + 9*x^3 - 5*x + 1
L.is_galois()
True
EL=E.change_ring(L); EL
Elliptic Curve defined by y^2 + y = x^3 + (-1)*x over Number Field in a with defining polynomial x^6 - 3*x^5 - 2*x^4 + 9*x^3 - 5*x + 1
L.galois_group().is_isomorphic(SymmetricGroup(3))
True

Indeed, the 2-division polynomial of E factors completely over L:

EL.division_polynomial(2).roots(multiplicities=False)
[1/2*a^4 - a^3 - a^2 + 3/2*a, 1/2*a^5 - 3/2*a^4 - a^3 + 4*a^2 + a - 3/2, -1/2*a^5 + a^4 + 2*a^3 - 3*a^2 - 5/2*a + 3/2]

We use Robert Miller's number field Selmer group function.

List=L.primes_above(2)
LSelmerGroup=L.selmer_group(List, 2); LSelmerGroup
[a^3 - 2*a^2 - 2*a + 3, -1, a^3 - 2*a^2 - a + 1, a^5 - 3*a^4 - a^3 + 7*a^2 - 2*a - 1, a, a^3 - 2*a^2 - 2*a + 2, a^4 - 3*a^3 - a^2 + 6*a - 1]

The key difficulty is implementing the L-Selmer group as a vector space. Robert Miller's function only gives a basis as elements of L--we need the structure of the actual group.

F2=FiniteField(2); F2
Finite Field of size 2
V=F2^(len(LSelmerGroup)); V
Vector space of dimension 7 over Finite Field of size 2

Two functions: this one goes from a vector to a Selmer class.

def V_to_Selmer(V, LSelmerGroup, v): a=1 for i in range(dim(V)): a=a*(LSelmerGroup[i]^v[i]) return a

This one goes the opposite way. It is by far the most time-consuming operation here.

def Selmer_to_V(V, LSelmerGroup, a): for v in V: if (a/V_to_Selmer(V, LSelmerGroup, v)).is_square()==True: return v

Here we learn the Galois action on 2-torsion points.

G=L.galois_group(); G
Galois group of Number Field in a with defining polynomial x^6 - 3*x^5 - 2*x^4 + 9*x^3 - 5*x + 1
P=EL.division_polynomial(2).roots(multiplicities=False)[0]
Q=EL.division_polynomial(2).roots(multiplicities=False)[2]
PQ=EL.division_polynomial(2).roots(multiplicities=False)[1]
tau=G.gens()[0]; sigma=G.gens()[1]^-1
tau(P)==Q; tau(Q)==P; tau(PQ)==PQ; sigma(P)==Q; sigma(Q)==PQ; sigma(PQ)==P
True True True True True True

W represents the tensor product vector space.

W=F2^(2*len(LSelmerGroup)); W
Vector space of dimension 14 over Finite Field of size 2

Functions for dealing with the tensor product:

def Glue(u, v, V, W): w=W.zero_vector() for i in range(dim(V)): w[i]=u[i] w[i+dim(V)]=v[i] return w
def Split(w, V, W): u=V.zero_vector(); v=V.zero_vector() for i in range(dim(V)): u[i]=w[i] v[i]=w[i+dim(V)] return [u, v]

Now we can write the Galois generators as matrices. They are big, but once constructed, Sage handles them with lightning speed.

ListTau=list(W.basis()) for j in range(dim(V)): ListTau[j]=Glue(V.zero_vector(), Selmer_to_V(V, LSelmerGroup, tau(V_to_Selmer(V, LSelmerGroup, V.basis()[j]))), V, W) ListTau[j+dim(V)]=Glue(Selmer_to_V(V, LSelmerGroup, tau(V_to_Selmer(V, LSelmerGroup, V.basis()[j]))), V.zero_vector(), V, W) MatrixTau=Matrix(ListTau); print MatrixTau.str()
[0 0 0 0 0 0 0 1 1 1 0 0 1 0] [0 0 0 0 0 0 0 0 1 0 0 0 0 0] [0 0 0 0 0 0 0 0 1 0 0 1 0 0] [0 0 0 0 0 0 0 0 1 1 1 0 1 0] [0 0 0 0 0 0 0 0 1 1 0 0 0 0] [0 0 0 0 0 0 0 0 1 1 0 1 1 0] [0 0 0 0 0 0 0 0 0 1 0 1 0 1] [1 1 1 0 0 1 0 0 0 0 0 0 0 0] [0 1 0 0 0 0 0 0 0 0 0 0 0 0] [0 1 0 0 1 0 0 0 0 0 0 0 0 0] [0 1 1 1 0 1 0 0 0 0 0 0 0 0] [0 1 1 0 0 0 0 0 0 0 0 0 0 0] [0 1 1 0 1 1 0 0 0 0 0 0 0 0] [0 0 1 0 1 0 1 0 0 0 0 0 0 0]
ListSigma=list(W.basis()) for j in range(dim(V)): ListSigma[j]=Glue(V.zero_vector(), Selmer_to_V(V, LSelmerGroup, sigma(V_to_Selmer(V, LSelmerGroup, V.basis()[j]))), V, W) ListSigma[j+dim(V)]=Glue(Selmer_to_V(V, LSelmerGroup, sigma(V_to_Selmer(V, LSelmerGroup, V.basis()[j]))), Selmer_to_V(V, LSelmerGroup, sigma(V_to_Selmer(V, LSelmerGroup, V.basis()[j]))), V, W) MatrixSigma=Matrix(ListSigma); print MatrixSigma.str()
[0 0 0 0 0 0 0 1 1 1 1 1 0 0] [0 0 0 0 0 0 0 0 1 0 0 0 0 0] [0 0 0 0 0 0 0 0 1 0 1 0 0 0] [0 0 0 0 0 0 0 0 1 1 1 0 0 0] [0 0 0 0 0 0 0 0 1 1 1 1 1 0] [0 0 0 0 0 0 0 0 1 1 0 1 0 0] [0 0 0 0 0 0 0 0 1 1 0 1 1 1] [1 1 1 1 1 0 0 1 1 1 1 1 0 0] [0 1 0 0 0 0 0 0 1 0 0 0 0 0] [0 1 0 1 0 0 0 0 1 0 1 0 0 0] [0 1 1 1 0 0 0 0 1 1 1 0 0 0] [0 1 1 1 1 1 0 0 1 1 1 1 1 0] [0 1 1 0 1 0 0 0 1 1 0 1 0 0] [0 1 1 0 1 1 1 0 1 1 0 1 1 1]

Our problem is reduced to finding the common Eigenspace of these two matrices.

Id=Matrix(W.basis()) Eigens=(MatrixSigma-Id).left_kernel().intersection((MatrixTau-Id).left_kernel()); Eigens
Vector space of degree 14 and dimension 2 over Finite Field of size 2 Basis matrix: [0 0 0 1 1 0 0 0 0 0 1 0 1 0] [0 0 0 0 0 1 0 0 1 1 0 1 1 0]
SelmerEigens=[[V_to_Selmer(V, LSelmerGroup, Split(w, V, W)[0]), V_to_Selmer(V, LSelmerGroup, Split(w, V, W)[1])] for w in Eigens]; SelmerEigens
[[1, 1], [a^4 - 2*a^3 - 2*a^2 + 4*a - 1, a^5 - 4*a^4 + a^3 + 9*a^2 - 5*a - 1], [a^3 - 2*a^2 - 2*a + 2, 2*a^4 - 5*a^3 - a^2 + 4*a - 1], [-a^5 + 3*a^4 - 5*a^2 + 4*a - 1, -a^2 + a]]

We have bounded the Selmer group inside a group of size 4. Now finding it exactly is a matter of checking a modified local condition at primes above 2. We do this in a way that is surely sub-optimal: trying to divide a Mordell-Weil generator by two in various extension fields.

def MWDiv(EL, L, eig): RR.<tt>=L[] M.<b>=L.extension(tt^2-(eig[0])) SS.<uu>=M[] N.<c>=M.extension(uu^2-(eig[1])) EN=EL.change_ring(N) MWPoint=EN(0,0,1) return MWPoint.division_points(2)
MWDiv(EL, L, SelmerEigens[1])
[(((-1/2*a^5 + a^4 + 2*a^3 - 5/2*a^2 - 3*a)*b - 1/2*a^5 + a^4 + 2*a^3 - 5/2*a^2 - 3*a)*c + (-1/2*a^5 + 3/2*a^4 + a^3 - 4*a^2 - a + 3/2)*b : ((1/2*a^5 - a^4 - 2*a^3 + 2*a^2 + 7/2*a + 1)*b + 1/2*a)*c + (a^5 - 5/2*a^4 - 3*a^3 + 7*a^2 + 3*a - 5/2)*b + 1/2 : 1), (((1/2*a^5 - a^4 - 2*a^3 + 5/2*a^2 + 3*a)*b + 1/2*a^5 - a^4 - 2*a^3 + 5/2*a^2 + 3*a)*c + (-1/2*a^5 + 3/2*a^4 + a^3 - 4*a^2 - a + 3/2)*b : ((-1/2*a^5 + a^4 + 2*a^3 - 2*a^2 - 7/2*a - 1)*b - 1/2*a)*c + (a^5 - 5/2*a^4 - 3*a^3 + 7*a^2 + 3*a - 5/2)*b + 1/2 : 1), (((1/2*a^5 - a^4 - 2*a^3 + 5/2*a^2 + 3*a)*b - 1/2*a^5 + a^4 + 2*a^3 - 5/2*a^2 - 3*a)*c + (1/2*a^5 - 3/2*a^4 - a^3 + 4*a^2 + a - 3/2)*b : ((-1/2*a^5 + a^4 + 2*a^3 - 2*a^2 - 7/2*a - 1)*b + 1/2*a)*c + (-a^5 + 5/2*a^4 + 3*a^3 - 7*a^2 - 3*a + 5/2)*b + 1/2 : 1), (((-1/2*a^5 + a^4 + 2*a^3 - 5/2*a^2 - 3*a)*b + 1/2*a^5 - a^4 - 2*a^3 + 5/2*a^2 + 3*a)*c + (1/2*a^5 - 3/2*a^4 - a^3 + 4*a^2 + a - 3/2)*b : ((1/2*a^5 - a^4 - 2*a^3 + 2*a^2 + 7/2*a + 1)*b - 1/2*a)*c + (-a^5 + 5/2*a^4 + 3*a^3 - 7*a^2 - 3*a + 5/2)*b + 1/2 : 1)]
MWDiv(EL, L, SelmerEigens[2])
[]
MWDiv(EL, L, SelmerEigens[3])
[]

The first nonzero element in the list above is the true Selmer generator. The others fail. Hence the 2-Selmer group has rank 1, and so does E

Now let's try a modified Selmer group, using the Kolyvagin prime 17.

List=list(set(L.primes_above(2)).union(set(L.primes_above(17)))); List
[Fractional ideal (a^5 - 2*a^4 - 4*a^3 + 4*a^2 + 6*a), Fractional ideal (a^3 - 2*a^2 - 2*a + 3), Fractional ideal (2*a^3 - 2*a^2 - 5*a), Fractional ideal (-a^5 + 3*a^4 + 2*a^3 - 10*a^2 + a + 5)]
LSelmerGroup=L.selmer_group(List, 2); LSelmerGroup
[a^5 - 2*a^4 - 4*a^3 + 4*a^2 + 6*a, a^3 - 2*a^2 - 2*a + 3, 2*a^3 - 2*a^2 - 5*a, -a^5 + 3*a^4 + 2*a^3 - 10*a^2 + a + 5, -1, a^3 - 2*a^2 - a + 1, a^5 - 3*a^4 - a^3 + 7*a^2 - 2*a - 1, a, a^3 - 2*a^2 - 2*a + 2, a^4 - 3*a^3 - a^2 + 6*a - 1]
V=F2^(len(LSelmerGroup)); V
Vector space of dimension 10 over Finite Field of size 2
W=F2^(2*len(LSelmerGroup)); W
Vector space of dimension 20 over Finite Field of size 2
ListTau=list(W.basis()) for j in range(dim(V)): ListTau[j]=Glue(V.zero_vector(), Selmer_to_V(V, LSelmerGroup, tau(V_to_Selmer(V, LSelmerGroup, V.basis()[j]))), V, W) ListTau[j+dim(V)]=Glue(Selmer_to_V(V, LSelmerGroup, tau(V_to_Selmer(V, LSelmerGroup, V.basis()[j]))), V.zero_vector(), V, W) MatrixTau=Matrix(ListTau); print MatrixTau.str()
[0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 1 0 0 1 0] [0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 1 0 0 1 0] [0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 1 1 0] [0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1 1 1 0 0] [0 0 0 0 0 0 0 0 0 0 0 0 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 0] [0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 1 0] [0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0] [0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 1 0] [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 1] [1 0 0 0 1 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0] [0 1 0 0 1 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0] [0 0 0 1 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0] [0 0 1 0 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0] [0 0 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 0 0 0 0 0 0 0 0 0 0 0] [0 0 0 0 1 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0] [0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0] [0 0 0 0 1 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 1 0 1 0 1 0 0 0 0 0 0 0 0 0 0]
ListSigma=list(W.basis()) for j in range(dim(V)): ListSigma[j]=Glue(V.zero_vector(), Selmer_to_V(V, LSelmerGroup, sigma(V_to_Selmer(V, LSelmerGroup, V.basis()[j]))), V, W) ListSigma[j+dim(V)]=Glue(Selmer_to_V(V, LSelmerGroup, sigma(V_to_Selmer(V, LSelmerGroup, V.basis()[j]))), Selmer_to_V(V, LSelmerGroup, sigma(V_to_Selmer(V, LSelmerGroup, V.basis()[j]))), V, W) MatrixSigma=Matrix(ListSigma); print MatrixSigma.str()
[0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1 1 1 0 0] [0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 1 1 1 0 0] [0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 1 0 0 1 0] [0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0] [0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0] [0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0] [0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 0 0] [0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 1 1] [0 0 1 0 1 1 1 1 0 0 0 0 1 0 1 1 1 1 0 0] [0 1 0 0 1 1 1 1 0 0 0 1 0 0 1 1 1 1 0 0] [0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0] [1 0 0 0 1 1 0 0 1 0 1 0 0 0 1 1 0 0 1 0] [0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0] [0 0 0 0 1 0 1 0 0 0 0 0 0 0 1 0 1 0 0 0] [0 0 0 0 1 1 1 0 0 0 0 0 0 0 1 1 1 0 0 0] [0 0 0 0 1 1 1 1 1 0 0 0 0 0 1 1 1 1 1 0] [0 0 0 0 1 1 0 1 0 0 0 0 0 0 1 1 0 1 0 0] [0 0 0 0 1 1 0 1 1 1 0 0 0 0 1 1 0 1 1 1]
Id=Matrix(W.basis()) Eigens=(MatrixSigma-Id).left_kernel().intersection((MatrixTau-Id).left_kernel()); Eigens
Vector space of degree 20 and dimension 3 over Finite Field of size 2 Basis matrix: [1 0 1 0 0 0 0 0 0 0 1 0 0 1 1 1 1 1 0 0] [0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 1 0 1 0] [0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 1 0 1 1 0]
SelmerEigens=[[V_to_Selmer(V, LSelmerGroup, Split(w, V, W)[0]), V_to_Selmer(V, LSelmerGroup, Split(w, V, W)[1])] for w in Eigens]; SelmerEigens
[[1, 1], [-7*a^5 + 14*a^4 + 23*a^3 - 32*a^2 - 25*a + 5, -5*a^4 + 10*a^3 - a^2 - 4*a + 2], [a^4 - 2*a^3 - 2*a^2 + 4*a - 1, a^5 - 4*a^4 + a^3 + 9*a^2 - 5*a - 1], [-2*a^5 + 12*a^3 - 5*a^2 - 16*a + 4, -5*a^5 + 30*a^4 - 41*a^3 - 17*a^2 + 35*a - 8], [a^3 - 2*a^2 - 2*a + 2, 2*a^4 - 5*a^3 - a^2 + 4*a - 1], [5*a^5 - 10*a^4 - 14*a^3 + 18*a^2 + 13*a - 6, 5*a^5 - 19*a^4 + 2*a^3 + 43*a^2 - 16*a - 10], [-a^5 + 3*a^4 - 5*a^2 + 4*a - 1, -a^2 + a], [-a^5 + 6*a^3 + 6*a^2 - 8*a + 2, 2*a^4 - 4*a^3 - 3*a^2 + 5*a + 6]]

To narrow down this group of size 8, we must check the transverse condition at primes above 17. The function below will do this:

def local_conditions(A, p, u, a): F=A.residue_field(p) vp=a.valuation(p) b=F(a/u^vp) unramified=(vp%2==0) transverse=(b.nth_root(2, all=True)!=[]) return [unramified, transverse]
I=L.ideal(17); factor(I)
(Fractional ideal (-a^5 + 3*a^4 + 2*a^3 - 10*a^2 + a + 5)) * (Fractional ideal (2*a^3 - 2*a^2 - 5*a)) * (Fractional ideal (a^5 - 2*a^4 - 4*a^3 + 4*a^2 + 6*a))
for i in range(1, len(SelmerEigens)): SelmerEigens[i] for p in L.primes_above(17): local_conditions(L, p, 17, SelmerEigens[i][0])[1] local_conditions(L, p, 17, SelmerEigens[i][1])[1]
[-7*a^5 + 14*a^4 + 23*a^3 - 32*a^2 - 25*a + 5, -5*a^4 + 10*a^3 - a^2 - 4*a + 2] True True True True True True [a^4 - 2*a^3 - 2*a^2 + 4*a - 1, a^5 - 4*a^4 + a^3 + 9*a^2 - 5*a - 1] True False False True False False [-2*a^5 + 12*a^3 - 5*a^2 - 16*a + 4, -5*a^5 + 30*a^4 - 41*a^3 - 17*a^2 + 35*a - 8] True False False True False False [a^3 - 2*a^2 - 2*a + 2, 2*a^4 - 5*a^3 - a^2 + 4*a - 1] True True True True True True [5*a^5 - 10*a^4 - 14*a^3 + 18*a^2 + 13*a - 6, 5*a^5 - 19*a^4 + 2*a^3 + 43*a^2 - 16*a - 10] True True True True True True [-a^5 + 3*a^4 - 5*a^2 + 4*a - 1, -a^2 + a] True False False True False False [-a^5 + 6*a^3 + 6*a^2 - 8*a + 2, 2*a^4 - 4*a^3 - 3*a^2 + 5*a + 6] True False False True False False

Now the modified Selmer group is bounded in a group of size 4, and it suffices to check the local condition at 2.

MWDiv(EL, L, SelmerEigens[1])
[]
MWDiv(EL, L, SelmerEigens[4])
[]
MWDiv(EL, L, SelmerEigens[5])
[]

So this modified Selmer group turns out to be trivial.

One more example, with Kolyvagin prime 29:

List=list(set(L.primes_above(2)).union(set(L.primes_above(29)))); List
[Fractional ideal (a^5 - 2*a^4 - 6*a^3 + 10*a^2 + 9*a - 8), Fractional ideal (a^3 - 2*a^2 - 2*a + 3), Fractional ideal (2*a^5 - 4*a^4 - 7*a^3 + 9*a^2 + 6*a), Fractional ideal (-a^5 + 3*a^4 + 4*a^3 - 10*a^2 - 8*a + 4)]
LSelmerGroup=L.selmer_group(List, 2); LSelmerGroup
[a^5 - 2*a^4 - 6*a^3 + 10*a^2 + 9*a - 8, a^3 - 2*a^2 - 2*a + 3, 2*a^5 - 4*a^4 - 7*a^3 + 9*a^2 + 6*a, -a^5 + 3*a^4 + 4*a^3 - 10*a^2 - 8*a + 4, -1, a^3 - 2*a^2 - a + 1, a^5 - 3*a^4 - a^3 + 7*a^2 - 2*a - 1, a, a^3 - 2*a^2 - 2*a + 2, a^4 - 3*a^3 - a^2 + 6*a - 1]
V=F2^(len(LSelmerGroup)); V
Vector space of dimension 10 over Finite Field of size 2
W=F2^(2*len(LSelmerGroup)); W
Vector space of dimension 20 over Finite Field of size 2
ListTau=list(W.basis()) for j in range(dim(V)): ListTau[j]=Glue(V.zero_vector(), Selmer_to_V(V, LSelmerGroup, tau(V_to_Selmer(V, LSelmerGroup, V.basis()[j]))), V, W) ListTau[j+dim(V)]=Glue(Selmer_to_V(V, LSelmerGroup, tau(V_to_Selmer(V, LSelmerGroup, V.basis()[j]))), V.zero_vector(), V, W) MatrixTau=Matrix(ListTau); print MatrixTau.str()
[0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 1 1 1 0] [0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 1 0 0 1 0] [0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 1 1 0 0] [0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0 0 0 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 0] [0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 1 0] [0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0] [0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 1 0] [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 1] [0 0 1 0 1 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0] [0 1 0 0 1 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0] [1 0 0 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0] [0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0] [0 0 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 0 0 0 0 0 0 0 0 0 0 0] [0 0 0 0 1 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0] [0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0] [0 0 0 0 1 1 0 1 1 0 0 0 0 0 0 0 0 0 0 0] [0 0 0 0 0 1 0 1 0 1 0 0 0 0 0 0 0 0 0 0]
ListSigma=list(W.basis()) for j in range(dim(V)): ListSigma[j]=Glue(V.zero_vector(), Selmer_to_V(V, LSelmerGroup, sigma(V_to_Selmer(V, LSelmerGroup, V.basis()[j]))), V, W) ListSigma[j+dim(V)]=Glue(Selmer_to_V(V, LSelmerGroup, sigma(V_to_Selmer(V, LSelmerGroup, V.basis()[j]))), Selmer_to_V(V, LSelmerGroup, sigma(V_to_Selmer(V, LSelmerGroup, V.basis()[j]))), V, W) MatrixSigma=Matrix(ListSigma); print MatrixSigma.str()
[0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0 0 1 0 0 1 1 1 1 0 0] [0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 1 0] [0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 1 1 1 0] [0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0] [0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0 0 0] [0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 0 0 0] [0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 0] [0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 0 0] [0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 1 1] [0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0] [0 1 0 0 1 1 1 1 0 0 0 1 0 0 1 1 1 1 0 0] [1 0 0 0 0 1 0 0 1 0 1 0 0 0 0 1 0 0 1 0] [0 0 1 0 1 0 1 1 1 0 0 0 1 0 1 0 1 1 1 0] [0 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0] [0 0 0 0 1 0 1 0 0 0 0 0 0 0 1 0 1 0 0 0] [0 0 0 0 1 1 1 0 0 0 0 0 0 0 1 1 1 0 0 0] [0 0 0 0 1 1 1 1 1 0 0 0 0 0 1 1 1 1 1 0] [0 0 0 0 1 1 0 1 0 0 0 0 0 0 1 1 0 1 0 0] [0 0 0 0 1 1 0 1 1 1 0 0 0 0 1 1 0 1 1 1]
Id=Matrix(W.basis()) Eigens=(MatrixSigma-Id).left_kernel().intersection((MatrixTau-Id).left_kernel()); Eigens
Vector space of degree 20 and dimension 3 over Finite Field of size 2 Basis matrix: [0 0 1 1 1 0 0 0 0 0 1 0 0 1 1 1 1 1 0 0] [0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 1 0 1 0] [0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 1 0 1 1 0]
SelmerEigens=[[V_to_Selmer(V, LSelmerGroup, Split(w, V, W)[0]), V_to_Selmer(V, LSelmerGroup, Split(w, V, W)[1])] for w in Eigens]; SelmerEigens
[[1, 1], [13*a^5 - 23*a^4 - 53*a^3 + 58*a^2 + 59*a - 18, -11*a^4 + 22*a^3 + 21*a^2 - 32*a + 4], [a^4 - 2*a^3 - 2*a^2 + 4*a - 1, a^5 - 4*a^4 + a^3 + 9*a^2 - 5*a - 1], [2*a^5 - 15*a^4 + 14*a^3 + 39*a^2 - 24*a + 4, -11*a^5 + 20*a^4 + 25*a^3 - 15*a^2 - 15*a + 6], [a^3 - 2*a^2 - 2*a + 2, 2*a^4 - 5*a^3 - a^2 + 4*a - 1], [-12*a^5 + 19*a^4 + 40*a^3 - 29*a^2 - 21*a + 1, -13*a^5 + 53*a^4 - 16*a^3 - 121*a^2 + 78*a + 6], [-a^5 + 3*a^4 - 5*a^2 + 4*a - 1, -a^2 + a], [16*a^5 - 33*a^4 - 33*a^3 + 51*a^2 - 18*a + 3, 4*a^4 - 8*a^3 - 5*a^2 + 9*a - 12]]
for i in range(1, len(SelmerEigens)): i; SelmerEigens[i] for p in L.primes_above(29): local_conditions(L, p, 29, SelmerEigens[i][0])[1] local_conditions(L, p, 29, SelmerEigens[i][1])[1]
1 [13*a^5 - 23*a^4 - 53*a^3 + 58*a^2 + 59*a - 18, -11*a^4 + 22*a^3 + 21*a^2 - 32*a + 4] True True True True True True 2 [a^4 - 2*a^3 - 2*a^2 + 4*a - 1, a^5 - 4*a^4 + a^3 + 9*a^2 - 5*a - 1] True True True True True True 3 [2*a^5 - 15*a^4 + 14*a^3 + 39*a^2 - 24*a + 4, -11*a^5 + 20*a^4 + 25*a^3 - 15*a^2 - 15*a + 6] True True True True True True 4 [a^3 - 2*a^2 - 2*a + 2, 2*a^4 - 5*a^3 - a^2 + 4*a - 1] True False False True False False 5 [-12*a^5 + 19*a^4 + 40*a^3 - 29*a^2 - 21*a + 1, -13*a^5 + 53*a^4 - 16*a^3 - 121*a^2 + 78*a + 6] True False False True False False 6 [-a^5 + 3*a^4 - 5*a^2 + 4*a - 1, -a^2 + a] True False False True False False 7 [16*a^5 - 33*a^4 - 33*a^3 + 51*a^2 - 18*a + 3, 4*a^4 - 8*a^3 - 5*a^2 + 9*a - 12] True False False True False False
MWDiv(EL, L, SelmerEigens[1])
[]
MWDiv(EL, L, SelmerEigens[2])
[(((-1/2*a^5 + a^4 + 2*a^3 - 5/2*a^2 - 3*a)*b - 1/2*a^5 + a^4 + 2*a^3 - 5/2*a^2 - 3*a)*c + (-1/2*a^5 + 3/2*a^4 + a^3 - 4*a^2 - a + 3/2)*b : ((1/2*a^5 - a^4 - 2*a^3 + 2*a^2 + 7/2*a + 1)*b + 1/2*a)*c + (a^5 - 5/2*a^4 - 3*a^3 + 7*a^2 + 3*a - 5/2)*b + 1/2 : 1), (((1/2*a^5 - a^4 - 2*a^3 + 5/2*a^2 + 3*a)*b + 1/2*a^5 - a^4 - 2*a^3 + 5/2*a^2 + 3*a)*c + (-1/2*a^5 + 3/2*a^4 + a^3 - 4*a^2 - a + 3/2)*b : ((-1/2*a^5 + a^4 + 2*a^3 - 2*a^2 - 7/2*a - 1)*b - 1/2*a)*c + (a^5 - 5/2*a^4 - 3*a^3 + 7*a^2 + 3*a - 5/2)*b + 1/2 : 1), (((1/2*a^5 - a^4 - 2*a^3 + 5/2*a^2 + 3*a)*b - 1/2*a^5 + a^4 + 2*a^3 - 5/2*a^2 - 3*a)*c + (1/2*a^5 - 3/2*a^4 - a^3 + 4*a^2 + a - 3/2)*b : ((-1/2*a^5 + a^4 + 2*a^3 - 2*a^2 - 7/2*a - 1)*b + 1/2*a)*c + (-a^5 + 5/2*a^4 + 3*a^3 - 7*a^2 - 3*a + 5/2)*b + 1/2 : 1), (((-1/2*a^5 + a^4 + 2*a^3 - 5/2*a^2 - 3*a)*b + 1/2*a^5 - a^4 - 2*a^3 + 5/2*a^2 + 3*a)*c + (1/2*a^5 - 3/2*a^4 - a^3 + 4*a^2 + a - 3/2)*b : ((1/2*a^5 - a^4 - 2*a^3 + 2*a^2 + 7/2*a + 1)*b - 1/2*a)*c + (-a^5 + 5/2*a^4 + 3*a^3 - 7*a^2 - 3*a + 5/2)*b + 1/2 : 1)]
MWDiv(EL, L, SelmerEigens[3])
[]

This at least tips us off that this modified Selmer group is nontrivial. But the theory of Kolyvagin systems predicts that it should have rank 2, not 1. I think the problem is that the local condition at 2 is implemented incorrectly. There must be a better test than the one I wrote. That would be the first priority for improving this code...