GAP (Forms) - Chapter 4: Constructing forms and basic functionality

Goto Chapter: Top 1 2 3 4 5 Bib Ind
[Top of Book] [Contents] [Previous Chapter] [Next Chapter]

[MathJax on]

4 Constructing forms and basic functionality
4.1 Important filters
4.1-1 Categories for forms
4.1-2 Representation for forms
4.2 Constructing forms using a matrix
4.2-1 BilinearFormByMatrix
4.2-2 QuadraticFormByMatrix
4.2-3 HermitianFormByMatrix
4.3 Constructing forms using a polynomial
4.3-1 BilinearFormByPolynomial
4.3-2 QuadraticFormByPolynomial
4.3-3 HermitianFormByPolynomial
4.4 Switching between bilinear and quadratic forms
4.4-1 QuadraticFormByBilinearForm
4.4-2 BilinearFormByQuadraticForm
4.4-3 AssociatedBilinearForm
4.5 Evaluating forms
4.5-1 EvaluateForm
4.6 Orthogonality, totally isotropic subspaces, and totally singular subspaces
4.6-1 OrthogonalSubspaceMat
4.6-2 IsIsotropicVector
4.6-3 IsSingularVector
4.6-4 IsTotallyIsotropicSubspace
4.6-5 IsTotallySingularSubspace
4.7 Attributes and properties of forms
4.7-1 IsReflexiveForm
4.7-2 IsAlternatingForm
4.7-3 IsSymmetricForm
4.7-4 IsOrthogonalForm
4.7-5 IsPseudoForm
4.7-6 IsSymplecticForm
4.7-7 IsDegenerateForm
4.7-8 IsSingularForm
4.7-9 BaseField
4.7-10 GramMatrix
4.7-11 RadicalOfForm
4.7-12 PolynomialOfForm
4.7-13 DiscriminantOfForm
4.8 Recognition of forms preserved by a classical group
4.8-1 PreservedForms
4.8-2 PreservedSesquilinearForms
4.8-3 PreservedQuadraticForms
4.9 The trivial form and some of its properties

### 4 Constructing forms and basic functionality

In this chapter, all operations to construct sesquilinear and quadratic forms are listed, along with their basic attributes and properties.

#### 4.1 Important filters

##### 4.1-1 Categories for forms

`‣ IsBilinearForm` | ( category )

`‣ IsHermitianForm` | ( category )

`‣ IsSesquilinearForm` | ( category )

`‣ IsQuadraticForm` | ( category )

`‣ IsForm` | ( category )

`‣ IsTrivialForm` | ( category )

The categories `IsBilinearForm` and `IsHermitianForm` are categories for bilinear and hermitian forms, respectively. They are disjoint and are both contained in the category `IsSesquilinearForm`.

Quadratic forms are contained in the category `IsQuadraticForm`. The categories `IsSesquilinearForm` and `IsQuadraticForm` are disjoint and are both contained in the category `IsForm`.

The user is allowed to construct the trivial form (mapping all vectors to the zero element of the field). The trivial form is an object in the category `IsTrivialForm`. This category is contained in `IsForm` and disjoint from `IsSesquilinearForm` and `IsQuadraticForm`.

##### 4.1-2 Representation for forms

`‣ IsFormRep` | ( representation )

Every form is represented by a matrix, the base field and a string describing the ``type'' of the form.

#### 4.2 Constructing forms using a matrix

##### 4.2-1 BilinearFormByMatrix

`‣ BilinearFormByMatrix`( matrix[, field] ) | ( operation )

Returns: a bilinear form

The argument matrix must be a symmetric, or skew-symmetric, square matrix over the finite field field. The argument field is an optional argument, and if it is not given, then we assume that the defining field of the bilinear form is the smallest field containing the entries of matrix. Below we give an example where the defining field can make a difference in some applications. As it is only possible to construct reflexive bilinear forms, it is checked whether the matrix matrix is symmetric or skew symmetric. If matrix matrix is not symmetric nor skew symmetric, then an error message is returned. The output is a bilinear form (i.e., an object in `IsBilinearForm`) with Gram matrix matrix and defining field field. (See 3.1 for more on bilinear forms).

    gap> mat := IdentityMat(4, GF(9));
    [ [ Z(3)^0, 0*Z(3), 0*Z(3), 0*Z(3) ], [ 0*Z(3), Z(3)^0, 0*Z(3), 0*Z(3) ],
      [ 0*Z(3), 0*Z(3), Z(3)^0, 0*Z(3) ], [ 0*Z(3), 0*Z(3), 0*Z(3), Z(3)^0 ] ]
    gap> form := BilinearFormByMatrix(mat,GF(9));
    < bilinear form >
    gap> Display(form);
    Bilinear form
    Gram Matrix:
     1 . . .
     . 1 . .
     . . 1 .
     . . . 1
    gap> mat := [[0*Z(2),Z(16)^12,0*Z(2),Z(4)^2,Z(16)^13],
    >    [Z(16)^12,0*Z(2),0*Z(2),Z(16)^11,Z(16)],
    >    [0*Z(2),0*Z(2),0*Z(2),Z(4)^2,Z(16)^3],
    >    [Z(4)^2,Z(16)^11,Z(4)^2,0*Z(2),Z(16)^3],
    >    [Z(16)^13,Z(16),Z(16)^3,Z(16)^3,0*Z(2) ]];
    [ [ 0*Z(2), Z(2^4)^12, 0*Z(2), Z(2^2)^2, Z(2^4)^13 ],
      [ Z(2^4)^12, 0*Z(2), 0*Z(2), Z(2^4)^11, Z(2^4) ],
      [ 0*Z(2), 0*Z(2), 0*Z(2), Z(2^2)^2, Z(2^4)^3 ],
      [ Z(2^2)^2, Z(2^4)^11, Z(2^2)^2, 0*Z(2), Z(2^4)^3 ],
      [ Z(2^4)^13, Z(2^4), Z(2^4)^3, Z(2^4)^3, 0*Z(2) ] ]
    gap> form := BilinearFormByMatrix(mat,GF(16));
    < bilinear form >
    gap> Display(form);
    Bilinear form
    Gram Matrix:
    z = Z(16)
        . z^12    . z^10 z^13
     z^12    .    . z^11  z^1
        .    .    . z^10  z^3
     z^10 z^11 z^10    .  z^3
     z^13  z^1  z^3  z^3    .
    gap> mat := [[1,0,0,0],[0,1,0,0],[0,0,0,1],[0,0,1,0]]*Z(7)^0;
    [ [ Z(7)^0, 0*Z(7), 0*Z(7), 0*Z(7) ], [ 0*Z(7), Z(7)^0, 0*Z(7), 0*Z(7) ],
      [ 0*Z(7), 0*Z(7), 0*Z(7), Z(7)^0 ], [ 0*Z(7), 0*Z(7), Z(7)^0, 0*Z(7) ] ]
    gap> form := BilinearFormByMatrix(mat);
    < bilinear form >
    gap> WittIndex(form);
    1
    gap> form := BilinearFormByMatrix(mat,GF(49));
    < bilinear form >
    gap> WittIndex(form);
    2

##### 4.2-2 QuadraticFormByMatrix

`‣ QuadraticFormByMatrix`( matrix[, field] ) | ( operation )

Returns: a quadratic form

