
function DotProd(a,b)
   return &+[a[i]*b[i] : i in [1..#a]];
end function;

function ModularSymbolsMod2(E)
   assert Type(E) eq CrvEll;

   N := Conductor(E);

   repeat 
      p := NextPrime(1000+Random(2000));
      "Trying p = ", p;
      Mminus := ModularSymbols(E,GF(p),-1 : stop := 29);
      if Dimension(Mminus) eq 1 then
         Mplus := ModularSymbols(E,GF(p),+1 : stop := 29);
      end if;
   until Dimension(Mminus) eq 1 and Dimension(Mplus) eq 1;     

   M := ModularSymbols(N,2);
   Am := AmbientSpace(Mminus);
   Ap := AmbientSpace(Mplus);
   Bm := [Am!<1,ModularSymbol(M.i)[1][2]> : i in [1..Dimension(M)]];
   Bp := [Ap!<1,ModularSymbol(M.i)[1][2]> : i in [1..Dimension(M)]];
   vm := Eltseq(Basis(DualVectorSpace(Mminus))[1]);
   vp := Eltseq(Basis(DualVectorSpace(Mplus))[1]);
   V := VectorSpace(GF(p),Dimension(M));
   Im := V![DotProd(vm,Eltseq(Bm[i])) : i in [1..#Bm]];
   Ip := V![DotProd(vp,Eltseq(Bp[i])) : i in [1..#Bp]];

   okm, ratm := RationalReconstruction(Im);
   okp, ratp := RationalReconstruction(Ip);

   if not (okm and okp) then
      error "Failed to rationally reconstruct, with p=",p;
   end if;

   ratm *:= LCM([Denominator(x) : x in Eltseq(ratm)]);
   ratp *:= LCM([Denominator(x) : x in Eltseq(ratp)]);

   ratm /:= GCD([Numerator(x) : x in Eltseq(ratm)]);
   ratp /:= GCD([Numerator(x) : x in Eltseq(ratp)]);

   W := DualVectorSpace(M);
   modm := W![GF(2)!(Integers()!x) : x in Eltseq(ratm)];
   modp := W![GF(2)!(Integers()!x) : x in Eltseq(ratp)];

   Answer := ModularSymbolsDual(M, sub<W|[modm, modp]>);

   return Answer;
end function;
