When working with a particular congruence subgroup it is often useful to be able to produce a picture of a fundamental domain of the group. Also when considering images of geodesics in Hh * it can be useful to draw the images. The following graphics functions provide a useful tool for this purpose.
Colours: SeqEnum Default: [1,1,0]
Outline: BoolElt Default: true
Fill: BoolElt Default: true
Show: BoolElt Default: false
Labels: SeqEnum Default: {[0,1]}
Fontsize: RngIntElt Default: 2
Size: SeqEnum Default: [ ]
Pixels: RngIntElt Default: 300
Overwrite: BoolElt Default: false
Radius: FldReElt Default: 0.5
PenColours: SeEnum Default: [0,0,0]
Given a sequence of polygons, each of which is defined by a sequence of points in the upper half plane, produce the postscript drawing of these polygons, and write the result to the named file. The function returns a sequence of 4 real numbers, [x0,x1,h,S], where (x0,0) are the coordinates of the lower left corner, (x1,h) are the coordinates of the upper right corner, and the scale is such that there are S pixels per unit. These values are either given by the user, or computed automatically.
- Colours : Either a sequence of 3 numbers, or a sequence of such sequences, one for each polygon in the sequence of polygons given. A colour is represented by 3 real numbers between 0 and 1, giving the red, green and blue components of the colour. This colour is used for the filling of the polygon.
- PenColours : A sequence of 3 numbers, or a sequence of such sequences, one for each polygon in the sequence of polygons given. A colour is represented by 3 real numbers between 0 and 1, giving the red, green and blue components of the colour. This colour is used for drawing the outline of the polygon.
- Labels : A sequence of elements of type SetCspElt, FldRatElt or RngIntElt, which will be labeled on the real axis in the diagram.
- Fontsize : The size of the font used in labeling the diagram.
- Pixels : When using Autoscale, the scale is computed so that the width of the resulting diagram is given by Pixels in pixels, plus a 20 pixel border. The minimal possible value for Pixels is 10, and if any smaller value is given it will be set to 10.
- Size : If Size is not the empty sequence, the values in the sequence Size are used to determine the size of the image. When Size is given by [x0,x1,y,S], the picture is draw with coordinates (x0,0) in the lower left corner, (x1,h) in the upper right corner, and the scale is such that there are S pixels per unit. If Size is not given, then an appropriate size for the image is computed automatically.
- Overwrite : If Overwrite is set to true, then if the name of the file given names a file which already exists, it will be overwritten. Otherwise the user will be asked whether they want to overwrite the file or not.
- Show : If Show is set to true a System command is issued to make a window pop up showing the file just created. The system command is System("gv file &"). In future other options may be possible. If Show is false then
- Fill : A boolean or sequence of booleans, determining whether the polygon is drawn filled in with a colour, the colour coming from the sequence Colours. If both Fill and Outline are set to false outline is reset to true.
- Outline : A boolean or sequence of booleans, determining whether the polygon is drawn with an outline. If both Fill and Outline are set to false outline is reset to true.
- Radius : A real number giving the radius of points marked on the diagram. A point will be marked for any polygon given by a single point.
Colour: SeqEnum Default: [1,1,0]
Show: BoolElt Default: false
Fontsize: RngIntElt Default: 2
Labelsize: RngIntElt Default: 3
Autoscale: BoolElt Default: true
Size: SeqEnum Default: []
Pixels: RngIntElt Default: 300
Overwrite: BoolElt Default: false
ShowInternalEdges: BoolElt Default: false
- Display: a fundamental domain corresponding to the Farey Symbol FS, or a group G, for which the Farey symbol will be computed, with edge identifications and cusps labeled. This function returns a sequence of 4 real numbers, [x0,x1,h,S], where (x0,0) are the coordinates of the lower left corner, (x1,h) are the coordinates of the upper right corner, and the scale is such that there are S pixels per unit. These values are either given by the user, or computed automatically. A polygon can be a sequence of any number of points of type HypSpcElt or SetCspElt. When at least 3 points are given a polygon is drawn. For two points, a geodesic between them is drawn. For one point a small circle is drawn to mark the point.
- Colour: This colour is used in colouring the domain drawn. A colour is represented by a sequence of 3 real numbers between 0 and 1, giving the red, green and blue components of the colour.
- Fontsize : The size of the font used in labeling the cusps on the diagram.
- Labelsize : The size of the font used in labeling the identification labels on the diagram.
- Autoscale : If true, the scale is computed and the file is created so that all the polygons listed can be seen in the diagram, if this is feasible. if Autoscale is set to false, then the variable Size must be given.
- Pixels : When using Autoscale, the scale is computed so that the width of the resulting diagram is given by Pixels in pixels, plus a 20 pixel border. The minimal possible value for Pixels is 10, and if any smaller value is given it will be set to 10.
- Size : When Autoscale is false, the values in the sequence Size are used to determine the size of the image. When Size is given by [x0,x1,y,S], the picture is draw with coordinates (x0,0) in the lower left corner, (x1,h) in the upper right corner, and the scale is such that there are S pixels per unit.
- Overwrite : If Overwrite is set to true, then if the name of the file given names a file which already exists, it will be overwritten. Otherwise the user will be asked whether they want to overwrite the file or not.
- Show : If Show is set to true a System command is issued to make a window pop up showing the file just created. The system command is System("gv file &"). In future other options may be possible. If Show is false then
- ShowInternalEdges : If this is set to true then internal edges are drawn dividing the domain into fundamental domains for Γ0(2).
> G := Gamma0(24); > FS := FareySymbol(G); > C := Cusps(FS); > Domain := FundamentalDomain(G); > red := [1,0,0]; > DisplayPolygons(Domain,"/tmp/Gamma0N12.ps": > Colours := red, Labels := C, Show := true, Fontsize := 1); [ 0.E-28, 1.000000000000000000000000000, 1.500000000000000000000000000, 300 ]
The user could write a procedure as follows for drawing the fundamental domain as a union of fundamental domains for PSL2(Z).
> procedure draw_fundamental_domain(Group,file) > cosets := CosetRepresentatives(Group); > H<i,r> := UpperHalfPlaneWithCusps(); > tri := [H|Infinity(),0,r]; > red := [1,0,0]; > yellow := [1,1,0]; > cyan := [0,1,1]; > cols := &cat[[red,yellow,cyan] : i in [1..(Ceiling(#cosets/3))]]; > trans := [g*tri : g in cosets]; > Outlines := [false : g in cosets]; > DisplayPolygons(trans,file: > Colours := cols, Outline := Outlines, Show := true); > end procedure; > > // use the procedure to draw a domain for Gamma_0(19): > draw_fundamental_domain(Gamma0(19),"/tmp/gamma019.ps"); [ 0.E-28, 1.000000000000000000000000000, 1.500000000000000000000000000, 300 ]
In the following example, we use the cosets of Γ0(11) to draw a fundamental domain for Γ0(11), divided up into fundamental domains for the group of automorphisms of Hh * generated by PSL2(Z) together with the map z |-> - /line(z).
> G := Gamma0(11); > H<i,rho> := UpperHalfPlaneWithCusps(); > tri := [H|Infinity(),i,rho]; > tri1 := [H|0,i,rho]; > C11 := CosetRepresentatives(G); > Colours := [[0.6,0.2,0.9] : i in [1..#C11]] cat [[1,1,0] : i in [1..#C11]]; > triangles := [g*tri : g in C11] cat [g*tri1 : g in C11]; > DisplayPolygons(triangles,"/tmp/Gamma_0_11.ps": > Colours := Colours, Show := false); [ 0.E-57, 1.000000000000000000000000000, 1.500000000000000000000000000, 300 ]
Continuing from the above example, we can take any other polygon we wish, and look at it's translates under the action of the cosets of Γ0(11).
> tri2 := [H|Infinity(),2*i + 1,i,rho]; > DisplayPolygons([g*tri2 : g in C11],"/tmp/pic.ps": > Colours := Colours, Show := true); [ 0.E-57, 1.000000000000000000000000000, 2.500000000000000000000000000, 300 ]
In the next example we define three different triangles. Each of these is a fundamental domain for Γ0(2), though Magma currently does not verify this. For each choice we use a set of generators of Γ0(2) to draw a partial tiling of the upper half plane with equivalent fundamental domains.
> G := CongruenceSubgroup(4,2); > H<i,r> := UpperHalfPlaneWithCusps(); > generators := Generators(G); > M := generators cat [g^(-1) : g in generators] cat [G!1]; > tri1 := [H|Infinity(),r-1,0,r,r+1]; > tri2 := [H|Infinity(),i-1,0,i+1]; > tri3 := FundamentalDomain(G); > X := [1..#M]; > L := [G!m : m in Set([Matrix(M[i]*M[j]*M[k]) : i in X, j in X, k in X])]; > DisplayPolygons([g*tri1 : g in L],"/tmp/picture1.ps": Show := true); [ -4.000000000000000000000000000, 3.500000000000000000000000000, 1.500000000000000000000000000, 200 ] > DisplayPolygons([g*tri2 : g in L],"/tmp/picture2.ps": Show := true); [ -4.000000000000000000000000000, 3.000000000000000000000000000, 1.500000000000000000000000000, 200 ] > DisplayPolygons([g*tri3 : g in L],"/tmp/picture3.ps": Show := true); [ -4.000000000000000000000000000, 3.000000000000000000000000000, 1.500000000000000000000000000, 200 ]
Edges and Polygons with different numbers of sides can be included in the same picture, as in the following example.
> H<i,r> := UpperHalfPlaneWithCusps(); > cosets := CosetRepresentatives(Gamma0(19)); > polygons := [g*tri : g in cosets, tri in [[H|i,r],[H|i,2*r,3*r-1]]]; > outlines := [true : i in cosets] cat [false : i in cosets]; > cyan := [0,1,1]; > DisplayPolygons(polygons,"/tmp/pic.ps": > Colours := cyan, Outline := outlines, Labels := [], Show := false); [ 0.E-57, 1.000000000000000000000000000, 3.098076211353315940291169512, 300 ]
In the following example a function is defined to determine the colouring of the polygons in terms of which Farey sequence pairs of end points of the polygons belong to.
> frac := func<a | a[1]/a[2]>; > > function FareyValue(m) > mat := Matrix(m); > Denominators := [mat[2,1],mat[2,2],mat[2,1]+mat[2,2]]; > values := [Abs(v) : v in Denominators]; > return &+ContinuedFraction(frac(Sort(values))); > end function; > > procedure drawDomain(cosets) > H<i,r> := UpperHalfPlaneWithCusps(); > tri := [H|Infinity(),0,r]; > cols := [[0.5,0.2*FareyValue(c),1-0.2*FareyValue(c)] : c in cosets]; > trans := [g*tri : g in cosets]; > DisplayPolygons(trans,"/tmp/pic.ps": > Outline := false, Colours := cols, Show := true); > end procedure; > > // Now we can use the above functions and procedure, for example > // take the cosets as follows: > C := CosetRepresentatives(Gamma0(41)); > // Then draw the picture: > drawDomain(C); [ 0.E-28, 1.000000000000000000000000000, 1.500000000000000000000000000, 300 ]
> G := CongruenceSubgroup(5); > FS := FareySymbol(G); > FS; [ 2, 2, 7, 8, 8, 10, 9, 3, 3, 9, 4, 1, 1, 4, 5, 5, 10, 11, 11, 7, 6, 6 ] [ oo, 0, 1/5, 2/9, 1/4, 3/11, 5/18, 2/7, 1/3, 3/8, 5/13, 2/5, 1/2, 3/5, 5/8, 2/3, 5/7, 8/11, 3/4, 7/9, 4/5, 1, oo ] > // The following command graphically displays the information contained in FS: > DisplayFareySymbolDomain(FS,"/tmp/Gamma5b.ps": Show := false); [ 0, 1.0000, 0.50000, 800 ] > // This picture represents a modular curve with genus 0: > Genus(G); 0
The example in question is Γ0(37). A simple question is to find what is the fundamental domain, and to give a list of inequivalent elliptic points of the group, and display this information graphically. First we create the group and find the information we are interested in:
> G := Gamma0(37); > // To draw a picture of the fundamental domain we need to define > // the upper half plane. > H<i,r> := UpperHalfPlaneWithCusps(); > D := FundamentalDomain(G,H); > E := EllipticPoints(G,H);
We can now take a look at the picture:
> // We need to make sure the polygons we want to display all > // have the same type, so we have t create the following object: > HH:=Parent(D); > // now we make a list of polygons and points: > P1:=[HH|D] cat [HH|[e] : e in E]; > // we take a look at the default picture of the situation: > DisplayPolygons(P1,"/tmp/pic.ps": Show := true); [ 0.E-28, 1.0000, 1.5000, 300 ]
The points have been displayed in yellow, the default colour, but we'd prefer a different colour. Also the picture is not quite the right size. It has been shown with the real axis shown from 0 to 1, which is reasonable, but we'd prefer less height, and the scale 300 could be changed, as in this example:
> // use different colours: > yellow := [1,1,0]; > red := [1,0,0]; > green := [0,1,0]; > cyan := [0,1,1]; > black := [0,0,0]; > Colours := [yellow] cat [red : e in E]; > // use a different size and scale: > Size := [0,1,0.2,400]; > // view the result: > DisplayPolygons(P1,"/tmp/pic.ps": > Show := true, Colours := Colours, Size := Size); [ 0, 1, 0.1999999999999999999999999999, 400 ]After more experimenting we reach the following:
> // We use a slightly different list of polygons, to show more > // structure. > tri := [H|Infinity(),0,H.2]; > cosets := CosetRepresentatives(G); > P := [HH|g*tri : g in cosets] cat [HH|[e] : e in E] cat [HH|D]; > // Choosing some colours: > LotsOfColours := &cat[[yellow,green,cyan] : c in cosets]; > Colours := [LotsOfColours[i] : i in [1..#cosets]] > cat [black] > cat [red : e in E]; > // choose which polygons are filled, and which have outlines: > outlines := [false : i in cosets] cat [false : i in E] cat [true]; > fill := [true : i in cosets] cat [true : i in E] cat [false]; > labels := Cusps(FareySymbol(G)); > // Create a file of the result: > DisplayPolygons(P,"/tmp/pic.ps": > Colours := Colours, Show := false, Size := [0,1,1,200], > Labels := labels, Outline := outlines, Fill := fill, > Fontsize := 1, Radius := 0.3); [ 0, 1, 1, 200 ]
If we are satisfied with the resulting picture then we can include the resulting picture in a latex file as in the following example, where we use the Latex graphicx package to include the diagram.
\documentclass{article} \usepackage[dvips]{graphicx} \begin{document} Here is a picture of a fundamental domain for $Γ_0(37)$: $${\includegraphics{/tmp/pic.ps}}$$ In the picture we have marked $4$ inequivalent elliptic points. \end{document}
Note that currently, given a list of points to draw, the postscript file will include all of the points, even if they are not in the area of the bounding box, which can produce bad results some times. This should be changed in a future version. Sometimes using the Fundamental domain function can produce results in a more reliable way, as in the following example, which produces a similar picture to the above, and a latex file can be written in the same way.
> G := Gamma0(37); > H<i,r> := UpperHalfPlaneWithCusps(); > D := FundamentalDomain(G,H); > HH:=Parent(D); > E := EllipticPoints(G,H); > P:=[HH|D] cat [HH|[e] : e in E]; > labels := Cusps(FareySymbol(G)); > yellow := [1,1,0]; > red := [1,0,0]; > Colours := [yellow] cat [red : e in E]; > DisplayPolygons(P,"/tmp/pic.ps": > Colours := Colours, Show := false, Size := [0,1,0.2,200], > Labels := labels, > Fontsize := 1, Radius := 0.3); [ 0, 1, 0.1999999999999999999999999999, 200 ]