Helper classes to implement tensor operations#
Warning
This module is not meant to be used directly. It just provides functionality for other classes to implement tensor operations.
The VectorCollection
constructs the basis of tensor products
(and symmetric/exterior powers) in terms of a chosen collection of
vectors that generate the vector space(s).
EXAMPLES:
sage: from sage.modules.tensor_operations import VectorCollection, TensorOperation
sage: V = VectorCollection([(1,0), (-1, 0), (1,2)], QQ, 2)
sage: W = VectorCollection([(1,1), (1,-1), (-1, 1)], QQ, 2)
sage: VW = TensorOperation([V, W], operation='product')
Here is the tensor product of two vectors:
sage: V.vectors()[0]
(1, 0)
sage: W.vectors()[1]
(1, -1)
In a convenient choice of basis, the tensor product is
\((a,b)\otimes(c,d)=(ac,ad,bc,bd)\). In this example, it is one of the
vectors of the vector collection VW
sage: VW.index_map(0, 1)
1
sage: VW.vectors()[VW.index_map(0, 1)]
(1, -1, 0, 0)
sage: rows = []
sage: for i, j in cartesian_product((range(3), range(3))):
....: v = V.vectors()[i]
....: w = W.vectors()[j]
....: i_tensor_j = VW.index_map(i, j)
....: vw = VW.vectors()[i_tensor_j]
....: rows.append([i, v, j, w, i_tensor_j, vw])
sage: table(rows)
0 (1, 0) 0 (1, 1) 0 (1, 1, 0, 0)
0 (1, 0) 1 (1, -1) 1 (1, -1, 0, 0)
0 (1, 0) 2 (-1, 1) 2 (-1, 1, 0, 0)
1 (-1, 0) 0 (1, 1) 3 (-1, -1, 0, 0)
1 (-1, 0) 1 (1, -1) 2 (-1, 1, 0, 0)
1 (-1, 0) 2 (-1, 1) 1 (1, -1, 0, 0)
2 (1, 2) 0 (1, 1) 4 (1, 1, 2, 2)
2 (1, 2) 1 (1, -1) 5 (1, -1, 2, -2)
2 (1, 2) 2 (-1, 1) 6 (-1, 1, -2, 2)
- class sage.modules.tensor_operations.TensorOperation(vector_collections, operation='product')#
Bases:
VectorCollection
Auxiliary class to compute the tensor product of two
VectorCollection
objects.Warning
This class is only used as a base class for filtered vector spaces. You should not use it yourself.
INPUT:
vector_collections
– a nonempty list/tuple/iterable ofVectorCollection
objects.operation
– string. The tensor operation. Currently allowed values areproduct
,symmetric
, andantisymmetric
.
Todo
More general tensor operations (specified by Young tableaux) should be implemented.
EXAMPLES:
sage: from sage.modules.tensor_operations import VectorCollection, TensorOperation sage: R = VectorCollection([(1,0), (1,2), (-1,-2)], QQ, 2) sage: S = VectorCollection([(1,), (-1,)], QQ, 1) sage: R_tensor_S = TensorOperation([R, S]) sage: R_tensor_S.index_map(0, 0) 0 sage: matrix(ZZ, 3, 2, lambda i,j: R_tensor_S.index_map(i, j)) [0 1] [2 3] [3 2] sage: R_tensor_S.vectors() ((1, 0), (-1, 0), (1, 2), (-1, -2))
- codomain()#
The codomain of the index map.
OUTPUT:
A list of integers. The image of
index_map()
.EXAMPLES:
sage: from sage.modules.tensor_operations import ....: VectorCollection, TensorOperation sage: R = VectorCollection([(1,0), (0,1), (-2,-3)], QQ, 2) sage: detR = TensorOperation([R]*2, 'antisymmetric') # needs sage.groups sage: sorted(detR.preimage()) # needs sage.groups [(0, 1), (0, 2), (1, 2)] sage: sorted(detR.codomain()) # needs sage.groups [0, 1, 2]
- index_map(*i)#
Return the result of the tensor operation.
INPUT:
*i
– list of integers. The indices (in the corresponding factor of the tensor operation) of the domain vector.
OUTPUT:
The index (in
vectors()
) of the image of the tensor product/operation acting on the domain vectors indexed by \(i\).None
is returned if the tensor operation maps the generators to zero (usually because of antisymmetry).EXAMPLES:
sage: from sage.modules.tensor_operations import ....: VectorCollection, TensorOperation sage: R = VectorCollection([(1,0), (1,2), (-1,-2)], QQ, 2) sage: Sym3_R = TensorOperation([R]*3, 'symmetric')
The symmetric product of the first vector
(1,0)
, the second vector(1,2)
, and the third vector(-1,-2)
equals the vector with index number 4 (that is, the fifth) in the symmetric product vector collection:sage: Sym3_R.index_map(0, 1, 2) 4
In suitable coordinates, this is the vector:
sage: Sym3_R.vectors()[4] (-1, -4, -4, 0)
The product is symmetric:
sage: Sym3_R.index_map(2, 0, 1) 4 sage: Sym3_R.index_map(2, 1, 0) 4
As another example, here is the rank-2 determinant:
sage: from sage.modules.tensor_operations import ....: VectorCollection, TensorOperation sage: R = VectorCollection([(1,0), (0,1), (-2,-3)], QQ, 2) sage: detR = TensorOperation([R]*2, 'antisymmetric') # needs sage.groups sage: detR.index_map(1, 0) # needs sage.groups 0 sage: detR.index_map(0, 1) # needs sage.groups 0
- preimage()#
A choice of pre-image multi-indices.
OUTPUT:
A list of multi-indices (tuples of integers) whose image is the entire image under the
index_map()
.EXAMPLES:
sage: from sage.modules.tensor_operations import ....: VectorCollection, TensorOperation sage: R = VectorCollection([(1,0), (0,1), (-2,-3)], QQ, 2) sage: detR = TensorOperation([R]*2, 'antisymmetric') # needs sage.groups sage: sorted(detR.preimage()) # needs sage.groups [(0, 1), (0, 2), (1, 2)] sage: sorted(detR.codomain()) # needs sage.groups [0, 1, 2]
- class sage.modules.tensor_operations.VectorCollection(vector_collection, base_ring, dim)#
Bases:
FreeModule_ambient_field
An ordered collection of generators of a vector space.
This is like a list of vectors, but with extra argument checking.
Warning
This class is only used as a base class for filtered vector spaces. You should not use it yourself.
INPUT:
dim
– integer. The dimension of the ambient vector space.base_ring
– a field. The base field of the ambient vector space.rays
– any list/iterable of things than can be converted into vectors of the ambient vector space. These will be used to span the subspaces of the filtration. Must span the ambient vector space.
EXAMPLES:
sage: from sage.modules.tensor_operations import VectorCollection sage: R = VectorCollection([(1,0), (0,1), (1,2)], QQ, 2); R Vector space of dimension 2 over Rational Field
- n_vectors()#
Return the number of vectors
OUTPUT:
Integer.
EXAMPLES:
sage: from sage.modules.tensor_operations import VectorCollection sage: V = VectorCollection([(1,0), (0,1), (1,2)], QQ, 2) sage: V.n_vectors() 3
- vectors()#
Return the collection of vectors
OUTPUT:
A tuple of vectors. The vectors that were specified in the constructor, in the same order.
EXAMPLES:
sage: from sage.modules.tensor_operations import VectorCollection sage: V = VectorCollection([(1,0), (0,1), (1,2)], QQ, 2) sage: V.vectors() ((1, 0), (0, 1), (1, 2))
- sage.modules.tensor_operations.antisymmetrized_coordinate_sums(dim, n)#
Return formal anti-symmetrized sum of multi-indices
INPUT:
dim
– integer. The dimension (range of each index).n
– integer. The total number of indices.
OUTPUT:
An anti-symmetrized formal sum of multi-indices (tuples of integers)
EXAMPLES:
sage: from sage.modules.tensor_operations import antisymmetrized_coordinate_sums sage: antisymmetrized_coordinate_sums(3, 2) # needs sage.groups ((0, 1) - (1, 0), (0, 2) - (2, 0), (1, 2) - (2, 1))
- sage.modules.tensor_operations.symmetrized_coordinate_sums(dim, n)#
Return formal symmetrized sum of multi-indices
INPUT:
dim
– integer. The dimension (range of each index).n
– integer. The total number of indices.
OUTPUT:
A symmetrized formal sum of multi-indices (tuples of integers)
EXAMPLES:
sage: from sage.modules.tensor_operations import symmetrized_coordinate_sums sage: symmetrized_coordinate_sums(2, 2) ((0, 0), (0, 1) + (1, 0), (1, 1))