Hecke triangle groups

AUTHORS:

  • Jonas Jermann (2013): initial version

class sage.modular.modform_hecketriangle.hecke_triangle_groups.HeckeTriangleGroup(n)[source]

Bases: FinitelyGeneratedMatrixGroup_generic, UniqueRepresentation

Hecke triangle group \((2, n, \infty)\).

Element[source]

alias of HeckeTriangleGroupElement

I()[source]

Return the identity element/matrix for self.

EXAMPLES:

sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
sage: HeckeTriangleGroup(10).I()
[1 0]
[0 1]

sage: HeckeTriangleGroup(10).I().parent()
Hecke triangle group for n = 10
>>> from sage.all import *
>>> from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
>>> HeckeTriangleGroup(Integer(10)).I()
[1 0]
[0 1]

>>> HeckeTriangleGroup(Integer(10)).I().parent()
Hecke triangle group for n = 10
S()[source]

Return the generator of self corresponding to the conformal circle inversion.

EXAMPLES:

sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
sage: HeckeTriangleGroup(3).S()
[ 0 -1]
[ 1  0]
sage: HeckeTriangleGroup(10).S()
[ 0 -1]
[ 1  0]
sage: HeckeTriangleGroup(10).S()^2 == -HeckeTriangleGroup(10).I()
True
sage: HeckeTriangleGroup(10).S()^4 == HeckeTriangleGroup(10).I()
True

sage: HeckeTriangleGroup(10).S().parent()
Hecke triangle group for n = 10
>>> from sage.all import *
>>> from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
>>> HeckeTriangleGroup(Integer(3)).S()
[ 0 -1]
[ 1  0]
>>> HeckeTriangleGroup(Integer(10)).S()
[ 0 -1]
[ 1  0]
>>> HeckeTriangleGroup(Integer(10)).S()**Integer(2) == -HeckeTriangleGroup(Integer(10)).I()
True
>>> HeckeTriangleGroup(Integer(10)).S()**Integer(4) == HeckeTriangleGroup(Integer(10)).I()
True

>>> HeckeTriangleGroup(Integer(10)).S().parent()
Hecke triangle group for n = 10
T(m=1)[source]

Return the element in self corresponding to the translation by m*self.lam().

INPUT:

  • m – integer (default: 1); namely the second generator of self

EXAMPLES:

sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
sage: HeckeTriangleGroup(3).T()
[1 1]
[0 1]
sage: HeckeTriangleGroup(10).T(-4)
[     1 -4*lam]
[     0      1]
sage: HeckeTriangleGroup(10).T().parent()
Hecke triangle group for n = 10
>>> from sage.all import *
>>> from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
>>> HeckeTriangleGroup(Integer(3)).T()
[1 1]
[0 1]
>>> HeckeTriangleGroup(Integer(10)).T(-Integer(4))
[     1 -4*lam]
[     0      1]
>>> HeckeTriangleGroup(Integer(10)).T().parent()
Hecke triangle group for n = 10
U()[source]

Return an alternative generator of self instead of T. U stabilizes rho and has order 2*self.n().

If n=infinity then U is parabolic and has infinite order, it then fixes the cusp [-1].

EXAMPLES:

sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
sage: HeckeTriangleGroup(3).U()
[ 1 -1]
[ 1  0]
sage: HeckeTriangleGroup(3).U()^3 == -HeckeTriangleGroup(3).I()
True
sage: HeckeTriangleGroup(3).U()^6 == HeckeTriangleGroup(3).I()
True
sage: HeckeTriangleGroup(10).U()
[lam  -1]
[  1   0]
sage: HeckeTriangleGroup(10).U()^10 == -HeckeTriangleGroup(10).I()
True
sage: HeckeTriangleGroup(10).U()^20 == HeckeTriangleGroup(10).I()
True

sage: HeckeTriangleGroup(10).U().parent()
Hecke triangle group for n = 10
>>> from sage.all import *
>>> from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
>>> HeckeTriangleGroup(Integer(3)).U()
[ 1 -1]
[ 1  0]
>>> HeckeTriangleGroup(Integer(3)).U()**Integer(3) == -HeckeTriangleGroup(Integer(3)).I()
True
>>> HeckeTriangleGroup(Integer(3)).U()**Integer(6) == HeckeTriangleGroup(Integer(3)).I()
True
>>> HeckeTriangleGroup(Integer(10)).U()
[lam  -1]
[  1   0]
>>> HeckeTriangleGroup(Integer(10)).U()**Integer(10) == -HeckeTriangleGroup(Integer(10)).I()
True
>>> HeckeTriangleGroup(Integer(10)).U()**Integer(20) == HeckeTriangleGroup(Integer(10)).I()
True

>>> HeckeTriangleGroup(Integer(10)).U().parent()
Hecke triangle group for n = 10
V(j)[source]

Return the j’th generator for the usual representatives of conjugacy classes of self. It is given by V=U^(j-1)*T.

