# Tensor products of free modules#

The class TensorFreeModule implements tensor products of the type

$T^{(k,l)}(M) = \underbrace{M\otimes\cdots\otimes M}_{k\ \; \mbox{times}} \otimes \underbrace{M^*\otimes\cdots\otimes M^*}_{l\ \; \mbox{times}},$

where $$M$$ is a free module of finite rank over a commutative ring $$R$$ and $$M^*=\mathrm{Hom}_R(M,R)$$ is the dual of $$M$$. Note that $$T^{(1,0)}(M) = M$$ and $$T^{(0,1)}(M) = M^*$$.

Thanks to the canonical isomorphism $$M^{**} \simeq M$$ (which holds since $$M$$ is a free module of finite rank), $$T^{(k,l)}(M)$$ can be identified with the set of tensors of type $$(k,l)$$ defined as multilinear maps

$\underbrace{M^*\times\cdots\times M^*}_{k\ \; \mbox{times}} \times \underbrace{M\times\cdots\times M}_{l\ \; \mbox{times}} \longrightarrow R$

Accordingly, TensorFreeModule is a Sage parent class, whose element class is FreeModuleTensor.

$$T^{(k,l)}(M)$$ is itself a free module over $$R$$, of rank $$n^{k+l}$$, $$n$$ being the rank of $$M$$. Accordingly the class TensorFreeModule inherits from the class FiniteRankFreeModule_abstract.

Todo

implement more general tensor products, i.e. tensor product of the type $$M_1\otimes\cdots\otimes M_n$$, where the $$M_i$$’s are $$n$$ free modules of finite rank over the same ring $$R$$.

AUTHORS:

• Eric Gourgoulhon, Michal Bejger (2014-2015): initial version

REFERENCES:

class sage.tensor.modules.tensor_free_module.TensorFreeModule(fmodule, tensor_type, name=None, latex_name=None, category=None)[source]#

Class for the free modules over a commutative ring $$R$$ that are tensor products of a given free module $$M$$ over $$R$$ with itself and its dual $$M^*$$:

$T^{(k,l)}(M) = \underbrace{M\otimes\cdots\otimes M}_{k\ \; \mbox{times}} \otimes \underbrace{M^*\otimes\cdots\otimes M^*}_{l\ \; \mbox{times}}$

As recalled above, $$T^{(k,l)}(M)$$ can be canonically identified with the set of tensors of type $$(k,l)$$ on $$M$$.

This is a Sage parent class, whose element class is FreeModuleTensor.

INPUT:

• fmodule – free module $$M$$ of finite rank over a commutative ring $$R$$, as an instance of FiniteRankFreeModule

• tensor_type – pair (k, l) with k being the contravariant rank and l the covariant rank

• name – (default: None) string; name given to the tensor module

• latex_name – (default: None) string; LaTeX symbol to denote the tensor module; if none is provided, it is set to name

EXAMPLES:

Set of tensors of type $$(1,2)$$ on a free $$\ZZ$$-module of rank 3:

sage: M = FiniteRankFreeModule(ZZ, 3, name='M')
sage: e = M.basis('e')
sage: from sage.tensor.modules.tensor_free_module import TensorFreeModule
sage: T = TensorFreeModule(M, (1,2)) ; T
Free module of type-(1,2) tensors on the
Rank-3 free module M over the Integer Ring

>>> from sage.all import *
>>> M = FiniteRankFreeModule(ZZ, Integer(3), name='M')
>>> e = M.basis('e')
>>> from sage.tensor.modules.tensor_free_module import TensorFreeModule
>>> T = TensorFreeModule(M, (Integer(1),Integer(2))) ; T
Free module of type-(1,2) tensors on the
Rank-3 free module M over the Integer Ring


Instead of importing TensorFreeModule in the global name space, it is recommended to use the module’s method tensor_module():

sage: T = M.tensor_module(1,2) ; T
Free module of type-(1,2) tensors on the
Rank-3 free module M over the Integer Ring
sage: latex(T)
T^{(1, 2)}\left(M\right)

