Elements of free modules of finite rank

The class FiniteRankFreeModuleElement implements elements of free modules of finite rank over a commutative ring.

AUTHORS:

REFERENCES:

  • Chap. 21 of R. Godement : Algebra [God1968]

  • Chap. 12 of J. M. Lee: Introduction to Smooth Manifolds [Lee2013] (only when the free module is a vector space)

  • Chap. 2 of B. O’Neill: Semi-Riemannian Geometry [ONe1983]

class sage.tensor.modules.free_module_element.FiniteRankFreeModuleElement(fmodule: FiniteRankFreeModule, name: str | None = None, latex_name: str | None = None)[source]

Bases: AlternatingContrTensor

Element of a free module of finite rank over a commutative ring.

This is a Sage element class, the corresponding parent class being FiniteRankFreeModule.

The class FiniteRankFreeModuleElement inherits from AlternatingContrTensor because the elements of a free module \(M\) of finite rank over a commutative ring \(R\) are identified with tensors of type \((1,0)\) on \(M\) via the canonical map

\[\begin{split}\begin{array}{lllllll} \Phi: & M & \longrightarrow & M^{**} & & & \\ & v & \longmapsto & \bar v : & M^* & \longrightarrow & R \\ & & & & a & \longmapsto & a(v) \end{array}\end{split}\]

Note that for free modules of finite rank, this map is actually an isomorphism, enabling the canonical identification: \(M^{**}= M\).

INPUT:

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

  • name – (default: None) name given to the element

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

EXAMPLES:

Let us consider a rank-3 free module \(M\) over \(\ZZ\):

sage: M = FiniteRankFreeModule(ZZ, 3, name='M')
sage: e = M.basis('e') ; e
Basis (e_0,e_1,e_2) 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') ; e
Basis (e_0,e_1,e_2) on the Rank-3 free module M over the Integer Ring
M = FiniteRankFreeModule(ZZ, 3, name='M')
e = M.basis('e') ; e

There are three ways to construct an element of the free module \(M\): the first one (recommended) is using the free module:

sage: v = M([2,0,-1], basis=e, name='v') ; v
Element v of the Rank-3 free module M over the Integer Ring
sage: v.display()  # expansion on the default basis (e)
v = 2 e_0 - e_2
sage: v.parent() is M
True
>>> from sage.all import *
>>> v = M([Integer(2),Integer(0),-Integer(1)], basis=e, name='v') ; v
Element v of the Rank-3 free module M over the Integer Ring
>>> v.display()  # expansion on the default basis (e)
v = 2 e_0 - e_2
>>> v.parent() is M
True
v = M([2,0,-1], basis=e, name='v') ; v
v.display()  # expansion on the default basis (e)
v.parent() is M

The second way is to construct a tensor of type \((1,0)\) on \(M\) (cf. the canonical identification \(M^{**} = M\) recalled above):

sage: v2 = M.tensor((1,0), name='v')
sage: v2[0], v2[2] = 2, -1 ; v2
Element v of the Rank-3 free module M over the Integer Ring
sage: v2.display()
v = 2 e_0 - e_2
sage: v2 == v
True
>>> from sage.all import *
>>> v2 = M.tensor((Integer(1),Integer(0)), name='v')
>>> v2[Integer(0)], v2[Integer(2)] = Integer(2), -Integer(1) ; v2
Element v of the Rank-3 free module M over the Integer Ring
>>> v2.display()
v = 2 e_0 - e_2
>>> v2 == v
True
v2 = M.tensor((1,0), name='v')
v2[0], v2[2] = 2, -1 ; v2
v2.display()
v2 == v

Finally, the third way is via some linear combination of the basis elements:

sage: v3 = 2*e[0] - e[2]
sage: v3.set_name('v') ; v3 # in this case, the name has to be set separately
Element v of the Rank-3 free module M over the Integer Ring
sage: v3.display()
v = 2 e_0 - e_2
sage: v3 == v
True
>>> from sage.all import *
>>> v3 = Integer(2)*e[Integer(0)] - e[Integer(2)]
>>> v3.set_name('v') ; v3 # in this case, the name has to be set separately
Element v of the Rank-3 free module M over the Integer Ring
>>> v3.display()
v = 2 e_0 - e_2
>>> v3 == v
True
v3 = 2*e[0] - e[2]
v3.set_name('v') ; v3 # in this case, the name has to be set separately
v3.display()
v3 == v

The canonical identification \(M^{**} = M\) is implemented by letting the module elements act on linear forms, providing the same result as the reverse operation (cf. the map \(\Phi\) defined above):

sage: a = M.linear_form(name='a')
sage: a[:] = (2, 1, -3) ; a
Linear form a on the Rank-3 free module M over the Integer Ring
sage: v(a)
7
sage: a(v)
7
sage: a(v) == v(a)
True
>>> from sage.all import *
>>> a = M.linear_form(name='a')
>>> a[:] = (Integer(2), Integer(1), -Integer(3)) ; a
Linear form a on the Rank-3 free module M over the Integer Ring
>>> v(a)
7
>>> a(v)
7
>>> a(v) == v(a)
True
a = M.linear_form(name='a')
a[:] = (2, 1, -3) ; a
v(a)
a(v)
a(v) == v(a)

ARITHMETIC EXAMPLES

Addition:

sage: M = FiniteRankFreeModule(ZZ, 3, name='M')
sage: e = M.basis('e') ; e
Basis (e_0,e_1,e_2) on the Rank-3 free module M over the Integer Ring
sage: a = M([0,1,3], name='a') ; a
Element a of the Rank-3 free module M over the Integer Ring
sage: a.display()
a = e_1 + 3 e_2
sage: b = M([2,-2,1], name='b') ; b
Element b of the Rank-3 free module M over the Integer Ring
sage: b.display()
b = 2 e_0 - 2 e_1 + e_2
sage: s = a + b ; s
Element a+b of the Rank-3 free module M over the Integer Ring
sage: s.display()
a+b = 2 e_0 - e_1 + 4 e_2
sage: all(s[i] == a[i] + b[i] for i in M.irange())
True
>>> from sage.all import *
>>> M = FiniteRankFreeModule(ZZ, Integer(3), name='M')
>>> e = M.basis('e') ; e
Basis (e_0,e_1,e_2) on the Rank-3 free module M over the Integer Ring
>>> a = M([Integer(0),Integer(1),Integer(3)], name='a') ; a
Element a of the Rank-3 free module M over the Integer Ring
>>> a.display()
a = e_1 + 3 e_2
>>> b = M([Integer(2),-Integer(2),Integer(1)], name='b') ; b
Element b of the Rank-3 free module M over the Integer Ring
>>> b.display()
b = 2 e_0 - 2 e_1 + e_2
>>> s = a + b ; s
Element a+b of the Rank-3 free module M over the Integer Ring
>>> s.display()
a+b = 2 e_0 - e_1 + 4 e_2
>>> all(s[i] == a[i] + b[i] for i in M.irange())
True
M = FiniteRankFreeModule(ZZ, 3, name='M')
e = M.basis('e') ; e
a = M([0,1,3], name='a') ; a
a.display()
b = M([2,-2,1], name='b') ; b
b.display()
s = a + b ; s
s.display()
all(s[i] == a[i] + b[i] for i in M.irange())

Subtraction:

sage: s = a - b ; s
Element a-b of the Rank-3 free module M over the Integer Ring
sage: s.display()
a-b = -2 e_0 + 3 e_1 + 2 e_2
sage: all(s[i] == a[i] - b[i] for i in M.irange())
True
>>> from sage.all import *
>>> s = a - b ; s
Element a-b of the Rank-3 free module M over the Integer Ring
>>> s.display()
a-b = -2 e_0 + 3 e_1 + 2 e_2
>>> all(s[i] == a[i] - b[i] for i in M.irange())
True
s = a - b ; s
s.display()
all(s[i] == a[i] - b[i] for i in M.irange())

Multiplication by a scalar:

sage: s = 2*a ; s
Element of the Rank-3 free module M over the Integer Ring
sage: s.display()
2 e_1 + 6 e_2
sage: a.display()
a = e_1 + 3 e_2
>>> from sage.all import *
>>> s = Integer(2)*a ; s
Element of the Rank-3 free module M over the Integer Ring
>>> s.display()
2 e_1 + 6 e_2
>>> a.display()
a = e_1 + 3 e_2
s = 2*a ; s
s.display()
a.display()

Tensor product:

sage: s = a*b ; s
Type-(2,0) tensor a⊗b on the Rank-3 free module M over the Integer Ring
sage: s.symmetries()
no symmetry;  no antisymmetry
sage: s[:]
[ 0  0  0]
[ 2 -2  1]
[ 6 -6  3]
sage: s = a*s ; s
Type-(3,0) tensor a⊗a⊗b on the Rank-3 free module M over the Integer Ring
sage: s[:]
[[[0, 0, 0], [0, 0, 0], [0, 0, 0]],
 [[0, 0, 0], [2, -2, 1], [6, -6, 3]],
 [[0, 0, 0], [6, -6, 3], [18, -18, 9]]]
>>> from sage.all import *
>>> s = a*b ; s
Type-(2,0) tensor a⊗b on the Rank-3 free module M over the Integer Ring
>>> s.symmetries()
no symmetry;  no antisymmetry
>>> s[:]
[ 0  0  0]
[ 2 -2  1]
[ 6 -6  3]
>>> s = a*s ; s
Type-(3,0) tensor a⊗a⊗b on the Rank-3 free module M over the Integer Ring
>>> s[:]
[[[0, 0, 0], [0, 0, 0], [0, 0, 0]],
 [[0, 0, 0], [2, -2, 1], [6, -6, 3]],
 [[0, 0, 0], [6, -6, 3], [18, -18, 9]]]
s = a*b ; s
s.symmetries()
s[:]
s = a*s ; s
s[:]

Exterior product:

sage: s = a.wedge(b) ; s
Alternating contravariant tensor a∧b of degree 2 on the Rank-3 free
 module M over the Integer Ring
sage: s.display()
a∧b = -2 e_0∧e_1 - 6 e_0∧e_2 + 7 e_1∧e_2
>>> from sage.all import *
>>> s = a.wedge(b) ; s
Alternating contravariant tensor a∧b of degree 2 on the Rank-3 free
 module M over the Integer Ring
>>> s.display()
a∧b = -2 e_0∧e_1 - 6 e_0∧e_2 + 7 e_1∧e_2
s = a.wedge(b) ; s
s.display()