The argument matrix must be a square matrix over the finite field field. The argument field is an optional argument, and if it is not given, then we assume that the defining field of the bilinear form is the smallest field containing the entries of matrix. Below we give an example where the defining field can make a difference in some applications. Any square matrix determines a quadratic form, but the Gram matrix is recomputed so that it is an upper triangle matrix. The output is a quadratic form (i.e., an object in `IsQuadraticForm`) with defining field field. (See 3.2 for more on bilinear forms).

    gap> mat := [[1,0,0,0],[0,3,0,0],[0,0,0,6],[0,0,6,0]]*Z(7)^0;
    [ [ Z(7)^0, 0*Z(7), 0*Z(7), 0*Z(7) ], [ 0*Z(7), Z(7), 0*Z(7), 0*Z(7) ],
      [ 0*Z(7), 0*Z(7), 0*Z(7), Z(7)^3 ], [ 0*Z(7), 0*Z(7), Z(7)^3, 0*Z(7) ] ]
    gap> form := QuadraticFormByMatrix(mat,GF(7));
    < quadratic form >
    gap> Display(form);
    Quadratic form
    Gram Matrix:
     1 . . .
     . 3 . .
     . . . 5
     . . . .
    gap> gf := GF(2^2);
    GF(2^2)
    gap> mat := InvariantQuadraticForm( SO(-1, 4, 4) )!.matrix;
    [ [ 0*Z(2), Z(2)^0, 0*Z(2), 0*Z(2) ], [ 0*Z(2), 0*Z(2), 0*Z(2), 0*Z(2) ],
      [ 0*Z(2), 0*Z(2), Z(2^2)^2, Z(2)^0 ], [ 0*Z(2), 0*Z(2), 0*Z(2), Z(2^2)^2 ] ]
    gap> form := QuadraticFormByMatrix( mat, gf );
    < quadratic form >
    gap> Display(form);
    Quadratic form
    Gram Matrix:
    z = Z(4)
       .   1   .   .
       .   .   .   .
       .   . z^2   1
       .   .   . z^2

The following example shows how using the argument field has influence on the properties of the constructed form.

    gap> mat :=
    > [[Z(2)^0,Z(2)^0,0*Z(2),0*Z(2)],[0*Z(2),Z(2)^0,0*Z(2),0*Z(2)],
    >  [0*Z(2),0*Z(2),0*Z(2),Z(2)^0],[0*Z(2),0*Z(2),0*Z(2),0*Z(2)]];
    [ [ Z(2)^0, Z(2)^0, 0*Z(2), 0*Z(2) ], [ 0*Z(2), Z(2)^0, 0*Z(2), 0*Z(2) ],
      [ 0*Z(2), 0*Z(2), 0*Z(2), Z(2)^0 ], [ 0*Z(2), 0*Z(2), 0*Z(2), 0*Z(2) ] ]
    gap> form := QuadraticFormByMatrix(mat);
    < quadratic form >
    gap> WittIndex(form);
    1
    gap> form := QuadraticFormByMatrix(mat,GF(4));
    < quadratic form >
    gap> WittIndex(form);
    2

##### 4.2-3 HermitianFormByMatrix

`‣ HermitianFormByMatrix`( matrix, field ) | ( operation )

Returns: a hermitian sesquilinear form

The argument matrix must be a hermitian square matrix over the finite field field, and field has square order. The field must be specified, since we can only determine the smallest field containing the entries of matrix. As it is only possible to construct reflexive sesquilinear forms, it is checked whether the matrix is a hermitian matrix, and if not, an error message is returned. The output is a hermitian sesquilinear form (i.e., an object in `IsHermitianForm`) with Gram matrix matrix and defining field field. (See 3.1 for more on hermitian forms).

    gap> gf := GF(3^2);
    GF(3^2)
    gap> mat := IdentityMat(4, gf);
    [ [ Z(3)^0, 0*Z(3), 0*Z(3), 0*Z(3) ], [ 0*Z(3), Z(3)^0, 0*Z(3), 0*Z(3) ],
      [ 0*Z(3), 0*Z(3), Z(3)^0, 0*Z(3) ], [ 0*Z(3), 0*Z(3), 0*Z(3), Z(3)^0 ] ]
    gap> form := HermitianFormByMatrix( mat, gf );
    < hermitian form >
    gap> Display(form);
    Hermitian form
    Gram Matrix:
     1 . . .
     . 1 . .
     . . 1 .
     . . . 1
    gap> mat := [[Z(11)^0,0*Z(11),0*Z(11)],[0*Z(11),0*Z(11),Z(11)],
    >     [0*Z(11),Z(11),0*Z(11)]];
    [ [ Z(11)^0, 0*Z(11), 0*Z(11) ], [ 0*Z(11), 0*Z(11), Z(11) ],
      [ 0*Z(11), Z(11), 0*Z(11) ] ]
    gap> form := HermitianFormByMatrix(mat,GF(121));
    < hermitian form >
    gap> Display(form);
    Hermitian form
    Gram Matrix:
      1  .  .
      .  .  2
      .  2  .

#### 4.3 Constructing forms using a polynomial

Suppose that f is a sesquilinear form on an n-dimensional vectorspace. Consider a vector x with coordinates x1,...,xn with xi indeterminates over the field. Then f(x,x) is a polynomial in n indeterminates. When f is alternating, f(x,x) is identically zero, but in all other cases, f(x,x) determines f completely.

Conversely, suppose that Q is a quadratic form on an n-dimensional vectorspace. Consider a vector x with coordinates x1,...,xn with xi indeterminates over the field. Then Q(x) is a polynomial in n indeterminates, and Q(x) determines Q completely.

Forms provides functionality to construct bilinear, hermitian and quadratic forms using an appropriate polynomial.

##### 4.3-1 BilinearFormByPolynomial

`‣ BilinearFormByPolynomial`( poly, r[, n] ) | ( operation )

Returns: a bilinear form

The argument poly must be a polynomial in the polynomial ring r. The (optional) last argument is the dimension for the underlying vector space of the resulting form, which by default is the number of indeterminates specified by poly. It is checked whether the polynomial is a homogeneous polynomial of degree two over the given field, and if not, an error message is returned. It is not possible to construct a nontrivial bilinear form from a polynomial in even characteristic. The output is a bilinear (orthogonal) form in the category `IsBilinearForm`. (See 3.1 for more on bilinear forms).

    gap> r := PolynomialRing( GF(11), 4);
    GF(11)[x_1,x_2,x_3,x_4]
    gap> vars := IndeterminatesOfPolynomialRing( r );
    [ x_1, x_2, x_3, x_4 ]
    gap> pol := vars[1]*vars[2]+vars[3]*vars[4];
    x_1*x_2+x_3*x_4
    gap> form := BilinearFormByPolynomial(pol, r, 4);
    < bilinear form >
    gap> Display(form);
    Bilinear form
    Gram Matrix:
      .  6  .  .
      6  .  .  .
      .  .  .  6
      .  .  6  .
    Polynomial: x_1*x_2+x_3*x_4
    gap> r := PolynomialRing(GF(4),2);
    GF(2^2)[x_1,x_2]
    gap> pol := r.1*r.2;
    x_1*x_2
    gap> form := BilinearFormByPolynomial(pol,r);
    Error, No orthogonal form can be associated with a quadratic polynomial in even cha\
    ra
    cteristic
     called from
    BilinearFormByPolynomial( pol, pring, n
     ) at ./pkg/forms/lib/forms.gi:470 called from
    <function "unknown">( <arguments> )
     called from read-eval loop at line 14 of *stdin*
    you can 'quit;' to quit to outer loop, or
    you can 'return;' to continue
    brk> quit;

##### 4.3-2 QuadraticFormByPolynomial

`‣ QuadraticFormByPolynomial`( poly, r[, n] ) | ( operation )

Returns: a quadratic form