>>> from sage.all import *
>>> T = M.tensor_module(Integer(1),Integer(2)) ; T
Free module of type-(1,2) tensors on the
Rank-3 free module M over the Integer Ring
>>> latex(T)
T^{(1, 2)}\left(M\right)


The module M itself is considered as the set of tensors of type $$(1,0)$$:

sage: M is M.tensor_module(1,0)
True

>>> from sage.all import *
>>> M is M.tensor_module(Integer(1),Integer(0))
True


T is a module (actually a free module) over $$\ZZ$$:

sage: T.category()
Category of tensor products of finite dimensional modules over Integer Ring
sage: T in Modules(ZZ)
True
sage: T.rank()
27
sage: T.base_ring()
Integer Ring
sage: T.base_module()
Rank-3 free module M over the Integer Ring

>>> from sage.all import *
>>> T.category()
Category of tensor products of finite dimensional modules over Integer Ring
>>> T in Modules(ZZ)
True
>>> T.rank()
27
>>> T.base_ring()
Integer Ring
>>> T.base_module()
Rank-3 free module M over the Integer Ring


T is a parent object, whose elements are instances of FreeModuleTensor:

sage: t = T.an_element() ; t
Type-(1,2) tensor on the Rank-3 free module M over the Integer Ring
sage: from sage.tensor.modules.free_module_tensor import FreeModuleTensor
sage: isinstance(t, FreeModuleTensor)
True
sage: t in T
True
sage: T.is_parent_of(t)
True

>>> from sage.all import *
>>> t = T.an_element() ; t
Type-(1,2) tensor on the Rank-3 free module M over the Integer Ring
>>> from sage.tensor.modules.free_module_tensor import FreeModuleTensor
>>> isinstance(t, FreeModuleTensor)
True
>>> t in T
True
>>> T.is_parent_of(t)
True


Elements can be constructed from T. In particular, 0 yields the zero element of T:

sage: T(0)
Type-(1,2) tensor zero on the Rank-3 free module M over the Integer Ring
sage: T(0) is T.zero()
True

>>> from sage.all import *
>>> T(Integer(0))
Type-(1,2) tensor zero on the Rank-3 free module M over the Integer Ring
>>> T(Integer(0)) is T.zero()
True


while non-zero elements are constructed by providing their components in a given basis:

sage: e
Basis (e_0,e_1,e_2) on the Rank-3 free module M over the Integer Ring
sage: comp = [[[i-j+k for k in range(3)] for j in range(3)] for i in range(3)]
sage: t = T(comp, basis=e, name='t') ; t
Type-(1,2) tensor t on the Rank-3 free module M over the Integer Ring
sage: t.comp(e)[:]
[[[0, 1, 2], [-1, 0, 1], [-2, -1, 0]],
[[1, 2, 3], [0, 1, 2], [-1, 0, 1]],
[[2, 3, 4], [1, 2, 3], [0, 1, 2]]]
sage: t.display(e)
t = e_0⊗e^0⊗e^1 + 2 e_0⊗e^0⊗e^2 - e_0⊗e^1⊗e^0 + e_0⊗e^1⊗e^2
- 2 e_0⊗e^2⊗e^0 - e_0⊗e^2⊗e^1 + e_1⊗e^0⊗e^0 + 2 e_1⊗e^0⊗e^1
+ 3 e_1⊗e^0⊗e^2 + e_1⊗e^1⊗e^1 + 2 e_1⊗e^1⊗e^2 - e_1⊗e^2⊗e^0
+ e_1⊗e^2⊗e^2 + 2 e_2⊗e^0⊗e^0 + 3 e_2⊗e^0⊗e^1 + 4 e_2⊗e^0⊗e^2
+ e_2⊗e^1⊗e^0 + 2 e_2⊗e^1⊗e^1 + 3 e_2⊗e^1⊗e^2 + e_2⊗e^2⊗e^1
+ 2 e_2⊗e^2⊗e^2

