# 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: 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: 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 trac ticket #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 – (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 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: 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]
)


Using the invariant_form option:

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]

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

The general or special orthogonal group in GAP.

invariant_bilinear_form()

Return the symmetric bilinear form preserved by the orthogonal group.

OUTPUT:

A matrix $$M$$ such that, for every group element g, the identity $$g m g^T = m$$ holds. In characteristic different from two, this uniquely determines the orthogonal group.

EXAMPLES:

sage: G = GO(4, GF(7), -1)
sage: G.invariant_bilinear_form()
[0 1 0 0]
[1 0 0 0]
[0 0 2 0]
[0 0 0 2]

sage: G = GO(4, GF(7), +1)
sage: G.invariant_bilinear_form()
[0 1 0 0]
[1 0 0 0]
[0 0 6 0]
[0 0 0 2]

sage: G = SO(4, GF(7), -1)
sage: G.invariant_bilinear_form()
[0 1 0 0]
[1 0 0 0]
[0 0 2 0]
[0 0 0 2]

invariant_form()

Return the symmetric bilinear form preserved by the orthogonal group.

OUTPUT:

A matrix $$M$$ such that, for every group element g, the identity $$g m g^T = m$$ holds. In characteristic different from two, this uniquely determines the orthogonal group.

EXAMPLES:

sage: G = GO(4, GF(7), -1)
sage: G.invariant_bilinear_form()
[0 1 0 0]
[1 0 0 0]
[0 0 2 0]
[0 0 0 2]

sage: G = GO(4, GF(7), +1)
sage: G.invariant_bilinear_form()
[0 1 0 0]
[1 0 0 0]
[0 0 6 0]
[0 0 0 2]

sage: G = SO(4, GF(7), -1)
sage: G.invariant_bilinear_form()
[0 1 0 0]
[1 0 0 0]
[0 0 2 0]
[0 0 0 2]

invariant_quadratic_form()

Return the quadratic form preserved by the orthogonal group.

OUTPUT:

The matrix $$Q$$ defining “orthogonal” as follows. The matrix determines a quadratic form $$q$$ on the natural vector space $$V$$, on which $$G$$ acts, by $$q(v) = v Q v^t$$. A matrix $$M$$ is an element of the orthogonal group if $$q(v) = q(v M)$$ for all $$v \in V$$.

EXAMPLES:

sage: G = GO(4, GF(7), -1)
[0 1 0 0]
[0 0 0 0]
[0 0 1 0]
[0 0 0 1]

sage: G = GO(4, GF(7), +1)
[0 1 0 0]
[0 0 0 0]
[0 0 3 0]
[0 0 0 1]

sage: G = GO(4, QQ)
[1 0 0 0]
[0 1 0 0]
[0 0 1 0]
[0 0 0 1]

sage: G = SO(4, GF(7), -1)
[0 1 0 0]
[0 0 0 0]
[0 0 1 0]
[0 0 0 1]

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

General Orthogonal Group over arbitrary rings.

EXAMPLES:

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: 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)

invariant_bilinear_form()

Return the symmetric bilinear form preserved by self.

OUTPUT:

A matrix.

EXAMPLES:

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]

invariant_form()

Return the symmetric bilinear form preserved by self.

OUTPUT:

A matrix.

EXAMPLES:

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]

invariant_quadratic_form()

Return the symmetric bilinear form preserved by self.

OUTPUT:

A matrix.

EXAMPLES:

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]

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 – (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 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: 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]
)


Using the invariant_form option:

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

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.