INPUT:

  • j –integer; to get the usual representatives j should range from 1 to self.n()-1

OUTPUT: the corresponding matrix/element

The matrix is parabolic if j is congruent to \(\pm 1\) modulo self.n(). It is elliptic if j is congruent to 0 modulo self.n(). It is hyperbolic otherwise.

EXAMPLES:

sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
sage: G = HeckeTriangleGroup(3)
sage: G.V(0) == -G.S()
True
sage: G.V(1) == G.T()
True
sage: G.V(2)
[1 0]
[1 1]
sage: G.V(3) == G.S()
True

sage: G = HeckeTriangleGroup(5)
sage: G.element_repr_method("default")
sage: G.V(1)
[  1 lam]
[  0   1]
sage: G.V(2)
[lam lam]
[  1 lam]
sage: G.V(3)
[lam   1]
[lam lam]
sage: G.V(4)
[  1   0]
[lam   1]
sage: G.V(5) == G.S()
True
>>> from sage.all import *
>>> from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
>>> G = HeckeTriangleGroup(Integer(3))
>>> G.V(Integer(0)) == -G.S()
True
>>> G.V(Integer(1)) == G.T()
True
>>> G.V(Integer(2))
[1 0]
[1 1]
>>> G.V(Integer(3)) == G.S()
True

>>> G = HeckeTriangleGroup(Integer(5))
>>> G.element_repr_method("default")
>>> G.V(Integer(1))
[  1 lam]
[  0   1]
>>> G.V(Integer(2))
[lam lam]
[  1 lam]
>>> G.V(Integer(3))
[lam   1]
[lam lam]
>>> G.V(Integer(4))
[  1   0]
[lam   1]
>>> G.V(Integer(5)) == G.S()
True
alpha()[source]

Return the parameter alpha of self.

This is the first parameter of the hypergeometric series used in the calculation of the Hauptmodul of self.

EXAMPLES:

sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
sage: HeckeTriangleGroup(3).alpha()
1/12
sage: HeckeTriangleGroup(4).alpha()
1/8
sage: HeckeTriangleGroup(5).alpha()
3/20
sage: HeckeTriangleGroup(6).alpha()
1/6
sage: HeckeTriangleGroup(10).alpha()
1/5
sage: HeckeTriangleGroup(infinity).alpha()
1/4
>>> from sage.all import *
>>> from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
>>> HeckeTriangleGroup(Integer(3)).alpha()
1/12
>>> HeckeTriangleGroup(Integer(4)).alpha()
1/8
>>> HeckeTriangleGroup(Integer(5)).alpha()
3/20
>>> HeckeTriangleGroup(Integer(6)).alpha()
1/6
>>> HeckeTriangleGroup(Integer(10)).alpha()
1/5
>>> HeckeTriangleGroup(infinity).alpha()
1/4
base_field()[source]

Return the base field of self.

EXAMPLES:

sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
sage: HeckeTriangleGroup(n=infinity).base_field()
Rational Field
sage: HeckeTriangleGroup(n=7).base_field()
Number Field in lam with defining polynomial x^3 - x^2 - 2*x + 1 with lam = 1.801937735804839?
>>> from sage.all import *
>>> from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
>>> HeckeTriangleGroup(n=infinity).base_field()
Rational Field
>>> HeckeTriangleGroup(n=Integer(7)).base_field()
Number Field in lam with defining polynomial x^3 - x^2 - 2*x + 1 with lam = 1.801937735804839?
base_ring()[source]

Return the base ring of self.

EXAMPLES:

sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
sage: HeckeTriangleGroup(n=infinity).base_ring()
Integer Ring
sage: HeckeTriangleGroup(n=7).base_ring()
Maximal Order generated by lam in Number Field in lam with defining polynomial x^3 - x^2 - 2*x + 1 with lam = 1.801937735804839?
>>> from sage.all import *
>>> from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
>>> HeckeTriangleGroup(n=infinity).base_ring()
Integer Ring
>>> HeckeTriangleGroup(n=Integer(7)).base_ring()
Maximal Order generated by lam in Number Field in lam with defining polynomial x^3 - x^2 - 2*x + 1 with lam = 1.801937735804839?
beta()[source]

Return the parameter beta of self.

This is the second parameter of the hypergeometric series used in the calculation of the Hauptmodul of self.

EXAMPLES:

sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
sage: HeckeTriangleGroup(3).beta()
5/12
sage: HeckeTriangleGroup(4).beta()
3/8
sage: HeckeTriangleGroup(5).beta()
7/20
sage: HeckeTriangleGroup(6).beta()
1/3
sage: HeckeTriangleGroup(10).beta()
3/10
sage: HeckeTriangleGroup(infinity).beta()
1/4
>>> from sage.all import *
>>> from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
>>> HeckeTriangleGroup(Integer(3)).beta()
5/12
>>> HeckeTriangleGroup(Integer(4)).beta()
3/8
>>> HeckeTriangleGroup(Integer(5)).beta()
7/20
>>> HeckeTriangleGroup(Integer(6)).beta()
1/3
>>> HeckeTriangleGroup(Integer(10)).beta()
3/10
>>> HeckeTriangleGroup(infinity).beta()
1/4
class_number(D, primitive=True)[source]