>>> from sage.all import *
>>> e
Basis (e_0,e_1,e_2) on the Rank-3 free module M over the Integer Ring
>>> comp = [[[i-j+k for k in range(Integer(3))] for j in range(Integer(3))] for i in range(Integer(3))]
>>> t = T(comp, basis=e, name='t') ; t
Type-(1,2) tensor t on the Rank-3 free module M over the Integer Ring
>>> t.comp(e)[:]
[[[0, 1, 2], [-1, 0, 1], [-2, -1, 0]],
[[1, 2, 3], [0, 1, 2], [-1, 0, 1]],
[[2, 3, 4], [1, 2, 3], [0, 1, 2]]]
>>> t.display(e)
t = e_0⊗e^0⊗e^1 + 2 e_0⊗e^0⊗e^2 - e_0⊗e^1⊗e^0 + e_0⊗e^1⊗e^2
- 2 e_0⊗e^2⊗e^0 - e_0⊗e^2⊗e^1 + e_1⊗e^0⊗e^0 + 2 e_1⊗e^0⊗e^1
+ 3 e_1⊗e^0⊗e^2 + e_1⊗e^1⊗e^1 + 2 e_1⊗e^1⊗e^2 - e_1⊗e^2⊗e^0
+ e_1⊗e^2⊗e^2 + 2 e_2⊗e^0⊗e^0 + 3 e_2⊗e^0⊗e^1 + 4 e_2⊗e^0⊗e^2
+ e_2⊗e^1⊗e^0 + 2 e_2⊗e^1⊗e^1 + 3 e_2⊗e^1⊗e^2 + e_2⊗e^2⊗e^1
+ 2 e_2⊗e^2⊗e^2


An alternative is to construct the tensor from an empty list of components and to set the nonzero components afterwards:

sage: t = T([], name='t')
sage: t.set_comp(e)[0,1,1] = -3
sage: t.set_comp(e)[2,0,1] = 4
sage: t.display(e)
t = -3 e_0⊗e^1⊗e^1 + 4 e_2⊗e^0⊗e^1

>>> from sage.all import *
>>> t = T([], name='t')
>>> t.set_comp(e)[Integer(0),Integer(1),Integer(1)] = -Integer(3)
>>> t.set_comp(e)[Integer(2),Integer(0),Integer(1)] = Integer(4)
>>> t.display(e)
t = -3 e_0⊗e^1⊗e^1 + 4 e_2⊗e^0⊗e^1


See the documentation of FreeModuleTensor for the full list of arguments that can be provided to the __call__ operator. For instance, to construct a tensor symmetric with respect to the last two indices:

sage: t = T([], name='t', sym=(1,2))
sage: t.set_comp(e)[0,1,1] = -3
sage: t.set_comp(e)[2,0,1] = 4
sage: t.display(e)  # notice that t^2_{10} has be set equal to t^2_{01} by symmetry
t = -3 e_0⊗e^1⊗e^1 + 4 e_2⊗e^0⊗e^1 + 4 e_2⊗e^1⊗e^0

>>> from sage.all import *
>>> t = T([], name='t', sym=(Integer(1),Integer(2)))
>>> t.set_comp(e)[Integer(0),Integer(1),Integer(1)] = -Integer(3)
>>> t.set_comp(e)[Integer(2),Integer(0),Integer(1)] = Integer(4)
>>> t.display(e)  # notice that t^2_{10} has be set equal to t^2_{01} by symmetry
t = -3 e_0⊗e^1⊗e^1 + 4 e_2⊗e^0⊗e^1 + 4 e_2⊗e^1⊗e^0


The tensor modules over a given module $$M$$ are unique:

sage: T is M.tensor_module(1,2)
True

>>> from sage.all import *
>>> T is M.tensor_module(Integer(1),Integer(2))
True


There is a coercion map from $$\Lambda^p(M^*)$$, the set of alternating forms of degree $$p$$, to $$T^{(0,p)}(M)$$:

sage: L2 = M.dual_exterior_power(2) ; L2
2nd exterior power of the dual of the Rank-3 free module M over the
Integer Ring
sage: T02 = M.tensor_module(0,2) ; T02
Free module of type-(0,2) tensors on the Rank-3 free module M over the
Integer Ring
sage: T02.has_coerce_map_from(L2)
True

>>> from sage.all import *
>>> L2 = M.dual_exterior_power(Integer(2)) ; L2
2nd exterior power of the dual of the Rank-3 free module M over the
Integer Ring
>>> T02 = M.tensor_module(Integer(0),Integer(2)) ; T02
Free module of type-(0,2) tensors on the Rank-3 free module M over the
Integer Ring
>>> T02.has_coerce_map_from(L2)
True


Of course, for $$p\geq 2$$, there is no coercion in the reverse direction, since not every tensor of type $$(0,p)$$ is alternating:

sage: L2.has_coerce_map_from(T02)
False

>>> from sage.all import *
>>> L2.has_coerce_map_from(T02)
False


The coercion map $$\Lambda^2(M^*)\rightarrow T^{(0,2)}(M)$$ in action:

sage: a = M.alternating_form(2, name='a') ; a
Alternating form a of degree 2 on the Rank-3 free module M over the
Integer Ring
sage: a[0,1], a[1,2] = 4, -3
sage: a.display(e)
a = 4 e^0∧e^1 - 3 e^1∧e^2
sage: a.parent() is L2
True
sage: ta = T02(a) ; ta
Type-(0,2) tensor a on the Rank-3 free module M over the Integer Ring
sage: ta.display(e)
a = 4 e^0⊗e^1 - 4 e^1⊗e^0 - 3 e^1⊗e^2 + 3 e^2⊗e^1
sage: ta.symmetries() # the antisymmetry is of course preserved
no symmetry;  antisymmetry: (0, 1)

>>> from sage.all import *
>>> a = M.alternating_form(Integer(2), name='a') ; a
Alternating form a of degree 2 on the Rank-3 free module M over the
Integer Ring
>>> a[Integer(0),Integer(1)], a[Integer(1),Integer(2)] = Integer(4), -Integer(3)
>>> a.display(e)
a = 4 e^0∧e^1 - 3 e^1∧e^2
>>> a.parent() is L2
True
>>> ta = T02(a) ; ta
Type-(0,2) tensor a on the Rank-3 free module M over the Integer Ring
>>> ta.display(e)
a = 4 e^0⊗e^1 - 4 e^1⊗e^0 - 3 e^1⊗e^2 + 3 e^2⊗e^1
>>> ta.symmetries() # the antisymmetry is of course preserved
no symmetry;  antisymmetry: (0, 1)


For the degree $$p=1$$, we have the identity $$\Lambda^1(M^*) = T^{(0,1)}(M) = M^*$$:

sage: M.dual_exterior_power(1) is M.tensor_module(0,1)
True
sage: M.tensor_module(0,1) is M.dual()
True

>>> from sage.all import *
>>> M.dual_exterior_power(Integer(1)) is M.tensor_module(Integer(0),Integer(1))
True
>>> M.tensor_module(Integer(0),Integer(1)) is M.dual()
True


There is a canonical identification between tensors of type $$(1,1)$$ and endomorphisms of module $$M$$. Accordingly, coercion maps have been implemented between $$T^{(1,1)}(M)$$ and $$\mathrm{End}(M)$$ (the module of all endomorphisms of $$M$$, see FreeModuleHomset):

sage: T11 = M.tensor_module(1,1) ; T11
Free module of type-(1,1) tensors on the Rank-3 free module M over the
Integer Ring
sage: End(M)
Set of Morphisms from Rank-3 free module M over the Integer Ring
to Rank-3 free module M over the Integer Ring
in Category of finite dimensional modules over Integer Ring
sage: T11.has_coerce_map_from(End(M))
True
sage: End(M).has_coerce_map_from(T11)
True

