Graphical Output#
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 \({\mathbb{H}}^*\) it can be useful to draw the images. The following graphics functions provide a useful tool for this purpose.
- DisplayPolygons(P, file): SeqEnum, MonStgElt#
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 areSpixels per unit. These values are either given by the user, or computed automatically.ColoursEither 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.
PenColoursA 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.
LabelsA sequence of elements of type
SetCspElt,FldRatEltorRngIntElt, which will be labeled on the real axis in the diagram.FontsizeThe size of the font used in labeling the diagram.
PixelsWhen using Autoscale, the scale is computed so that the width of the resulting diagram is given by
Pixelsin pixels, plus a \(20\) pixel border. The minimal possible value forPixelsis \(10\), and if any smaller value is given it will be set to \(10\).SizeIf
Sizeis not the empty sequence, the values in the sequenceSizeare used to determine the size of the image. WhenSizeis 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 areSpixels per unit. IfSizeis not given, then an appropriate size for the image is computed automatically.OverwriteIf
Overwriteis set totrue, 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.ShowIf
Showis set totruea System command is issued to make a window pop up showing the file just created. The system command isSystem("gv file &"). In future other options may be possible. IfShowisfalsethenFillA boolean or sequence of booleans, determining whether the polygon is drawn filled in with a colour, the colour coming from the sequence
Colours. If bothFillandOutlineare set tofalseoutline is reset totrue.OutlineA boolean or sequence of booleans, determining whether the polygon is drawn with an outline. If both
FillandOutlineare set tofalseoutline is reset totrue.RadiusA real number giving the radius of points marked on the diagram. A point will be marked for any polygon given by a single point.
- DisplayFareySymbolDomain(FS, file): SymFry, MonStgElt -> SeqEnum#
- DisplayFareySymbolDomain(G, file): GrpPSL2, MonStgElt -> SeqEnum#
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
Displaya 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 areSpixels 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 typeHypSpcEltorSetCspElt. 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.ColourThis 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.
FontsizeThe size of the font used in labeling the cusps on the diagram.
LabelsizeThe size of the font used in labeling the identification labels on the diagram.
AutoscaleIf
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. ifAutoscaleis set tofalse, then the variableSizemust be given.PixelsWhen using
Autoscale, the scale is computed so that the width of the resulting diagram is given byPixelsin pixels, plus a \(20\) pixel border. The minimal possible value forPixelsis \(10\), and if any smaller value is given it will be set to \(10\).SizeWhen
Autoscaleisfalse, the values in the sequenceSizeare used to determine the size of the image. WhenSizeis 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 areSpixels per unit.OverwriteIf
Overwriteis set totrue, 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.ShowIf
Showis set totruea System command is issued to make a window pop up showing the file just created. The system command isSystem("gv file &"). In future other options may be possible. IfShowisfalsethenShowInternalEdgesIf this is set to
truethen internal edges are drawn dividing the domain into fundamental domains for \(\Gamma_0(2)\).
- Example: Graphics (ex-73f434)#
In the first example we draw a fundamental domain for \(\Gamma_0(12)\).
> 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 \({\operatorname{PSL}}_2({\mathbb{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 \(\Gamma_0(11)\) to draw a fundamental domain for \(\Gamma_0(11)\), divided up into fundamental domains for the group of automorphisms of \({\mathbb{H}}^*\) generated by \({\operatorname{PSL}}_2({\mathbb{Z}})\) together with the map \(z\mapsto -\overline{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 \(\Gamma_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 \(\Gamma^0(2)\), though Magma currently does not verify this. For each choice we use a set of generators of \(\Gamma^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 ]
- Example: More Graphics (ex-a1acee)#
Functions are provided for drawing pictures coming from Farey symbols and fundamental domains. These functions provide short cuts for producing some of the pictures in the previous examples, but are not so flexible.
> 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
- Example: Graphics (ex-da7abd)#
In the following example we show how to create a postscript file and include the resulting file in a latex file.
The example in question is \(\Gamma_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
graphicxpackage to include the diagram.\\documentclass{article} \\usepackage[dvips]{graphicx} \\begin{document} Here is a picture of a fundamental domain for $\\Gamma_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 ]