Path: blob/master/sage/modular/arithgroup/arithgroup_element.py
4054 views
"""1Elements of Arithmetic Subgroups2"""34################################################################################5#6# Copyright (C) 2009, The Sage Group -- http://www.sagemath.org/7#8# Distributed under the terms of the GNU General Public License (GPL)9#10# The full text of the GPL is available at:11#12# http://www.gnu.org/licenses/13#14################################################################################1516from sage.structure.element import MultiplicativeGroupElement17from sage.rings.all import ZZ18import sage.matrix.all as matrix19from sage.matrix.matrix_integer_2x2 import Matrix_integer_2x2 as mi2x22021from all import is_ArithmeticSubgroup2223M2Z = matrix.MatrixSpace(ZZ,2)2425class ArithmeticSubgroupElement(MultiplicativeGroupElement):26r"""27An element of the group `{\rm SL}_2(\ZZ)`, i.e. a 2x2 integer matrix of28determinant 1.29"""3031def __init__(self, parent, x, check=True):32"""33Create an element of an arithmetic subgroup.3435INPUT:3637- parent - an arithmetic subgroup3839- x - data defining a 2x2 matrix over ZZ40which lives in parent4142- check - if True, check that parent43is an arithmetic subgroup, and that44x defines a matrix of determinant 14546We tend not to create elements of arithmetic subgroups that aren't47SL2Z, in order to avoid coercion issues (that is, the other arithmetic48subgroups are "facade parents").4950EXAMPLES::5152sage: G = Gamma0(27)53sage: sage.modular.arithgroup.arithgroup_element.ArithmeticSubgroupElement(G, [4,1,27,7])54[ 4 1]55[27 7]56sage: sage.modular.arithgroup.arithgroup_element.ArithmeticSubgroupElement(Integers(3), [4,1,27,7])57Traceback (most recent call last):58...59TypeError: parent (= Ring of integers modulo 3) must be an arithmetic subgroup60sage: sage.modular.arithgroup.arithgroup_element.ArithmeticSubgroupElement(G, [2,0,0,2])61Traceback (most recent call last):62...63TypeError: matrix must have determinant 164sage: sage.modular.arithgroup.arithgroup_element.ArithmeticSubgroupElement(G, [2,0,0,2], check=False)65[2, 0, 0, 2]6667sage: x = Gamma0(11)([2,1,11,6])68sage: x == loads(dumps(x))69True7071sage: x = Gamma0(5).072sage: SL2Z(x)73[1 1]74[0 1]75sage: x in SL2Z76True77"""78if check:79if not is_ArithmeticSubgroup(parent):80raise TypeError, "parent (= %s) must be an arithmetic subgroup"%parent8182x = mi2x2(M2Z, x, copy=True, coerce=True)83if x.determinant() != 1:84raise TypeError, "matrix must have determinant 1"8586try:87x.set_immutable()88except AttributeError:89pass9091MultiplicativeGroupElement.__init__(self, parent)92self.__x = x9394def __iter__(self):95"""96EXAMPLES::9798sage: Gamma0(2).099[1 1]100[0 1]101sage: list(Gamma0(2).0)102[1, 1, 0, 1]103"""104return iter(self.__x)105106def __repr__(self):107"""108Return the string representation of self.109110EXAMPLES::111112sage: Gamma1(5)([6,1,5,1]).__repr__()113'[6 1]\n[5 1]'114"""115return "%s"%self.__x116117def __cmp__(self, right):118"""119Compare self to right.120121EXAMPLES::122123sage: x = Gamma0(18)([19,1,18,1])124sage: x.__cmp__(3) is not 0125True126sage: x.__cmp__(x)1270128129sage: x = Gamma0(5)([1,1,0,1])130sage: x == 0131False132133This once caused a segfault (see trac #5443)::134135sage: r,s,t,u,v = map(SL2Z, [[1, 1, 0, 1], [-1, 0, 0, -1], [1, -1, 0, 1], [1, -1, 2, -1], [-1, 1, -2, 1]])136sage: v == s*u137True138sage: s*u == v139True140"""141from sage.misc.functional import parent142if parent(self) != parent(right):143return cmp(type(self), type(right))144else:145return cmp(self.__x, right.__x)146147def __nonzero__(self):148"""149Return True, since the self lives in SL(2,\Z), which does not150contain the zero matrix.151152EXAMPLES::153154sage: x = Gamma0(5)([1,1,0,1])155sage: x.__nonzero__()156True157"""158return True159160def _mul_(self, right):161"""162Return self * right.163164EXAMPLES::165166sage: x = Gamma0(7)([1,0,7,1]) * Gamma0(7)([3,2,7,5]) ; x # indirect doctest167[ 3 2]168[28 19]169sage: x.parent()170Modular Group SL(2,Z)171172We check that #5048 is fixed::173174sage: a = Gamma0(10).1 * Gamma0(5).2; a # random175sage: a.parent()176Modular Group SL(2,Z)177178"""179return self.parent()(self.__x * right.__x, check=False)180181def __invert__(self):182"""183Return the inverse of self.184185EXAMPLES::186187sage: Gamma0(11)([1,-1,0,1]).__invert__()188[1 1]189[0 1]190"""191I = mi2x2(M2Z, [self.__x[1,1], -self.__x[0,1], -self.__x[1,0], self.__x[0,0]], copy=True, coerce=True)192return self.parent()(I, check=False)193194def matrix(self):195"""196Return the matrix corresponding to self.197198EXAMPLES::199200sage: x = Gamma1(3)([4,5,3,4]) ; x201[4 5]202[3 4]203sage: x.matrix()204[4 5]205[3 4]206sage: type(x.matrix())207<type 'sage.matrix.matrix_integer_2x2.Matrix_integer_2x2'>208"""209return self.__x210211def determinant(self):212"""213Return the determinant of self, which is always 1.214215EXAMPLES::216217sage: Gamma0(691)([1,0,691,1]).determinant()2181219"""220return ZZ(1)221222def det(self):223"""224Return the determinant of self, which is always 1.225226EXAMPLES::227228sage: Gamma1(11)([12,11,-11,-10]).det()2291230"""231return self.determinant()232233def a(self):234"""235Return the upper left entry of self.236237EXAMPLES::238239sage: Gamma0(13)([7,1,13,2]).a()2407241"""242return self.__x[0,0]243244def b(self):245"""246Return the upper right entry of self.247248EXAMPLES::249250sage: Gamma0(13)([7,1,13,2]).b()2511252"""253return self.__x[0,1]254255def c(self):256"""257Return the lower left entry of self.258259EXAMPLES::260261sage: Gamma0(13)([7,1,13,2]).c()26213263"""264return self.__x[1,0]265266def d(self):267"""268Return the lower right entry of self.269270EXAMPLES::271272sage: Gamma0(13)([7,1,13,2]).d()2732274"""275return self.__x[1,1]276277def acton(self, z):278"""279Return the result of the action of self on z as a fractional linear280transformation.281282EXAMPLES::283284sage: G = Gamma0(15)285sage: g = G([1, 2, 15, 31])286287An example of g acting on a symbolic variable::288289sage: z = var('z')290sage: g.acton(z)291(z + 2)/(15*z + 31)292293An example involving the Gaussian numbers::294295sage: K.<i> = NumberField(x^2 + 1)296sage: g.acton(i)2971/1186*i + 77/1186298299An example with complex numbers::300301sage: C.<i> = ComplexField()302sage: g.acton(i)3030.0649241146711636 + 0.000843170320404721*I304"""305return (self.__x[0,0]*z + self.__x[0,1])/(self.__x[1,0]*z + self.__x[1,1])306307308def __getitem__(self, q):309r"""310Fetch entries by direct indexing.311312EXAMPLE::313sage: SL2Z([3,2,1,1])[0,0]3143315"""316return self.__x[q]317318319