Return the class number of self for the discriminant D.

This is the number of conjugacy classes of (primitive) elements of discriminant D.

Note: Due to the 1-1 correspondence with hyperbolic fixed points resp. hyperbolic binary quadratic forms this also gives the class number in those cases.

INPUT:

  • D – an element of the base ring corresponding to a valid discriminant

  • primitive – if True (default) then only primitive elements are considered

EXAMPLES:

sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
sage: G = HeckeTriangleGroup(n=4)

sage: G.class_number(4)
1
sage: G.class_number(4, primitive=False)
1
sage: G.class_number(14)
2
sage: G.class_number(32)
2
sage: G.class_number(32, primitive=False)
3
sage: G.class_number(68)
4
>>> from sage.all import *
>>> from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
>>> G = HeckeTriangleGroup(n=Integer(4))

>>> G.class_number(Integer(4))
1
>>> G.class_number(Integer(4), primitive=False)
1
>>> G.class_number(Integer(14))
2
>>> G.class_number(Integer(32))
2
>>> G.class_number(Integer(32), primitive=False)
3
>>> G.class_number(Integer(68))
4
class_representatives(D, primitive=True)[source]

Return a representative for each conjugacy class for the discriminant D (ignoring the sign).

If primitive=True only one representative for each fixed point is returned (ignoring sign).

INPUT:

  • D – an element of the base ring corresponding to a valid discriminant

  • primitive – if True (default) then only primitive representatives are considered

EXAMPLES:

sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
sage: G = HeckeTriangleGroup(n=4)
sage: G.element_repr_method("conj")

sage: R = G.class_representatives(4)
sage: R
[[V(2)]]
sage: [v.continued_fraction()[1] for v in R]
[(2,)]

sage: R = G.class_representatives(0)
sage: R
[[V(3)]]
sage: [v.continued_fraction()[1] for v in R]
[(1, 2)]

sage: R = G.class_representatives(-4)
sage: R
[[S]]
sage: R = G.class_representatives(-4, primitive=False)
sage: R
[[S], [U^2]]

sage: R = G.class_representatives(G.lam()^2 - 4)
sage: R
[[U]]
sage: R = G.class_representatives(G.lam()^2 - 4, primitive=False)
sage: R
[[U], [U^(-1)]]

sage: R = G.class_representatives(14)
sage: sorted(R)
[[V(2)*V(3)], [V(1)*V(2)]]
sage: sorted(v.continued_fraction()[1] for v in R)
[(1, 2, 2), (3,)]

sage: R = G.class_representatives(32)
sage: sorted(R)
[[V(3)^2*V(1)], [V(1)^2*V(3)]]
sage: [v.continued_fraction()[1] for v in sorted(R)]
[(1, 2, 1, 3), (1, 4)]

sage: R = G.class_representatives(32, primitive=False)
sage: sorted(R)
[[V(3)^2*V(1)], [V(1)^2*V(3)], [V(2)^2]]

sage: G.element_repr_method("default")
>>> from sage.all import *
>>> from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
>>> G = HeckeTriangleGroup(n=Integer(4))
>>> G.element_repr_method("conj")

>>> R = G.class_representatives(Integer(4))
>>> R
[[V(2)]]
>>> [v.continued_fraction()[Integer(1)] for v in R]
[(2,)]

>>> R = G.class_representatives(Integer(0))
>>> R
[[V(3)]]
>>> [v.continued_fraction()[Integer(1)] for v in R]
[(1, 2)]

>>> R = G.class_representatives(-Integer(4))
>>> R
[[S]]
>>> R = G.class_representatives(-Integer(4), primitive=False)
>>> R
[[S], [U^2]]

>>> R = G.class_representatives(G.lam()**Integer(2) - Integer(4))
>>> R
[[U]]
>>> R = G.class_representatives(G.lam()**Integer(2) - Integer(4), primitive=False)
>>> R
[[U], [U^(-1)]]

>>> R = G.class_representatives(Integer(14))
>>> sorted(R)
[[V(2)*V(3)], [V(1)*V(2)]]
>>> sorted(v.continued_fraction()[Integer(1)] for v in R)
[(1, 2, 2), (3,)]

>>> R = G.class_representatives(Integer(32))
>>> sorted(R)
[[V(3)^2*V(1)], [V(1)^2*V(3)]]
>>> [v.continued_fraction()[Integer(1)] for v in sorted(R)]
[(1, 2, 1, 3), (1, 4)]

>>> R = G.class_representatives(Integer(32), primitive=False)
>>> sorted(R)
[[V(3)^2*V(1)], [V(1)^2*V(3)], [V(2)^2]]

>>> G.element_repr_method("default")
dvalue()[source]