>>> from sage.all import *
>>> T11 = M.tensor_module(Integer(1),Integer(1)) ; T11
Free module of type-(1,1) tensors on the Rank-3 free module M over the
Integer Ring
>>> End(M)
Set of Morphisms from Rank-3 free module M over the Integer Ring
to Rank-3 free module M over the Integer Ring
in Category of finite dimensional modules over Integer Ring
>>> T11.has_coerce_map_from(End(M))
True
>>> End(M).has_coerce_map_from(T11)
True


The coercion map $$\mathrm{End}(M)\rightarrow T^{(1,1)}(M)$$ in action:

sage: phi = End(M).an_element() ; phi
Generic endomorphism of Rank-3 free module M over the Integer Ring
sage: phi.matrix(e)
[1 1 1]
[1 1 1]
[1 1 1]
sage: tphi = T11(phi) ; tphi # image of phi by the coercion map
Type-(1,1) tensor on the Rank-3 free module M over the Integer Ring
sage: tphi[:]
[1 1 1]
[1 1 1]
[1 1 1]
sage: t = M.tensor((1,1))
sage: t[0,0], t[1,1], t[2,2] = -1,-2,-3
sage: t[:]
[-1  0  0]
[ 0 -2  0]
[ 0  0 -3]
sage: s = t + phi ; s  # phi is coerced to a type-(1,1) tensor prior to the addition
Type-(1,1) tensor on the Rank-3 free module M over the Integer Ring
sage: s[:]
[ 0  1  1]
[ 1 -1  1]
[ 1  1 -2]

>>> from sage.all import *
>>> phi = End(M).an_element() ; phi
Generic endomorphism of Rank-3 free module M over the Integer Ring
>>> phi.matrix(e)
[1 1 1]
[1 1 1]
[1 1 1]
>>> tphi = T11(phi) ; tphi # image of phi by the coercion map
Type-(1,1) tensor on the Rank-3 free module M over the Integer Ring
>>> tphi[:]
[1 1 1]
[1 1 1]
[1 1 1]
>>> t = M.tensor((Integer(1),Integer(1)))
>>> t[Integer(0),Integer(0)], t[Integer(1),Integer(1)], t[Integer(2),Integer(2)] = -Integer(1),-Integer(2),-Integer(3)
>>> t[:]
[-1  0  0]
[ 0 -2  0]
[ 0  0 -3]
>>> s = t + phi ; s  # phi is coerced to a type-(1,1) tensor prior to the addition
Type-(1,1) tensor on the Rank-3 free module M over the Integer Ring
>>> s[:]
[ 0  1  1]
[ 1 -1  1]
[ 1  1 -2]


The coercion map $$T^{(1,1)}(M) \rightarrow \mathrm{End}(M)$$ in action:

sage: phi1 = End(M)(tphi) ; phi1
Generic endomorphism of Rank-3 free module M over the Integer Ring
sage: phi1 == phi
True
sage: s = phi + t ; s  # t is coerced to an endomorphism prior to the addition
Generic endomorphism of Rank-3 free module M over the Integer Ring
sage: s.matrix(e)
[ 0  1  1]
[ 1 -1  1]
[ 1  1 -2]

>>> from sage.all import *
>>> phi1 = End(M)(tphi) ; phi1
Generic endomorphism of Rank-3 free module M over the Integer Ring
>>> phi1 == phi
True
>>> s = phi + t ; s  # t is coerced to an endomorphism prior to the addition
Generic endomorphism of Rank-3 free module M over the Integer Ring
>>> s.matrix(e)
[ 0  1  1]
[ 1 -1  1]
[ 1  1 -2]


There is a coercion $$\mathrm{GL}(M)\rightarrow T^{(1,1)}(M)$$, i.e. from automorphisms of $$M$$ to type-$$(1,1)$$ tensors on $$M$$:

sage: GL = M.general_linear_group() ; GL
General linear group of the Rank-3 free module M over the Integer Ring
sage: T11.has_coerce_map_from(GL)
True

