Free modules of finite rank¶
The class FiniteRankFreeModule implements free modules of finite rank
over a commutative ring.
A free module of finite rank over a commutative ring \(R\) is a module \(M\) over \(R\) that admits a finite basis, i.e. a finite family of linearly independent generators. Since \(R\) is commutative, it has the invariant basis number property, so that the rank of the free module \(M\) is defined uniquely, as the cardinality of any basis of \(M\).
No distinguished basis of \(M\) is assumed. On the contrary, many bases can be introduced on the free module along with change-of-basis rules (as module automorphisms). Each module element has then various representations over the various bases.
Note
The class FiniteRankFreeModule does not inherit from
class FreeModule_generic
nor from class
CombinatorialFreeModule, since
both classes deal with modules with a distinguished basis (see
details below). Accordingly, the class
FiniteRankFreeModule inherits directly from the generic class
Parent with the category set to
Modules (and not to
ModulesWithBasis).
Todo
- implement submodules 
- create a FreeModules category (cf. the TODO statement in the documentation of - Modules: Implement a ``FreeModules(R)`` category, when so prompted by a concrete use case)
AUTHORS:
- Eric Gourgoulhon, Michal Bejger (2014-2015): initial version 
- Travis Scrimshaw (2016): category set to - Modules(ring).FiniteDimensional()(Issue #20770)
- Michael Jung (2019): improve treatment of the zero element 
- Eric Gourgoulhon (2021): unicode symbols for tensor and exterior products 
- Matthias Koeppe (2022): - FiniteRankFreeModule_abstract, symmetric powers
REFERENCES:
EXAMPLES:
Let us define a free module of rank 2 over \(\ZZ\):
sage: M = FiniteRankFreeModule(ZZ, 2, name='M') ; M
Rank-2 free module M over the Integer Ring
sage: M.category()
Category of finite dimensional modules over Integer Ring
>>> from sage.all import *
>>> M = FiniteRankFreeModule(ZZ, Integer(2), name='M') ; M
Rank-2 free module M over the Integer Ring
>>> M.category()
Category of finite dimensional modules over Integer Ring
We introduce a first basis on M:
sage: e = M.basis('e') ; e
Basis (e_0,e_1) on the Rank-2 free module M over the Integer Ring
>>> from sage.all import *
>>> e = M.basis('e') ; e
Basis (e_0,e_1) on the Rank-2 free module M over the Integer Ring
The elements of the basis are of course module elements:
sage: e[0]
Element e_0 of the Rank-2 free module M over the Integer Ring
sage: e[1]
Element e_1 of the Rank-2 free module M over the Integer Ring
sage: e[0].parent()
Rank-2 free module M over the Integer Ring
>>> from sage.all import *
>>> e[Integer(0)]
Element e_0 of the Rank-2 free module M over the Integer Ring
>>> e[Integer(1)]
Element e_1 of the Rank-2 free module M over the Integer Ring
>>> e[Integer(0)].parent()
Rank-2 free module M over the Integer Ring
We define a module element by its components w.r.t. basis e:
sage: u = M([2,-3], basis=e, name='u')
sage: u.display(e)
u = 2 e_0 - 3 e_1
>>> from sage.all import *
>>> u = M([Integer(2),-Integer(3)], basis=e, name='u')
>>> u.display(e)
u = 2 e_0 - 3 e_1
Module elements can be also be created by arithmetic expressions:
sage: v = -2*u + 4*e[0] ; v
Element of the Rank-2 free module M over the Integer Ring
sage: v.display(e)
6 e_1
sage: u == 2*e[0] - 3*e[1]
True
>>> from sage.all import *
>>> v = -Integer(2)*u + Integer(4)*e[Integer(0)] ; v
Element of the Rank-2 free module M over the Integer Ring
>>> v.display(e)
6 e_1
>>> u == Integer(2)*e[Integer(0)] - Integer(3)*e[Integer(1)]
True
We define a second basis on M from a family of linearly independent
elements:
sage: f = M.basis('f', from_family=(e[0]-e[1], -2*e[0]+3*e[1])) ; f
Basis (f_0,f_1) on the Rank-2 free module M over the Integer Ring
sage: f[0].display(e)
f_0 = e_0 - e_1
sage: f[1].display(e)
f_1 = -2 e_0 + 3 e_1
>>> from sage.all import *
>>> f = M.basis('f', from_family=(e[Integer(0)]-e[Integer(1)], -Integer(2)*e[Integer(0)]+Integer(3)*e[Integer(1)])) ; f
Basis (f_0,f_1) on the Rank-2 free module M over the Integer Ring
>>> f[Integer(0)].display(e)
f_0 = e_0 - e_1
>>> f[Integer(1)].display(e)
f_1 = -2 e_0 + 3 e_1
We may of course express the elements of basis e in terms of basis f:
sage: e[0].display(f)
e_0 = 3 f_0 + f_1
sage: e[1].display(f)
e_1 = 2 f_0 + f_1
>>> from sage.all import *
>>> e[Integer(0)].display(f)
e_0 = 3 f_0 + f_1
>>> e[Integer(1)].display(f)
e_1 = 2 f_0 + f_1
as well as any module element:
sage: u.display(f)
u = -f_1
sage: v.display(f)
12 f_0 + 6 f_1
>>> from sage.all import *
>>> u.display(f)
u = -f_1
>>> v.display(f)
12 f_0 + 6 f_1
The two bases are related by a module automorphism:
sage: a = M.change_of_basis(e,f) ; a
Automorphism of the Rank-2 free module M over the Integer Ring
sage: a.parent()
General linear group of the Rank-2 free module M over the Integer Ring
sage: a.matrix(e)
[ 1 -2]
[-1  3]
>>> from sage.all import *
>>> a = M.change_of_basis(e,f) ; a
Automorphism of the Rank-2 free module M over the Integer Ring
>>> a.parent()
General linear group of the Rank-2 free module M over the Integer Ring
>>> a.matrix(e)
[ 1 -2]
[-1  3]
Let us check that basis f is indeed the image of basis e by a:
sage: f[0] == a(e[0])
True
sage: f[1] == a(e[1])
True
>>> from sage.all import *
>>> f[Integer(0)] == a(e[Integer(0)])
True
>>> f[Integer(1)] == a(e[Integer(1)])
True
The reverse change of basis is of course the inverse automorphism:
sage: M.change_of_basis(f,e) == a^(-1)
True
>>> from sage.all import *
>>> M.change_of_basis(f,e) == a**(-Integer(1))
True
We introduce a new module element via its components w.r.t. basis f:
sage: v = M([2,4], basis=f, name='v')
sage: v.display(f)
v = 2 f_0 + 4 f_1
>>> from sage.all import *
>>> v = M([Integer(2),Integer(4)], basis=f, name='v')
>>> v.display(f)
v = 2 f_0 + 4 f_1
The sum of the two module elements u and v can be performed even if
they have been defined on different bases, thanks to the known relation
between the two bases:
sage: s = u + v ; s
Element u+v of the Rank-2 free module M over the Integer Ring
>>> from sage.all import *
>>> s = u + v ; s
Element u+v of the Rank-2 free module M over the Integer Ring
We can display the result in either basis:
sage: s.display(e)
u+v = -4 e_0 + 7 e_1
sage: s.display(f)
u+v = 2 f_0 + 3 f_1
>>> from sage.all import *
>>> s.display(e)
u+v = -4 e_0 + 7 e_1
>>> s.display(f)
u+v = 2 f_0 + 3 f_1
Tensor products of elements are implemented:
sage: t = u*v ; t
Type-(2,0) tensor u⊗v on the Rank-2 free module M over the Integer Ring
sage: t.parent()
Free module of type-(2,0) tensors on the
 Rank-2 free module M over the Integer Ring
sage: t.display(e)
u⊗v = -12 e_0⊗e_0 + 20 e_0⊗e_1 + 18 e_1⊗e_0 - 30 e_1⊗e_1
sage: t.display(f)
u⊗v = -2 f_1⊗f_0 - 4 f_1⊗f_1
>>> from sage.all import *
>>> t = u*v ; t
Type-(2,0) tensor u⊗v on the Rank-2 free module M over the Integer Ring
>>> t.parent()
Free module of type-(2,0) tensors on the
 Rank-2 free module M over the Integer Ring
>>> t.display(e)
u⊗v = -12 e_0⊗e_0 + 20 e_0⊗e_1 + 18 e_1⊗e_0 - 30 e_1⊗e_1
>>> t.display(f)
u⊗v = -2 f_1⊗f_0 - 4 f_1⊗f_1
We can access to tensor components w.r.t. to a given basis via the square bracket operator:
sage: t[e,0,1]
20
sage: t[f,1,0]
-2
sage: u[e,0]
2
sage: u[e,:]
[2, -3]
sage: u[f,:]
[0, -1]
>>> from sage.all import *
>>> t[e,Integer(0),Integer(1)]
20
>>> t[f,Integer(1),Integer(0)]
-2
>>> u[e,Integer(0)]
2
>>> u[e,:]
[2, -3]
>>> u[f,:]
[0, -1]
The parent of the automorphism a is the group \(\mathrm{GL}(M)\), but
a can also be considered as a tensor of type \((1,1)\) on M:
sage: a.parent()
General linear group of the Rank-2 free module M over the Integer Ring
sage: a.tensor_type()
(1, 1)
sage: a.display(e)
e_0⊗e^0 - 2 e_0⊗e^1 - e_1⊗e^0 + 3 e_1⊗e^1
sage: a.display(f)
f_0⊗f^0 - 2 f_0⊗f^1 - f_1⊗f^0 + 3 f_1⊗f^1
>>> from sage.all import *
>>> a.parent()
General linear group of the Rank-2 free module M over the Integer Ring
>>> a.tensor_type()
(1, 1)
>>> a.display(e)
e_0⊗e^0 - 2 e_0⊗e^1 - e_1⊗e^0 + 3 e_1⊗e^1
>>> a.display(f)
f_0⊗f^0 - 2 f_0⊗f^1 - f_1⊗f^0 + 3 f_1⊗f^1
As such, we can form its tensor product with t, yielding a tensor of
type \((3,1)\):
sage: t*a
Type-(3,1) tensor on the Rank-2 free module M over the Integer Ring
sage: (t*a).display(e)
-12 e_0⊗e_0⊗e_0⊗e^0 + 24 e_0⊗e_0⊗e_0⊗e^1 + 12 e_0⊗e_0⊗e_1⊗e^0
 - 36 e_0⊗e_0⊗e_1⊗e^1 + 20 e_0⊗e_1⊗e_0⊗e^0 - 40 e_0⊗e_1⊗e_0⊗e^1
 - 20 e_0⊗e_1⊗e_1⊗e^0 + 60 e_0⊗e_1⊗e_1⊗e^1 + 18 e_1⊗e_0⊗e_0⊗e^0
 - 36 e_1⊗e_0⊗e_0⊗e^1 - 18 e_1⊗e_0⊗e_1⊗e^0 + 54 e_1⊗e_0⊗e_1⊗e^1
 - 30 e_1⊗e_1⊗e_0⊗e^0 + 60 e_1⊗e_1⊗e_0⊗e^1 + 30 e_1⊗e_1⊗e_1⊗e^0
 - 90 e_1⊗e_1⊗e_1⊗e^1
>>> from sage.all import *
>>> t*a
Type-(3,1) tensor on the Rank-2 free module M over the Integer Ring
>>> (t*a).display(e)
-12 e_0⊗e_0⊗e_0⊗e^0 + 24 e_0⊗e_0⊗e_0⊗e^1 + 12 e_0⊗e_0⊗e_1⊗e^0
 - 36 e_0⊗e_0⊗e_1⊗e^1 + 20 e_0⊗e_1⊗e_0⊗e^0 - 40 e_0⊗e_1⊗e_0⊗e^1
 - 20 e_0⊗e_1⊗e_1⊗e^0 + 60 e_0⊗e_1⊗e_1⊗e^1 + 18 e_1⊗e_0⊗e_0⊗e^0
 - 36 e_1⊗e_0⊗e_0⊗e^1 - 18 e_1⊗e_0⊗e_1⊗e^0 + 54 e_1⊗e_0⊗e_1⊗e^1
 - 30 e_1⊗e_1⊗e_0⊗e^0 + 60 e_1⊗e_1⊗e_0⊗e^1 + 30 e_1⊗e_1⊗e_1⊗e^0
 - 90 e_1⊗e_1⊗e_1⊗e^1
The parent of \(t\otimes a\) is itself a free module of finite rank over \(\ZZ\):
sage: T = (t*a).parent() ; T
Free module of type-(3,1) tensors on the Rank-2 free module M over the
 Integer Ring
sage: T.base_ring()
Integer Ring
sage: T.rank()
16
>>> from sage.all import *
>>> T = (t*a).parent() ; T
Free module of type-(3,1) tensors on the Rank-2 free module M over the
 Integer Ring
>>> T.base_ring()
Integer Ring
>>> T.rank()
16
Differences between FiniteRankFreeModule and FreeModule
(or VectorSpace)
To illustrate the differences, let us create two free modules of rank 3 over
\(\ZZ\), one with FiniteRankFreeModule and the other one with
FreeModule:
sage: M = FiniteRankFreeModule(ZZ, 3, name='M') ; M
Rank-3 free module M over the Integer Ring
sage: N = FreeModule(ZZ, 3) ; N
Ambient free module of rank 3 over the principal ideal domain Integer Ring
>>> from sage.all import *
>>> M = FiniteRankFreeModule(ZZ, Integer(3), name='M') ; M
Rank-3 free module M over the Integer Ring
>>> N = FreeModule(ZZ, Integer(3)) ; N
Ambient free module of rank 3 over the principal ideal domain Integer Ring
The main difference is that FreeModule returns a free module with a
distinguished basis, while FiniteRankFreeModule does not:
sage: N.basis()
[(1, 0, 0), (0, 1, 0), (0, 0, 1)]
sage: M.bases()
[]
sage: M.print_bases()
No basis has been defined on the Rank-3 free module M over the Integer Ring
>>> from sage.all import *
>>> N.basis()
[(1, 0, 0), (0, 1, 0), (0, 0, 1)]
>>> M.bases()
[]
>>> M.print_bases()
No basis has been defined on the Rank-3 free module M over the Integer Ring
This is also revealed by the category of each module:
sage: M.category()
Category of finite dimensional modules over Integer Ring
sage: N.category()
Category of finite dimensional modules with basis over
 (Dedekind domains and euclidean domains and noetherian rings
 and infinite enumerated sets and metric spaces)
>>> from sage.all import *
>>> M.category()
Category of finite dimensional modules over Integer Ring
>>> N.category()
Category of finite dimensional modules with basis over
 (Dedekind domains and euclidean domains and noetherian rings
 and infinite enumerated sets and metric spaces)
In other words, the module created by FreeModule is actually \(\ZZ^3\),
while, in the absence of any distinguished basis, no canonical isomorphism
relates the module created by FiniteRankFreeModule to \(\ZZ^3\):
sage: N is ZZ^3
True
sage: M is ZZ^3
False
sage: M == ZZ^3
False
>>> from sage.all import *
>>> N is ZZ**Integer(3)
True
>>> M is ZZ**Integer(3)
False
>>> M == ZZ**Integer(3)
False
Because it is \(\ZZ^3\), N is unique, while there may be various modules
of the same rank over the same ring created by FiniteRankFreeModule;
they are then distinguished by their names (actually by the complete
sequence of arguments of FiniteRankFreeModule):
sage: N1 = FreeModule(ZZ, 3) ; N1
Ambient free module of rank 3 over the principal ideal domain Integer Ring
sage: N1 is N  # FreeModule(ZZ, 3) is unique
True
sage: M1 = FiniteRankFreeModule(ZZ, 3, name='M_1') ; M1
Rank-3 free module M_1 over the Integer Ring
sage: M1 is M  # M1 and M are different rank-3 modules over ZZ
False
sage: M1b = FiniteRankFreeModule(ZZ, 3, name='M_1') ; M1b
Rank-3 free module M_1 over the Integer Ring
sage: M1b is M1  # because M1b and M1 have the same name
True
>>> from sage.all import *
>>> N1 = FreeModule(ZZ, Integer(3)) ; N1
Ambient free module of rank 3 over the principal ideal domain Integer Ring
>>> N1 is N  # FreeModule(ZZ, 3) is unique
True
>>> M1 = FiniteRankFreeModule(ZZ, Integer(3), name='M_1') ; M1
Rank-3 free module M_1 over the Integer Ring
>>> M1 is M  # M1 and M are different rank-3 modules over ZZ
False
>>> M1b = FiniteRankFreeModule(ZZ, Integer(3), name='M_1') ; M1b
Rank-3 free module M_1 over the Integer Ring
>>> M1b is M1  # because M1b and M1 have the same name
True
As illustrated above, various bases can be introduced on the module created by
FiniteRankFreeModule:
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: f = M.basis('f', from_family=(-e[0], e[1]-e[2], -2*e[1]+3*e[2])) ; f
Basis (f_0,f_1,f_2) on the Rank-3 free module M over the Integer Ring
sage: M.bases()
[Basis (e_0,e_1,e_2) on the Rank-3 free module M over the Integer Ring,
 Basis (f_0,f_1,f_2) on the Rank-3 free module M over the Integer Ring]
>>> from sage.all import *
>>> e = M.basis('e') ; e
Basis (e_0,e_1,e_2) on the Rank-3 free module M over the Integer Ring
>>> f = M.basis('f', from_family=(-e[Integer(0)], e[Integer(1)]-e[Integer(2)], -Integer(2)*e[Integer(1)]+Integer(3)*e[Integer(2)])) ; f
Basis (f_0,f_1,f_2) on the Rank-3 free module M over the Integer Ring
>>> M.bases()
[Basis (e_0,e_1,e_2) on the Rank-3 free module M over the Integer Ring,
 Basis (f_0,f_1,f_2) on the Rank-3 free module M over the Integer Ring]
Each element of a basis is accessible via its index:
sage: e[0]
Element e_0 of the Rank-3 free module M over the Integer Ring
sage: e[0].parent()
Rank-3 free module M over the Integer Ring
sage: f[1]
Element f_1 of the Rank-3 free module M over the Integer Ring
sage: f[1].parent()
Rank-3 free module M over the Integer Ring
>>> from sage.all import *
>>> e[Integer(0)]
Element e_0 of the Rank-3 free module M over the Integer Ring
>>> e[Integer(0)].parent()
Rank-3 free module M over the Integer Ring
>>> f[Integer(1)]
Element f_1 of the Rank-3 free module M over the Integer Ring
>>> f[Integer(1)].parent()
Rank-3 free module M over the Integer Ring
while on module N, the element of the (unique) basis is accessible
directly from the module symbol:
sage: N.0
(1, 0, 0)
sage: N.1
(0, 1, 0)
sage: N.0.parent()
Ambient free module of rank 3 over the principal ideal domain Integer Ring
>>> from sage.all import *
>>> N.gen(0)
(1, 0, 0)
>>> N.gen(1)
(0, 1, 0)
>>> N.gen(0).parent()
Ambient free module of rank 3 over the principal ideal domain Integer Ring
The arithmetic of elements is similar; the difference lies in the display:
a basis has to be specified for elements of M, while elements of N are
displayed directly as elements of \(\ZZ^3\):
sage: u = 2*e[0] - 3*e[2] ; u
Element of the Rank-3 free module M over the Integer Ring
sage: u.display(e)
2 e_0 - 3 e_2
sage: u.display(f)
-2 f_0 - 6 f_1 - 3 f_2
sage: u[e,:]
[2, 0, -3]
sage: u[f,:]
[-2, -6, -3]
sage: v = 2*N.0 - 3*N.2 ; v
(2, 0, -3)
>>> from sage.all import *
>>> u = Integer(2)*e[Integer(0)] - Integer(3)*e[Integer(2)] ; u
Element of the Rank-3 free module M over the Integer Ring
>>> u.display(e)
2 e_0 - 3 e_2
>>> u.display(f)
-2 f_0 - 6 f_1 - 3 f_2
>>> u[e,:]
[2, 0, -3]
>>> u[f,:]
[-2, -6, -3]
>>> v = Integer(2)*N.gen(0) - Integer(3)*N.gen(2) ; v
(2, 0, -3)
For the case of M, in order to avoid to specify the basis if the user is
always working with the same basis (e.g. only one basis has been defined),
the concept of default basis has been introduced:
sage: M.default_basis()
Basis (e_0,e_1,e_2) on the Rank-3 free module M over the Integer Ring
sage: M.print_bases()
Bases defined on the Rank-3 free module M over the Integer Ring:
 - (e_0,e_1,e_2) (default basis)
 - (f_0,f_1,f_2)
>>> from sage.all import *
>>> M.default_basis()
Basis (e_0,e_1,e_2) on the Rank-3 free module M over the Integer Ring
>>> M.print_bases()
Bases defined on the Rank-3 free module M over the Integer Ring:
 - (e_0,e_1,e_2) (default basis)
 - (f_0,f_1,f_2)
This is different from the distinguished basis of N: it simply means that
the mention of the basis can be omitted in function arguments:
sage: u.display()  # equivalent to u.display(e)
2 e_0 - 3 e_2
sage: u[:]         # equivalent to u[e,:]
[2, 0, -3]
>>> from sage.all import *
>>> u.display()  # equivalent to u.display(e)
2 e_0 - 3 e_2
>>> u[:]         # equivalent to u[e,:]
[2, 0, -3]
At any time, the default basis can be changed:
sage: M.set_default_basis(f)
sage: u.display()
-2 f_0 - 6 f_1 - 3 f_2
>>> from sage.all import *
>>> M.set_default_basis(f)
>>> u.display()
-2 f_0 - 6 f_1 - 3 f_2
Another difference between FiniteRankFreeModule and FreeModule is that
for the former the range of indices can be specified (by default, it starts
from 0):
sage: M = FiniteRankFreeModule(ZZ, 3, name='M', start_index=1) ; M
Rank-3 free module M over the Integer Ring
sage: e = M.basis('e') ; e  # compare with (e_0,e_1,e_2) above
Basis (e_1,e_2,e_3) on the Rank-3 free module M over the Integer Ring
sage: e[1], e[2], e[3]
(Element e_1 of the Rank-3 free module M over the Integer Ring,
 Element e_2 of the Rank-3 free module M over the Integer Ring,
 Element e_3 of the Rank-3 free module M over the Integer Ring)
>>> from sage.all import *
>>> M = FiniteRankFreeModule(ZZ, Integer(3), name='M', start_index=Integer(1)) ; M
Rank-3 free module M over the Integer Ring
>>> e = M.basis('e') ; e  # compare with (e_0,e_1,e_2) above
Basis (e_1,e_2,e_3) on the Rank-3 free module M over the Integer Ring
>>> e[Integer(1)], e[Integer(2)], e[Integer(3)]
(Element e_1 of the Rank-3 free module M over the Integer Ring,
 Element e_2 of the Rank-3 free module M over the Integer Ring,
 Element e_3 of the Rank-3 free module M over the Integer Ring)
All the above holds for VectorSpace instead of FreeModule: the object
created by VectorSpace is actually a Cartesian power of the base field:
sage: V = VectorSpace(QQ,3) ; V
Vector space of dimension 3 over Rational Field
sage: V.category()
Category of finite dimensional vector spaces with basis
 over (number fields and quotient fields and metric spaces)
sage: V is QQ^3
True
sage: V.basis()
[(1, 0, 0), (0, 1, 0), (0, 0, 1)]
>>> from sage.all import *
>>> V = VectorSpace(QQ,Integer(3)) ; V
Vector space of dimension 3 over Rational Field
>>> V.category()
Category of finite dimensional vector spaces with basis
 over (number fields and quotient fields and metric spaces)
>>> V is QQ**Integer(3)
True
>>> V.basis()
[(1, 0, 0), (0, 1, 0), (0, 0, 1)]
To create a vector space without any distinguished basis, one has to use
FiniteRankFreeModule:
sage: V = FiniteRankFreeModule(QQ, 3, name='V') ; V
3-dimensional vector space V over the Rational Field
sage: V.category()
Category of finite dimensional vector spaces over Rational Field
sage: V.bases()
[]
sage: V.print_bases()
No basis has been defined on the 3-dimensional vector space V over the
 Rational Field
>>> from sage.all import *
>>> V = FiniteRankFreeModule(QQ, Integer(3), name='V') ; V
3-dimensional vector space V over the Rational Field
>>> V.category()
Category of finite dimensional vector spaces over Rational Field
>>> V.bases()
[]
>>> V.print_bases()
No basis has been defined on the 3-dimensional vector space V over the
 Rational Field
The class FiniteRankFreeModule has been created for the needs
of the SageManifolds project, where
free modules do not have any distinguished basis. Too kinds of free modules
occur in the context of differentiable manifolds (see
here for more
details):
- the tangent vector space at any point of the manifold (cf. - TangentSpace);
- the set of vector fields on a parallelizable open subset \(U\) of the manifold, which is a free module over the algebra of scalar fields on \(U\) (cf. - VectorFieldFreeModule).
For instance, without any specific coordinate choice, no basis can be distinguished in a tangent space.
On the other side, the modules created by FreeModule have much more
algebraic functionalities than those created by FiniteRankFreeModule. In
particular, submodules have not been implemented yet in
FiniteRankFreeModule. Moreover, modules resulting from FreeModule
are tailored to the specific kind of their base ring:
- free module over a commutative ring that is not an integral domain (\(\ZZ/6\ZZ\)): - sage: R = IntegerModRing(6) ; R Ring of integers modulo 6 sage: FreeModule(R, 3) Ambient free module of rank 3 over Ring of integers modulo 6 sage: type(FreeModule(R, 3)) <class 'sage.modules.free_module.FreeModule_ambient_with_category'> - >>> from sage.all import * >>> R = IntegerModRing(Integer(6)) ; R Ring of integers modulo 6 >>> FreeModule(R, Integer(3)) Ambient free module of rank 3 over Ring of integers modulo 6 >>> type(FreeModule(R, Integer(3))) <class 'sage.modules.free_module.FreeModule_ambient_with_category'> 
- free module over an integral domain that is not principal (\(\ZZ[X]\)): - sage: R.<X> = ZZ[] ; R Univariate Polynomial Ring in X over Integer Ring sage: FreeModule(R, 3) Ambient free module of rank 3 over the integral domain Univariate Polynomial Ring in X over Integer Ring sage: type(FreeModule(R, 3)) <class 'sage.modules.free_module.FreeModule_ambient_domain_with_category'> - >>> from sage.all import * >>> R = ZZ['X']; (X,) = R._first_ngens(1); R Univariate Polynomial Ring in X over Integer Ring >>> FreeModule(R, Integer(3)) Ambient free module of rank 3 over the integral domain Univariate Polynomial Ring in X over Integer Ring >>> type(FreeModule(R, Integer(3))) <class 'sage.modules.free_module.FreeModule_ambient_domain_with_category'> 
- free module over a principal ideal domain (\(\ZZ\)): - sage: R = ZZ ; R Integer Ring sage: FreeModule(R,3) Ambient free module of rank 3 over the principal ideal domain Integer Ring sage: type(FreeModule(R, 3)) <class 'sage.modules.free_module.FreeModule_ambient_pid_with_category'> - >>> from sage.all import * >>> R = ZZ ; R Integer Ring >>> FreeModule(R,Integer(3)) Ambient free module of rank 3 over the principal ideal domain Integer Ring >>> type(FreeModule(R, Integer(3))) <class 'sage.modules.free_module.FreeModule_ambient_pid_with_category'> 
On the contrary, all objects constructed with FiniteRankFreeModule belong
to the same class:
sage: R = IntegerModRing(6)
sage: type(FiniteRankFreeModule(R, 3))
<class 'sage.tensor.modules.finite_rank_free_module.FiniteRankFreeModule_with_category'>
sage: R.<X> = ZZ[]
sage: type(FiniteRankFreeModule(R, 3))
<class 'sage.tensor.modules.finite_rank_free_module.FiniteRankFreeModule_with_category'>
sage: R = ZZ
sage: type(FiniteRankFreeModule(R, 3))
<class 'sage.tensor.modules.finite_rank_free_module.FiniteRankFreeModule_with_category'>
>>> from sage.all import *
>>> R = IntegerModRing(Integer(6))
>>> type(FiniteRankFreeModule(R, Integer(3)))
<class 'sage.tensor.modules.finite_rank_free_module.FiniteRankFreeModule_with_category'>
>>> R = ZZ['X']; (X,) = R._first_ngens(1)
>>> type(FiniteRankFreeModule(R, Integer(3)))
<class 'sage.tensor.modules.finite_rank_free_module.FiniteRankFreeModule_with_category'>
>>> R = ZZ
>>> type(FiniteRankFreeModule(R, Integer(3)))
<class 'sage.tensor.modules.finite_rank_free_module.FiniteRankFreeModule_with_category'>
Differences between FiniteRankFreeModule and
CombinatorialFreeModule
An alternative to construct free modules in Sage is
CombinatorialFreeModule.
However, as FreeModule, it leads to a module with a distinguished basis:
sage: N = CombinatorialFreeModule(ZZ, [1,2,3]) ; N
Free module generated by {1, 2, 3} over Integer Ring
sage: N.category()
Category of finite dimensional modules with basis over Integer Ring
>>> from sage.all import *
>>> N = CombinatorialFreeModule(ZZ, [Integer(1),Integer(2),Integer(3)]) ; N
Free module generated by {1, 2, 3} over Integer Ring
>>> N.category()
Category of finite dimensional modules with basis over Integer Ring
The distinguished basis is returned by the method basis():
sage: b = N.basis() ; b
Finite family {1: B[1], 2: B[2], 3: B[3]}
sage: b[1]
B[1]
sage: b[1].parent()
Free module generated by {1, 2, 3} over Integer Ring
>>> from sage.all import *
>>> b = N.basis() ; b
Finite family {1: B[1], 2: B[2], 3: B[3]}
>>> b[Integer(1)]
B[1]
>>> b[Integer(1)].parent()
Free module generated by {1, 2, 3} over Integer Ring
For the free module M created above with FiniteRankFreeModule, the
method basis has at least one argument: the symbol string that
specifies which basis is required:
sage: e = M.basis('e') ; e
Basis (e_1,e_2,e_3) on the Rank-3 free module M over the Integer Ring
sage: e[1]
Element e_1 of the Rank-3 free module M over the Integer Ring
sage: e[1].parent()
Rank-3 free module M over the Integer Ring
>>> from sage.all import *
>>> e = M.basis('e') ; e
Basis (e_1,e_2,e_3) on the Rank-3 free module M over the Integer Ring
>>> e[Integer(1)]
Element e_1 of the Rank-3 free module M over the Integer Ring
>>> e[Integer(1)].parent()
Rank-3 free module M over the Integer Ring
The arithmetic of elements is similar:
sage: u = 2*e[1] - 5*e[3] ; u
Element of the Rank-3 free module M over the Integer Ring
sage: v = 2*b[1] - 5*b[3] ; v
2*B[1] - 5*B[3]
>>> from sage.all import *
>>> u = Integer(2)*e[Integer(1)] - Integer(5)*e[Integer(3)] ; u
Element of the Rank-3 free module M over the Integer Ring
>>> v = Integer(2)*b[Integer(1)] - Integer(5)*b[Integer(3)] ; v
2*B[1] - 5*B[3]
One notices that elements of N are displayed directly in terms of their
expansions on the distinguished basis. For elements of M, one has to use
the method
display()
in order to specify the basis:
sage: u.display(e)
2 e_1 - 5 e_3
>>> from sage.all import *
>>> u.display(e)
2 e_1 - 5 e_3
The components on the basis are returned by the square bracket operator for
M and by the method coefficient for N:
sage: [u[e,i] for i in {1,2,3}]
[2, 0, -5]
sage: u[e,:]  # a shortcut for the above
[2, 0, -5]
sage: [v.coefficient(i) for i in {1,2,3}]
[2, 0, -5]
>>> from sage.all import *
>>> [u[e,i] for i in {Integer(1),Integer(2),Integer(3)}]
[2, 0, -5]
>>> u[e,:]  # a shortcut for the above
[2, 0, -5]
>>> [v.coefficient(i) for i in {Integer(1),Integer(2),Integer(3)}]
[2, 0, -5]
- class sage.tensor.modules.finite_rank_free_module.FiniteRankDualFreeModule(fmodule, name=None, latex_name=None)[source]¶
- Bases: - ReflexiveModule_dual,- FiniteRankFreeModule_abstract- Dual of a free module of finite rank over a commutative ring. - Given a free module \(M\) of finite rank over a commutative ring \(R\), the dual of \(M\) is the set \(M^*\) of all linear forms on \(M\), i.e., linear maps \[M \longrightarrow R\]- This is a Sage parent class, whose element class is - FreeModuleAltForm.- INPUT: - fmodule– free module \(M\) of finite rank, as an instance of- FiniteRankFreeModule
- name– (default:- None) string; name given to \(M^*\)
- latex_name– (default:- None) string; LaTeX symbol to denote \(M^*\)
 - EXAMPLES: - sage: M = FiniteRankFreeModule(ZZ, 3, name='M') sage: e = M.basis('e') sage: A = M.dual(); A Dual of 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') >>> A = M.dual(); A Dual of the Rank-3 free module M over the Integer Ring - Ais a module (actually a free module) over \(\ZZ\):- sage: A.category() Category of finite dimensional modules over Integer Ring sage: A in Modules(ZZ) True sage: A.rank() 3 sage: A.base_ring() Integer Ring sage: A.base_module() Rank-3 free module M over the Integer Ring - >>> from sage.all import * >>> A.category() Category of finite dimensional modules over Integer Ring >>> A in Modules(ZZ) True >>> A.rank() 3 >>> A.base_ring() Integer Ring >>> A.base_module() Rank-3 free module M over the Integer Ring - Ais a parent object, whose elements are linear forms, represented by instances of the class- FreeModuleAltForm:- sage: a = A.an_element() ; a Linear form on the Rank-3 free module M over the Integer Ring sage: a.display() # expansion with respect to M's default basis (e) e^0 sage: from sage.tensor.modules.free_module_alt_form import FreeModuleAltForm sage: isinstance(a, FreeModuleAltForm) True sage: a in A True sage: A.is_parent_of(a) True - >>> from sage.all import * >>> a = A.an_element() ; a Linear form on the Rank-3 free module M over the Integer Ring >>> a.display() # expansion with respect to M's default basis (e) e^0 >>> from sage.tensor.modules.free_module_alt_form import FreeModuleAltForm >>> isinstance(a, FreeModuleAltForm) True >>> a in A True >>> A.is_parent_of(a) True - Elements can be constructed from - A. In particular, 0 yields the zero element of- A:- sage: A(0) Linear form zero on the Rank-3 free module M over the Integer Ring sage: A(0) is A.zero() True - >>> from sage.all import * >>> A(Integer(0)) Linear form zero on the Rank-3 free module M over the Integer Ring >>> A(Integer(0)) is A.zero() True - while nonzero 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 = [0,3,-1] sage: a = A(comp, basis=e, name='a') ; a Linear form a on the Rank-3 free module M over the Integer Ring sage: a.display(e) a = 3 e^1 - 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 = [Integer(0),Integer(3),-Integer(1)] >>> a = A(comp, basis=e, name='a') ; a Linear form a on the Rank-3 free module M over the Integer Ring >>> a.display(e) a = 3 e^1 - e^2 - An alternative is to construct the alternating form from an empty list of components and to set the nonzero components afterwards: - sage: a = A([], name='a') sage: a.set_comp(e)[0] = 3 sage: a.set_comp(e)[1] = -1 sage: a.set_comp(e)[2] = 4 sage: a.display(e) a = 3 e^0 - e^1 + 4 e^2 - >>> from sage.all import * >>> a = A([], name='a') >>> a.set_comp(e)[Integer(0)] = Integer(3) >>> a.set_comp(e)[Integer(1)] = -Integer(1) >>> a.set_comp(e)[Integer(2)] = Integer(4) >>> a.display(e) a = 3 e^0 - e^1 + 4 e^2 - The dual is unique: - sage: A is M.dual() True - >>> from sage.all import * >>> A is M.dual() True - The exterior power \(\Lambda^1(M^*)\) is nothing but \(M^*\): - sage: M.dual_exterior_power(1) is M.dual() True - >>> from sage.all import * >>> M.dual_exterior_power(Integer(1)) is M.dual() True - It also coincides with the module of type-\((0,1)\) tensors: - sage: M.dual_exterior_power(1) is M.tensor_module(0,1) True - >>> from sage.all import * >>> M.dual_exterior_power(Integer(1)) is M.tensor_module(Integer(0),Integer(1)) True - Element[source]¶
- alias of - FreeModuleAltForm
 - base_module()[source]¶
- Return the free module on which - selfis constructed.- OUTPUT: - instance of - FiniteRankFreeModulerepresenting the free module on which the dual is defined.
 - EXAMPLES: - sage: M = FiniteRankFreeModule(ZZ, 5, name='M') sage: A = M.dual() sage: A.base_module() Rank-5 free module M over the Integer Ring sage: A.base_module() is M True - >>> from sage.all import * >>> M = FiniteRankFreeModule(ZZ, Integer(5), name='M') >>> A = M.dual() >>> A.base_module() Rank-5 free module M over the Integer Ring >>> A.base_module() is M True 
 - zero()[source]¶
- Return the zero of - self.- EXAMPLES: - sage: M = FiniteRankFreeModule(ZZ, 3, name='M') sage: e = M.basis('e') sage: A = M.dual() sage: A.zero() Linear form zero on the Rank-3 free module M over the Integer Ring sage: A(0) is A.zero() True - >>> from sage.all import * >>> M = FiniteRankFreeModule(ZZ, Integer(3), name='M') >>> e = M.basis('e') >>> A = M.dual() >>> A.zero() Linear form zero on the Rank-3 free module M over the Integer Ring >>> A(Integer(0)) is A.zero() True 
 
- class sage.tensor.modules.finite_rank_free_module.FiniteRankFreeModule(ring, rank, name=None, latex_name=None, start_index: int = 0, output_formatter=None, category=None, ambient=None)[source]¶
- Bases: - ReflexiveModule_base,- FiniteRankFreeModule_abstract- Free module of finite rank over a commutative ring. - A free module of finite rank over a commutative ring \(R\) is a module \(M\) over \(R\) that admits a finite basis, i.e. a finite family of linearly independent generators. Since \(R\) is commutative, it has the invariant basis number property, so that the rank of the free module \(M\) is defined uniquely, as the cardinality of any basis of \(M\). - No distinguished basis of \(M\) is assumed. On the contrary, many bases can be introduced on the free module along with change-of-basis rules (as module automorphisms). Each module element has then various representations over the various bases. - Note - The class - FiniteRankFreeModuledoes not inherit from class- FreeModule_genericnor from class- CombinatorialFreeModule, since both classes deal with modules with a distinguished basis (see details above). Moreover, following the recommendation exposed in Issue #16427 the class- FiniteRankFreeModuleinherits directly from- Parent(with the category set to- Modules) and not from the Cython class- Module.- The class - FiniteRankFreeModuleis a Sage parent class, the corresponding element class being- FiniteRankFreeModuleElement.- INPUT: - ring– commutative ring \(R\) over which the free module is constructed
- rank– positive integer; rank of the free module
- name– (default:- None) string; name given to the free module
- latex_name– (default:- None) string; LaTeX symbol to denote the freemodule; if none is provided, it is set to- name
- start_index– (default: 0) integer; lower bound of the range of indices in bases defined on the free module
- output_formatter– (default:- None) function or unbound method called to format the output of the tensor components;- output_formattermust take 1 or 2 arguments: the first argument must be an element of the ring \(R\) and the second one, if any, some format specification
 - EXAMPLES: - Free module of rank 3 over \(\ZZ\): - sage: FiniteRankFreeModule._clear_cache_() # for doctests only sage: M = FiniteRankFreeModule(ZZ, 3) ; M Rank-3 free module over the Integer Ring sage: M = FiniteRankFreeModule(ZZ, 3, name='M') ; M # declaration with a name Rank-3 free module M over the Integer Ring sage: M.category() Category of finite dimensional modules over Integer Ring sage: M.base_ring() Integer Ring sage: M.rank() 3 - >>> from sage.all import * >>> FiniteRankFreeModule._clear_cache_() # for doctests only >>> M = FiniteRankFreeModule(ZZ, Integer(3)) ; M Rank-3 free module over the Integer Ring >>> M = FiniteRankFreeModule(ZZ, Integer(3), name='M') ; M # declaration with a name Rank-3 free module M over the Integer Ring >>> M.category() Category of finite dimensional modules over Integer Ring >>> M.base_ring() Integer Ring >>> M.rank() 3 - If the base ring is a field, the free module is in the category of vector spaces: - sage: V = FiniteRankFreeModule(QQ, 3, name='V') ; V 3-dimensional vector space V over the Rational Field sage: V.category() Category of finite dimensional vector spaces over Rational Field - >>> from sage.all import * >>> V = FiniteRankFreeModule(QQ, Integer(3), name='V') ; V 3-dimensional vector space V over the Rational Field >>> V.category() Category of finite dimensional vector spaces over Rational Field - The LaTeX output is adjusted via the parameter - latex_name:- sage: latex(M) # the default is the symbol provided in the string ``name`` M sage: M = FiniteRankFreeModule(ZZ, 3, name='M', latex_name=r'\mathcal{M}') sage: latex(M) \mathcal{M} - >>> from sage.all import * >>> latex(M) # the default is the symbol provided in the string ``name`` M >>> M = FiniteRankFreeModule(ZZ, Integer(3), name='M', latex_name=r'\mathcal{M}') >>> latex(M) \mathcal{M} - The free module M has no distinguished basis: - sage: M in ModulesWithBasis(ZZ) False sage: M in Modules(ZZ) True - >>> from sage.all import * >>> M in ModulesWithBasis(ZZ) False >>> M in Modules(ZZ) True - In particular, no basis is initialized at the module construction: - sage: M.print_bases() No basis has been defined on the Rank-3 free module M over the Integer Ring sage: M.bases() [] - >>> from sage.all import * >>> M.print_bases() No basis has been defined on the Rank-3 free module M over the Integer Ring >>> M.bases() [] - Bases have to be introduced by means of the method - basis(), the first defined basis being considered as the default basis, meaning it can be skipped in function arguments required a basis (this can be changed by means of the method- set_default_basis()):- 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: M.default_basis() Basis (e_0,e_1,e_2) on the Rank-3 free module M over the Integer Ring - >>> from sage.all import * >>> e = M.basis('e') ; e Basis (e_0,e_1,e_2) on the Rank-3 free module M over the Integer Ring >>> M.default_basis() Basis (e_0,e_1,e_2) on the Rank-3 free module M over the Integer Ring - A second basis can be created from a family of linearly independent elements expressed in terms of basis - e:- sage: f = M.basis('f', from_family=(-e[0], e[1]+e[2], 2*e[1]+3*e[2])) sage: f Basis (f_0,f_1,f_2) on the Rank-3 free module M over the Integer Ring sage: M.print_bases() Bases defined on the Rank-3 free module M over the Integer Ring: - (e_0,e_1,e_2) (default basis) - (f_0,f_1,f_2) sage: M.bases() [Basis (e_0,e_1,e_2) on the Rank-3 free module M over the Integer Ring, Basis (f_0,f_1,f_2) on the Rank-3 free module M over the Integer Ring] - >>> from sage.all import * >>> f = M.basis('f', from_family=(-e[Integer(0)], e[Integer(1)]+e[Integer(2)], Integer(2)*e[Integer(1)]+Integer(3)*e[Integer(2)])) >>> f Basis (f_0,f_1,f_2) on the Rank-3 free module M over the Integer Ring >>> M.print_bases() Bases defined on the Rank-3 free module M over the Integer Ring: - (e_0,e_1,e_2) (default basis) - (f_0,f_1,f_2) >>> M.bases() [Basis (e_0,e_1,e_2) on the Rank-3 free module M over the Integer Ring, Basis (f_0,f_1,f_2) on the Rank-3 free module M over the Integer Ring] - M is a parent object, whose elements are instances of - FiniteRankFreeModuleElement(actually a dynamically generated subclass of it):- sage: v = M.an_element() ; v Element of the Rank-3 free module M over the Integer Ring sage: from sage.tensor.modules.free_module_element import FiniteRankFreeModuleElement sage: isinstance(v, FiniteRankFreeModuleElement) True sage: v in M True sage: M.is_parent_of(v) True sage: v.display() # expansion w.r.t. the default basis (e) e_0 + e_1 + e_2 sage: v.display(f) -f_0 + f_1 - >>> from sage.all import * >>> v = M.an_element() ; v Element of the Rank-3 free module M over the Integer Ring >>> from sage.tensor.modules.free_module_element import FiniteRankFreeModuleElement >>> isinstance(v, FiniteRankFreeModuleElement) True >>> v in M True >>> M.is_parent_of(v) True >>> v.display() # expansion w.r.t. the default basis (e) e_0 + e_1 + e_2 >>> v.display(f) -f_0 + f_1 - The test suite of the category of modules is passed: - sage: TestSuite(M).run() - >>> from sage.all import * >>> TestSuite(M).run() - Constructing an element of - Mfrom (the integer) 0 yields the zero element of- M:- sage: M(0) Element zero of the Rank-3 free module M over the Integer Ring sage: M(0) is M.zero() True - >>> from sage.all import * >>> M(Integer(0)) Element zero of the Rank-3 free module M over the Integer Ring >>> M(Integer(0)) is M.zero() True - Non-zero elements are constructed by providing their components in a given basis: - sage: v = M([-1,0,3]) ; v # components in the default basis (e) Element of the Rank-3 free module M over the Integer Ring sage: v.display() # expansion w.r.t. the default basis (e) -e_0 + 3 e_2 sage: v.display(f) f_0 - 6 f_1 + 3 f_2 sage: v = M([-1,0,3], basis=f) ; v # components in a specific basis Element of the Rank-3 free module M over the Integer Ring sage: v.display(f) -f_0 + 3 f_2 sage: v.display() e_0 + 6 e_1 + 9 e_2 sage: v = M([-1,0,3], basis=f, name='v') ; v Element v of the Rank-3 free module M over the Integer Ring sage: v.display(f) v = -f_0 + 3 f_2 sage: v.display() v = e_0 + 6 e_1 + 9 e_2 - >>> from sage.all import * >>> v = M([-Integer(1),Integer(0),Integer(3)]) ; v # components in the default basis (e) Element of the Rank-3 free module M over the Integer Ring >>> v.display() # expansion w.r.t. the default basis (e) -e_0 + 3 e_2 >>> v.display(f) f_0 - 6 f_1 + 3 f_2 >>> v = M([-Integer(1),Integer(0),Integer(3)], basis=f) ; v # components in a specific basis Element of the Rank-3 free module M over the Integer Ring >>> v.display(f) -f_0 + 3 f_2 >>> v.display() e_0 + 6 e_1 + 9 e_2 >>> v = M([-Integer(1),Integer(0),Integer(3)], basis=f, name='v') ; v Element v of the Rank-3 free module M over the Integer Ring >>> v.display(f) v = -f_0 + 3 f_2 >>> v.display() v = e_0 + 6 e_1 + 9 e_2 - An alternative is to construct the element from an empty list of componentsand to set the nonzero components afterwards: - sage: v = M([], name='v') sage: v[e,0] = -1 sage: v[e,2] = 3 sage: v.display(e) v = -e_0 + 3 e_2 - >>> from sage.all import * >>> v = M([], name='v') >>> v[e,Integer(0)] = -Integer(1) >>> v[e,Integer(2)] = Integer(3) >>> v.display(e) v = -e_0 + 3 e_2 - Indices on the free module, such as indices labelling the element of a basis, are provided by the generator method - irange(). By default, they range from 0 to the module’s rank minus one:- sage: list(M.irange()) [0, 1, 2] - >>> from sage.all import * >>> list(M.irange()) [0, 1, 2] - This can be changed via the parameter - start_indexin the module construction:- sage: M1 = FiniteRankFreeModule(ZZ, 3, name='M', start_index=1) sage: list(M1.irange()) [1, 2, 3] - >>> from sage.all import * >>> M1 = FiniteRankFreeModule(ZZ, Integer(3), name='M', start_index=Integer(1)) >>> list(M1.irange()) [1, 2, 3] - The parameter - output_formatterin the constructor of the free module is used to set the output format of tensor components:- sage: N = FiniteRankFreeModule(QQ, 3, output_formatter=Rational.numerical_approx) sage: e = N.basis('e') sage: v = N([1/3, 0, -2], basis=e) sage: v[e,:] [0.333333333333333, 0.000000000000000, -2.00000000000000] sage: v.display(e) # default format (53 bits of precision) 0.333333333333333 e_0 - 2.00000000000000 e_2 sage: v.display(e, format_spec=10) # 10 bits of precision 0.33 e_0 - 2.0 e_2 - >>> from sage.all import * >>> N = FiniteRankFreeModule(QQ, Integer(3), output_formatter=Rational.numerical_approx) >>> e = N.basis('e') >>> v = N([Integer(1)/Integer(3), Integer(0), -Integer(2)], basis=e) >>> v[e,:] [0.333333333333333, 0.000000000000000, -2.00000000000000] >>> v.display(e) # default format (53 bits of precision) 0.333333333333333 e_0 - 2.00000000000000 e_2 >>> v.display(e, format_spec=Integer(10)) # 10 bits of precision 0.33 e_0 - 2.0 e_2 - Element[source]¶
- alias of - FiniteRankFreeModuleElement
 - alternating_contravariant_tensor(degree, name=None, latex_name=None)[source]¶
- Construct an alternating contravariant tensor on the free module. - INPUT: - degree– degree of the alternating contravariant tensor (i.e. its tensor rank)
- name– (default:- None) string; name given to the alternating contravariant tensor
- latex_name– (default:- None) string; LaTeX symbol to denote the alternating contravariant tensor; if none is provided, the LaTeX symbol is set to- name
 - OUTPUT: - instance of - AlternatingContrTensor
 - EXAMPLES: - Alternating contravariant tensor on a rank-3 module: - sage: M = FiniteRankFreeModule(ZZ, 3, name='M') sage: a = M.alternating_contravariant_tensor(2, 'a') ; a Alternating contravariant tensor a of degree 2 on the Rank-3 free module M over the Integer Ring - >>> from sage.all import * >>> M = FiniteRankFreeModule(ZZ, Integer(3), name='M') >>> a = M.alternating_contravariant_tensor(Integer(2), 'a') ; a Alternating contravariant tensor a of degree 2 on the Rank-3 free module M over the Integer Ring - The nonzero components in a given basis have to be set in a second step, thereby fully specifying the alternating form: - 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.set_comp(e)[0,1] = 2 sage: a.set_comp(e)[1,2] = -3 sage: a.display(e) a = 2 e_0∧e_1 - 3 e_1∧e_2 - >>> from sage.all import * >>> e = M.basis('e') ; e Basis (e_0,e_1,e_2) on the Rank-3 free module M over the Integer Ring >>> a.set_comp(e)[Integer(0),Integer(1)] = Integer(2) >>> a.set_comp(e)[Integer(1),Integer(2)] = -Integer(3) >>> a.display(e) a = 2 e_0∧e_1 - 3 e_1∧e_2 - An alternating contravariant tensor of degree 1 is simply an element of the module: - sage: a = M.alternating_contravariant_tensor(1, 'a') ; a Element a of the Rank-3 free module M over the Integer Ring - >>> from sage.all import * >>> a = M.alternating_contravariant_tensor(Integer(1), 'a') ; a Element a of the Rank-3 free module M over the Integer Ring - See - AlternatingContrTensorfor more documentation.
 - alternating_form(degree, name=None, latex_name=None)[source]¶
- Construct an alternating form on the free module. - INPUT: - degree– the degree of the alternating form (i.e. its tensor rank)
- name– (default:- None) string; name given to the alternating form
- latex_name– (default:- None) string; LaTeX symbol to denote the alternating form; if none is provided, the LaTeX symbol is set to- name
 - OUTPUT: - instance of - FreeModuleAltForm
 - EXAMPLES: - Alternating forms on a rank-3 module: - sage: M = FiniteRankFreeModule(ZZ, 3, name='M') sage: a = M.alternating_form(2, 'a') ; a Alternating form a of degree 2 on the Rank-3 free module M over the Integer Ring - >>> from sage.all import * >>> M = FiniteRankFreeModule(ZZ, Integer(3), name='M') >>> a = M.alternating_form(Integer(2), 'a') ; a Alternating form a of degree 2 on the Rank-3 free module M over the Integer Ring - The nonzero components in a given basis have to be set in a second step, thereby fully specifying the alternating form: - 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.set_comp(e)[0,1] = 2 sage: a.set_comp(e)[1,2] = -3 sage: a.display(e) a = 2 e^0∧e^1 - 3 e^1∧e^2 - >>> from sage.all import * >>> e = M.basis('e') ; e Basis (e_0,e_1,e_2) on the Rank-3 free module M over the Integer Ring >>> a.set_comp(e)[Integer(0),Integer(1)] = Integer(2) >>> a.set_comp(e)[Integer(1),Integer(2)] = -Integer(3) >>> a.display(e) a = 2 e^0∧e^1 - 3 e^1∧e^2 - An alternating form of degree 1 is a linear form: - sage: a = M.alternating_form(1, 'a') ; a Linear form a on the Rank-3 free module M over the Integer Ring - >>> from sage.all import * >>> a = M.alternating_form(Integer(1), 'a') ; a Linear form a on the Rank-3 free module M over the Integer Ring - To construct such a form, it is preferable to call the method - linear_form()instead:- sage: a = M.linear_form('a') ; a Linear form a on the Rank-3 free module M over the Integer Ring - >>> from sage.all import * >>> a = M.linear_form('a') ; a Linear form a on the Rank-3 free module M over the Integer Ring - See - FreeModuleAltFormfor more documentation.
 - automorphism(matrix=None, basis=None, name=None, latex_name=None)[source]¶
- Construct a module automorphism of - self.- Denoting - selfby \(M\), an automorphism of- selfis an element of the general linear group \(\mathrm{GL}(M)\).- INPUT: - matrix– (default:- None) matrix of size rank(M)*rank(M) representing the automorphism with respect to- basis; this entry can actually be any material from which a matrix of elements of- selfbase ring can be constructed; the columns of- matrixmust be the components w.r.t.- basisof the images of the elements of- basis. If- matrixis- None, the automorphism has to be initialized afterwards by method- set_comp()or via the operator [].
- basis– (default:- None) basis of- selfdefining the matrix representation; if- Nonethe default basis of- selfis assumed.
- name– (default:- None) string; name given to the automorphism
- latex_name– (default:- None) string; LaTeX symbol to denote the automorphism; if none is provided, the LaTeX symbol is set to- name
 - OUTPUT: - instance of - FreeModuleAutomorphism
 - EXAMPLES: - Automorphism of a rank-2 free \(\ZZ\)-module: - sage: M = FiniteRankFreeModule(ZZ, 2, name='M') sage: e = M.basis('e') sage: a = M.automorphism(matrix=[[1,2],[1,3]], basis=e, name='a') ; a Automorphism a of the Rank-2 free module M over the Integer Ring sage: a.parent() General linear group of the Rank-2 free module M over the Integer Ring sage: a.matrix(e) [1 2] [1 3] - >>> from sage.all import * >>> M = FiniteRankFreeModule(ZZ, Integer(2), name='M') >>> e = M.basis('e') >>> a = M.automorphism(matrix=[[Integer(1),Integer(2)],[Integer(1),Integer(3)]], basis=e, name='a') ; a Automorphism a of the Rank-2 free module M over the Integer Ring >>> a.parent() General linear group of the Rank-2 free module M over the Integer Ring >>> a.matrix(e) [1 2] [1 3] - An automorphism is a tensor of type (1,1): - sage: a.tensor_type() (1, 1) sage: a.display(e) a = e_0⊗e^0 + 2 e_0⊗e^1 + e_1⊗e^0 + 3 e_1⊗e^1 - >>> from sage.all import * >>> a.tensor_type() (1, 1) >>> a.display(e) a = e_0⊗e^0 + 2 e_0⊗e^1 + e_1⊗e^0 + 3 e_1⊗e^1 - The automorphism components can be specified in a second step, as components of a type-\((1,1)\) tensor: - sage: a1 = M.automorphism(name='a') sage: a1[e,:] = [[1,2],[1,3]] sage: a1.matrix(e) [1 2] [1 3] sage: a1 == a True - >>> from sage.all import * >>> a1 = M.automorphism(name='a') >>> a1[e,:] = [[Integer(1),Integer(2)],[Integer(1),Integer(3)]] >>> a1.matrix(e) [1 2] [1 3] >>> a1 == a True - Component by component specification: - sage: a2 = M.automorphism(name='a') sage: a2[0,0] = 1 # component set in the module's default basis (e) sage: a2[0,1] = 2 sage: a2[1,0] = 1 sage: a2[1,1] = 3 sage: a2.matrix(e) [1 2] [1 3] sage: a2 == a True - >>> from sage.all import * >>> a2 = M.automorphism(name='a') >>> a2[Integer(0),Integer(0)] = Integer(1) # component set in the module's default basis (e) >>> a2[Integer(0),Integer(1)] = Integer(2) >>> a2[Integer(1),Integer(0)] = Integer(1) >>> a2[Integer(1),Integer(1)] = Integer(3) >>> a2.matrix(e) [1 2] [1 3] >>> a2 == a True - See - FreeModuleAutomorphismfor more documentation.
 - bases()[source]¶
- Return the list of bases that have been defined on the free module - self.- Use the method - print_bases()to get a formatted output with more information.- OUTPUT: - list of instances of class - FreeModuleBasis
 - EXAMPLES: - Bases on a rank-3 free module: - sage: M = FiniteRankFreeModule(ZZ, 3, name='M_3', start_index=1) sage: M.bases() [] sage: e = M.basis('e') sage: M.bases() [Basis (e_1,e_2,e_3) on the Rank-3 free module M_3 over the Integer Ring] sage: f = M.basis('f') sage: M.bases() [Basis (e_1,e_2,e_3) on the Rank-3 free module M_3 over the Integer Ring, Basis (f_1,f_2,f_3) on the Rank-3 free module M_3 over the Integer Ring] - >>> from sage.all import * >>> M = FiniteRankFreeModule(ZZ, Integer(3), name='M_3', start_index=Integer(1)) >>> M.bases() [] >>> e = M.basis('e') >>> M.bases() [Basis (e_1,e_2,e_3) on the Rank-3 free module M_3 over the Integer Ring] >>> f = M.basis('f') >>> M.bases() [Basis (e_1,e_2,e_3) on the Rank-3 free module M_3 over the Integer Ring, Basis (f_1,f_2,f_3) on the Rank-3 free module M_3 over the Integer Ring] 
 - basis(symbol, latex_symbol=None, from_family=None, indices=None, latex_indices=None, symbol_dual=None, latex_symbol_dual=None)[source]¶
- Define or return a basis of the free module - self.- Let \(M\) denotes the free module - selfand \(n\) its rank.- The basis can be defined from a set of \(n\) linearly independent elements of \(M\) by means of the argument - from_family. If- from_familyis not specified, the basis is created from scratch and, at this stage, is unrelated to bases that could have been defined previously on \(M\). It can be related afterwards by means of the method- set_change_of_basis().- If the basis specified by the given symbol already exists, it is simply returned, whatever the value of the arguments - latex_symbolor- from_family.- Note that another way to construct a basis of - selfis to use the method- new_basis()on an existing basis, with the automorphism relating the two bases as an argument.- INPUT: - symbol– either a string, to be used as a common base for the symbols of the elements of the basis, or a list/tuple of strings, representing the individual symbols of the elements of the basis
- latex_symbol– (default:- None) either a string, to be used as a common base for the LaTeX symbols of the elements of the basis, or a list/tuple of strings, representing the individual LaTeX symbols of the elements of the basis; if- None,- symbolis used in place of- latex_symbol
- from_family– (default:- None) tuple or list of \(n\) linearly independent elements of the free module- self(\(n\) being the rank of- self)
- indices– (default:- None; used only if- symbolis a single string) list/tuple of strings representing the indices labelling the elements of the basis; if- None, the indices will be generated as integers within the range declared on- self
- latex_indices– (default:- None) list/tuple of strings representing the indices for the LaTeX symbols of the elements of the basis; if- None,- indicesis used instead
- symbol_dual– (default:- None) same as- symbolbut for the dual basis; if- None,- symbolmust be a string and is used for the common base of the symbols of the elements of the dual basis
- latex_symbol_dual– (default:- None) same as- latex_symbolbut for the dual basis
 - OUTPUT: - instance of - FreeModuleBasisrepresenting a basis on- self
 - EXAMPLES: - Bases on a rank-3 free module: - 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: e[0] Element e_0 of the Rank-3 free module M over the Integer Ring sage: latex(e) \left(e_{0},e_{1},e_{2}\right) - >>> 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 >>> e[Integer(0)] Element e_0 of the Rank-3 free module M over the Integer Ring >>> latex(e) \left(e_{0},e_{1},e_{2}\right) - The LaTeX symbol can be set explicitly: - sage: eps = M.basis('eps', latex_symbol=r'\epsilon') ; eps Basis (eps_0,eps_1,eps_2) on the Rank-3 free module M over the Integer Ring sage: latex(eps) \left(\epsilon_{0},\epsilon_{1},\epsilon_{2}\right) - >>> from sage.all import * >>> eps = M.basis('eps', latex_symbol=r'\epsilon') ; eps Basis (eps_0,eps_1,eps_2) on the Rank-3 free module M over the Integer Ring >>> latex(eps) \left(\epsilon_{0},\epsilon_{1},\epsilon_{2}\right) - The indices can be customized: - sage: f = M.basis('f', indices=('x', 'y', 'z')); f Basis (f_x,f_y,f_z) on the Rank-3 free module M over the Integer Ring sage: latex(f[1]) f_{y} - >>> from sage.all import * >>> f = M.basis('f', indices=('x', 'y', 'z')); f Basis (f_x,f_y,f_z) on the Rank-3 free module M over the Integer Ring >>> latex(f[Integer(1)]) f_{y} - By providing a list or a tuple for the argument - symbol, one can have a different symbol for each element of the basis; it is then mandatory to specify some symbols for the dual basis:- sage: g = M.basis(('a', 'b', 'c'), symbol_dual=('A', 'B', 'C')); g Basis (a,b,c) on the Rank-3 free module M over the Integer Ring sage: g.dual_basis() Dual basis (A,B,C) on the Rank-3 free module M over the Integer Ring - >>> from sage.all import * >>> g = M.basis(('a', 'b', 'c'), symbol_dual=('A', 'B', 'C')); g Basis (a,b,c) on the Rank-3 free module M over the Integer Ring >>> g.dual_basis() Dual basis (A,B,C) on the Rank-3 free module M over the Integer Ring - If the provided symbol and indices are that of an already defined basis, the latter is returned (no new basis is created): - sage: M.basis('e') is e True sage: M.basis('eps') is eps True sage: M.basis('e', indices=['x', 'y', 'z']) is e False sage: M.basis('e', indices=['x', 'y', 'z']) is \ ....: M.basis('e', indices=['x', 'y', 'z']) True - >>> from sage.all import * >>> M.basis('e') is e True >>> M.basis('eps') is eps True >>> M.basis('e', indices=['x', 'y', 'z']) is e False >>> M.basis('e', indices=['x', 'y', 'z']) is M.basis('e', indices=['x', 'y', 'z']) True - The individual elements of the basis are labelled according the parameter - start_indexprovided at the free module construction:- sage: M = FiniteRankFreeModule(ZZ, 3, name='M', start_index=1) sage: e = M.basis('e') ; e Basis (e_1,e_2,e_3) on the Rank-3 free module M over the Integer Ring sage: e[1] Element e_1 of the Rank-3 free module M over the Integer Ring - >>> from sage.all import * >>> M = FiniteRankFreeModule(ZZ, Integer(3), name='M', start_index=Integer(1)) >>> e = M.basis('e') ; e Basis (e_1,e_2,e_3) on the Rank-3 free module M over the Integer Ring >>> e[Integer(1)] Element e_1 of the Rank-3 free module M over the Integer Ring - Construction of a basis from a spanning family of linearly independent module elements: - sage: f1 = -e[2] sage: f2 = 4*e[1] + 3*e[3] sage: f3 = 7*e[1] + 5*e[3] sage: f = M.basis('f', from_family=(f1,f2,f3)) sage: f[1].display() f_1 = -e_2 sage: f[2].display() f_2 = 4 e_1 + 3 e_3 sage: f[3].display() f_3 = 7 e_1 + 5 e_3 - >>> from sage.all import * >>> f1 = -e[Integer(2)] >>> f2 = Integer(4)*e[Integer(1)] + Integer(3)*e[Integer(3)] >>> f3 = Integer(7)*e[Integer(1)] + Integer(5)*e[Integer(3)] >>> f = M.basis('f', from_family=(f1,f2,f3)) >>> f[Integer(1)].display() f_1 = -e_2 >>> f[Integer(2)].display() f_2 = 4 e_1 + 3 e_3 >>> f[Integer(3)].display() f_3 = 7 e_1 + 5 e_3 - The change-of-basis automorphisms have been registered: - sage: M.change_of_basis(e,f).matrix(e) [ 0 4 7] [-1 0 0] [ 0 3 5] sage: M.change_of_basis(f,e).matrix(e) [ 0 -1 0] [-5 0 7] [ 3 0 -4] sage: M.change_of_basis(f,e) == M.change_of_basis(e,f).inverse() True - >>> from sage.all import * >>> M.change_of_basis(e,f).matrix(e) [ 0 4 7] [-1 0 0] [ 0 3 5] >>> M.change_of_basis(f,e).matrix(e) [ 0 -1 0] [-5 0 7] [ 3 0 -4] >>> M.change_of_basis(f,e) == M.change_of_basis(e,f).inverse() True - Check of the change-of-basis e –> f: - sage: a = M.change_of_basis(e,f) ; a Automorphism of the Rank-3 free module M over the Integer Ring sage: all( f[i] == a(e[i]) for i in M.irange() ) True - >>> from sage.all import * >>> a = M.change_of_basis(e,f) ; a Automorphism of the Rank-3 free module M over the Integer Ring >>> all( f[i] == a(e[i]) for i in M.irange() ) True - Providing a family of module elements that are not linearly independent raise an error: - sage: g = M.basis('g', from_family=(f1, f2, f1+f2)) Traceback (most recent call last): ... ValueError: the provided module elements are not linearly independent - >>> from sage.all import * >>> g = M.basis('g', from_family=(f1, f2, f1+f2)) Traceback (most recent call last): ... ValueError: the provided module elements are not linearly independent - For more documentation on bases see - FreeModuleBasis.
 - change_of_basis(basis1, basis2)[source]¶
- Return a module automorphism linking two bases defined on the free module - self.- If the automorphism has not been recorded yet (in the internal dictionary - self._basis_changes), it is computed by transitivity, i.e. by performing products of recorded changes of basis.- INPUT: - basis1– a basis of- self, denoted \((e_i)\) below
- basis2– a basis of- self, denoted \((f_i)\) below
 - OUTPUT: - instance of - FreeModuleAutomorphismdescribing the automorphism \(P\) that relates the basis \((e_i)\) to the basis \((f_i)\) according to \(f_i = P(e_i)\)
 - EXAMPLES: - Changes of basis on a rank-2 free module: - sage: FiniteRankFreeModule._clear_cache_() # for doctests only sage: M = FiniteRankFreeModule(ZZ, 2, name='M', start_index=1) sage: e = M.basis('e') sage: f = M.basis('f', from_family=(e[1]+2*e[2], e[1]+3*e[2])) sage: P = M.change_of_basis(e,f) ; P Automorphism of the Rank-2 free module M over the Integer Ring sage: P.matrix(e) [1 1] [2 3] - >>> from sage.all import * >>> FiniteRankFreeModule._clear_cache_() # for doctests only >>> M = FiniteRankFreeModule(ZZ, Integer(2), name='M', start_index=Integer(1)) >>> e = M.basis('e') >>> f = M.basis('f', from_family=(e[Integer(1)]+Integer(2)*e[Integer(2)], e[Integer(1)]+Integer(3)*e[Integer(2)])) >>> P = M.change_of_basis(e,f) ; P Automorphism of the Rank-2 free module M over the Integer Ring >>> P.matrix(e) [1 1] [2 3] - Note that the columns of this matrix contain the components of the elements of basis - fw.r.t. to basis- e:- sage: f[1].display(e) f_1 = e_1 + 2 e_2 sage: f[2].display(e) f_2 = e_1 + 3 e_2 - >>> from sage.all import * >>> f[Integer(1)].display(e) f_1 = e_1 + 2 e_2 >>> f[Integer(2)].display(e) f_2 = e_1 + 3 e_2 - The change of basis is cached: - sage: P is M.change_of_basis(e,f) True - >>> from sage.all import * >>> P is M.change_of_basis(e,f) True - Check of the change-of-basis automorphism: - sage: f[1] == P(e[1]) True sage: f[2] == P(e[2]) True - >>> from sage.all import * >>> f[Integer(1)] == P(e[Integer(1)]) True >>> f[Integer(2)] == P(e[Integer(2)]) True - Check of the reverse change of basis: - sage: M.change_of_basis(f,e) == P^(-1) True - >>> from sage.all import * >>> M.change_of_basis(f,e) == P**(-Integer(1)) True - We have of course: - sage: M.change_of_basis(e,e) Identity map of the Rank-2 free module M over the Integer Ring sage: M.change_of_basis(e,e) is M.identity_map() True - >>> from sage.all import * >>> M.change_of_basis(e,e) Identity map of the Rank-2 free module M over the Integer Ring >>> M.change_of_basis(e,e) is M.identity_map() True - Let us introduce a third basis on - M:- sage: h = M.basis('h', from_family=(3*e[1]+4*e[2], 5*e[1]+7*e[2])) - >>> from sage.all import * >>> h = M.basis('h', from_family=(Integer(3)*e[Integer(1)]+Integer(4)*e[Integer(2)], Integer(5)*e[Integer(1)]+Integer(7)*e[Integer(2)])) - The change of basis - e–>- hhas been recorded directly from the definition of- h:- sage: Q = M.change_of_basis(e,h) ; Q.matrix(e) [3 5] [4 7] - >>> from sage.all import * >>> Q = M.change_of_basis(e,h) ; Q.matrix(e) [3 5] [4 7] - The change of basis - f–>- his computed by transitivity, i.e. from the changes of basis- f–>- eand- e–>- h:- sage: R = M.change_of_basis(f,h) ; R Automorphism of the Rank-2 free module M over the Integer Ring sage: R.matrix(e) [-1 2] [-2 3] sage: R.matrix(f) [ 5 8] [-2 -3] - >>> from sage.all import * >>> R = M.change_of_basis(f,h) ; R Automorphism of the Rank-2 free module M over the Integer Ring >>> R.matrix(e) [-1 2] [-2 3] >>> R.matrix(f) [ 5 8] [-2 -3] - Let us check that - Ris indeed the change of basis- f–>- h:- sage: h[1] == R(f[1]) True sage: h[2] == R(f[2]) True - >>> from sage.all import * >>> h[Integer(1)] == R(f[Integer(1)]) True >>> h[Integer(2)] == R(f[Integer(2)]) True - A related check is: - sage: R == Q*P^(-1) True - >>> from sage.all import * >>> R == Q*P**(-Integer(1)) True 
 - construction()[source]¶
- The construction functor and base ring for - self.- EXAMPLES: - sage: FiniteRankFreeModule._clear_cache_() # for doctests only sage: M = FiniteRankFreeModule(ZZ, 3, name='M') sage: M.construction() (VectorFunctor, Integer Ring) sage: N = FiniteRankFreeModule(ZZ, 3, name='N', start_index=17) sage: N.construction() (VectorFunctor, Integer Ring) - >>> from sage.all import * >>> FiniteRankFreeModule._clear_cache_() # for doctests only >>> M = FiniteRankFreeModule(ZZ, Integer(3), name='M') >>> M.construction() (VectorFunctor, Integer Ring) >>> N = FiniteRankFreeModule(ZZ, Integer(3), name='N', start_index=Integer(17)) >>> N.construction() (VectorFunctor, Integer Ring) 
 - default_basis()[source]¶
- Return the default basis of the free module - self.- The default basis is simply a basis whose name can be skipped in methods requiring a basis as an argument. By default, it is the first basis introduced on the module. It can be changed by the method - set_default_basis().- OUTPUT: - instance of - FreeModuleBasis
 - EXAMPLES: - At the module construction, no default basis is assumed: - sage: M = FiniteRankFreeModule(ZZ, 2, name='M', start_index=1) sage: M.default_basis() No default basis has been defined on the Rank-2 free module M over the Integer Ring - >>> from sage.all import * >>> M = FiniteRankFreeModule(ZZ, Integer(2), name='M', start_index=Integer(1)) >>> M.default_basis() No default basis has been defined on the Rank-2 free module M over the Integer Ring - The first defined basis becomes the default one: - sage: e = M.basis('e') ; e Basis (e_1,e_2) on the Rank-2 free module M over the Integer Ring sage: M.default_basis() Basis (e_1,e_2) on the Rank-2 free module M over the Integer Ring sage: f = M.basis('f') ; f Basis (f_1,f_2) on the Rank-2 free module M over the Integer Ring sage: M.default_basis() Basis (e_1,e_2) on the Rank-2 free module M over the Integer Ring - >>> from sage.all import * >>> e = M.basis('e') ; e Basis (e_1,e_2) on the Rank-2 free module M over the Integer Ring >>> M.default_basis() Basis (e_1,e_2) on the Rank-2 free module M over the Integer Ring >>> f = M.basis('f') ; f Basis (f_1,f_2) on the Rank-2 free module M over the Integer Ring >>> M.default_basis() Basis (e_1,e_2) on the Rank-2 free module M over the Integer Ring 
 - dual()[source]¶
- Return the dual module of - self.- EXAMPLES: - Dual of a free module over \(\ZZ\): - sage: M = FiniteRankFreeModule(ZZ, 3, name='M') sage: M.dual() Dual of the Rank-3 free module M over the Integer Ring sage: latex(M.dual()) M^* - >>> from sage.all import * >>> M = FiniteRankFreeModule(ZZ, Integer(3), name='M') >>> M.dual() Dual of the Rank-3 free module M over the Integer Ring >>> latex(M.dual()) M^* - The dual is a free module of the same rank as M: - sage: from sage.tensor.modules.finite_rank_free_module import FiniteRankFreeModule_abstract sage: isinstance(M.dual(), FiniteRankFreeModule_abstract) True sage: M.dual().rank() 3 - >>> from sage.all import * >>> from sage.tensor.modules.finite_rank_free_module import FiniteRankFreeModule_abstract >>> isinstance(M.dual(), FiniteRankFreeModule_abstract) True >>> M.dual().rank() 3 - It is formed by alternating forms of degree 1, i.e. linear forms: - sage: M.dual() is M.dual_exterior_power(1) True sage: M.dual().an_element() Linear form on the Rank-3 free module M over the Integer Ring sage: a = M.linear_form() sage: a in M.dual() True - >>> from sage.all import * >>> M.dual() is M.dual_exterior_power(Integer(1)) True >>> M.dual().an_element() Linear form on the Rank-3 free module M over the Integer Ring >>> a = M.linear_form() >>> a in M.dual() True - The elements of a dual basis belong of course to the dual module: - sage: e = M.basis('e') sage: e.dual_basis()[0] in M.dual() True - >>> from sage.all import * >>> e = M.basis('e') >>> e.dual_basis()[Integer(0)] in M.dual() True 
 - dual_exterior_power(p)[source]¶
- Return the \(p\)-th exterior power of the dual of - self.- If \(M\) stands for the free module - self, the p-th exterior power of the dual of \(M\) is the set \(\Lambda^p(M^*)\) of all alternating forms of degree \(p\) on \(M\), i.e. of all multilinear maps\[\underbrace{M\times\cdots\times M}_{p\ \; \mbox{times}} \longrightarrow R\]- that vanish whenever any of two of their arguments are equal. \(\Lambda^p(M^*)\) is a free module of rank \(\binom{n}{p}\) over the same ring as \(M\), where \(n\) is the rank of \(M\). - INPUT: - p– nonnegative integer
 - OUTPUT: - for \(p=0\), the base ring \(R\) 
- for \(p=1\), instance of - FiniteRankDualFreeModulerepresenting the dual \(M^*\)
- for \(p\geq 1\), instance of - ExtPowerDualFreeModulerepresenting the free module \(\Lambda^p(M^*)\)
 - EXAMPLES: - Exterior powers of the dual of a free \(\ZZ\)-module of rank 3: - sage: M = FiniteRankFreeModule(ZZ, 3, name='M') sage: e = M.basis('e') sage: M.dual_exterior_power(0) # return the base ring Integer Ring sage: M.dual_exterior_power(1) # return the dual module Dual of the Rank-3 free module M over the Integer Ring sage: M.dual_exterior_power(1) is M.dual() True sage: M.dual_exterior_power(2) 2nd exterior power of the dual of the Rank-3 free module M over the Integer Ring sage: M.dual_exterior_power(2).an_element() Alternating form of degree 2 on the Rank-3 free module M over the Integer Ring sage: M.dual_exterior_power(2).an_element().display() e^0∧e^1 sage: M.dual_exterior_power(3) 3rd exterior power of the dual of the Rank-3 free module M over the Integer Ring sage: M.dual_exterior_power(3).an_element() Alternating form of degree 3 on the Rank-3 free module M over the Integer Ring sage: M.dual_exterior_power(3).an_element().display() e^0∧e^1∧e^2 - >>> from sage.all import * >>> M = FiniteRankFreeModule(ZZ, Integer(3), name='M') >>> e = M.basis('e') >>> M.dual_exterior_power(Integer(0)) # return the base ring Integer Ring >>> M.dual_exterior_power(Integer(1)) # return the dual module Dual of the Rank-3 free module M over the Integer Ring >>> M.dual_exterior_power(Integer(1)) is M.dual() True >>> M.dual_exterior_power(Integer(2)) 2nd exterior power of the dual of the Rank-3 free module M over the Integer Ring >>> M.dual_exterior_power(Integer(2)).an_element() Alternating form of degree 2 on the Rank-3 free module M over the Integer Ring >>> M.dual_exterior_power(Integer(2)).an_element().display() e^0∧e^1 >>> M.dual_exterior_power(Integer(3)) 3rd exterior power of the dual of the Rank-3 free module M over the Integer Ring >>> M.dual_exterior_power(Integer(3)).an_element() Alternating form of degree 3 on the Rank-3 free module M over the Integer Ring >>> M.dual_exterior_power(Integer(3)).an_element().display() e^0∧e^1∧e^2 - See - ExtPowerDualFreeModulefor more documentation.
 - dual_symmetric_power(p)[source]¶
- Return the \(p\)-th symmetric power of the dual of - self.- EXAMPLES: - Symmetric powers of the dual of a free \(\ZZ\)-module of rank 3: - sage: M = FiniteRankFreeModule(ZZ, 3, name='M') sage: e = M.basis('e') sage: M.dual_symmetric_power(0) Free module of type-(0,0) tensors on the Rank-3 free module M over the Integer Ring sage: M.dual_symmetric_power(1) # return the dual module Dual of the Rank-3 free module M over the Integer Ring sage: M.dual_symmetric_power(2) Free module of fully symmetric type-(0,2) tensors on the Rank-3 free module M over the Integer Ring sage: M.dual_symmetric_power(2).an_element() Symmetric bilinear form on the Rank-3 free module M over the Integer Ring sage: M.dual_symmetric_power(2).an_element().display() e^0⊗e^0 sage: M.dual_symmetric_power(3) Free module of fully symmetric type-(0,3) tensors on the Rank-3 free module M over the Integer Ring sage: M.dual_symmetric_power(3).an_element() Type-(0,3) tensor on the Rank-3 free module M over the Integer Ring sage: M.dual_symmetric_power(3).an_element().display() e^0⊗e^0⊗e^0 - >>> from sage.all import * >>> M = FiniteRankFreeModule(ZZ, Integer(3), name='M') >>> e = M.basis('e') >>> M.dual_symmetric_power(Integer(0)) Free module of type-(0,0) tensors on the Rank-3 free module M over the Integer Ring >>> M.dual_symmetric_power(Integer(1)) # return the dual module Dual of the Rank-3 free module M over the Integer Ring >>> M.dual_symmetric_power(Integer(2)) Free module of fully symmetric type-(0,2) tensors on the Rank-3 free module M over the Integer Ring >>> M.dual_symmetric_power(Integer(2)).an_element() Symmetric bilinear form on the Rank-3 free module M over the Integer Ring >>> M.dual_symmetric_power(Integer(2)).an_element().display() e^0⊗e^0 >>> M.dual_symmetric_power(Integer(3)) Free module of fully symmetric type-(0,3) tensors on the Rank-3 free module M over the Integer Ring >>> M.dual_symmetric_power(Integer(3)).an_element() Type-(0,3) tensor on the Rank-3 free module M over the Integer Ring >>> M.dual_symmetric_power(Integer(3)).an_element().display() e^0⊗e^0⊗e^0 
 - endomorphism(matrix_rep, basis=None, name=None, latex_name=None)[source]¶
- Construct an endomorphism of the free module - self.- The returned object is a module morphism \(\phi: M \rightarrow M\), where \(M\) is - self.- INPUT: - matrix_rep– matrix of size rank(M)*rank(M) representing the endomorphism with respect to- basis; this entry can actually be any material from which a matrix of elements of- selfbase ring can be constructed; the columns of- matrix_repmust be the components w.r.t.- basisof the images of the elements of- basis.
- basis– (default:- None) basis of- selfdefining the matrix representation; if None the default basis of- selfis assumed.
- name– (default:- None) string; name given to the endomorphism
- latex_name– (default:- None) string; LaTeX symbol to denote the endomorphism. If none is provided,- namewill be used.
 - OUTPUT: - the endomorphism \(\phi: M \rightarrow M\) corresponding to the given specifications, as an instance of - FiniteRankFreeModuleMorphism
 - EXAMPLES: - Construction of an endomorphism with minimal data (module’s default basis and no name): - sage: M = FiniteRankFreeModule(ZZ, 2, name='M') sage: e = M.basis('e') sage: phi = M.endomorphism([[1,-2], [-3,4]]) ; phi Generic endomorphism of Rank-2 free module M over the Integer Ring sage: phi.matrix() # matrix w.r.t the default basis [ 1 -2] [-3 4] - >>> from sage.all import * >>> M = FiniteRankFreeModule(ZZ, Integer(2), name='M') >>> e = M.basis('e') >>> phi = M.endomorphism([[Integer(1),-Integer(2)], [-Integer(3),Integer(4)]]) ; phi Generic endomorphism of Rank-2 free module M over the Integer Ring >>> phi.matrix() # matrix w.r.t the default basis [ 1 -2] [-3 4] - Construction with full list of arguments (matrix given a basis different from the default one): - sage: a = M.automorphism() ; a[0,1], a[1,0] = 1, -1 sage: ep = e.new_basis(a, 'ep', latex_symbol="e'") sage: phi = M.endomorphism([[1,-2], [-3,4]], basis=ep, name='phi', ....: latex_name=r'\phi') sage: phi Generic endomorphism of Rank-2 free module M over the Integer Ring sage: phi.matrix(ep) # the input matrix [ 1 -2] [-3 4] sage: phi.matrix() # matrix w.r.t the default basis [4 3] [2 1] - >>> from sage.all import * >>> a = M.automorphism() ; a[Integer(0),Integer(1)], a[Integer(1),Integer(0)] = Integer(1), -Integer(1) >>> ep = e.new_basis(a, 'ep', latex_symbol="e'") >>> phi = M.endomorphism([[Integer(1),-Integer(2)], [-Integer(3),Integer(4)]], basis=ep, name='phi', ... latex_name=r'\phi') >>> phi Generic endomorphism of Rank-2 free module M over the Integer Ring >>> phi.matrix(ep) # the input matrix [ 1 -2] [-3 4] >>> phi.matrix() # matrix w.r.t the default basis [4 3] [2 1] - See - FiniteRankFreeModuleMorphismfor more documentation.
 - exterior_power(p)[source]¶
- Return the \(p\)-th exterior power of - self.- If \(M\) stands for the free module - self, the p-th exterior power of \(M\) is the set \(\Lambda^p(M)\) of all alternating contravariant tensors of rank \(p\), i.e. of all multilinear maps\[\underbrace{M^*\times\cdots\times M^*}_{p\ \; \mbox{times}} \longrightarrow R\]- that vanish whenever any of two of their arguments are equal. \(\Lambda^p(M)\) is a free module of rank \(\binom{n}{p}\) over the same ring as \(M\), where \(n\) is the rank of \(M\). - INPUT: - p– nonnegative integer
 - OUTPUT: - for \(p=0\), the base ring \(R\) 
- for \(p=1\), the free module \(M\), since \(\Lambda^1(M)=M\) 
- for \(p\geq 2\), instance of - ExtPowerFreeModulerepresenting the free module \(\Lambda^p(M)\)
 - EXAMPLES: - Exterior powers of a free \(\ZZ\)-module of rank 3: - sage: M = FiniteRankFreeModule(ZZ, 3, name='M') sage: e = M.basis('e') sage: M.exterior_power(0) # return the base ring Integer Ring sage: M.exterior_power(1) # return the module itself Rank-3 free module M over the Integer Ring sage: M.exterior_power(1) is M True sage: M.exterior_power(2) 2nd exterior power of the Rank-3 free module M over the Integer Ring sage: M.exterior_power(2).an_element() Alternating contravariant tensor of degree 2 on the Rank-3 free module M over the Integer Ring sage: M.exterior_power(2).an_element().display() e_0∧e_1 sage: M.exterior_power(3) 3rd exterior power of the Rank-3 free module M over the Integer Ring sage: M.exterior_power(3).an_element() Alternating contravariant tensor of degree 3 on the Rank-3 free module M over the Integer Ring sage: M.exterior_power(3).an_element().display() e_0∧e_1∧e_2 - >>> from sage.all import * >>> M = FiniteRankFreeModule(ZZ, Integer(3), name='M') >>> e = M.basis('e') >>> M.exterior_power(Integer(0)) # return the base ring Integer Ring >>> M.exterior_power(Integer(1)) # return the module itself Rank-3 free module M over the Integer Ring >>> M.exterior_power(Integer(1)) is M True >>> M.exterior_power(Integer(2)) 2nd exterior power of the Rank-3 free module M over the Integer Ring >>> M.exterior_power(Integer(2)).an_element() Alternating contravariant tensor of degree 2 on the Rank-3 free module M over the Integer Ring >>> M.exterior_power(Integer(2)).an_element().display() e_0∧e_1 >>> M.exterior_power(Integer(3)) 3rd exterior power of the Rank-3 free module M over the Integer Ring >>> M.exterior_power(Integer(3)).an_element() Alternating contravariant tensor of degree 3 on the Rank-3 free module M over the Integer Ring >>> M.exterior_power(Integer(3)).an_element().display() e_0∧e_1∧e_2 - See - ExtPowerFreeModulefor more documentation.
 - general_linear_group()[source]¶
- Return the general linear group of - self.- If - selfis the free module \(M\), the general linear group is the group \(\mathrm{GL}(M)\) of automorphisms of \(M\).- OUTPUT: - instance of class - FreeModuleLinearGrouprepresenting \(\mathrm{GL}(M)\)
 - EXAMPLES: - The general linear group of a rank-3 free module: - sage: M = FiniteRankFreeModule(ZZ, 3, name='M') sage: e = M.basis('e') sage: GL = M.general_linear_group() ; GL General linear group of the Rank-3 free module M over the Integer Ring sage: GL.category() Category of groups sage: type(GL) <class 'sage.tensor.modules.free_module_linear_group.FreeModuleLinearGroup_with_category'> - >>> from sage.all import * >>> M = FiniteRankFreeModule(ZZ, Integer(3), name='M') >>> e = M.basis('e') >>> GL = M.general_linear_group() ; GL General linear group of the Rank-3 free module M over the Integer Ring >>> GL.category() Category of groups >>> type(GL) <class 'sage.tensor.modules.free_module_linear_group.FreeModuleLinearGroup_with_category'> - There is a unique instance of the general linear group: - sage: M.general_linear_group() is GL True - >>> from sage.all import * >>> M.general_linear_group() is GL True - The group identity element: - sage: GL.one() Identity map of the Rank-3 free module M over the Integer Ring sage: GL.one().matrix(e) [1 0 0] [0 1 0] [0 0 1] - >>> from sage.all import * >>> GL.one() Identity map of the Rank-3 free module M over the Integer Ring >>> GL.one().matrix(e) [1 0 0] [0 1 0] [0 0 1] - An element: - sage: GL.an_element() Automorphism of the Rank-3 free module M over the Integer Ring sage: GL.an_element().matrix(e) [ 1 0 0] [ 0 -1 0] [ 0 0 1] - >>> from sage.all import * >>> GL.an_element() Automorphism of the Rank-3 free module M over the Integer Ring >>> GL.an_element().matrix(e) [ 1 0 0] [ 0 -1 0] [ 0 0 1] - See - FreeModuleLinearGroupfor more documentation.
 - hom(codomain, matrix_rep, bases=None, name=None, latex_name=None)[source]¶
- Homomorphism from - selfto a free module.- Define a module homomorphism \[\phi:\ M \longrightarrow N,\]- where \(M\) is - selfand \(N\) is a free module of finite rank over the same ring \(R\) as- self.- Note - This method is a redefinition of - sage.structure.parent.Parent.hom()because the latter assumes that- selfhas some privileged generators, while an instance of- FiniteRankFreeModulehas no privileged basis.- INPUT: - codomain– the target module \(N\)
- matrix_rep– matrix of size rank(N)*rank(M) representing the homomorphism with respect to the pair of bases defined by- bases; this entry can actually be any material from which a matrix of elements of \(R\) can be constructed; the columns of- matrix_repmust be the components w.r.t.- basis_Nof the images of the elements of- basis_M.
- bases– (default:- None) pair- (basis_M, basis_N)defining the matrix representation,- basis_Mbeing a basis of- selfand- basis_Na basis of module \(N\) ; if None the pair formed by the default bases of each module is assumed.
- name– (default:- None) string; name given to the homomorphism
- latex_name– (default:- None) string; LaTeX symbol to denote the homomorphism. If- None,- namewill be used.
 - OUTPUT: - the homomorphism \(\phi: M \rightarrow N\) corresponding to the given specifications, as an instance of - FiniteRankFreeModuleMorphism
 - EXAMPLES: - Homomorphism between two free modules over \(\ZZ\): - sage: M = FiniteRankFreeModule(ZZ, 3, name='M') sage: N = FiniteRankFreeModule(ZZ, 2, name='N') sage: e = M.basis('e') sage: f = N.basis('f') sage: phi = M.hom(N, [[-1,2,0], [5,1,2]]) ; phi Generic morphism: From: Rank-3 free module M over the Integer Ring To: Rank-2 free module N over the Integer Ring - >>> from sage.all import * >>> M = FiniteRankFreeModule(ZZ, Integer(3), name='M') >>> N = FiniteRankFreeModule(ZZ, Integer(2), name='N') >>> e = M.basis('e') >>> f = N.basis('f') >>> phi = M.hom(N, [[-Integer(1),Integer(2),Integer(0)], [Integer(5),Integer(1),Integer(2)]]) ; phi Generic morphism: From: Rank-3 free module M over the Integer Ring To: Rank-2 free module N over the Integer Ring - Homomorphism defined by a matrix w.r.t. bases that are not the default ones: - sage: ep = M.basis('ep', latex_symbol=r"e'") sage: fp = N.basis('fp', latex_symbol=r"f'") sage: phi = M.hom(N, [[3,2,1], [1,2,3]], bases=(ep, fp)) ; phi Generic morphism: From: Rank-3 free module M over the Integer Ring To: Rank-2 free module N over the Integer Ring - >>> from sage.all import * >>> ep = M.basis('ep', latex_symbol=r"e'") >>> fp = N.basis('fp', latex_symbol=r"f'") >>> phi = M.hom(N, [[Integer(3),Integer(2),Integer(1)], [Integer(1),Integer(2),Integer(3)]], bases=(ep, fp)) ; phi Generic morphism: From: Rank-3 free module M over the Integer Ring To: Rank-2 free module N over the Integer Ring - Call with all arguments specified: - sage: phi = M.hom(N, [[3,2,1], [1,2,3]], bases=(ep, fp), ....: name='phi', latex_name=r'\phi') - >>> from sage.all import * >>> phi = M.hom(N, [[Integer(3),Integer(2),Integer(1)], [Integer(1),Integer(2),Integer(3)]], bases=(ep, fp), ... name='phi', latex_name=r'\phi') - The parent: - sage: phi.parent() is Hom(M,N) True - >>> from sage.all import * >>> phi.parent() is Hom(M,N) True - See class - FiniteRankFreeModuleMorphismfor more documentation.
 - identity_map(name='Id', latex_name=None)[source]¶
- Return the identity map of the free module - self.- INPUT: - name– (string; default: ‘Id’) name given to the identity identity map
- latex_name– (string; default:- None) LaTeX symbol to denote the identity map; if none is provided, the LaTeX symbol is set to ‘mathrm{Id}’ if- nameis ‘Id’ and to- nameotherwise
 - OUTPUT: - the identity map of - selfas an instance of- FreeModuleAutomorphism
 - EXAMPLES: - Identity map of a rank-3 \(\ZZ\)-module: - sage: M = FiniteRankFreeModule(ZZ, 3, name='M') sage: e = M.basis('e') sage: Id = M.identity_map() ; Id Identity map of the Rank-3 free module M over the Integer Ring sage: Id.parent() General linear group of the Rank-3 free module M over the Integer Ring sage: Id.matrix(e) [1 0 0] [0 1 0] [0 0 1] - >>> from sage.all import * >>> M = FiniteRankFreeModule(ZZ, Integer(3), name='M') >>> e = M.basis('e') >>> Id = M.identity_map() ; Id Identity map of the Rank-3 free module M over the Integer Ring >>> Id.parent() General linear group of the Rank-3 free module M over the Integer Ring >>> Id.matrix(e) [1 0 0] [0 1 0] [0 0 1] - The default LaTeX symbol: - sage: latex(Id) \mathrm{Id} - >>> from sage.all import * >>> latex(Id) \mathrm{Id} - It can be changed by means of the method - set_name():- sage: Id.set_name(latex_name=r'\mathrm{1}_M') sage: latex(Id) \mathrm{1}_M - >>> from sage.all import * >>> Id.set_name(latex_name=r'\mathrm{1}_M') >>> latex(Id) \mathrm{1}_M - The identity map is actually the identity element of GL(M): - sage: Id is M.general_linear_group().one() True - >>> from sage.all import * >>> Id is M.general_linear_group().one() True - It is also a tensor of type-\((1,1)\) on M: - sage: Id.tensor_type() (1, 1) sage: Id.comp(e) Kronecker delta of size 3x3 sage: Id[:] [1 0 0] [0 1 0] [0 0 1] - >>> from sage.all import * >>> Id.tensor_type() (1, 1) >>> Id.comp(e) Kronecker delta of size 3x3 >>> Id[:] [1 0 0] [0 1 0] [0 0 1] - Example with a LaTeX symbol different from the default one and set at the creation of the object: - sage: N = FiniteRankFreeModule(ZZ, 3, name='N') sage: f = N.basis('f') sage: Id = N.identity_map(name='Id_N', latex_name=r'\mathrm{Id}_N') sage: Id Identity map of the Rank-3 free module N over the Integer Ring sage: latex(Id) \mathrm{Id}_N - >>> from sage.all import * >>> N = FiniteRankFreeModule(ZZ, Integer(3), name='N') >>> f = N.basis('f') >>> Id = N.identity_map(name='Id_N', latex_name=r'\mathrm{Id}_N') >>> Id Identity map of the Rank-3 free module N over the Integer Ring >>> latex(Id) \mathrm{Id}_N 
 - irange(start=None)[source]¶
- Single index generator, labelling the elements of a basis of - self.- INPUT: - start– (default:- None) integer; initial value of the index; if none is provided,- self._sindexis assumed
 - OUTPUT: - an iterable index, starting from - startand ending at- self._sindex + self.rank() - 1
 - EXAMPLES: - Index range on a rank-3 module: - sage: M = FiniteRankFreeModule(ZZ, 3) sage: list(M.irange()) [0, 1, 2] sage: list(M.irange(start=1)) [1, 2] - >>> from sage.all import * >>> M = FiniteRankFreeModule(ZZ, Integer(3)) >>> list(M.irange()) [0, 1, 2] >>> list(M.irange(start=Integer(1))) [1, 2] - The default starting value corresponds to the parameter - start_indexprovided at the module construction (the default value being 0):- sage: M1 = FiniteRankFreeModule(ZZ, 3, start_index=1) sage: list(M1.irange()) [1, 2, 3] sage: M2 = FiniteRankFreeModule(ZZ, 3, start_index=-4) sage: list(M2.irange()) [-4, -3, -2] - >>> from sage.all import * >>> M1 = FiniteRankFreeModule(ZZ, Integer(3), start_index=Integer(1)) >>> list(M1.irange()) [1, 2, 3] >>> M2 = FiniteRankFreeModule(ZZ, Integer(3), start_index=-Integer(4)) >>> list(M2.irange()) [-4, -3, -2] 
 - linear_form(name=None, latex_name=None)[source]¶
- Construct a linear form on the free module - self.- A linear form on a free module \(M\) over a ring \(R\) is a map \(M \rightarrow R\) that is linear. It can be viewed as a tensor of type \((0,1)\) on \(M\). - INPUT: - name– (default:- None) string; name given to the linear form
- latex_name– (default:- None) string; LaTeX symbol to denote the linear form; if none is provided, the LaTeX symbol is set to- name
 - OUTPUT: - instance of - FreeModuleAltForm
 - EXAMPLES: - Linear form on a rank-3 free module: - sage: M = FiniteRankFreeModule(ZZ, 3, name='M') sage: e = M.basis('e') sage: a = M.linear_form('A') ; a Linear form A on the Rank-3 free module M over the Integer Ring sage: a[:] = [2,-1,3] # components w.r.t. the module's default basis (e) sage: a.display() A = 2 e^0 - e^1 + 3 e^2 - >>> from sage.all import * >>> M = FiniteRankFreeModule(ZZ, Integer(3), name='M') >>> e = M.basis('e') >>> a = M.linear_form('A') ; a Linear form A on the Rank-3 free module M over the Integer Ring >>> a[:] = [Integer(2),-Integer(1),Integer(3)] # components w.r.t. the module's default basis (e) >>> a.display() A = 2 e^0 - e^1 + 3 e^2 - A linear form maps module elements to ring elements: - sage: v = M([1,1,1]) sage: a(v) 4 - >>> from sage.all import * >>> v = M([Integer(1),Integer(1),Integer(1)]) >>> a(v) 4 - Test of linearity: - sage: u = M([-5,-2,7]) sage: a(3*u - 4*v) == 3*a(u) - 4*a(v) True - >>> from sage.all import * >>> u = M([-Integer(5),-Integer(2),Integer(7)]) >>> a(Integer(3)*u - Integer(4)*v) == Integer(3)*a(u) - Integer(4)*a(v) True - See - FreeModuleAltFormfor more documentation.
 - print_bases()[source]¶
- Display the bases that have been defined on the free module - self.- Use the method - bases()to get the raw list of bases.- EXAMPLES: - Bases on a rank-4 free module: - sage: M = FiniteRankFreeModule(ZZ, 4, name='M', start_index=1) sage: M.print_bases() No basis has been defined on the Rank-4 free module M over the Integer Ring sage: e = M.basis('e') sage: M.print_bases() Bases defined on the Rank-4 free module M over the Integer Ring: - (e_1,e_2,e_3,e_4) (default basis) sage: f = M.basis('f') sage: M.print_bases() Bases defined on the Rank-4 free module M over the Integer Ring: - (e_1,e_2,e_3,e_4) (default basis) - (f_1,f_2,f_3,f_4) sage: M.set_default_basis(f) sage: M.print_bases() Bases defined on the Rank-4 free module M over the Integer Ring: - (e_1,e_2,e_3,e_4) - (f_1,f_2,f_3,f_4) (default basis) - >>> from sage.all import * >>> M = FiniteRankFreeModule(ZZ, Integer(4), name='M', start_index=Integer(1)) >>> M.print_bases() No basis has been defined on the Rank-4 free module M over the Integer Ring >>> e = M.basis('e') >>> M.print_bases() Bases defined on the Rank-4 free module M over the Integer Ring: - (e_1,e_2,e_3,e_4) (default basis) >>> f = M.basis('f') >>> M.print_bases() Bases defined on the Rank-4 free module M over the Integer Ring: - (e_1,e_2,e_3,e_4) (default basis) - (f_1,f_2,f_3,f_4) >>> M.set_default_basis(f) >>> M.print_bases() Bases defined on the Rank-4 free module M over the Integer Ring: - (e_1,e_2,e_3,e_4) - (f_1,f_2,f_3,f_4) (default basis) 
 - set_change_of_basis(basis1, basis2, change_of_basis, compute_inverse=True)[source]¶
- Relates two bases by an automorphism of - self.- This updates the internal dictionary - self._basis_changes.- INPUT: - basis1– basis 1, denoted \((e_i)\) below
- basis2– basis 2, denoted \((f_i)\) below
- change_of_basis– instance of class- FreeModuleAutomorphismdescribing the automorphism \(P\) that relates the basis \((e_i)\) to the basis \((f_i)\) according to \(f_i = P(e_i)\)
- compute_inverse– boolean (default:- True); if set to- True, the inverse automorphism is computed and the change from basis \((f_i)\) to \((e_i)\) is set to it in the internal dictionary- self._basis_changes
 - EXAMPLES: - Defining a change of basis on a rank-2 free module: - sage: M = FiniteRankFreeModule(QQ, 2, name='M') sage: e = M.basis('e') sage: f = M.basis('f') sage: a = M.automorphism() sage: a[:] = [[1, 2], [-1, 3]] sage: M.set_change_of_basis(e, f, a) - >>> from sage.all import * >>> M = FiniteRankFreeModule(QQ, Integer(2), name='M') >>> e = M.basis('e') >>> f = M.basis('f') >>> a = M.automorphism() >>> a[:] = [[Integer(1), Integer(2)], [-Integer(1), Integer(3)]] >>> M.set_change_of_basis(e, f, a) - The change of basis and its inverse have been recorded: - sage: M.change_of_basis(e,f).matrix(e) [ 1 2] [-1 3] sage: M.change_of_basis(f,e).matrix(e) [ 3/5 -2/5] [ 1/5 1/5] - >>> from sage.all import * >>> M.change_of_basis(e,f).matrix(e) [ 1 2] [-1 3] >>> M.change_of_basis(f,e).matrix(e) [ 3/5 -2/5] [ 1/5 1/5] - and are effective: - sage: f[0].display(e) f_0 = e_0 - e_1 sage: e[0].display(f) e_0 = 3/5 f_0 + 1/5 f_1 - >>> from sage.all import * >>> f[Integer(0)].display(e) f_0 = e_0 - e_1 >>> e[Integer(0)].display(f) e_0 = 3/5 f_0 + 1/5 f_1 
 - set_default_basis(basis)[source]¶
- Set the default basis of - self.- The default basis is simply a basis whose name can be skipped in methods requiring a basis as an argument. By default, it is the first basis introduced on the module. - INPUT: - basis– instance of- FreeModuleBasisrepresenting a basis on- self
 - EXAMPLES: - Changing the default basis on a rank-3 free module: - sage: M = FiniteRankFreeModule(ZZ, 3, name='M', start_index=1) sage: e = M.basis('e') ; e Basis (e_1,e_2,e_3) on the Rank-3 free module M over the Integer Ring sage: f = M.basis('f') ; f Basis (f_1,f_2,f_3) on the Rank-3 free module M over the Integer Ring sage: M.default_basis() Basis (e_1,e_2,e_3) on the Rank-3 free module M over the Integer Ring sage: M.set_default_basis(f) sage: M.default_basis() Basis (f_1,f_2,f_3) on the Rank-3 free module M over the Integer Ring - >>> from sage.all import * >>> M = FiniteRankFreeModule(ZZ, Integer(3), name='M', start_index=Integer(1)) >>> e = M.basis('e') ; e Basis (e_1,e_2,e_3) on the Rank-3 free module M over the Integer Ring >>> f = M.basis('f') ; f Basis (f_1,f_2,f_3) on the Rank-3 free module M over the Integer Ring >>> M.default_basis() Basis (e_1,e_2,e_3) on the Rank-3 free module M over the Integer Ring >>> M.set_default_basis(f) >>> M.default_basis() Basis (f_1,f_2,f_3) on the Rank-3 free module M over the Integer Ring 
 - sym_bilinear_form(name=None, latex_name=None)[source]¶
- Construct a symmetric bilinear form on the free module - self.- INPUT: - name– (default:- None) string; name given to the symmetric bilinear form
- latex_name– (default:- None) string; LaTeX symbol to denote the symmetric bilinear form; if none is provided, the LaTeX symbol is set to- name
 - OUTPUT: - instance of - FreeModuleTensorof tensor type \((0,2)\) and symmetric
 - EXAMPLES: - Symmetric bilinear form on a rank-3 free module: - sage: M = FiniteRankFreeModule(ZZ, 3, name='M') sage: a = M.sym_bilinear_form('A') ; a Symmetric bilinear form A on the Rank-3 free module M over the Integer Ring - >>> from sage.all import * >>> M = FiniteRankFreeModule(ZZ, Integer(3), name='M') >>> a = M.sym_bilinear_form('A') ; a Symmetric bilinear form A on the Rank-3 free module M over the Integer Ring - A symmetric bilinear form is a type-\((0,2)\) tensor that is symmetric: - sage: a.parent() Free module of type-(0,2) tensors on the Rank-3 free module M over the Integer Ring sage: a.tensor_type() (0, 2) sage: a.tensor_rank() 2 sage: a.symmetries() symmetry: (0, 1); no antisymmetry - >>> from sage.all import * >>> a.parent() Free module of type-(0,2) tensors on the Rank-3 free module M over the Integer Ring >>> a.tensor_type() (0, 2) >>> a.tensor_rank() 2 >>> a.symmetries() symmetry: (0, 1); no antisymmetry - Components with respect to a given basis: - sage: e = M.basis('e') sage: a[0,0], a[0,1], a[0,2] = 1, 2, 3 sage: a[1,1], a[1,2] = 4, 5 sage: a[2,2] = 6 - >>> from sage.all import * >>> e = M.basis('e') >>> a[Integer(0),Integer(0)], a[Integer(0),Integer(1)], a[Integer(0),Integer(2)] = Integer(1), Integer(2), Integer(3) >>> a[Integer(1),Integer(1)], a[Integer(1),Integer(2)] = Integer(4), Integer(5) >>> a[Integer(2),Integer(2)] = Integer(6) - Only independent components have been set; the other ones are deduced by symmetry: - sage: a[1,0], a[2,0], a[2,1] (2, 3, 5) sage: a[:] [1 2 3] [2 4 5] [3 5 6] - >>> from sage.all import * >>> a[Integer(1),Integer(0)], a[Integer(2),Integer(0)], a[Integer(2),Integer(1)] (2, 3, 5) >>> a[:] [1 2 3] [2 4 5] [3 5 6] - A symmetric bilinear form acts on pairs of module elements: - sage: u = M([2,-1,3]) ; v = M([-2,4,1]) sage: a(u,v) 61 sage: a(v,u) == a(u,v) True - >>> from sage.all import * >>> u = M([Integer(2),-Integer(1),Integer(3)]) ; v = M([-Integer(2),Integer(4),Integer(1)]) >>> a(u,v) 61 >>> a(v,u) == a(u,v) True - The sum of two symmetric bilinear forms is another symmetric bilinear form: - sage: b = M.sym_bilinear_form('B') sage: b[0,0], b[0,1], b[1,2] = -2, 1, -3 sage: s = a + b ; s Symmetric bilinear form A+B on the Rank-3 free module M over the Integer Ring sage: a[:], b[:], s[:] ( [1 2 3] [-2 1 0] [-1 3 3] [2 4 5] [ 1 0 -3] [ 3 4 2] [3 5 6], [ 0 -3 0], [ 3 2 6] ) - >>> from sage.all import * >>> b = M.sym_bilinear_form('B') >>> b[Integer(0),Integer(0)], b[Integer(0),Integer(1)], b[Integer(1),Integer(2)] = -Integer(2), Integer(1), -Integer(3) >>> s = a + b ; s Symmetric bilinear form A+B on the Rank-3 free module M over the Integer Ring >>> a[:], b[:], s[:] ( [1 2 3] [-2 1 0] [-1 3 3] [2 4 5] [ 1 0 -3] [ 3 4 2] [3 5 6], [ 0 -3 0], [ 3 2 6] ) - Adding a symmetric bilinear from with a non-symmetric one results in a generic type-\((0,2)\) tensor: - sage: c = M.tensor((0,2), name='C') sage: c[0,1] = 4 sage: s = a + c ; s Type-(0,2) tensor A+C on the Rank-3 free module M over the Integer Ring sage: s.symmetries() no symmetry; no antisymmetry sage: s[:] [1 6 3] [2 4 5] [3 5 6] - >>> from sage.all import * >>> c = M.tensor((Integer(0),Integer(2)), name='C') >>> c[Integer(0),Integer(1)] = Integer(4) >>> s = a + c ; s Type-(0,2) tensor A+C on the Rank-3 free module M over the Integer Ring >>> s.symmetries() no symmetry; no antisymmetry >>> s[:] [1 6 3] [2 4 5] [3 5 6] - See - FreeModuleTensorfor more documentation.
 - symmetric_power(p)[source]¶
- Return the \(p\)-th symmetric power of - self.- EXAMPLES: - Symmetric powers of a free \(\ZZ\)-module of rank 3: - sage: M = FiniteRankFreeModule(ZZ, 3, name='M') sage: e = M.basis('e') sage: M.symmetric_power(0) Free module of type-(0,0) tensors on the Rank-3 free module M over the Integer Ring sage: M.symmetric_power(1) # return the module itself Rank-3 free module M over the Integer Ring sage: M.symmetric_power(1) is M True sage: M.symmetric_power(2) Free module of fully symmetric type-(2,0) tensors on the Rank-3 free module M over the Integer Ring sage: M.symmetric_power(2).an_element() Type-(2,0) tensor on the Rank-3 free module M over the Integer Ring sage: M.symmetric_power(2).an_element().display() e_0⊗e_0 sage: M.symmetric_power(3) Free module of fully symmetric type-(3,0) tensors on the Rank-3 free module M over the Integer Ring sage: M.symmetric_power(3).an_element() Type-(3,0) tensor on the Rank-3 free module M over the Integer Ring sage: M.symmetric_power(3).an_element().display() e_0⊗e_0⊗e_0 - >>> from sage.all import * >>> M = FiniteRankFreeModule(ZZ, Integer(3), name='M') >>> e = M.basis('e') >>> M.symmetric_power(Integer(0)) Free module of type-(0,0) tensors on the Rank-3 free module M over the Integer Ring >>> M.symmetric_power(Integer(1)) # return the module itself Rank-3 free module M over the Integer Ring >>> M.symmetric_power(Integer(1)) is M True >>> M.symmetric_power(Integer(2)) Free module of fully symmetric type-(2,0) tensors on the Rank-3 free module M over the Integer Ring >>> M.symmetric_power(Integer(2)).an_element() Type-(2,0) tensor on the Rank-3 free module M over the Integer Ring >>> M.symmetric_power(Integer(2)).an_element().display() e_0⊗e_0 >>> M.symmetric_power(Integer(3)) Free module of fully symmetric type-(3,0) tensors on the Rank-3 free module M over the Integer Ring >>> M.symmetric_power(Integer(3)).an_element() Type-(3,0) tensor on the Rank-3 free module M over the Integer Ring >>> M.symmetric_power(Integer(3)).an_element().display() e_0⊗e_0⊗e_0 
 - tensor(*args, **kwds)[source]¶
- Construct a tensor on the free module - selfor a tensor product with other modules.- If - argsconsist of other parents, just delegate to- tensor_product().- Otherwise, construct a tensor from the following input. - INPUT: - tensor_type– pair- (k, l)with- kbeing the contravariant rank and- lthe covariant rank
- name– (default:- None) string; name given to the tensor
- latex_name– (default:- None) string; LaTeX symbol to denote the tensor; if none is provided, the LaTeX symbol is set to- name
- sym– (default:- None) a symmetry or an iterable of symmetries among the tensor arguments: each symmetry is described by a tuple containing the positions of the involved arguments, with the convention- position = 0for the first argument. For instance:- sym = (0,1)for a symmetry between the 1st and 2nd arguments
- sym = [(0,2), (1,3,4)]for a symmetry between the 1st and 3rd arguments and a symmetry between the 2nd, 4th and 5th arguments.
 
- antisym– (default:- None) antisymmetry or iterable of antisymmetries among the arguments, with the same convention as for- sym
 - OUTPUT: - instance of - FreeModuleTensorrepresenting the tensor defined on- selfwith the provided characteristics
 - EXAMPLES: - Tensors on a rank-3 free module: - sage: M = FiniteRankFreeModule(ZZ, 3, name='M') sage: t = M.tensor((1,0), name='t') ; t Element t of the Rank-3 free module M over the Integer Ring sage: t = M.tensor((0,1), name='t') ; t Linear form t on the Rank-3 free module M over the Integer Ring sage: t = M.tensor((1,1), name='t') ; t Type-(1,1) tensor t on the Rank-3 free module M over the Integer Ring sage: t = M.tensor((0,2), name='t', sym=(0,1)) ; t Symmetric bilinear form t on the Rank-3 free module M over the Integer Ring sage: t = M.tensor((0,2), name='t', antisym=(0,1)) ; t Alternating form t of degree 2 on the Rank-3 free module M over the Integer Ring sage: t = M.tensor((1,2), name='t') ; t Type-(1,2) tensor t on the Rank-3 free module M over the Integer Ring - >>> from sage.all import * >>> M = FiniteRankFreeModule(ZZ, Integer(3), name='M') >>> t = M.tensor((Integer(1),Integer(0)), name='t') ; t Element t of the Rank-3 free module M over the Integer Ring >>> t = M.tensor((Integer(0),Integer(1)), name='t') ; t Linear form t on the Rank-3 free module M over the Integer Ring >>> t = M.tensor((Integer(1),Integer(1)), name='t') ; t Type-(1,1) tensor t on the Rank-3 free module M over the Integer Ring >>> t = M.tensor((Integer(0),Integer(2)), name='t', sym=(Integer(0),Integer(1))) ; t Symmetric bilinear form t on the Rank-3 free module M over the Integer Ring >>> t = M.tensor((Integer(0),Integer(2)), name='t', antisym=(Integer(0),Integer(1))) ; t Alternating form t of degree 2 on the Rank-3 free module M over the Integer Ring >>> t = M.tensor((Integer(1),Integer(2)), name='t') ; t Type-(1,2) tensor t on the Rank-3 free module M over the Integer Ring - See - FreeModuleTensorfor more examples and documentation.
 - tensor_from_comp(tensor_type, comp, name=None, latex_name=None)[source]¶
- Construct a tensor on - selffrom a set of components.- The tensor symmetries are deduced from those of the components. - INPUT: - tensor_type– pair- (k, l)with- kbeing the contravariant rank and- lthe covariant rank
- comp– instance of- Componentsrepresenting the tensor components in a given basis
- name– (default:- None) string; name given to the tensor
- latex_name– (default:- None) string; LaTeX symbol to denote the tensor; if none is provided, the LaTeX symbol is set to- name
 - OUTPUT: - instance of - FreeModuleTensorrepresenting the tensor defined on- selfwith the provided characteristics.
 - EXAMPLES: - Construction of a tensor of rank 1: - sage: from sage.tensor.modules.comp import Components, CompWithSym, CompFullySym, CompFullyAntiSym 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: c = Components(ZZ, e, 1) sage: c[:] [0, 0, 0] sage: c[:] = [-1,4,2] sage: t = M.tensor_from_comp((1,0), c) sage: t Element of the Rank-3 free module M over the Integer Ring sage: t.display(e) -e_0 + 4 e_1 + 2 e_2 sage: t = M.tensor_from_comp((0,1), c) ; t Linear form on the Rank-3 free module M over the Integer Ring sage: t.display(e) -e^0 + 4 e^1 + 2 e^2 - >>> from sage.all import * >>> from sage.tensor.modules.comp import Components, CompWithSym, CompFullySym, CompFullyAntiSym >>> 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 >>> c = Components(ZZ, e, Integer(1)) >>> c[:] [0, 0, 0] >>> c[:] = [-Integer(1),Integer(4),Integer(2)] >>> t = M.tensor_from_comp((Integer(1),Integer(0)), c) >>> t Element of the Rank-3 free module M over the Integer Ring >>> t.display(e) -e_0 + 4 e_1 + 2 e_2 >>> t = M.tensor_from_comp((Integer(0),Integer(1)), c) ; t Linear form on the Rank-3 free module M over the Integer Ring >>> t.display(e) -e^0 + 4 e^1 + 2 e^2 - Construction of a tensor of rank 2: - sage: c = CompFullySym(ZZ, e, 2) sage: c[0,0], c[1,2] = 4, 5 sage: t = M.tensor_from_comp((0,2), c) ; t Symmetric bilinear form on the Rank-3 free module M over the Integer Ring sage: t.symmetries() symmetry: (0, 1); no antisymmetry sage: t.display(e) 4 e^0⊗e^0 + 5 e^1⊗e^2 + 5 e^2⊗e^1 sage: c = CompFullyAntiSym(ZZ, e, 2) sage: c[0,1], c[1,2] = 4, 5 sage: t = M.tensor_from_comp((0,2), c) ; t Alternating form of degree 2 on the Rank-3 free module M over the Integer Ring sage: t.display(e) 4 e^0∧e^1 + 5 e^1∧e^2 - >>> from sage.all import * >>> c = CompFullySym(ZZ, e, Integer(2)) >>> c[Integer(0),Integer(0)], c[Integer(1),Integer(2)] = Integer(4), Integer(5) >>> t = M.tensor_from_comp((Integer(0),Integer(2)), c) ; t Symmetric bilinear form on the Rank-3 free module M over the Integer Ring >>> t.symmetries() symmetry: (0, 1); no antisymmetry >>> t.display(e) 4 e^0⊗e^0 + 5 e^1⊗e^2 + 5 e^2⊗e^1 >>> c = CompFullyAntiSym(ZZ, e, Integer(2)) >>> c[Integer(0),Integer(1)], c[Integer(1),Integer(2)] = Integer(4), Integer(5) >>> t = M.tensor_from_comp((Integer(0),Integer(2)), c) ; t Alternating form of degree 2 on the Rank-3 free module M over the Integer Ring >>> t.display(e) 4 e^0∧e^1 + 5 e^1∧e^2 
 - tensor_module(k, l, sym, antisym)[source]¶
- Return the free module of all tensors of type \((k, l)\) defined on - self.- INPUT: - k– nonnegative integer; the contravariant rank, the tensor type being \((k, l)\)
- l– nonnegative integer; the covariant rank, the tensor type being \((k, l)\)
- sym– (default:- None) a symmetry or a list of symmetries among the tensor arguments: each symmetry is described by a tuple containing the positions of the involved arguments, with the convention- position = 0for the first argument. For instance:- sym = (0,1)for a symmetry between the 1st and 2nd arguments
- sym = [(0,2), (1,3,4)]for a symmetry between the 1st and 3rd arguments and a symmetry between the 2nd, 4th and 5th arguments.
 
- antisym– (default:- None) antisymmetry or list of antisymmetries among the arguments, with the same convention as for- sym
 - OUTPUT: - instance of - TensorFreeModulerepresenting the free module \(T^{(k,l)}(M)\) of type-\((k,l)\) tensors on the free module- self
 - EXAMPLES: - Tensor modules over a free module over \(\ZZ\): - sage: M = FiniteRankFreeModule(ZZ, 3, name='M') 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: T.an_element() Type-(1,2) tensor on the Rank-3 free module M over the Integer Ring - >>> from sage.all import * >>> M = FiniteRankFreeModule(ZZ, Integer(3), name='M') >>> 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 >>> T.an_element() Type-(1,2) tensor on the Rank-3 free module M over the Integer Ring - Tensor modules are unique: - sage: M.tensor_module(1,2) is T True - >>> from sage.all import * >>> M.tensor_module(Integer(1),Integer(2)) is T True - The module of type-\((1,0)\) tensors is the base module itself: - sage: M.tensor_module(1,0) is M True - >>> from sage.all import * >>> M.tensor_module(Integer(1),Integer(0)) is M True - while the module of type-\((0,1)\) tensors is the dual of the base module: - sage: M.tensor_module(0, 1) is M.dual() True - >>> from sage.all import * >>> M.tensor_module(Integer(0), Integer(1)) is M.dual() True - By using the arguments - symand- antisym, submodules of a full tensor module can be constructed:- sage: T = M.tensor_module(4, 4, sym=((0, 1)), antisym=((4, 5))); T Free module of type-(4,4) tensors on the Rank-3 free module M over the Integer Ring, with symmetry on the index positions (0, 1), with antisymmetry on the index positions (4, 5) sage: T._name 'T^{2,3}(M)⊗T^{6,7}(M*)⊗Sym^{0,1}(M)⊗ASym^{4,5}(M*)' sage: latex(T) T^{\{2,3\}}(M) \otimes T^{\{6,7\}}(M^*) \otimes \mathrm{Sym}^{\{0,1\}}(M) \otimes \mathrm{ASym}^{\{4,5\}}(M^*) - >>> from sage.all import * >>> T = M.tensor_module(Integer(4), Integer(4), sym=((Integer(0), Integer(1))), antisym=((Integer(4), Integer(5)))); T Free module of type-(4,4) tensors on the Rank-3 free module M over the Integer Ring, with symmetry on the index positions (0, 1), with antisymmetry on the index positions (4, 5) >>> T._name 'T^{2,3}(M)⊗T^{6,7}(M*)⊗Sym^{0,1}(M)⊗ASym^{4,5}(M*)' >>> latex(T) T^{\{2,3\}}(M) \otimes T^{\{6,7\}}(M^*) \otimes \mathrm{Sym}^{\{0,1\}}(M) \otimes \mathrm{ASym}^{\{4,5\}}(M^*) - See - TensorFreeModuleand- TensorFreeSubmodule_symfor more documentation.
 
- class sage.tensor.modules.finite_rank_free_module.FiniteRankFreeModule_abstract(ring, rank, name=None, latex_name=None, category=None, ambient=None)[source]¶
- Bases: - UniqueRepresentation,- ReflexiveModule_abstract- Abstract base class for free modules of finite rank over a commutative ring. - ambient()[source]¶
- Return the ambient module associated to this module. - EXAMPLES: - sage: M = FiniteRankFreeModule(ZZ, 3, name='M') sage: M.ambient_module() is M True sage: M = FiniteRankFreeModule(ZZ, 3, name='M') sage: Sym0123x45M = M.tensor_module(6, 0, sym=((0, 1, 2, 3), (4, 5))) sage: T60M = M.tensor_module(6, 0) sage: Sym0123x45M.ambient_module() is T60M True - >>> from sage.all import * >>> M = FiniteRankFreeModule(ZZ, Integer(3), name='M') >>> M.ambient_module() is M True >>> M = FiniteRankFreeModule(ZZ, Integer(3), name='M') >>> Sym0123x45M = M.tensor_module(Integer(6), Integer(0), sym=((Integer(0), Integer(1), Integer(2), Integer(3)), (Integer(4), Integer(5)))) >>> T60M = M.tensor_module(Integer(6), Integer(0)) >>> Sym0123x45M.ambient_module() is T60M True 
 - ambient_module()[source]¶
- Return the ambient module associated to this module. - EXAMPLES: - sage: M = FiniteRankFreeModule(ZZ, 3, name='M') sage: M.ambient_module() is M True sage: M = FiniteRankFreeModule(ZZ, 3, name='M') sage: Sym0123x45M = M.tensor_module(6, 0, sym=((0, 1, 2, 3), (4, 5))) sage: T60M = M.tensor_module(6, 0) sage: Sym0123x45M.ambient_module() is T60M True - >>> from sage.all import * >>> M = FiniteRankFreeModule(ZZ, Integer(3), name='M') >>> M.ambient_module() is M True >>> M = FiniteRankFreeModule(ZZ, Integer(3), name='M') >>> Sym0123x45M = M.tensor_module(Integer(6), Integer(0), sym=((Integer(0), Integer(1), Integer(2), Integer(3)), (Integer(4), Integer(5)))) >>> T60M = M.tensor_module(Integer(6), Integer(0)) >>> Sym0123x45M.ambient_module() is T60M True 
 - is_submodule(other)[source]¶
- Return - Trueif- selfis a submodule of- other.- EXAMPLES: - sage: M = FiniteRankFreeModule(ZZ, 3, name='M') sage: N = FiniteRankFreeModule(ZZ, 4, name='N') sage: M.is_submodule(M) True sage: M.is_submodule(N) False - >>> from sage.all import * >>> M = FiniteRankFreeModule(ZZ, Integer(3), name='M') >>> N = FiniteRankFreeModule(ZZ, Integer(4), name='N') >>> M.is_submodule(M) True >>> M.is_submodule(N) False 
 - isomorphism_with_fixed_basis(basis=None, codomain=None)[source]¶
- Construct the canonical isomorphism from the free module - selfto a free module in which- basisof- selfis mapped to the distinguished basis of- codomain.- INPUT: - basis– (default:- None) the basis of- selfwhich should be mapped to the distinguished basis on- codomain; if- None, the default basis is assumed.
- codomain– (default:- None) the codomain of the isomorphism represented by a free module within the category- ModulesWithBasiswith the same rank and base ring as- self; if- None, a free module represented by- CombinatorialFreeModuleis constructed
 - OUTPUT: - a module isomorphism represented by - SetIsomorphism
 - EXAMPLES: - sage: V = FiniteRankFreeModule(QQ, 3, start_index=1); V 3-dimensional vector space over the Rational Field sage: basis = e = V.basis("e"); basis Basis (e_1,e_2,e_3) on the 3-dimensional vector space over the Rational Field sage: phi_e = V.isomorphism_with_fixed_basis(basis); phi_e Generic morphism: From: 3-dimensional vector space over the Rational Field To: Free module generated by {1, 2, 3} over Rational Field sage: phi_e.codomain().category() Category of finite dimensional vector spaces with basis over Rational Field sage: phi_e(e[1] + 2 * e[2]) e[1] + 2*e[2] sage: abc = V.basis(['a', 'b', 'c'], symbol_dual=['d', 'e', 'f']); abc Basis (a,b,c) on the 3-dimensional vector space over the Rational Field sage: phi_abc = V.isomorphism_with_fixed_basis(abc); phi_abc Generic morphism: From: 3-dimensional vector space over the Rational Field To: Free module generated by {1, 2, 3} over Rational Field sage: phi_abc(abc[1] + 2 * abc[2]) B[1] + 2*B[2] - >>> from sage.all import * >>> V = FiniteRankFreeModule(QQ, Integer(3), start_index=Integer(1)); V 3-dimensional vector space over the Rational Field >>> basis = e = V.basis("e"); basis Basis (e_1,e_2,e_3) on the 3-dimensional vector space over the Rational Field >>> phi_e = V.isomorphism_with_fixed_basis(basis); phi_e Generic morphism: From: 3-dimensional vector space over the Rational Field To: Free module generated by {1, 2, 3} over Rational Field >>> phi_e.codomain().category() Category of finite dimensional vector spaces with basis over Rational Field >>> phi_e(e[Integer(1)] + Integer(2) * e[Integer(2)]) e[1] + 2*e[2] >>> abc = V.basis(['a', 'b', 'c'], symbol_dual=['d', 'e', 'f']); abc Basis (a,b,c) on the 3-dimensional vector space over the Rational Field >>> phi_abc = V.isomorphism_with_fixed_basis(abc); phi_abc Generic morphism: From: 3-dimensional vector space over the Rational Field To: Free module generated by {1, 2, 3} over Rational Field >>> phi_abc(abc[Integer(1)] + Integer(2) * abc[Integer(2)]) B[1] + 2*B[2] - Providing a codomain: - sage: W = CombinatorialFreeModule(QQ, ['a', 'b', 'c']) sage: phi_eW = V.isomorphism_with_fixed_basis(basis, codomain=W); phi_eW Generic morphism: From: 3-dimensional vector space over the Rational Field To: Free module generated by {'a', 'b', 'c'} over Rational Field sage: phi_eW(e[1] + 2 * e[2]) B['a'] + 2*B['b'] sage: ~phi_eW Generic morphism: From: Free module generated by {'a', 'b', 'c'} over Rational Field To: 3-dimensional vector space over the Rational Field sage: (~phi_eW)(W.basis()['b']).display() e_2 - >>> from sage.all import * >>> W = CombinatorialFreeModule(QQ, ['a', 'b', 'c']) >>> phi_eW = V.isomorphism_with_fixed_basis(basis, codomain=W); phi_eW Generic morphism: From: 3-dimensional vector space over the Rational Field To: Free module generated by {'a', 'b', 'c'} over Rational Field >>> phi_eW(e[Integer(1)] + Integer(2) * e[Integer(2)]) B['a'] + 2*B['b'] >>> ~phi_eW Generic morphism: From: Free module generated by {'a', 'b', 'c'} over Rational Field To: 3-dimensional vector space over the Rational Field >>> (~phi_eW)(W.basis()['b']).display() e_2 - Providing a - Module_free_ambientas the codomain:- sage: W = QQ^3 sage: phi_eW = V.isomorphism_with_fixed_basis(basis, codomain=W); phi_eW Generic morphism: From: 3-dimensional vector space over the Rational Field To: Vector space of dimension 3 over Rational Field sage: phi_eW(e[1] + 2 * e[2]) (1, 2, 0) - >>> from sage.all import * >>> W = QQ**Integer(3) >>> phi_eW = V.isomorphism_with_fixed_basis(basis, codomain=W); phi_eW Generic morphism: From: 3-dimensional vector space over the Rational Field To: Vector space of dimension 3 over Rational Field >>> phi_eW(e[Integer(1)] + Integer(2) * e[Integer(2)]) (1, 2, 0) - Sending (1,1)-tensors to matrices: - sage: T11 = V.tensor_module(1, 1); T11 Free module of type-(1,1) tensors on the 3-dimensional vector space over the Rational Field sage: e_T11 = T11.basis("e"); e_T11 Standard basis on the Free module of type-(1,1) tensors on the 3-dimensional vector space over the Rational Field induced by Basis (e_1,e_2,e_3) on the 3-dimensional vector space over the Rational Field sage: W = MatrixSpace(QQ, 3) sage: phi_e_T11 = T11.isomorphism_with_fixed_basis(e_T11, codomain=W); phi_e_T11 Generic morphism: From: Free module of type-(1,1) tensors on the 3-dimensional vector space over the Rational Field To: Full MatrixSpace of 3 by 3 dense matrices over Rational Field sage: t = T11.an_element(); t.display() 1/2 e_1⊗e^1 sage: phi_e_T11(t) [1/2 0 0] [ 0 0 0] [ 0 0 0] sage: ~phi_e_T11 Generic morphism: From: Full MatrixSpace of 3 by 3 dense matrices over Rational Field To: Free module of type-(1,1) tensors on the 3-dimensional vector space over the Rational Field sage: (~phi_e_T11)(W([[0, 1/2, 1/3], ....: [-1/2, 0, 0], ....: [-1/3, 0, 0]])).display() 1/2 e_1⊗e^2 + 1/3 e_1⊗e^3 - 1/2 e_2⊗e^1 - 1/3 e_3⊗e^1 - >>> from sage.all import * >>> T11 = V.tensor_module(Integer(1), Integer(1)); T11 Free module of type-(1,1) tensors on the 3-dimensional vector space over the Rational Field >>> e_T11 = T11.basis("e"); e_T11 Standard basis on the Free module of type-(1,1) tensors on the 3-dimensional vector space over the Rational Field induced by Basis (e_1,e_2,e_3) on the 3-dimensional vector space over the Rational Field >>> W = MatrixSpace(QQ, Integer(3)) >>> phi_e_T11 = T11.isomorphism_with_fixed_basis(e_T11, codomain=W); phi_e_T11 Generic morphism: From: Free module of type-(1,1) tensors on the 3-dimensional vector space over the Rational Field To: Full MatrixSpace of 3 by 3 dense matrices over Rational Field >>> t = T11.an_element(); t.display() 1/2 e_1⊗e^1 >>> phi_e_T11(t) [1/2 0 0] [ 0 0 0] [ 0 0 0] >>> ~phi_e_T11 Generic morphism: From: Full MatrixSpace of 3 by 3 dense matrices over Rational Field To: Free module of type-(1,1) tensors on the 3-dimensional vector space over the Rational Field >>> (~phi_e_T11)(W([[Integer(0), Integer(1)/Integer(2), Integer(1)/Integer(3)], ... [-Integer(1)/Integer(2), Integer(0), Integer(0)], ... [-Integer(1)/Integer(3), Integer(0), Integer(0)]])).display() 1/2 e_1⊗e^2 + 1/3 e_1⊗e^3 - 1/2 e_2⊗e^1 - 1/3 e_3⊗e^1 - Sending symmetric bilinear forms to matrices (note that they are currently elements of \(T^{(0,2)}(M)\), not the symmetric power of \(M\)): - sage: T02 = V.tensor_module(0, 2); T02 Free module of type-(0,2) tensors on the 3-dimensional vector space over the Rational Field sage: e_T02 = T02.basis("e"); e_T02 Standard basis on the Free module of type-(0,2) tensors on the 3-dimensional vector space over the Rational Field induced by Basis (e_1,e_2,e_3) on the 3-dimensional vector space over the Rational Field sage: W = MatrixSpace(QQ, 3) sage: phi_e_T02 = T02.isomorphism_with_fixed_basis(e_T02, codomain=W); phi_e_T02 Generic morphism: From: Free module of type-(0,2) tensors on the 3-dimensional vector space over the Rational Field To: Full MatrixSpace of 3 by 3 dense matrices over Rational Field sage: a = V.sym_bilinear_form() sage: a[1,1], a[1,2], a[1,3] = 1, 2, 3 sage: a[2,2], a[2,3] = 4, 5 sage: a[3,3] = 6 sage: a.display() e^1⊗e^1 + 2 e^1⊗e^2 + 3 e^1⊗e^3 + 2 e^2⊗e^1 + 4 e^2⊗e^2 + 5 e^2⊗e^3 + 3 e^3⊗e^1 + 5 e^3⊗e^2 + 6 e^3⊗e^3 sage: phi_e_T02(a) [1 2 3] [2 4 5] [3 5 6] - >>> from sage.all import * >>> T02 = V.tensor_module(Integer(0), Integer(2)); T02 Free module of type-(0,2) tensors on the 3-dimensional vector space over the Rational Field >>> e_T02 = T02.basis("e"); e_T02 Standard basis on the Free module of type-(0,2) tensors on the 3-dimensional vector space over the Rational Field induced by Basis (e_1,e_2,e_3) on the 3-dimensional vector space over the Rational Field >>> W = MatrixSpace(QQ, Integer(3)) >>> phi_e_T02 = T02.isomorphism_with_fixed_basis(e_T02, codomain=W); phi_e_T02 Generic morphism: From: Free module of type-(0,2) tensors on the 3-dimensional vector space over the Rational Field To: Full MatrixSpace of 3 by 3 dense matrices over Rational Field >>> a = V.sym_bilinear_form() >>> a[Integer(1),Integer(1)], a[Integer(1),Integer(2)], a[Integer(1),Integer(3)] = Integer(1), Integer(2), Integer(3) >>> a[Integer(2),Integer(2)], a[Integer(2),Integer(3)] = Integer(4), Integer(5) >>> a[Integer(3),Integer(3)] = Integer(6) >>> a.display() e^1⊗e^1 + 2 e^1⊗e^2 + 3 e^1⊗e^3 + 2 e^2⊗e^1 + 4 e^2⊗e^2 + 5 e^2⊗e^3 + 3 e^3⊗e^1 + 5 e^3⊗e^2 + 6 e^3⊗e^3 >>> phi_e_T02(a) [1 2 3] [2 4 5] [3 5 6] - Same but explicitly in the subspace of symmetric bilinear forms: - sage: Sym2Vdual = V.dual_symmetric_power(2); Sym2Vdual Free module of fully symmetric type-(0,2) tensors on the 3-dimensional vector space over the Rational Field sage: Sym2Vdual.is_submodule(T02) True sage: Sym2Vdual.rank() 6 sage: e_Sym2Vdual = Sym2Vdual.basis("e"); e_Sym2Vdual Standard basis on the Free module of fully symmetric type-(0,2) tensors on the 3-dimensional vector space over the Rational Field induced by Basis (e_1,e_2,e_3) on the 3-dimensional vector space over the Rational Field sage: W_basis = [phi_e_T02(b) for b in e_Sym2Vdual]; W_basis [ [1 0 0] [0 1 0] [0 0 1] [0 0 0] [0 0 0] [0 0 0] [0 0 0] [1 0 0] [0 0 0] [0 1 0] [0 0 1] [0 0 0] [0 0 0], [0 0 0], [1 0 0], [0 0 0], [0 1 0], [0 0 1] ] sage: W = MatrixSpace(QQ, 3).submodule(W_basis); W Free module generated by {0, 1, 2, 3, 4, 5} over Rational Field sage: phi_e_Sym2Vdual = Sym2Vdual.isomorphism_with_fixed_basis(e_Sym2Vdual, ....: codomain=W) sage: phi_e_Sym2Vdual Generic morphism: From: Free module of fully symmetric type-(0,2) tensors on the 3-dimensional vector space over the Rational Field To: Free module generated by {0, 1, 2, 3, 4, 5} over Rational Field - >>> from sage.all import * >>> Sym2Vdual = V.dual_symmetric_power(Integer(2)); Sym2Vdual Free module of fully symmetric type-(0,2) tensors on the 3-dimensional vector space over the Rational Field >>> Sym2Vdual.is_submodule(T02) True >>> Sym2Vdual.rank() 6 >>> e_Sym2Vdual = Sym2Vdual.basis("e"); e_Sym2Vdual Standard basis on the Free module of fully symmetric type-(0,2) tensors on the 3-dimensional vector space over the Rational Field induced by Basis (e_1,e_2,e_3) on the 3-dimensional vector space over the Rational Field >>> W_basis = [phi_e_T02(b) for b in e_Sym2Vdual]; W_basis [ [1 0 0] [0 1 0] [0 0 1] [0 0 0] [0 0 0] [0 0 0] [0 0 0] [1 0 0] [0 0 0] [0 1 0] [0 0 1] [0 0 0] [0 0 0], [0 0 0], [1 0 0], [0 0 0], [0 1 0], [0 0 1] ] >>> W = MatrixSpace(QQ, Integer(3)).submodule(W_basis); W Free module generated by {0, 1, 2, 3, 4, 5} over Rational Field >>> phi_e_Sym2Vdual = Sym2Vdual.isomorphism_with_fixed_basis(e_Sym2Vdual, ... codomain=W) >>> phi_e_Sym2Vdual Generic morphism: From: Free module of fully symmetric type-(0,2) tensors on the 3-dimensional vector space over the Rational Field To: Free module generated by {0, 1, 2, 3, 4, 5} over Rational Field - Sending tensors to elements of the tensor square of - CombinatorialFreeModule:- sage: T20 = V.tensor_module(2, 0); T20 Free module of type-(2,0) tensors on the 3-dimensional vector space over the Rational Field sage: e_T20 = T02.basis("e"); e_T20 Standard basis on the Free module of type-(0,2) tensors on the 3-dimensional vector space over the Rational Field induced by Basis (e_1,e_2,e_3) on the 3-dimensional vector space over the Rational Field sage: W = CombinatorialFreeModule(QQ, [1, 2, 3]).tensor_square(); W Free module generated by {1, 2, 3} over Rational Field # Free module generated by {1, 2, 3} over Rational Field sage: phi_e_T20 = T20.isomorphism_with_fixed_basis(e_T20, codomain=W); phi_e_T20 Generic morphism: From: Free module of type-(2,0) tensors on the 3-dimensional vector space over the Rational Field To: Free module generated by {1, 2, 3} over Rational Field # Free module generated by {1, 2, 3} over Rational Field sage: t = T20.an_element(); t.display() 1/2 e_1⊗e_1 sage: phi_e_T20(t) 1/2*B[1] # B[1] - >>> from sage.all import * >>> T20 = V.tensor_module(Integer(2), Integer(0)); T20 Free module of type-(2,0) tensors on the 3-dimensional vector space over the Rational Field >>> e_T20 = T02.basis("e"); e_T20 Standard basis on the Free module of type-(0,2) tensors on the 3-dimensional vector space over the Rational Field induced by Basis (e_1,e_2,e_3) on the 3-dimensional vector space over the Rational Field >>> W = CombinatorialFreeModule(QQ, [Integer(1), Integer(2), Integer(3)]).tensor_square(); W Free module generated by {1, 2, 3} over Rational Field # Free module generated by {1, 2, 3} over Rational Field >>> phi_e_T20 = T20.isomorphism_with_fixed_basis(e_T20, codomain=W); phi_e_T20 Generic morphism: From: Free module of type-(2,0) tensors on the 3-dimensional vector space over the Rational Field To: Free module generated by {1, 2, 3} over Rational Field # Free module generated by {1, 2, 3} over Rational Field >>> t = T20.an_element(); t.display() 1/2 e_1⊗e_1 >>> phi_e_T20(t) 1/2*B[1] # B[1] 
 - rank()[source]¶
- Return the rank of the free module - self.- Since the ring over which - selfis built is assumed to be commutative (and hence has the invariant basis number property), the rank is defined uniquely, as the cardinality of any basis of- self.- EXAMPLES: - Rank of free modules over \(\ZZ\): - sage: M = FiniteRankFreeModule(ZZ, 3) sage: M.rank() 3 sage: M.tensor_module(0,1).rank() 3 sage: M.tensor_module(0,2).rank() 9 sage: M.tensor_module(1,0).rank() 3 sage: M.tensor_module(1,1).rank() 9 sage: M.tensor_module(1,2).rank() 27 sage: M.tensor_module(2,2).rank() 81 - >>> from sage.all import * >>> M = FiniteRankFreeModule(ZZ, Integer(3)) >>> M.rank() 3 >>> M.tensor_module(Integer(0),Integer(1)).rank() 3 >>> M.tensor_module(Integer(0),Integer(2)).rank() 9 >>> M.tensor_module(Integer(1),Integer(0)).rank() 3 >>> M.tensor_module(Integer(1),Integer(1)).rank() 9 >>> M.tensor_module(Integer(1),Integer(2)).rank() 27 >>> M.tensor_module(Integer(2),Integer(2)).rank() 81 
 - zero()[source]¶
- Return the zero element of - self.- EXAMPLES: - Zero elements of free modules over \(\ZZ\): - sage: M = FiniteRankFreeModule(ZZ, 3, name='M') sage: M.zero() Element zero of the Rank-3 free module M over the Integer Ring sage: M.zero().parent() is M True sage: M.zero() is M(0) True sage: T = M.tensor_module(1,1) sage: T.zero() Type-(1,1) tensor zero on the Rank-3 free module M over the Integer Ring sage: T.zero().parent() is T True sage: T.zero() is T(0) True - >>> from sage.all import * >>> M = FiniteRankFreeModule(ZZ, Integer(3), name='M') >>> M.zero() Element zero of the Rank-3 free module M over the Integer Ring >>> M.zero().parent() is M True >>> M.zero() is M(Integer(0)) True >>> T = M.tensor_module(Integer(1),Integer(1)) >>> T.zero() Type-(1,1) tensor zero on the Rank-3 free module M over the Integer Ring >>> T.zero().parent() is T True >>> T.zero() is T(Integer(0)) True - Components of the zero element with respect to some basis: - sage: e = M.basis('e') sage: M.zero()[e,:] [0, 0, 0] sage: all(M.zero()[e,i] == M.base_ring().zero() for i in M.irange()) True sage: T.zero()[e,:] [0 0 0] [0 0 0] [0 0 0] sage: M.tensor_module(1,2).zero()[e,:] [[[0, 0, 0], [0, 0, 0], [0, 0, 0]], [[0, 0, 0], [0, 0, 0], [0, 0, 0]], [[0, 0, 0], [0, 0, 0], [0, 0, 0]]] - >>> from sage.all import * >>> e = M.basis('e') >>> M.zero()[e,:] [0, 0, 0] >>> all(M.zero()[e,i] == M.base_ring().zero() for i in M.irange()) True >>> T.zero()[e,:] [0 0 0] [0 0 0] [0 0 0] >>> M.tensor_module(Integer(1),Integer(2)).zero()[e,:] [[[0, 0, 0], [0, 0, 0], [0, 0, 0]], [[0, 0, 0], [0, 0, 0], [0, 0, 0]], [[0, 0, 0], [0, 0, 0], [0, 0, 0]]]