Path: blob/master/sage/groups/matrix_gps/orthogonal.py
4069 views
r"""1Orthogonal Linear Groups23Paraphrased from the GAP manual: The general orthogonal group4`GO(e,d,q)` consists of those `d\times d` matrices5over the field `GF(q)` that respect a non-singular6quadratic form specified by `e`. (Use the GAP command7InvariantQuadraticForm to determine this form explicitly.) The8value of `e` must be `0` for odd `d` (and9can optionally be omitted in this case), respectively one of10`1` or `-1` for even `d`.1112SpecialOrthogonalGroup returns a group isomorphic to the special13orthogonal group `SO(e,d,q)`, which is the subgroup of all14those matrices in the general orthogonal group that have15determinant one. (The index of `SO(e,d,q)` in16`GO(e,d,q)` is `2` if `q` is odd, but17`SO(e,d,q) = GO(e,d,q)` if `q` is even.)1819.. warning::2021GAP notation: GO([e,] d, q), SO([e,] d, q) ([...] denotes and22optional value)2324Sage notation: GO(d, GF(q), e=0), SO( d, GF(q), e=0)2526There is no Python trick I know of to allow the first argument to27have the default value e=0 and leave the other two arguments as28non-default. This forces us into non-standard notation.2930AUTHORS:3132- David Joyner (2006-03): initial version3334- David Joyner (2006-05): added examples, _latex_, __str__, gens,35as_matrix_group3637- William Stein (2006-12-09): rewrite38"""3940#*****************************************************************************41# Copyright (C) 2006 David Joyner and William Stein42#43# Distributed under the terms of the GNU General Public License (GPL)44# http://www.gnu.org/licenses/45#*****************************************************************************4647from sage.rings.all import is_FiniteField, Integer, FiniteField48from matrix_group import MatrixGroup_gap, MatrixGroup_gap_finite_field4950from sage.interfaces.gap import gap5152def SO(n, R, e=0, var='a'):53"""54Return the special orthogonal group of degree `n` over the55ring `R`.5657INPUT:585960- ``n`` - the degree6162- ``R`` - ring6364- ``e`` - a parameter for orthogonal groups only65depending on the invariant form666768EXAMPLES::6970sage: G = SO(3,GF(5))71sage: G.gens()72[73[2 0 0]74[0 3 0]75[0 0 1],76[3 2 3]77[0 2 0]78[0 3 1],79[1 4 4]80[4 0 0]81[2 0 4]82]83sage: G = SO(3,GF(5))84sage: G.as_matrix_group()85Matrix group over Finite Field of size 5 with 3 generators:86[[[2, 0, 0], [0, 3, 0], [0, 0, 1]], [[3, 2, 3], [0, 2, 0], [0, 3, 1]], [[1, 4, 4], [4, 0, 0], [2, 0, 4]]]87"""88if isinstance(R, (int, long, Integer)):89R = FiniteField(R, var)90if n%2!=0 and e != 0:91raise ValueError, "must have e = 0 for n even"92if n%2 == 0 and e**2 != 1:93raise ValueError, "must have e=-1 or e=1 if n is even"94if is_FiniteField(R):95return SpecialOrthogonalGroup_finite_field(n, R, e)96else:97return SpecialOrthogonalGroup_generic(n, R, e)9899class OrthogonalGroup(MatrixGroup_gap):100def __init__(self, n, R, e=0, var='a'):101"""102INPUT:103104105- ``n`` - the degree106107- ``R`` - the base ring108109- ``e`` - a parameter for orthogonal groups only110depending on the invariant form111112- ``var`` - variable used to define field of113definition of actual matrices in this group.114"""115MatrixGroup_gap.__init__(self, n, R, var)116self.__form = e117118def invariant_form(self):119"""120Return the invariant form of this orthogonal group.121122TODO: What is the point of this? What does it do? How does it123work?124125EXAMPLES::126127sage: G = SO( 4, GF(7), 1)128sage: G.invariant_form()1291130"""131return self.__form132133class SpecialOrthogonalGroup_generic(OrthogonalGroup):134"""135EXAMPLES::136137sage: G = SO( 4, GF(7), 1); G138Special Orthogonal Group of degree 4, form parameter 1, over the Finite Field of size 7139sage: G._gap_init_()140'SO(1, 4, 7)'141sage: G.random_element()142[1 2 5 0]143[2 2 1 0]144[1 3 1 5]145[1 3 1 3]146"""147def _gap_init_(self):148"""149EXAMPLES::150151sage: G = SO(3,GF(5))152sage: G._gap_init_()153'SO(0, 3, 5)'154"""155return "SO(%s, %s, %s)"%( self.invariant_form(), self.degree(), self.base_ring().order())156157def _repr_(self):158"""159EXAMPLES::160161sage: G = SO(3,GF(5))162sage: G163Special Orthogonal Group of degree 3, form parameter 0, over the Finite Field of size 5164"""165return "Special Orthogonal Group of degree %s, form parameter %s, over the %s"%( self.degree(), self.invariant_form(), self.base_ring())166167def _latex_(self):168"""169EXAMPLES::170171sage: G = SO(3,GF(5))172sage: latex(G)173\text{SO}_{3}(\Bold{F}_{5}, 0)174"""175return "\\text{SO}_{%s}(%s, %s)"%(self.degree(), self.base_ring()._latex_(), self.invariant_form())176177def invariant_quadratic_form(self):178r"""179Return the quadratic form `q(v) = v Q v^t` on the space on180which this group `G` that satisfies the equation181`q(v) = q(v M)` for all `v \in V` and182`M \in G`.183184.. note::185186Uses GAP's command InvariantQuadraticForm.187188OUTPUT:189190191- ``Q`` - matrix that defines the invariant quadratic192form.193194195EXAMPLES::196197sage: G = SO( 4, GF(7), 1)198sage: G.invariant_quadratic_form()199[0 1 0 0]200[0 0 0 0]201[0 0 3 0]202[0 0 0 1]203"""204F = self.base_ring()205I = gap(self).InvariantQuadraticForm()206Q = I.attribute('matrix')207return Q._matrix_(F)208209210class SpecialOrthogonalGroup_finite_field(SpecialOrthogonalGroup_generic, MatrixGroup_gap_finite_field):211pass212213214########################################################################215# General Orthogonal Group216########################################################################217218def GO( n , R , e=0 ):219"""220Return the general orthogonal group.221222EXAMPLES:223"""224if n%2!=0 and e!=0:225raise ValueError, "if e = 0, then n must be even."226if n%2 == 0 and e**2!=1:227raise ValueError, "must have e=-1 or e=1, if d is even."228if isinstance(R, (int, long, Integer)):229R = FiniteField(R)230if is_FiniteField(R):231return GeneralOrthogonalGroup_finite_field(n, R, e)232else:233return GeneralOrthogonalGroup_generic(n, R, e)234235class GeneralOrthogonalGroup_generic(OrthogonalGroup):236"""237EXAMPLES::238239sage: GO( 3, GF(7), 0)240General Orthogonal Group of degree 3, form parameter 0, over the Finite Field of size 7241sage: GO( 3, GF(7), 0).order()242672243sage: GO( 3, GF(7), 0).random_element()244[5 1 4]245[1 0 0]246[6 0 1]247"""248def _gap_init_(self):249"""250EXAMPLES::251252sage: GO( 3, GF(7), 0)._gap_init_()253'GO(0, 3, 7)'254"""255return "GO(%s, %s, %s)"%( self.invariant_form(), self.degree(), (self.base_ring()).order() )256257def _repr_(self):258"""259String representation of self.260261EXAMPLES::262263sage: GO(3,7)264General Orthogonal Group of degree 3, form parameter 0, over the Finite Field of size 7265"""266return "General Orthogonal Group of degree %s, form parameter %s, over the %s"%( self.degree(), self.invariant_form(), self.base_ring())267268def _latex_(self):269"""270EXAMPLES::271272sage: G = GO(3,GF(5))273sage: latex(G)274\text{GO}_{3}(5, 0)275"""276return "\\text{GO}_{%s}(%s, %s)"%( self.degree(), self.base_ring().order(),self.invariant_form() )277278def invariant_quadratic_form(self):279"""280This wraps GAP's command "InvariantQuadraticForm". From the GAP281documentation:282283INPUT:284285286- ``self`` - a matrix group G287288289OUTPUT:290291292- ``Q`` - the matrix satisfying the property: The293quadratic form q on the natural vector space V on which G acts is294given by `q(v) = v Q v^t`, and the invariance under G is295given by the equation `q(v) = q(v M)` for all296`v \in V` and `M \in G`.297298299EXAMPLES::300301sage: G = GO( 4, GF(7), 1)302sage: G.invariant_quadratic_form()303[0 1 0 0]304[0 0 0 0]305[0 0 3 0]306[0 0 0 1]307"""308F = self.base_ring()309G = self._gap_init_()310cmd = "r := InvariantQuadraticForm("+G+")"311gap.eval(cmd)312cmd = "r.matrix"313Q = gap(cmd)314return Q._matrix_(F)315316class GeneralOrthogonalGroup_finite_field(GeneralOrthogonalGroup_generic, MatrixGroup_gap_finite_field):317pass318319320321