The argument poly must be a polynomial in the polynomial ring r. The (optional) last argument is the dimension for the underlying vector space of the resulting form, which by default is the number of indeterminates specified by poly. It is checked whether the polynomial is a homogeneous polynomial of degree two over the given field, and if not, an error message is returned. The output is a quadratic form in the category `IsQuadraticForm`. (See 3.2 for more on quadratic forms).

    gap> r := PolynomialRing( GF(8), 3);
    GF(2^3)[x_1,x_2,x_3]
    gap> poly := r.1^2 + r.2^2 + r.3^2;
    x_1^2+x_2^2+x_3^2
    gap> form := QuadraticFormByPolynomial(poly, r);
    < quadratic form >
    gap> RadicalOfForm(form);
    <vector space over GF(2^3), with 63 generators>
    gap> r := PolynomialRing(GF(9),4);
    GF(3^2)[x_1,x_2,x_3,x_4]
    gap> poly := Z(3)^2*r.1^2+r.2^2+r.3*r.4;
    x_1^2+x_2^2+x_3*x_4
    gap> qform := QuadraticFormByPolynomial(poly,r);
    < quadratic form >
    gap> Display(qform);
    Quadratic form
    Gram Matrix:
     1 . . .
     . 1 . .
     . . . 1
     . . . .
    Polynomial: x_1^2+x_2^2+x_3*x_4

##### 4.3-3 HermitianFormByPolynomial

`‣ HermitianFormByPolynomial`( poly, r[, n] ) | ( operation )

Returns: an hermitian form

The argument poly must be a polynomial in the polynomial ring r defined over a finite field of square order q2 The (optional) last argument is the dimension for the underlying vector space of the resulting form, which by default is the number of indeterminates specified by poly. It is checked whether the polynomial is a homogeneous polynomial of degree q+1, and if not, an error message is returned. The output is a hermitian form in the category `IsHermitianForm`. (See 3.1 for more on hermitian forms).

    gap> r := PolynomialRing( GF(9), 4);
    GF(3^2)[x_1,x_2,x_3,x_4]
    gap> vars := IndeterminatesOfPolynomialRing( r );
    [ x_1, x_2, x_3, x_4 ]
    gap> poly := vars[1]*vars[2]^3+vars[1]^3*vars[2]+
    >              vars[3]*vars[4]^3+vars[3]^3*vars[4];
    x_1^3*x_2+x_1*x_2^3+x_3^3*x_4+x_3*x_4^3
    gap> form := HermitianFormByPolynomial(poly,r);
    < hermitian form >
    gap> Display(form);
    Hermitian form
    Gram Matrix:
     . 1 . .
     1 . . .
     . . . 1
     . . 1 .
    Polynomial: x_1^3*x_2+x_1*x_2^3+x_3^3*x_4+x_3*x_4^3

#### 4.4 Switching between bilinear and quadratic forms

When the characteristic of the field is odd, a homogeneous quadratic polynomial determines a bilinear form, and a quadratic form. In some situations, when a quadratic form Q is given, it is useful to consider the bilinear form f such that f(v,v)=Q(v), i.e., the bilinear form which is determined by exactly the same polynomial determining the quadratic form Q. Forms provides functionality to construct a bilinear form f from a given quadratic form Q such that f(v,v)=Q(v). Conversely, we can extract a quadratic form from a given bilinear form.

##### 4.4-1 QuadraticFormByBilinearForm

`‣ QuadraticFormByBilinearForm`( form ) | ( operation )

Returns: a quadratic form

The argument form is an orthogonal bilinear form (and thus it belongs to `IsBilinearForm`), otherwise a ``No method found'' error is returned. The output is the quadratic form Q (an object in `IsQuadraticForm`), such that Q(v) = form(v,v) for all vectors v in a vector space equipped with form. An error is returned when the characteristic of the field is even, or when form is not orthogonal.

    gap> mat := [ [ Z(3^2)^7, Z(3)^0, Z(3^2)^2, 0*Z(3), Z(3^2)^5 ],
    >    [ Z(3)^0, Z(3^2)^7, Z(3^2)^6, Z(3^2)^5, Z(3^2)^2 ],
    >    [ Z(3^2)^2, Z(3^2)^6, Z(3^2)^7, Z(3^2)^2, Z(3^2)^2 ],
    >    [ 0*Z(3), Z(3^2)^5, Z(3^2)^2, Z(3^2)^6, Z(3^2)^7 ],
    >    [ Z(3^2)^5, Z(3^2)^2, Z(3^2)^2, Z(3^2)^7, Z(3) ] ];
    [ [ Z(3^2)^7, Z(3)^0, Z(3^2)^2, 0*Z(3), Z(3^2)^5 ],
      [ Z(3)^0, Z(3^2)^7, Z(3^2)^6, Z(3^2)^5, Z(3^2)^2 ],
      [ Z(3^2)^2, Z(3^2)^6, Z(3^2)^7, Z(3^2)^2, Z(3^2)^2 ],
      [ 0*Z(3), Z(3^2)^5, Z(3^2)^2, Z(3^2)^6, Z(3^2)^7 ],
      [ Z(3^2)^5, Z(3^2)^2, Z(3^2)^2, Z(3^2)^7, Z(3) ] ]
    gap> form := BilinearFormByMatrix(mat,GF(9));
    < bilinear form >
    gap> Q := QuadraticFormByBilinearForm(form);
    < quadratic form >
    gap> Display(form);
    Bilinear form
    Gram Matrix:
    z = Z(9)
     z^7   1 z^2   . z^5
       1 z^7 z^6 z^5 z^2
     z^2 z^6 z^7 z^2 z^2
       . z^5 z^2 z^6 z^7
     z^5 z^2 z^2 z^7   2
    gap> Display(Q);
    Quadratic form
    Gram Matrix:
    z = Z(9)
     z^7   2 z^6   . z^1
       . z^7 z^2 z^1 z^6
       .   . z^7 z^6 z^6
       .   .   . z^6 z^3
       .   .   .   .   2
    gap> Set(List(GF(9)^5),x->[x,x]^form=x^Q);
    [ true ]
    gap> PolynomialOfForm(form);
    Z(3^2)^7*x_1^2-x_1*x_2+Z(3^2)^6*x_1*x_3+Z(3^2)*x_1*x_5+Z(3^2)^7*x_2^2+Z(3^2)^2
    *x_2*x_3+Z(3^2)*x_2*x_4+Z(3^2)^6*x_2*x_5+Z(3^2)^7*x_3^2+Z(3^2)^6*x_3*x_4+Z(3^2
    )^6*x_3*x_5+Z(3^2)^6*x_4^2+Z(3^2)^3*x_4*x_5-x_5^2
    gap> PolynomialOfForm(Q);
    Z(3^2)^7*x_1^2-x_1*x_2+Z(3^2)^6*x_1*x_3+Z(3^2)*x_1*x_5+Z(3^2)^7*x_2^2+Z(3^2)^2
    *x_2*x_3+Z(3^2)*x_2*x_4+Z(3^2)^6*x_2*x_5+Z(3^2)^7*x_3^2+Z(3^2)^6*x_3*x_4+Z(3^2
    )^6*x_3*x_5+Z(3^2)^6*x_4^2+Z(3^2)^3*x_4*x_5-x_5^2

Note that the given bilinear form form is not the associated bilinear form of the constructed quadratic form Q, according to the definition in Section 3.2. We can construct the associated bilinear forms by using `AssociatedBilinearForm` (4.4-3). (See 3.2 for more on quadratic forms).

##### 4.4-2 BilinearFormByQuadraticForm

`‣ BilinearFormByQuadraticForm`( Q ) | ( operation )

