Fundamental Domains

Fundamental Domain drawer


Click on the image to go to a page with the java program, and same text as below

Click here to go to a page with a Java 1.1.1 applet for drawing fundamental domains for congruence subgroups acting on the upper-half plane. Since it may take a minute or so to load the java program, you may like to open it in a separate window, and read the text below while you wait for it to load.

This program lives on two web pages:

WARNING: this program is currently very slow for large index, so proceed carefully for N larger than 20 or so (depending on your computer). Sometimes updating the screen does not work properly, and I don't yet know why. If you change group type, and it redraws the new fundamental domain without wiping out the old one, try clicking the "0" button to get the picture to redraw properly.

NOTE: This page is not yet finished, and the program is still under development. I have only really tested this program with one browser on one computer, so I would be intersted to know how it works on other computers. Any comments are very much appreciated. Email me at [email protected]

Page contents

  • Features
  • Screen shots
  • Background definitions of Congruence subgroups
  • About the Algorithm used
  • Bugs
  • To do
  • Source code
  • C program
  • Features and Instructions

    General controls:

    You can change scale, colour, position of the origin, using the orange coloured buttons. Press "0" to put the origin in the center. (max scale currently fixed to 20000000, but doesn't work so well at this scale in some cases.) Scale is in pixels per unit.

    Expand Rectangle: You can click on the screen and drag the mouse to form a rectangle. If you click on 'expand rectangle' the scale changes so the height of the rectangle becomes the height of the screen. The center of the rectangle moves the the center of the screen (in vertical direction only).

    Fundamental Domain drawing part:

    Will draw domains for Gamma^0(N), Gamma^1(N), Gamma_0(N), Gamma_1(N), Gamma(N).

    Changing N - you can type in N, or you can press the ">" and "<" buttons to increase N in steps.

    Edit Mode: In this mode the triangles can be moved to give a different fundamental domain for the same group, by clicking on the yellow circles on the boundary.

    Links: These show how the boundary is linked up

    find matrix: You can find what matrix a triangle corresponds to by clicking on it; the colour changes, and the matrix will be printed in the left lower corner. Click again to change colour back.

    Triangle Drawing part:

    Here you can draw a triangle corresponding to transforming a standard domain by a given matrix. Currently only matrices of determinant 1 are allowed, for convenience at points in computation, but I will probably change this later. You can enter the matrix, or use the buttons TM, RM, etc to transform the matrix M. Matrices are T=[1,1;0,1], T'=[1,-1;0,1], S=[0,-1;1,0], R = [0,-1;1,1].

    move/copyIf move is selected, when the matrix is applied (eg, T, R, etc) the triangle is moved by this matrix. If copy is selected, a copy is made, which is a translate by the applied matrix.

    Move to: this moves the origin so that the triangle just drawn is in the middle of the screen

    Scale to: If you click on this, in addition to moving, it also scales, so the triangle just drawn is in the middle of the screen, _and_ at a reasonable size so you can see it.

    Screen Shots

  • Here is a screen shot showing Gamma^0(6), with 'links' and 'edit mode' turned on, and after a little moving around of triangles using edit function.
  • Here is a screen shot of Gamma^1(10).
  • Here is a screen shot of Gamma_0(60), after a little expansion of scale (using 'expand rectangle').
  • Here is a screen shot of Gamma_0(60), after expansion to show more detail, and also with a triangle highlighted, and giving the corresponding matrix.
  • Here is a screen shot of a detail from Gamma_1(21).
  • Congruence Subgroups

    The group of 2 by 2 matrices with determinant 1, SL2(Z) acts on the upper half complex plane:

    [a,b;c,d]z -> (az+b)/(cz+d)

    The triangles drawn by this program are Fundamental domains for SL2(Z). These triangles are used to construct the Fundamental domains for other subgroups of SL2(Z). The subgroups for which the fundamental domain is computed currently are the following:

    Gamma_0(N), Gamma_1(N), Gamma(N), Gamma^1(N) and Gamma^0(N),
    where N is a positive integer. These subgroups consist of matrices in SL2(Z) of the following forms respectively:

    [a,b;Nc,d], , [Na+1,Nb;Nc,Nd+1], [Na+1,Nb;Nc+1,d] and [a,Nb;c,d].
    Here a,b,c,d are integers.


    Pretty simple so far! Main points - I wanted to make the domain so the triangles are all 'as big' as possible - so you can see them; I also wanted to use computations of Gamma0(N) in finding Gamma1(N), to cut down on time taken. These two aims conflict somewhat, and also programming to try and take care of both at once got a little complicated, and easy to introduce errors, so unfortunately at the moment the computation of Gamma0(N) is not used in finding Gamma1(N). This is definitely slower than when I used Gamma0(N) to find Gamma1(N), but appears to be bug free. At some stage I'll speed up the program by carefully rewriting this part to build Gamma1(N) from Gamma0(N). As the domain is constructed a record is kept of how everything fits together. This is used to find the cusps and their widths, just by explicitly looking. The elliptic points are found in the same way (this information currently computed but not displayed), and this is used to calculate the genus from the formula in Shimura's book. I'm thinking about completely revising the program and implement a different and better algorithm. (E.g., compute all cusps and widths first, and use that to construct the domain.)

    Since a few people asked, I've now written a longer description of how the algorithm works. This is avaliable in ps and dvi format: ps file, ps.gz file, dvi and images in tar.gz file.


  • problems with large integers, e.g., with large scale funny things happen.
  • Don't try it for N too large! Gets slow for large index. Depends on your computer how this works. try for small N first. Be careful with index greater than 100, it might crash for too large index!
  • There are various places where I've imposed arbitrary limits on things like number of cusps, since I specified size of array they are stored in. Probably should change to variable length.
  • Still has various drawing problems, e.g., when dots are removed stuff is left behind, etc.
  • Sometimes if you move the page or browser window around strange things happen. It doesn't update well enough. Sometimes controls stop working. It forgets there is a rectangle on the screen if you move the side bar of netscape browser, etc.
  • There are bugs in 'link' and 'edit' mode I need to fix.
  • To save time, I only compute the outline of each triangle once, but this means that if you change the size of the applet while it is running things are in the wrong place, since it assumes there will be no screen size change.
  • To Do

  • Fix bugs!
  • Add an option to put more marks on the axis, especially where cusps are.
  • Put screen shots on this page
  • Need to get people to check this applet on different computers.
  • Possibly would be better in a smaller size?
  • Improve the appearance of the linking lines.
  • Add postscript out put option (original program was a C program producing postscript output.)
  • Want to work out how to make it faster and download faster
  • Add a demo of getting a triangle to the identity triangle
  • make it only compute the triangles that will appear on the screen.
  • Add a graph drawing mode to create corresponding graph.
  • Add possibility to compute fundamental domains for more groups.
  • Implement different methods of drawing the domains, such as Kulkarni's method.
  • add option to split triangles into two parts
  • Source Code

    The source code is still rather messy, but I have decided to put it up anyway. You can find a directory of the code here. The code here is for a slightly different version than the program above. In particular it gives intersections of two groups of the type described above.

    If you want to look at the code, please download the following 8 java class files, plus the README file, and a copy of the GNU GPL:

    Controls for input (Main)
    For drawing
    Computation of the
    coset representatives:
    README (Instructions/Notes)
    fundomain.tar.gz (everything)

    I have also included the compiled classes of this program, in the directory here. The program seems to work faster when compiled under java 1.1 than java 1.2, though both will work.

    C program with postscript output

    Before writing the java program, I wrote a c program, which produces output in postscript. The c program only draws diagrams for Gamma_0(N), Gamma_1(N), Gamma^0(N) and Gamma^1(N). It runs at the command line, and produces output more quickly than the java program, but there is less flexibility. You can get the c source code at the following link. The instructions in the top of the file describe how to compile and run the program on unix type machines:

    Fundamental domain drawer C program