Advanced Examples

These examples are intended to demonstrate basic programming in Magma using the functions of this chapter together with a few from Chapter SCHEMES. There is little or no explanation of the geometry behind the examples. We assume here that you are familiar with that and are really interested in the problem of realising it in Magma.

Contents

Trigonal Curves

We discuss a particular example covered by Petri's theorem. In fact, we write down a curve C of genus 8 which is trigonal. We discover this easily since its canonical embedding is not cut out by quadrics. It would be nice to have automatic functions to recognise the equations of the surface scroll cut out by the quadrics, but at the moment they don't exist so we have to make that calculation by hand.

Example Crv_trigonal-curve (H121E38)

First we make the curve and compute its canonical model.
> k := Rationals();
> P<X,Y,Z> := ProjectiveSpace(k,2);
> C := Curve(P,X^8 + X^4*Y^3*Z + Z^8);
> Genus(C);
8
> phi := CanonicalMap(C);
> P7<a,b,c,d,e,f,g,h> := Codomain(phi);
> CC := phi(C);
> CC;
a^3*e + d^4 + d^2*h^2
a^3*f + d^3*e + d*e*h^2
a^3*g + d^3*f + d*f*h^2
a^3*h + d^3*g + d*g*h^2
a^2*b + d^3 + d*h^2
a^2*c + d^2*e + e*h^2
a*b*c + d^2*f + f*h^2
a*c^2 + d^2*g + g*h^2
b*c^2 + d^2*h + h^3
-a*c + b^2  -a*e + b*d  -a*f + c*d  -a*f + b*e
-a*g + c*e  -d*f + e^2  -a*g + b*f  -a*h + c*f
-d*g + e*f  -d*h + f^2  -a*h + b*g  -b*h + c*g
-d*h + e*g  -e*h + f*g  -f*h + g^2
In this example, we can see all the quadrics which cut out the canonical model CC. But even if we could not, or if computing the full canonical ideal was too difficult, we can compute the conics in the canonical ideal separately using only linear algebra.
> SC := Image(phi,C,2);
> SC;
a*c - b^2  a*e - b*d  a*f - c*d  a*g - c*e
a*h - c*f  b*e - c*d  b*f - c*e  b*g - c*f
b*h - c*g  d*f - e^2  d*g - e*f  d*h - f^2
e*g - f^2  e*h - f*g  f*h - g^2
> Dimension(SC);
2
We would like to identify the scroll SC. Even better, we would like to find a map from a ruled surface to this scroll and pull the image curve CC back to this ruled surface. Then the fibres of the ruling will cut out the g13 on C giving its trigonal structure. We will also see the Maroni invariant of C directly. In this case one immediately recognises the equations of the scroll so can write down the ruled surface and choose the bidegree of linear system which gives the map to the scroll.
> F<r,s,u,v> := RuledSurface(k,2,4);
> psi := map< F -> P7 |
>	[r^2*u, r*s*u, s^2*u, r^4*v, r^3*s*v, r^2*s^2*v, r*s^3*v, s^4*v] >;
> SF := psi(F);
> DefiningIdeal(SF) eq DefiningIdeal(SC);
true
To realise the curve's trigonal structure, we need to create a divisor by intersecting it with a fibre of the ruling. The natural way would be to pull the curve back to F via psi and work there. However, Magma currently cannot create divisors that lie on curves on scrolls.

Luckily, we can work with the image CC in P7 and obtain the divisor D of the image of a fibre under psi intersected with CC for our g13. This is then used to define a 3 - 1 map to the projective line.

> fib := psi(Scheme(F,r));
> Dimension(fib);
1
> D := Divisor(CC,fib);
> Degree(D);
3
> #Basis(D);
2
So D really does give us a g13. To get the map to P1, we can pull it back to C, but it is faster to compose the divisor map on CC with phi. Proceeding this way, it is then a good idea to use the function field of C to simplify the map description.
> phiD := DivisorMap(D);
> mpD := Expand(Restriction(phi,C,CC)*phiD);
> FC := FunctionField(C);
> rat := FC!(p1/p2) where p1,p2 := Explode(DefiningPolynomials(mpD));
> P1 := Curve(Codomain(mpD));  // get P1 as a curve
> mpD := map<C->P1|[rat,1]>; mpD;
Mapping from: CrvPln: C to Crv: P1
with equations :
X
Z

Algebraic Geometric Codes