Returns: a bilinear form

The argument Q must be a quadratic form (and thus it belongs to `IsQuadraticForm`). The output is the orthogonal bilinear form f (an object in `IsBilinearForm`), such that f(v,v) = Q(v) for all vectors v in a vector space equipped with Q. An error is returned when the characteristic of the field is even.

    gap> r := PolynomialRing(GF(9),4);
    GF(3^2)[x_1,x_2,x_3,x_4]
    gap> poly := -r.1*r.2+Z(3^2)*r.3^2+r.4^2;
    -x_1*x_2+Z(3^2)*x_3^2+x_4^2
    gap> qform := QuadraticFormByPolynomial(poly,r);
    < quadratic form >
    gap> Display( qform );
    Quadratic form
    Gram Matrix:
    z = Z(9)
       .   2   .   .
       .   .   .   .
       .   . z^1   .
       .   .   .   1
    Polynomial: -x_1*x_2+Z(3^2)*x_3^2+x_4^2
    gap> form := BilinearFormByQuadraticForm( qform );
    < bilinear form >
    gap> Display(form);
    Bilinear form
    Gram Matrix:
    z = Z(9)
       .   1   .   .
       1   .   .   .
       .   . z^1   .
       .   .   .   1
    gap> Set(GF(9)^4, x -> [x,x]^form = x^qform);
    [ true ]

Note that the constructed bilinear form f is not the associated bilinear form of the given quadratic form Q, according to the definition in Section 3.2. We can construct the associated bilinear forms by using `AssociatedBilinearForm` (4.4-3). (See 3.2 for more on quadratic forms).

##### 4.4-3 AssociatedBilinearForm

`‣ AssociatedBilinearForm`( Q ) | ( operation )

Returns: a bilinear form

The argument Q must be a quadratic form (and thus it belongs to `IsQuadraticForm`). The output is the associated bilinear form f (an object in `IsBilinearForm`), as defined in Section 3.2, i.e. the bilinear form f such that f(v,w) = Q(v+w)-Q(v)-Q(w) for all vectors v,w in a vector space equipped with Q. (See 3.2 for more on quadratic forms).

    gap> r:= PolynomialRing(GF(121),6);
    GF(11^2)[x_1,x_2,x_3,x_4,x_5,x_6]
    gap> poly := r.1*r.5-r.2*r.6+r.3*r.4;
    x_1*x_5-x_2*x_6+x_3*x_4
    gap> form := QuadraticFormByPolynomial(poly,r);
    < quadratic form >
    gap> aform := AssociatedBilinearForm(form);
    < bilinear form >
    gap> Display(aform);
    Bilinear form
    Gram Matrix:
      .  .  .  .  1  .
      .  .  .  .  . 10
      .  .  .  1  .  .
      .  .  1  .  .  .
      1  .  .  .  .  .
      . 10  .  .  .  .

#### 4.5 Evaluating forms

##### 4.5-1 EvaluateForm

`‣ EvaluateForm`( f, u[, v] ) | ( operation )

Returns: a finite field element

The argument f is either a sesquilinear or quadratic form defined over a finite field GF(q). The other argument is a pair of vectors or matrices, or a single vector or matrix. In case that u (and v when using three arguments) is a matrix, its rows represent a basis for the subspace (or subspaces) where f is evaluated in. This operation evaluates the form on the given vector or pair of vectors and returns an element in GF(q). There is also an overloading of the operation \^ where `(u,v)^f` represents f(u,v) in the case that f is sesquilinear, and `u^f` stands for f(u) in the quadratic case. So for convenience, the user may use this compressed version of this operation, which we show in the following example:

    gap> mat := [[Z(8),0,0,0],[0,0,Z(8)^4,0],[0,0,0,1],[0,0,0,0]]*Z(8)^0;;
    gap> form := QuadraticFormByMatrix(mat,GF(8));
    < quadratic form >
    gap> u := [ Z(2^3)^4, Z(2^3)^4, Z(2)^0, Z(2^3)^3 ];
    [ Z(2^3)^4, Z(2^3)^4, Z(2)^0, Z(2^3)^3 ]
    gap> EvaluateForm( form, u );
    Z(2^3)^6
    gap> u^form;
    Z(2^3)^6
    gap> gram := [[0,0,0,0,0,2],[0,0,0,0,2,0],[0,0,0,1,0,0],
    >               [0,0,1,0,0,0],[0,2,0,0,0,0],[2,0,0,0,0,0]]*Z(3)^0;;
    gap> form := BilinearFormByMatrix(gram,GF(3));
    < bilinear form >
    gap> u := [ [ Z(3)^0, 0*Z(3), 0*Z(3), Z(3)^0, 0*Z(3), Z(3)^0 ],
    >   [ 0*Z(3), 0*Z(3), Z(3)^0, Z(3)^0, Z(3), 0*Z(3) ] ];;
    gap> v := [ [ Z(3)^0, 0*Z(3), Z(3)^0, Z(3), 0*Z(3), Z(3) ],
    >   [ 0*Z(3), Z(3)^0, 0*Z(3), Z(3), Z(3), Z(3) ] ];;
    gap> EvaluateForm( form, u, v);
    [ [ Z(3)^0, Z(3)^0 ], [ 0*Z(3), 0*Z(3) ] ]
    gap> [u,v]^form;
    [ [ Z(3)^0, Z(3)^0 ], [ 0*Z(3), 0*Z(3) ] ]

#### 4.6 Orthogonality, totally isotropic subspaces, and totally singular subspaces

##### 4.6-1 OrthogonalSubspaceMat

`‣ OrthogonalSubspaceMat`( form, v ) | ( operation )

`‣ OrthogonalSubspaceMat`( form, mat ) | ( operation )

Returns: a base of the subspace orthogonal to the given vector or subspace with relation to the given form

