R := FunctionField(Rationals(),2); // R is the field of rational functions in c and t. // Here c will be such that the function field of X_{9C^{0}-9a} is Q(c). // The function field of X_{0}(2) is Q(t), and j = t^3/(t+16). This is // the model of X_{0}(2) from the Rouse, Zureick-Brown paper. b := c^3; j1 := (b+3)^3*(b+27)/b; j2 := t^3/(t+16); num := Numerator(j1-j2); // This numerator is the equation of the fiber product curve. C := ProjectiveClosure(Curve(AffineSpace(Rationals(),2),num)); // Sometimes a fiber product has multiple components. IsAbsolutelyIrreducible(C); // Not in this case. Genus(C); // It has genus 2! chk, H, mp := IsHyperelliptic(C); // Every genus 2 curve/Q is either hyperelliptic, or has a degree 2 map // to a pointless conic. The return value chk is true or false. // If chk is true, H is a hyperelliptic model, and mp is the map from C to H. // The map from C to H is only a birational map, there are points on C // where the map isn't defined. // The model H is y^2 + (x^3+1)y = -9x^3, which is the minimal hyperelliptic // model. We want a model of the form y^2 = sextic. H2, mp2 := SimplifiedModel(H); // Now that we have a simplified model, we can ask Magma to do some // stuff with it. J := Jacobian(H2); TorsionSubgroup(J); RankBounds(J); // The torsion subgroup of J(Q) is Z/3Z x Z/9Z. The Jacobian has a rank // of 0. So J(Q) is finite. // Magma can find H2(Q) in this case. (It can also find it in the // case when J(Q) has rank 1.) ratpoints := Chabauty0(J); ratpoints; // There are exactly six rational points on H2. // We want to know that the image on the j-line of all of these points are. // This is actually kind of tricky to figure out, because we have // a map j : C -> P^1, and maps C -> H, H -> H2. The map from H to H2 // Magma can easily invert. The map from C -> H is birational map, but it's // pretty complicated, and Magma will struggle some to compute a birational // inverse to this map. // First, let's map the rational points back to H. mp2inv := Inverse(mp2); ratp := { mp2inv(p) : p in ratpoints }; // Now, for each of the 6 rational points p on H, Magma can write down // the equations for the preimage scheme mp^(-1)(p) as a subscheme of C. // Then it can find the rational points on all such schemes. This gives us // all rational points on C. ptsonC := {}; for p in ratp do X := p@@mp; rat := RationalPoints(X); for q in rat do Include(~ptsonC,C!Eltseq(q)); end for; end for; // Programming note: When Magma computes the rational points on X, // it returns them as points on X. In order to put stuff into a set, // all the things in the set must be of the same type. Because we're working // with 6 different choices of X in the for loop, we have to tell Magma to // take each point we find, and think of it as a point on C. The // command Eltseq(q) returns the projective coordinates of q, and the // command C!Eltseq(q) means ``make the point on C that has these projective // coordinates.'' ptsonC; // The hyperelliptic curve had 6 rational points. However, we only get 5 // rational points on C. What happened? pointlist := [ p : p in ptsonC ]; pointlist; [ IsSingular(p) : p in pointlist ]; // The point [0,1,0] is a singular point of C, and on a non-singular model, // there are multiple points sitting over it. How can we handle this? FF := FunctionField(C); jfunc := FF.2^3/(FF.2+16); plac := Places(C![0,1,0]); plac; // We'll use Magma's function field machinery. This is the map from C2 -> P^1 // represented as an element of the function field of C. The set plac // is all the places (which can be thought of as points on the non-singular // model). Degree(plac[1]); Degree(plac[2]); // Both places have degree 1. So they are rational points on the non-singular // model. What is their image under j? Evaluate(jfunc,plac[1]); Evaluate(jfunc,plac[2]); // Both are cusps. What are the values of j at the other 4 points on the curve? Evaluate(jfunc,pointlist[1]); Evaluate(jfunc,pointlist[3]); Evaluate(jfunc,pointlist[4]); Evaluate(jfunc,pointlist[5]); // So in summary there are 6 rational points on C. Four of them are cusps, // one of them corresponds to j = 0, and one corresponds to j = 54000. // Is 54000 a CM j-invariant? E := EllipticCurveWithjInvariant(54000); HasComplexMultiplication(E); // Yes. It is.