Return a symbolic expression (or an exact value in case n=3, 4, 6) for the transfinite diameter (or capacity) of self.

This is the first nontrivial Fourier coefficient of the Hauptmodul for the Hecke triangle group in case it is normalized to J_inv(i)=1.

EXAMPLES:

sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
sage: HeckeTriangleGroup(3).dvalue()
1/1728
sage: HeckeTriangleGroup(4).dvalue()
1/256
sage: HeckeTriangleGroup(5).dvalue()
e^(2*euler_gamma - 4*pi/(sqrt(5) + 1) + psi(17/20) + psi(13/20))
sage: HeckeTriangleGroup(6).dvalue()
1/108
sage: HeckeTriangleGroup(10).dvalue()
e^(2*euler_gamma - 4*pi/sqrt(2*sqrt(5) + 10) + psi(4/5) + psi(7/10))
sage: HeckeTriangleGroup(infinity).dvalue()
1/64
>>> from sage.all import *
>>> from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
>>> HeckeTriangleGroup(Integer(3)).dvalue()
1/1728
>>> HeckeTriangleGroup(Integer(4)).dvalue()
1/256
>>> HeckeTriangleGroup(Integer(5)).dvalue()
e^(2*euler_gamma - 4*pi/(sqrt(5) + 1) + psi(17/20) + psi(13/20))
>>> HeckeTriangleGroup(Integer(6)).dvalue()
1/108
>>> HeckeTriangleGroup(Integer(10)).dvalue()
e^(2*euler_gamma - 4*pi/sqrt(2*sqrt(5) + 10) + psi(4/5) + psi(7/10))
>>> HeckeTriangleGroup(infinity).dvalue()
1/64
element_repr_method(method=None)[source]

Either return or set the representation method for elements of self.

INPUT:

  • method – if method=None (default) the current default representation method is returned. Otherwise the default method is set to method. If method is not available a ValueError is raised. Possible methods are:

    • default: use the usual representation method for matrix group elements

    • basic: the representation is given as a word in S and powers of T

    • conj: the conjugacy representative of the element is represented as a word in powers of the basic blocks, together with an unspecified conjugation matrix

    • block: same as conj but the conjugation matrix is specified as well

EXAMPLES:

sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
sage: G = HeckeTriangleGroup(5)
sage: G.element_repr_method()
'default'
sage: G.element_repr_method("basic")
sage: G.element_repr_method()
'basic'
>>> from sage.all import *
>>> from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
>>> G = HeckeTriangleGroup(Integer(5))
>>> G.element_repr_method()
'default'
>>> G.element_repr_method("basic")
>>> G.element_repr_method()
'basic'
get_FD(z)[source]

Return a tuple (A,w) which determines how to map z to the usual (strict) fundamental domain of self.

INPUT:

  • z – a complex number or an element of AlgebraicField()

OUTPUT:

A tuple (A, w).

  • A – a matrix in self such that A.acton(w)==z (if z is exact at least)

  • w – a complex number or an element of AlgebraicField() (depending on the type z) which lies inside the (strict) fundamental domain of self (self.in_FD(w)==True) and which is equivalent to z (by the above property)

EXAMPLES:

sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
sage: G = HeckeTriangleGroup(8)
sage: z = AlgebraicField()(1+i/2)
sage: (A, w) = G.get_FD(z)
sage: A
[-lam    1]
[  -1    0]
sage: A.acton(w) == z
True

sage: from sage.modular.modform_hecketriangle.space import ModularForms
sage: z = (134.12 + 0.22*i).n()
sage: (A, w) = G.get_FD(z)
sage: A
[-73*lam^3 + 74*lam       73*lam^2 - 1]
[        -lam^2 + 1                lam]
sage: w
0.769070776942... + 0.779859114103...*I
sage: z
134.120000000... + 0.220000000000...*I
sage: A.acton(w)
134.1200000... + 0.2200000000...*I
>>> from sage.all import *
>>> from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
>>> G = HeckeTriangleGroup(Integer(8))
>>> z = AlgebraicField()(Integer(1)+i/Integer(2))
>>> (A, w) = G.get_FD(z)
>>> A
[-lam    1]
[  -1    0]
>>> A.acton(w) == z
True

>>> from sage.modular.modform_hecketriangle.space import ModularForms
>>> z = (RealNumber('134.12') + RealNumber('0.22')*i).n()
>>> (A, w) = G.get_FD(z)
>>> A
[-73*lam^3 + 74*lam       73*lam^2 - 1]
[        -lam^2 + 1                lam]
>>> w
0.769070776942... + 0.779859114103...*I
>>> z
134.120000000... + 0.220000000000...*I
>>> A.acton(w)
134.1200000... + 0.2200000000...*I
in_FD(z)[source]

Return True if z lies in the (strict) fundamental domain of self.

EXAMPLES:

sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
sage: HeckeTriangleGroup(5).in_FD(CC(1.5/2 + 0.9*i))
True
sage: HeckeTriangleGroup(4).in_FD(CC(1.5/2 + 0.9*i))
False
>>> from sage.all import *
>>> from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
>>> HeckeTriangleGroup(Integer(5)).in_FD(CC(RealNumber('1.5')/Integer(2) + RealNumber('0.9')*i))
True
>>> HeckeTriangleGroup(Integer(4)).in_FD(CC(RealNumber('1.5')/Integer(2) + RealNumber('0.9')*i))
False
is_arithmetic()[source]

Return True if self is an arithmetic subgroup.

EXAMPLES:

sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
sage: HeckeTriangleGroup(3).is_arithmetic()
True
sage: HeckeTriangleGroup(4).is_arithmetic()
True
sage: HeckeTriangleGroup(5).is_arithmetic()
False
sage: HeckeTriangleGroup(6).is_arithmetic()
True
sage: HeckeTriangleGroup(10).is_arithmetic()
False
sage: HeckeTriangleGroup(infinity).is_arithmetic()
True
>>> from sage.all import *
>>> from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
>>> HeckeTriangleGroup(Integer(3)).is_arithmetic()
True
>>> HeckeTriangleGroup(Integer(4)).is_arithmetic()
True
>>> HeckeTriangleGroup(Integer(5)).is_arithmetic()
False
>>> HeckeTriangleGroup(Integer(6)).is_arithmetic()
True
>>> HeckeTriangleGroup(Integer(10)).is_arithmetic()
False
>>> HeckeTriangleGroup(infinity).is_arithmetic()
True
is_discriminant(D, primitive=True)[source]

Return whether D is a discriminant of an element of self.

Note: Checking that something isn’t a discriminant takes much longer than checking for valid discriminants.

INPUT:

  • D – an element of the base ring

  • primitive – if True (default) then only primitive elements are considered

OUTPUT:

True if D is a primitive discriminant (a discriminant of a primitive element) and False otherwise. If primitive=False then also non-primitive elements are considered.

EXAMPLES:

sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
sage: G = HeckeTriangleGroup(n=4)

sage: G.is_discriminant(68)
True
sage: G.is_discriminant(196, primitive=False)    # long time
True
sage: G.is_discriminant(2)
False
>>> from sage.all import *
>>> from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
>>> G = HeckeTriangleGroup(n=Integer(4))

>>> G.is_discriminant(Integer(68))
True
>>> G.is_discriminant(Integer(196), primitive=False)    # long time
True
>>> G.is_discriminant(Integer(2))
False
lam()[source]

Return the parameter lambda of self, where lambda is twice the real part of rho, lying between 1 (when n=3) and 2 (when n=infinity).

EXAMPLES:

sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
sage: HeckeTriangleGroup(3).lam()
1
sage: HeckeTriangleGroup(4).lam()
lam
sage: HeckeTriangleGroup(4).lam()^2
2
sage: HeckeTriangleGroup(6).lam()^2
3
sage: AA(HeckeTriangleGroup(10).lam())
1.9021130325903...?
sage: HeckeTriangleGroup(infinity).lam()
2
>>> from sage.all import *
>>> from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
>>> HeckeTriangleGroup(Integer(3)).lam()
1
>>> HeckeTriangleGroup(Integer(4)).lam()
lam
>>> HeckeTriangleGroup(Integer(4)).lam()**Integer(2)
2
>>> HeckeTriangleGroup(Integer(6)).lam()**Integer(2)
3
>>> AA(HeckeTriangleGroup(Integer(10)).lam())
1.9021130325903...?
>>> HeckeTriangleGroup(infinity).lam()
2
lam_minpoly()[source]

Return the minimal polynomial of the corresponding lambda parameter of self.

EXAMPLES:

sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
sage: HeckeTriangleGroup(10).lam_minpoly()
x^4 - 5*x^2 + 5
sage: HeckeTriangleGroup(17).lam_minpoly()
x^8 - x^7 - 7*x^6 + 6*x^5 + 15*x^4 - 10*x^3 - 10*x^2 + 4*x + 1
sage: HeckeTriangleGroup(infinity).lam_minpoly()
x - 2
>>> from sage.all import *
>>> from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
>>> HeckeTriangleGroup(Integer(10)).lam_minpoly()
x^4 - 5*x^2 + 5
>>> HeckeTriangleGroup(Integer(17)).lam_minpoly()
x^8 - x^7 - 7*x^6 + 6*x^5 + 15*x^4 - 10*x^3 - 10*x^2 + 4*x + 1
>>> HeckeTriangleGroup(infinity).lam_minpoly()
x - 2
list_discriminants(D, primitive=True, hyperbolic=True, incomplete=False)[source]

Return a list of all discriminants up to some upper bound D.

INPUT:

  • D – an element/discriminant of the base ring or more generally an upper bound for the discriminant

  • primitive – if True (default) then only primitive discriminants are listed

  • hyperbolic – if True (default) then only positive discriminants are listed

  • incomplete – if True (default: False) then all (also higher) discriminants which were gathered so far are listed (however there might be missing discriminants in between).

