# 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')#

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 of VectorCollection objects.

• operation – string. The tensor operation. Currently allowed values are product, symmetric, and antisymmetric.

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')
sage: sorted(detR.preimage())
[(0, 1), (0, 2), (1, 2)]
sage: sorted(detR.codomain())
[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')
sage: detR.index_map(1, 0)
0
sage: detR.index_map(0, 1)
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')
sage: sorted(detR.preimage())
[(0, 1), (0, 2), (1, 2)]
sage: sorted(detR.codomain())
[0, 1, 2]

class sage.modules.tensor_operations.VectorCollection(vector_collection, base_ring, dim)#

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