Finite -modules with bilinear and quadratic forms¶
AUTHORS:
Simon Brandhorst (2017-09): First created
- sage.modules.torsion_quadratic_module.TorsionQuadraticForm(q)[source]¶
Create a torsion quadratic form module from a rational matrix.
The resulting quadratic form takes values in
or (depending onq
). If it takes values modulo , then it is non-degenerate. In any case the bilinear form is non-degenerate.INPUT:
q
– a symmetric rational matrix
EXAMPLES:
sage: q1 = Matrix(QQ, 2, [1,1/2,1/2,1]) sage: TorsionQuadraticForm(q1) Finite quadratic module over Integer Ring with invariants (2, 2) Gram matrix of the quadratic form with values in Q/2Z: [ 1 1/2] [1/2 1]
>>> from sage.all import * >>> q1 = Matrix(QQ, Integer(2), [Integer(1),Integer(1)/Integer(2),Integer(1)/Integer(2),Integer(1)]) >>> TorsionQuadraticForm(q1) Finite quadratic module over Integer Ring with invariants (2, 2) Gram matrix of the quadratic form with values in Q/2Z: [ 1 1/2] [1/2 1]
In the following example the quadratic form is degenerate. But the bilinear form is still non-degenerate:
sage: q2 = diagonal_matrix(QQ, [1/4,1/3]) sage: TorsionQuadraticForm(q2) Finite quadratic module over Integer Ring with invariants (12,) Gram matrix of the quadratic form with values in Q/Z: [7/12]
>>> from sage.all import * >>> q2 = diagonal_matrix(QQ, [Integer(1)/Integer(4),Integer(1)/Integer(3)]) >>> TorsionQuadraticForm(q2) Finite quadratic module over Integer Ring with invariants (12,) Gram matrix of the quadratic form with values in Q/Z: [7/12]
- class sage.modules.torsion_quadratic_module.TorsionQuadraticModule(V, W, gens, modulus, modulus_qf)[source]¶
Bases:
FGP_Module_class
,CachedRepresentation
Finite quotients with a bilinear and a quadratic form.
Let
be a symmetricFreeQuadraticModule
and a submodule of the same rank as . The quotient is a torsion quadratic module. It inherits a bilinear form and a quadratic form . , where and , whereINPUT:
V
– aFreeModule
with a symmetric inner product matrixW
– a submodule ofV
of the same rank asV
check
– boolean (default:True
)modulus
– a rational number dividing (default: ); the inner product is defined inmodulus
modulus_qf
– a rational number dividing (default: ); the quadratic form is defined inmodulus_qf
EXAMPLES:
sage: from sage.modules.torsion_quadratic_module import TorsionQuadraticModule sage: V = FreeModule(ZZ, 3) sage: T = TorsionQuadraticModule(V, 5*V); T Finite quadratic module over Integer Ring with invariants (5, 5, 5) Gram matrix of the quadratic form with values in Q/5Z: [1 0 0] [0 1 0] [0 0 1]
>>> from sage.all import * >>> from sage.modules.torsion_quadratic_module import TorsionQuadraticModule >>> V = FreeModule(ZZ, Integer(3)) >>> T = TorsionQuadraticModule(V, Integer(5)*V); T Finite quadratic module over Integer Ring with invariants (5, 5, 5) Gram matrix of the quadratic form with values in Q/5Z: [1 0 0] [0 1 0] [0 0 1]
- Element[source]¶
alias of
TorsionQuadraticModuleElement
- all_submodules()[source]¶
Return a list of all submodules of
self
.Warning
This method creates all submodules in memory. The number of submodules grows rapidly with the number of generators. For example consider a vector space of dimension
over a finite field of prime order . The number of subspaces is (very) roughly .EXAMPLES:
sage: D = IntegralLattice("D4").discriminant_group() # needs sage.combinat sage: D.all_submodules() # needs sage.combinat [Finite quadratic module over Integer Ring with invariants () Gram matrix of the quadratic form with values in Q/2Z: [], Finite quadratic module over Integer Ring with invariants (2,) Gram matrix of the quadratic form with values in Q/2Z: [1], Finite quadratic module over Integer Ring with invariants (2,) Gram matrix of the quadratic form with values in Q/2Z: [1], Finite quadratic module over Integer Ring with invariants (2,) Gram matrix of the quadratic form with values in Q/2Z: [1], Finite quadratic module over Integer Ring with invariants (2, 2) Gram matrix of the quadratic form with values in Q/2Z: [ 1 1/2] [1/2 1]]
>>> from sage.all import * >>> D = IntegralLattice("D4").discriminant_group() # needs sage.combinat >>> D.all_submodules() # needs sage.combinat [Finite quadratic module over Integer Ring with invariants () Gram matrix of the quadratic form with values in Q/2Z: [], Finite quadratic module over Integer Ring with invariants (2,) Gram matrix of the quadratic form with values in Q/2Z: [1], Finite quadratic module over Integer Ring with invariants (2,) Gram matrix of the quadratic form with values in Q/2Z: [1], Finite quadratic module over Integer Ring with invariants (2,) Gram matrix of the quadratic form with values in Q/2Z: [1], Finite quadratic module over Integer Ring with invariants (2, 2) Gram matrix of the quadratic form with values in Q/2Z: [ 1 1/2] [1/2 1]]
- brown_invariant()[source]¶
Return the Brown invariant of this torsion quadratic form.
Let
be a torsion quadratic module with values in . The Brown invariant is defined by the equationThe Brown invariant is additive with respect to direct sums of torsion quadratic modules.
OUTPUT: an element of
EXAMPLES:
sage: L = IntegralLattice("D4") # needs sage.combinat sage: D = L.discriminant_group() # needs sage.combinat sage: D.brown_invariant() # needs sage.combinat 4
>>> from sage.all import * >>> L = IntegralLattice("D4") # needs sage.combinat >>> D = L.discriminant_group() # needs sage.combinat >>> D.brown_invariant() # needs sage.combinat 4
We require the quadratic form to be defined modulo
:sage: from sage.modules.torsion_quadratic_module import TorsionQuadraticModule sage: V = FreeQuadraticModule(ZZ, 3, matrix.identity(3)) sage: T = TorsionQuadraticModule((1/10)*V, V) sage: T.brown_invariant() Traceback (most recent call last): ... ValueError: the torsion quadratic form must have values in QQ / 2 ZZ
>>> from sage.all import * >>> from sage.modules.torsion_quadratic_module import TorsionQuadraticModule >>> V = FreeQuadraticModule(ZZ, Integer(3), matrix.identity(Integer(3))) >>> T = TorsionQuadraticModule((Integer(1)/Integer(10))*V, V) >>> T.brown_invariant() Traceback (most recent call last): ... ValueError: the torsion quadratic form must have values in QQ / 2 ZZ
- gens()[source]¶
Return generators of
self
.There is no assumption on the generators except that they generate the module.
EXAMPLES:
sage: from sage.modules.torsion_quadratic_module import TorsionQuadraticModule sage: V = FreeModule(ZZ, 3) sage: T = TorsionQuadraticModule(V, 5*V) sage: T.gens() ((1, 0, 0), (0, 1, 0), (0, 0, 1))
>>> from sage.all import * >>> from sage.modules.torsion_quadratic_module import TorsionQuadraticModule >>> V = FreeModule(ZZ, Integer(3)) >>> T = TorsionQuadraticModule(V, Integer(5)*V) >>> T.gens() ((1, 0, 0), (0, 1, 0), (0, 0, 1))
- genus(signature_pair)[source]¶
Return the genus defined by
self
and thesignature_pair
.If no such genus exists, raise a
ValueError
.REFERENCES:
[Nik1977] Corollary 1.9.4 and 1.16.3.
EXAMPLES:
sage: # needs sage.combinat sage: L = IntegralLattice("D4").direct_sum(IntegralLattice("A2")) sage: D = L.discriminant_group() sage: genus = D.genus(L.signature_pair()) # needs sage.libs.pari sage: genus # needs sage.libs.pari Genus of None Signature: (6, 0) Genus symbol at 2: 1^4:2^-2 Genus symbol at 3: 1^-5 3^-1 sage: genus == L.genus() # needs sage.libs.pari True
>>> from sage.all import * >>> # needs sage.combinat >>> L = IntegralLattice("D4").direct_sum(IntegralLattice("A2")) >>> D = L.discriminant_group() >>> genus = D.genus(L.signature_pair()) # needs sage.libs.pari >>> genus # needs sage.libs.pari Genus of None Signature: (6, 0) Genus symbol at 2: 1^4:2^-2 Genus symbol at 3: 1^-5 3^-1 >>> genus == L.genus() # needs sage.libs.pari True
Let
be an even unimodular lattice of signature . Then is primitively embedded in . We compute the discriminant form of the orthogonal complement of in :sage: DK = D.twist(-1) # needs sage.combinat sage.libs.pari sage: DK # needs sage.combinat sage.libs.pari Finite quadratic module over Integer Ring with invariants (2, 6) Gram matrix of the quadratic form with values in Q/2Z: [ 1 1/2] [1/2 1/3]
>>> from sage.all import * >>> DK = D.twist(-Integer(1)) # needs sage.combinat sage.libs.pari >>> DK # needs sage.combinat sage.libs.pari Finite quadratic module over Integer Ring with invariants (2, 6) Gram matrix of the quadratic form with values in Q/2Z: [ 1 1/2] [1/2 1/3]
We know that
has signature and thus we can compute the genus of as:sage: DK.genus((3,1)) # needs sage.combinat sage.libs.pari Genus of None Signature: (3, 1) Genus symbol at 2: 1^2:2^-2 Genus symbol at 3: 1^-3 3^1
>>> from sage.all import * >>> DK.genus((Integer(3),Integer(1))) # needs sage.combinat sage.libs.pari Genus of None Signature: (3, 1) Genus symbol at 2: 1^2:2^-2 Genus symbol at 3: 1^-3 3^1
We can also compute the genus of an odd lattice from its discriminant form:
sage: L = IntegralLattice(matrix.diagonal(range(1, 5))) sage: D = L.discriminant_group() sage: D.genus((4,0)) # needs sage.libs.pari Genus of None Signature: (4, 0) Genus symbol at 2: [1^-2 2^1 4^1]_6 Genus symbol at 3: 1^-3 3^1
>>> from sage.all import * >>> L = IntegralLattice(matrix.diagonal(range(Integer(1), Integer(5)))) >>> D = L.discriminant_group() >>> D.genus((Integer(4),Integer(0))) # needs sage.libs.pari Genus of None Signature: (4, 0) Genus symbol at 2: [1^-2 2^1 4^1]_6 Genus symbol at 3: 1^-3 3^1
- gram_matrix_bilinear()[source]¶
Return the Gram matrix with respect to the generators.
OUTPUT:
A rational matrix
G
withG[i,j]
given by the inner product of the -th and -th generator. Its entries are only well defined .EXAMPLES:
sage: from sage.modules.torsion_quadratic_module import TorsionQuadraticModule sage: V = FreeQuadraticModule(ZZ, 3, matrix.identity(3)*5) sage: T = TorsionQuadraticModule((1/5)*V, V) sage: T.gram_matrix_bilinear() [1/5 0 0] [ 0 1/5 0] [ 0 0 1/5]
>>> from sage.all import * >>> from sage.modules.torsion_quadratic_module import TorsionQuadraticModule >>> V = FreeQuadraticModule(ZZ, Integer(3), matrix.identity(Integer(3))*Integer(5)) >>> T = TorsionQuadraticModule((Integer(1)/Integer(5))*V, V) >>> T.gram_matrix_bilinear() [1/5 0 0] [ 0 1/5 0] [ 0 0 1/5]
- gram_matrix_quadratic()[source]¶
The Gram matrix of the quadratic form with respect to the generators.
OUTPUT:
a rational matrix
Gq
withGq[i,j] = gens[i]*gens[j]
andG[i,i] = gens[i].q()
EXAMPLES:
sage: from sage.modules.torsion_quadratic_module import TorsionQuadraticModule sage: D4_gram = Matrix(ZZ, [[2,0,0,-1],[0,2,0,-1],[0,0,2,-1],[-1,-1,-1,2]]) sage: D4 = FreeQuadraticModule(ZZ, 4, D4_gram) sage: D4dual = D4.span(D4_gram.inverse()) sage: discrForm = TorsionQuadraticModule(D4dual, D4) sage: discrForm.gram_matrix_quadratic() [ 1 1/2] [1/2 1] sage: discrForm.gram_matrix_bilinear() [ 0 1/2] [1/2 0]
>>> from sage.all import * >>> from sage.modules.torsion_quadratic_module import TorsionQuadraticModule >>> D4_gram = Matrix(ZZ, [[Integer(2),Integer(0),Integer(0),-Integer(1)],[Integer(0),Integer(2),Integer(0),-Integer(1)],[Integer(0),Integer(0),Integer(2),-Integer(1)],[-Integer(1),-Integer(1),-Integer(1),Integer(2)]]) >>> D4 = FreeQuadraticModule(ZZ, Integer(4), D4_gram) >>> D4dual = D4.span(D4_gram.inverse()) >>> discrForm = TorsionQuadraticModule(D4dual, D4) >>> discrForm.gram_matrix_quadratic() [ 1 1/2] [1/2 1] >>> discrForm.gram_matrix_bilinear() [ 0 1/2] [1/2 0]
- is_genus(signature_pair, even=True)[source]¶
Return
True
if there is a lattice with this signature and discriminant form.Todo
implement the same for odd lattices
INPUT:
signature_pair
– tuple of nonnegative integers(s_plus, s_minus)
even
– boolean (default:True
)
EXAMPLES:
sage: L3 = IntegralLattice(3 * Matrix(ZZ, 2, [2,1,1,2])) sage: L = IntegralLattice("D4").direct_sum(L3) # needs sage.combinat sage: D = L.discriminant_group() # needs sage.combinat sage: D.is_genus((6,0)) # needs sage.combinat True
>>> from sage.all import * >>> L3 = IntegralLattice(Integer(3) * Matrix(ZZ, Integer(2), [Integer(2),Integer(1),Integer(1),Integer(2)])) >>> L = IntegralLattice("D4").direct_sum(L3) # needs sage.combinat >>> D = L.discriminant_group() # needs sage.combinat >>> D.is_genus((Integer(6),Integer(0))) # needs sage.combinat True
Let us see if there is a lattice in the genus defined by the same discriminant form but with a different signature:
sage: D.is_genus((4,2)) # needs sage.combinat False sage: D.is_genus((16,2)) # needs sage.combinat True
>>> from sage.all import * >>> D.is_genus((Integer(4),Integer(2))) # needs sage.combinat False >>> D.is_genus((Integer(16),Integer(2))) # needs sage.combinat True
- normal_form(partial=False)[source]¶
Return the normal form of this torsion quadratic module.
Two torsion quadratic modules are isomorphic if and only if they have the same value modules and the same normal form.
A torsion quadratic module
with values in is in normal form if the rescaled quadratic module with values in is in normal form.For the definition of normal form see [MirMor2009] IV Definition 4.6. Below are some of its properties. Let
be odd and be the smallest non-square modulo . The normal form is a diagonal matrix with diagonal entries either or .If
is even, then the normal form consists of blocks of the formor of
blocks of the formThe blocks are ordered by their valuation.
INPUT:
partial
– boolean (default:False
); return only a partial normal form. It is not unique but still useful to extract invariants.
OUTPUT: a torsion quadratic module
EXAMPLES:
sage: L1 = IntegralLattice(matrix([[-2,0,0], [0,1,0], [0,0,4]])) sage: L1.discriminant_group().normal_form() # needs sage.rings.padics Finite quadratic module over Integer Ring with invariants (2, 4) Gram matrix of the quadratic form with values in Q/Z: [1/2 0] [ 0 1/4] sage: L2 = IntegralLattice(matrix([[-2,0,0], [0,1,0], [0,0,-4]])) sage: L2.discriminant_group().normal_form() # needs sage.rings.padics Finite quadratic module over Integer Ring with invariants (2, 4) Gram matrix of the quadratic form with values in Q/Z: [1/2 0] [ 0 1/4]
>>> from sage.all import * >>> L1 = IntegralLattice(matrix([[-Integer(2),Integer(0),Integer(0)], [Integer(0),Integer(1),Integer(0)], [Integer(0),Integer(0),Integer(4)]])) >>> L1.discriminant_group().normal_form() # needs sage.rings.padics Finite quadratic module over Integer Ring with invariants (2, 4) Gram matrix of the quadratic form with values in Q/Z: [1/2 0] [ 0 1/4] >>> L2 = IntegralLattice(matrix([[-Integer(2),Integer(0),Integer(0)], [Integer(0),Integer(1),Integer(0)], [Integer(0),Integer(0),-Integer(4)]])) >>> L2.discriminant_group().normal_form() # needs sage.rings.padics Finite quadratic module over Integer Ring with invariants (2, 4) Gram matrix of the quadratic form with values in Q/Z: [1/2 0] [ 0 1/4]
We check that Issue #24864 is fixed:
sage: L1 = IntegralLattice(matrix([[-4,0,0], [0,4,0], [0,0,-2]])) sage: AL1 = L1.discriminant_group() sage: L2 = IntegralLattice(matrix([[-4,0,0], [0,-4,0], [0,0,2]])) sage: AL2 = L2.discriminant_group() sage: AL1.normal_form() # needs sage.rings.padics Finite quadratic module over Integer Ring with invariants (2, 4, 4) Gram matrix of the quadratic form with values in Q/2Z: [1/2 0 0] [ 0 1/4 0] [ 0 0 5/4] sage: AL2.normal_form() # needs sage.libs.pari sage.rings.padics Finite quadratic module over Integer Ring with invariants (2, 4, 4) Gram matrix of the quadratic form with values in Q/2Z: [1/2 0 0] [ 0 1/4 0] [ 0 0 5/4]
>>> from sage.all import * >>> L1 = IntegralLattice(matrix([[-Integer(4),Integer(0),Integer(0)], [Integer(0),Integer(4),Integer(0)], [Integer(0),Integer(0),-Integer(2)]])) >>> AL1 = L1.discriminant_group() >>> L2 = IntegralLattice(matrix([[-Integer(4),Integer(0),Integer(0)], [Integer(0),-Integer(4),Integer(0)], [Integer(0),Integer(0),Integer(2)]])) >>> AL2 = L2.discriminant_group() >>> AL1.normal_form() # needs sage.rings.padics Finite quadratic module over Integer Ring with invariants (2, 4, 4) Gram matrix of the quadratic form with values in Q/2Z: [1/2 0 0] [ 0 1/4 0] [ 0 0 5/4] >>> AL2.normal_form() # needs sage.libs.pari sage.rings.padics Finite quadratic module over Integer Ring with invariants (2, 4, 4) Gram matrix of the quadratic form with values in Q/2Z: [1/2 0 0] [ 0 1/4 0] [ 0 0 5/4]
Some exotic cases:
sage: from sage.modules.torsion_quadratic_module import TorsionQuadraticModule sage: D4_gram = Matrix(ZZ, 4, 4,[2,0,0,-1, 0,2,0,-1, 0,0,2,-1, -1,-1,-1,2]) sage: D4 = FreeQuadraticModule(ZZ, 4, D4_gram) sage: D4dual = D4.span(D4_gram.inverse()) sage: T = TorsionQuadraticModule((1/6)*D4dual, D4); T Finite quadratic module over Integer Ring with invariants (6, 6, 12, 12) Gram matrix of the quadratic form with values in Q/(1/3)Z: [ 1/18 1/12 5/36 1/36] [ 1/12 1/6 1/36 1/9] [ 5/36 1/36 1/36 11/72] [ 1/36 1/9 11/72 1/36] sage: T.normal_form() # needs sage.libs.pari sage.rings.padics Finite quadratic module over Integer Ring with invariants (6, 6, 12, 12) Gram matrix of the quadratic form with values in Q/(1/3)Z: [ 1/6 1/12 0 0 0 0 0 0] [1/12 1/6 0 0 0 0 0 0] [ 0 0 1/12 1/24 0 0 0 0] [ 0 0 1/24 1/12 0 0 0 0] [ 0 0 0 0 1/9 0 0 0] [ 0 0 0 0 0 1/9 0 0] [ 0 0 0 0 0 0 1/9 0] [ 0 0 0 0 0 0 0 1/9]
>>> from sage.all import * >>> from sage.modules.torsion_quadratic_module import TorsionQuadraticModule >>> D4_gram = Matrix(ZZ, Integer(4), Integer(4),[Integer(2),Integer(0),Integer(0),-Integer(1), Integer(0),Integer(2),Integer(0),-Integer(1), Integer(0),Integer(0),Integer(2),-Integer(1), -Integer(1),-Integer(1),-Integer(1),Integer(2)]) >>> D4 = FreeQuadraticModule(ZZ, Integer(4), D4_gram) >>> D4dual = D4.span(D4_gram.inverse()) >>> T = TorsionQuadraticModule((Integer(1)/Integer(6))*D4dual, D4); T Finite quadratic module over Integer Ring with invariants (6, 6, 12, 12) Gram matrix of the quadratic form with values in Q/(1/3)Z: [ 1/18 1/12 5/36 1/36] [ 1/12 1/6 1/36 1/9] [ 5/36 1/36 1/36 11/72] [ 1/36 1/9 11/72 1/36] >>> T.normal_form() # needs sage.libs.pari sage.rings.padics Finite quadratic module over Integer Ring with invariants (6, 6, 12, 12) Gram matrix of the quadratic form with values in Q/(1/3)Z: [ 1/6 1/12 0 0 0 0 0 0] [1/12 1/6 0 0 0 0 0 0] [ 0 0 1/12 1/24 0 0 0 0] [ 0 0 1/24 1/12 0 0 0 0] [ 0 0 0 0 1/9 0 0 0] [ 0 0 0 0 0 1/9 0 0] [ 0 0 0 0 0 0 1/9 0] [ 0 0 0 0 0 0 0 1/9]
- orthogonal_group(gens=None, check=False)[source]¶
Orthogonal group of the associated torsion quadratic form.
Warning
This is can be smaller than the orthogonal group of the bilinear form.
INPUT:
gens
– a list of generators, for instance square matrices, something that acts onself
, or an automorphism of the underlying abelian groupcheck
– perform additional checks on the generators
EXAMPLES:
You can provide generators to obtain a subgroup of the full orthogonal group:
sage: D = TorsionQuadraticForm(matrix.identity(2)/2) sage: f = matrix(2, [0,1,1,0]) sage: D.orthogonal_group(gens=[f]).order() # needs sage.groups 2
>>> from sage.all import * >>> D = TorsionQuadraticForm(matrix.identity(Integer(2))/Integer(2)) >>> f = matrix(Integer(2), [Integer(0),Integer(1),Integer(1),Integer(0)]) >>> D.orthogonal_group(gens=[f]).order() # needs sage.groups 2
If no generators are given a slow brute force approach is used to calculate the full orthogonal group:
sage: D = TorsionQuadraticForm(matrix.identity(3)/2) sage: OD = D.orthogonal_group() # needs sage.groups sage: OD.order() # needs sage.groups 6 sage: fd = D.hom([D.1, D.0, D.2]) # needs sage.symbolic sage: OD(fd) # needs sage.groups sage.symbolic [0 1 0] [1 0 0] [0 0 1]
>>> from sage.all import * >>> D = TorsionQuadraticForm(matrix.identity(Integer(3))/Integer(2)) >>> OD = D.orthogonal_group() # needs sage.groups >>> OD.order() # needs sage.groups 6 >>> fd = D.hom([D.gen(1), D.gen(0), D.gen(2)]) # needs sage.symbolic >>> OD(fd) # needs sage.groups sage.symbolic [0 1 0] [1 0 0] [0 0 1]
We compute the kernel of the action of the orthogonal group of
on the discriminant group:sage: # needs sage.combinat sage.groups sage: L = IntegralLattice('A4') sage: O = L.orthogonal_group() sage: D = L.discriminant_group() sage: Obar = D.orthogonal_group(O.gens()) sage: O.order() 240 sage: Obar.order() 2 sage: phi = O.hom(Obar.gens()) sage: phi.kernel().order() 120
>>> from sage.all import * >>> # needs sage.combinat sage.groups >>> L = IntegralLattice('A4') >>> O = L.orthogonal_group() >>> D = L.discriminant_group() >>> Obar = D.orthogonal_group(O.gens()) >>> O.order() 240 >>> Obar.order() 2 >>> phi = O.hom(Obar.gens()) >>> phi.kernel().order() 120
- orthogonal_submodule_to(S)[source]¶
Return the submodule orthogonal to
S
.INPUT:
S
– a submodule, list, or tuple of generators
EXAMPLES:
sage: from sage.modules.torsion_quadratic_module import TorsionQuadraticModule sage: V = FreeModule(ZZ, 10) sage: T = TorsionQuadraticModule(V, 3*V) sage: S = T.submodule(T.gens()[:5]) sage: O = T.orthogonal_submodule_to(S) sage: O Finite quadratic module over Integer Ring with invariants (3, 3, 3, 3, 3) Gram matrix of the quadratic form with values in Q/3Z: [1 0 0 0 0] [0 1 0 0 0] [0 0 1 0 0] [0 0 0 1 0] [0 0 0 0 1] sage: O.V() + S.V() == T.V() True
>>> from sage.all import * >>> from sage.modules.torsion_quadratic_module import TorsionQuadraticModule >>> V = FreeModule(ZZ, Integer(10)) >>> T = TorsionQuadraticModule(V, Integer(3)*V) >>> S = T.submodule(T.gens()[:Integer(5)]) >>> O = T.orthogonal_submodule_to(S) >>> O Finite quadratic module over Integer Ring with invariants (3, 3, 3, 3, 3) Gram matrix of the quadratic form with values in Q/3Z: [1 0 0 0 0] [0 1 0 0 0] [0 0 1 0 0] [0 0 0 1 0] [0 0 0 0 1] >>> O.V() + S.V() == T.V() True
- primary_part(m)[source]¶
Return the
m
-primary part of this torsion quadratic module as a submodule.INPUT:
m
– integer
OUTPUT: a submodule
EXAMPLES:
sage: from sage.modules.torsion_quadratic_module import TorsionQuadraticModule sage: T = TorsionQuadraticModule((1/6)*ZZ^3, ZZ^3); T Finite quadratic module over Integer Ring with invariants (6, 6, 6) Gram matrix of the quadratic form with values in Q/(1/3)Z: [1/36 0 0] [ 0 1/36 0] [ 0 0 1/36] sage: T.primary_part(2) Finite quadratic module over Integer Ring with invariants (2, 2, 2) Gram matrix of the quadratic form with values in Q/(1/3)Z: [1/4 0 0] [ 0 1/4 0] [ 0 0 1/4]
>>> from sage.all import * >>> from sage.modules.torsion_quadratic_module import TorsionQuadraticModule >>> T = TorsionQuadraticModule((Integer(1)/Integer(6))*ZZ**Integer(3), ZZ**Integer(3)); T Finite quadratic module over Integer Ring with invariants (6, 6, 6) Gram matrix of the quadratic form with values in Q/(1/3)Z: [1/36 0 0] [ 0 1/36 0] [ 0 0 1/36] >>> T.primary_part(Integer(2)) Finite quadratic module over Integer Ring with invariants (2, 2, 2) Gram matrix of the quadratic form with values in Q/(1/3)Z: [1/4 0 0] [ 0 1/4 0] [ 0 0 1/4]
- submodule_with_gens(gens)[source]¶
Return a submodule with generators given by
gens
.INPUT:
gens
– list of generators that convert intoself
OUTPUT: a submodule with the specified generators
EXAMPLES:
sage: from sage.modules.torsion_quadratic_module import TorsionQuadraticModule sage: V = FreeQuadraticModule(ZZ, 3, matrix.identity(3)*10) sage: T = TorsionQuadraticModule((1/10)*V, V) sage: g = T.gens() sage: new_gens = [2*g[0], 5*g[0]] sage: T.submodule_with_gens(new_gens) Finite quadratic module over Integer Ring with invariants (10,) Gram matrix of the quadratic form with values in Q/2Z: [2/5 0] [ 0 1/2]
>>> from sage.all import * >>> from sage.modules.torsion_quadratic_module import TorsionQuadraticModule >>> V = FreeQuadraticModule(ZZ, Integer(3), matrix.identity(Integer(3))*Integer(10)) >>> T = TorsionQuadraticModule((Integer(1)/Integer(10))*V, V) >>> g = T.gens() >>> new_gens = [Integer(2)*g[Integer(0)], Integer(5)*g[Integer(0)]] >>> T.submodule_with_gens(new_gens) Finite quadratic module over Integer Ring with invariants (10,) Gram matrix of the quadratic form with values in Q/2Z: [2/5 0] [ 0 1/2]
The generators do not need to be independent:
sage: new_gens = [g[0], 2*g[1], g[0], g[1]] sage: T.submodule_with_gens(new_gens) Finite quadratic module over Integer Ring with invariants (10, 10) Gram matrix of the quadratic form with values in Q/2Z: [1/10 0 1/10 0] [ 0 2/5 0 1/5] [1/10 0 1/10 0] [ 0 1/5 0 1/10]
>>> from sage.all import * >>> new_gens = [g[Integer(0)], Integer(2)*g[Integer(1)], g[Integer(0)], g[Integer(1)]] >>> T.submodule_with_gens(new_gens) Finite quadratic module over Integer Ring with invariants (10, 10) Gram matrix of the quadratic form with values in Q/2Z: [1/10 0 1/10 0] [ 0 2/5 0 1/5] [1/10 0 1/10 0] [ 0 1/5 0 1/10]
- twist(s)[source]¶
Return the torsion quadratic module with quadratic form scaled by
s
.If the old form was defined modulo
, then the new form is defined modulo .INPUT:
s
– a rational number
EXAMPLES:
sage: q = TorsionQuadraticForm(matrix.diagonal([3/9, 1/9])) sage: q.twist(-1) Finite quadratic module over Integer Ring with invariants (3, 9) Gram matrix of the quadratic form with values in Q/Z: [2/3 0] [ 0 8/9]
>>> from sage.all import * >>> q = TorsionQuadraticForm(matrix.diagonal([Integer(3)/Integer(9), Integer(1)/Integer(9)])) >>> q.twist(-Integer(1)) Finite quadratic module over Integer Ring with invariants (3, 9) Gram matrix of the quadratic form with values in Q/Z: [2/3 0] [ 0 8/9]
This form is defined modulo
:sage: q.twist(3) Finite quadratic module over Integer Ring with invariants (3, 9) Gram matrix of the quadratic form with values in Q/3Z: [ 1 0] [ 0 1/3]
>>> from sage.all import * >>> q.twist(Integer(3)) Finite quadratic module over Integer Ring with invariants (3, 9) Gram matrix of the quadratic form with values in Q/3Z: [ 1 0] [ 0 1/3]
The next form is defined modulo
:sage: q.twist(4) Finite quadratic module over Integer Ring with invariants (3, 9) Gram matrix of the quadratic form with values in Q/4Z: [4/3 0] [ 0 4/9]
>>> from sage.all import * >>> q.twist(Integer(4)) Finite quadratic module over Integer Ring with invariants (3, 9) Gram matrix of the quadratic form with values in Q/4Z: [4/3 0] [ 0 4/9]
- value_module()[source]¶
Return
with .This is where the inner product takes values.
EXAMPLES:
sage: A2 = Matrix(ZZ, 2, 2, [2,-1,-1,2]) sage: L = IntegralLattice(2*A2) sage: D = L.discriminant_group(); D Finite quadratic module over Integer Ring with invariants (2, 6) Gram matrix of the quadratic form with values in Q/2Z: [ 1 1/2] [1/2 1/3] sage: D.value_module() Q/Z
>>> from sage.all import * >>> A2 = Matrix(ZZ, Integer(2), Integer(2), [Integer(2),-Integer(1),-Integer(1),Integer(2)]) >>> L = IntegralLattice(Integer(2)*A2) >>> D = L.discriminant_group(); D Finite quadratic module over Integer Ring with invariants (2, 6) Gram matrix of the quadratic form with values in Q/2Z: [ 1 1/2] [1/2 1/3] >>> D.value_module() Q/Z
- value_module_qf()[source]¶
Return
with .This is where the torsion quadratic form takes values.
EXAMPLES:
sage: A2 = Matrix(ZZ, 2, 2, [2,-1,-1,2]) sage: L = IntegralLattice(2 * A2) sage: D = L.discriminant_group(); D Finite quadratic module over Integer Ring with invariants (2, 6) Gram matrix of the quadratic form with values in Q/2Z: [ 1 1/2] [1/2 1/3] sage: D.value_module_qf() Q/2Z
>>> from sage.all import * >>> A2 = Matrix(ZZ, Integer(2), Integer(2), [Integer(2),-Integer(1),-Integer(1),Integer(2)]) >>> L = IntegralLattice(Integer(2) * A2) >>> D = L.discriminant_group(); D Finite quadratic module over Integer Ring with invariants (2, 6) Gram matrix of the quadratic form with values in Q/2Z: [ 1 1/2] [1/2 1/3] >>> D.value_module_qf() Q/2Z
- class sage.modules.torsion_quadratic_module.TorsionQuadraticModuleElement(parent, x, check=True)[source]¶
Bases:
FGP_Element
An element of a torsion quadratic module.
INPUT:
parent
– parentx
– element ofparent.V()
check
– boolean (default:True
)
- b(other)[source]¶
Compute the inner product of two elements.
OUTPUT:
an element of
with
EXAMPLES:
sage: from sage.modules.torsion_quadratic_module import TorsionQuadraticModule sage: V = (1/2)*ZZ^2; W = ZZ^2 sage: T = TorsionQuadraticModule(V, W) sage: g = T.gens() sage: x = g[0]; x (1, 0) sage: y = g[0] + g[1] sage: x*y 1/4
>>> from sage.all import * >>> from sage.modules.torsion_quadratic_module import TorsionQuadraticModule >>> V = (Integer(1)/Integer(2))*ZZ**Integer(2); W = ZZ**Integer(2) >>> T = TorsionQuadraticModule(V, W) >>> g = T.gens() >>> x = g[Integer(0)]; x (1, 0) >>> y = g[Integer(0)] + g[Integer(1)] >>> x*y 1/4
The inner product has further aliases:
sage: x.inner_product(y) 1/4 sage: x.b(y) 1/4
>>> from sage.all import * >>> x.inner_product(y) 1/4 >>> x.b(y) 1/4
- inner_product(other)[source]¶
Compute the inner product of two elements.
OUTPUT:
an element of
with
EXAMPLES:
sage: from sage.modules.torsion_quadratic_module import TorsionQuadraticModule sage: V = (1/2)*ZZ^2; W = ZZ^2 sage: T = TorsionQuadraticModule(V, W) sage: g = T.gens() sage: x = g[0]; x (1, 0) sage: y = g[0] + g[1] sage: x*y 1/4
>>> from sage.all import * >>> from sage.modules.torsion_quadratic_module import TorsionQuadraticModule >>> V = (Integer(1)/Integer(2))*ZZ**Integer(2); W = ZZ**Integer(2) >>> T = TorsionQuadraticModule(V, W) >>> g = T.gens() >>> x = g[Integer(0)]; x (1, 0) >>> y = g[Integer(0)] + g[Integer(1)] >>> x*y 1/4
The inner product has further aliases:
sage: x.inner_product(y) 1/4 sage: x.b(y) 1/4
>>> from sage.all import * >>> x.inner_product(y) 1/4 >>> x.b(y) 1/4
- q()[source]¶
Compute the quadratic product of
self
.OUTPUT:
an element of
where
EXAMPLES:
sage: from sage.modules.torsion_quadratic_module import TorsionQuadraticModule sage: W = FreeQuadraticModule(ZZ, 2, 2*matrix.identity(2)) sage: V = (1/2) * W sage: T = TorsionQuadraticModule(V, W) sage: x = T.gen(0) sage: x (1, 0) sage: x.quadratic_product() 1/2 sage: x.quadratic_product().parent() Q/2Z sage: x*x 1/2 sage: (x*x).parent() Q/Z
>>> from sage.all import * >>> from sage.modules.torsion_quadratic_module import TorsionQuadraticModule >>> W = FreeQuadraticModule(ZZ, Integer(2), Integer(2)*matrix.identity(Integer(2))) >>> V = (Integer(1)/Integer(2)) * W >>> T = TorsionQuadraticModule(V, W) >>> x = T.gen(Integer(0)) >>> x (1, 0) >>> x.quadratic_product() 1/2 >>> x.quadratic_product().parent() Q/2Z >>> x*x 1/2 >>> (x*x).parent() Q/Z
- quadratic_product()[source]¶
Compute the quadratic product of
self
.OUTPUT:
an element of
where
EXAMPLES:
sage: from sage.modules.torsion_quadratic_module import TorsionQuadraticModule sage: W = FreeQuadraticModule(ZZ, 2, 2*matrix.identity(2)) sage: V = (1/2) * W sage: T = TorsionQuadraticModule(V, W) sage: x = T.gen(0) sage: x (1, 0) sage: x.quadratic_product() 1/2 sage: x.quadratic_product().parent() Q/2Z sage: x*x 1/2 sage: (x*x).parent() Q/Z
>>> from sage.all import * >>> from sage.modules.torsion_quadratic_module import TorsionQuadraticModule >>> W = FreeQuadraticModule(ZZ, Integer(2), Integer(2)*matrix.identity(Integer(2))) >>> V = (Integer(1)/Integer(2)) * W >>> T = TorsionQuadraticModule(V, W) >>> x = T.gen(Integer(0)) >>> x (1, 0) >>> x.quadratic_product() 1/2 >>> x.quadratic_product().parent() Q/2Z >>> x*x 1/2 >>> (x*x).parent() Q/Z