OUTPUT: list of discriminants less than or equal to D

EXAMPLES:

sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
sage: G = HeckeTriangleGroup(n=4)
sage: G.list_discriminants(D=68)
[4, 12, 14, 28, 32, 46, 60, 68]
sage: G.list_discriminants(D=0, hyperbolic=False, primitive=False)
[-4, -2, 0]

sage: G = HeckeTriangleGroup(n=5)
sage: G.list_discriminants(D=20)
[4*lam, 7*lam + 6, 9*lam + 5]
sage: G.list_discriminants(D=0, hyperbolic=False, primitive=False)
[-4, -lam - 2, lam - 3, 0]
>>> from sage.all import *
>>> from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
>>> G = HeckeTriangleGroup(n=Integer(4))
>>> G.list_discriminants(D=Integer(68))
[4, 12, 14, 28, 32, 46, 60, 68]
>>> G.list_discriminants(D=Integer(0), hyperbolic=False, primitive=False)
[-4, -2, 0]

>>> G = HeckeTriangleGroup(n=Integer(5))
>>> G.list_discriminants(D=Integer(20))
[4*lam, 7*lam + 6, 9*lam + 5]
>>> G.list_discriminants(D=Integer(0), hyperbolic=False, primitive=False)
[-4, -lam - 2, lam - 3, 0]
n()[source]

Return the parameter n of self, where pi/n is the angle at rho of the corresponding basic hyperbolic triangle with vertices i, rho and infinity.

EXAMPLES:

sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
sage: HeckeTriangleGroup(10).n()
10
sage: HeckeTriangleGroup(infinity).n()
+Infinity
>>> from sage.all import *
>>> from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
>>> HeckeTriangleGroup(Integer(10)).n()
10
>>> HeckeTriangleGroup(infinity).n()
+Infinity
one()[source]

Return the identity element/matrix for self.

EXAMPLES:

sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
sage: G = HeckeTriangleGroup(10)
sage: G(1) == G.one()
True
sage: G(1)
[1 0]
[0 1]

sage: G(1).parent()
Hecke triangle group for n = 10
>>> from sage.all import *
>>> from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
>>> G = HeckeTriangleGroup(Integer(10))
>>> G(Integer(1)) == G.one()
True
>>> G(Integer(1))
[1 0]
[0 1]

>>> G(Integer(1)).parent()
Hecke triangle group for n = 10
rational_period_functions(k, D)[source]

Return a list of basic rational period functions of weight k for discriminant D.

The list is expected to be a generating set for all rational period functions of the given weight and discriminant (unknown).

The method assumes that D > 0.

Also see the element method \(rational_period_function\) for more information.

  • k – even integer, the desired weight of the rational period functions

  • D – an element of the base ring corresponding to a valid discriminant

EXAMPLES:

sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
sage: G = HeckeTriangleGroup(n=4)
sage: sorted(G.rational_period_functions(k=4, D=12))
[(z^4 - 1)/z^4]
sage: sorted(G.rational_period_functions(k=-2, D=12))
[-z^2 + 1, 4*lam*z^2 - 4*lam]
sage: sorted(G.rational_period_functions(k=2, D=14))
[(24*z^6 - 120*z^4 + 120*z^2 - 24)/(9*z^8 - 80*z^6 + 146*z^4 - 80*z^2 + 9),
 (24*z^6 - 120*z^4 + 120*z^2 - 24)/(9*z^8 - 80*z^6 + 146*z^4 - 80*z^2 + 9),
 1/z,
 (z^2 - 1)/z^2]
sage: sorted(G.rational_period_functions(k=-4, D=14))
[-16*z^4 + 16, -z^4 + 1, 16*z^4 - 16]
>>> from sage.all import *
>>> from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
>>> G = HeckeTriangleGroup(n=Integer(4))
>>> sorted(G.rational_period_functions(k=Integer(4), D=Integer(12)))
[(z^4 - 1)/z^4]
>>> sorted(G.rational_period_functions(k=-Integer(2), D=Integer(12)))
[-z^2 + 1, 4*lam*z^2 - 4*lam]
>>> sorted(G.rational_period_functions(k=Integer(2), D=Integer(14)))
[(24*z^6 - 120*z^4 + 120*z^2 - 24)/(9*z^8 - 80*z^6 + 146*z^4 - 80*z^2 + 9),
 (24*z^6 - 120*z^4 + 120*z^2 - 24)/(9*z^8 - 80*z^6 + 146*z^4 - 80*z^2 + 9),
 1/z,
 (z^2 - 1)/z^2]
>>> sorted(G.rational_period_functions(k=-Integer(4), D=Integer(14)))
[-16*z^4 + 16, -z^4 + 1, 16*z^4 - 16]
reduced_elements(D)[source]

Return all reduced (primitive) elements of discriminant D.

Also see the element method is_reduced() for more information.

  • D – an element of the base ring corresponding to a valid discriminant