The argument form is a sesquilinear or quadratic form. For a given vector v, this operation returns a base of the subspace orthogonal to v with relation to the sesquilinear form or with relation to the associated bilinear form of the quadratic form form. For a given matrix mat, this operation returns a base of the subspace orthogonal to the subspace spanned by the rows of mat with relation to the sesquilinear form or with relation to the associated bilinear form of the quadratic form form

    gap> mat := [[0,0,0,-2],[0,0,-3,0],[0,3,0,0],[2,0,0,0]]*Z(7)^0;
    [ [ 0*Z(7), 0*Z(7), 0*Z(7), Z(7)^5 ], [ 0*Z(7), 0*Z(7), Z(7)^4, 0*Z(7) ],
      [ 0*Z(7), Z(7), 0*Z(7), 0*Z(7) ], [ Z(7)^2, 0*Z(7), 0*Z(7), 0*Z(7) ] ]
    gap> form := BilinearFormByMatrix(mat);
    < bilinear form >
    gap> v := [0*Z(7),Z(7)^0,Z(7)^3,Z(7)^5];
    [ 0*Z(7), Z(7)^0, Z(7)^3, Z(7)^5 ]
    gap> vperp := OrthogonalSubspaceMat(form,v);
    [ [ Z(7)^0, Z(7)^0, 0*Z(7), 0*Z(7) ], [ Z(7)^0, 0*Z(7), Z(7)^0, 0*Z(7) ],
      [ 0*Z(7), 0*Z(7), 0*Z(7), Z(7)^0 ] ]
    gap> List(vperp,x->[x,v]^form);
    [ 0*Z(7), 0*Z(7), 0*Z(7) ]
    gap> sub := [[1,1,0,0],[0,0,1,2]]*Z(7)^0;
    [ [ Z(7)^0, Z(7)^0, 0*Z(7), 0*Z(7) ], [ 0*Z(7), 0*Z(7), Z(7)^0, Z(7)^2 ] ]
    gap> subperp := OrthogonalSubspaceMat(form,sub);
    [ [ Z(7)^0, Z(7)^0, 0*Z(7), 0*Z(7) ], [ 0*Z(7), 0*Z(7), Z(7)^4, Z(7)^0 ] ]
    gap> List(subperp,x->List(sub,y->[x,y]^form));
    [ [ 0*Z(7), 0*Z(7) ], [ 0*Z(7), 0*Z(7) ] ]
    gap> mat := [[1,0,0],[0,0,1],[0,0,0]]*Z(2)^0;
    [ [ Z(2)^0, 0*Z(2), 0*Z(2) ], [ 0*Z(2), 0*Z(2), Z(2)^0 ],
      [ 0*Z(2), 0*Z(2), 0*Z(2) ] ]
    gap> form := QuadraticFormByMatrix(mat);
    < quadratic form >
    gap> v := [Z(2)^0,Z(2)^0,0*Z(2)];
    [ Z(2)^0, Z(2)^0, 0*Z(2) ]
    gap> vperp := OrthogonalSubspaceMat(form,v);
    [ <an immutable GF2 vector of length 3>, <an immutable GF2 vector of length
        3> ]
    gap> bil_form := AssociatedBilinearForm(form);
    < bilinear form >
    gap> List(vperp,x->[x,v]^bil_form);
    [ 0*Z(2), 0*Z(2) ]
    gap> sub := [[1,0,1],[1,0,0]]*Z(2)^0;
    [ [ Z(2)^0, 0*Z(2), Z(2)^0 ], [ Z(2)^0, 0*Z(2), 0*Z(2) ] ]
    gap> subperp := OrthogonalSubspaceMat(form,sub);
    [ <an immutable GF2 vector of length 3>, <an immutable GF2 vector of length
        3> ]
    gap> List(subperp,x->List(sub,y->[x,y]^bil_form));
    [ [ 0*Z(2), 0*Z(2) ], [ 0*Z(2), 0*Z(2) ] ]

##### 4.6-2 IsIsotropicVector

`‣ IsIsotropicVector`( form, v ) | ( operation )

Returns: true or false

The operation return true if and only if v is isotropic with relation to the sesquilinear or quadratic form form.

    gap> mat := [[1,0,0,0],[0,-1,0,0],[0,0,0,1],[0,0,1,0]]*Z(41)^0;
    [ [ Z(41)^0, 0*Z(41), 0*Z(41), 0*Z(41) ],
      [ 0*Z(41), Z(41)^20, 0*Z(41), 0*Z(41) ],
      [ 0*Z(41), 0*Z(41), 0*Z(41), Z(41)^0 ],
      [ 0*Z(41), 0*Z(41), Z(41)^0, 0*Z(41) ] ]
    gap> form := BilinearFormByMatrix(mat);
    < bilinear form >
    gap> v := [1,1,0,0]*Z(41)^0;
    [ Z(41)^0, Z(41)^0, 0*Z(41), 0*Z(41) ]
    gap> IsIsotropicVector(form,v);
    true
    gap> mat := [[1,0,0,0,0],[0,0,0,0,1],[0,0,0,0,0],[0,0,1,0,0],[0,0,0,0,0]]*Z(8)^0;
    [ [ Z(2)^0, 0*Z(2), 0*Z(2), 0*Z(2), 0*Z(2) ],
      [ 0*Z(2), 0*Z(2), 0*Z(2), 0*Z(2), Z(2)^0 ],
      [ 0*Z(2), 0*Z(2), 0*Z(2), 0*Z(2), 0*Z(2) ],
      [ 0*Z(2), 0*Z(2), Z(2)^0, 0*Z(2), 0*Z(2) ],
      [ 0*Z(2), 0*Z(2), 0*Z(2), 0*Z(2), 0*Z(2) ] ]
    gap> form := QuadraticFormByMatrix(mat);
    < quadratic form >
    gap> v1 := [1,0,0,0,0]*Z(8)^0;
    [ Z(2)^0, 0*Z(2), 0*Z(2), 0*Z(2), 0*Z(2) ]
    gap> v2 := [0,1,0,0,0]*Z(8)^0;
    [ 0*Z(2), Z(2)^0, 0*Z(2), 0*Z(2), 0*Z(2) ]
    gap> IsIsotropicVector(form,v1);
    true
    gap> IsIsotropicVector(form,v2);
    true

##### 4.6-3 IsSingularVector

`‣ IsSingularVector`( form, v ) | ( operation )

Returns: true or false

The operation return true if and only if v is singular with relation to the quadratic form form. Note that only when the characteristic of the field is odd, the singular vectors with relation to a quadratic form are the isotropic vectors with relation to its associated form.

    gap> mat := [[1,0,0,0,0],[0,0,0,0,1],[0,0,0,0,0],[0,0,1,0,0],[0,0,0,0,0]]*Z(8)^0;
    [ [ Z(2)^0, 0*Z(2), 0*Z(2), 0*Z(2), 0*Z(2) ],
      [ 0*Z(2), 0*Z(2), 0*Z(2), 0*Z(2), Z(2)^0 ],
      [ 0*Z(2), 0*Z(2), 0*Z(2), 0*Z(2), 0*Z(2) ],
      [ 0*Z(2), 0*Z(2), Z(2)^0, 0*Z(2), 0*Z(2) ],
      [ 0*Z(2), 0*Z(2), 0*Z(2), 0*Z(2), 0*Z(2) ] ]
    gap> form := QuadraticFormByMatrix(mat);
    < quadratic form >
    gap> v1 := [1,0,0,0,0]*Z(8)^0;
    [ Z(2)^0, 0*Z(2), 0*Z(2), 0*Z(2), 0*Z(2) ]
    gap> v2 := [0,1,0,0,0]*Z(8)^0;
    [ 0*Z(2), Z(2)^0, 0*Z(2), 0*Z(2), 0*Z(2) ]
    gap> IsSingularVector(form,v1);
    false
    gap> IsSingularVector(form,v2);
    true
    gap> IsIsotropicVector(form,v1);
    true
    gap> IsIsotropicVector(form,v2);
    true

##### 4.6-4 IsTotallyIsotropicSubspace

`‣ IsTotallyIsotropicSubspace`( form, sub ) | ( operation )

Returns: true or false

