Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.
Path: blob/master/sage/SageManifolds/SM_tensors_modules.sagews
Views: 1034
Tensors on free modules
A tutorial
This Sage worksheet provides some introduction to tensors on free modules of finite rank. This is a pure algebraic subpart of SageManifolds (version 0.8), which does not depend on other parts of SageManifolds and which has been integrated in Sage 6.6.
This worksheet is released under the GNU General Public License version 2.
(c) Eric Gourgoulhon, Michal Bejger (2015)
The whole worksheet file can be downloaded from here.
Constructing a free module of finite rank
Let be a commutative ring and a free module of finite rank over , i.e. a module over that admits a finite basis (finite family of linearly independent generators). Since is commutative, it has the invariant basis number property: all bases of have the same cardinality, which is called the rank of . In this tutorial, we consider a free module of rank 3 over the integer ring :
The first two arguments are the ring and the rank; the third one is a string to denote the module and the last one defines the range of indices to be used for tensor components on the module: setting it to 1 means that indices will range in . The default value is start_index=0.
The command print returns a short description of the just constructed module:
If we ask just for M, the module's LaTeX symbol is returned (provided that the worksheet's Typeset box has been selected); by default, this is the same as the argument name in the constructor (this can be changed by providing the optional argument latex_name):
The indices of basis elements or tensor components on the module are generated by the method irange(), to be used in loops:
If the parameter start_index had not been specified, the default range of the indices would have been instead:
is the category of modules over :
Self-inquiry commands are
Defining bases on the free module
At construction, the free module has no pre-defined basis:
For this reason, the class FiniteRankFreeModule does not inherit from Sage class CombinatorialFreeModule:
and does not belong to the category of modules with a distinguished basis:
It simply belongs to the category of modules over :
We define a first basis on as follows:
The elements of the basis are accessed via their indices:
Let us introduce a second basis on the free module from a family of 3 linearly independent module elements:
We may ask to view each element of basis in terms of its expansion onto basis , via the method display(), abridged as disp():
Conversely, the expression of basis is terms of basis is
The module automorphism relating the two bases is obtained as
It belongs to the general linear group of the free module :
and its matrix w.r.t. basis is
Let us check that the elements of basis are images of the elements of basis via :
The reverse change of basis is of course the inverse automorphism:
At this stage, two bases have been defined on :
The first defined basis, , is considered as the default basis, which means that it can be skipped in any method argument requirying a basis. For instance, let us consider the method display():
Since is the default basis, the above command is fully equivalent to
Of course, the names of non-default bases have to be specified:
Note that the concept of default basis is different from that of distinguished basis which is implemented in other free module constructions in Sage (e.g. CombinatorialFreeModule): the default basis is intended only for shorthand notations in user commands, avoiding to repeat the basis name many times; it is by no means a privileged basis on the module. For user convenience, the default basis can be changed at any moment by means of the method set_default_basis():
Let us revert to as the default basis:
Module elements
Elements of the free module are constructed by providing their components with respect to a given basis to the operator () acting on the module:
Since is the default basis, its mention can be skipped:
While has been defined from the basis , its expression in terms of the basis can be evaluated, thanks to the known relation between the two bases:
According to Sage terminology, the parent of is of course :
We have also
Let us define a second module element, from the basis this time:
Another way to define module elements is of course via linear combinations:
As the result of a linear combination, has no name; it can be given one by the method set_name() and the LaTeX symbol can be specified if different from the name:
Module operations are implemented, independently of the bases:
The components of a module element with respect to a given basis are given by the method components():
A shortcut is comp():
The function display_comp() provides a list of components w.r.t. to a given basis:
As a shortcut, instead of calling the method comp(), the basis can be provided as the first argument of the square bracket operator:
For the default basis, the basis can be omitted:
A specific module element is the zero one:
Linear forms
Let us introduce some linear form on the free module :
is specified by its components with respect to the basis dual to :
The notation stands for the elements of the basis dual to , i.e. the basis of the dual module such that
Indeed
The linear form can also be defined by its components with respect to the basis dual to :
For consistency, the previously defined components with respect to the basis dual to are automatically deleted and new ones are computed from the change-of-basis formula:
By definition, linear forms belong to the dual module:
The dual module is itself a free module of the same rank as :
Linear forms map module elements to ring elements:
in a linear way:
Alternating forms
Let us introduce a second linear form, , on the free module :
and take its exterior product with the linear form :
is antisymmetric:
and is multilinear:
We may check the standard formula for the exterior product of two linear forms:
In terms of tensor product (denoted here by *), it reads
The parent of the alternating form is the second external power of the dual module , which is denoted by :
is a tensor field of type :
whose components with respect to any basis are antisymmetric:
An alternating form can be constructed from scratch:
Only the non-zero and non-redundant components are to be defined (the others are deduced by antisymmetry); for the components with respect to the default basis, we write:
Then
Internally, only non-redundant components are stored, in a dictionary whose keys are the indices:
The other components are deduced by antisymmetry.
The exterior product of a linear form with an alternating form of degree 2 leads to an alternating form of degree 3:
is antisymmetric:
Tensors
and being non negative integers, a tensor of type on the free module is a multilinear map
$ t: \underbrace{M^*\times\cdots\times M^*}_{k\ \; \mbox{times}}
\times \underbrace{M\times\cdots\times M}_{l\ \; \mbox{times}}
\longrightarrow R $
In the present case the ring is .
For free modules of finite rank, we have the canonical isomorphism , so that the set of all tensors of type can be identified with the tensor product
$ T^{(k,l)}(M) = \underbrace{M\otimes\cdots\otimes M}_{k\ \; \mbox{times}}
\otimes \underbrace{M^*\otimes\cdots\otimes M^*}_{l\ \; \mbox{times}} $
In particular, tensors of type are identified with elements of :
According to the above definition, linear forms are tensors of type (0,1):
Note that, at the Python level, we do not have the identification of with :
This is because and are different objects:
However, we have coercion (automatic conversion) of elements of into elements of :
as well as coercion in the reverse direction:
Arbitrary tensors are constructed via the module method tensor(), by providing the tensor type and possibly the symbol to denote the tensor:
Let us set some component of in the basis , for instance the component :
Since is the default basis, a shortcut for the above is
The unset components are zero:
Components can be set at any time:
The components with respect to the basis are evaluated by the change-of-basis formula :
Another view of , which reflects the fact that , is
Recall that is the basis of that is dual to the basis of .
In term of the basis and its dual basis , we have
As a tensor of type (1,1), maps pairs (linear form, module element) to ring elements:
Tensors of type (1,1) can be considered as endomorphisms, thanks to the isomorphism
In a given basis, the matrix of the endomorphism is identical to the matrix of the tensor :
As an endomorphism, maps module elements to module elements:
belongs to the module :
or, in Sage terminology,
is itself a free module of finite rank over :
Tensor calculus
In addition to the arithmetic operations inherent to the module structure of , the following operations are implemented:
- tensor product
- symmetrization and antisymmetrization
- tensor contraction
Tensor product
The tensor product is formed with the * operator. For instance the tensor product is
The components w.r.t. a given basis can also be displayed as an array:
Each component ca be accessed individually:
The tensor product is not commutative:
Forming a tensor of rank 4:
Symmetrization / antisymmetrization
The (anti)symmetrization of a tensor over arguments involve the division by , which does not always make sense in the base ring . In the present case, and to (anti)symmetrize over 2 arguments, we restrict to tensors with even components:
Symmetrization can be performed on an arbitray number of arguments, by providing their positions (first position = 0). In the present case
One may use index notation to specify the symmetry:
Of course, since is already symmetric:
The antisymmetrization proceeds accordingly:
As for symmetries, index notation can be used, instead of antisymmetrize():
Of course, since is already antisymmetric:
Tensor contractions
Contracting the type-(1,1) tensor with the module element results in another module element:
The components (w.r.t. a given basis) of the contraction are of course :
This contraction coincides with the action of as an endomorphism:
Instead of contract(), index notations can be used to denote the contraction:
Contracting the linear form with the module element results in a ring element:
It is of course the result of the linear form acting on the module element:
By default, the contraction is performed on the last index of the first tensor and the first index of the second one. To perform contraction on other indices, one should specify the indices positions (with the convention position=0 for the first index): for instance to get the contraction (with ):
To get :
or, in terms of index notation:
As for any function, inline documentation is obtained via the quotation mark: