Orthogonal Linear Groups - Groups

Skip to content
Back to top
View this page
Edit this page

# Orthogonal Linear Groups

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. The special orthogonal group is the normal subgroup of matrices of determinant one.

In characteristics different from 2, a quadratic form is equivalent to a bilinear symmetric form. Furthermore, over the real numbers a positive definite quadratic form is equivalent to the diagonal quadratic form, equivalent to the bilinear symmetric form defined by the identity matrix. Hence, the orthogonal group \(GO(n,\RR)\) is the group of orthogonal matrices in the usual sense.

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. The index of \(SO(e,d,q)\) in \(GO(e,d,q)\) is \(2\) if \(q\) is odd, but \(SO(e,d,q) = GO(e,d,q)\) if \(q\) is even.)

Warning

GAP and Sage use different notations:

- GAP notation: The optional `e` comes first, that is, `GO([e,] d, q)`, `SO([e,] d, q)`.

- Sage notation: The optional `e` comes last, the standard Python convention: `GO(d, GF(q), e=0)`, `SO(d, GF(q), e=0)`.

EXAMPLES:

Sage

    sage: GO(3,7)
    General Orthogonal Group of degree 3 over Finite Field of size 7

    sage: G = SO(4, GF(7), 1); G
    Special Orthogonal Group of degree 4 and form parameter 1
     over Finite Field of size 7

    sage: # needs sage.libs.gap
    sage: G.random_element()   # random
    [4 3 5 2]
    [6 6 4 0]
    [0 4 6 0]
    [4 4 5 1]

Python

    >>> from sage.all import *
    >>> GO(Integer(3),Integer(7))
    General Orthogonal Group of degree 3 over Finite Field of size 7

    >>> G = SO(Integer(4), GF(Integer(7)), Integer(1)); G
    Special Orthogonal Group of degree 4 and form parameter 1
     over Finite Field of size 7

    >>> # needs sage.libs.gap
    >>> G.random_element()   # random
    [4 3 5 2]
    [6 6 4 0]
    [0 4 6 0]
    [4 4 5 1]

AUTHORS:

- David Joyner (2006-03): initial version

- David Joyner (2006-05): added examples, _latex_, __str__, gens, as_matrix_group

- William Stein (2006-12-09): rewrite

- Volker Braun (2013-1) port to new Parent, libGAP, extreme refactoring.

- Sebastian Oehms (2018-8) add `invariant_form()` (as alias), `_OG`, option for user defined invariant bilinear form, and bug-fix in cmd-string for calling GAP (see Issue #26028)

sage.groups.matrix_gps.orthogonal.GO(n, R, e=0, var='a', invariant_form=None)

  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

  - `var` – (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 symmetric form to be kept invariant by the orthogonal group; the form is checked to be non-degenerate and symmetric but not to be positive definite

  OUTPUT: the general orthogonal group of given degree, base ring, and choice of invariant form

  EXAMPLES:

  Sage

      sage: GO(3, GF(7))
      General Orthogonal Group of degree 3 over Finite Field of size 7

      sage: # needs sage.libs.gap
      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]
      )

  Python

      >>> from sage.all import *
      >>> GO(Integer(3), GF(Integer(7)))
      General Orthogonal Group of degree 3 over Finite Field of size 7

      >>> # needs sage.libs.gap
      >>> GO(Integer(3), GF(Integer(7))).order()
      672
      >>> GO(Integer(3), GF(Integer(7))).gens()
      (
      [3 0 0]  [0 1 0]
      [0 5 0]  [1 6 6]
      [0 0 1], [0 2 1]
      )

  Using the `invariant_form` option:

  Sage

      sage: m = matrix(QQ, 3, 3, [[0, 1, 0], [1, 0, 0], [0, 0, 3]])
      sage: GO3  = GO(3, QQ)
      sage: GO3m = GO(3, QQ, invariant_form=m)
      sage: GO3 == GO3m
      False
      sage: GO3.invariant_form()
      [1 0 0]
      [0 1 0]
      [0 0 1]
      sage: GO3m.invariant_form()
      [0 1 0]
      [1 0 0]
      [0 0 3]
      sage: pm = Permutation([2,3,1]).to_matrix()
      sage: g = GO3(pm); g in GO3; g
      True
      [0 0 1]
      [1 0 0]
      [0 1 0]
      sage: GO3m(pm)
      Traceback (most recent call last):
      ...
      TypeError: matrix must be orthogonal with respect to the symmetric form
      [0 1 0]
      [1 0 0]
      [0 0 3]

      sage: GO(3,3, invariant_form=[[1,0,0], [0,2,0], [0,0,1]])
      Traceback (most recent call last):
      ...
      NotImplementedError: invariant_form for finite groups is fixed by GAP
      sage: 5 + 5
      10
      sage: R.<x> = ZZ[]
      sage: GO(2, R, invariant_form=[[x,0], [0,1]])
      General Orthogonal Group of degree 2 over
       Univariate Polynomial Ring in x over Integer Ring with respect to symmetric form
      [x 0]
      [0 1]

  [Python]

      >>> from sage.all import *
      >>> m = matrix(QQ, Integer(3), Integer(3), [[Integer(0), Integer(1), Integer(0)], [Integer(1), Integer(0), Integer(0)], [Integer(0), Integer(0), Integer(3)]])
      >>> GO3  = GO(Integer(3), QQ)
      >>> GO3m = GO(Integer(3), QQ, invariant_form=m)
      >>> GO3 == GO3m
      False
      >>> GO3.invariant_form()
      [1 0 0]
      [0 1 0]
      [0 0 1]
      >>> GO3m.invariant_form()
      [0 1 0]
      [1 0 0]
      [0 0 3]
      >>> pm = Permutation([Integer(2),Integer(3),Integer(1)]).to_matrix()
      >>> g = GO3(pm); g in GO3; g
      True
      [0 0 1]
      [1 0 0]
      [0 1 0]
      >>> GO3m(pm)
      Traceback (most recent call last):
      ...
      TypeError: matrix must be orthogonal with respect to the symmetric form
      [0 1 0]
      [1 0 0]
      [0 0 3]

      >>> GO(Integer(3),Integer(3), invariant_form=[[Integer(1),Integer(0),Integer(0)], [Integer(0),Integer(2),Integer(0)], [Integer(0),Integer(0),Integer(1)]])
      Traceback (most recent call last):
      ...
      NotImplementedError: invariant_form for finite groups is fixed by GAP
      >>> Integer(5) + Integer(5)
      10
      >>> R = ZZ['x']; (x,) = R._first_ngens(1)
      >>> GO(Integer(2), R, invariant_form=[[x,Integer(0)], [Integer(0),Integer(1)]])
      General Orthogonal Group of degree 2 over
       Univariate Polynomial Ring in x over Integer Ring with respect to symmetric form
      [x 0]
      [0 1]

class sage.groups.matrix_gps.orthogonal.OrthogonalMatrixGroup_generic(degree, base_ring, special, sage_name, latex_string, category=None, invariant_form=None)

  Bases: `NamedMatrixGroup_generic`

  General Orthogonal Group over arbitrary rings.

  EXAMPLES:

  Sage

      sage: G = GO(3, GF(7)); G
      General Orthogonal Group of degree 3 over Finite Field of size 7
      sage: latex(G)
      \text{GO}_{3}(\Bold{F}_{7})

      sage: G = SO(3, GF(5));  G
      Special Orthogonal Group of degree 3 over Finite Field of size 5
      sage: latex(G)
      \text{SO}_{3}(\Bold{F}_{5})

      sage: # needs sage.rings.number_field
      sage: CF3 = CyclotomicField(3); e3 = CF3.gen()
      sage: m = matrix(CF3, 3,3, [[1,e3,0],[e3,2,0],[0,0,1]])
      sage: G = SO(3, CF3, invariant_form=m)
      sage: latex(G)
      \text{SO}_{3}(\Bold{Q}(\zeta_{3}))\text{ with respect to non positive definite symmetric form }\left(\begin{array}{rrr}
      1 & \zeta_{3} & 0 \\
      \zeta_{3} & 2 & 0 \\
      0 & 0 & 1
      \end{array}\right)

  Python

      >>> from sage.all import *
      >>> G = GO(Integer(3), GF(Integer(7))); G
      General Orthogonal Group of degree 3 over Finite Field of size 7
      >>> latex(G)
      \text{GO}_{3}(\Bold{F}_{7})

      >>> G = SO(Integer(3), GF(Integer(5)));  G
      Special Orthogonal Group of degree 3 over Finite Field of size 5
      >>> latex(G)
      \text{SO}_{3}(\Bold{F}_{5})

      >>> # needs sage.rings.number_field
      >>> CF3 = CyclotomicField(Integer(3)); e3 = CF3.gen()
      >>> m = matrix(CF3, Integer(3),Integer(3), [[Integer(1),e3,Integer(0)],[e3,Integer(2),Integer(0)],[Integer(0),Integer(0),Integer(1)]])
      >>> G = SO(Integer(3), CF3, invariant_form=m)
      >>> latex(G)
      \text{SO}_{3}(\Bold{Q}(\zeta_{3}))\text{ with respect to non positive definite symmetric form }\left(\begin{array}{rrr}
      1 & \zeta_{3} & 0 \\
      \zeta_{3} & 2 & 0 \\
      0 & 0 & 1
      \end{array}\right)

  invariant_bilinear_form()

    Return the symmetric bilinear form preserved by `self`.

    OUTPUT: a matrix

    EXAMPLES:

    Sage

        sage: # needs sage.libs.gap
        sage: GO(2,3,+1).invariant_bilinear_form()
        [0 1]
        [1 0]
        sage: GO(2,3,-1).invariant_bilinear_form()
        [2 1]
        [1 1]
        sage: G = GO(4, QQ)
        sage: G.invariant_bilinear_form()
        [1 0 0 0]
        [0 1 0 0]
        [0 0 1 0]
        [0 0 0 1]
        sage: GO3m = GO(3, QQ, invariant_form=(1,0,0, 0,2,0, 0,0,3))
        sage: GO3m.invariant_bilinear_form()
        [1 0 0]
        [0 2 0]
        [0 0 3]

    Python

        >>> from sage.all import *
        >>> # needs sage.libs.gap
        >>> GO(Integer(2),Integer(3),+Integer(1)).invariant_bilinear_form()
        [0 1]
        [1 0]
        >>> GO(Integer(2),Integer(3),-Integer(1)).invariant_bilinear_form()
        [2 1]
        [1 1]
        >>> G = GO(Integer(4), QQ)
        >>> G.invariant_bilinear_form()
        [1 0 0 0]
        [0 1 0 0]
        [0 0 1 0]
        [0 0 0 1]
        >>> GO3m = GO(Integer(3), QQ, invariant_form=(Integer(1),Integer(0),Integer(0), Integer(0),Integer(2),Integer(0), Integer(0),Integer(0),Integer(3)))
        >>> GO3m.invariant_bilinear_form()
        [1 0 0]
        [0 2 0]
        [0 0 3]

  invariant_form()

    alias of `invariant_bilinear_form()`.

  invariant_quadratic_form()

    alias of `invariant_bilinear_form()`.

