Hecke triangle group elements¶
AUTHORS:
Jonas Jermann (2014): initial version
- class sage.modular.modform_hecketriangle.hecke_triangle_group_element.HeckeTriangleGroupElement(parent, M, check=True, **kwargs)[source]¶
Bases:
MatrixGroupElement_generic
Elements of HeckeTriangleGroup.
- a()[source]¶
Return the upper left entry of
self
.EXAMPLES:
sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup sage: U = HeckeTriangleGroup(n=7).U() sage: U.a() lam sage: U.a().parent() 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 >>> U = HeckeTriangleGroup(n=Integer(7)).U() >>> U.a() lam >>> U.a().parent() 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.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup U = HeckeTriangleGroup(n=7).U() U.a() U.a().parent()
- acton(tau)[source]¶
Return the image of
tau
under the action ofself
by linear fractional transformations or by conjugation in casetau
is an element of the parent ofself
.It is possible to act on points of
HyperbolicPlane()
.Note
There is a 1-1 correspondence between hyperbolic fixed points and the corresponding primitive element in the stabilizer. The action in the two cases above is compatible with this correspondence.
INPUT:
tau
– either an element ofself
or any element to which a linear fractional transformation can be applied in the usual way.In particular
infinity
is a possible argument and a possible return value.As mentioned it is also possible to use points of
HyperbolicPlane()
.
EXAMPLES:
sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup sage: G = HeckeTriangleGroup(5) sage: G.S().acton(SR(1 + i/2)) 2/5*I - 4/5 sage: G.S().acton(SR(1 + i/2)).parent() Symbolic Ring sage: G.S().acton(QQbar(1 + i/2)) 2/5*I - 4/5 sage: G.S().acton(QQbar(1 + i/2)).parent() Algebraic Field sage: G.S().acton(i + exp(-2)) -1/(e^(-2) + I) sage: G.S().acton(i + exp(-2)).parent() Symbolic Ring sage: G.T().acton(infinity) == infinity True sage: G.U().acton(infinity) lam sage: G.V(2).acton(-G.lam()) == infinity True sage: G.V(2).acton(G.U()) == G.V(2)*G.U()*G.V(2).inverse() True sage: G.V(2).inverse().acton(G.U()) [ 0 -1] [ 1 lam] sage: p = HyperbolicPlane().PD().get_point(-I/2+1/8) sage: G.V(2).acton(p) Point in PD -((-(47*I + 161)*sqrt(5) - 47*I - 161)/(145*sqrt(5) + 94*I + 177) + I)/(I*(-(47*I + 161)*sqrt(5) - 47*I - 161)/(145*sqrt(5) + 94*I + 177) + 1) sage: bool(G.V(2).acton(p).to_model('UHP').coordinates() ....: == G.V(2).acton(p.to_model('UHP').coordinates())) True sage: p = HyperbolicPlane().PD().get_point(I) sage: G.U().acton(p) Boundary point in PD 1/2*(sqrt(5) - 2*I + 1)/(-1/2*I*sqrt(5) - 1/2*I + 1) sage: G.U().acton(p).to_model('UHP') == HyperbolicPlane().UHP().get_point(G.lam()) True sage: G.U().acton(p) == HyperbolicPlane().UHP().get_point(G.lam()).to_model('PD') True
>>> from sage.all import * >>> from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup >>> G = HeckeTriangleGroup(Integer(5)) >>> G.S().acton(SR(Integer(1) + i/Integer(2))) 2/5*I - 4/5 >>> G.S().acton(SR(Integer(1) + i/Integer(2))).parent() Symbolic Ring >>> G.S().acton(QQbar(Integer(1) + i/Integer(2))) 2/5*I - 4/5 >>> G.S().acton(QQbar(Integer(1) + i/Integer(2))).parent() Algebraic Field >>> G.S().acton(i + exp(-Integer(2))) -1/(e^(-2) + I) >>> G.S().acton(i + exp(-Integer(2))).parent() Symbolic Ring >>> G.T().acton(infinity) == infinity True >>> G.U().acton(infinity) lam >>> G.V(Integer(2)).acton(-G.lam()) == infinity True >>> G.V(Integer(2)).acton(G.U()) == G.V(Integer(2))*G.U()*G.V(Integer(2)).inverse() True >>> G.V(Integer(2)).inverse().acton(G.U()) [ 0 -1] [ 1 lam] >>> p = HyperbolicPlane().PD().get_point(-I/Integer(2)+Integer(1)/Integer(8)) >>> G.V(Integer(2)).acton(p) Point in PD -((-(47*I + 161)*sqrt(5) - 47*I - 161)/(145*sqrt(5) + 94*I + 177) + I)/(I*(-(47*I + 161)*sqrt(5) - 47*I - 161)/(145*sqrt(5) + 94*I + 177) + 1) >>> bool(G.V(Integer(2)).acton(p).to_model('UHP').coordinates() ... == G.V(Integer(2)).acton(p.to_model('UHP').coordinates())) True >>> p = HyperbolicPlane().PD().get_point(I) >>> G.U().acton(p) Boundary point in PD 1/2*(sqrt(5) - 2*I + 1)/(-1/2*I*sqrt(5) - 1/2*I + 1) >>> G.U().acton(p).to_model('UHP') == HyperbolicPlane().UHP().get_point(G.lam()) True >>> G.U().acton(p) == HyperbolicPlane().UHP().get_point(G.lam()).to_model('PD') True
from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup G = HeckeTriangleGroup(5) G.S().acton(SR(1 + i/2)) G.S().acton(SR(1 + i/2)).parent() G.S().acton(QQbar(1 + i/2)) G.S().acton(QQbar(1 + i/2)).parent() G.S().acton(i + exp(-2)) G.S().acton(i + exp(-2)).parent() G.T().acton(infinity) == infinity G.U().acton(infinity) G.V(2).acton(-G.lam()) == infinity G.V(2).acton(G.U()) == G.V(2)*G.U()*G.V(2).inverse() G.V(2).inverse().acton(G.U()) p = HyperbolicPlane().PD().get_point(-I/2+1/8) G.V(2).acton(p) bool(G.V(2).acton(p).to_model('UHP').coordinates() == G.V(2).acton(p.to_model('UHP').coordinates())) p = HyperbolicPlane().PD().get_point(I) G.U().acton(p) G.U().acton(p).to_model('UHP') == HyperbolicPlane().UHP().get_point(G.lam()) G.U().acton(p) == HyperbolicPlane().UHP().get_point(G.lam()).to_model('PD')
- as_hyperbolic_plane_isometry(model='UHP')[source]¶
Return
self
as an isometry ofHyperbolicPlane()
(in the upper half plane model).EXAMPLES:
sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup sage: el = HeckeTriangleGroup(7).V(4) sage: el.as_hyperbolic_plane_isometry() Isometry in UHP [lam^2 - 1 lam] [lam^2 - 1 lam^2 - 1] sage: el.as_hyperbolic_plane_isometry().parent() Set of Morphisms from Hyperbolic plane in the Upper Half Plane Model to Hyperbolic plane in the Upper Half Plane Model in Category of hyperbolic models of Hyperbolic plane sage: el.as_hyperbolic_plane_isometry("KM").parent() Set of Morphisms from Hyperbolic plane in the Klein Disk Model to Hyperbolic plane in the Klein Disk Model in Category of hyperbolic models of Hyperbolic plane
>>> from sage.all import * >>> from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup >>> el = HeckeTriangleGroup(Integer(7)).V(Integer(4)) >>> el.as_hyperbolic_plane_isometry() Isometry in UHP [lam^2 - 1 lam] [lam^2 - 1 lam^2 - 1] >>> el.as_hyperbolic_plane_isometry().parent() Set of Morphisms from Hyperbolic plane in the Upper Half Plane Model to Hyperbolic plane in the Upper Half Plane Model in Category of hyperbolic models of Hyperbolic plane >>> el.as_hyperbolic_plane_isometry("KM").parent() Set of Morphisms from Hyperbolic plane in the Klein Disk Model to Hyperbolic plane in the Klein Disk Model in Category of hyperbolic models of Hyperbolic plane
from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup el = HeckeTriangleGroup(7).V(4) el.as_hyperbolic_plane_isometry() el.as_hyperbolic_plane_isometry().parent() el.as_hyperbolic_plane_isometry("KM").parent()
- b()[source]¶
Return the upper right entry of
self
.EXAMPLES:
sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup sage: U = HeckeTriangleGroup(n=7).U() sage: U.b() -1 sage: U.b().parent() 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 >>> U = HeckeTriangleGroup(n=Integer(7)).U() >>> U.b() -1 >>> U.b().parent() 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.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup U = HeckeTriangleGroup(n=7).U() U.b() U.b().parent()
- block_decomposition()[source]¶
Return a tuple
(L, R, sgn)
such thatself = sgn * R.acton(prod(L)) = sgn * R*prod(L)*R.inverse()
.In the parabolic and hyperbolic case the tuple entries in
L
are powers of basic block matrices:V(j) = U^(j-1)*T = self.parent().V(j)
for1 <= j <= n-1
. In the elliptic case the tuple entries are eitherS
orU
.This decomposition data is (also) described by
_block_decomposition_data()
.Warning: The case
n=infinity
is not verified at all and probably wrong!EXAMPLES:
sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup sage: G = HeckeTriangleGroup(n=7) sage: G.element_repr_method("basic") sage: G.T().block_decomposition() ((T,), T^(-1), 1) sage: G.V(2).acton(G.T(-3)).block_decomposition() ((-S*T^(-3)*S,), T, 1) sage: (-G.V(2)^2).block_decomposition() ((T*S*T^2*S*T,), T*S*T, -1) sage: el = (-G.V(2)*G.V(6)*G.V(3)*G.V(2)*G.V(6)*G.V(3)) sage: el.block_decomposition() ((-S*T^(-1)*S, T*S*T*S*T, T*S*T, -S*T^(-1)*S, T*S*T*S*T, T*S*T), T*S*T, -1) sage: (G.U()^4*G.S()*G.V(2)).acton(el).block_decomposition() ((T*S*T, -S*T^(-1)*S, T*S*T*S*T, T*S*T, -S*T^(-1)*S, T*S*T*S*T), T*S*T*S*T*S*T^2*S*T, -1) sage: (G.V(1)^5*G.V(2)*G.V(3)^3).block_decomposition() ((T*S*T*S*T^2*S*T*S*T^2*S*T*S*T, T^5, T*S*T), T^6*S*T, 1) sage: G.element_repr_method("default") sage: (-G.I()).block_decomposition() ( ([1 0] [1 0] [-1 0] [0 1],), [0 1], [ 0 -1] ) sage: G.U().block_decomposition() ( ([lam -1] [1 0] [1 0] [ 1 0],), [0 1], [0 1] ) sage: (-G.S()).block_decomposition() ( ([ 0 -1] [-1 0] [-1 0] [ 1 0],), [ 0 -1], [ 0 -1] ) sage: (G.V(2)*G.V(3)).acton(G.U()^6).block_decomposition() ( ([ 0 1] [-2*lam^2 - 2*lam + 2 -2*lam^2 - 2*lam + 1] [-1 0] [ -1 lam],), [ -2*lam^2 + 1 -2*lam^2 - lam + 2], [ 0 -1] ) sage: (G.U()^(-6)).block_decomposition() ( ([lam -1] [1 0] [-1 0] [ 1 0],), [0 1], [ 0 -1] ) sage: G = HeckeTriangleGroup(n=8) sage: (G.U()^4).block_decomposition() ( ([ lam^2 - 1 -lam^3 + 2*lam] [1 0] [1 0] [ lam^3 - 2*lam -lam^2 + 1],), [0 1], [0 1] ) sage: (G.U()^(-4)).block_decomposition() ( ([ lam^2 - 1 -lam^3 + 2*lam] [1 0] [-1 0] [ lam^3 - 2*lam -lam^2 + 1],), [0 1], [ 0 -1] )
>>> from sage.all import * >>> from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup >>> G = HeckeTriangleGroup(n=Integer(7)) >>> G.element_repr_method("basic") >>> G.T().block_decomposition() ((T,), T^(-1), 1) >>> G.V(Integer(2)).acton(G.T(-Integer(3))).block_decomposition() ((-S*T^(-3)*S,), T, 1) >>> (-G.V(Integer(2))**Integer(2)).block_decomposition() ((T*S*T^2*S*T,), T*S*T, -1) >>> el = (-G.V(Integer(2))*G.V(Integer(6))*G.V(Integer(3))*G.V(Integer(2))*G.V(Integer(6))*G.V(Integer(3))) >>> el.block_decomposition() ((-S*T^(-1)*S, T*S*T*S*T, T*S*T, -S*T^(-1)*S, T*S*T*S*T, T*S*T), T*S*T, -1) >>> (G.U()**Integer(4)*G.S()*G.V(Integer(2))).acton(el).block_decomposition() ((T*S*T, -S*T^(-1)*S, T*S*T*S*T, T*S*T, -S*T^(-1)*S, T*S*T*S*T), T*S*T*S*T*S*T^2*S*T, -1) >>> (G.V(Integer(1))**Integer(5)*G.V(Integer(2))*G.V(Integer(3))**Integer(3)).block_decomposition() ((T*S*T*S*T^2*S*T*S*T^2*S*T*S*T, T^5, T*S*T), T^6*S*T, 1) >>> G.element_repr_method("default") >>> (-G.I()).block_decomposition() ( ([1 0] [1 0] [-1 0] [0 1],), [0 1], [ 0 -1] ) >>> G.U().block_decomposition() ( ([lam -1] [1 0] [1 0] [ 1 0],), [0 1], [0 1] ) >>> (-G.S()).block_decomposition() ( ([ 0 -1] [-1 0] [-1 0] [ 1 0],), [ 0 -1], [ 0 -1] ) >>> (G.V(Integer(2))*G.V(Integer(3))).acton(G.U()**Integer(6)).block_decomposition() ( ([ 0 1] [-2*lam^2 - 2*lam + 2 -2*lam^2 - 2*lam + 1] [-1 0] [ -1 lam],), [ -2*lam^2 + 1 -2*lam^2 - lam + 2], [ 0 -1] ) >>> (G.U()**(-Integer(6))).block_decomposition() ( ([lam -1] [1 0] [-1 0] [ 1 0],), [0 1], [ 0 -1] ) >>> G = HeckeTriangleGroup(n=Integer(8)) >>> (G.U()**Integer(4)).block_decomposition() ( ([ lam^2 - 1 -lam^3 + 2*lam] [1 0] [1 0] [ lam^3 - 2*lam -lam^2 + 1],), [0 1], [0 1] ) >>> (G.U()**(-Integer(4))).block_decomposition() ( ([ lam^2 - 1 -lam^3 + 2*lam] [1 0] [-1 0] [ lam^3 - 2*lam -lam^2 + 1],), [0 1], [ 0 -1] )
from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup G = HeckeTriangleGroup(n=7) G.element_repr_method("basic") G.T().block_decomposition() G.V(2).acton(G.T(-3)).block_decomposition() (-G.V(2)^2).block_decomposition() el = (-G.V(2)*G.V(6)*G.V(3)*G.V(2)*G.V(6)*G.V(3)) el.block_decomposition() (G.U()^4*G.S()*G.V(2)).acton(el).block_decomposition() (G.V(1)^5*G.V(2)*G.V(3)^3).block_decomposition() G.element_repr_method("default") (-G.I()).block_decomposition() G.U().block_decomposition() (-G.S()).block_decomposition() (G.V(2)*G.V(3)).acton(G.U()^6).block_decomposition() (G.U()^(-6)).block_decomposition() G = HeckeTriangleGroup(n=8) (G.U()^4).block_decomposition() (G.U()^(-4)).block_decomposition()
- block_length(primitive=False)[source]¶
Return the block length of
self
. The block length is given by the number of factors used for the decomposition of the conjugacy representative ofself
described inprimitive_representative()
. In particular the block length is invariant under conjugation.The definition is mostly used for parabolic or hyperbolic elements: In particular it gives a lower bound for the (absolute value of) the trace and the discriminant for primitive hyperbolic elements. Namely
abs(trace) >= lambda * block_length
anddiscriminant >= block_length^2 * lambda^2 - 4
.Warning: The case
n=infinity
is not verified at all and probably wrong!INPUT:
primitive
– boolean (default:False
); ifTrue
then the conjugacy representative of the primitive part is used instead
OUTPUT:
An integer. For hyperbolic elements a nonnegative integer. For parabolic elements a negative sign corresponds to taking the inverse. For elliptic elements a (non-trivial) integer with minimal absolute value is chosen. For +- the identity element
0
is returned.EXAMPLES:
sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup sage: G = HeckeTriangleGroup(n=7) sage: G.T().block_length() 1 sage: G.V(2).acton(G.T(-3)).block_length() 3 sage: G.V(2).acton(G.T(-3)).block_length(primitive=True) 1 sage: (-G.V(2)).block_length() 1 sage: el = -G.V(2)^3*G.V(6)^2*G.V(3) sage: t = el.block_length() sage: D = el.discriminant() sage: trace = el.trace() sage: (trace, D, t) (-124*lam^2 - 103*lam + 68, 65417*lam^2 + 52456*lam - 36300, 6) sage: abs(AA(trace)) >= AA(G.lam()*t) True sage: AA(D) >= AA(t^2 * G.lam() - 4) True sage: (el^3).block_length(primitive=True) == t True sage: el = (G.U()^4*G.S()*G.V(2)).acton(-G.V(2)^3*G.V(6)^2*G.V(3)) sage: t = el.block_length() sage: D = el.discriminant() sage: trace = el.trace() sage: (trace, D, t) (-124*lam^2 - 103*lam + 68, 65417*lam^2 + 52456*lam - 36300, 6) sage: abs(AA(trace)) >= AA(G.lam()*t) True sage: AA(D) >= AA(t^2 * G.lam() - 4) True sage: (el^(-2)).block_length(primitive=True) == t True sage: el = G.V(1)^5*G.V(2)*G.V(3)^3 sage: t = el.block_length() sage: D = el.discriminant() sage: trace = el.trace() sage: (trace, D, t) (284*lam^2 + 224*lam - 156, 330768*lam^2 + 265232*lam - 183556, 9) sage: abs(AA(trace)) >= AA(G.lam()*t) True sage: AA(D) >= AA(t^2 * G.lam() - 4) True sage: (el^(-1)).block_length(primitive=True) == t True sage: (G.V(2)*G.V(3)).acton(G.U()^6).block_length() 1 sage: (G.V(2)*G.V(3)).acton(G.U()^6).block_length(primitive=True) 1 sage: (-G.I()).block_length() 0 sage: G.U().block_length() 1 sage: (-G.S()).block_length() 1
>>> from sage.all import * >>> from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup >>> G = HeckeTriangleGroup(n=Integer(7)) >>> G.T().block_length() 1 >>> G.V(Integer(2)).acton(G.T(-Integer(3))).block_length() 3 >>> G.V(Integer(2)).acton(G.T(-Integer(3))).block_length(primitive=True) 1 >>> (-G.V(Integer(2))).block_length() 1 >>> el = -G.V(Integer(2))**Integer(3)*G.V(Integer(6))**Integer(2)*G.V(Integer(3)) >>> t = el.block_length() >>> D = el.discriminant() >>> trace = el.trace() >>> (trace, D, t) (-124*lam^2 - 103*lam + 68, 65417*lam^2 + 52456*lam - 36300, 6) >>> abs(AA(trace)) >= AA(G.lam()*t) True >>> AA(D) >= AA(t**Integer(2) * G.lam() - Integer(4)) True >>> (el**Integer(3)).block_length(primitive=True) == t True >>> el = (G.U()**Integer(4)*G.S()*G.V(Integer(2))).acton(-G.V(Integer(2))**Integer(3)*G.V(Integer(6))**Integer(2)*G.V(Integer(3))) >>> t = el.block_length() >>> D = el.discriminant() >>> trace = el.trace() >>> (trace, D, t) (-124*lam^2 - 103*lam + 68, 65417*lam^2 + 52456*lam - 36300, 6) >>> abs(AA(trace)) >= AA(G.lam()*t) True >>> AA(D) >= AA(t**Integer(2) * G.lam() - Integer(4)) True >>> (el**(-Integer(2))).block_length(primitive=True) == t True >>> el = G.V(Integer(1))**Integer(5)*G.V(Integer(2))*G.V(Integer(3))**Integer(3) >>> t = el.block_length() >>> D = el.discriminant() >>> trace = el.trace() >>> (trace, D, t) (284*lam^2 + 224*lam - 156, 330768*lam^2 + 265232*lam - 183556, 9) >>> abs(AA(trace)) >= AA(G.lam()*t) True >>> AA(D) >= AA(t**Integer(2) * G.lam() - Integer(4)) True >>> (el**(-Integer(1))).block_length(primitive=True) == t True >>> (G.V(Integer(2))*G.V(Integer(3))).acton(G.U()**Integer(6)).block_length() 1 >>> (G.V(Integer(2))*G.V(Integer(3))).acton(G.U()**Integer(6)).block_length(primitive=True) 1 >>> (-G.I()).block_length() 0 >>> G.U().block_length() 1 >>> (-G.S()).block_length() 1
from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup G = HeckeTriangleGroup(n=7) G.T().block_length() G.V(2).acton(G.T(-3)).block_length() G.V(2).acton(G.T(-3)).block_length(primitive=True) (-G.V(2)).block_length() el = -G.V(2)^3*G.V(6)^2*G.V(3) t = el.block_length() D = el.discriminant() trace = el.trace() (trace, D, t) abs(AA(trace)) >= AA(G.lam()*t) AA(D) >= AA(t^2 * G.lam() - 4) (el^3).block_length(primitive=True) == t el = (G.U()^4*G.S()*G.V(2)).acton(-G.V(2)^3*G.V(6)^2*G.V(3)) t = el.block_length() D = el.discriminant() trace = el.trace() (trace, D, t) abs(AA(trace)) >= AA(G.lam()*t) AA(D) >= AA(t^2 * G.lam() - 4) (el^(-2)).block_length(primitive=True) == t el = G.V(1)^5*G.V(2)*G.V(3)^3 t = el.block_length() D = el.discriminant() trace = el.trace() (trace, D, t) abs(AA(trace)) >= AA(G.lam()*t) AA(D) >= AA(t^2 * G.lam() - 4) (el^(-1)).block_length(primitive=True) == t (G.V(2)*G.V(3)).acton(G.U()^6).block_length() (G.V(2)*G.V(3)).acton(G.U()^6).block_length(primitive=True) (-G.I()).block_length() G.U().block_length() (-G.S()).block_length()
- c()[source]¶
Return the lower left entry of
self
.EXAMPLES:
sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup sage: U = HeckeTriangleGroup(n=7).U() sage: U.c() 1
>>> from sage.all import * >>> from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup >>> U = HeckeTriangleGroup(n=Integer(7)).U() >>> U.c() 1
from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup U = HeckeTriangleGroup(n=7).U() U.c()
- conjugacy_type(ignore_sign=True, primitive=False)[source]¶
Return a unique description of the conjugacy class of
self
(by default only up to a sign).Warning: The case
n=infinity
is not verified at all and probably wrong!INPUT:
ignore_sign
– ifTrue
(default) then the conjugacy classes are only considered up to a signprimitive
– boolean (default:False
); ifTrue
then the conjugacy class of the primitive part is considered instead and the sign is ignored
OUTPUT:
A unique representative for the given block data (without the conjugation matrix) among all cyclic permutations. If
ignore_sign=True
then the sign is excluded as well.EXAMPLES:
sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup sage: G = HeckeTriangleGroup(n=7) sage: (-G.I()).conjugacy_type() ((6, 0),) sage: G.U().acton(G.S()).conjugacy_type() (0, 1) sage: (G.U()^4).conjugacy_type() (1, -3) sage: ((G.V(2)*G.V(3)^2*G.V(2)*G.V(3))^2).conjugacy_type() ((3, 2), (2, 1), (3, 1), (2, 1), (3, 2), (2, 1), (3, 1), (2, 1)) sage: (-G.I()).conjugacy_type(ignore_sign=False) (((6, 0),), -1) sage: G.S().conjugacy_type(ignore_sign=False) ((0, 1), 1) sage: (G.U()^4).conjugacy_type(ignore_sign=False) ((1, -3), -1) sage: G.U().acton((G.V(2)*G.V(3)^2*G.V(2)*G.V(3))^2).conjugacy_type(ignore_sign=False) (((3, 2), (2, 1), (3, 1), (2, 1), (3, 2), (2, 1), (3, 1), (2, 1)), 1) sage: (-G.I()).conjugacy_type(primitive=True) ((6, 0),) sage: G.S().conjugacy_type(primitive=True) (0, 1) sage: G.V(2).acton(G.U()^4).conjugacy_type(primitive=True) (1, 1) sage: (G.V(3)^2).conjugacy_type(primitive=True) ((3, 1),) sage: G.S().acton((G.V(2)*G.V(3)^2*G.V(2)*G.V(3))^2).conjugacy_type(primitive=True) ((3, 2), (2, 1), (3, 1), (2, 1))
>>> from sage.all import * >>> from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup >>> G = HeckeTriangleGroup(n=Integer(7)) >>> (-G.I()).conjugacy_type() ((6, 0),) >>> G.U().acton(G.S()).conjugacy_type() (0, 1) >>> (G.U()**Integer(4)).conjugacy_type() (1, -3) >>> ((G.V(Integer(2))*G.V(Integer(3))**Integer(2)*G.V(Integer(2))*G.V(Integer(3)))**Integer(2)).conjugacy_type() ((3, 2), (2, 1), (3, 1), (2, 1), (3, 2), (2, 1), (3, 1), (2, 1)) >>> (-G.I()).conjugacy_type(ignore_sign=False) (((6, 0),), -1) >>> G.S().conjugacy_type(ignore_sign=False) ((0, 1), 1) >>> (G.U()**Integer(4)).conjugacy_type(ignore_sign=False) ((1, -3), -1) >>> G.U().acton((G.V(Integer(2))*G.V(Integer(3))**Integer(2)*G.V(Integer(2))*G.V(Integer(3)))**Integer(2)).conjugacy_type(ignore_sign=False) (((3, 2), (2, 1), (3, 1), (2, 1), (3, 2), (2, 1), (3, 1), (2, 1)), 1) >>> (-G.I()).conjugacy_type(primitive=True) ((6, 0),) >>> G.S().conjugacy_type(primitive=True) (0, 1) >>> G.V(Integer(2)).acton(G.U()**Integer(4)).conjugacy_type(primitive=True) (1, 1) >>> (G.V(Integer(3))**Integer(2)).conjugacy_type(primitive=True) ((3, 1),) >>> G.S().acton((G.V(Integer(2))*G.V(Integer(3))**Integer(2)*G.V(Integer(2))*G.V(Integer(3)))**Integer(2)).conjugacy_type(primitive=True) ((3, 2), (2, 1), (3, 1), (2, 1))
from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup G = HeckeTriangleGroup(n=7) (-G.I()).conjugacy_type() G.U().acton(G.S()).conjugacy_type() (G.U()^4).conjugacy_type() ((G.V(2)*G.V(3)^2*G.V(2)*G.V(3))^2).conjugacy_type() (-G.I()).conjugacy_type(ignore_sign=False) G.S().conjugacy_type(ignore_sign=False) (G.U()^4).conjugacy_type(ignore_sign=False) G.U().acton((G.V(2)*G.V(3)^2*G.V(2)*G.V(3))^2).conjugacy_type(ignore_sign=False) (-G.I()).conjugacy_type(primitive=True) G.S().conjugacy_type(primitive=True) G.V(2).acton(G.U()^4).conjugacy_type(primitive=True) (G.V(3)^2).conjugacy_type(primitive=True) G.S().acton((G.V(2)*G.V(3)^2*G.V(2)*G.V(3))^2).conjugacy_type(primitive=True)
- continued_fraction()[source]¶
For hyperbolic and parabolic elements: Return the (negative) lambda-continued fraction expansion (lambda-CF) of the (attracting) hyperbolic fixed point of
self
.Let
r_j in Z
forj >= 0
. A finite lambda-CF is defined as:[r_0; r_1, ..., r_k] := (T^(r_0)*S* ... *T^(r_k)*S)(infinity)
, whereS
andT
are the generators ofself
. An infinite lambda-CF is defined as a corresponding limit value (k->infinity) if it exists.In this case the lambda-CF of parabolic and hyperbolic fixed points are returned which have an eventually periodic lambda-CF. The parabolic elements are exactly those with a cyclic permutation of the period
[2, 1, ..., 1]
withn-3
ones.Warning: The case
n=infinity
is not verified at all and probably wrong!OUTPUT:
A tuple
(preperiod, period)
with the preperiod and period tuples of the lambda-CF.EXAMPLES:
sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup sage: G = HeckeTriangleGroup(n=7) sage: G.T().continued_fraction() ((0, 1), (1, 1, 1, 1, 2)) sage: G.V(2).acton(G.T(-3)).continued_fraction() ((), (2, 1, 1, 1, 1)) sage: (-G.V(2)).continued_fraction() ((1,), (2,)) sage: (-G.V(2)^3*G.V(6)^2*G.V(3)).continued_fraction() ((1,), (2, 2, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 2)) sage: (G.U()^4*G.S()*G.V(2)).acton(-G.V(2)^3*G.V(6)^2*G.V(3)).continued_fraction() ((1, 1, 1, 2), (2, 2, 2, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1)) sage: (G.V(1)^5*G.V(2)*G.V(3)^3).continued_fraction() ((6,), (2, 1, 2, 1, 2, 1, 7)) sage: G = HeckeTriangleGroup(n=8) sage: G.T().continued_fraction() ((0, 1), (1, 1, 1, 1, 1, 2)) sage: G.V(2).acton(G.T(-3)).continued_fraction() ((), (2, 1, 1, 1, 1, 1)) sage: (-G.V(2)).continued_fraction() ((1,), (2,)) sage: (-G.V(2)^3*G.V(6)^2*G.V(3)).continued_fraction() ((1,), (2, 2, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 2)) sage: (G.U()^4*G.S()*G.V(2)).acton(-G.V(2)^3*G.V(6)^2*G.V(3)).continued_fraction() ((1, 1, 1, 2), (2, 2, 2, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1)) sage: (G.V(1)^5*G.V(2)*G.V(3)^3).continued_fraction() ((6,), (2, 1, 2, 1, 2, 1, 7)) sage: (G.V(2)^3*G.V(5)*G.V(1)*G.V(6)^2*G.V(4)).continued_fraction() ((1,), (2, 2, 2, 1, 1, 1, 3, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 2))
>>> from sage.all import * >>> from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup >>> G = HeckeTriangleGroup(n=Integer(7)) >>> G.T().continued_fraction() ((0, 1), (1, 1, 1, 1, 2)) >>> G.V(Integer(2)).acton(G.T(-Integer(3))).continued_fraction() ((), (2, 1, 1, 1, 1)) >>> (-G.V(Integer(2))).continued_fraction() ((1,), (2,)) >>> (-G.V(Integer(2))**Integer(3)*G.V(Integer(6))**Integer(2)*G.V(Integer(3))).continued_fraction() ((1,), (2, 2, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 2)) >>> (G.U()**Integer(4)*G.S()*G.V(Integer(2))).acton(-G.V(Integer(2))**Integer(3)*G.V(Integer(6))**Integer(2)*G.V(Integer(3))).continued_fraction() ((1, 1, 1, 2), (2, 2, 2, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1)) >>> (G.V(Integer(1))**Integer(5)*G.V(Integer(2))*G.V(Integer(3))**Integer(3)).continued_fraction() ((6,), (2, 1, 2, 1, 2, 1, 7)) >>> G = HeckeTriangleGroup(n=Integer(8)) >>> G.T().continued_fraction() ((0, 1), (1, 1, 1, 1, 1, 2)) >>> G.V(Integer(2)).acton(G.T(-Integer(3))).continued_fraction() ((), (2, 1, 1, 1, 1, 1)) >>> (-G.V(Integer(2))).continued_fraction() ((1,), (2,)) >>> (-G.V(Integer(2))**Integer(3)*G.V(Integer(6))**Integer(2)*G.V(Integer(3))).continued_fraction() ((1,), (2, 2, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 2)) >>> (G.U()**Integer(4)*G.S()*G.V(Integer(2))).acton(-G.V(Integer(2))**Integer(3)*G.V(Integer(6))**Integer(2)*G.V(Integer(3))).continued_fraction() ((1, 1, 1, 2), (2, 2, 2, 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1)) >>> (G.V(Integer(1))**Integer(5)*G.V(Integer(2))*G.V(Integer(3))**Integer(3)).continued_fraction() ((6,), (2, 1, 2, 1, 2, 1, 7)) >>> (G.V(Integer(2))**Integer(3)*G.V(Integer(5))*G.V(Integer(1))*G.V(Integer(6))**Integer(2)*G.V(Integer(4))).continued_fraction() ((1,), (2, 2, 2, 1, 1, 1, 3, 1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 2))
from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup G = HeckeTriangleGroup(n=7) G.T().continued_fraction() G.V(2).acton(G.T(-3)).continued_fraction() (-G.V(2)).continued_fraction() (-G.V(2)^3*G.V(6)^2*G.V(3)).continued_fraction() (G.U()^4*G.S()*G.V(2)).acton(-G.V(2)^3*G.V(6)^2*G.V(3)).continued_fraction() (G.V(1)^5*G.V(2)*G.V(3)^3).continued_fraction() G = HeckeTriangleGroup(n=8) G.T().continued_fraction() G.V(2).acton(G.T(-3)).continued_fraction() (-G.V(2)).continued_fraction() (-G.V(2)^3*G.V(6)^2*G.V(3)).continued_fraction() (G.U()^4*G.S()*G.V(2)).acton(-G.V(2)^3*G.V(6)^2*G.V(3)).continued_fraction() (G.V(1)^5*G.V(2)*G.V(3)^3).continued_fraction() (G.V(2)^3*G.V(5)*G.V(1)*G.V(6)^2*G.V(4)).continued_fraction()
- d()[source]¶
Return the lower right of
self
.EXAMPLES:
sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup sage: U = HeckeTriangleGroup(n=7).U() sage: U.d() 0
>>> from sage.all import * >>> from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup >>> U = HeckeTriangleGroup(n=Integer(7)).U() >>> U.d() 0
from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup U = HeckeTriangleGroup(n=7).U() U.d()
- discriminant()[source]¶
Return the discriminant of
self
which corresponds to the discriminant of the corresponding quadratic form ofself
.EXAMPLES:
sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup sage: G = HeckeTriangleGroup(n=7) sage: G.V(3).discriminant() 4*lam^2 + 4*lam - 4 sage: AA(G.V(3).discriminant()) 16.19566935808922?
>>> from sage.all import * >>> from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup >>> G = HeckeTriangleGroup(n=Integer(7)) >>> G.V(Integer(3)).discriminant() 4*lam^2 + 4*lam - 4 >>> AA(G.V(Integer(3)).discriminant()) 16.19566935808922?
from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup G = HeckeTriangleGroup(n=7) G.V(3).discriminant() AA(G.V(3).discriminant())
- fixed_points(embedded=False, order='default')[source]¶
Return a pair of (mutually conjugate) fixed points of
self
in a possible quadratic extension of the base field.INPUT:
embedded
– boolean (default:False
); ifTrue
, the fixed points are embedded intoAlgebraicRealField
resp.AlgebraicField
order
– iforder='none'
the fixed points are chosen and ordered according to a fixed formulaIf
order='sign'
the fixed points are always ordered according to the sign in front of the square root.If
order='default'
(default) then in case the fixed points are hyperbolic they are ordered according to the sign of the trace ofself
instead, such that the attracting fixed point comes first.If
order='trace'
the fixed points are always ordered according to the sign of the trace ofself
. If the trace is zero they are ordered by the sign in front of the square root. In particular the fixed_points in this case remain the same for-self
.
OUTPUT:
If
embedded=True
an element of eitherAlgebraicRealField
orAlgebraicField
is returned. Otherwise an element of a relative field extension over the base field of (the parent of)self
is returned.Warning: Relative field extensions do not support default embeddings. So the correct embedding (which is the positive resp. imaginary positive one) has to be chosen.
EXAMPLES:
sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup sage: G = HeckeTriangleGroup(n=infinity) sage: (-G.T(-4)).fixed_points() (+Infinity, +Infinity) sage: (-G.S()).fixed_points() (1/2*e, -1/2*e) sage: p = (-G.S()).fixed_points(embedded=True)[0] sage: p I sage: (-G.S()).acton(p) == p True sage: (-G.V(2)).fixed_points() (1/2*e, -1/2*e) sage: (-G.V(2)).fixed_points() == G.V(2).fixed_points() True sage: p = (-G.V(2)).fixed_points(embedded=True)[1] sage: p -1.732050807568878? sage: (-G.V(2)).acton(p) == p True sage: G = HeckeTriangleGroup(n=7) sage: (-G.S()).fixed_points() (1/2*e, -1/2*e) sage: p = (-G.S()).fixed_points(embedded=True)[1] sage: p -I sage: (-G.S()).acton(p) == p True sage: (G.U()^4).fixed_points() ((1/2*lam^2 - 1/2*lam - 1/2)*e + 1/2*lam, (-1/2*lam^2 + 1/2*lam + 1/2)*e + 1/2*lam) sage: pts = (G.U()^4).fixed_points(order='trace') sage: (G.U()^4).fixed_points() == [pts[1], pts[0]] False sage: (G.U()^4).fixed_points(order='trace') == (-G.U()^4).fixed_points(order='trace') True sage: (G.U()^4).fixed_points() == (G.U()^4).fixed_points(order='none') True sage: (-G.U()^4).fixed_points() == (G.U()^4).fixed_points() True sage: (-G.U()^4).fixed_points(order='none') == pts True sage: p = (G.U()^4).fixed_points(embedded=True)[1] sage: p 0.9009688679024191? - 0.4338837391175581?*I sage: (G.U()^4).acton(p) == p True sage: (-G.V(5)).fixed_points() ((1/2*lam^2 - 1/2*lam - 1/2)*e, (-1/2*lam^2 + 1/2*lam + 1/2)*e) sage: (-G.V(5)).fixed_points() == G.V(5).fixed_points() True sage: p = (-G.V(5)).fixed_points(embedded=True)[0] sage: p 0.6671145837954892? sage: (-G.V(5)).acton(p) == p True
>>> from sage.all import * >>> from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup >>> G = HeckeTriangleGroup(n=infinity) >>> (-G.T(-Integer(4))).fixed_points() (+Infinity, +Infinity) >>> (-G.S()).fixed_points() (1/2*e, -1/2*e) >>> p = (-G.S()).fixed_points(embedded=True)[Integer(0)] >>> p I >>> (-G.S()).acton(p) == p True >>> (-G.V(Integer(2))).fixed_points() (1/2*e, -1/2*e) >>> (-G.V(Integer(2))).fixed_points() == G.V(Integer(2)).fixed_points() True >>> p = (-G.V(Integer(2))).fixed_points(embedded=True)[Integer(1)] >>> p -1.732050807568878? >>> (-G.V(Integer(2))).acton(p) == p True >>> G = HeckeTriangleGroup(n=Integer(7)) >>> (-G.S()).fixed_points() (1/2*e, -1/2*e) >>> p = (-G.S()).fixed_points(embedded=True)[Integer(1)] >>> p -I >>> (-G.S()).acton(p) == p True >>> (G.U()**Integer(4)).fixed_points() ((1/2*lam^2 - 1/2*lam - 1/2)*e + 1/2*lam, (-1/2*lam^2 + 1/2*lam + 1/2)*e + 1/2*lam) >>> pts = (G.U()**Integer(4)).fixed_points(order='trace') >>> (G.U()**Integer(4)).fixed_points() == [pts[Integer(1)], pts[Integer(0)]] False >>> (G.U()**Integer(4)).fixed_points(order='trace') == (-G.U()**Integer(4)).fixed_points(order='trace') True >>> (G.U()**Integer(4)).fixed_points() == (G.U()**Integer(4)).fixed_points(order='none') True >>> (-G.U()**Integer(4)).fixed_points() == (G.U()**Integer(4)).fixed_points() True >>> (-G.U()**Integer(4)).fixed_points(order='none') == pts True >>> p = (G.U()**Integer(4)).fixed_points(embedded=True)[Integer(1)] >>> p 0.9009688679024191? - 0.4338837391175581?*I >>> (G.U()**Integer(4)).acton(p) == p True >>> (-G.V(Integer(5))).fixed_points() ((1/2*lam^2 - 1/2*lam - 1/2)*e, (-1/2*lam^2 + 1/2*lam + 1/2)*e) >>> (-G.V(Integer(5))).fixed_points() == G.V(Integer(5)).fixed_points() True >>> p = (-G.V(Integer(5))).fixed_points(embedded=True)[Integer(0)] >>> p 0.6671145837954892? >>> (-G.V(Integer(5))).acton(p) == p True
from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup G = HeckeTriangleGroup(n=infinity) (-G.T(-4)).fixed_points() (-G.S()).fixed_points() p = (-G.S()).fixed_points(embedded=True)[0] p (-G.S()).acton(p) == p (-G.V(2)).fixed_points() (-G.V(2)).fixed_points() == G.V(2).fixed_points() p = (-G.V(2)).fixed_points(embedded=True)[1] p (-G.V(2)).acton(p) == p G = HeckeTriangleGroup(n=7) (-G.S()).fixed_points() p = (-G.S()).fixed_points(embedded=True)[1] p (-G.S()).acton(p) == p (G.U()^4).fixed_points() pts = (G.U()^4).fixed_points(order='trace') (G.U()^4).fixed_points() == [pts[1], pts[0]] (G.U()^4).fixed_points(order='trace') == (-G.U()^4).fixed_points(order='trace') (G.U()^4).fixed_points() == (G.U()^4).fixed_points(order='none') (-G.U()^4).fixed_points() == (G.U()^4).fixed_points() (-G.U()^4).fixed_points(order='none') == pts p = (G.U()^4).fixed_points(embedded=True)[1] p (G.U()^4).acton(p) == p (-G.V(5)).fixed_points() (-G.V(5)).fixed_points() == G.V(5).fixed_points() p = (-G.V(5)).fixed_points(embedded=True)[0] p (-G.V(5)).acton(p) == p
- is_elliptic()[source]¶
Return whether
self
is an elliptic matrix.EXAMPLES:
sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup sage: G = HeckeTriangleGroup(n=7) sage: [ G.V(k).is_elliptic() for k in range(1,8) ] [False, False, False, False, False, False, True] sage: G.U().is_elliptic() True
>>> from sage.all import * >>> from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup >>> G = HeckeTriangleGroup(n=Integer(7)) >>> [ G.V(k).is_elliptic() for k in range(Integer(1),Integer(8)) ] [False, False, False, False, False, False, True] >>> G.U().is_elliptic() True
from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup G = HeckeTriangleGroup(n=7) [ G.V(k).is_elliptic() for k in range(1,8) ] G.U().is_elliptic()
- is_hecke_symmetric()[source]¶
Return whether the conjugacy class of the primitive part of
self
, denoted by[gamma]
is \(Hecke-symmetric\): I.e. if[gamma] == [gamma^(-1)]
.This is equivalent to
self.simple_fixed_point_set()
being equal with it’s \(Hecke-conjugated\) set (where each fixed point is replaced by the other (\(Hecke-conjugated\)) fixed point.It is also equivalent to
[Q] == [-Q]
for the corresponding hyperbolic binary quadratic formQ
.The method assumes that
self
is hyperbolic.Warning
The case
n=infinity
is not verified at all and probably wrong!EXAMPLES:
sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup sage: G = HeckeTriangleGroup(n=5) sage: el = G.V(2) sage: el.is_hecke_symmetric() False sage: (el.simple_fixed_point_set(), el.inverse().simple_fixed_point_set()) ({1/2*e, (-1/2*lam + 1/2)*e}, {-1/2*e, (1/2*lam - 1/2)*e}) sage: el = G.V(3)*G.V(2)^(-1)*G.V(1)*G.V(6) sage: el.is_hecke_symmetric() False sage: el.simple_fixed_point_set() == el.inverse().simple_fixed_point_set() False sage: el = G.V(2)*G.V(3) sage: el.is_hecke_symmetric() True sage: sorted(el.simple_fixed_point_set(), key=str) [(-lam + 3/2)*e + 1/2*lam - 1, (-lam + 3/2)*e - 1/2*lam + 1, (lam - 3/2)*e + 1/2*lam - 1, (lam - 3/2)*e - 1/2*lam + 1] sage: el.simple_fixed_point_set() == el.inverse().simple_fixed_point_set() True
>>> from sage.all import * >>> from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup >>> G = HeckeTriangleGroup(n=Integer(5)) >>> el = G.V(Integer(2)) >>> el.is_hecke_symmetric() False >>> (el.simple_fixed_point_set(), el.inverse().simple_fixed_point_set()) ({1/2*e, (-1/2*lam + 1/2)*e}, {-1/2*e, (1/2*lam - 1/2)*e}) >>> el = G.V(Integer(3))*G.V(Integer(2))**(-Integer(1))*G.V(Integer(1))*G.V(Integer(6)) >>> el.is_hecke_symmetric() False >>> el.simple_fixed_point_set() == el.inverse().simple_fixed_point_set() False >>> el = G.V(Integer(2))*G.V(Integer(3)) >>> el.is_hecke_symmetric() True >>> sorted(el.simple_fixed_point_set(), key=str) [(-lam + 3/2)*e + 1/2*lam - 1, (-lam + 3/2)*e - 1/2*lam + 1, (lam - 3/2)*e + 1/2*lam - 1, (lam - 3/2)*e - 1/2*lam + 1] >>> el.simple_fixed_point_set() == el.inverse().simple_fixed_point_set() True
from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup G = HeckeTriangleGroup(n=5) el = G.V(2) el.is_hecke_symmetric() (el.simple_fixed_point_set(), el.inverse().simple_fixed_point_set()) el = G.V(3)*G.V(2)^(-1)*G.V(1)*G.V(6) el.is_hecke_symmetric() el.simple_fixed_point_set() == el.inverse().simple_fixed_point_set() el = G.V(2)*G.V(3) el.is_hecke_symmetric() sorted(el.simple_fixed_point_set(), key=str) el.simple_fixed_point_set() == el.inverse().simple_fixed_point_set()
- is_hyperbolic()[source]¶
Return whether
self
is a hyperbolic matrix.EXAMPLES:
sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup sage: G = HeckeTriangleGroup(n=7) sage: [ G.V(k).is_hyperbolic() for k in range(1,8) ] [False, True, True, True, True, False, False] sage: G.U().is_hyperbolic() False
>>> from sage.all import * >>> from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup >>> G = HeckeTriangleGroup(n=Integer(7)) >>> [ G.V(k).is_hyperbolic() for k in range(Integer(1),Integer(8)) ] [False, True, True, True, True, False, False] >>> G.U().is_hyperbolic() False
from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup G = HeckeTriangleGroup(n=7) [ G.V(k).is_hyperbolic() for k in range(1,8) ] G.U().is_hyperbolic()
- is_identity()[source]¶
Return whether
self
is the identity or minus the identity.EXAMPLES:
sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup sage: G = HeckeTriangleGroup(n=7) sage: [ G.V(k).is_identity() for k in range(1,8) ] [False, False, False, False, False, False, False] sage: G.U().is_identity() False
>>> from sage.all import * >>> from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup >>> G = HeckeTriangleGroup(n=Integer(7)) >>> [ G.V(k).is_identity() for k in range(Integer(1),Integer(8)) ] [False, False, False, False, False, False, False] >>> G.U().is_identity() False
from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup G = HeckeTriangleGroup(n=7) [ G.V(k).is_identity() for k in range(1,8) ] G.U().is_identity()
- is_parabolic(exclude_one=False)[source]¶
Return whether
self
is a parabolic matrix.If
exclude_one
is set, then +- the identity element is not considered parabolic.EXAMPLES:
sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup sage: G = HeckeTriangleGroup(n=7) sage: [ G.V(k).is_parabolic() for k in range(1,8) ] [True, False, False, False, False, True, False] sage: G.U().is_parabolic() False sage: G.V(6).is_parabolic(exclude_one=True) True sage: G.V(7).is_parabolic(exclude_one=True) False
>>> from sage.all import * >>> from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup >>> G = HeckeTriangleGroup(n=Integer(7)) >>> [ G.V(k).is_parabolic() for k in range(Integer(1),Integer(8)) ] [True, False, False, False, False, True, False] >>> G.U().is_parabolic() False >>> G.V(Integer(6)).is_parabolic(exclude_one=True) True >>> G.V(Integer(7)).is_parabolic(exclude_one=True) False
from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup G = HeckeTriangleGroup(n=7) [ G.V(k).is_parabolic() for k in range(1,8) ] G.U().is_parabolic() G.V(6).is_parabolic(exclude_one=True) G.V(7).is_parabolic(exclude_one=True)
- is_primitive()[source]¶
Return whether
self
is primitive. We call an element primitive if (up to a sign and taking inverses) it generates the full stabilizer subgroup of the corresponding fixed point. In the non-elliptic case this means that primitive elements cannot be written as a \(non-trivial\) power of another element.The notion is mostly used for hyperbolic and parabolic elements.
Warning: The case
n=infinity
is not verified at all and probably wrong!EXAMPLES:
sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup sage: G = HeckeTriangleGroup(n=7) sage: G.V(2).acton(G.T(-1)).is_primitive() True sage: G.T(3).is_primitive() False sage: (-G.V(2)^2).is_primitive() False sage: (G.V(1)^5*G.V(2)*G.V(3)^3).is_primitive() True sage: (-G.I()).is_primitive() True sage: (-G.U()).is_primitive() True sage: (-G.S()).is_primitive() True sage: (G.U()^6).is_primitive() True sage: G = HeckeTriangleGroup(n=8) sage: (G.U()^2).is_primitive() False sage: (G.U()^(-4)).is_primitive() False sage: (G.U()^(-3)).is_primitive() True
>>> from sage.all import * >>> from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup >>> G = HeckeTriangleGroup(n=Integer(7)) >>> G.V(Integer(2)).acton(G.T(-Integer(1))).is_primitive() True >>> G.T(Integer(3)).is_primitive() False >>> (-G.V(Integer(2))**Integer(2)).is_primitive() False >>> (G.V(Integer(1))**Integer(5)*G.V(Integer(2))*G.V(Integer(3))**Integer(3)).is_primitive() True >>> (-G.I()).is_primitive() True >>> (-G.U()).is_primitive() True >>> (-G.S()).is_primitive() True >>> (G.U()**Integer(6)).is_primitive() True >>> G = HeckeTriangleGroup(n=Integer(8)) >>> (G.U()**Integer(2)).is_primitive() False >>> (G.U()**(-Integer(4))).is_primitive() False >>> (G.U()**(-Integer(3))).is_primitive() True
from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup G = HeckeTriangleGroup(n=7) G.V(2).acton(G.T(-1)).is_primitive() G.T(3).is_primitive() (-G.V(2)^2).is_primitive() (G.V(1)^5*G.V(2)*G.V(3)^3).is_primitive() (-G.I()).is_primitive() (-G.U()).is_primitive() (-G.S()).is_primitive() (G.U()^6).is_primitive() G = HeckeTriangleGroup(n=8) (G.U()^2).is_primitive() (G.U()^(-4)).is_primitive() (G.U()^(-3)).is_primitive()
- is_reduced(require_primitive=True, require_hyperbolic=True)[source]¶
Return whether
self
is reduced. We call an element reduced if the associated lambda-CF is purely periodic.I.e. (in the hyperbolic case) if the associated hyperbolic fixed point (resp. the associated hyperbolic binary quadratic form) is reduced.
Note that if
self
is reduced then the element corresponding to the cyclic permutation of the lambda-CF (which is conjugate to the original element) is again reduced. In particular the reduced elements in the conjugacy class ofself
form a finite cycle.Elliptic elements and +- identity are not considered reduced.
Warning: The case
n=infinity
is not verified at all and probably wrong!INPUT:
require_primitive
– ifTrue
(default) then non-primitive elements are not considered reducedrequire_hyperbolic
– ifTrue
(default) then non-hyperbolic elements are not considered reduced
EXAMPLES:
sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup sage: G = HeckeTriangleGroup(n=7) sage: G.I().is_reduced(require_hyperbolic=False) False sage: G.U().reduce().is_reduced(require_hyperbolic=False) False sage: G.T().reduce().is_reduced() False sage: G.T().reduce().is_reduced(require_hyperbolic=False) True sage: (G.V(5)^2).reduce(primitive=False).is_reduced() False sage: (G.V(5)^2).reduce(primitive=False).is_reduced(require_primitive=False) True sage: G.V(5).reduce().is_reduced() True sage: (-G.V(2)).reduce().is_reduced() True sage: (-G.V(2)^3*G.V(6)^2*G.V(3)).reduce().is_reduced() True sage: (G.U()^4*G.S()*G.V(2)).acton(-G.V(2)^3*G.V(6)^2*G.V(3)).reduce().is_reduced() True
>>> from sage.all import * >>> from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup >>> G = HeckeTriangleGroup(n=Integer(7)) >>> G.I().is_reduced(require_hyperbolic=False) False >>> G.U().reduce().is_reduced(require_hyperbolic=False) False >>> G.T().reduce().is_reduced() False >>> G.T().reduce().is_reduced(require_hyperbolic=False) True >>> (G.V(Integer(5))**Integer(2)).reduce(primitive=False).is_reduced() False >>> (G.V(Integer(5))**Integer(2)).reduce(primitive=False).is_reduced(require_primitive=False) True >>> G.V(Integer(5)).reduce().is_reduced() True >>> (-G.V(Integer(2))).reduce().is_reduced() True >>> (-G.V(Integer(2))**Integer(3)*G.V(Integer(6))**Integer(2)*G.V(Integer(3))).reduce().is_reduced() True >>> (G.U()**Integer(4)*G.S()*G.V(Integer(2))).acton(-G.V(Integer(2))**Integer(3)*G.V(Integer(6))**Integer(2)*G.V(Integer(3))).reduce().is_reduced() True
from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup G = HeckeTriangleGroup(n=7) G.I().is_reduced(require_hyperbolic=False) G.U().reduce().is_reduced(require_hyperbolic=False) G.T().reduce().is_reduced() G.T().reduce().is_reduced(require_hyperbolic=False) (G.V(5)^2).reduce(primitive=False).is_reduced() (G.V(5)^2).reduce(primitive=False).is_reduced(require_primitive=False) G.V(5).reduce().is_reduced() (-G.V(2)).reduce().is_reduced() (-G.V(2)^3*G.V(6)^2*G.V(3)).reduce().is_reduced() (G.U()^4*G.S()*G.V(2)).acton(-G.V(2)^3*G.V(6)^2*G.V(3)).reduce().is_reduced()
- is_reflection()[source]¶
Return whether
self
is the usual reflection on the unit circle.EXAMPLES:
sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup sage: (-HeckeTriangleGroup(n=7).S()).is_reflection() True sage: HeckeTriangleGroup(n=7).U().is_reflection() False
>>> from sage.all import * >>> from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup >>> (-HeckeTriangleGroup(n=Integer(7)).S()).is_reflection() True >>> HeckeTriangleGroup(n=Integer(7)).U().is_reflection() False
from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup (-HeckeTriangleGroup(n=7).S()).is_reflection() HeckeTriangleGroup(n=7).U().is_reflection()
- is_simple()[source]¶
Return whether
self
is simple. We call an element simple if it is hyperbolic, primitive, has positive sign and if the associated hyperbolic fixed points satisfy:alpha' < 0 < alpha
wherealpha
is the attracting fixed point for the element.I.e. if the associated hyperbolic fixed point (resp. the associated hyperbolic binary quadratic form) is simple.
There are only finitely many simple elements for a given discriminant. They can be used to provide explicit descriptions of rational period functions.
Warning: The case
n=infinity
is not verified at all and probably wrong!EXAMPLES:
sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup sage: G = HeckeTriangleGroup(n=5) sage: el = G.V(2) sage: el.is_simple() True sage: R = el.simple_elements() sage: [v.is_simple() for v in R] [True] sage: (fp1, fp2) = R[0].fixed_points(embedded=True) sage: (fp1, fp2) (1.272019649514069?, -1.272019649514069?) sage: fp2 < 0 < fp1 True sage: el = G.V(3)*G.V(2)^(-1)*G.V(1)*G.V(6) sage: el.is_simple() False sage: R = el.simple_elements() sage: [v.is_simple() for v in R] [True, True] sage: (fp1, fp2) = R[1].fixed_points(embedded=True) sage: fp2 < 0 < fp1 True sage: el = G.V(1)^2*G.V(2)*G.V(4) sage: el.is_simple() True sage: R = el.simple_elements() sage: el in R True sage: [v.is_simple() for v in R] [True, True, True, True] sage: (fp1, fp2) = R[2].fixed_points(embedded=True) sage: fp2 < 0 < fp1 True
>>> from sage.all import * >>> from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup >>> G = HeckeTriangleGroup(n=Integer(5)) >>> el = G.V(Integer(2)) >>> el.is_simple() True >>> R = el.simple_elements() >>> [v.is_simple() for v in R] [True] >>> (fp1, fp2) = R[Integer(0)].fixed_points(embedded=True) >>> (fp1, fp2) (1.272019649514069?, -1.272019649514069?) >>> fp2 < Integer(0) < fp1 True >>> el = G.V(Integer(3))*G.V(Integer(2))**(-Integer(1))*G.V(Integer(1))*G.V(Integer(6)) >>> el.is_simple() False >>> R = el.simple_elements() >>> [v.is_simple() for v in R] [True, True] >>> (fp1, fp2) = R[Integer(1)].fixed_points(embedded=True) >>> fp2 < Integer(0) < fp1 True >>> el = G.V(Integer(1))**Integer(2)*G.V(Integer(2))*G.V(Integer(4)) >>> el.is_simple() True >>> R = el.simple_elements() >>> el in R True >>> [v.is_simple() for v in R] [True, True, True, True] >>> (fp1, fp2) = R[Integer(2)].fixed_points(embedded=True) >>> fp2 < Integer(0) < fp1 True
from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup G = HeckeTriangleGroup(n=5) el = G.V(2) el.is_simple() R = el.simple_elements() [v.is_simple() for v in R] (fp1, fp2) = R[0].fixed_points(embedded=True) (fp1, fp2) fp2 < 0 < fp1 el = G.V(3)*G.V(2)^(-1)*G.V(1)*G.V(6) el.is_simple() R = el.simple_elements() [v.is_simple() for v in R] (fp1, fp2) = R[1].fixed_points(embedded=True) fp2 < 0 < fp1 el = G.V(1)^2*G.V(2)*G.V(4) el.is_simple() R = el.simple_elements() el in R [v.is_simple() for v in R] (fp1, fp2) = R[2].fixed_points(embedded=True) fp2 < 0 < fp1
- is_translation(exclude_one=False)[source]¶
Return whether
self
is a translation. Ifexclude_one = True
, then the identity map is not considered as a translation.EXAMPLES:
sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup sage: (-HeckeTriangleGroup(n=7).T(-4)).is_translation() True sage: (-HeckeTriangleGroup(n=7).I()).is_translation() True sage: (-HeckeTriangleGroup(n=7).I()).is_translation(exclude_one=True) False
>>> from sage.all import * >>> from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup >>> (-HeckeTriangleGroup(n=Integer(7)).T(-Integer(4))).is_translation() True >>> (-HeckeTriangleGroup(n=Integer(7)).I()).is_translation() True >>> (-HeckeTriangleGroup(n=Integer(7)).I()).is_translation(exclude_one=True) False
from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup (-HeckeTriangleGroup(n=7).T(-4)).is_translation() (-HeckeTriangleGroup(n=7).I()).is_translation() (-HeckeTriangleGroup(n=7).I()).is_translation(exclude_one=True)
- linking_number()[source]¶
Let
g
denote a holomorphic primitive ofE2
in the sense:lambda/(2*pi*i) d/dz g = E2
. Letgamma=self
and letM_gamma(z)
beLog((c*z+d) * sgn(a+d))
ifc, a+d > 0
, resp.Log((c*z+d) / i*sgn(c))
ifa+d = 0, c!=0
, resp.0
ifc=0
. Letk=4 * n / (n-2)
, then:g(gamma.acton(z) - g(z) - k*M_gamma(z)
is equal to2*pi*i / (n-2) * self.linking_number()
.In particular it is independent of
z
and a conjugacy invariant.If
self
is hyperbolic then in the classical casen=3
this is the linking number of the closed geodesic (corresponding toself
) with the trefoil knot.EXAMPLES:
sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup sage: from sage.modular.modform_hecketriangle.space import QuasiModularForms sage: def E2_primitive(z, n=3, prec=10, num_prec=53): ....: G = HeckeTriangleGroup(n=n) ....: MF = QuasiModularForms(group=G, k=2, ep=-1) ....: q = MF.get_q(prec=prec) ....: int_series = integrate((MF.E2().q_expansion(prec=prec) - 1) / q) ....: t_const = (2*pi*i/G.lam()).n(num_prec) ....: d = MF.get_d(fix_d=True, d_num_prec=num_prec) ....: q = exp(t_const * z) ....: return t_const*z + sum((int_series.coefficients()[m]).subs(d=d) * q**int_series.exponents()[m] ....: for m in range(len(int_series.coefficients()))) sage: def M(gamma, z, num_prec=53): ....: a = ComplexField(num_prec)(gamma.a()) ....: b = ComplexField(num_prec)(gamma.b()) ....: c = ComplexField(num_prec)(gamma.c()) ....: d = ComplexField(num_prec)(gamma.d()) ....: if c == 0: ....: return 0 ....: elif a + d == 0: ....: return log(-i.n(num_prec)*(c*z + d)*sign(c)) ....: else: ....: return log((c*z+d)*sign(a+d)) sage: def num_linking_number(A, z, n=3, prec=10, num_prec=53): ....: z = z.n(num_prec) ....: k = 4 * n / (n - 2) ....: return (n-2) / (2*pi*i).n(num_prec) * (E2_primitive(A.acton(z), n=n, prec=prec, num_prec=num_prec) ....: - E2_primitive(z, n=n, prec=prec, num_prec=num_prec) ....: - k*M(A, z, num_prec=num_prec)) sage: G = HeckeTriangleGroup(8) sage: z = i sage: for A in [G.S(), G.T(), G.U(), G.U()^(G.n()//2), G.U()^(-3)]: ....: print("A={}: ".format(A.string_repr("conj"))) ....: num_linking_number(A, z, G.n()) ....: A.linking_number() A=[S]: 0.000000000000... 0 A=[V(1)]: 6.000000000000... 6 A=[U]: -2.00000000000... -2 A=[U^4]: 0.596987639289... + 0.926018962976...*I 0 A=[U^(-3)]: 5.40301236071... + 0.926018962976...*I 6 sage: z = ComplexField(1000)(- 2.3 + 3.1*i) sage: B = G.I() sage: for A in [G.S(), G.T(), G.U(), G.U()^(G.n()//2), G.U()^(-3)]: ....: print("A={}: ".format(A.string_repr("conj"))) ....: num_linking_number(B.acton(A), z, G.n(), prec=100, num_prec=1000).n(53) ....: B.acton(A).linking_number() A=[S]: 6.63923483989...e-31 + 2.45195568651...e-30*I 0 A=[V(1)]: 6.000000000000... 6 A=[U]: -2.00000000000... + 2.45195568651...e-30*I -2 A=[U^4]: 0.00772492873864... + 0.00668936643212...*I 0 A=[U^(-3)]: 5.99730551444... + 0.000847636355069...*I 6 sage: z = ComplexField(5000)(- 2.3 + 3.1*i) sage: B = G.U() sage: for A in [G.S(), G.T(), G.U(), G.U()^(G.n()//2), G.U()^(-3)]: # long time ....: print("A={}: ".format(A.string_repr("conj"))) ....: num_linking_number(B.acton(A), z, G.n(), prec=200, num_prec=5000).n(53) ....: B.acton(A).linking_number() A=[S]: -7.90944791339...e-34 - 9.38956758807...e-34*I 0 A=[V(1)]: 5.99999997397... - 5.96520311160...e-8*I 6 A=[U]: -2.00000000000... - 1.33113963568...e-61*I -2 A=[U^4]: -2.32704571946...e-6 + 5.91899385948...e-7*I 0 A=[U^(-3)]: 6.00000032148... - 1.82676936467...e-7*I 6 sage: A = G.V(2)*G.V(3) sage: B = G.I() sage: num_linking_number(B.acton(A), z, G.n(), prec=200, num_prec=5000).n(53) # long time 6.00498424588... - 0.00702329345176...*I sage: A.linking_number() 6 The numerical properties for anything larger are basically too bad to make nice further tests...
>>> from sage.all import * >>> from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup >>> from sage.modular.modform_hecketriangle.space import QuasiModularForms >>> def E2_primitive(z, n=Integer(3), prec=Integer(10), num_prec=Integer(53)): ... G = HeckeTriangleGroup(n=n) ... MF = QuasiModularForms(group=G, k=Integer(2), ep=-Integer(1)) ... q = MF.get_q(prec=prec) ... int_series = integrate((MF.E2().q_expansion(prec=prec) - Integer(1)) / q) ... t_const = (Integer(2)*pi*i/G.lam()).n(num_prec) ... d = MF.get_d(fix_d=True, d_num_prec=num_prec) ... q = exp(t_const * z) ... return t_const*z + sum((int_series.coefficients()[m]).subs(d=d) * q**int_series.exponents()[m] ... for m in range(len(int_series.coefficients()))) >>> def M(gamma, z, num_prec=Integer(53)): ... a = ComplexField(num_prec)(gamma.a()) ... b = ComplexField(num_prec)(gamma.b()) ... c = ComplexField(num_prec)(gamma.c()) ... d = ComplexField(num_prec)(gamma.d()) ... if c == Integer(0): ... return Integer(0) ... elif a + d == Integer(0): ... return log(-i.n(num_prec)*(c*z + d)*sign(c)) ... else: ... return log((c*z+d)*sign(a+d)) >>> def num_linking_number(A, z, n=Integer(3), prec=Integer(10), num_prec=Integer(53)): ... z = z.n(num_prec) ... k = Integer(4) * n / (n - Integer(2)) ... return (n-Integer(2)) / (Integer(2)*pi*i).n(num_prec) * (E2_primitive(A.acton(z), n=n, prec=prec, num_prec=num_prec) ... - E2_primitive(z, n=n, prec=prec, num_prec=num_prec) ... - k*M(A, z, num_prec=num_prec)) >>> G = HeckeTriangleGroup(Integer(8)) >>> z = i >>> for A in [G.S(), G.T(), G.U(), G.U()**(G.n()//Integer(2)), G.U()**(-Integer(3))]: ... print("A={}: ".format(A.string_repr("conj"))) ... num_linking_number(A, z, G.n()) ... A.linking_number() A=[S]: 0.000000000000... 0 A=[V(1)]: 6.000000000000... 6 A=[U]: -2.00000000000... -2 A=[U^4]: 0.596987639289... + 0.926018962976...*I 0 A=[U^(-3)]: 5.40301236071... + 0.926018962976...*I 6 >>> z = ComplexField(Integer(1000))(- RealNumber('2.3') + RealNumber('3.1')*i) >>> B = G.I() >>> for A in [G.S(), G.T(), G.U(), G.U()**(G.n()//Integer(2)), G.U()**(-Integer(3))]: ... print("A={}: ".format(A.string_repr("conj"))) ... num_linking_number(B.acton(A), z, G.n(), prec=Integer(100), num_prec=Integer(1000)).n(Integer(53)) ... B.acton(A).linking_number() A=[S]: 6.63923483989...e-31 + 2.45195568651...e-30*I 0 A=[V(1)]: 6.000000000000... 6 A=[U]: -2.00000000000... + 2.45195568651...e-30*I -2 A=[U^4]: 0.00772492873864... + 0.00668936643212...*I 0 A=[U^(-3)]: 5.99730551444... + 0.000847636355069...*I 6 >>> z = ComplexField(Integer(5000))(- RealNumber('2.3') + RealNumber('3.1')*i) >>> B = G.U() >>> for A in [G.S(), G.T(), G.U(), G.U()**(G.n()//Integer(2)), G.U()**(-Integer(3))]: # long time ... print("A={}: ".format(A.string_repr("conj"))) ... num_linking_number(B.acton(A), z, G.n(), prec=Integer(200), num_prec=Integer(5000)).n(Integer(53)) ... B.acton(A).linking_number() A=[S]: -7.90944791339...e-34 - 9.38956758807...e-34*I 0 A=[V(1)]: 5.99999997397... - 5.96520311160...e-8*I 6 A=[U]: -2.00000000000... - 1.33113963568...e-61*I -2 A=[U^4]: -2.32704571946...e-6 + 5.91899385948...e-7*I 0 A=[U^(-3)]: 6.00000032148... - 1.82676936467...e-7*I 6 >>> A = G.V(Integer(2))*G.V(Integer(3)) >>> B = G.I() >>> num_linking_number(B.acton(A), z, G.n(), prec=Integer(200), num_prec=Integer(5000)).n(Integer(53)) # long time 6.00498424588... - 0.00702329345176...*I >>> A.linking_number() 6 The numerical properties for anything larger are basically too bad to make nice further tests...
from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup from sage.modular.modform_hecketriangle.space import QuasiModularForms def E2_primitive(z, n=3, prec=10, num_prec=53): G = HeckeTriangleGroup(n=n) MF = QuasiModularForms(group=G, k=2, ep=-1) q = MF.get_q(prec=prec) int_series = integrate((MF.E2().q_expansion(prec=prec) - 1) / q) t_const = (2*pi*i/G.lam()).n(num_prec) d = MF.get_d(fix_d=True, d_num_prec=num_prec) q = exp(t_const * z) return t_const*z + sum((int_series.coefficients()[m]).subs(d=d) * q**int_series.exponents()[m] for m in range(len(int_series.coefficients()))) def M(gamma, z, num_prec=53): a = ComplexField(num_prec)(gamma.a()) b = ComplexField(num_prec)(gamma.b()) c = ComplexField(num_prec)(gamma.c()) d = ComplexField(num_prec)(gamma.d()) if c == 0: return 0 elif a + d == 0: return log(-i.n(num_prec)*(c*z + d)*sign(c)) else: return log((c*z+d)*sign(a+d)) def num_linking_number(A, z, n=3, prec=10, num_prec=53): z = z.n(num_prec) k = 4 * n / (n - 2) return (n-2) / (2*pi*i).n(num_prec) * (E2_primitive(A.acton(z), n=n, prec=prec, num_prec=num_prec) - E2_primitive(z, n=n, prec=prec, num_prec=num_prec) - k*M(A, z, num_prec=num_prec)) G = HeckeTriangleGroup(8) z = i for A in [G.S(), G.T(), G.U(), G.U()^(G.n()//2), G.U()^(-3)]: print("A={}: ".format(A.string_repr("conj"))) num_linking_number(A, z, G.n()) A.linking_number() z = ComplexField(1000)(- 2.3 + 3.1*i) B = G.I() for A in [G.S(), G.T(), G.U(), G.U()^(G.n()//2), G.U()^(-3)]: print("A={}: ".format(A.string_repr("conj"))) num_linking_number(B.acton(A), z, G.n(), prec=100, num_prec=1000).n(53) B.acton(A).linking_number() z = ComplexField(5000)(- 2.3 + 3.1*i) B = G.U() for A in [G.S(), G.T(), G.U(), G.U()^(G.n()//2), G.U()^(-3)]: # long time print("A={}: ".format(A.string_repr("conj"))) num_linking_number(B.acton(A), z, G.n(), prec=200, num_prec=5000).n(53) B.acton(A).linking_number() A = G.V(2)*G.V(3) B = G.I() num_linking_number(B.acton(A), z, G.n(), prec=200, num_prec=5000).n(53) # long time A.linking_number()
- primitive_part(method='cf')[source]¶
Return the primitive part of
self
. I.e. a group elementA
with nonnegative trace such thatself = sign * A^power
, wheresign = self.sign()
is +- the identity (to correct the sign) andpower = self.primitive_power()
.The primitive part itself is chosen such that it cannot be written as a non-trivial power of another element. It is a generator of the stabilizer of the corresponding (attracting) fixed point.
If
self
is elliptic then the primitive part is chosen as a conjugate ofS
orU
.Warning: The case
n=infinity
is not verified at all and probably wrong!INPUT:
method
– the method used to determine the primitive part (seeprimitive_representative()
), default:'cf'
. The parameter is ignored for elliptic elements or +- the identity.The result should not depend on the method.
OUTPUT: the primitive part as a group element of
self
EXAMPLES:
sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup sage: G = HeckeTriangleGroup(n=7) sage: G.element_repr_method("block") sage: G.T().primitive_part() (T^(-1)*S) * (V(6)) * (T^(-1)*S)^(-1) sage: G.V(2).acton(G.T(-3)).primitive_part() (T) * (V(6)) * (T)^(-1) sage: (-G.V(2)).primitive_part() (T*S*T) * (V(2)) * (T*S*T)^(-1) sage: (-G.V(2)^3*G.V(6)^2*G.V(3)).primitive_part() V(2)^3*V(6)^2*V(3) sage: (G.U()^4*G.S()*G.V(2)).acton(-G.V(2)^3*G.V(6)^2*G.V(3)).primitive_part() (T*S*T*S*T*S*T^2*S*T) * (V(2)^3*V(6)^2*V(3)) * (T*S*T*S*T*S*T^2*S*T)^(-1) sage: (G.V(1)^5*G.V(2)*G.V(3)^3).primitive_part() (T^6*S*T) * (V(3)^3*V(1)^5*V(2)) * (T^6*S*T)^(-1) sage: (G.V(2)*G.V(3)).acton(G.U()^6).primitive_part() (-T*S*T^2*S*T*S*T) * (U) * (-T*S*T^2*S*T*S*T)^(-1) sage: (-G.I()).primitive_part() 1 sage: G.U().primitive_part() U sage: (-G.S()).primitive_part() S sage: el = (G.V(2)*G.V(3)).acton(G.U()^6) sage: el.primitive_part() (-T*S*T^2*S*T*S*T) * (U) * (-T*S*T^2*S*T*S*T)^(-1) sage: el.primitive_part() == el.primitive_part(method='block') True sage: G.T().primitive_part() (T^(-1)*S) * (V(6)) * (T^(-1)*S)^(-1) sage: G.T().primitive_part(method='block') (T^(-1)) * (V(1)) * (T^(-1))^(-1) sage: G.V(2).acton(G.T(-3)).primitive_part() == G.V(2).acton(G.T(-3)).primitive_part(method='block') True sage: (-G.V(2)).primitive_part() == (-G.V(2)).primitive_part(method='block') True sage: el = -G.V(2)^3*G.V(6)^2*G.V(3) sage: el.primitive_part() == el.primitive_part(method='block') True sage: el = (G.U()^4*G.S()*G.V(2)).acton(-G.V(2)^3*G.V(6)^2*G.V(3)) sage: el.primitive_part() == el.primitive_part(method='block') True sage: el=G.V(1)^5*G.V(2)*G.V(3)^3 sage: el.primitive_part() == el.primitive_part(method='block') True sage: G.element_repr_method("default")
>>> from sage.all import * >>> from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup >>> G = HeckeTriangleGroup(n=Integer(7)) >>> G.element_repr_method("block") >>> G.T().primitive_part() (T^(-1)*S) * (V(6)) * (T^(-1)*S)^(-1) >>> G.V(Integer(2)).acton(G.T(-Integer(3))).primitive_part() (T) * (V(6)) * (T)^(-1) >>> (-G.V(Integer(2))).primitive_part() (T*S*T) * (V(2)) * (T*S*T)^(-1) >>> (-G.V(Integer(2))**Integer(3)*G.V(Integer(6))**Integer(2)*G.V(Integer(3))).primitive_part() V(2)^3*V(6)^2*V(3) >>> (G.U()**Integer(4)*G.S()*G.V(Integer(2))).acton(-G.V(Integer(2))**Integer(3)*G.V(Integer(6))**Integer(2)*G.V(Integer(3))).primitive_part() (T*S*T*S*T*S*T^2*S*T) * (V(2)^3*V(6)^2*V(3)) * (T*S*T*S*T*S*T^2*S*T)^(-1) >>> (G.V(Integer(1))**Integer(5)*G.V(Integer(2))*G.V(Integer(3))**Integer(3)).primitive_part() (T^6*S*T) * (V(3)^3*V(1)^5*V(2)) * (T^6*S*T)^(-1) >>> (G.V(Integer(2))*G.V(Integer(3))).acton(G.U()**Integer(6)).primitive_part() (-T*S*T^2*S*T*S*T) * (U) * (-T*S*T^2*S*T*S*T)^(-1) >>> (-G.I()).primitive_part() 1 >>> G.U().primitive_part() U >>> (-G.S()).primitive_part() S >>> el = (G.V(Integer(2))*G.V(Integer(3))).acton(G.U()**Integer(6)) >>> el.primitive_part() (-T*S*T^2*S*T*S*T) * (U) * (-T*S*T^2*S*T*S*T)^(-1) >>> el.primitive_part() == el.primitive_part(method='block') True >>> G.T().primitive_part() (T^(-1)*S) * (V(6)) * (T^(-1)*S)^(-1) >>> G.T().primitive_part(method='block') (T^(-1)) * (V(1)) * (T^(-1))^(-1) >>> G.V(Integer(2)).acton(G.T(-Integer(3))).primitive_part() == G.V(Integer(2)).acton(G.T(-Integer(3))).primitive_part(method='block') True >>> (-G.V(Integer(2))).primitive_part() == (-G.V(Integer(2))).primitive_part(method='block') True >>> el = -G.V(Integer(2))**Integer(3)*G.V(Integer(6))**Integer(2)*G.V(Integer(3)) >>> el.primitive_part() == el.primitive_part(method='block') True >>> el = (G.U()**Integer(4)*G.S()*G.V(Integer(2))).acton(-G.V(Integer(2))**Integer(3)*G.V(Integer(6))**Integer(2)*G.V(Integer(3))) >>> el.primitive_part() == el.primitive_part(method='block') True >>> el=G.V(Integer(1))**Integer(5)*G.V(Integer(2))*G.V(Integer(3))**Integer(3) >>> el.primitive_part() == el.primitive_part(method='block') True >>> G.element_repr_method("default")
from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup G = HeckeTriangleGroup(n=7) G.element_repr_method("block") G.T().primitive_part() G.V(2).acton(G.T(-3)).primitive_part() (-G.V(2)).primitive_part() (-G.V(2)^3*G.V(6)^2*G.V(3)).primitive_part() (G.U()^4*G.S()*G.V(2)).acton(-G.V(2)^3*G.V(6)^2*G.V(3)).primitive_part() (G.V(1)^5*G.V(2)*G.V(3)^3).primitive_part() (G.V(2)*G.V(3)).acton(G.U()^6).primitive_part() (-G.I()).primitive_part() G.U().primitive_part() (-G.S()).primitive_part() el = (G.V(2)*G.V(3)).acton(G.U()^6) el.primitive_part() el.primitive_part() == el.primitive_part(method='block') G.T().primitive_part() G.T().primitive_part(method='block') G.V(2).acton(G.T(-3)).primitive_part() == G.V(2).acton(G.T(-3)).primitive_part(method='block') (-G.V(2)).primitive_part() == (-G.V(2)).primitive_part(method='block') el = -G.V(2)^3*G.V(6)^2*G.V(3) el.primitive_part() == el.primitive_part(method='block') el = (G.U()^4*G.S()*G.V(2)).acton(-G.V(2)^3*G.V(6)^2*G.V(3)) el.primitive_part() == el.primitive_part(method='block') el=G.V(1)^5*G.V(2)*G.V(3)^3 el.primitive_part() == el.primitive_part(method='block') G.element_repr_method("default")
- primitive_power(method='cf')[source]¶
Return the primitive power of
self
. I.e. an integerpower
such thatself = sign * primitive_part^power
, wheresign = self.sign()
andprimitive_part = self.primitive_part(method)
.Warning: For the parabolic case the sign depends on the method: The “cf” method may return a negative power but the “block” method never will.
Warning: The case
n=infinity
is not verified at all and probably wrong!INPUT:
method
– the method used to determine the primitive power (seeprimitive_representative()
), default:'cf'
. The parameter is ignored for elliptic elements or +- the identity.
OUTPUT:
An integer. For +- the identity element
0
is returned, for parabolic and hyperbolic elements a positive integer. And for elliptic elements a (nonzero) integer with minimal absolute value such thatprimitive_part^power
still has a positive sign.EXAMPLES:
sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup sage: G = HeckeTriangleGroup(n=7) sage: G.T().primitive_power() -1 sage: G.V(2).acton(G.T(-3)).primitive_power() 3 sage: (-G.V(2)^2).primitive_power() 2 sage: el = (-G.V(2)*G.V(6)*G.V(3)*G.V(2)*G.V(6)*G.V(3)) sage: el.primitive_power() 2 sage: (G.U()^4*G.S()*G.V(2)).acton(el).primitive_power() 2 sage: (G.V(2)*G.V(3)).acton(G.U()^6).primitive_power() -1 sage: G.V(2).acton(G.T(-3)).primitive_power() == G.V(2).acton(G.T(-3)).primitive_power(method='block') True sage: (-G.I()).primitive_power() 0 sage: G.U().primitive_power() 1 sage: (-G.S()).primitive_power() 1 sage: el = (G.V(2)*G.V(3)).acton(G.U()^6) sage: el.primitive_power() -1 sage: el.primitive_power() == (-el).primitive_power() True sage: (G.U()^(-6)).primitive_power() 1 sage: G = HeckeTriangleGroup(n=8) sage: (G.U()^4).primitive_power() 4 sage: (G.U()^(-4)).primitive_power() 4
>>> from sage.all import * >>> from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup >>> G = HeckeTriangleGroup(n=Integer(7)) >>> G.T().primitive_power() -1 >>> G.V(Integer(2)).acton(G.T(-Integer(3))).primitive_power() 3 >>> (-G.V(Integer(2))**Integer(2)).primitive_power() 2 >>> el = (-G.V(Integer(2))*G.V(Integer(6))*G.V(Integer(3))*G.V(Integer(2))*G.V(Integer(6))*G.V(Integer(3))) >>> el.primitive_power() 2 >>> (G.U()**Integer(4)*G.S()*G.V(Integer(2))).acton(el).primitive_power() 2 >>> (G.V(Integer(2))*G.V(Integer(3))).acton(G.U()**Integer(6)).primitive_power() -1 >>> G.V(Integer(2)).acton(G.T(-Integer(3))).primitive_power() == G.V(Integer(2)).acton(G.T(-Integer(3))).primitive_power(method='block') True >>> (-G.I()).primitive_power() 0 >>> G.U().primitive_power() 1 >>> (-G.S()).primitive_power() 1 >>> el = (G.V(Integer(2))*G.V(Integer(3))).acton(G.U()**Integer(6)) >>> el.primitive_power() -1 >>> el.primitive_power() == (-el).primitive_power() True >>> (G.U()**(-Integer(6))).primitive_power() 1 >>> G = HeckeTriangleGroup(n=Integer(8)) >>> (G.U()**Integer(4)).primitive_power() 4 >>> (G.U()**(-Integer(4))).primitive_power() 4
from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup G = HeckeTriangleGroup(n=7) G.T().primitive_power() G.V(2).acton(G.T(-3)).primitive_power() (-G.V(2)^2).primitive_power() el = (-G.V(2)*G.V(6)*G.V(3)*G.V(2)*G.V(6)*G.V(3)) el.primitive_power() (G.U()^4*G.S()*G.V(2)).acton(el).primitive_power() (G.V(2)*G.V(3)).acton(G.U()^6).primitive_power() G.V(2).acton(G.T(-3)).primitive_power() == G.V(2).acton(G.T(-3)).primitive_power(method='block') (-G.I()).primitive_power() G.U().primitive_power() (-G.S()).primitive_power() el = (G.V(2)*G.V(3)).acton(G.U()^6) el.primitive_power() el.primitive_power() == (-el).primitive_power() (G.U()^(-6)).primitive_power() G = HeckeTriangleGroup(n=8) (G.U()^4).primitive_power() (G.U()^(-4)).primitive_power()
- primitive_representative(method='block')[source]¶
Return a tuple
(P, R)
which gives the decomposition of the primitive part ofself
, namelyR*P*R.inverse()
into a specific representativeP
and the corresponding conjugation matrixR
(the result depends on the method used).Together they describe the primitive part of
self
. I.e. an element which is equal toself
up to a sign after taking the appropriate power.See
_primitive_block_decomposition_data()
for a description about the representative in case the default methodblock
is used. Also seeprimitive_part()
to construct the primitive part ofself
.Warning: The case
n=infinity
is not verified at all and probably wrong!INPUT:
method
–'block'
(default) or'cf'
. The method used to determineP
andR
. Ifself
is elliptic, this parameter is ignored, and ifself
is +- the identity then theblock
method is used.With
'block'
the decomposition described in_primitive_block_decomposition_data()
is used.With
'cf'
a reduced representative from the lambda-CF ofself
is used (seecontinued_fraction()
). In that caseP
corresponds to the period andR
to the preperiod.
OUTPUT:
A tuple
(P, R)
of group elements such thatR*P*R.inverse()
is a/the primitive part ofself
EXAMPLES:
sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup sage: G = HeckeTriangleGroup(n=7) sage: G.element_repr_method("basic") sage: el = G.T().primitive_representative(method='cf') sage: el (S*T^(-1)*S*T^(-1)*S*T*S, S*T*S) sage: (el[0]).is_primitive() True sage: el = G.V(2).acton(G.T(-3)).primitive_representative(method='cf') sage: el (-T*S*T^(-1)*S*T^(-1), 1) sage: (el[0]).is_primitive() True sage: el = (-G.V(2)).primitive_representative(method='cf') sage: el (T^2*S, T*S) sage: (el[0]).is_primitive() True sage: el = (-G.V(2)^3*G.V(6)^2*G.V(3)).primitive_representative(method='cf') sage: el (-T^2*S*T^2*S*T*S*T^(-2)*S*T*S*T*S*T^2*S, T*S) sage: (el[0]).is_primitive() True sage: el = (G.U()^4*G.S()*G.V(2)).acton(-G.V(2)^3*G.V(6)^2*G.V(3)).primitive_representative(method='cf') sage: el (-T^2*S*T^2*S*T^2*S*T*S*T^(-2)*S*T*S*T*S, T*S*T*S*T*S*T^2*S) sage: (el[0]).is_primitive() True sage: el = (G.V(1)^5*G.V(2)*G.V(3)^3).primitive_representative(method='cf') sage: el (T^2*S*T*S*T^2*S*T*S*T^2*S*T*S*T^7*S, T^6*S) sage: (el[0]).is_primitive() True sage: el = (G.V(2)*G.V(3)).acton(G.U()^6).primitive_representative(method='cf') sage: el (T*S, -T*S*T^2*S*T*S*T) sage: (el[0]).is_primitive() True sage: G.element_repr_method("block") sage: el = G.T().primitive_representative() sage: (el[0]).is_primitive() True sage: el = G.V(2).acton(G.T(-3)).primitive_representative() sage: el ((-S*T^(-1)*S) * (V(6)) * (-S*T^(-1)*S)^(-1), (T^(-1)) * (V(1)) * (T^(-1))^(-1)) sage: (el[0]).is_primitive() True sage: el = (-G.V(2)).primitive_representative() sage: el ((T*S*T) * (V(2)) * (T*S*T)^(-1), (T*S*T) * (V(2)) * (T*S*T)^(-1)) sage: (el[0]).is_primitive() True sage: el = (-G.V(2)^3*G.V(6)^2*G.V(3)).primitive_representative() sage: el (V(2)^3*V(6)^2*V(3), 1) sage: (el[0]).is_primitive() True sage: el = (G.U()^4*G.S()*G.V(2)).acton(-G.V(2)^3*G.V(6)^2*G.V(3)).primitive_representative() sage: el (V(2)^3*V(6)^2*V(3), (T*S*T*S*T*S*T) * (V(2)*V(4)) * (T*S*T*S*T*S*T)^(-1)) sage: (el[0]).is_primitive() True sage: el = (G.V(1)^5*G.V(2)*G.V(3)^3).primitive_representative() sage: el (V(3)^3*V(1)^5*V(2), (T^6*S*T) * (V(1)^5*V(2)) * (T^6*S*T)^(-1)) sage: (el[0]).is_primitive() True sage: G.element_repr_method("default") sage: el = G.I().primitive_representative() sage: el ( [1 0] [1 0] [0 1], [0 1] ) sage: (el[0]).is_primitive() True sage: el = G.U().primitive_representative() sage: el ( [lam -1] [1 0] [ 1 0], [0 1] ) sage: (el[0]).is_primitive() True sage: el = (-G.S()).primitive_representative() sage: el ( [ 0 -1] [-1 0] [ 1 0], [ 0 -1] ) sage: (el[0]).is_primitive() True sage: el = (G.V(2)*G.V(3)).acton(G.U()^6).primitive_representative() sage: el ( [lam -1] [-2*lam^2 - 2*lam + 2 -2*lam^2 - 2*lam + 1] [ 1 0], [ -2*lam^2 + 1 -2*lam^2 - lam + 2] ) sage: (el[0]).is_primitive() True
>>> from sage.all import * >>> from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup >>> G = HeckeTriangleGroup(n=Integer(7)) >>> G.element_repr_method("basic") >>> el = G.T().primitive_representative(method='cf') >>> el (S*T^(-1)*S*T^(-1)*S*T*S, S*T*S) >>> (el[Integer(0)]).is_primitive() True >>> el = G.V(Integer(2)).acton(G.T(-Integer(3))).primitive_representative(method='cf') >>> el (-T*S*T^(-1)*S*T^(-1), 1) >>> (el[Integer(0)]).is_primitive() True >>> el = (-G.V(Integer(2))).primitive_representative(method='cf') >>> el (T^2*S, T*S) >>> (el[Integer(0)]).is_primitive() True >>> el = (-G.V(Integer(2))**Integer(3)*G.V(Integer(6))**Integer(2)*G.V(Integer(3))).primitive_representative(method='cf') >>> el (-T^2*S*T^2*S*T*S*T^(-2)*S*T*S*T*S*T^2*S, T*S) >>> (el[Integer(0)]).is_primitive() True >>> el = (G.U()**Integer(4)*G.S()*G.V(Integer(2))).acton(-G.V(Integer(2))**Integer(3)*G.V(Integer(6))**Integer(2)*G.V(Integer(3))).primitive_representative(method='cf') >>> el (-T^2*S*T^2*S*T^2*S*T*S*T^(-2)*S*T*S*T*S, T*S*T*S*T*S*T^2*S) >>> (el[Integer(0)]).is_primitive() True >>> el = (G.V(Integer(1))**Integer(5)*G.V(Integer(2))*G.V(Integer(3))**Integer(3)).primitive_representative(method='cf') >>> el (T^2*S*T*S*T^2*S*T*S*T^2*S*T*S*T^7*S, T^6*S) >>> (el[Integer(0)]).is_primitive() True >>> el = (G.V(Integer(2))*G.V(Integer(3))).acton(G.U()**Integer(6)).primitive_representative(method='cf') >>> el (T*S, -T*S*T^2*S*T*S*T) >>> (el[Integer(0)]).is_primitive() True >>> G.element_repr_method("block") >>> el = G.T().primitive_representative() >>> (el[Integer(0)]).is_primitive() True >>> el = G.V(Integer(2)).acton(G.T(-Integer(3))).primitive_representative() >>> el ((-S*T^(-1)*S) * (V(6)) * (-S*T^(-1)*S)^(-1), (T^(-1)) * (V(1)) * (T^(-1))^(-1)) >>> (el[Integer(0)]).is_primitive() True >>> el = (-G.V(Integer(2))).primitive_representative() >>> el ((T*S*T) * (V(2)) * (T*S*T)^(-1), (T*S*T) * (V(2)) * (T*S*T)^(-1)) >>> (el[Integer(0)]).is_primitive() True >>> el = (-G.V(Integer(2))**Integer(3)*G.V(Integer(6))**Integer(2)*G.V(Integer(3))).primitive_representative() >>> el (V(2)^3*V(6)^2*V(3), 1) >>> (el[Integer(0)]).is_primitive() True >>> el = (G.U()**Integer(4)*G.S()*G.V(Integer(2))).acton(-G.V(Integer(2))**Integer(3)*G.V(Integer(6))**Integer(2)*G.V(Integer(3))).primitive_representative() >>> el (V(2)^3*V(6)^2*V(3), (T*S*T*S*T*S*T) * (V(2)*V(4)) * (T*S*T*S*T*S*T)^(-1)) >>> (el[Integer(0)]).is_primitive() True >>> el = (G.V(Integer(1))**Integer(5)*G.V(Integer(2))*G.V(Integer(3))**Integer(3)).primitive_representative() >>> el (V(3)^3*V(1)^5*V(2), (T^6*S*T) * (V(1)^5*V(2)) * (T^6*S*T)^(-1)) >>> (el[Integer(0)]).is_primitive() True >>> G.element_repr_method("default") >>> el = G.I().primitive_representative() >>> el ( [1 0] [1 0] [0 1], [0 1] ) >>> (el[Integer(0)]).is_primitive() True >>> el = G.U().primitive_representative() >>> el ( [lam -1] [1 0] [ 1 0], [0 1] ) >>> (el[Integer(0)]).is_primitive() True >>> el = (-G.S()).primitive_representative() >>> el ( [ 0 -1] [-1 0] [ 1 0], [ 0 -1] ) >>> (el[Integer(0)]).is_primitive() True >>> el = (G.V(Integer(2))*G.V(Integer(3))).acton(G.U()**Integer(6)).primitive_representative() >>> el ( [lam -1] [-2*lam^2 - 2*lam + 2 -2*lam^2 - 2*lam + 1] [ 1 0], [ -2*lam^2 + 1 -2*lam^2 - lam + 2] ) >>> (el[Integer(0)]).is_primitive() True
from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup G = HeckeTriangleGroup(n=7) G.element_repr_method("basic") el = G.T().primitive_representative(method='cf') el (el[0]).is_primitive() el = G.V(2).acton(G.T(-3)).primitive_representative(method='cf') el (el[0]).is_primitive() el = (-G.V(2)).primitive_representative(method='cf') el (el[0]).is_primitive() el = (-G.V(2)^3*G.V(6)^2*G.V(3)).primitive_representative(method='cf') el (el[0]).is_primitive() el = (G.U()^4*G.S()*G.V(2)).acton(-G.V(2)^3*G.V(6)^2*G.V(3)).primitive_representative(method='cf') el (el[0]).is_primitive() el = (G.V(1)^5*G.V(2)*G.V(3)^3).primitive_representative(method='cf') el (el[0]).is_primitive() el = (G.V(2)*G.V(3)).acton(G.U()^6).primitive_representative(method='cf') el (el[0]).is_primitive() G.element_repr_method("block") el = G.T().primitive_representative() (el[0]).is_primitive() el = G.V(2).acton(G.T(-3)).primitive_representative() el (el[0]).is_primitive() el = (-G.V(2)).primitive_representative() el (el[0]).is_primitive() el = (-G.V(2)^3*G.V(6)^2*G.V(3)).primitive_representative() el (el[0]).is_primitive() el = (G.U()^4*G.S()*G.V(2)).acton(-G.V(2)^3*G.V(6)^2*G.V(3)).primitive_representative() el (el[0]).is_primitive() el = (G.V(1)^5*G.V(2)*G.V(3)^3).primitive_representative() el (el[0]).is_primitive() G.element_repr_method("default") el = G.I().primitive_representative() el (el[0]).is_primitive() el = G.U().primitive_representative() el (el[0]).is_primitive() el = (-G.S()).primitive_representative() el (el[0]).is_primitive() el = (G.V(2)*G.V(3)).acton(G.U()^6).primitive_representative() el (el[0]).is_primitive()
- rational_period_function(k)[source]¶
The method assumes that
self
is hyperbolic.Return the rational period function of weight
k
for the primitive conjugacy class ofself
.A \(rational period function\) of weight
k
is a rational functionq
which satisfies:q + q|S == 0
andq + q|U + q|U^2 + ... + q|U^(n-1) == 0
, whereS = self.parent().S()
,U = self.parent().U()
and|
is the usual \(slash-operator\) of weight \(k\). Note that ifk < 0
thenq
is a polynomial.This method returns a very basic rational period function associated with the primitive conjugacy class of
self
. The (strong) expectation is that all rational period functions are formed by linear combinations of such functions.There is also a close relation with modular integrals of weight
2-k
and sometimes2-k
is used for the weight instead ofk
.Warning: The case
n=infinity
is not verified at all and probably wrong!EXAMPLES:
sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup sage: G = HeckeTriangleGroup(n=5) sage: S = G.S() sage: U = G.U() sage: def is_rpf(f, k=None): ....: if not f + S.slash(f, k=k) == 0: ....: return False ....: if not sum([(U^m).slash(f, k=k) for m in range(G.n())]) == 0: ....: return False ....: return True sage: z = PolynomialRing(G.base_ring(), 'z').gen() sage: [is_rpf(1 - z^(-k), k=k) for k in range(-6, 6, 2)] # long time [True, True, True, True, True, True] sage: [is_rpf(1/z, k=k) for k in range(-6, 6, 2)] [False, False, False, False, True, False] sage: el = G.V(2) sage: el.is_hecke_symmetric() False sage: rpf = el.rational_period_function(-4) sage: is_rpf(rpf) == is_rpf(rpf, k=-4) True sage: is_rpf(rpf) True sage: is_rpf(rpf, k=-6) False sage: is_rpf(rpf, k=2) False sage: rpf -lam*z^4 + lam sage: rpf = el.rational_period_function(-2) sage: is_rpf(rpf) True sage: rpf (lam + 1)*z^2 - lam - 1 sage: el.rational_period_function(0) == 0 True sage: rpf = el.rational_period_function(2) sage: is_rpf(rpf) True sage: rpf ((lam + 1)*z^2 - lam - 1)/(lam*z^4 + (-lam - 2)*z^2 + lam) sage: el = G.V(3)*G.V(2)^(-1)*G.V(1)*G.V(6) sage: el.is_hecke_symmetric() False sage: rpf = el.rational_period_function(-6) sage: is_rpf(rpf) True sage: rpf (68*lam + 44)*z^6 + (-24*lam - 12)*z^4 + (24*lam + 12)*z^2 - 68*lam - 44 sage: rpf = el.rational_period_function(-2) sage: is_rpf(rpf) True sage: rpf (4*lam + 4)*z^2 - 4*lam - 4 sage: el.rational_period_function(0) == 0 True sage: rpf = el.rational_period_function(2) sage: is_rpf(rpf) == is_rpf(rpf, k=2) True sage: is_rpf(rpf) True sage: rpf.denominator() (8*lam + 5)*z^8 + (-94*lam - 58)*z^6 + (199*lam + 124)*z^4 + (-94*lam - 58)*z^2 + 8*lam + 5 sage: el = G.V(2)*G.V(3) sage: el.is_hecke_symmetric() True sage: el.rational_period_function(-4) == 0 True sage: rpf = el.rational_period_function(-2) sage: is_rpf(rpf) True sage: rpf (8*lam + 4)*z^2 - 8*lam - 4 sage: el.rational_period_function(0) == 0 True sage: rpf = el.rational_period_function(2) sage: is_rpf(rpf) True sage: rpf.denominator() (144*lam + 89)*z^8 + (-618*lam - 382)*z^6 + (951*lam + 588)*z^4 + (-618*lam - 382)*z^2 + 144*lam + 89 sage: el.rational_period_function(4) == 0 True
>>> from sage.all import * >>> from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup >>> G = HeckeTriangleGroup(n=Integer(5)) >>> S = G.S() >>> U = G.U() >>> def is_rpf(f, k=None): ... if not f + S.slash(f, k=k) == Integer(0): ... return False ... if not sum([(U**m).slash(f, k=k) for m in range(G.n())]) == Integer(0): ... return False ... return True >>> z = PolynomialRing(G.base_ring(), 'z').gen() >>> [is_rpf(Integer(1) - z**(-k), k=k) for k in range(-Integer(6), Integer(6), Integer(2))] # long time [True, True, True, True, True, True] >>> [is_rpf(Integer(1)/z, k=k) for k in range(-Integer(6), Integer(6), Integer(2))] [False, False, False, False, True, False] >>> el = G.V(Integer(2)) >>> el.is_hecke_symmetric() False >>> rpf = el.rational_period_function(-Integer(4)) >>> is_rpf(rpf) == is_rpf(rpf, k=-Integer(4)) True >>> is_rpf(rpf) True >>> is_rpf(rpf, k=-Integer(6)) False >>> is_rpf(rpf, k=Integer(2)) False >>> rpf -lam*z^4 + lam >>> rpf = el.rational_period_function(-Integer(2)) >>> is_rpf(rpf) True >>> rpf (lam + 1)*z^2 - lam - 1 >>> el.rational_period_function(Integer(0)) == Integer(0) True >>> rpf = el.rational_period_function(Integer(2)) >>> is_rpf(rpf) True >>> rpf ((lam + 1)*z^2 - lam - 1)/(lam*z^4 + (-lam - 2)*z^2 + lam) >>> el = G.V(Integer(3))*G.V(Integer(2))**(-Integer(1))*G.V(Integer(1))*G.V(Integer(6)) >>> el.is_hecke_symmetric() False >>> rpf = el.rational_period_function(-Integer(6)) >>> is_rpf(rpf) True >>> rpf (68*lam + 44)*z^6 + (-24*lam - 12)*z^4 + (24*lam + 12)*z^2 - 68*lam - 44 >>> rpf = el.rational_period_function(-Integer(2)) >>> is_rpf(rpf) True >>> rpf (4*lam + 4)*z^2 - 4*lam - 4 >>> el.rational_period_function(Integer(0)) == Integer(0) True >>> rpf = el.rational_period_function(Integer(2)) >>> is_rpf(rpf) == is_rpf(rpf, k=Integer(2)) True >>> is_rpf(rpf) True >>> rpf.denominator() (8*lam + 5)*z^8 + (-94*lam - 58)*z^6 + (199*lam + 124)*z^4 + (-94*lam - 58)*z^2 + 8*lam + 5 >>> el = G.V(Integer(2))*G.V(Integer(3)) >>> el.is_hecke_symmetric() True >>> el.rational_period_function(-Integer(4)) == Integer(0) True >>> rpf = el.rational_period_function(-Integer(2)) >>> is_rpf(rpf) True >>> rpf (8*lam + 4)*z^2 - 8*lam - 4 >>> el.rational_period_function(Integer(0)) == Integer(0) True >>> rpf = el.rational_period_function(Integer(2)) >>> is_rpf(rpf) True >>> rpf.denominator() (144*lam + 89)*z^8 + (-618*lam - 382)*z^6 + (951*lam + 588)*z^4 + (-618*lam - 382)*z^2 + 144*lam + 89 >>> el.rational_period_function(Integer(4)) == Integer(0) True
from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup G = HeckeTriangleGroup(n=5) S = G.S() U = G.U() def is_rpf(f, k=None): if not f + S.slash(f, k=k) == 0: return False if not sum([(U^m).slash(f, k=k) for m in range(G.n())]) == 0: return False return True z = PolynomialRing(G.base_ring(), 'z').gen() [is_rpf(1 - z^(-k), k=k) for k in range(-6, 6, 2)] # long time [is_rpf(1/z, k=k) for k in range(-6, 6, 2)] el = G.V(2) el.is_hecke_symmetric() rpf = el.rational_period_function(-4) is_rpf(rpf) == is_rpf(rpf, k=-4) is_rpf(rpf) is_rpf(rpf, k=-6) is_rpf(rpf, k=2) rpf rpf = el.rational_period_function(-2) is_rpf(rpf) rpf el.rational_period_function(0) == 0 rpf = el.rational_period_function(2) is_rpf(rpf) rpf el = G.V(3)*G.V(2)^(-1)*G.V(1)*G.V(6) el.is_hecke_symmetric() rpf = el.rational_period_function(-6) is_rpf(rpf) rpf rpf = el.rational_period_function(-2) is_rpf(rpf) rpf el.rational_period_function(0) == 0 rpf = el.rational_period_function(2) is_rpf(rpf) == is_rpf(rpf, k=2) is_rpf(rpf) rpf.denominator() el = G.V(2)*G.V(3) el.is_hecke_symmetric() el.rational_period_function(-4) == 0 rpf = el.rational_period_function(-2) is_rpf(rpf) rpf el.rational_period_function(0) == 0 rpf = el.rational_period_function(2) is_rpf(rpf) rpf.denominator() el.rational_period_function(4) == 0
- reduce(primitive=True)[source]¶
Return a reduced version of
self
(with the same the same fixed points). Also seeis_reduced()
.If
self
is elliptic (or +- the identity) the result is never reduced (by definition). Instead a more canonical conjugation representative ofself
(resp. it’s primitive part) is chosen.Warning: The case
n=infinity
is not verified at all and probably wrong!INPUT:
primitive
– ifTrue
(default) then a primitive representative forself
is returned
EXAMPLES:
sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup sage: G = HeckeTriangleGroup(n=7) sage: print(G.T().reduce().string_repr("basic")) S*T^(-1)*S*T^(-1)*S*T*S sage: G.T().reduce().is_reduced(require_hyperbolic=False) True sage: print(G.V(2).acton(-G.T(-3)).reduce().string_repr("basic")) -T*S*T^(-1)*S*T^(-1) sage: print(G.V(2).acton(-G.T(-3)).reduce(primitive=False).string_repr("basic")) T*S*T^(-3)*S*T^(-1) sage: print((-G.V(2)).reduce().string_repr("basic")) T^2*S sage: (-G.V(2)).reduce().is_reduced() True sage: print((-G.V(2)^3*G.V(6)^2*G.V(3)).reduce().string_repr("block")) (-S*T^(-1)) * (V(2)^3*V(6)^2*V(3)) * (-S*T^(-1))^(-1) sage: (-G.V(2)^3*G.V(6)^2*G.V(3)).reduce().is_reduced() True sage: print((-G.I()).reduce().string_repr("block")) 1 sage: print(G.U().reduce().string_repr("block")) U sage: print((-G.S()).reduce().string_repr("block")) S sage: print((G.V(2)*G.V(3)).acton(G.U()^6).reduce().string_repr("block")) U sage: print((G.V(2)*G.V(3)).acton(G.U()^6).reduce(primitive=False).string_repr("block")) -U^(-1)
>>> from sage.all import * >>> from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup >>> G = HeckeTriangleGroup(n=Integer(7)) >>> print(G.T().reduce().string_repr("basic")) S*T^(-1)*S*T^(-1)*S*T*S >>> G.T().reduce().is_reduced(require_hyperbolic=False) True >>> print(G.V(Integer(2)).acton(-G.T(-Integer(3))).reduce().string_repr("basic")) -T*S*T^(-1)*S*T^(-1) >>> print(G.V(Integer(2)).acton(-G.T(-Integer(3))).reduce(primitive=False).string_repr("basic")) T*S*T^(-3)*S*T^(-1) >>> print((-G.V(Integer(2))).reduce().string_repr("basic")) T^2*S >>> (-G.V(Integer(2))).reduce().is_reduced() True >>> print((-G.V(Integer(2))**Integer(3)*G.V(Integer(6))**Integer(2)*G.V(Integer(3))).reduce().string_repr("block")) (-S*T^(-1)) * (V(2)^3*V(6)^2*V(3)) * (-S*T^(-1))^(-1) >>> (-G.V(Integer(2))**Integer(3)*G.V(Integer(6))**Integer(2)*G.V(Integer(3))).reduce().is_reduced() True >>> print((-G.I()).reduce().string_repr("block")) 1 >>> print(G.U().reduce().string_repr("block")) U >>> print((-G.S()).reduce().string_repr("block")) S >>> print((G.V(Integer(2))*G.V(Integer(3))).acton(G.U()**Integer(6)).reduce().string_repr("block")) U >>> print((G.V(Integer(2))*G.V(Integer(3))).acton(G.U()**Integer(6)).reduce(primitive=False).string_repr("block")) -U^(-1)
from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup G = HeckeTriangleGroup(n=7) print(G.T().reduce().string_repr("basic")) G.T().reduce().is_reduced(require_hyperbolic=False) print(G.V(2).acton(-G.T(-3)).reduce().string_repr("basic")) print(G.V(2).acton(-G.T(-3)).reduce(primitive=False).string_repr("basic")) print((-G.V(2)).reduce().string_repr("basic")) (-G.V(2)).reduce().is_reduced() print((-G.V(2)^3*G.V(6)^2*G.V(3)).reduce().string_repr("block")) (-G.V(2)^3*G.V(6)^2*G.V(3)).reduce().is_reduced() print((-G.I()).reduce().string_repr("block")) print(G.U().reduce().string_repr("block")) print((-G.S()).reduce().string_repr("block")) print((G.V(2)*G.V(3)).acton(G.U()^6).reduce().string_repr("block")) print((G.V(2)*G.V(3)).acton(G.U()^6).reduce(primitive=False).string_repr("block"))
- reduced_elements()[source]¶
Return the cycle of reduced elements in the (primitive) conjugacy class of
self
.I.e. the set (cycle) of all reduced elements which are conjugate to
self.primitive_part()
. E.g.self.primitive_representative().reduce()
.Also see
is_reduced()
. In particular the result of this method only depends on the (primitive) conjugacy class ofself
.The method assumes that
self
is hyperbolic or parabolic.Warning: The case
n=infinity
is not verified at all and probably wrong!EXAMPLES:
sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup sage: G = HeckeTriangleGroup(n=5) sage: G.element_repr_method("basic") sage: el = G.V(1) sage: el.continued_fraction() ((0, 1), (1, 1, 2)) sage: R = el.reduced_elements() sage: R [T*S*T*S*T^2*S, T*S*T^2*S*T*S, -T*S*T^(-1)*S*T^(-1)] sage: [v.continued_fraction() for v in R] [((), (1, 1, 2)), ((), (1, 2, 1)), ((), (2, 1, 1))] sage: el = G.V(3)*G.V(2)^(-1)*G.V(1)*G.V(6) sage: el.continued_fraction() ((1,), (3,)) sage: R = el.reduced_elements() sage: [v.continued_fraction() for v in R] [((), (3,))] sage: G.element_repr_method("default")
>>> from sage.all import * >>> from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup >>> G = HeckeTriangleGroup(n=Integer(5)) >>> G.element_repr_method("basic") >>> el = G.V(Integer(1)) >>> el.continued_fraction() ((0, 1), (1, 1, 2)) >>> R = el.reduced_elements() >>> R [T*S*T*S*T^2*S, T*S*T^2*S*T*S, -T*S*T^(-1)*S*T^(-1)] >>> [v.continued_fraction() for v in R] [((), (1, 1, 2)), ((), (1, 2, 1)), ((), (2, 1, 1))] >>> el = G.V(Integer(3))*G.V(Integer(2))**(-Integer(1))*G.V(Integer(1))*G.V(Integer(6)) >>> el.continued_fraction() ((1,), (3,)) >>> R = el.reduced_elements() >>> [v.continued_fraction() for v in R] [((), (3,))] >>> G.element_repr_method("default")
from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup G = HeckeTriangleGroup(n=5) G.element_repr_method("basic") el = G.V(1) el.continued_fraction() R = el.reduced_elements() R [v.continued_fraction() for v in R] el = G.V(3)*G.V(2)^(-1)*G.V(1)*G.V(6) el.continued_fraction() R = el.reduced_elements() [v.continued_fraction() for v in R] G.element_repr_method("default")
- root_extension_embedding(K=None)[source]¶
Return the correct embedding from the root extension field to
K
.INPUT:
K
– a field to which we want the (correct) embedding. IfK=None
(default), thenAlgebraicField()
is used for elliptic elements andAlgebraicRealField()
otherwise.
EXAMPLES:
sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup sage: G = HeckeTriangleGroup(n=infinity) sage: fp = (-G.S()).fixed_points()[0] sage: alg_fp = (-G.S()).root_extension_embedding()(fp) sage: alg_fp 1*I sage: alg_fp == (-G.S()).fixed_points(embedded=True)[0] True sage: fp = (-G.V(2)).fixed_points()[1] sage: alg_fp = (-G.V(2)).root_extension_embedding()(fp) sage: alg_fp -1.732050807568...? sage: alg_fp == (-G.V(2)).fixed_points(embedded=True)[1] True sage: fp = (-G.V(2)).fixed_points()[0] sage: alg_fp = (-G.V(2)).root_extension_embedding()(fp) sage: alg_fp 1.732050807568...? sage: alg_fp == (-G.V(2)).fixed_points(embedded=True)[0] True sage: G = HeckeTriangleGroup(n=7) sage: fp = (-G.S()).fixed_points()[1] sage: alg_fp = (-G.S()).root_extension_embedding()(fp) sage: alg_fp 0.?... - 1.000000000000...?*I sage: alg_fp == (-G.S()).fixed_points(embedded=True)[1] True sage: fp = (-G.U()^4).fixed_points()[0] sage: alg_fp = (-G.U()^4).root_extension_embedding()(fp) sage: alg_fp 0.9009688679024...? + 0.4338837391175...?*I sage: alg_fp == (-G.U()^4).fixed_points(embedded=True)[0] True sage: (-G.U()^4).root_extension_embedding(CC)(fp) 0.900968867902... + 0.433883739117...*I sage: (-G.U()^4).root_extension_embedding(CC)(fp).parent() Complex Field with 53 bits of precision sage: fp = (-G.V(5)).fixed_points()[1] sage: alg_fp = (-G.V(5)).root_extension_embedding()(fp) sage: alg_fp -0.6671145837954...? sage: alg_fp == (-G.V(5)).fixed_points(embedded=True)[1] True
>>> from sage.all import * >>> from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup >>> G = HeckeTriangleGroup(n=infinity) >>> fp = (-G.S()).fixed_points()[Integer(0)] >>> alg_fp = (-G.S()).root_extension_embedding()(fp) >>> alg_fp 1*I >>> alg_fp == (-G.S()).fixed_points(embedded=True)[Integer(0)] True >>> fp = (-G.V(Integer(2))).fixed_points()[Integer(1)] >>> alg_fp = (-G.V(Integer(2))).root_extension_embedding()(fp) >>> alg_fp -1.732050807568...? >>> alg_fp == (-G.V(Integer(2))).fixed_points(embedded=True)[Integer(1)] True >>> fp = (-G.V(Integer(2))).fixed_points()[Integer(0)] >>> alg_fp = (-G.V(Integer(2))).root_extension_embedding()(fp) >>> alg_fp 1.732050807568...? >>> alg_fp == (-G.V(Integer(2))).fixed_points(embedded=True)[Integer(0)] True >>> G = HeckeTriangleGroup(n=Integer(7)) >>> fp = (-G.S()).fixed_points()[Integer(1)] >>> alg_fp = (-G.S()).root_extension_embedding()(fp) >>> alg_fp 0.?... - 1.000000000000...?*I >>> alg_fp == (-G.S()).fixed_points(embedded=True)[Integer(1)] True >>> fp = (-G.U()**Integer(4)).fixed_points()[Integer(0)] >>> alg_fp = (-G.U()**Integer(4)).root_extension_embedding()(fp) >>> alg_fp 0.9009688679024...? + 0.4338837391175...?*I >>> alg_fp == (-G.U()**Integer(4)).fixed_points(embedded=True)[Integer(0)] True >>> (-G.U()**Integer(4)).root_extension_embedding(CC)(fp) 0.900968867902... + 0.433883739117...*I >>> (-G.U()**Integer(4)).root_extension_embedding(CC)(fp).parent() Complex Field with 53 bits of precision >>> fp = (-G.V(Integer(5))).fixed_points()[Integer(1)] >>> alg_fp = (-G.V(Integer(5))).root_extension_embedding()(fp) >>> alg_fp -0.6671145837954...? >>> alg_fp == (-G.V(Integer(5))).fixed_points(embedded=True)[Integer(1)] True
from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup G = HeckeTriangleGroup(n=infinity) fp = (-G.S()).fixed_points()[0] alg_fp = (-G.S()).root_extension_embedding()(fp) alg_fp alg_fp == (-G.S()).fixed_points(embedded=True)[0] fp = (-G.V(2)).fixed_points()[1] alg_fp = (-G.V(2)).root_extension_embedding()(fp) alg_fp alg_fp == (-G.V(2)).fixed_points(embedded=True)[1] fp = (-G.V(2)).fixed_points()[0] alg_fp = (-G.V(2)).root_extension_embedding()(fp) alg_fp alg_fp == (-G.V(2)).fixed_points(embedded=True)[0] G = HeckeTriangleGroup(n=7) fp = (-G.S()).fixed_points()[1] alg_fp = (-G.S()).root_extension_embedding()(fp) alg_fp alg_fp == (-G.S()).fixed_points(embedded=True)[1] fp = (-G.U()^4).fixed_points()[0] alg_fp = (-G.U()^4).root_extension_embedding()(fp) alg_fp alg_fp == (-G.U()^4).fixed_points(embedded=True)[0] (-G.U()^4).root_extension_embedding(CC)(fp) (-G.U()^4).root_extension_embedding(CC)(fp).parent() fp = (-G.V(5)).fixed_points()[1] alg_fp = (-G.V(5)).root_extension_embedding()(fp) alg_fp alg_fp == (-G.V(5)).fixed_points(embedded=True)[1]
- root_extension_field()[source]¶
Return a field extension which contains the fixed points of
self
. Namely the root extension field of the parent for the discriminant ofself
. Also see the parent methodroot_extension_field(D)
androot_extension_embedding()
(which provides the correct embedding).EXAMPLES:
sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup sage: G = HeckeTriangleGroup(n=infinity) sage: G.V(3).discriminant() 32 sage: G.V(3).root_extension_field() == G.root_extension_field(32) True sage: G.T().root_extension_field() == G.root_extension_field(G.T().discriminant()) == G.base_field() True sage: (G.S()).root_extension_field() == G.root_extension_field(G.S().discriminant()) True sage: G = HeckeTriangleGroup(n=7) sage: D = G.V(3).discriminant() sage: D 4*lam^2 + 4*lam - 4 sage: G.V(3).root_extension_field() == G.root_extension_field(D) True sage: G.U().root_extension_field() == G.root_extension_field(G.U().discriminant()) True sage: G.V(1).root_extension_field() == G.base_field() True
>>> from sage.all import * >>> from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup >>> G = HeckeTriangleGroup(n=infinity) >>> G.V(Integer(3)).discriminant() 32 >>> G.V(Integer(3)).root_extension_field() == G.root_extension_field(Integer(32)) True >>> G.T().root_extension_field() == G.root_extension_field(G.T().discriminant()) == G.base_field() True >>> (G.S()).root_extension_field() == G.root_extension_field(G.S().discriminant()) True >>> G = HeckeTriangleGroup(n=Integer(7)) >>> D = G.V(Integer(3)).discriminant() >>> D 4*lam^2 + 4*lam - 4 >>> G.V(Integer(3)).root_extension_field() == G.root_extension_field(D) True >>> G.U().root_extension_field() == G.root_extension_field(G.U().discriminant()) True >>> G.V(Integer(1)).root_extension_field() == G.base_field() True
from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup G = HeckeTriangleGroup(n=infinity) G.V(3).discriminant() G.V(3).root_extension_field() == G.root_extension_field(32) G.T().root_extension_field() == G.root_extension_field(G.T().discriminant()) == G.base_field() (G.S()).root_extension_field() == G.root_extension_field(G.S().discriminant()) G = HeckeTriangleGroup(n=7) D = G.V(3).discriminant() D G.V(3).root_extension_field() == G.root_extension_field(D) G.U().root_extension_field() == G.root_extension_field(G.U().discriminant()) G.V(1).root_extension_field() == G.base_field()
- sign()[source]¶
Return the sign element/matrix (+- identity) of
self
. The sign is given by the sign of the trace. if the trace is zero it is instead given by the sign of the lower left entry.EXAMPLES:
sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup sage: G = HeckeTriangleGroup(n=7) sage: (-G.T(-1)).sign() [-1 0] [ 0 -1] sage: G.S().sign() [1 0] [0 1] sage: (-G.S()).sign() [-1 0] [ 0 -1] sage: (G.U()^6).sign() [-1 0] [ 0 -1] sage: G = HeckeTriangleGroup(n=8) sage: (G.U()^4).trace() 0 sage: (G.U()^4).sign() [1 0] [0 1] sage: (G.U()^(-4)).sign() [-1 0] [ 0 -1]
>>> from sage.all import * >>> from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup >>> G = HeckeTriangleGroup(n=Integer(7)) >>> (-G.T(-Integer(1))).sign() [-1 0] [ 0 -1] >>> G.S().sign() [1 0] [0 1] >>> (-G.S()).sign() [-1 0] [ 0 -1] >>> (G.U()**Integer(6)).sign() [-1 0] [ 0 -1] >>> G = HeckeTriangleGroup(n=Integer(8)) >>> (G.U()**Integer(4)).trace() 0 >>> (G.U()**Integer(4)).sign() [1 0] [0 1] >>> (G.U()**(-Integer(4))).sign() [-1 0] [ 0 -1]
from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup G = HeckeTriangleGroup(n=7) (-G.T(-1)).sign() G.S().sign() (-G.S()).sign() (G.U()^6).sign() G = HeckeTriangleGroup(n=8) (G.U()^4).trace() (G.U()^4).sign() (G.U()^(-4)).sign()
- simple_elements()[source]¶
Return all simple elements in the primitive conjugacy class of
self
.I.e. the set of all simple elements which are conjugate to
self.primitive_part()
.Also see
is_simple()
. In particular the result of this method only depends on the (primitive) conjugacy class ofself
.The method assumes that
self
is hyperbolic.Warning: The case
n=infinity
is not verified at all and probably wrong!EXAMPLES:
sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup sage: G = HeckeTriangleGroup(n=5) sage: el = G.V(2) sage: el.continued_fraction() ((1,), (2,)) sage: R = el.simple_elements() sage: R [ [lam lam] [ 1 lam] ] sage: R[0].is_simple() True sage: el = G.V(3)*G.V(2)^(-1)*G.V(1)*G.V(6) sage: el.continued_fraction() ((1,), (3,)) sage: R = el.simple_elements() sage: R [ [ 2*lam 2*lam + 1] [ lam 2*lam + 1] [ 1 lam], [ 1 2*lam] ] sage: [v.is_simple() for v in R] [True, True] sage: el = G.V(1)^2*G.V(2)*G.V(4) sage: el.discriminant() 135*lam + 86 sage: R = el.simple_elements() sage: R [ [ 3*lam 3*lam + 2] [8*lam + 3 3*lam + 2] [5*lam + 2 9*lam + 6] [3*lam + 4 6*lam + 3], [ lam + 2 lam], [ lam + 2 4*lam + 1], [2*lam + 1 7*lam + 4] [ lam + 2 7*lam + 2] ]
>>> from sage.all import * >>> from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup >>> G = HeckeTriangleGroup(n=Integer(5)) >>> el = G.V(Integer(2)) >>> el.continued_fraction() ((1,), (2,)) >>> R = el.simple_elements() >>> R [ [lam lam] [ 1 lam] ] >>> R[Integer(0)].is_simple() True >>> el = G.V(Integer(3))*G.V(Integer(2))**(-Integer(1))*G.V(Integer(1))*G.V(Integer(6)) >>> el.continued_fraction() ((1,), (3,)) >>> R = el.simple_elements() >>> R [ [ 2*lam 2*lam + 1] [ lam 2*lam + 1] [ 1 lam], [ 1 2*lam] ] >>> [v.is_simple() for v in R] [True, True] >>> el = G.V(Integer(1))**Integer(2)*G.V(Integer(2))*G.V(Integer(4)) >>> el.discriminant() 135*lam + 86 >>> R = el.simple_elements() >>> R [ [ 3*lam 3*lam + 2] [8*lam + 3 3*lam + 2] [5*lam + 2 9*lam + 6] [3*lam + 4 6*lam + 3], [ lam + 2 lam], [ lam + 2 4*lam + 1], [2*lam + 1 7*lam + 4] [ lam + 2 7*lam + 2] ]
from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup G = HeckeTriangleGroup(n=5) el = G.V(2) el.continued_fraction() R = el.simple_elements() R R[0].is_simple() el = G.V(3)*G.V(2)^(-1)*G.V(1)*G.V(6) el.continued_fraction() R = el.simple_elements() R [v.is_simple() for v in R] el = G.V(1)^2*G.V(2)*G.V(4) el.discriminant() R = el.simple_elements() R
This agrees with the results (p.16) from Culp-Ressler on binary quadratic forms for Hecke triangle groups:
sage: [v.continued_fraction() for v in R] [((1,), (1, 1, 4, 2)), ((3,), (2, 1, 1, 4)), ((2,), (2, 1, 1, 4)), ((1,), (2, 1, 1, 4))]
>>> from sage.all import * >>> [v.continued_fraction() for v in R] [((1,), (1, 1, 4, 2)), ((3,), (2, 1, 1, 4)), ((2,), (2, 1, 1, 4)), ((1,), (2, 1, 1, 4))]
[v.continued_fraction() for v in R]
- simple_fixed_point_set(extended=True)[source]¶
Return a set of all attracting fixed points in the conjugacy class of the primitive part of
self
.If
extended=True
(default) then alsoS.acton(alpha)
are added foralpha
in the set.This is a so called \(irreducible system of poles\) for rational period functions for the parent group. I.e. the fixed points occur as a irreducible part of the nonzero pole set of some rational period function and all pole sets are given as a union of such irreducible systems of poles.
The method assumes that
self
is hyperbolic.Warning: The case
n=infinity
is not verified at all and probably wrong!EXAMPLES:
sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup sage: G = HeckeTriangleGroup(n=5) sage: el = G.V(2) sage: el.simple_fixed_point_set() {1/2*e, (-1/2*lam + 1/2)*e} sage: el.simple_fixed_point_set(extended=False) {1/2*e} sage: el = G.V(3)*G.V(2)^(-1)*G.V(1)*G.V(6) sage: el.simple_fixed_point_set() {(-lam + 3/2)*e + 1/2*lam - 1, (-lam + 3/2)*e - 1/2*lam + 1, 1/2*e - 1/2*lam, 1/2*e + 1/2*lam} sage: el.simple_fixed_point_set(extended=False) {1/2*e - 1/2*lam, 1/2*e + 1/2*lam}
>>> from sage.all import * >>> from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup >>> G = HeckeTriangleGroup(n=Integer(5)) >>> el = G.V(Integer(2)) >>> el.simple_fixed_point_set() {1/2*e, (-1/2*lam + 1/2)*e} >>> el.simple_fixed_point_set(extended=False) {1/2*e} >>> el = G.V(Integer(3))*G.V(Integer(2))**(-Integer(1))*G.V(Integer(1))*G.V(Integer(6)) >>> el.simple_fixed_point_set() {(-lam + 3/2)*e + 1/2*lam - 1, (-lam + 3/2)*e - 1/2*lam + 1, 1/2*e - 1/2*lam, 1/2*e + 1/2*lam} >>> el.simple_fixed_point_set(extended=False) {1/2*e - 1/2*lam, 1/2*e + 1/2*lam}
from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup G = HeckeTriangleGroup(n=5) el = G.V(2) el.simple_fixed_point_set() el.simple_fixed_point_set(extended=False) el = G.V(3)*G.V(2)^(-1)*G.V(1)*G.V(6) el.simple_fixed_point_set() el.simple_fixed_point_set(extended=False)
- slash(f, tau=None, k=None)[source]¶
Return the \(slash-operator\) of weight
k
to applied tof
, evaluated attau
. I.e.(f|_k[self])(tau)
.INPUT:
f
– a function intau
(or an object for which evaluation atself.acton(tau)
makes sensetau
– where to evaluate the result. This should be a valid argument foracton()
.If
tau
is a point ofHyperbolicPlane()
then its coordinates in the upper half plane model are used.Default:
None
in which casef
has to be a rational function / polynomial in one variable and the generator of the polynomial ring is used fortau
. That wayslash
acts on rational functions / polynomials.k
– even integerDefault:
None
in which casef
either has to be a rational function / polynomial in one variable (then -degree is used). Orf
needs to have aweight
attribute which is then used.
EXAMPLES:
sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup sage: from sage.modular.modform_hecketriangle.space import ModularForms sage: G = HeckeTriangleGroup(n=5) sage: E4 = ModularForms(group=G, k=4, ep=1).E4() sage: z = CC(-1/(-1/(2*i+30)-1)) sage: (G.S()).slash(E4, z) 32288.0558881... - 118329.856601...*I sage: (G.V(2)*G.V(3)).slash(E4, z) 32288.0558892... - 118329.856603...*I sage: E4(z) 32288.0558881... - 118329.856601...*I sage: z = HyperbolicPlane().PD().get_point(CC(-I/2 + 1/8)) sage: (G.V(2)*G.V(3)).slash(E4, z) -(21624.437... - 12725.035...*I)/((0.610... + 0.324...*I)*sqrt(5) + 2.720... + 0.648...*I)^4 sage: z = PolynomialRing(G.base_ring(), 'z').gen() sage: rat = z^2 + 1/(z-G.lam()) sage: dr = rat.numerator().degree() - rat.denominator().degree() sage: G.S().slash(rat) == G.S().slash(rat, tau=None, k=-dr) True sage: G.S().slash(rat) (z^6 - lam*z^4 - z^3)/(-lam*z^4 - z^3) sage: G.S().slash(rat, k=0) (z^4 - lam*z^2 - z)/(-lam*z^4 - z^3) sage: G.S().slash(rat, k=-4) (z^8 - lam*z^6 - z^5)/(-lam*z^4 - z^3)
>>> from sage.all import * >>> from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup >>> from sage.modular.modform_hecketriangle.space import ModularForms >>> G = HeckeTriangleGroup(n=Integer(5)) >>> E4 = ModularForms(group=G, k=Integer(4), ep=Integer(1)).E4() >>> z = CC(-Integer(1)/(-Integer(1)/(Integer(2)*i+Integer(30))-Integer(1))) >>> (G.S()).slash(E4, z) 32288.0558881... - 118329.856601...*I >>> (G.V(Integer(2))*G.V(Integer(3))).slash(E4, z) 32288.0558892... - 118329.856603...*I >>> E4(z) 32288.0558881... - 118329.856601...*I >>> z = HyperbolicPlane().PD().get_point(CC(-I/Integer(2) + Integer(1)/Integer(8))) >>> (G.V(Integer(2))*G.V(Integer(3))).slash(E4, z) -(21624.437... - 12725.035...*I)/((0.610... + 0.324...*I)*sqrt(5) + 2.720... + 0.648...*I)^4 >>> z = PolynomialRing(G.base_ring(), 'z').gen() >>> rat = z**Integer(2) + Integer(1)/(z-G.lam()) >>> dr = rat.numerator().degree() - rat.denominator().degree() >>> G.S().slash(rat) == G.S().slash(rat, tau=None, k=-dr) True >>> G.S().slash(rat) (z^6 - lam*z^4 - z^3)/(-lam*z^4 - z^3) >>> G.S().slash(rat, k=Integer(0)) (z^4 - lam*z^2 - z)/(-lam*z^4 - z^3) >>> G.S().slash(rat, k=-Integer(4)) (z^8 - lam*z^6 - z^5)/(-lam*z^4 - z^3)
from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup from sage.modular.modform_hecketriangle.space import ModularForms G = HeckeTriangleGroup(n=5) E4 = ModularForms(group=G, k=4, ep=1).E4() z = CC(-1/(-1/(2*i+30)-1)) (G.S()).slash(E4, z) (G.V(2)*G.V(3)).slash(E4, z) E4(z) z = HyperbolicPlane().PD().get_point(CC(-I/2 + 1/8)) (G.V(2)*G.V(3)).slash(E4, z) z = PolynomialRing(G.base_ring(), 'z').gen() rat = z^2 + 1/(z-G.lam()) dr = rat.numerator().degree() - rat.denominator().degree() G.S().slash(rat) == G.S().slash(rat, tau=None, k=-dr) G.S().slash(rat) G.S().slash(rat, k=0) G.S().slash(rat, k=-4)
- string_repr(method='default')[source]¶
Return a string representation of
self
using the specifiedmethod
. This method is used to representself
. The default representation method can be set for the parent withself.parent().element_repr_method(method)
.INPUT:
method
– one of'default'
– use the usual representation method for matrix group elements'basic'
– the representation is given as a word inS
and powers ofT
. Note: IfS, T
are defined accordingly the output can be used/evaluated directly to recoverself
.'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 asconj
but the conjugation matrix is specified as well. Note: AssumingS, T, U, V
are defined accordingly the output can directly be used/evaluated to recoverself
.
Warning: For
n=infinity
the methodsconj
andblock
are not verified at all and are probably wrong!EXAMPLES:
sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup sage: G = HeckeTriangleGroup(n=5) sage: el1 = -G.I() sage: el2 = G.S()*G.T(3)*G.S()*G.T(-2) sage: el3 = G.V(2)*G.V(3)^2*G.V(4)^3 sage: el4 = G.U()^4 sage: el5 = (G.V(2)*G.T()).acton(-G.S()) sage: el4.string_repr(method='basic') 'S*T^(-1)' sage: G.element_repr_method('default') sage: el1 [-1 0] [ 0 -1] sage: el2 [ -1 2*lam] [ 3*lam -6*lam - 7] sage: el3 [34*lam + 19 5*lam + 4] [27*lam + 18 5*lam + 2] sage: el4 [ 0 -1] [ 1 -lam] sage: el5 [-7*lam - 4 9*lam + 6] [-4*lam - 5 7*lam + 4] sage: G.element_repr_method('basic') sage: el1 -1 sage: el2 S*T^3*S*T^(-2) sage: el3 -T*S*T*S*T^(-1)*S*T^(-2)*S*T^(-4)*S sage: el4 S*T^(-1) sage: el5 T*S*T^2*S*T^(-2)*S*T^(-1) sage: G.element_repr_method('conj') sage: el1 [-1] sage: el2 [-V(4)^2*V(1)^3] sage: el3 [V(3)^2*V(4)^3*V(2)] sage: el4 [-U^(-1)] sage: el5 [-S] sage: G.element_repr_method('block') sage: el1 -1 sage: el2 -(S*T^3) * (V(4)^2*V(1)^3) * (S*T^3)^(-1) sage: el3 (T*S*T) * (V(3)^2*V(4)^3*V(2)) * (T*S*T)^(-1) sage: el4 -U^(-1) sage: el5 -(T*S*T^2) * (S) * (T*S*T^2)^(-1) sage: G.element_repr_method('default') sage: G = HeckeTriangleGroup(n=infinity) sage: el = G.S()*G.T(3)*G.S()*G.T(-2) sage: print(el.string_repr()) [ -1 4] [ 6 -25] sage: print(el.string_repr(method='basic')) S*T^3*S*T^(-2)
>>> from sage.all import * >>> from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup >>> G = HeckeTriangleGroup(n=Integer(5)) >>> el1 = -G.I() >>> el2 = G.S()*G.T(Integer(3))*G.S()*G.T(-Integer(2)) >>> el3 = G.V(Integer(2))*G.V(Integer(3))**Integer(2)*G.V(Integer(4))**Integer(3) >>> el4 = G.U()**Integer(4) >>> el5 = (G.V(Integer(2))*G.T()).acton(-G.S()) >>> el4.string_repr(method='basic') 'S*T^(-1)' >>> G.element_repr_method('default') >>> el1 [-1 0] [ 0 -1] >>> el2 [ -1 2*lam] [ 3*lam -6*lam - 7] >>> el3 [34*lam + 19 5*lam + 4] [27*lam + 18 5*lam + 2] >>> el4 [ 0 -1] [ 1 -lam] >>> el5 [-7*lam - 4 9*lam + 6] [-4*lam - 5 7*lam + 4] >>> G.element_repr_method('basic') >>> el1 -1 >>> el2 S*T^3*S*T^(-2) >>> el3 -T*S*T*S*T^(-1)*S*T^(-2)*S*T^(-4)*S >>> el4 S*T^(-1) >>> el5 T*S*T^2*S*T^(-2)*S*T^(-1) >>> G.element_repr_method('conj') >>> el1 [-1] >>> el2 [-V(4)^2*V(1)^3] >>> el3 [V(3)^2*V(4)^3*V(2)] >>> el4 [-U^(-1)] >>> el5 [-S] >>> G.element_repr_method('block') >>> el1 -1 >>> el2 -(S*T^3) * (V(4)^2*V(1)^3) * (S*T^3)^(-1) >>> el3 (T*S*T) * (V(3)^2*V(4)^3*V(2)) * (T*S*T)^(-1) >>> el4 -U^(-1) >>> el5 -(T*S*T^2) * (S) * (T*S*T^2)^(-1) >>> G.element_repr_method('default') >>> G = HeckeTriangleGroup(n=infinity) >>> el = G.S()*G.T(Integer(3))*G.S()*G.T(-Integer(2)) >>> print(el.string_repr()) [ -1 4] [ 6 -25] >>> print(el.string_repr(method='basic')) S*T^3*S*T^(-2)
from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup G = HeckeTriangleGroup(n=5) el1 = -G.I() el2 = G.S()*G.T(3)*G.S()*G.T(-2) el3 = G.V(2)*G.V(3)^2*G.V(4)^3 el4 = G.U()^4 el5 = (G.V(2)*G.T()).acton(-G.S()) el4.string_repr(method='basic') G.element_repr_method('default') el1 el2 el3 el4 el5 G.element_repr_method('basic') el1 el2 el3 el4 el5 G.element_repr_method('conj') el1 el2 el3 el4 el5 G.element_repr_method('block') el1 el2 el3 el4 el5 G.element_repr_method('default') G = HeckeTriangleGroup(n=infinity) el = G.S()*G.T(3)*G.S()*G.T(-2) print(el.string_repr()) print(el.string_repr(method='basic'))
- trace()[source]¶
Return the trace of
self
, which is the sum of the diagonal entries.EXAMPLES:
sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup sage: G = HeckeTriangleGroup(n=7) sage: G.U().trace() lam sage: G.S().trace() 0
>>> from sage.all import * >>> from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup >>> G = HeckeTriangleGroup(n=Integer(7)) >>> G.U().trace() lam >>> G.S().trace() 0
from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup G = HeckeTriangleGroup(n=7) G.U().trace() G.S().trace()
- word_S_T()[source]¶
Decompose
self
into a product of the generatorsS
andT
of its parent, together with a sign correction matrix, namely:self = sgn * prod(L)
.Warning: If
self
is +- the identityprod(L)
is an empty product which produces1
instead of the identity matrix.OUTPUT:
The function returns a tuple
(L, sgn)
where the entries ofL
are either the generatorS
or a non-trivial integer power of the generatorT
.sgn
is +- the identity.If this decomposition is not possible a
TypeError
is raised.EXAMPLES:
sage: from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup sage: G = HeckeTriangleGroup(n=17) sage: (-G.I()).word_S_T()[0] () sage: (-G.I()).word_S_T()[1] [-1 0] [ 0 -1] sage: (L, sgn) = (-G.V(2)).word_S_T() sage: L ( [ 1 lam] [ 0 -1] [ 1 lam] [ 0 1], [ 1 0], [ 0 1] ) sage: sgn == -G.I() True sage: -G.V(2) == sgn * prod(L) True sage: (L, sgn) = G.U().word_S_T() sage: L ( [ 1 lam] [ 0 -1] [ 0 1], [ 1 0] ) sage: sgn == G.I() True sage: G.U() == sgn * prod(L) True sage: G = HeckeTriangleGroup(n=infinity) sage: (L, sgn) = (-G.V(2)*G.V(3)).word_S_T() sage: L ( [1 2] [ 0 -1] [1 4] [ 0 -1] [1 2] [ 0 -1] [1 2] [0 1], [ 1 0], [0 1], [ 1 0], [0 1], [ 1 0], [0 1] ) sage: -G.V(2)*G.V(3) == sgn * prod(L) True
>>> from sage.all import * >>> from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup >>> G = HeckeTriangleGroup(n=Integer(17)) >>> (-G.I()).word_S_T()[Integer(0)] () >>> (-G.I()).word_S_T()[Integer(1)] [-1 0] [ 0 -1] >>> (L, sgn) = (-G.V(Integer(2))).word_S_T() >>> L ( [ 1 lam] [ 0 -1] [ 1 lam] [ 0 1], [ 1 0], [ 0 1] ) >>> sgn == -G.I() True >>> -G.V(Integer(2)) == sgn * prod(L) True >>> (L, sgn) = G.U().word_S_T() >>> L ( [ 1 lam] [ 0 -1] [ 0 1], [ 1 0] ) >>> sgn == G.I() True >>> G.U() == sgn * prod(L) True >>> G = HeckeTriangleGroup(n=infinity) >>> (L, sgn) = (-G.V(Integer(2))*G.V(Integer(3))).word_S_T() >>> L ( [1 2] [ 0 -1] [1 4] [ 0 -1] [1 2] [ 0 -1] [1 2] [0 1], [ 1 0], [0 1], [ 1 0], [0 1], [ 1 0], [0 1] ) >>> -G.V(Integer(2))*G.V(Integer(3)) == sgn * prod(L) True
from sage.modular.modform_hecketriangle.hecke_triangle_groups import HeckeTriangleGroup G = HeckeTriangleGroup(n=17) (-G.I()).word_S_T()[0] (-G.I()).word_S_T()[1] (L, sgn) = (-G.V(2)).word_S_T() L sgn == -G.I() -G.V(2) == sgn * prod(L) (L, sgn) = G.U().word_S_T() L sgn == G.I() G.U() == sgn * prod(L) G = HeckeTriangleGroup(n=infinity) (L, sgn) = (-G.V(2)*G.V(3)).word_S_T() L -G.V(2)*G.V(3) == sgn * prod(L)
- sage.modular.modform_hecketriangle.hecke_triangle_group_element.coerce_AA(p)[source]¶
Return the argument first coerced into
AA
and then simplified.This leads to a major performance gain with some operations.
EXAMPLES:
sage: # needs sage.rings.number_field sage.symbolic sage: from sage.modular.modform_hecketriangle.hecke_triangle_group_element import coerce_AA sage: p = (791264*AA(2*cos(pi/8))^2 - 463492).sqrt() sage: AA(p)._exact_field() Number Field in a with defining polynomial y^8 ... with a in ... sage: coerce_AA(p)._exact_field() Number Field in a with defining polynomial y^4 - 1910*y^2 - 3924*y + 681058 with a in ...?
>>> from sage.all import * >>> # needs sage.rings.number_field sage.symbolic >>> from sage.modular.modform_hecketriangle.hecke_triangle_group_element import coerce_AA >>> p = (Integer(791264)*AA(Integer(2)*cos(pi/Integer(8)))**Integer(2) - Integer(463492)).sqrt() >>> AA(p)._exact_field() Number Field in a with defining polynomial y^8 ... with a in ... >>> coerce_AA(p)._exact_field() Number Field in a with defining polynomial y^4 - 1910*y^2 - 3924*y + 681058 with a in ...?
# needs sage.rings.number_field sage.symbolic from sage.modular.modform_hecketriangle.hecke_triangle_group_element import coerce_AA p = (791264*AA(2*cos(pi/8))^2 - 463492).sqrt() AA(p)._exact_field() coerce_AA(p)._exact_field()
- sage.modular.modform_hecketriangle.hecke_triangle_group_element.cyclic_representative(L)[source]¶
Return a unique representative among all cyclic permutations of the given list/tuple.
INPUT:
L
– list or tuple
OUTPUT:
The maximal element among all cyclic permutations with respect to lexicographical ordering.
EXAMPLES:
sage: from sage.modular.modform_hecketriangle.hecke_triangle_group_element import cyclic_representative sage: cyclic_representative((1,)) (1,) sage: cyclic_representative((2,2)) (2, 2) sage: cyclic_representative((1,2,1,2)) (2, 1, 2, 1) sage: cyclic_representative((1,2,3,2,3,1)) (3, 2, 3, 1, 1, 2)
>>> from sage.all import * >>> from sage.modular.modform_hecketriangle.hecke_triangle_group_element import cyclic_representative >>> cyclic_representative((Integer(1),)) (1,) >>> cyclic_representative((Integer(2),Integer(2))) (2, 2) >>> cyclic_representative((Integer(1),Integer(2),Integer(1),Integer(2))) (2, 1, 2, 1) >>> cyclic_representative((Integer(1),Integer(2),Integer(3),Integer(2),Integer(3),Integer(1))) (3, 2, 3, 1, 1, 2)
from sage.modular.modform_hecketriangle.hecke_triangle_group_element import cyclic_representative cyclic_representative((1,)) cyclic_representative((2,2)) cyclic_representative((1,2,1,2)) cyclic_representative((1,2,3,2,3,1))