Free quadratic modules¶
Sage supports computation with free quadratic modules over an arbitrary commutative ring. Nontrivial functionality is available over \(\ZZ\) and fields. All free modules over an integral domain are equipped with an embedding in an ambient vector space and an inner product, which you can specify and change.
Create the free module of rank \(n\) over an arbitrary commutative ring \(R\)
using the command FreeModule(R,n)
with a given inner_product_matrix
.
The following example illustrates the creation of both a vector space
and a free module over the integers and a submodule of it. Use the functions
FreeModule
, span
and member functions of free modules
to create free modules. ‘’Do not use the FreeModule_xxx
constructors
directly.’’
EXAMPLES:
sage: M = Matrix(QQ, [[2,1,0], [1,2,1], [0,1,2]])
sage: V = VectorSpace(QQ, 3, inner_product_matrix=M)
sage: type(V)
<class 'sage.modules.free_quadratic_module.FreeQuadraticModule_ambient_field_with_category'>
sage: V.inner_product_matrix()
[2 1 0]
[1 2 1]
[0 1 2]
sage: W = V.subspace([[1,2,7], [1,1,0]])
sage: type(W)
<class 'sage.modules.free_quadratic_module.FreeQuadraticModule_submodule_field_with_category'>
sage: W
Quadratic space of degree 3 and dimension 2 over Rational Field
Basis matrix:
[ 1 0 -7]
[ 0 1 7]
Inner product matrix:
[2 1 0]
[1 2 1]
[0 1 2]
sage: W.gram_matrix()
[ 100 -104]
[-104 114]
>>> from sage.all import *
>>> M = Matrix(QQ, [[Integer(2),Integer(1),Integer(0)], [Integer(1),Integer(2),Integer(1)], [Integer(0),Integer(1),Integer(2)]])
>>> V = VectorSpace(QQ, Integer(3), inner_product_matrix=M)
>>> type(V)
<class 'sage.modules.free_quadratic_module.FreeQuadraticModule_ambient_field_with_category'>
>>> V.inner_product_matrix()
[2 1 0]
[1 2 1]
[0 1 2]
>>> W = V.subspace([[Integer(1),Integer(2),Integer(7)], [Integer(1),Integer(1),Integer(0)]])
>>> type(W)
<class 'sage.modules.free_quadratic_module.FreeQuadraticModule_submodule_field_with_category'>
>>> W
Quadratic space of degree 3 and dimension 2 over Rational Field
Basis matrix:
[ 1 0 -7]
[ 0 1 7]
Inner product matrix:
[2 1 0]
[1 2 1]
[0 1 2]
>>> W.gram_matrix()
[ 100 -104]
[-104 114]
AUTHORS:
David Kohel (2008-06): First created (based on free_module.py)
- sage.modules.free_quadratic_module.FreeQuadraticModule(base_ring, rank, inner_product_matrix, sparse=False, inner_product_ring=None)[source]¶
Create the free quadratic module over the given commutative ring of the given rank.
INPUT:
base_ring
– a commutative ringrank
– nonnegative integerinner_product_matrix
– the inner product matrixsparse
– boolean (default:False
)inner_product_ring
– the inner product codomain ring (default:None
)
OUTPUT:
A free quadratic module (with given inner product matrix).
Note
In Sage, it is the case that there is only one dense and one sparse free ambient quadratic module of rank \(n\) over \(R\) and given inner product matrix.
EXAMPLES:
sage: M2 = FreeQuadraticModule(ZZ, 2, inner_product_matrix=[1,2,3,4]) sage: M2 is FreeQuadraticModule(ZZ, 2, inner_product_matrix=[1,2,3,4]) True sage: M2.inner_product_matrix() [1 2] [3 4] sage: M3 = FreeModule(ZZ, 2, inner_product_matrix=[[1,2],[3,4]]) sage: M3 is M2 True
>>> from sage.all import * >>> M2 = FreeQuadraticModule(ZZ, Integer(2), inner_product_matrix=[Integer(1),Integer(2),Integer(3),Integer(4)]) >>> M2 is FreeQuadraticModule(ZZ, Integer(2), inner_product_matrix=[Integer(1),Integer(2),Integer(3),Integer(4)]) True >>> M2.inner_product_matrix() [1 2] [3 4] >>> M3 = FreeModule(ZZ, Integer(2), inner_product_matrix=[[Integer(1),Integer(2)],[Integer(3),Integer(4)]]) >>> M3 is M2 True
- class sage.modules.free_quadratic_module.FreeQuadraticModule_ambient(base_ring, rank, inner_product_matrix, sparse=False)[source]¶
Bases:
FreeModule_ambient
,FreeQuadraticModule_generic
Ambient free module over a commutative ring.
- class sage.modules.free_quadratic_module.FreeQuadraticModule_ambient_domain(base_ring, rank, inner_product_matrix, sparse=False)[source]¶
Bases:
FreeModule_ambient_domain
,FreeQuadraticModule_ambient
Ambient free quadratic module over an integral domain.
- ambient_vector_space()[source]¶
Return the ambient vector space, which is this free module tensored with its fraction field.
EXAMPLES:
sage: M = ZZ^3; M.ambient_vector_space() Vector space of dimension 3 over Rational Field
>>> from sage.all import * >>> M = ZZ**Integer(3); M.ambient_vector_space() Vector space of dimension 3 over Rational Field
- class sage.modules.free_quadratic_module.FreeQuadraticModule_ambient_field(base_field, dimension, inner_product_matrix, sparse=False)[source]¶
Bases:
FreeModule_ambient_field
,FreeQuadraticModule_generic_field
,FreeQuadraticModule_ambient_pid
Create the ambient vector space of given dimension over the given field.
INPUT:
base_field
– a fielddimension
– nonnegative integersparse
– boolean (default:False
)
EXAMPLES:
sage: VectorSpace(QQ,3,inner_product_matrix=[[2,1,0],[1,2,0],[0,1,2]]) Ambient quadratic space of dimension 3 over Rational Field Inner product matrix: [2 1 0] [1 2 0] [0 1 2]
>>> from sage.all import * >>> VectorSpace(QQ,Integer(3),inner_product_matrix=[[Integer(2),Integer(1),Integer(0)],[Integer(1),Integer(2),Integer(0)],[Integer(0),Integer(1),Integer(2)]]) Ambient quadratic space of dimension 3 over Rational Field Inner product matrix: [2 1 0] [1 2 0] [0 1 2]
- class sage.modules.free_quadratic_module.FreeQuadraticModule_ambient_pid(base_ring, rank, inner_product_matrix, sparse=False)[source]¶
Bases:
FreeModule_ambient_pid
,FreeQuadraticModule_generic_pid
,FreeQuadraticModule_ambient_domain
Ambient free quadratic module over a principal ideal domain.
- class sage.modules.free_quadratic_module.FreeQuadraticModule_generic(base_ring, rank, degree, inner_product_matrix, sparse=False)[source]¶
Bases:
FreeModule_generic
Base class for all free quadratic modules.
Modules are ordered by inclusion in the same ambient space.
- ambient_module()[source]¶
Return the ambient module associated to this module.
EXAMPLES:
sage: R.<x,y> = QQ[] sage: M = FreeModule(R,2) sage: M.ambient_module() Ambient free module of rank 2 over the integral domain Multivariate Polynomial Ring in x, y over Rational Field sage: V = FreeModule(QQ, 4).span([[1,2,3,4], [1,0,0,0]]); V Vector space of degree 4 and dimension 2 over Rational Field Basis matrix: [ 1 0 0 0] [ 0 1 3/2 2] sage: V.ambient_module() Vector space of dimension 4 over Rational Field
>>> from sage.all import * >>> R = QQ['x, y']; (x, y,) = R._first_ngens(2) >>> M = FreeModule(R,Integer(2)) >>> M.ambient_module() Ambient free module of rank 2 over the integral domain Multivariate Polynomial Ring in x, y over Rational Field >>> V = FreeModule(QQ, Integer(4)).span([[Integer(1),Integer(2),Integer(3),Integer(4)], [Integer(1),Integer(0),Integer(0),Integer(0)]]); V Vector space of degree 4 and dimension 2 over Rational Field Basis matrix: [ 1 0 0 0] [ 0 1 3/2 2] >>> V.ambient_module() Vector space of dimension 4 over Rational Field
- determinant()[source]¶
Return the determinant of this free module.
EXAMPLES:
sage: M = FreeModule(ZZ, 3, inner_product_matrix=1) sage: M.determinant() 1 sage: N = M.span([[1,2,3]]) sage: N.determinant() 14 sage: P = M.span([[1,2,3], [1,1,1]]) sage: P.determinant() 6
>>> from sage.all import * >>> M = FreeModule(ZZ, Integer(3), inner_product_matrix=Integer(1)) >>> M.determinant() 1 >>> N = M.span([[Integer(1),Integer(2),Integer(3)]]) >>> N.determinant() 14 >>> P = M.span([[Integer(1),Integer(2),Integer(3)], [Integer(1),Integer(1),Integer(1)]]) >>> P.determinant() 6
- discriminant()[source]¶
Return the discriminant of this free module.
This is defined to be \((-1)^r\) of the determinant, where \(r = n/2\) (\(n\) even) or \((n-1)/2\) (\(n\) odd) for a module of rank \(n\).
EXAMPLES:
sage: M = FreeModule(ZZ, 3) sage: M.discriminant() 1 sage: N = M.span([[1,2,3]]) sage: N.discriminant() 14 sage: P = M.span([[1,2,3], [1,1,1]]) sage: P.discriminant() 6
>>> from sage.all import * >>> M = FreeModule(ZZ, Integer(3)) >>> M.discriminant() 1 >>> N = M.span([[Integer(1),Integer(2),Integer(3)]]) >>> N.discriminant() 14 >>> P = M.span([[Integer(1),Integer(2),Integer(3)], [Integer(1),Integer(1),Integer(1)]]) >>> P.discriminant() 6
- gram_matrix()[source]¶
Return the Gram matrix associated to this free module.
This is defined to be
B*A*B.transpose()
, whereA
is the inner product matrix (induced from the ambient space), andB
the basis matrix.EXAMPLES:
sage: V = VectorSpace(QQ,4) sage: u = V([1/2,1/2,1/2,1/2]) sage: v = V([0,1,1,0]) sage: w = V([0,0,1,1]) sage: M = span([u,v,w], ZZ) sage: M.inner_product_matrix() == V.inner_product_matrix() True sage: L = M.submodule_with_basis([u,v,w]) sage: L.inner_product_matrix() == M.inner_product_matrix() True sage: L.gram_matrix() [1 1 1] [1 2 1] [1 1 2]
>>> from sage.all import * >>> V = VectorSpace(QQ,Integer(4)) >>> u = V([Integer(1)/Integer(2),Integer(1)/Integer(2),Integer(1)/Integer(2),Integer(1)/Integer(2)]) >>> v = V([Integer(0),Integer(1),Integer(1),Integer(0)]) >>> w = V([Integer(0),Integer(0),Integer(1),Integer(1)]) >>> M = span([u,v,w], ZZ) >>> M.inner_product_matrix() == V.inner_product_matrix() True >>> L = M.submodule_with_basis([u,v,w]) >>> L.inner_product_matrix() == M.inner_product_matrix() True >>> L.gram_matrix() [1 1 1] [1 2 1] [1 1 2]
- inner_product_matrix()[source]¶
Return the inner product matrix associated to this module.
By definition, this is the inner product matrix of the ambient space, hence may be of degree greater than the rank of the module.
Note
The inner product does not have to be symmetric (see examples).
Todo
Differentiate the image ring of the inner product from the base ring of the module and/or ambient space. E.g. On an integral module over ZZ the inner product pairing could naturally take values in ZZ, QQ, RR, or CC.
EXAMPLES:
sage: M = FreeModule(ZZ, 3) sage: M.inner_product_matrix() [1 0 0] [0 1 0] [0 0 1]
>>> from sage.all import * >>> M = FreeModule(ZZ, Integer(3)) >>> M.inner_product_matrix() [1 0 0] [0 1 0] [0 0 1]
The inner product does not have to be symmetric or definite:
sage: N = FreeModule(ZZ,2,inner_product_matrix=[[1,-1],[2,5]]) sage: N.inner_product_matrix() [ 1 -1] [ 2 5] sage: u, v = N.basis() sage: u.inner_product(v) -1 sage: v.inner_product(u) 2
>>> from sage.all import * >>> N = FreeModule(ZZ,Integer(2),inner_product_matrix=[[Integer(1),-Integer(1)],[Integer(2),Integer(5)]]) >>> N.inner_product_matrix() [ 1 -1] [ 2 5] >>> u, v = N.basis() >>> u.inner_product(v) -1 >>> v.inner_product(u) 2
The inner product matrix is defined with respect to the ambient space:
sage: V = QQ^3 sage: u = V([1/2,1,1]) sage: v = V([1,1,1/2]) sage: M = span([u,v], ZZ) sage: M.inner_product_matrix() [1 0 0] [0 1 0] [0 0 1] sage: M.inner_product_matrix() == V.inner_product_matrix() True sage: M.gram_matrix() [ 1/2 -3/4] [-3/4 13/4]
>>> from sage.all import * >>> V = QQ**Integer(3) >>> u = V([Integer(1)/Integer(2),Integer(1),Integer(1)]) >>> v = V([Integer(1),Integer(1),Integer(1)/Integer(2)]) >>> M = span([u,v], ZZ) >>> M.inner_product_matrix() [1 0 0] [0 1 0] [0 0 1] >>> M.inner_product_matrix() == V.inner_product_matrix() True >>> M.gram_matrix() [ 1/2 -3/4] [-3/4 13/4]
- class sage.modules.free_quadratic_module.FreeQuadraticModule_generic_field(base_field, dimension, degree, inner_product_matrix, sparse=False)[source]¶
Bases:
FreeModule_generic_field
,FreeQuadraticModule_generic_pid
Base class for all free modules over fields.
- span(gens, check=True, already_echelonized=False)[source]¶
Return the \(K\)-span of the given list of gens, where \(K\) is the base field of
self
.Note that this span is a subspace of the ambient vector space, but need not be a subspace of
self
.INPUT:
gens
– list of vectorscheck
– boolean (default:True
); whether or not to coerce entries of gens into base fieldalready_echelonized
– boolean (default:False
); set this if you know the gens are already in echelon form
EXAMPLES:
sage: V = VectorSpace(GF(7), 3) sage: W = V.subspace([[2,3,4]]); W Vector space of degree 3 and dimension 1 over Finite Field of size 7 Basis matrix: [1 5 2] sage: W.span([[1,1,1]]) Vector space of degree 3 and dimension 1 over Finite Field of size 7 Basis matrix: [1 1 1]
>>> from sage.all import * >>> V = VectorSpace(GF(Integer(7)), Integer(3)) >>> W = V.subspace([[Integer(2),Integer(3),Integer(4)]]); W Vector space of degree 3 and dimension 1 over Finite Field of size 7 Basis matrix: [1 5 2] >>> W.span([[Integer(1),Integer(1),Integer(1)]]) Vector space of degree 3 and dimension 1 over Finite Field of size 7 Basis matrix: [1 1 1]
- span_of_basis(basis, check=True, already_echelonized=False)[source]¶
Return the free \(K\)-module with the given basis, where \(K\) is the base field of
self
.Note that this span is a subspace of the ambient vector space, but need not be a subspace of
self
.INPUT:
basis
– list of vectorscheck
– boolean (default:True
); whether or not to coerce entries of gens into base fieldalready_echelonized
– boolean (default:False
); set this if you know the gens are already in echelon form
EXAMPLES:
sage: V = VectorSpace(GF(7), 3) sage: W = V.subspace([[2,3,4]]); W Vector space of degree 3 and dimension 1 over Finite Field of size 7 Basis matrix: [1 5 2] sage: W.span_of_basis([[2,2,2], [3,3,0]]) Vector space of degree 3 and dimension 2 over Finite Field of size 7 User basis matrix: [2 2 2] [3 3 0]
>>> from sage.all import * >>> V = VectorSpace(GF(Integer(7)), Integer(3)) >>> W = V.subspace([[Integer(2),Integer(3),Integer(4)]]); W Vector space of degree 3 and dimension 1 over Finite Field of size 7 Basis matrix: [1 5 2] >>> W.span_of_basis([[Integer(2),Integer(2),Integer(2)], [Integer(3),Integer(3),Integer(0)]]) Vector space of degree 3 and dimension 2 over Finite Field of size 7 User basis matrix: [2 2 2] [3 3 0]
The basis vectors must be linearly independent or a
ValueError
exception is raised:sage: W.span_of_basis([[2,2,2], [3,3,3]]) Traceback (most recent call last): ... ValueError: The given basis vectors must be linearly independent.
>>> from sage.all import * >>> W.span_of_basis([[Integer(2),Integer(2),Integer(2)], [Integer(3),Integer(3),Integer(3)]]) Traceback (most recent call last): ... ValueError: The given basis vectors must be linearly independent.
- class sage.modules.free_quadratic_module.FreeQuadraticModule_generic_pid(base_ring, rank, degree, inner_product_matrix, sparse=False)[source]¶
Bases:
FreeModule_generic_pid
,FreeQuadraticModule_generic
Class of all free modules over a PID.
- span(gens, check=True, already_echelonized=False)[source]¶
Return the \(R\)-span of the given list of gens, where \(R\) is the base ring of
self
.Note that this span need not be a submodule of
self
, nor even of the ambient space. It must, however, be contained in the ambient vector space, i.e., the ambient space tensored with the fraction field of \(R\).EXAMPLES:
sage: V = FreeModule(ZZ,3) sage: W = V.submodule([V.gen(0)]) sage: W.span([V.gen(1)]) Free module of degree 3 and rank 1 over Integer Ring Echelon basis matrix: [0 1 0] sage: W.submodule([V.gen(1)]) Traceback (most recent call last): ... ArithmeticError: argument gens (= [(0, 1, 0)]) does not generate a submodule of self
>>> from sage.all import * >>> V = FreeModule(ZZ,Integer(3)) >>> W = V.submodule([V.gen(Integer(0))]) >>> W.span([V.gen(Integer(1))]) Free module of degree 3 and rank 1 over Integer Ring Echelon basis matrix: [0 1 0] >>> W.submodule([V.gen(Integer(1))]) Traceback (most recent call last): ... ArithmeticError: argument gens (= [(0, 1, 0)]) does not generate a submodule of self
- span_of_basis(basis, check=True, already_echelonized=False)[source]¶
Return the free \(R\)-module with the given basis, where \(R\) is the base ring of
self
.Note that this \(R\)-module need not be a submodule of
self
, nor even of the ambient space. It must, however, be contained in the ambient vector space, i.e., the ambient space tensored with the fraction field of \(R\).EXAMPLES:
sage: M = FreeModule(ZZ,3) sage: W = M.span_of_basis([M([1,2,3])])
>>> from sage.all import * >>> M = FreeModule(ZZ,Integer(3)) >>> W = M.span_of_basis([M([Integer(1),Integer(2),Integer(3)])])
Next we create two free \(\ZZ\)-modules, neither of which is a submodule of \(W\):
sage: W.span_of_basis([M([2,4,0])]) Free module of degree 3 and rank 1 over Integer Ring User basis matrix: [2 4 0]
>>> from sage.all import * >>> W.span_of_basis([M([Integer(2),Integer(4),Integer(0)])]) Free module of degree 3 and rank 1 over Integer Ring User basis matrix: [2 4 0]
The following module is not even in the ambient space:
sage: Q = QQ sage: W.span_of_basis([ Q('1/5')*M([1,2,0]), Q('1/7')*M([1,1,0]) ]) Free module of degree 3 and rank 2 over Integer Ring User basis matrix: [1/5 2/5 0] [1/7 1/7 0]
>>> from sage.all import * >>> Q = QQ >>> W.span_of_basis([ Q('1/5')*M([Integer(1),Integer(2),Integer(0)]), Q('1/7')*M([Integer(1),Integer(1),Integer(0)]) ]) Free module of degree 3 and rank 2 over Integer Ring User basis matrix: [1/5 2/5 0] [1/7 1/7 0]
Of course the input basis vectors must be linearly independent:
sage: W.span_of_basis([ [1,2,0], [2,4,0] ]) Traceback (most recent call last): ... ValueError: The given basis vectors must be linearly independent.
>>> from sage.all import * >>> W.span_of_basis([ [Integer(1),Integer(2),Integer(0)], [Integer(2),Integer(4),Integer(0)] ]) Traceback (most recent call last): ... ValueError: The given basis vectors must be linearly independent.
- zero_submodule()[source]¶
Return the zero submodule of this module.
EXAMPLES:
sage: V = FreeModule(ZZ,2) sage: V.zero_submodule() Free module of degree 2 and rank 0 over Integer Ring Echelon basis matrix: []
>>> from sage.all import * >>> V = FreeModule(ZZ,Integer(2)) >>> V.zero_submodule() Free module of degree 2 and rank 0 over Integer Ring Echelon basis matrix: []
- class sage.modules.free_quadratic_module.FreeQuadraticModule_submodule_field(ambient, gens, inner_product_matrix, check=True, already_echelonized=False)[source]¶
Bases:
FreeModule_submodule_field
,FreeQuadraticModule_submodule_with_basis_field
An embedded vector subspace with echelonized basis.
EXAMPLES:
Since this is an embedded vector subspace with echelonized basis, the methods
echelon_coordinates()
andcoordinates()
return the same coordinates:sage: V = QQ^3 sage: W = V.span([[1,2,3], [4,5,6]]) sage: W Vector space of degree 3 and dimension 2 over Rational Field Basis matrix: [ 1 0 -1] [ 0 1 2] sage: v = V([1,5,9]) sage: W.echelon_coordinates(v) [1, 5] sage: vector(QQ, W.echelon_coordinates(v)) * W.basis_matrix() (1, 5, 9) sage: v = V([1,5,9]) sage: W.coordinates(v) [1, 5] sage: vector(QQ, W.coordinates(v)) * W.basis_matrix() (1, 5, 9)
>>> from sage.all import * >>> V = QQ**Integer(3) >>> W = V.span([[Integer(1),Integer(2),Integer(3)], [Integer(4),Integer(5),Integer(6)]]) >>> W Vector space of degree 3 and dimension 2 over Rational Field Basis matrix: [ 1 0 -1] [ 0 1 2] >>> v = V([Integer(1),Integer(5),Integer(9)]) >>> W.echelon_coordinates(v) [1, 5] >>> vector(QQ, W.echelon_coordinates(v)) * W.basis_matrix() (1, 5, 9) >>> v = V([Integer(1),Integer(5),Integer(9)]) >>> W.coordinates(v) [1, 5] >>> vector(QQ, W.coordinates(v)) * W.basis_matrix() (1, 5, 9)
- class sage.modules.free_quadratic_module.FreeQuadraticModule_submodule_pid(ambient, gens, inner_product_matrix, check=True, already_echelonized=False)[source]¶
Bases:
FreeModule_submodule_pid
,FreeQuadraticModule_submodule_with_basis_pid
An \(R\)-submodule of \(K^n\) where \(K\) is the fraction field of a principal ideal domain \(R\).
EXAMPLES:
sage: M = ZZ^3 sage: W = M.span_of_basis([[1,2,3], [4,5,19]]); W Free module of degree 3 and rank 2 over Integer Ring User basis matrix: [ 1 2 3] [ 4 5 19]
>>> from sage.all import * >>> M = ZZ**Integer(3) >>> W = M.span_of_basis([[Integer(1),Integer(2),Integer(3)], [Integer(4),Integer(5),Integer(19)]]); W Free module of degree 3 and rank 2 over Integer Ring User basis matrix: [ 1 2 3] [ 4 5 19]
We can save and load submodules and elements:
sage: loads(W.dumps()) == W True sage: v = W.0 + W.1 sage: loads(v.dumps()) == v True
>>> from sage.all import * >>> loads(W.dumps()) == W True >>> v = W.gen(0) + W.gen(1) >>> loads(v.dumps()) == v True
- class sage.modules.free_quadratic_module.FreeQuadraticModule_submodule_with_basis_field(ambient, basis, inner_product_matrix, check=True, echelonize=False, echelonized_basis=None, already_echelonized=False)[source]¶
Bases:
FreeModule_submodule_with_basis_field
,FreeQuadraticModule_generic_field
,FreeQuadraticModule_submodule_with_basis_pid
An embedded vector subspace with a distinguished user basis.
EXAMPLES:
sage: M = QQ^3; W = M.submodule_with_basis([[1,2,3], [4,5,19]]); W Vector space of degree 3 and dimension 2 over Rational Field User basis matrix: [ 1 2 3] [ 4 5 19]
>>> from sage.all import * >>> M = QQ**Integer(3); W = M.submodule_with_basis([[Integer(1),Integer(2),Integer(3)], [Integer(4),Integer(5),Integer(19)]]); W Vector space of degree 3 and dimension 2 over Rational Field User basis matrix: [ 1 2 3] [ 4 5 19]
Since this is an embedded vector subspace with a distinguished user basis possibly different than the echelonized basis, the
echelon_coordinates()
and usercoordinates()
do not agree:sage: V = QQ^3 sage: W = V.submodule_with_basis([[1,2,3], [4,5,6]]) sage: W Vector space of degree 3 and dimension 2 over Rational Field User basis matrix: [1 2 3] [4 5 6] sage: v = V([1,5,9]) sage: W.echelon_coordinates(v) [1, 5] sage: vector(QQ, W.echelon_coordinates(v)) * W.echelonized_basis_matrix() (1, 5, 9) sage: v = V([1,5,9]) sage: W.coordinates(v) [5, -1] sage: vector(QQ, W.coordinates(v)) * W.basis_matrix() (1, 5, 9)
>>> from sage.all import * >>> V = QQ**Integer(3) >>> W = V.submodule_with_basis([[Integer(1),Integer(2),Integer(3)], [Integer(4),Integer(5),Integer(6)]]) >>> W Vector space of degree 3 and dimension 2 over Rational Field User basis matrix: [1 2 3] [4 5 6] >>> v = V([Integer(1),Integer(5),Integer(9)]) >>> W.echelon_coordinates(v) [1, 5] >>> vector(QQ, W.echelon_coordinates(v)) * W.echelonized_basis_matrix() (1, 5, 9) >>> v = V([Integer(1),Integer(5),Integer(9)]) >>> W.coordinates(v) [5, -1] >>> vector(QQ, W.coordinates(v)) * W.basis_matrix() (1, 5, 9)
We can load and save submodules:
sage: loads(W.dumps()) == W True sage: K.<x> = FractionField(PolynomialRing(QQ,'x')) sage: M = K^3; W = M.span_of_basis([[1,1,x]]) sage: loads(W.dumps()) == W True
>>> from sage.all import * >>> loads(W.dumps()) == W True >>> K = FractionField(PolynomialRing(QQ,'x'), names=('x',)); (x,) = K._first_ngens(1) >>> M = K**Integer(3); W = M.span_of_basis([[Integer(1),Integer(1),x]]) >>> loads(W.dumps()) == W True
- class sage.modules.free_quadratic_module.FreeQuadraticModule_submodule_with_basis_pid(ambient, basis, inner_product_matrix, check=True, echelonize=False, echelonized_basis=None, already_echelonized=False)[source]¶
Bases:
FreeModule_submodule_with_basis_pid
,FreeQuadraticModule_generic_pid
An \(R\)-submodule of \(K^n\) with distinguished basis, where \(K\) is the fraction field of a principal ideal domain \(R\).
Modules are ordered by inclusion.
EXAMPLES:
First we compare two equal vector spaces:
sage: A = FreeQuadraticModule(QQ,3,2*matrix.identity(3)) sage: V = A.span([[1,2,3], [5,6,7], [8,9,10]]) sage: W = A.span([[5,6,7], [8,9,10]]) sage: V == W True
>>> from sage.all import * >>> A = FreeQuadraticModule(QQ,Integer(3),Integer(2)*matrix.identity(Integer(3))) >>> V = A.span([[Integer(1),Integer(2),Integer(3)], [Integer(5),Integer(6),Integer(7)], [Integer(8),Integer(9),Integer(10)]]) >>> W = A.span([[Integer(5),Integer(6),Integer(7)], [Integer(8),Integer(9),Integer(10)]]) >>> V == W True
Next we compare a one dimensional space to the two dimensional space defined above:
sage: M = A.span([[5,6,7]]) sage: V == M False sage: M < V True sage: V < M False
>>> from sage.all import * >>> M = A.span([[Integer(5),Integer(6),Integer(7)]]) >>> V == M False >>> M < V True >>> V < M False
We compare a \(\ZZ\)-module to the one-dimensional space above:
sage: V = A.span([[5,6,7]]) sage: V = V.change_ring(ZZ).scale(1/11) sage: V < M True sage: M < V False
>>> from sage.all import * >>> V = A.span([[Integer(5),Integer(6),Integer(7)]]) >>> V = V.change_ring(ZZ).scale(Integer(1)/Integer(11)) >>> V < M True >>> M < V False
- change_ring(R)[source]¶
Return the free module over \(R\) obtained by coercing each element of
self
into a vector over the fraction field of \(R\), then taking the resulting \(R\)-module.This raises a
TypeError
if coercion is not possible.INPUT:
R
– a principal ideal domain
EXAMPLES:
Changing rings preserves the inner product and the user basis:
sage: V = QQ^3 sage: W = V.subspace([[2, '1/2', 1]]); W Vector space of degree 3 and dimension 1 over Rational Field Basis matrix: [ 1 1/4 1/2] sage: W.change_ring(GF(7)) Vector space of degree 3 and dimension 1 over Finite Field of size 7 Basis matrix: [1 2 4] sage: N = FreeModule(ZZ, 2, inner_product_matrix=[[1,-1], [2,5]]) sage: N.inner_product_matrix() [ 1 -1] [ 2 5] sage: Np = N.change_ring(RDF) sage: Np.inner_product_matrix() [ 1.0 -1.0] [ 2.0 5.0]
>>> from sage.all import * >>> V = QQ**Integer(3) >>> W = V.subspace([[Integer(2), '1/2', Integer(1)]]); W Vector space of degree 3 and dimension 1 over Rational Field Basis matrix: [ 1 1/4 1/2] >>> W.change_ring(GF(Integer(7))) Vector space of degree 3 and dimension 1 over Finite Field of size 7 Basis matrix: [1 2 4] >>> N = FreeModule(ZZ, Integer(2), inner_product_matrix=[[Integer(1),-Integer(1)], [Integer(2),Integer(5)]]) >>> N.inner_product_matrix() [ 1 -1] [ 2 5] >>> Np = N.change_ring(RDF) >>> Np.inner_product_matrix() [ 1.0 -1.0] [ 2.0 5.0]
- sage.modules.free_quadratic_module.InnerProductSpace(K, dimension, inner_product_matrix, sparse=False)[source]¶
EXAMPLES:
The base can be complicated, as long as it is a field:
sage: F.<x> = FractionField(PolynomialRing(ZZ,'x')) sage: D = diagonal_matrix([x, x - 1, x + 1]) sage: V = QuadraticSpace(F, 3, D) sage: V Ambient quadratic space of dimension 3 over Fraction Field of Univariate Polynomial Ring in x over Integer Ring Inner product matrix: [ x 0 0] [ 0 x - 1 0] [ 0 0 x + 1] sage: V.basis() [ (1, 0, 0), (0, 1, 0), (0, 0, 1) ]
>>> from sage.all import * >>> F = FractionField(PolynomialRing(ZZ,'x'), names=('x',)); (x,) = F._first_ngens(1) >>> D = diagonal_matrix([x, x - Integer(1), x + Integer(1)]) >>> V = QuadraticSpace(F, Integer(3), D) >>> V Ambient quadratic space of dimension 3 over Fraction Field of Univariate Polynomial Ring in x over Integer Ring Inner product matrix: [ x 0 0] [ 0 x - 1 0] [ 0 0 x + 1] >>> V.basis() [ (1, 0, 0), (0, 1, 0), (0, 0, 1) ]
The base must be a field or a
TypeError
is raised:sage: QuadraticSpace(ZZ, 5, identity_matrix(ZZ,2)) Traceback (most recent call last): ... TypeError: argument K (= Integer Ring) must be a field
>>> from sage.all import * >>> QuadraticSpace(ZZ, Integer(5), identity_matrix(ZZ,Integer(2))) Traceback (most recent call last): ... TypeError: argument K (= Integer Ring) must be a field
- sage.modules.free_quadratic_module.QuadraticSpace(K, dimension, inner_product_matrix, sparse=False)[source]¶
EXAMPLES:
The base can be complicated, as long as it is a field:
sage: F.<x> = FractionField(PolynomialRing(ZZ,'x')) sage: D = diagonal_matrix([x, x - 1, x + 1]) sage: V = QuadraticSpace(F, 3, D) sage: V Ambient quadratic space of dimension 3 over Fraction Field of Univariate Polynomial Ring in x over Integer Ring Inner product matrix: [ x 0 0] [ 0 x - 1 0] [ 0 0 x + 1] sage: V.basis() [ (1, 0, 0), (0, 1, 0), (0, 0, 1) ]
>>> from sage.all import * >>> F = FractionField(PolynomialRing(ZZ,'x'), names=('x',)); (x,) = F._first_ngens(1) >>> D = diagonal_matrix([x, x - Integer(1), x + Integer(1)]) >>> V = QuadraticSpace(F, Integer(3), D) >>> V Ambient quadratic space of dimension 3 over Fraction Field of Univariate Polynomial Ring in x over Integer Ring Inner product matrix: [ x 0 0] [ 0 x - 1 0] [ 0 0 x + 1] >>> V.basis() [ (1, 0, 0), (0, 1, 0), (0, 0, 1) ]
The base must be a field or a
TypeError
is raised:sage: QuadraticSpace(ZZ, 5, identity_matrix(ZZ,2)) Traceback (most recent call last): ... TypeError: argument K (= Integer Ring) must be a field
>>> from sage.all import * >>> QuadraticSpace(ZZ, Integer(5), identity_matrix(ZZ,Integer(2))) Traceback (most recent call last): ... TypeError: argument K (= Integer Ring) must be a field
- sage.modules.free_quadratic_module.is_FreeQuadraticModule(M)[source]¶
Return
True
if \(M\) is a free quadratic module.EXAMPLES:
sage: from sage.modules.free_quadratic_module import is_FreeQuadraticModule sage: U = FreeModule(QQ,3) sage: is_FreeQuadraticModule(U) doctest:warning... DeprecationWarning: the function is_FreeQuadraticModule is deprecated; use 'isinstance(..., FreeQuadraticModule_generic)' instead See https://github.com/sagemath/sage/issues/37924 for details. False sage: V = FreeModule(QQ,3,inner_product_matrix=diagonal_matrix([1,1,1])) sage: is_FreeQuadraticModule(V) True sage: W = FreeModule(QQ,3,inner_product_matrix=diagonal_matrix([2,3,3])) sage: is_FreeQuadraticModule(W) True
>>> from sage.all import * >>> from sage.modules.free_quadratic_module import is_FreeQuadraticModule >>> U = FreeModule(QQ,Integer(3)) >>> is_FreeQuadraticModule(U) doctest:warning... DeprecationWarning: the function is_FreeQuadraticModule is deprecated; use 'isinstance(..., FreeQuadraticModule_generic)' instead See https://github.com/sagemath/sage/issues/37924 for details. False >>> V = FreeModule(QQ,Integer(3),inner_product_matrix=diagonal_matrix([Integer(1),Integer(1),Integer(1)])) >>> is_FreeQuadraticModule(V) True >>> W = FreeModule(QQ,Integer(3),inner_product_matrix=diagonal_matrix([Integer(2),Integer(3),Integer(3)])) >>> is_FreeQuadraticModule(W) True