def _UG(n, R, special, var='a', invariant_form=None): r""" This function is commonly used by the functions :func:`GU` and :func:`SU` to avoid duplicated code. For documentation and examples see the individual functions. TESTS:: sage: GU(3,25).order() # indirect doctest 3961191000000 """ prefix = 'General' latex_prefix = 'G' if special: prefix = 'Special' latex_prefix = 'S' degree, ring = normalize_args_vectorspace(n, R, var=var) if is_FiniteField(ring): q = ring.cardinality() ring = GF(q**2, name=var) if invariant_form is not None: raise NotImplementedError( "invariant_form for finite groups is fixed by GAP") if invariant_form is not None: invariant_form = normalize_args_invariant_form(ring, degree, invariant_form) if not invariant_form.is_hermitian(): raise ValueError("invariant_form must be hermitian") inserted_text = 'with respect to hermitian form' try: if not invariant_form.is_positive_definite(): inserted_text = 'with respect to non positive definite hermitian form' except: pass name = '{0} Unitary Group of degree {1} over {2} {3}\n{4}'.format( prefix, degree, ring, inserted_text, invariant_form) ltx = r'\text{{{0}U}}_{{{1}}}({2})\text{{ {3} }}{4}'.format( latex_prefix, degree, latex(ring), inserted_text, latex(invariant_form)) else: name = '{0} Unitary Group of degree {1} over {2}'.format( prefix, degree, ring) ltx = r'\text{{{0}U}}_{{{1}}}({2})'.format(latex_prefix, degree, latex(ring)) if is_FiniteField(ring): cmd = '{0}U({1}, {2})'.format(latex_prefix, degree, q) return UnitaryMatrixGroup_gap(degree, ring, special, name, ltx, cmd) else: return UnitaryMatrixGroup_generic(degree, ring, special, name, ltx, invariant_form=invariant_form)
def _OG(n, R, special, e=0, var='a', invariant_form=None): r""" This function is commonly used by the functions GO and SO to avoid uneccessarily duplicated code. For documentation and examples see the individual functions. TESTS: Check that :trac:`26028` is fixed:: sage: GO(3,25).order() # indirect doctest 31200 """ prefix = 'General' ltx_prefix ='G' if special: prefix = 'Special' ltx_prefix ='S' degree, ring = normalize_args_vectorspace(n, R, var=var) e = normalize_args_e(degree, ring, e) if e == 0: if invariant_form is not None: if is_FiniteField(ring): raise NotImplementedError("invariant_form for finite groups is fixed by GAP") invariant_form = normalize_args_invariant_form(ring, degree, invariant_form) if not invariant_form.is_symmetric(): raise ValueError("invariant_form must be symmetric") try: if invariant_form.is_positive_definite(): inserted_text = "with respect to positive definite symmetric form" else: inserted_text = "with respect to non positive definite symmetric form" except ValueError: inserted_text = "with respect to symmetric form" name = '{0} Orthogonal Group of degree {1} over {2} {3}\n{4}'.format( prefix, degree, ring, inserted_text,invariant_form) ltx = r'\text{{{0}O}}_{{{1}}}({2})\text{{ {3} }}{4}'.format( ltx_prefix, degree, latex(ring), inserted_text, latex(invariant_form)) else: name = '{0} Orthogonal Group of degree {1} over {2}'.format(prefix, degree, ring) ltx = r'\text{{{0}O}}_{{{1}}}({2})'.format(ltx_prefix, degree, latex(ring)) else: name = '{0} Orthogonal Group of degree {1} and form parameter {2} over {3}'.format(prefix, degree, e, ring) ltx = r'\text{{{0}O}}_{{{1}}}({2}, {3})'.format(ltx_prefix, degree, latex(ring), '+' if e == 1 else '-') if is_FiniteField(ring): cmd = '{0}O({1}, {2}, {3})'.format(ltx_prefix, e, degree, ring.order()) return OrthogonalMatrixGroup_gap(degree, ring, False, name, ltx, cmd) else: return OrthogonalMatrixGroup_generic(degree, ring, False, name, ltx, invariant_form=invariant_form)
def _OG(n, R, special, e=0, var='a', invariant_form=None): r""" This function is commonly used by the functions GO and SO to avoid uneccessarily duplicated code. For documentation and examples see the individual functions. TESTS: Check that :trac:`26028` is fixed:: sage: GO(3,25).order() # indirect doctest 31200 """ prefix = 'General' ltx_prefix ='G' if special: prefix = 'Special' ltx_prefix ='S' degree, ring = normalize_args_vectorspace(n, R, var=var) e = normalize_args_e(degree, ring, e) if e == 0: if invariant_form is not None: if is_FiniteField(ring): raise NotImplementedError("invariant_form for finite groups is fixed by GAP") invariant_form = normalize_args_invariant_form(ring, degree, invariant_form) if not invariant_form.is_symmetric(): raise ValueError("invariant_form must be symmetric") try: if invariant_form.is_positive_definite(): inserted_text = "with respect to positive definite symmetric form" else: inserted_text = "with respect to non positive definite symmetric form" except ValueError: inserted_text = "with respect to symmetric form" name = '{0} Orthogonal Group of degree {1} over {2} {3}\n{4}'.format( prefix, degree, ring, inserted_text,invariant_form) ltx = r'\text{{{0}O}}_{{{1}}}({2})\text{{ {3} }}{4}'.format( ltx_prefix, degree, latex(ring), inserted_text, latex(invariant_form)) else: name = '{0} Orthogonal Group of degree {1} over {2}'.format(prefix, degree, ring) ltx = r'\text{{{0}O}}_{{{1}}}({2})'.format(ltx_prefix, degree, latex(ring)) else: name = '{0} Orthogonal Group of degree {1} and form parameter {2} over {3}'.format(prefix, degree, e, ring) ltx = r'\text{{{0}O}}_{{{1}}}({2}, {3})'.format(ltx_prefix, degree, latex(ring), '+' if e == 1 else '-') if is_FiniteField(ring): cmd = '{0}O({1}, {2}, {3})'.format(ltx_prefix, e, degree, ring.order()) return OrthogonalMatrixGroup_gap(degree, ring, False, name, ltx, cmd) else: return OrthogonalMatrixGroup_generic(degree, ring, False, name, ltx, invariant_form=invariant_form)
def SU(n, R, var='a'): """ The special unitary group `SU( d, R )` consists of all `d \times d` matrices that preserve a nondegenerate sesquilinear form over the ring `R` and have determinant one. .. note:: For a finite field the matrices that preserve a sesquilinear form over `F_q` live over `F_{q^2}`. So ``SU(n,q)`` for integer ``q`` constructs the matrix group over the base ring ``GF(q^2)``. .. note:: This group is also available via ``groups.matrix.SU()``. INPUT: - ``n`` -- a positive integer. - ``R`` -- ring or an integer. If an integer is specified, the corresponding finite field is used. - ``var`` -- variable used to represent generator of the finite field, if needed. OUTPUT: Return the special unitary group. EXAMPLES:: sage: SU(3,5) Special Unitary Group of degree 3 over Finite Field in a of size 5^2 sage: SU(3, GF(5)) Special Unitary Group of degree 3 over Finite Field in a of size 5^2 sage: SU(3,QQ) Special Unitary Group of degree 3 over Rational Field TESTS:: sage: groups.matrix.SU(2, 3) Special Unitary Group of degree 2 over Finite Field in a of size 3^2 """ degree, ring = normalize_args_vectorspace(n, R, var=var) if is_FiniteField(ring): q = ring.cardinality() ring = GF(q**2, name=var) name = 'Special Unitary Group of degree {0} over {1}'.format(degree, ring) ltx = r'\text{{SU}}_{{{0}}}({1})'.format(degree, latex(ring)) if is_FiniteField(ring): cmd = 'SU({0}, {1})'.format(degree, q) return UnitaryMatrixGroup_gap(degree, ring, True, name, ltx, cmd) else: return UnitaryMatrixGroup_generic(degree, ring, True, name, ltx)
def SU(n, R, var='a'): """ The special unitary group `SU( d, R )` consists of all `d \times d` matrices that preserve a nondegenerate sequilinear form over the ring `R` and have determinant one. .. note:: For a finite field the matrices that preserve a sesquilinear form over `F_q` live over `F_{q^2}`. So ``SU(n,q)`` for integer ``q`` constructs the matrix group over the base ring ``GF(q^2)``. .. note:: This group is also available via ``groups.matrix.SU()``. INPUT: - ``n`` -- a positive integer. - ``R`` -- ring or an integer. If an integer is specified, the corresponding finite field is used. - ``var`` -- variable used to represent generator of the finite field, if needed. OUTPUT: Return the special unitary group. EXAMPLES:: sage: SU(3,5) Special Unitary Group of degree 3 over Finite Field in a of size 5^2 sage: SU(3, GF(5)) Special Unitary Group of degree 3 over Finite Field in a of size 5^2 sage: SU(3,QQ) Special Unitary Group of degree 3 over Rational Field TESTS:: sage: groups.matrix.SU(2, 3) Special Unitary Group of degree 2 over Finite Field in a of size 3^2 """ degree, ring = normalize_args_vectorspace(n, R, var=var) if is_FiniteField(ring): q = ring.cardinality() ring = GF(q ** 2, name=var) name = 'Special Unitary Group of degree {0} over {1}'.format(degree, ring) ltx = r'\text{{SU}}_{{{0}}}({1})'.format(degree, latex(ring)) if is_FiniteField(ring): cmd = 'SU({0}, {1})'.format(degree, q) return UnitaryMatrixGroup_gap(degree, ring, True, name, ltx, cmd) else: return UnitaryMatrixGroup_generic(degree, ring, True, name, ltx)
def Sp(n, R, var='a'): r""" Return the symplectic group. The special linear group `GL( d, R )` consists of all `d \times d` matrices that are invertible over the ring `R` with determinant one. .. note:: This group is also available via ``groups.matrix.Sp()``. INPUT: - ``n`` -- a positive integer. - ``R`` -- ring or an integer. If an integer is specified, the corresponding finite field is used. - ``var`` -- variable used to represent generator of the finite field, if needed. EXAMPLES:: sage: Sp(4, 5) Symplectic Group of degree 4 over Finite Field of size 5 sage: Sp(4, IntegerModRing(15)) Symplectic Group of degree 4 over Ring of integers modulo 15 sage: Sp(3, GF(7)) Traceback (most recent call last): ... ValueError: the degree must be even TESTS:: sage: groups.matrix.Sp(2, 3) Symplectic Group of degree 2 over Finite Field of size 3 sage: G = Sp(4,5) sage: TestSuite(G).run() """ degree, ring = normalize_args_vectorspace(n, R, var=var) if degree % 2 != 0: raise ValueError('the degree must be even') name = 'Symplectic Group of degree {0} over {1}'.format(degree, ring) ltx = r'\text{{Sp}}_{{{0}}}({1})'.format(degree, latex(ring)) from sage.libs.gap.libgap import libgap try: cmd = 'Sp({0}, {1})'.format(degree, ring._gap_init_()) return SymplecticMatrixGroup_gap(degree, ring, True, name, ltx, cmd) except ValueError: return SymplecticMatrixGroup_generic(degree, ring, True, name, ltx)
def Sp(n, R, var='a'): r""" Return the symplectic group. The special linear group `GL( d, R )` consists of all `d \times d` matrices that are invertible over the ring `R` with determinant one. .. note:: This group is also available via ``groups.matrix.Sp()``. INPUT: - ``n`` -- a positive integer. - ``R`` -- ring or an integer. If an integer is specified, the corresponding finite field is used. - ``var`` -- variable used to represent generator of the finite field, if needed. EXAMPLES:: sage: Sp(4, 5) Symplectic Group of degree 4 over Finite Field of size 5 sage: Sp(4, IntegerModRing(15)) Symplectic Group of degree 4 over Ring of integers modulo 15 sage: Sp(3, GF(7)) Traceback (most recent call last): ... ValueError: the degree must be even TESTS:: sage: groups.matrix.Sp(2, 3) Symplectic Group of degree 2 over Finite Field of size 3 sage: G = Sp(4,5) sage: TestSuite(G).run() """ degree, ring = normalize_args_vectorspace(n, R, var=var) if degree % 2 != 0: raise ValueError('the degree must be even') name = 'Symplectic Group of degree {0} over {1}'.format(degree, ring) ltx = r'\text{{Sp}}_{{{0}}}({1})'.format(degree, latex(ring)) from sage.libs.gap.libgap import libgap try: cmd = 'Sp({0}, {1})'.format(degree, ring._gap_init_()) return SymplecticMatrixGroup_gap(degree, ring, True, name, ltx, cmd) except ValueError: return SymplecticMatrixGroup_generic(degree, ring, True, name, ltx)
def _UG(n, R, special, var='a', invariant_form=None): r""" This function is commonly used by the functions :func:`GU` and :func:`SU` to avoid duplicated code. For documentation and examples see the individual functions. TESTS:: sage: GU(3,25).order() # indirect doctest 3961191000000 """ prefix = 'General' latex_prefix ='G' if special: prefix = 'Special' latex_prefix ='S' degree, ring = normalize_args_vectorspace(n, R, var=var) if is_FiniteField(ring): q = ring.cardinality() ring = GF(q**2, name=var) if invariant_form is not None: raise NotImplementedError("invariant_form for finite groups is fixed by GAP") if invariant_form is not None: invariant_form = normalize_args_invariant_form(ring, degree, invariant_form) if not invariant_form.is_hermitian(): raise ValueError("invariant_form must be hermitian") try: if invariant_form.is_positive_definite(): inserted_text = "with respect to positive definite hermitian form" else: inserted_text = "with respect to non positive definite hermitian form" except ValueError: inserted_text = "with respect to hermitian form" name = '{0} Unitary Group of degree {1} over {2} {3}\n{4}'.format(prefix, degree, ring, inserted_text, invariant_form) ltx = r'\text{{{0}U}}_{{{1}}}({2})\text{{ {3} }}{4}'.format(latex_prefix, degree, latex(ring), inserted_text, latex(invariant_form)) else: name = '{0} Unitary Group of degree {1} over {2}'.format(prefix, degree, ring) ltx = r'\text{{{0}U}}_{{{1}}}({2})'.format(latex_prefix, degree, latex(ring)) if is_FiniteField(ring): cmd = '{0}U({1}, {2})'.format(latex_prefix, degree, q) return UnitaryMatrixGroup_gap(degree, ring, special, name, ltx, cmd) else: return UnitaryMatrixGroup_generic(degree, ring, special, name, ltx, invariant_form=invariant_form)
def GL(n, R, var='a'): """ Return the general linear group. The general linear group `GL( d, R )` consists of all `d \times d` matrices that are invertible over the ring `R`. .. NOTE:: This group is also available via ``groups.matrix.GL()``. INPUT: - ``n`` -- a positive integer. - ``R`` -- ring or an integer. If an integer is specified, the corresponding finite field is used. - ``var`` -- variable used to represent generator of the finite field, if needed. EXAMPLES:: sage: G = GL(6,GF(5)) sage: G.order() 11064475422000000000000000 sage: G.base_ring() Finite Field of size 5 sage: G.category() Category of finite groups sage: TestSuite(G).run() sage: G = GL(6, QQ) sage: G.category() Category of infinite groups sage: TestSuite(G).run() Here is the Cayley graph of (relatively small) finite General Linear Group:: sage: g = GL(2,3) sage: d = g.cayley_graph(); d Digraph on 48 vertices sage: d.plot(color_by_label=True, vertex_size=0.03, vertex_labels=False) # long time Graphics object consisting of 144 graphics primitives sage: d.plot3d(color_by_label=True) # long time Graphics3d Object :: sage: F = GF(3); MS = MatrixSpace(F,2,2) sage: gens = [MS([[2,0],[0,1]]), MS([[2,1],[2,0]])] sage: G = MatrixGroup(gens) sage: G.order() 48 sage: G.cardinality() 48 sage: H = GL(2,F) sage: H.order() 48 sage: H == G True sage: H.gens() == G.gens() True sage: H.as_matrix_group() == H True sage: H.gens() ( [2 0] [2 1] [0 1], [2 0] ) TESTS:: sage: groups.matrix.GL(2, 3) General Linear Group of degree 2 over Finite Field of size 3 """ degree, ring = normalize_args_vectorspace(n, R, var='a') try: if ring.is_finite(): cat = Groups().Finite() else: cat = Groups().Infinite() except AttributeError: cat = Groups() name = 'General Linear Group of degree {0} over {1}'.format(degree, ring) ltx = 'GL({0}, {1})'.format(degree, latex(ring)) try: cmd = 'GL({0}, {1})'.format(degree, ring._gap_init_()) return LinearMatrixGroup_gap(degree, ring, False, name, ltx, cmd, category=cat) except ValueError: return LinearMatrixGroup_generic(degree, ring, False, name, ltx, category=cat)
def SL(n, R, var='a'): r""" Return the special linear group. The special linear group `SL( d, R )` consists of all `d \times d` matrices that are invertible over the ring `R` with determinant one. .. note:: This group is also available via ``groups.matrix.SL()``. INPUT: - ``n`` -- a positive integer. - ``R`` -- ring or an integer. If an integer is specified, the corresponding finite field is used. - ``var`` -- variable used to represent generator of the finite field, if needed. EXAMPLES:: sage: SL(3, GF(2)) Special Linear Group of degree 3 over Finite Field of size 2 sage: G = SL(15, GF(7)); G Special Linear Group of degree 15 over Finite Field of size 7 sage: G.category() Category of finite groups sage: G.order() 1956712595698146962015219062429586341124018007182049478916067369638713066737882363393519966343657677430907011270206265834819092046250232049187967718149558134226774650845658791865745408000000 sage: len(G.gens()) 2 sage: G = SL(2, ZZ); G Special Linear Group of degree 2 over Integer Ring sage: G.category() Category of infinite groups sage: G.gens() ( [ 0 1] [1 1] [-1 0], [0 1] ) Next we compute generators for `\mathrm{SL}_3(\ZZ)` :: sage: G = SL(3,ZZ); G Special Linear Group of degree 3 over Integer Ring sage: G.gens() ( [0 1 0] [ 0 1 0] [1 1 0] [0 0 1] [-1 0 0] [0 1 0] [1 0 0], [ 0 0 1], [0 0 1] ) sage: TestSuite(G).run() TESTS:: sage: groups.matrix.SL(2, 3) Special Linear Group of degree 2 over Finite Field of size 3 """ degree, ring = normalize_args_vectorspace(n, R, var='a') try: if ring.is_finite() or n == 1: cat = Groups().Finite() else: cat = Groups().Infinite() except AttributeError: cat = Groups() name = 'Special Linear Group of degree {0} over {1}'.format(degree, ring) ltx = 'SL({0}, {1})'.format(degree, latex(ring)) from sage.libs.gap.libgap import libgap try: cmd = 'SL({0}, {1})'.format(degree, ring._gap_init_()) return LinearMatrixGroup_gap(degree, ring, True, name, ltx, cmd, category=cat) except ValueError: return LinearMatrixGroup_generic(degree, ring, True, name, ltx, category=cat)
def SO(n, R, e=None, var='a'): """ Return the special orthogonal group. The special orthogonal group `GO(n,R)` consists of all `n \times n` matrices with determinant one over the ring `R` preserving an `n`-ary positive definite quadratic form. In cases where there are multiple non-isomorphic quadratic forms, additional data needs to be specified to disambiguate. .. note:: This group is also available via ``groups.matrix.SO()``. INPUT: - ``n`` -- integer. The degree. - ``R`` -- ring or an integer. If an integer is specified, the corresponding finite field is used. - ``e`` -- ``+1`` or ``-1``, and ignored by default. Only relevant for finite fields and if the degree is even. A parameter that distinguishes inequivalent invariant forms. OUTPUT: The special orthogonal group of given degree, base ring, and choice of invariant form. EXAMPLES:: sage: G = SO(3,GF(5)) sage: G Special Orthogonal Group of degree 3 over Finite Field of size 5 sage: G = SO(3,GF(5)) sage: G.gens() ( [2 0 0] [3 2 3] [1 4 4] [0 3 0] [0 2 0] [4 0 0] [0 0 1], [0 3 1], [2 0 4] ) sage: G = SO(3,GF(5)) sage: G.as_matrix_group() Matrix group over Finite Field of size 5 with 3 generators ( [2 0 0] [3 2 3] [1 4 4] [0 3 0] [0 2 0] [4 0 0] [0 0 1], [0 3 1], [2 0 4] ) TESTS:: sage: groups.matrix.SO(2, 3, e=1) Special Orthogonal Group of degree 2 and form parameter 1 over Finite Field of size 3 """ degree, ring = normalize_args_vectorspace(n, R, var=var) e = normalize_args_e(degree, ring, e) if e == 0: name = 'Special Orthogonal Group of degree {0} over {1}'.format( degree, ring) ltx = r'\text{{SO}}_{{{0}}}({1})'.format(degree, latex(ring)) else: name = 'Special Orthogonal Group of degree' + \ ' {0} and form parameter {1} over {2}'.format(degree, e, ring) ltx = r'\text{{SO}}_{{{0}}}({1}, {2})'.format(degree, latex(ring), '+' if e == 1 else '-') if is_FiniteField(ring): cmd = 'SO({0}, {1}, {2})'.format(e, degree, ring.characteristic()) return OrthogonalMatrixGroup_gap(degree, ring, True, name, ltx, cmd) else: return OrthogonalMatrixGroup_generic(degree, ring, True, name, ltx)
def GO(n, R, e=0, var='a'): """ Return the general orthogonal group. The general orthogonal group `GO(n,R)` consists of all `n \times n` matrices over the ring `R` preserving an `n`-ary positive definite quadratic form. In cases where there are multiple non-isomorphic quadratic forms, additional data needs to be specified to disambiguate. In the case of a finite field and if the degree `n` is even, then there are two inequivalent quadratic forms and a third parameter ``e`` must be specified to disambiguate these two possibilities. .. note:: This group is also available via ``groups.matrix.GO()``. INPUT: - ``n`` -- integer. The degree. - ``R`` -- ring or an integer. If an integer is specified, the corresponding finite field is used. - ``e`` -- ``+1`` or ``-1``, and ignored by default. Only relevant for finite fields and if the degree is even. A parameter that distinguishes inequivalent invariant forms. OUTPUT: The general orthogonal group of given degree, base ring, and choice of invariant form. EXAMPLES:: sage: GO( 3, GF(7)) General Orthogonal Group of degree 3 over Finite Field of size 7 sage: GO( 3, GF(7)).order() 672 sage: GO( 3, GF(7)).gens() ( [3 0 0] [0 1 0] [0 5 0] [1 6 6] [0 0 1], [0 2 1] ) TESTS:: sage: groups.matrix.GO(2, 3, e=-1) General Orthogonal Group of degree 2 and form parameter -1 over Finite Field of size 3 """ degree, ring = normalize_args_vectorspace(n, R, var=var) e = normalize_args_e(degree, ring, e) if e == 0: name = 'General Orthogonal Group of degree {0} over {1}'.format( degree, ring) ltx = r'\text{{GO}}_{{{0}}}({1})'.format(degree, latex(ring)) else: name = 'General Orthogonal Group of degree' + \ ' {0} and form parameter {1} over {2}'.format(degree, e, ring) ltx = r'\text{{GO}}_{{{0}}}({1}, {2})'.format(degree, latex(ring), '+' if e == 1 else '-') if is_FiniteField(ring): cmd = 'GO({0}, {1}, {2})'.format(e, degree, ring.characteristic()) return OrthogonalMatrixGroup_gap(degree, ring, False, name, ltx, cmd) else: return OrthogonalMatrixGroup_generic(degree, ring, False, name, ltx)
def SO(n, R, e=None, var='a'): """ Return the special orthogonal group. The special orthogonal group `GO(n,R)` consists of all `n\times n` matrices with determint one over the ring `R` preserving an `n`-ary positive definite quadratic form. In cases where there are muliple non-isomorphic quadratic forms, additional data needs to be specified to disambiguate. .. note:: This group is also available via ``groups.matrix.SO()``. INPUT: - ``n`` -- integer. The degree. - ``R`` -- ring or an integer. If an integer is specified, the corresponding finite field is used. - ``e`` -- ``+1`` or ``-1``, and ignored by default. Only relevant for finite fields and if the degree is even. A parameter that distinguishes inequivalent invariant forms. OUTPUT: The special orthogonal group of given degree, base ring, and choice of invariant form. EXAMPLES:: sage: G = SO(3,GF(5)) sage: G Special Orthogonal Group of degree 3 over Finite Field of size 5 sage: G = SO(3,GF(5)) sage: G.gens() ( [2 0 0] [3 2 3] [1 4 4] [0 3 0] [0 2 0] [4 0 0] [0 0 1], [0 3 1], [2 0 4] ) sage: G = SO(3,GF(5)) sage: G.as_matrix_group() Matrix group over Finite Field of size 5 with 3 generators ( [2 0 0] [3 2 3] [1 4 4] [0 3 0] [0 2 0] [4 0 0] [0 0 1], [0 3 1], [2 0 4] ) TESTS:: sage: groups.matrix.SO(2, 3, e=1) Special Orthogonal Group of degree 2 and form parameter 1 over Finite Field of size 3 """ degree, ring = normalize_args_vectorspace(n, R, var=var) e = normalize_args_e(degree, ring, e) if e == 0: name = 'Special Orthogonal Group of degree {0} over {1}'.format(degree, ring) ltx = r'\text{{SO}}_{{{0}}}({1})'.format(degree, latex(ring)) else: name = 'Special Orthogonal Group of degree' + \ ' {0} and form parameter {1} over {2}'.format(degree, e, ring) ltx = r'\text{{SO}}_{{{0}}}({1}, {2})'.format(degree, latex(ring), '+' if e == 1 else '-') if is_FiniteField(ring): cmd = 'SO({0}, {1}, {2})'.format(e, degree, ring.characteristic()) return OrthogonalMatrixGroup_gap(degree, ring, True, name, ltx, cmd) else: return OrthogonalMatrixGroup_generic(degree, ring, True, name, ltx)
def GO(n, R, e=0, var='a'): """ Return the general orthogonal group. The general orthogonal group `GO(n,R)` consists of all `n\times n` matrices over the ring `R` preserving an `n`-ary positive definite quadratic form. In cases where there are muliple non-isomorphic quadratic forms, additional data needs to be specified to disambiguate. In the case of a finite field and if the degree `n` is even, then there are two inequivalent quadratic forms and a third parameter ``e`` must be specified to disambiguate these two possibilities. .. note:: This group is also available via ``groups.matrix.GO()``. INPUT: - ``n`` -- integer. The degree. - ``R`` -- ring or an integer. If an integer is specified, the corresponding finite field is used. - ``e`` -- ``+1`` or ``-1``, and ignored by default. Only relevant for finite fields and if the degree is even. A parameter that distinguishes inequivalent invariant forms. OUTPUT: The general orthogonal group of given degree, base ring, and choice of invariant form. EXAMPLES: sage: GO( 3, GF(7)) General Orthogonal Group of degree 3 over Finite Field of size 7 sage: GO( 3, GF(7)).order() 672 sage: GO( 3, GF(7)).gens() ( [3 0 0] [0 1 0] [0 5 0] [1 6 6] [0 0 1], [0 2 1] ) TESTS:: sage: groups.matrix.GO(2, 3, e=-1) General Orthogonal Group of degree 2 and form parameter -1 over Finite Field of size 3 """ degree, ring = normalize_args_vectorspace(n, R, var=var) e = normalize_args_e(degree, ring, e) if e == 0: name = 'General Orthogonal Group of degree {0} over {1}'.format(degree, ring) ltx = r'\text{{GO}}_{{{0}}}({1})'.format(degree, latex(ring)) else: name = 'General Orthogonal Group of degree' + \ ' {0} and form parameter {1} over {2}'.format(degree, e, ring) ltx = r'\text{{GO}}_{{{0}}}({1}, {2})'.format(degree, latex(ring), '+' if e == 1 else '-') if is_FiniteField(ring): cmd = 'GO({0}, {1}, {2})'.format(e, degree, ring.characteristic()) return OrthogonalMatrixGroup_gap(degree, ring, False, name, ltx, cmd) else: return OrthogonalMatrixGroup_generic(degree, ring, False, name, ltx)
def GL(n, R, var='a'): """ Return the general linear group. The general linear group `GL( d, R )` consists of all `d \times d` matrices that are invertible over the ring `R`. .. note:: This group is also available via ``groups.matrix.GL()``. INPUT: - ``n`` -- a positive integer. - ``R`` -- ring or an integer. If an integer is specified, the corresponding finite field is used. - ``var`` -- variable used to represent generator of the finite field, if needed. EXAMPLES:: sage: G = GL(6,GF(5)) sage: G.order() 11064475422000000000000000 sage: G.base_ring() Finite Field of size 5 sage: G.category() Category of finite groups sage: TestSuite(G).run() sage: G = GL(6, QQ) sage: G.category() Category of groups sage: TestSuite(G).run() Here is the Cayley graph of (relatively small) finite General Linear Group:: sage: g = GL(2,3) sage: d = g.cayley_graph(); d Digraph on 48 vertices sage: d.show(color_by_label=True, vertex_size=0.03, vertex_labels=False) sage: d.show3d(color_by_label=True) :: sage: F = GF(3); MS = MatrixSpace(F,2,2) sage: gens = [MS([[2,0],[0,1]]), MS([[2,1],[2,0]])] sage: G = MatrixGroup(gens) sage: G.order() 48 sage: G.cardinality() 48 sage: H = GL(2,F) sage: H.order() 48 sage: H == G True sage: H.gens() == G.gens() True sage: H.as_matrix_group() == H True sage: H.gens() ( [2 0] [2 1] [0 1], [2 0] ) TESTS:: sage: groups.matrix.GL(2, 3) General Linear Group of degree 2 over Finite Field of size 3 """ degree, ring = normalize_args_vectorspace(n, R, var='a') name = 'General Linear Group of degree {0} over {1}'.format(degree, ring) ltx = 'GL({0}, {1})'.format(degree, latex(ring)) try: cmd = 'GL({0}, {1})'.format(degree, ring._gap_init_()) return LinearMatrixGroup_gap(degree, ring, False, name, ltx, cmd) except ValueError: return LinearMatrixGroup_generic(degree, ring, False, name, ltx)
def GU(n, R, var='a'): r""" Return the general unitary group. The general unitary group `GU( d, R )` consists of all `d \times d` matrices that preserve a nondegenerate sequilinear form over the ring `R`. .. note:: For a finite field the matrices that preserve a sesquilinear form over `F_q` live over `F_{q^2}`. So ``GU(n,q)`` for integer ``q`` constructs the matrix group over the base ring ``GF(q^2)``. .. note:: This group is also available via ``groups.matrix.GU()``. INPUT: - ``n`` -- a positive integer. - ``R`` -- ring or an integer. If an integer is specified, the corresponding finite field is used. - ``var`` -- variable used to represent generator of the finite field, if needed. OUTPUT: Return the general unitary group. EXAMPLES:: sage: G = GU(3, 7); G General Unitary Group of degree 3 over Finite Field in a of size 7^2 sage: G.gens() ( [ a 0 0] [6*a 6 1] [ 0 1 0] [ 6 6 0] [ 0 0 5*a], [ 1 0 0] ) sage: GU(2,QQ) General Unitary Group of degree 2 over Rational Field sage: G = GU(3, 5, var='beta') sage: G.base_ring() Finite Field in beta of size 5^2 sage: G.gens() ( [ beta 0 0] [4*beta 4 1] [ 0 1 0] [ 4 4 0] [ 0 0 3*beta], [ 1 0 0] ) TESTS:: sage: groups.matrix.GU(2, 3) General Unitary Group of degree 2 over Finite Field in a of size 3^2 """ degree, ring = normalize_args_vectorspace(n, R, var=var) if is_FiniteField(ring): q = ring.cardinality() ring = GF(q ** 2, name=var) name = 'General Unitary Group of degree {0} over {1}'.format(degree, ring) ltx = r'\text{{GU}}_{{{0}}}({1})'.format(degree, latex(ring)) if is_FiniteField(ring): cmd = 'GU({0}, {1})'.format(degree, q) return UnitaryMatrixGroup_gap(degree, ring, False, name, ltx, cmd) else: return UnitaryMatrixGroup_generic(degree, ring, False, name, ltx)
def Sp(n, R, var='a', invariant_form=None): r""" Return the symplectic group. The special linear group `GL( d, R )` consists of all `d \times d` matrices that are invertible over the ring `R` with determinant one. .. NOTE:: This group is also available via ``groups.matrix.Sp()``. INPUT: - ``n`` -- a positive integer - ``R`` -- ring or an integer; if an integer is specified, the corresponding finite field is used - ``var`` -- (optional, default: ``'a'``) variable used to represent generator of the finite field, if needed - ``invariant_form`` -- (optional) instances being accepted by the matrix-constructor which define a `n \times n` square matrix over ``R`` describing the alternating form to be kept invariant by the symplectic group EXAMPLES:: sage: Sp(4, 5) Symplectic Group of degree 4 over Finite Field of size 5 sage: Sp(4, IntegerModRing(15)) Symplectic Group of degree 4 over Ring of integers modulo 15 sage: Sp(3, GF(7)) Traceback (most recent call last): ... ValueError: the degree must be even Using the ``invariant_form`` option:: sage: m = matrix(QQ, 4,4, [[0, 0, 1, 0], [0, 0, 0, 2], [-1, 0, 0, 0], [0, -2, 0, 0]]) sage: Sp4m = Sp(4, QQ, invariant_form=m) sage: Sp4 = Sp(4, QQ) sage: Sp4 == Sp4m False sage: Sp4.invariant_form() [ 0 0 0 1] [ 0 0 1 0] [ 0 -1 0 0] [-1 0 0 0] sage: Sp4m.invariant_form() [ 0 0 1 0] [ 0 0 0 2] [-1 0 0 0] [ 0 -2 0 0] sage: pm = Permutation([2,1,4,3]).to_matrix() sage: g = Sp4(pm); g in Sp4; g True [0 1 0 0] [1 0 0 0] [0 0 0 1] [0 0 1 0] sage: Sp4m(pm) Traceback (most recent call last): ... TypeError: matrix must be symplectic with respect to the alternating form [ 0 0 1 0] [ 0 0 0 2] [-1 0 0 0] [ 0 -2 0 0] sage: Sp(4,3, invariant_form=[[0,0,0,1],[0,0,1,0],[0,2,0,0], [2,0,0,0]]) Traceback (most recent call last): ... NotImplementedError: invariant_form for finite groups is fixed by GAP TESTS:: sage: TestSuite(Sp4).run() sage: TestSuite(Sp4m).run() sage: groups.matrix.Sp(2, 3) Symplectic Group of degree 2 over Finite Field of size 3 sage: G = Sp(4,5) sage: TestSuite(G).run() """ degree, ring = normalize_args_vectorspace(n, R, var=var) if degree % 2 != 0: raise ValueError('the degree must be even') if invariant_form is not None: if is_FiniteField(ring): raise NotImplementedError( "invariant_form for finite groups is fixed by GAP") invariant_form = normalize_args_invariant_form(ring, degree, invariant_form) if not invariant_form.is_alternating(): raise ValueError("invariant_form must be alternating") name = 'Symplectic Group of degree {0} over {1} with respect to alternating bilinear form\n{2}'.format( degree, ring, invariant_form) ltx = r'\text{{Sp}}_{{{0}}}({1})\text{{ with respect to alternating bilinear form}}{2}'.format( degree, latex(ring), latex(invariant_form)) else: name = 'Symplectic Group of degree {0} over {1}'.format(degree, ring) ltx = r'\text{{Sp}}_{{{0}}}({1})'.format(degree, latex(ring)) try: cmd = 'Sp({0}, {1})'.format(degree, ring._gap_init_()) return SymplecticMatrixGroup_gap(degree, ring, True, name, ltx, cmd) except ValueError: return SymplecticMatrixGroup_generic(degree, ring, True, name, ltx, invariant_form=invariant_form)
def Sp(n, R, var='a', invariant_form=None): r""" Return the symplectic group. The special linear group `GL( d, R )` consists of all `d \times d` matrices that are invertible over the ring `R` with determinant one. .. NOTE:: This group is also available via ``groups.matrix.Sp()``. INPUT: - ``n`` -- a positive integer - ``R`` -- ring or an integer; if an integer is specified, the corresponding finite field is used - ``var`` -- (optional, default: ``'a'``) variable used to represent generator of the finite field, if needed - ``invariant_form`` -- (optional) instances being accepted by the matrix-constructor which define a `n \times n` square matrix over ``R`` describing the alternating form to be kept invariant by the symplectic group EXAMPLES:: sage: Sp(4, 5) Symplectic Group of degree 4 over Finite Field of size 5 sage: Sp(4, IntegerModRing(15)) Symplectic Group of degree 4 over Ring of integers modulo 15 sage: Sp(3, GF(7)) Traceback (most recent call last): ... ValueError: the degree must be even Using the ``invariant_form`` option:: sage: m = matrix(QQ, 4,4, [[0, 0, 1, 0], [0, 0, 0, 2], [-1, 0, 0, 0], [0, -2, 0, 0]]) sage: Sp4m = Sp(4, QQ, invariant_form=m) sage: Sp4 = Sp(4, QQ) sage: Sp4 == Sp4m False sage: Sp4.invariant_form() [ 0 0 0 1] [ 0 0 1 0] [ 0 -1 0 0] [-1 0 0 0] sage: Sp4m.invariant_form() [ 0 0 1 0] [ 0 0 0 2] [-1 0 0 0] [ 0 -2 0 0] sage: pm = Permutation([2,1,4,3]).to_matrix() sage: g = Sp4(pm); g in Sp4; g True [0 1 0 0] [1 0 0 0] [0 0 0 1] [0 0 1 0] sage: Sp4m(pm) Traceback (most recent call last): ... TypeError: matrix must be symplectic with respect to the alternating form [ 0 0 1 0] [ 0 0 0 2] [-1 0 0 0] [ 0 -2 0 0] sage: Sp(4,3, invariant_form=[[0,0,0,1],[0,0,1,0],[0,2,0,0], [2,0,0,0]]) Traceback (most recent call last): ... NotImplementedError: invariant_form for finite groups is fixed by GAP TESTS:: sage: TestSuite(Sp4).run() sage: TestSuite(Sp4m).run() sage: groups.matrix.Sp(2, 3) Symplectic Group of degree 2 over Finite Field of size 3 sage: G = Sp(4,5) sage: TestSuite(G).run() """ degree, ring = normalize_args_vectorspace(n, R, var=var) if degree % 2 != 0: raise ValueError('the degree must be even') if invariant_form is not None: if is_FiniteField(ring): raise NotImplementedError("invariant_form for finite groups is fixed by GAP") invariant_form = normalize_args_invariant_form(ring, degree, invariant_form) if not invariant_form.is_alternating(): raise ValueError("invariant_form must be alternating") name = 'Symplectic Group of degree {0} over {1} with respect to alternating bilinear form\n{2}'.format( degree, ring, invariant_form) ltx = r'\text{{Sp}}_{{{0}}}({1})\text{{ with respect to alternating bilinear form}}{2}'.format( degree, latex(ring), latex(invariant_form)) else: name = 'Symplectic Group of degree {0} over {1}'.format(degree, ring) ltx = r'\text{{Sp}}_{{{0}}}({1})'.format(degree, latex(ring)) try: cmd = 'Sp({0}, {1})'.format(degree, ring._gap_init_()) return SymplecticMatrixGroup_gap(degree, ring, True, name, ltx, cmd) except ValueError: return SymplecticMatrixGroup_generic(degree, ring, True, name, ltx, invariant_form=invariant_form)
def GU(n, R, var='a'): r""" Return the general unitary group. The general unitary group `GU( d, R )` consists of all `d \times d` matrices that preserve a nondegenerate sesquilinear form over the ring `R`. .. note:: For a finite field the matrices that preserve a sesquilinear form over `F_q` live over `F_{q^2}`. So ``GU(n,q)`` for integer ``q`` constructs the matrix group over the base ring ``GF(q^2)``. .. note:: This group is also available via ``groups.matrix.GU()``. INPUT: - ``n`` -- a positive integer. - ``R`` -- ring or an integer. If an integer is specified, the corresponding finite field is used. - ``var`` -- variable used to represent generator of the finite field, if needed. OUTPUT: Return the general unitary group. EXAMPLES:: sage: G = GU(3, 7); G General Unitary Group of degree 3 over Finite Field in a of size 7^2 sage: G.gens() ( [ a 0 0] [6*a 6 1] [ 0 1 0] [ 6 6 0] [ 0 0 5*a], [ 1 0 0] ) sage: GU(2,QQ) General Unitary Group of degree 2 over Rational Field sage: G = GU(3, 5, var='beta') sage: G.base_ring() Finite Field in beta of size 5^2 sage: G.gens() ( [ beta 0 0] [4*beta 4 1] [ 0 1 0] [ 4 4 0] [ 0 0 3*beta], [ 1 0 0] ) TESTS:: sage: groups.matrix.GU(2, 3) General Unitary Group of degree 2 over Finite Field in a of size 3^2 """ degree, ring = normalize_args_vectorspace(n, R, var=var) if is_FiniteField(ring): q = ring.cardinality() ring = GF(q**2, name=var) name = 'General Unitary Group of degree {0} over {1}'.format(degree, ring) ltx = r'\text{{GU}}_{{{0}}}({1})'.format(degree, latex(ring)) if is_FiniteField(ring): cmd = 'GU({0}, {1})'.format(degree, q) return UnitaryMatrixGroup_gap(degree, ring, False, name, ltx, cmd) else: return UnitaryMatrixGroup_generic(degree, ring, False, name, ltx)
def SL(n, R, var='a'): r""" Return the special linear group. The special linear group `GL( d, R )` consists of all `d \times d` matrices that are invertible over the ring `R` with determinant one. .. note:: This group is also available via ``groups.matrix.SL()``. INPUT: - ``n`` -- a positive integer. - ``R`` -- ring or an integer. If an integer is specified, the corresponding finite field is used. - ``var`` -- variable used to represent generator of the finite field, if needed. EXAMPLES:: sage: SL(3, GF(2)) Special Linear Group of degree 3 over Finite Field of size 2 sage: G = SL(15, GF(7)); G Special Linear Group of degree 15 over Finite Field of size 7 sage: G.category() Category of finite groups sage: G.order() 1956712595698146962015219062429586341124018007182049478916067369638713066737882363393519966343657677430907011270206265834819092046250232049187967718149558134226774650845658791865745408000000 sage: len(G.gens()) 2 sage: G = SL(2, ZZ); G Special Linear Group of degree 2 over Integer Ring sage: G.gens() ( [ 0 1] [1 1] [-1 0], [0 1] ) Next we compute generators for `\mathrm{SL}_3(\ZZ)` :: sage: G = SL(3,ZZ); G Special Linear Group of degree 3 over Integer Ring sage: G.gens() ( [0 1 0] [ 0 1 0] [1 1 0] [0 0 1] [-1 0 0] [0 1 0] [1 0 0], [ 0 0 1], [0 0 1] ) sage: TestSuite(G).run() TESTS:: sage: groups.matrix.SL(2, 3) Special Linear Group of degree 2 over Finite Field of size 3 """ degree, ring = normalize_args_vectorspace(n, R, var='a') name = 'Special Linear Group of degree {0} over {1}'.format(degree, ring) ltx = 'SL({0}, {1})'.format(degree, latex(ring)) from sage.libs.gap.libgap import libgap try: cmd = 'SL({0}, {1})'.format(degree, ring._gap_init_()) return LinearMatrixGroup_gap(degree, ring, True, name, ltx, cmd) except ValueError: return LinearMatrixGroup_generic(degree, ring, True, name, ltx)