The operation return true if and only if the subspace spanned by the vectors in the list sub is totally isotropic with relation to the sesquilinear or quadratic form form. Note that when form is a quadratic form, it is checked whether sub generates a subspace that is totally isotropic with relation to the associated bilinear form of form.

    gap> mat := [[1,0,0,0],[0,-1,0,0],[0,0,0,1],[0,0,1,0]]*Z(7)^0;
    [ [ Z(7)^0, 0*Z(7), 0*Z(7), 0*Z(7) ], [ 0*Z(7), Z(7)^3, 0*Z(7), 0*Z(7) ],
      [ 0*Z(7), 0*Z(7), 0*Z(7), Z(7)^0 ], [ 0*Z(7), 0*Z(7), Z(7)^0, 0*Z(7) ] ]
    gap> form := BilinearFormByMatrix(mat);
    < bilinear form >
    gap> sub:= [[Z(7)^0,0*Z(7),Z(7)^0,Z(7)],[0*Z(7),Z(7)^0,Z(7)^0,Z(7)^4]];
    [ [ Z(7)^0, 0*Z(7), Z(7)^0, Z(7) ], [ 0*Z(7), Z(7)^0, Z(7)^0, Z(7)^4 ] ]
    gap> IsTotallyIsotropicSubspace(form,sub);
    true
    gap> mat := IdentityMat(6,GF(2));
    [ <a GF2 vector of length 6>, <a GF2 vector of length 6>,
      <a GF2 vector of length 6>, <a GF2 vector of length 6>,
      <a GF2 vector of length 6>, <a GF2 vector of length 6> ]
    gap> form := HermitianFormByMatrix(mat,GF(4));
    < hermitian form >
    gap> sub := [[Z(2)^0,0*Z(2),0*Z(2),Z(2)^0,Z(2)^0,Z(2)^0],
    >   [0*Z(2),Z(2)^0,0*Z(2),Z(2^2)^2,Z(2^2),Z(2)^0],
    >   [0*Z(2),0*Z(2),Z(2)^0,Z(2)^0,Z(2^2),Z(2^2)^2]];
    [ [ Z(2)^0, 0*Z(2), 0*Z(2), Z(2)^0, Z(2)^0, Z(2)^0 ],
      [ 0*Z(2), Z(2)^0, 0*Z(2), Z(2^2)^2, Z(2^2), Z(2)^0 ],
      [ 0*Z(2), 0*Z(2), Z(2)^0, Z(2)^0, Z(2^2), Z(2^2)^2 ] ]
    gap> IsTotallyIsotropicSubspace(form,sub);
    true

##### 4.6-5 IsTotallySingularSubspace

`‣ IsTotallySingularSubspace`( form, sub ) | ( operation )

Returns: true or false

The operation return true if and only if the subspace spanned by the vectors in the list sub is totally singular with relation to quadratic form form. Note that only when the characteristic of the field is odd, the totally singular subspaces of given dimension n with relation to a quadratic form are exactly the totally isotropic subspaces of dimension n with relation to its associated form.

    gap> mat := [[1,0,0,0,0],[0,0,0,0,1],[0,0,0,0,0],[0,0,1,0,0],[0,0,0,0,0]]*Z(8)^0;
    [ [ Z(2)^0, 0*Z(2), 0*Z(2), 0*Z(2), 0*Z(2) ],
      [ 0*Z(2), 0*Z(2), 0*Z(2), 0*Z(2), Z(2)^0 ],
      [ 0*Z(2), 0*Z(2), 0*Z(2), 0*Z(2), 0*Z(2) ],
      [ 0*Z(2), 0*Z(2), Z(2)^0, 0*Z(2), 0*Z(2) ],
      [ 0*Z(2), 0*Z(2), 0*Z(2), 0*Z(2), 0*Z(2) ] ]
    gap> form := QuadraticFormByMatrix(mat);
    < quadratic form >
    gap> sub := [[Z(2)^0,0*Z(2),Z(2^3)^6,Z(2^3),Z(2^3)^3],
    >        [0*Z(2),Z(2)^0,Z(2^3)^6,Z(2^3)^2,Z(2^3)]];
    [ [ Z(2)^0, 0*Z(2), Z(2^3)^6, Z(2^3), Z(2^3)^3 ],
      [ 0*Z(2), Z(2)^0, Z(2^3)^6, Z(2^3)^2, Z(2^3) ] ]
    gap> IsTotallySingularSubspace(form,sub);
    true

#### 4.7 Attributes and properties of forms

##### 4.7-1 IsReflexiveForm

`‣ IsReflexiveForm`( f ) | ( property )

Returns: true or false.

A sesquilinear form f on a vector space V is reflexive if f(v,w)=0 ⇒ f(w,v)=0 for all v,w ∈ V. The argument f must be a sesquilinear form (and thus it belongs to `IsSesquilinearForm`). A sesquilinear form f is reflexive if whenever we have f(u,v)=0, for two vectors u,v in the associated vector space, then we also have f(v,u)=0. This attribute simply returns true or false according to whether f is reflexive or not, and is stored as a property of f. It is not possible in this version of Forms to construct non-reflexive forms. (See 3.1 for more on reflexive sesquilinear forms).

##### 4.7-2 IsAlternatingForm

`‣ IsAlternatingForm`( f ) | ( property )

Returns: true or false.

A sesquilinear form f on a vector space V is alternating if f(v,v)=0 for all v ∈ V. The argument f must be a sesquilinear form (and thus it belongs to `IsSesquilinearForm`). A bilinear form f is alternating if f(v,v)=0 for all v. This method simply returns true or false according to whether f is alternating or not, and is stored as a property of f. (See 3.1 for more on alternating sesquilinear forms).

##### 4.7-3 IsSymmetricForm

`‣ IsSymmetricForm`( f ) | ( property )

Returns: true or false.

A sesquilinear form f on a vector space V is symmetric if f(v,w)=f(w,v) for all v,w ∈ V. The argument f must be a sesquilinear form (and thus it belongs to `IsSesquilinearForm`). A bilinear form f is symmetric if f(u,v)=f(v,u) for all pairs of vectors u and v. This attribute simply returns true or false according to whether f is symmetric or not, and is stored as a property of f. (See 3.1 for more on symmetric sesquilinear forms).

##### 4.7-4 IsOrthogonalForm

`‣ IsOrthogonalForm`( f ) | ( property )

Returns: true or false.

The argument f must be a sesquilinear form (and thus it belongs to `IsSesquilinearForm`). A bilinear form f is called orthogonal if the characteristic of the underlying field is odd, and f is a symmetric form. (See 3.1 for more on bilinear forms). This operation simply returns true or false according to whether f is an orthogonal bilinear form or not, and is stored as a property of f.

##### 4.7-5 IsPseudoForm

`‣ IsPseudoForm`( f ) | ( property )

Returns: true or false.

When the characteristic of the field is odd, we call a form f orthogonal if and only f is symmetric, and when the characteristic of the field is even, we call a form f pseudo if and only if f is symmetric but not alternating. The argument f must be a sesquilinear form (and thus it belongs to `IsSesquilinearForm`). (See 3.1 for more on pseudo forms). This method simply returns true or false according to whether f is a pseudo form or not, and is stored as a property of f.

##### 4.7-6 IsSymplecticForm

`‣ IsSymplecticForm`( f ) | ( property )

Returns: true or false.

We call a bilinear form f symplectic if and only if f is alternating. The argument f must be a sesquilinear form (and thus it belongs to `IsSesquilinearForm`). (See 3.1 for more on symplectic forms). This method simply returns true or false according to whether f is symplectic or not, and is stored as a property of f.

##### 4.7-7 IsDegenerateForm

`‣ IsDegenerateForm`( f ) | ( property )

Returns: true or false.

The argument f must be a form (and thus it belongs to `IsForm`). A sesquilinear form f is degenerate if its radical is non-trivial. A quadratic form is degenerate if and only if the radical of the associated bilinear form is non-trivial. Note that degeneracy for quadratic forms is too restrictive if the characteristic is even. See also `IsSingularForm` (4.7-8). This attribute simply returns true or false according to whether f is degenerate or not, and is stored as a property of f.

##### 4.7-8 IsSingularForm

`‣ IsSingularForm`( f ) | ( property )

Returns: true or false.

The argument f must be a quadratic form (and thus it belongs to `IsQuadraticForm`). A quadratic form f is singular if its radical is non-trivial. When the characteristic of the field is odd, a quadratic form is singular if and only if it is degenerate. This is not the case when the characteristic of the field is even. This method simply returns true or false according to whether f is singular or not, and is stored as a property of f.

##### 4.7-9 BaseField

`‣ BaseField`( f ) | ( attribute )

Returns: the underlying field of f.