EXAMPLES:

sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
sage: G = HeckeTriangleGroup(n=4)
sage: R = G.reduced_elements(D=12)
sage: R
[
[    5  -lam]  [     5 -3*lam]
[3*lam    -1], [   lam     -1]
]
sage: [v.continued_fraction() for v in R]
[((), (1, 3)), ((), (3, 1))]
sage: R = G.reduced_elements(D=14)
sage: sorted(R)
[
[3*lam    -1]  [4*lam    -3]  [ 5*lam     -7]  [ 5*lam     -3]
[    1     0], [    3  -lam], [     3 -2*lam], [     7 -2*lam]
]
sage: sorted(v.continued_fraction() for v in R)
[((), (1, 2, 2)), ((), (2, 1, 2)), ((), (2, 2, 1)), ((), (3,))]
>>> from sage.all import *
>>> from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
>>> G = HeckeTriangleGroup(n=Integer(4))
>>> R = G.reduced_elements(D=Integer(12))
>>> R
[
[    5  -lam]  [     5 -3*lam]
[3*lam    -1], [   lam     -1]
]
>>> [v.continued_fraction() for v in R]
[((), (1, 3)), ((), (3, 1))]
>>> R = G.reduced_elements(D=Integer(14))
>>> sorted(R)
[
[3*lam    -1]  [4*lam    -3]  [ 5*lam     -7]  [ 5*lam     -3]
[    1     0], [    3  -lam], [     3 -2*lam], [     7 -2*lam]
]
>>> sorted(v.continued_fraction() for v in R)
[((), (1, 2, 2)), ((), (2, 1, 2)), ((), (2, 2, 1)), ((), (3,))]
rho()[source]

Return the vertex rho of the basic hyperbolic triangle which describes self. rho has absolute value 1 and angle pi/n.

EXAMPLES:

sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
sage: HeckeTriangleGroup(3).rho() == QQbar(1/2 + sqrt(3)/2*i)
True
sage: HeckeTriangleGroup(4).rho() == QQbar(sqrt(2)/2*(1 + i))
True
sage: HeckeTriangleGroup(6).rho() == QQbar(sqrt(3)/2 + 1/2*i)
True
sage: HeckeTriangleGroup(10).rho()
0.95105651629515...? + 0.30901699437494...?*I
sage: HeckeTriangleGroup(infinity).rho()
1
>>> from sage.all import *
>>> from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
>>> HeckeTriangleGroup(Integer(3)).rho() == QQbar(Integer(1)/Integer(2) + sqrt(Integer(3))/Integer(2)*i)
True
>>> HeckeTriangleGroup(Integer(4)).rho() == QQbar(sqrt(Integer(2))/Integer(2)*(Integer(1) + i))
True
>>> HeckeTriangleGroup(Integer(6)).rho() == QQbar(sqrt(Integer(3))/Integer(2) + Integer(1)/Integer(2)*i)
True
>>> HeckeTriangleGroup(Integer(10)).rho()
0.95105651629515...? + 0.30901699437494...?*I
>>> HeckeTriangleGroup(infinity).rho()
1
root_extension_embedding(D, K=None)[source]

Return the correct embedding from the root extension field of the given discriminant D to the field K.

Also see the method root_extension_embedding(K) of HeckeTriangleGroupElement for more examples.

INPUT:

  • D – an element of the base ring of self corresponding to a discriminant

  • K – a field to which we want the (correct) embedding; if K=None (default) then AlgebraicField() is used for positive D and AlgebraicRealField() otherwise

OUTPUT:

The corresponding embedding if it was found. Otherwise a ValueError is raised.

EXAMPLES:

sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
sage: G = HeckeTriangleGroup(n=infinity)
sage: G.root_extension_embedding(32)
Ring morphism:
  From: Number Field in e with defining polynomial x^2 - 32
  To:   Algebraic Real Field
  Defn: e |--> 5.656854249492...?
sage: G.root_extension_embedding(-4)
Ring morphism:
  From: Number Field in e with defining polynomial x^2 + 4
  To:   Algebraic Field
  Defn: e |--> 2*I
sage: G.root_extension_embedding(4)
Coercion map:
  From: Rational Field
  To:   Algebraic Real Field

sage: G = HeckeTriangleGroup(n=7)
sage: lam = G.lam()
sage: D = 4*lam^2 + 4*lam - 4
sage: G.root_extension_embedding(D, CC)
Relative number field morphism:
  From: Number Field in e with defining polynomial x^2 - 4*lam^2 - 4*lam + 4 over its base field
  To:   Complex Field with 53 bits of precision
  Defn: e |--> 4.02438434522...
        lam |--> 1.80193773580...
sage: D = lam^2 - 4
sage: G.root_extension_embedding(D)
Relative number field morphism:
  From: Number Field in e with defining polynomial x^2 - lam^2 + 4 over its base field
  To:   Algebraic Field
  Defn: e |--> 0.?... + 0.867767478235...?*I
        lam |--> 1.801937735804...?