Magma includes functions for working with codes which arise from algebraic geometry. Discussion of these functions is left to the chapter on error-correcting linear codes, Chapter LINEAR CODES OVER FINITE FIELDS. As is well known, these codes are often created using Riemann--Roch spaces of divisors on curves. Here we demonstrate the creation of such a code taken from the book of van Lint and van der Geer [vLvdG88]. This is a famous example which arises many times in that book, as Example II (3.12) for instance.

Example Crv_klein-quartic-code (H121E39)

This code is based on the Klein quartic over the finite field F8 of 8 elements, a curve that we define immediately. Notice that we start by defining a curve C over the field of 2 elements. This is so that we can investigate C over small fields while still being able to work over F8 later.
> F2 := FiniteField(2);
> F4<t4> := FiniteField(4);
> F8<t8> := FiniteField(8);
> P<x,y,z> := ProjectiveSpace(F2,2);
> C := Curve(P,x^3*y + y^3*z + z^3*x);
> C8<a,b,c> := BaseChange(C,F8);
> C8;
Curve over GF(2^3) defined by
a^3*b + a*c^3 + b^3*c
The code will have length 24, corresponding to the 24 rational points of C.
> #RationalPoints(C8);
24
In constructing such codes, one must have a collection of points, in this case the 24 rational points we have just found, and a divisor whose support is disjoint from these points. As the divisor, we take some multiple of a conjugate pair of points defined over the finite field of 4 elements. In Magma, it is convenient to use the function field machinery to describe this as a place of degree 2. It is constructed as the intersection of C with one of its bitangents.
> L := Curve(P,x+y+z);
> IntersectionPoints(C,L);
{@ @}
> C4 := BaseChange(C,FiniteField(4));
> P4 := Ambient(C4);
> L4 := BaseChange(L,P4);
> IntersectionPoints(C4,L4);
{@ (t4 : t4^2 : 1), (t4^2 : t4 : 1) @}
> [ IntersectionNumber(C4,L4,p) : p in $1 ];
[ 2, 2 ]
So we see that L is indeed a bitangent of C and that the two points of intersection are defined properly over the finite field of 4 elements. In order to be able to compute the Riemann-Roch space of a divisor, we compute this intersection as a place on C8. Notice how the support of the divisor D is not used in its display until it has been explicitly computed.
> FF8 := FunctionField(C8);
> D := Divisor(C8, FF8!(a/c + b/c + 1));
> D;
Divisor on Curve over GF(2^3) defined by
a^3*b + a*c^3 + b^3*c
> Decomposition(D);
[
    <Place at (0 : 1 : 0), -3>,
    <Place at (1 : 0 : 0), -1>,
    <Place at ($.1 + 1 : $.1 : 1), 2>
]
> D;
Divisor -3*Place at (0 : 1 : 0) + 2*Place at ($.1 + 1 : $.1 : 1) -
1*Place at (1 : 0 : 0)
This divisor contains the place we require with multiplicity 2 and some negative contributions at infinity. We extract the degree 2 place we need.
> p := Support(D)[2];
> Degree(p);
2
Now we can make the code. Rather than using the rational points of C8, the code creation intrinsic takes a sequence of degree 1 places. But they are also easily retrieved. The divisor we use will be 3p.
> G := 3*p;
> S := Places(C8,1);
> #S;
24
> AGC := AlgebraicGeometricCode(S,G);
> Dimension(AGC);
4
In fact, it is the dual code that is really wanted, but this is easy.
> Dual(AGC);
[24, 20] Linear Code over GF(2^3)
Generator matrix:
[1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 t8^5 t8 t8^5 t8^3]
[0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 t8^5 t8^2 t8^6 t8^5]
[0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 t8^3 t8^6 t8^5]
[0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 t8^6 t8^3 t8^4]
[0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 t8^2 t8^3 t8 t8^2]
[0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 t8^6 t8^6 t8^2 t8^6]
[0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 t8^2 t8^4 t8^4 t8^6]
[0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 t8^6 t8^3 t8^3 t8^2]
[0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 t8^4 0 t8^4]
[0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 t8^4 t8^3 t8^6 1]
[0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 t8 t8^2 t8^2 t8^3]
[0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 t8^6 t8^6 0 1]
[0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 t8^2 t8^4 t8^3 0]
[0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 t8^6 t8 t8^2 t8]
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 t8^5 t8 t8^6]
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 t8 1 1 t8^3]
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 t8^3 1 t8^5 t8^2]
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 t8^2 t8^2 1 0]
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 t8^3 t8 t8^5 t8^5]
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 t8^4 t8^3 t8 t8^4]
V2.28, 13 July 2023