The argument f must be a form (and thus it belongs to `IsForm`). The method returns the field which is stored as the defining field of f. We sometimes stipulate in Forms that a form have a defining field, for mathematical reasons. Clearly, to define a hermitian form one needs to specify the field of scalars for the vector space that you wish your hermitian form to act on. The default, if the user has not specified a field on creation of a form, is the smallest field containing the entries or coefficients of the input (a matrix or polynomial). Having a particular defining field for a form can be very useful, for example, when one wants to find a change of basis from one form to another (isometric) form. In this case, one needs to know in which GL(d,q) the base-transition matrix should be taken.

##### 4.7-10 GramMatrix

`‣ GramMatrix`( f ) | ( attribute )

Returns: the Gram matrix of f.

The argument f must be a form (and thus it belongs to `IsForm`). This method returns the Gram matrix of f (see 3.1 and 3.2).

##### 4.7-11 RadicalOfForm

`‣ RadicalOfForm`( f ) | ( attribute )

Returns: The radical of the form f

The argument f must be a form (and thus it belongs to `IsForm`) on some vector space V. The radical of a sesquilinear form f is the subspace consisting of vectors which are orthogonal to every vector, i.e.,

Rad(f) = {v ∈ V | f(v,w) = 0 for all w ∈ V}.

The radical of the quadratic form Q, is the intersection of the set of all singular vectors with relation to Q and the radical of the associated bilinear form f (see `AssociatedBilinearForm` (4.4-3)), i.e.

Rad(Q) = {v ∈ V | Q(v) = 0 and v ∈ Rad(f)}.

    gap> r := PolynomialRing( GF(8), 3 );
    GF(2^3)[x_1,x_2,x_3]
    gap> poly := r.1^2 + r.2 * r.3;
    x_1^2+x_2*x_3
    gap> form := QuadraticFormByPolynomial( poly, r );
    < quadratic form >
    gap> r := RadicalOfForm( form );
    <vector space over GF(2^3), with 0 generators>
    gap> Dimension(r);
    0

##### 4.7-12 PolynomialOfForm

`‣ PolynomialOfForm`( f ) | ( attribute )

Returns: the polynomial associated with f.

The argument f must be a form (and thus it belongs to `IsForm`). All forms, except for bilinear forms in even characteristic, have an associated polynomial defining a quadratic or hermitian form (see 3.1 and 3.2). This method returns the polynomial associated with f, and if not already bound, stores it as a property of f.

    gap> mat := [ [ Z(8) , 0*Z(2), 0*Z(2), 0*Z(2), 0*Z(2) ],
    >  [ 0*Z(2), Z(2)^0, Z(2^3)^5, 0*Z(2), 0*Z(2) ],
    >  [ 0*Z(2), 0*Z(2), 0*Z(2), 0*Z(2), 0*Z(2) ],
    >  [ 0*Z(2), 0*Z(2), 0*Z(2), 0*Z(2), Z(2)^0 ],
    >  [ 0*Z(2), 0*Z(2), 0*Z(2), 0*Z(2), 0*Z(2) ] ];;
    gap> form := QuadraticFormByMatrix(mat,GF(8));
    < quadratic form >
    gap> PolynomialOfForm(form);
    Z(2^3)*x_1^2+x_2^2+Z(2^3)^5*x_2*x_3+x_4*x_5

##### 4.7-13 DiscriminantOfForm

`‣ DiscriminantOfForm`( f ) | ( attribute )

Returns: a string

The argument f must be a form (and thus it belongs to `IsForm`). Given a quadratic or bilinear form f of even dimension, this operation returns a string: ``square'' or ``nonsquare''. More specifically, let f be a from over GF(q), and let M be the Gram matrix of f. Define the discriminant of Q (n.b., quasideterminant in [CCN+85]) as `square' if det(M) is a square of GF(q), and `non-square' otherwise. The discriminant is an invariant of nondegenerate orthogonal spaces over finite fields of odd order, up to isometry. Thus, discriminants can be used to delineate the isometry type of an orthogonal form in even (algebraic) dimension. The discriminant of a hermitian form is not defined, and applying this operation on a hermitian form, will result in an error message.

    gap> gram := InvariantQuadraticForm(GO(-1,4,5))!.matrix;;
    gap> qform := QuadraticFormByMatrix(gram, GF(5));
    < quadratic form >
    gap> DiscriminantOfForm( qform );
    "nonsquare"

#### 4.8 Recognition of forms preserved by a classical group

In this section, we describe a function that was initially developed by Frank Celler (and which has now been adapted to Forms) for the recognition of quadratic and sesquilinear forms left invariant by a matrix group. More importantly, we should stress that this routine differs to that already offered by the MeatAxe in that it finds sesquilinear forms preserved up to scalars. Eventually, the procedure used for finding preserved sesquilinear forms does use the MeatAxe but in some cases it can rule out the existence of preserved forms without calling the MeatAxe. For more information on the algorithm, please see [CLGN+08].

##### 4.8-1 PreservedForms

`‣ PreservedForms`( group ) | ( operation )

Returns: a list of forms

The argument group is a matrix group. The function uses random methods to find all of the bilinear, unitary or quadratic forms preserved by group (the trivial form is also a possibility) up to a scalar. Since the procedure relies on a pseudo-random generator, the user may need to execute the operation more than once to find all invariant sesquilinear forms. Note that when possible, a quadratic form will be given.

    gap> group := GO(-1,4,4);
    GO(-1,4,4)
    gap> pres_forms := PreservedForms(group);
    [ < quadratic form > ]
    gap> group := GO(1,6,9);
    GO(+1,6,9)
    gap> pres_forms := PreservedForms(group);
    [ < quadratic form > ]
    gap> group := SU(4,16);
    SU(4,16)
    gap> pres_forms := PreservedForms(group);
    [ < hermitian form > ]

The next example demonstrates the impact of randomized methods on the number of preserved forms returned. For the particular matrix group, two preserved forms are returned after four calls of the operation.

    gap> gens := [ [ [ Z(5)^0, 0*Z(5), 0*Z(5), 0*Z(5) ],
    > 	[ 0*Z(5), 0*Z(5), Z(5)^3, Z(5^2)^21 ],
    > 	[ 0*Z(5), Z(5), Z(5), Z(5^2)^3 ],
    >      	[ 0*Z(5), Z(5^2)^21, Z(5^2)^15, Z(5)^2 ] ],
    >   [ [ Z(5)^3, Z(5^2)^7, Z(5^2)^16, Z(5^2)^15 ],
    >       	[ 0*Z(5), Z(5)^0, Z(5^2)^4, Z(5)^3 ],
    >       	[ Z(5^2)^22, Z(5^2)^10, Z(5^2)^21, Z(5)^2 ],
    >       	[ Z(5^2)^7, Z(5^2)^23, Z(5^2)^9, Z(5^2)^11 ] ],
    >   [ [ 0*Z(5), Z(5^2), 0*Z(5), 0*Z(5) ],
    > 	[ Z(5^2)^5, 0*Z(5), 0*Z(5), 0*Z(5) ],
    >       	[ 0*Z(5), 0*Z(5), Z(5)^0, Z(5^2)^4 ],
    >       	[ 0*Z(5), 0*Z(5), Z(5^2)^20, Z(5)^2 ] ] ];
    [ [ [ Z(5)^0, 0*Z(5), 0*Z(5), 0*Z(5) ], [ 0*Z(5), 0*Z(5), Z(5)^3, Z(5^2)^21 ],
          [ 0*Z(5), Z(5), Z(5), Z(5^2)^3 ],
          [ 0*Z(5), Z(5^2)^21, Z(5^2)^15, Z(5)^2 ] ],
      [ [ Z(5)^3, Z(5^2)^7, Z(5^2)^16, Z(5^2)^15 ],
          [ 0*Z(5), Z(5)^0, Z(5^2)^4, Z(5)^3 ],
          [ Z(5^2)^22, Z(5^2)^10, Z(5^2)^21, Z(5)^2 ],
          [ Z(5^2)^7, Z(5^2)^23, Z(5^2)^9, Z(5^2)^11 ] ],
      [ [ 0*Z(5), Z(5^2), 0*Z(5), 0*Z(5) ], [ Z(5^2)^5, 0*Z(5), 0*Z(5), 0*Z(5) ],
          [ 0*Z(5), 0*Z(5), Z(5)^0, Z(5^2)^4 ],
          [ 0*Z(5), 0*Z(5), Z(5^2)^20, Z(5)^2 ] ] ]
    gap> group := Group(gens);
    <matrix group with 3 generators>
    gap> PreservedForms(group);
    [ < quadratic form > ]
    gap> PreservedForms(group);
    [ < quadratic form > ]
    gap> PreservedForms(group);
    [ < quadratic form > ]
    gap> PreservedForms(group);
    [ < quadratic form >, < hermitian form > ]