>>> from sage.all import *
>>> GL = M.general_linear_group() ; GL
General linear group of the Rank-3 free module M over the Integer Ring
>>> T11.has_coerce_map_from(GL)
True


The coercion map $$\mathrm{GL}(M)\rightarrow T^{(1,1)}(M)$$ in action:

sage: a = GL.an_element() ; a
Automorphism of the Rank-3 free module M over the Integer Ring
sage: a.matrix(e)
[ 1  0  0]
[ 0 -1  0]
[ 0  0  1]
sage: ta = T11(a) ; ta
Type-(1,1) tensor on the Rank-3 free module M over the Integer Ring
sage: ta.display(e)
e_0⊗e^0 - e_1⊗e^1 + e_2⊗e^2
sage: a.display(e)
e_0⊗e^0 - e_1⊗e^1 + e_2⊗e^2

>>> from sage.all import *
>>> a = GL.an_element() ; a
Automorphism of the Rank-3 free module M over the Integer Ring
>>> a.matrix(e)
[ 1  0  0]
[ 0 -1  0]
[ 0  0  1]
>>> ta = T11(a) ; ta
Type-(1,1) tensor on the Rank-3 free module M over the Integer Ring
>>> ta.display(e)
e_0⊗e^0 - e_1⊗e^1 + e_2⊗e^2
>>> a.display(e)
e_0⊗e^0 - e_1⊗e^1 + e_2⊗e^2


Of course, there is no coercion in the reverse direction, since not every type-$$(1,1)$$ tensor is invertible:

sage: GL.has_coerce_map_from(T11)
False

>>> from sage.all import *
>>> GL.has_coerce_map_from(T11)
False

Element[source]#

alias of FreeModuleTensor

base_module()[source]#

Return the free module on which self is constructed.

OUTPUT:

EXAMPLES:

Base module of a type-$$(1,2)$$ tensor module:

sage: M = FiniteRankFreeModule(ZZ, 3, name='M')
sage: T = M.tensor_module(1,2)
sage: T.base_module()
Rank-3 free module M over the Integer Ring
sage: T.base_module() is M
True

>>> from sage.all import *
>>> M = FiniteRankFreeModule(ZZ, Integer(3), name='M')
>>> T = M.tensor_module(Integer(1),Integer(2))
>>> T.base_module()
Rank-3 free module M over the Integer Ring
>>> T.base_module() is M
True

basis(symbol, latex_symbol=None, from_family=None, indices=None, latex_indices=None, symbol_dual=None, latex_symbol_dual=None)[source]#

Return the standard basis of self corresponding to a basis of the base module.

INPUT:

EXAMPLES:

sage: M = FiniteRankFreeModule(ZZ, 3, name='M')
sage: T = M.tensor_module(1,1)
sage: e_T = T.basis('e'); e_T
Standard basis on the
Free module of type-(1,1) tensors on the Rank-3 free module M over the Integer Ring
induced by Basis (e_0,e_1,e_2) on the Rank-3 free module M over the Integer Ring
sage: for a in e_T: a.display()
e_0⊗e^0
e_0⊗e^1
e_0⊗e^2
e_1⊗e^0
e_1⊗e^1
e_1⊗e^2
e_2⊗e^0
e_2⊗e^1
e_2⊗e^2

sage: Sym2M = M.tensor_module(2, 0, sym=range(2))
sage: e_Sym2M = Sym2M.basis('e'); e_Sym2M
Standard basis on the
Free module of fully symmetric type-(2,0) tensors on the Rank-3 free module M over the Integer Ring
induced by Basis (e_0,e_1,e_2) on the Rank-3 free module M over the Integer Ring
sage: for a in e_Sym2M: a.display()
e_0⊗e_0
e_0⊗e_1 + e_1⊗e_0
e_0⊗e_2 + e_2⊗e_0
e_1⊗e_1
e_1⊗e_2 + e_2⊗e_1
e_2⊗e_2