>>> from sage.all import *
>>> from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
>>> G = HeckeTriangleGroup(n=infinity)
>>> G.root_extension_embedding(Integer(32))
Ring morphism:
  From: Number Field in e with defining polynomial x^2 - 32
  To:   Algebraic Real Field
  Defn: e |--> 5.656854249492...?
>>> G.root_extension_embedding(-Integer(4))
Ring morphism:
  From: Number Field in e with defining polynomial x^2 + 4
  To:   Algebraic Field
  Defn: e |--> 2*I
>>> G.root_extension_embedding(Integer(4))
Coercion map:
  From: Rational Field
  To:   Algebraic Real Field

>>> G = HeckeTriangleGroup(n=Integer(7))
>>> lam = G.lam()
>>> D = Integer(4)*lam**Integer(2) + Integer(4)*lam - Integer(4)
>>> G.root_extension_embedding(D, CC)
Relative number field morphism:
  From: Number Field in e with defining polynomial x^2 - 4*lam^2 - 4*lam + 4 over its base field
  To:   Complex Field with 53 bits of precision
  Defn: e |--> 4.02438434522...
        lam |--> 1.80193773580...
>>> D = lam**Integer(2) - Integer(4)
>>> G.root_extension_embedding(D)
Relative number field morphism:
  From: Number Field in e with defining polynomial x^2 - lam^2 + 4 over its base field
  To:   Algebraic Field
  Defn: e |--> 0.?... + 0.867767478235...?*I
        lam |--> 1.801937735804...?
root_extension_field(D)[source]

Return the quadratic extension field of the base field by the square root of the given discriminant D.

INPUT:

  • D – an element of the base ring of self corresponding to a discriminant

OUTPUT:

A relative (at most quadratic) extension to the base field of self in the variable e which corresponds to sqrt(D). If the extension degree is 1 then the base field is returned.

The correct embedding is the positive resp. positive imaginary one. Unfortunately no default embedding can be specified for relative number fields yet.

EXAMPLES:

sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
sage: G = HeckeTriangleGroup(n=infinity)
sage: G.root_extension_field(32)
Number Field in e with defining polynomial x^2 - 32
sage: G.root_extension_field(-4)
Number Field in e with defining polynomial x^2 + 4
sage: G.root_extension_field(4) == G.base_field()
True

sage: G = HeckeTriangleGroup(n=7)
sage: lam = G.lam()
sage: D = 4*lam^2 + 4*lam - 4
sage: G.root_extension_field(D)
Number Field in e with defining polynomial x^2 - 4*lam^2 - 4*lam + 4 over its base field
sage: G.root_extension_field(4) == G.base_field()
True
sage: D = lam^2 - 4
sage: G.root_extension_field(D)
Number Field in e with defining polynomial x^2 - lam^2 + 4 over its base field
>>> from sage.all import *
>>> from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
>>> G = HeckeTriangleGroup(n=infinity)
>>> G.root_extension_field(Integer(32))
Number Field in e with defining polynomial x^2 - 32
>>> G.root_extension_field(-Integer(4))
Number Field in e with defining polynomial x^2 + 4
>>> G.root_extension_field(Integer(4)) == G.base_field()
True

>>> G = HeckeTriangleGroup(n=Integer(7))
>>> lam = G.lam()
>>> D = Integer(4)*lam**Integer(2) + Integer(4)*lam - Integer(4)
>>> G.root_extension_field(D)
Number Field in e with defining polynomial x^2 - 4*lam^2 - 4*lam + 4 over its base field
>>> G.root_extension_field(Integer(4)) == G.base_field()
True
>>> D = lam**Integer(2) - Integer(4)
>>> G.root_extension_field(D)
Number Field in e with defining polynomial x^2 - lam^2 + 4 over its base field
simple_elements(D)[source]

Return all simple elements of discriminant D.

Also see the element method is_simple() for more information.

  • D – an element of the base ring corresponding to a valid discriminant

EXAMPLES:

sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
sage: G = HeckeTriangleGroup(n=4)
sage: sorted(G.simple_elements(D=12))
[
[  1 lam]  [  3 lam]
[lam   3], [lam   1]
]
sage: sorted(G.simple_elements(D=14))
[
[  lam     1]  [  lam     3]  [2*lam     1]  [2*lam     3]
[    3 2*lam], [    1 2*lam], [    3   lam], [    1   lam]
]
>>> from sage.all import *
>>> from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup
>>> G = HeckeTriangleGroup(n=Integer(4))
>>> sorted(G.simple_elements(D=Integer(12)))
[
[  1 lam]  [  3 lam]
[lam   3], [lam   1]
]
>>> sorted(G.simple_elements(D=Integer(14)))
[
[  lam     1]  [  lam     3]  [2*lam     1]  [2*lam     3]
[    3 2*lam], [    1 2*lam], [    3   lam], [    1   lam]
]