##### 4.8-2 PreservedSesquilinearForms

`‣ PreservedSesquilinearForms`( group ) | ( operation )

Returns: a list of forms

The argument group is a matrix group. The function uses random methods to find all of the bilinear or unitary forms preserved by group (the trivial form is also a possibility) up to a scalar. Since the procedure relies on a pseudo-random generator, the user may need to execute the operation more than once to find all invariant sesquilinear forms.

    gap> g := SU(4,3);
    SU(4,3)
    gap> forms := PreservedSesquilinearForms(g);
    [ < hermitian form > ]
    gap> Display( forms[1] );
    Hermitian form
    Gram Matrix:
     . . . 2
     . . 2 .
     . 2 . .
     2 . . .

Here is another example which shows that this procedure is suitable in some cases where using the MeatAxe is not applicable. Here, our matrix group is the group of similarities preserving a (hyperbolic) bilinear form on a 6-dimensional vector space over GF(3).

    gap> a := [ [ -1, 0, 0, -1, 0, 1 ], [ 0, -1, -1, 0, 0, 1 ],
    >        [ -1, 0, 0, 1, 0, 0 ],  [ 0, -1, 1, 0, 0, -1 ],
    >        [ 0, 0, 0, 0, 0, -1 ], [ 0, -1, -1, 1, 1, 1 ] ] * One(GF(3));;
    gap> b := [ [ 1, -1, 1, -1, 1, -1 ], [ 1, 1, -1, 1, 1, 0 ],
    >        [ -1, 0, 1, 0, 0, 0 ], [ 0, -1, 0, 0, 0, 1 ],
    >        [ 1, 1, 1, 1, 1, 1 ], [ -1, 1, 1, 1, -1, 0 ] ] * One(GF(3));;
    gap> g := Group( a, b );
    <matrix group with 2 generators>
    gap> forms := PreservedSesquilinearForms( g );
    [ < bilinear form > ]
    gap> Display( forms[1] );
    Bilinear form
    Gram Matrix:
     . 1 . . . .
     1 . . . . .
     . . . 1 . .
     . . 1 . . .
     . . . . . 1
     . . . . 1 .
    gap> m := GModuleByMats( [a,b], GF(3) );;
    gap> usemeataxe := MTX.InvariantBilinearForm(m);
    fail

##### 4.8-3 PreservedQuadraticForms

`‣ PreservedQuadraticForms`( group ) | ( operation )

Returns: a list of forms

The argument group is a matrix group. The function uses random methods to find all of the quadratic forms preserved by group up to a scalar. Since the procedure relies on a pseudo-random generator, the user may need to execute the operation more than once to find all invariant sesquilinear forms.

    gap> group := GO(-1,4,8);
    GO(-1,4,8)
    gap> pres_forms := PreservedQuadraticForms(group);
    [ < quadratic form > ]
    gap> group := GO(1,6,9);
    GO(+1,6,9)
    gap> pres_forms := PreservedQuadraticForms(group);
    [ < quadratic form > ]

#### 4.9 The trivial form and some of its properties

It can be useful to work with trivial a quadratic or sesquilinear form, i.e. a form mapping all vectors, couples of vectors respectively, to the zero element of their basefield. As mentioned in Section 4.1, Forms allows the construction of an object in the Category `IsTrivialForm`.

    gap> mat := [[0,0,0],[0,0,0],[0,0,0]]*Z(7)^0;
    [ [ 0*Z(7), 0*Z(7), 0*Z(7) ], [ 0*Z(7), 0*Z(7), 0*Z(7) ],
      [ 0*Z(7), 0*Z(7), 0*Z(7) ] ]
    gap> form1 := BilinearFormByMatrix(mat,GF(7));
    < trivial form >
    gap> form2 := QuadraticFormByMatrix(mat,GF(7));
    < trivial form >
    gap> form1 = form2;
    true
    gap> IsQuadraticForm(form1);
    false
    gap> IsSesquilinearForm(form1);
    false
    gap> mat := [[0,0],[0,0]]*Z(4)^0;
    [ [ 0*Z(2), 0*Z(2) ], [ 0*Z(2), 0*Z(2) ] ]
    gap> form3 := BilinearFormByMatrix(mat,GF(4));
    < trivial form >
    gap> form3 = form1;
    false

As we have seen by the above example, there is only one trivial form for a given vector space over a finite field, and such a trivial form can result from the construction of a quadratic form or a sesquilinear form, but the trivial form itself is none of these, although it can behave as a sesquilinear or a quadratic form, depending on its arguments.

    gap> mat := [[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]]*Z(3)^0;
    [ [ 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3) ], [ 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3) ],
      [ 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3) ], [ 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3) ] ]
    gap> form := BilinearFormByMatrix(mat,GF(3));
    < trivial form >
    gap> v := Random(GF(3)^4);
    [ Z(3), Z(3), 0*Z(3), Z(3) ]
    gap> [v,v]^form;
    0*Z(3)
    gap> v^form;
    0*Z(3)

The attributes and properties described in Section 4.7 are all applicable to trivial forms.

    gap> mat := [[0,0,0],[0,0,0],[0,0,0]]*Z(11)^0;
    [ [ 0*Z(11), 0*Z(11), 0*Z(11) ], [ 0*Z(11), 0*Z(11), 0*Z(11) ],
      [ 0*Z(11), 0*Z(11), 0*Z(11) ] ]
    gap> form := QuadraticFormByMatrix(mat,GF(121));
    < trivial form >
    gap> IsReflexiveForm(form);
    true
    gap> IsAlternatingForm(form);
    true
    gap> IsSymmetricForm(form);
    true
    gap> IsOrthogonalForm(form);
    false
    gap> IsPseudoForm(form);
    false
    gap> IsSymplecticForm(form);
    true
    gap> IsDegenerateForm(form);
    true
    gap> IsSingularForm(form);
    true
    gap> BaseField(form);
    GF(11^2)
    gap> GramMatrix(form);
    [ [ 0*Z(11), 0*Z(11), 0*Z(11) ], [ 0*Z(11), 0*Z(11), 0*Z(11) ],
      [ 0*Z(11), 0*Z(11), 0*Z(11) ] ]
    gap> RadicalOfForm(form);
    <vector space over GF(11^2), with 3 generators>

[Top of Book] [Contents] [Previous Chapter] [Next Chapter]
Goto Chapter: Top 1 2 3 4 5 Bib Ind

generated by GAPDoc2HTML