This notebook is part of the Introduction to manifolds in SageMath by Andrzej Chrzeszczyk (Jan Kochanowski University of Kielce, Poland).
version()
'SageMath version 9.6, Release Date: 2022-05-15'
If F is a field, a set V is called a vector space over F if there is an operation of addition $\ (x,y) → x+y\ \ $
from V×V to V, and a scalar multiplication operation $\ \ (α,x) → αx\ \ $ from F×V to V, such that the following properties are satisfied.
(i) (u+v) + w = u + (v+w) for all u, v, w ∈ V,
(ii) u+v=v+u for all u, v ∈ V,
(iii) There exists an element 0 ∈ V such that 0+v=v+0 for all v ∈ V,
(iv) For each v ∈ V there exists u ∈ V such that v+u=0,
(v) 1v=v for all v ∈ V,
(vi) $(\alpha\beta)v=\alpha(\beta v)$ for all $\alpha,\beta\in F$ and v∈V,
(vii) $(\alpha+\beta)v=\alpha v+\beta v$ for all $\alpha,\beta\in F$ and v∈V,
(viii) $\alpha(u+v)=\alpha u+\alpha v$ for all $\alpha\in F$
and $u$∈V.
The formal definition of the module M over the ring R is exactly as above (with V replaced by M and F replaced by R) but we relax the requirement that F be a field, and instead allow an arbitrary ring R (with unity). We shall restrict ourselves to the commutative rings R.
A free module of finite rank over a commutative ring R is a module $M$ over R that admits a finite basis, that is a finite family $\{e_1,\ldots,e_k\}$, which spans $M$, i.e., for every $v\in M$, $\ v=\sum_{i=1}^k a_ie_i$ for some $ a_i\in$ R, and $e_i$ are linearly independent i.e., $\sum_{i=1}^k a_ie_i=0$ implies that all $a_i$ are zero.
Since R is commutative, it has the invariant basis number property, so that the rank (dimension) of the free module M is defined uniquely, as the cardinality of any basis of $M$.
Basic motivation for introducing free modules into consideration in SageMath Manifolds is the fact that the sets of vector fields and tensor fields on a parallelizable open subset U of the manifold, are free modules over the ring of scalar fields on U.
Some frequently used commands from SageMath FiniteRankFreeModule
:
an_element endomorphism sym_bilinear_form
automorphism hom tensor
bases irange tensor_from_comp
basis linear_form tensor_module
change_of_basis rank alternating_form
default_basis set_change_of_basis dual_exterior_power
dual set_default_basis exterior_power
In our examples we will use mainly the SageMath symbolic ring SR.
Example 6.1
FiniteRankFreeModule
in SageMath
:
Symbolic ring SR is considered as a field:
SR.is_field() # Symbolic ring is a field
True
so the finite rank free modules over SR are in fact vector spaces:
V = FiniteRankFreeModule(SR,4,name='V') # rank 4 free module V over SR
#V? --detailed explanations concerning FiniteRankFreeModule
V # information on V
4-dimensional vector space V over the Symbolic Ring
Defining V as a finite rank free module over a field we obtain a vector space without predefined basis.
V.bases() # check that V has no predefined basis
[]
Later we shall see that without any specific coordinate choice, no basis can be distinguished in a tangent space. This is one more motivation for using modules in SageMath Manifolds.
Let us check that defining vector space with VectorSpace command, we introduce a predefined basis.
W = VectorSpace(SR,4); W
Vector space of dimension 4 over Symbolic Ring
W.basis()
[ (1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0, 0, 1) ]
In SageMath the VectorSpace of rank 4 over R is in fact R^4 -the Cartesian power of R.
W == SR^4
True
but an analogous FiniteRankFreeModule is not:
V == SR^4
False
Example 6.2
To define a vector in SageMath Manifolds
we need some basis.
%display latex
M = FiniteRankFreeModule(SR, 4, name='M') # module M
e = M.basis('e') # basis of M
# e? -detailed explanations concerning bases
# range(1,5)=[1,2,3,4] --coefficients of the linear combination
u = M(range(1,5),name='u');u.disp() # show vector
Vectors can be defined also as linear combinations of the basis.
al = srange(1,5) # a more flexible version of range
# linear combination of basis:
w = sum([al[k]*e[k] for k in range(4)])
w.disp() # show w
# a more general linear combination of a basis
# \alpha+[Tab] gives the Greek letter alpha
al = var('α',n=4) # α_i, i=1,2,3,4
# linear combination of basis:
w = sum([al[k]*e[k] for k in range(4)])
w.disp() # show w
By the linearity of the map $\Phi:M\to N$ between two modules over $R$ we mean the condition
$$ \Phi (av + bw ) = a\Phi (v) + b\Phi (w ),\quad\text{for}\quad v,w\in M,\quad a,b\in R.$$Automorphism of the module M is a bijective linear transformation M $\to$ M.
An automorphism allows for example for defining a new basis.
If more than one bases are defined, the first one is the default one.
Example 6.3
Let us define a module with two bases and an automorphism defining the change of basis.
%display latex
M = FiniteRankFreeModule(SR, 4, name='M') # 4-dim module over SR
a = M.automorphism() # automorphism of M
# a? --detailed explanations concerning module automorphism
e = M.basis('e') # define default basis
f = M.basis('f') # define second basis
# diagonal matrix with diagonal (4,3,2,1)
a[e,:]=diagonal_matrix(4, srange(4,0,-1)); # matrix of automorphism
M.set_change_of_basis(e, f, a) # define change of basis
u = M(range(1,5),name='u') # define vector
# displaying the vector in non-default basis needs
# the basis name as an argument
u.disp(),'________',u.disp(f) # vector u in bases e and f
M.default_basis() # default basis
Matrix of the automorphism:
a.matrix() # matrix of automorphism a
Example 6.4
The new basis can be also defined component by component.
%display latex
M=FiniteRankFreeModule(SR,4,name='M') # 4-dim module over SR
e = M.basis('e') # basis e
f = M.basis('f', from_family= # new basis f contains lin.comb.
(4*e[0],3*e[1],2*e[2],e[3])) # of elements of e
u = M(range(1,5),name='u'); # vector u
u.disp(),'______',u.disp(f) # u in bases e and f
Matrix of the change of basis e $\to$ f:
M.change_of_basis(e,f).matrix(e) # matrix of change of basis e->f
Matrix of the change of basis f $\to$ e:
M.change_of_basis(f,e).matrix(e) # matrix of change of basis f->e
Endomorphism of the module M is a general linear transformation M $\to$ M.
Example 6.5
Define an endomorphism using arbitrarily chosen matrix.
M = FiniteRankFreeModule(SR,4,name='M') # 4-dim module over SR
e = M.basis('e') # basis e
ma = matrix(4,4,range(16)) # matrix of endomorphism
phi = M.endomorphism(ma, basis=e, # define an endomorphism
name='phi',latex_name=r'\Phi') # Phi
u = M(range(1,5),name='u'); # vector u
phi(u).disp() # Phi(u)
To obtain general $N\times N$ matrices with elements $a_{ij}$ we can use for example the following definition:
aa = [[var('a'+str(i)+str(j)) # 4x4 symbolic matrix is
for j in range(4)] # defined by list of lists
for i in range(4)]
aa # list of lists (list of rows)
General endomorphism of a 4-dimensional module:
M = FiniteRankFreeModule(SR,4,name='M') # 4-dim module M over SR
e = M.basis('e') # basis of M
phi = M.endomorphism(aa, basis=e, # define an endomorphism
name='phi',latex_name=r'\Phi') # using matrix
for k in range(4): # show the values Phi(e_i)
show(phi(e[k]).disp())
# coefficients of phi(e_k) are taken from
# the k-th column of phi matrix
%display latex # matrix of endomorphism
phi.matrix()
The general linear maps between modules M, N are homomorphisms.
A bijective homomorphism is called isomorphism.
Example 6.7
Define two modules and a homomorphism between them.
M = FiniteRankFreeModule(SR,4,name='M') # 4-dim module M over SR
N = FiniteRankFreeModule(SR,2,name='N') # 2-dim module over SR
e = M.basis('e') # basis of M
f = N.basis('f') # basis of N
ma = matrix(2,4,lambda i,j:i+j) # matrix a_ij=i+j
phi = M.hom(N,ma); phi # define homomorphism
# with matrix ma
# mathematical object of which "phi" is an element
phi.parent()
Let us check the additivity property using general vectors V, W.
v = var('v',n=4) #(v0,v1,v2,v3) # components of vector V
w = var('w',n=4) #(w0,w1,w2,w3) # components of vector W
V = M(list(v)) # vector V
W = M(list(w)) # vector W
phi(V+W) == phi(V) + phi(W) # check the additivity
The value of the homomorphism phi on the vector V in the basis of N:
phi(V).disp() # phi(V)
The matrix of the homomorphism phi:
phi.matrix() # matrix of homomorphism
By a linear form or a linear functional on a module $\ M\ $ over $R$ we mean the map $f:M\to R$ such that
$$ f (av + bw ) = af(v) + bf(w ),\quad\text{for}\quad v,w\in M,\quad a,b\in R.$$The dual module $M^*$ is the module of linear forms on a module $M$.
Example 6.8
The module of all linear functionals or linear forms on M in SageMath Manifold
is M.dual()
:
M = FiniteRankFreeModule(SR,4,name='M') # 4-dim module over SR
Mstar = M.dual(); Mstar
# Since SR is a field, M is a vector space
SageMath dual.basis
allows to define a dual basis to a given basis $\ \{e_i\}_{i=1}^n$, i.e., the set of linear functionals $\ \{e^i\}_{i=1}^n\ $ such that $\quad e^i(e_j)=\delta^i_j.$
Example 6.9
Define dual basis in SageMath Manifolds
.
# continuation
e = M.basis('e'); # basis of M
ep = e.dual_basis(); ep # dual basis
Let us check that $\quad e^i(e_j)=\delta^i_j$:
%display latex
matrix(4,4,lambda i,j:ep[i](e[j])) # matrix e^i(e_j)
Linear forms on a module M are linear combinations of elements of the dual basis.
Example 6.10
Define a linear form in SageMath Manifolds
.
# continuation
a = M.linear_form('a') # linear form a on M
a[:] = 1,2,3,4 # define components of a
a.disp() # show a
Linear forms are elements of the dual module $M^*$.
# mathematical object of which "a" is an element
print(a.parent())
Dual of the 4-dimensional vector space M over the Symbolic Ring
Mstar = M.dual()
a.parent() == Mstar # check if parent of a is M dual
Take a look at the notebook Smooth functions and pullbacks.