sage: M = FiniteRankFreeModule(ZZ, 2)
sage: e = M.basis('e')
sage: f = M.basis('f', from_family=(-e[1], e[0]))
sage: for b in f: b.display()
f_0 = -e_1
f_1 = e_0
sage: S = M.tensor_module(2, 0, sym=(0,1))
sage: fS = S.basis('f')
sage: for b in fS: b.display()
e_1⊗e_1
-e_0⊗e_1 - e_1⊗e_0
e_0⊗e_0
sage: for b in fS: b.display(f)
f_0⊗f_0
f_0⊗f_1 + f_1⊗f_0
f_1⊗f_1

>>> from sage.all import *
>>> M = FiniteRankFreeModule(ZZ, Integer(3), name='M')
>>> T = M.tensor_module(Integer(1),Integer(1))
>>> e_T = T.basis('e'); e_T
Standard basis on the
Free module of type-(1,1) tensors on the Rank-3 free module M over the Integer Ring
induced by Basis (e_0,e_1,e_2) on the Rank-3 free module M over the Integer Ring
>>> for a in e_T: a.display()
e_0⊗e^0
e_0⊗e^1
e_0⊗e^2
e_1⊗e^0
e_1⊗e^1
e_1⊗e^2
e_2⊗e^0
e_2⊗e^1
e_2⊗e^2

>>> Sym2M = M.tensor_module(Integer(2), Integer(0), sym=range(Integer(2)))
>>> e_Sym2M = Sym2M.basis('e'); e_Sym2M
Standard basis on the
Free module of fully symmetric type-(2,0) tensors on the Rank-3 free module M over the Integer Ring
induced by Basis (e_0,e_1,e_2) on the Rank-3 free module M over the Integer Ring
>>> for a in e_Sym2M: a.display()
e_0⊗e_0
e_0⊗e_1 + e_1⊗e_0
e_0⊗e_2 + e_2⊗e_0
e_1⊗e_1
e_1⊗e_2 + e_2⊗e_1
e_2⊗e_2

>>> M = FiniteRankFreeModule(ZZ, Integer(2))
>>> e = M.basis('e')
>>> f = M.basis('f', from_family=(-e[Integer(1)], e[Integer(0)]))
>>> for b in f: b.display()
f_0 = -e_1
f_1 = e_0
>>> S = M.tensor_module(Integer(2), Integer(0), sym=(Integer(0),Integer(1)))
>>> fS = S.basis('f')
>>> for b in fS: b.display()
e_1⊗e_1
-e_0⊗e_1 - e_1⊗e_0
e_0⊗e_0
>>> for b in fS: b.display(f)
f_0⊗f_0
f_0⊗f_1 + f_1⊗f_0
f_1⊗f_1

tensor_type()[source]#

Return the tensor type of self.

OUTPUT:

• pair $$(k,l)$$ such that self is the module tensor product $$T^{(k,l)}(M)$$

EXAMPLES:

sage: M = FiniteRankFreeModule(ZZ, 3)
sage: T = M.tensor_module(1,2)
sage: T.tensor_type()
(1, 2)

>>> from sage.all import *
>>> M = FiniteRankFreeModule(ZZ, Integer(3))
>>> T = M.tensor_module(Integer(1),Integer(2))
>>> T.tensor_type()
(1, 2)

zero()[source]#

Return the zero of self.

EXAMPLES:

sage: M = FiniteRankFreeModule(ZZ, 3, name='M')
sage: e = M.basis('e')
sage: T11 = M.tensor_module(1,1)
sage: T11.zero()
Type-(1,1) tensor zero on the Rank-3 free module M over the Integer
Ring

>>> from sage.all import *
>>> M = FiniteRankFreeModule(ZZ, Integer(3), name='M')
>>> e = M.basis('e')
>>> T11 = M.tensor_module(Integer(1),Integer(1))
>>> T11.zero()
Type-(1,1) tensor zero on the Rank-3 free module M over the Integer
Ring


The zero element is cached:

sage: T11.zero() is T11(0)
True

>>> from sage.all import *
>>> T11.zero() is T11(Integer(0))
True