sage.groups.matrix_gps.orthogonal.SO(n, R, e=None, var='a', invariant_form=None)

  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

  - `var` – (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 symmetric form to be kept invariant by the orthogonal group; the form is checked to be non-degenerate and symmetric but not to be positive definite

  OUTPUT: the special orthogonal group of given degree, base ring, and choice of invariant form

  EXAMPLES:

  Sage

      sage: G = SO(3,GF(5)); G
      Special Orthogonal Group of degree 3 over Finite Field of size 5

      sage: # needs sage.libs.gap
      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.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]
      )

  Python

      >>> from sage.all import *
      >>> G = SO(Integer(3),GF(Integer(5))); G
      Special Orthogonal Group of degree 3 over Finite Field of size 5

      >>> # needs sage.libs.gap
      >>> G = SO(Integer(3),GF(Integer(5)))
      >>> 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]
      )
      >>> 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]
      )

  Using the `invariant_form` option:

  Sage

      sage: # needs sage.rings.number_field
      sage: CF3 = CyclotomicField(3); e3 = CF3.gen()
      sage: m = matrix(CF3, 3, 3, [[1,e3,0], [e3,2,0], [0,0,1]])
      sage: SO3  = SO(3, CF3)
      sage: SO3m = SO(3, CF3, invariant_form=m)
      sage: SO3 == SO3m
      False
      sage: SO3.invariant_form()
      [1 0 0]
      [0 1 0]
      [0 0 1]
      sage: SO3m.invariant_form()
      [    1 zeta3     0]
      [zeta3     2     0]
      [    0     0     1]
      sage: pm = Permutation([2,3,1]).to_matrix()
      sage: g = SO3(pm); g in SO3; g
      True
      [0 0 1]
      [1 0 0]
      [0 1 0]
      sage: SO3m(pm)
      Traceback (most recent call last):
      ...
      TypeError: matrix must be orthogonal with respect to the symmetric form
      [    1 zeta3     0]
      [zeta3     2     0]
      [    0     0     1]

      sage: SO(3, 5, invariant_form=[[1,0,0], [0,2,0], [0,0,3]])
      Traceback (most recent call last):
      ...
      NotImplementedError: invariant_form for finite groups is fixed by GAP
      sage: 5+5
      10

  [Python]

      >>> from sage.all import *
      >>> # needs sage.rings.number_field
      >>> CF3 = CyclotomicField(Integer(3)); e3 = CF3.gen()
      >>> m = matrix(CF3, Integer(3), Integer(3), [[Integer(1),e3,Integer(0)], [e3,Integer(2),Integer(0)], [Integer(0),Integer(0),Integer(1)]])
      >>> SO3  = SO(Integer(3), CF3)
      >>> SO3m = SO(Integer(3), CF3, invariant_form=m)
      >>> SO3 == SO3m
      False
      >>> SO3.invariant_form()
      [1 0 0]
      [0 1 0]
      [0 0 1]
      >>> SO3m.invariant_form()
      [    1 zeta3     0]
      [zeta3     2     0]
      [    0     0     1]
      >>> pm = Permutation([Integer(2),Integer(3),Integer(1)]).to_matrix()
      >>> g = SO3(pm); g in SO3; g
      True
      [0 0 1]
      [1 0 0]
      [0 1 0]
      >>> SO3m(pm)
      Traceback (most recent call last):
      ...
      TypeError: matrix must be orthogonal with respect to the symmetric form
      [    1 zeta3     0]
      [zeta3     2     0]
      [    0     0     1]

      >>> SO(Integer(3), Integer(5), invariant_form=[[Integer(1),Integer(0),Integer(0)], [Integer(0),Integer(2),Integer(0)], [Integer(0),Integer(0),Integer(3)]])
      Traceback (most recent call last):
      ...
      NotImplementedError: invariant_form for finite groups is fixed by GAP
      >>> Integer(5)+Integer(5)
      10

sage.groups.matrix_gps.orthogonal.normalize_args_e(degree, ring, e)

  Normalize the arguments that relate the choice of quadratic form for special orthogonal groups over finite fields.

  INPUT:

  - `degree` – integer; the degree of the affine group, that is, the dimension of the affine space the group is acting on

  - `ring` – a ring; the base ring of the affine space

  - `e` – integer; one of \(+1\), \(0\), \(-1\). Only relevant for finite fields and if the degree is even. A parameter that distinguishes inequivalent invariant forms.

  OUTPUT: the integer `e` with values required by GAP