# Two-generator subgroups of SL(2,R)

The algorithms explained in
- "The constructive membership problem for discrete free subgroups of SL(2,R)"
- "The constructive membership problem for discrete two-generator subgroups of SL(2,R)"

have been implemented in Magma and can be downloaded here.
### How to use this file with Magma:

The above package has to be loaded into your Magma workspace using:
```
> Attach("sl2r.m");
```

### Constructing a two-generator subgoup

Suppose A, B are matrices over K. To generate the group G:= <A, B> as a subgroup of (P)SL(2,R) one uses the commands *TwoGeneratorSubgroupSL2R* and *TwoGeneratorSubgroupPSL2R*.
Besides the matrices A and B they also expect an embedding of K into R as a third parameter. If K is the field of rationals, one has to use Infinity() as embedding.
```
> A:= Matrix(2, [ 2, 0, 2, 1/2 ]);
> B:= Matrix(2, [ 5, 2, -3, -1 ]);
> G:= TwoGeneratorSubgroupSL2R(A, B, Infinity()); G;
Two generator subgroup of SL(2,R) generated by
[ 2 0]
[ 2 1/2],
[ 5 2]
[-3 -1]
```

### Predicates of two-generator subgoups

The generators of G can be accessed as G.1 and G.2. The following functions
- IsDiscrete
- IsDiscreteAndFree
- IsDiscreteAndFreeProduct
- IsDiscreteAndElementary
- IsTriangleGroup
- IsFinite

can be used to decide if G is discrete, etc.
In the example above,
```
> IsDiscreteAndFree(G);
true
```

So the group G is discrete and free.
### Constructive membership for two-generator subgoups

Whenever the group G is discrete, the membership problem can be decided using the *Membership* intrinsic.
In the example above,
```
> Membership(G, A^10 * B^3 * A);
true $.1^10 * $.2^3 * $.1
> Membership(G, -A);
false
```

The first return value indicates whether the element is in G. If this is the case, then the second return value is a word in a free group of rank 2 that expresses the element in the generators of G.
Note that if G was created as a subgroup of PSL(2,R) then the second membership test above would yield true:
```
> H:= TwoGeneratorSubgroupPSL2R(A, B, Infinity());
> Membership(H, -A);
true $.1
```

As explained in the papers mentioned in the beginning, the algorithm usually computes a witness pair for G.
The chosen witness pair can be obtained using the *WitnessPair* intrinsic.
### Another example

We construct a (2,3,7)-triangle group:
```
> K:= NumberField( Polynomial([-1, 0, -2, 0, 1, 0, 1]) );
> eta:= K.1^2;
> X:= Matrix(K, 2, [0, -K.1, K.1^5 + K.1^3 - 2*K.1, 0 ]);
> Y:= Matrix(K, 2, [1/2, 1/2*(-K.1^5 - K.1^4 - K.1^3 + K.1 + 1), 1/2*(-K.1^5 + K.1^4 + 3*K.1 - 2) , 1/2] );
> plc:= InfinitePlaces(K)[1];
> G:= TwoGeneratorSubgroupSL2R(X, Y, plc);
> IsTriangleGroup(G);
true <2, 3, 7>
```