Opened 8 months ago
Last modified 2 weeks ago
#15916 needs_review enhancement
Tensors on free modules of finite rank
Reported by: | egourgoulhon | Owned by: | |
---|---|---|---|
Priority: | major | Milestone: | sage-6.4 |
Component: | linear algebra | Keywords: | free module, tensor, tensor product |
Cc: | SimonKing | Merged in: | |
Authors: | Eric Gourgoulhon, Michal Bejger | Reviewers: | |
Report Upstream: | N/A | Work issues: | |
Branch: | public/tensor_modules-15916 (Commits) | Commit: | c43321bf78adc4ac6ff324f910a879610742d383 |
Dependencies: | Stopgaps: |
Description (last modified by egourgoulhon)
Description
This ticket implements:
- tensor products of the type M\otimes ...\otimes M \otimes M* \otimes...\otimes M* where M is a free module of finite rank over a commutative ring R and M* is its dual (k factors of M and l factors of M*, say)
- the elements of the above tensor products, considered as tensors of type (k,l) on M, i.e. multilinear forms (M*)^{k} \times M^{l} --> R, thanks to the canonical isomorphism (M*)* = M (which holds since M is a free module of finite rank)
- the following tensor operations:
- operations inherent to the module structure (addition, multiplication by a ring element)
- tensor product of two tensors
- tensor contraction
- symmetry / antisymmetry handling (on subset of the tensor arguments or on all arguments)
- exterior product of alternating forms
No distinguished basis is assumed on the free module M; on the contrary many bases can be introduced. Each tensor has then various representations, via its components in the various bases.
Motivation and context
The ticket has been motivated by tensors on smooth manifolds over R, within the
SageManifolds project. In this context, tensors on free modules appear at two levels:
- tensors on tangent spaces:
- commutative ring R: real field R
- free module M: tangent vector space at a given manifold's point
- tensor fields on a manifold:
- commutative ring R: the algebra C^{oo}(U) of smooth functions U--> R, where U is a parallelizable open set of the manifold
- free module M: the set X(U) of smooth vector fields on U (since U is parallelizable, this is a free module; its rank is the manifold's dimension)
Documentation
Apart from the numerous doctests in the code, some pieces of documentation are
- the tutorial worksheet posted here (a pdf version is here)
- the "tensors on free modules" reference manual (a pdf version is here); it can also be generated via the command sage -docbuild tensors_free_module html
See also this page.
Remarks
- Although developed in the context of SageManifolds (ticket:14865), the ticket is self-contained and does not depend on other parts of SageManifolds. It this respect, it can be viewed as some attempt to include a first subset of SageManifolds in Sage, with a moderate size: the ticket comprises 12331 lines of Python code (most of them being doctests), while at present (version 0.6) SageManifolds contains 35157 lines of code.
- The ticket follows Sage's Parent/Element scheme and the (new) category framework. In particular, the ticket's free module class (FiniteRankFreeModule) passes the module TestSuite.
- It turned out to be necessary to develop a new class to implement free modules of finite rank. Indeed, the category of free modules does not exist yet in Sage: only those of generic modules (Modules) or free modules with a distinguished basis (ModulesWithBasis) are available. Now, the tangent space at a given point of a manifold is a vector space without any distinguished basis (in other words, while the tangent space is isomorphic to R^{n}, there is no canonical isomorphism, each isomorphism relying on the choice of some coordinate chart). The new class, FiniteRankFreeModule, does not rely on any distinguished basis. It inherits directly from Parent, with the category set to Modules(). In particular, it does not inherit from sage.modules.module.FreeModule_generic since the latter does not conform to the new coercion model and seems to assume a distinguished basis (cf. its method basis()).
Change History (36)
comment:1 Changed 8 months ago by egourgoulhon
comment:2 Changed 8 months ago by egourgoulhon
- Description modified (diff)
comment:3 Changed 7 months ago by git
- Commit changed from f8e9c3e62c1b016a41d377a0ccdbcd665aa189dc to e34f29ec69a4595f52894724a5aec22a571c02ce
comment:4 Changed 7 months ago by jhpalmieri
Is there any connection and/or overlap between this ticket and #15726?
comment:5 Changed 7 months ago by egourgoulhon
This ticket implements tensor modules T^{(k,l)}(M) of a fixed type (k,l) over a free module M of finite rank, while #15726 implements the tensor algebra T(M), which is the direct sum of all T^{(k,l)}(M).
Another major difference is that here the base module M is a generic free module, while in #15726 M is a free module with a distinguished basis (the classes TensorModule and TensorAlgebra of #15726 inherit from class CombinatorialFreeModule, which assumes a distinguished basis). In the present ticket, an arbitrary number of bases can be introduced on the free module M, along with the change-of-basis automorphisms, and each tensor has various sets of components, one per basis.
Another difference may regard symmetry/antisymmetry handling: the tensors implemented in this ticket can have arbitrary symmetries and/or antisymmetries. The symmetries are taken into account to reduce the storage of tensor components and to optimize some computations, such as the tensor product. But maybe something similar is implemented in #15726.
comment:6 Changed 6 months ago by vbraun_spam
- Milestone changed from sage-6.2 to sage-6.3
comment:7 Changed 5 months ago by git
- Commit changed from e34f29ec69a4595f52894724a5aec22a571c02ce to 8b7bd605a0b41f3e428c6e67bb85d630d193065a
Branch pushed to git repo; I updated commit sha1. New commits:
8b7bd60 | Updated 'tensors on free modules' to Sage 6.2 |
comment:8 Changed 5 months ago by git
- Commit changed from 8b7bd605a0b41f3e428c6e67bb85d630d193065a to 010c31309df79e4957bb7e8daca6cd47d22b2121
Branch pushed to git repo; I updated commit sha1. New commits:
010c313 | Minor improvements; coincides with SageManifolds as of 18 May 2014 (commit d488f8f807 on github) |
comment:9 Changed 3 months ago by git
- Commit changed from 010c31309df79e4957bb7e8daca6cd47d22b2121 to 267b6b937226357d87669f7c5c8c699d99188b5a
Branch pushed to git repo; I updated commit sha1. New commits:
267b6b9 | Update to SageManifolds v0.5 |
comment:10 Changed 3 months ago by egourgoulhon
This is now part of SageManifolds v0.5 (see this post on sage-devel and http://sagemanifolds.obspm.fr/changelog.html).
comment:11 Changed 3 months ago by egourgoulhon
- Status changed from new to needs_review
comment:12 Changed 3 months ago by egourgoulhon
- Description modified (diff)
comment:13 Changed 3 months ago by egourgoulhon
- Description modified (diff)
comment:14 Changed 3 months ago by egourgoulhon
- Description modified (diff)
comment:15 Changed 3 months ago by SimonKing
- Cc SimonKing added
comment:16 Changed 3 months ago by vbraun_spam
- Milestone changed from sage-6.3 to sage-6.4
comment:17 Changed 2 months ago by git
- Commit changed from 267b6b937226357d87669f7c5c8c699d99188b5a to 8f0878d7c04e15559a76c427fac9a764fa1ecca8
Branch pushed to git repo; I updated commit sha1. New commits:
8f0878d | Added index notation for tensor contractions and symmetrizations |
comment:18 Changed 4 weeks ago by git
- Commit changed from 8f0878d7c04e15559a76c427fac9a764fa1ecca8 to d8f518ff48c8be2ea73f2b51e067af9e6c87b4bf
Branch pushed to git repo; I updated commit sha1. New commits:
d8f518f | Update to SageManifolds v0.6 |
comment:19 Changed 4 weeks ago by egourgoulhon
The ticket has been updated to coincide with the pure algebraic part of SageManifolds v0.6. Changes are:
1/ The possibility to use index notations for denoting tensor contractions or symmetrizations: the indices have to be passed in LaTeX notations (possibly without {}) as a string inside the square bracket operator, e.g.
sage: S = A['^{ab}_{cd}']*B['^d_a'] # equivalent to S = A.contract(0, 3, B, 1, 0)
to denote the tensor S^{b}_{c} = A^{ab}_{cd} B^{d}_{a} ,
sage: S = A['^{(ab)}_{cd}'] # equivalent to S = A.symmetrize(0,1)
to denote the tensor S^{ab}_{cd} = A^{(ab)}_{cd}, and
sage: S = A['^{ab}_{[cd]}'] # equivalent to S = A.antisymmetrize(2,3)
to denote the tensor S^{ab}_{cd} = A^{ab}_{[cd]}.
See this page and this one for more details.
2/ The code for tensor contractions has been completely rewritten; it is more efficient and allows now for multiple contractions (as in the first example above).
3/ The argument of methods symmetrize() and antisymmetrize() in the FreeModuleTensor class is now directly a sequence of index positions (and no longer a single list/tuple encapsulating such a sequence).
Besides, new examples have been provided on http://sagemanifolds.obspm.fr/examples.html; two of them are directly relevant to this ticket:
- tensors on free modules of finite rank (tutorial)
- vector-field modules on the 2-sphere (a concrete example of use)
comment:20 follow-up: ↓ 21 Changed 4 weeks ago by vbraun
Doctest coverage: sage -coverage src/sage/tensor/
I don't think the string notation is very user friendly, A['^{ab}_{cd}']*B['^d_a'] looks more like line noise. How about recognizing symbolic variables and the built-in function any as special:
sage: var('a, d')
sage: A[a, any, any, d] * B[d, a]
Or, perhaps better in the long run: Define your own index class that knows about whether indices are upper or lower. Then we can also check that you don't contract two upper indices, and/or automatically insert the metric there:
sage: a, b, c, d = A.indices()
sage: a
Upper index
sage: A[a, b, c, d] * B[d, a]
comment:21 in reply to: ↑ 20 Changed 4 weeks ago by egourgoulhon
Replying to vbraun:
Doctest coverage: sage -coverage src/sage/tensor/
OK I see: most private methods appear to have no doctest because their doctests have been put in the docstring of the class itself: this is the only way for them to appear in the generated html documentation. This is particularly true for the __init__ methods (there are actually a lot of doctests for them). Shall the doctests be repeated in the docstring of the private methods ? What is the general policy for this ?
I don't think the string notation is very user friendly, A['^{ab}_{cd}']*B['^d_a'] looks more like line noise. How about recognizing symbolic variables and the built-in function any as special:
sage: var('a, d')
sage: A[a, any, any, d] * B[d, a]
Your suggestion for any is quite compeling, thanks. Note that, in the present version, it is already possible to replace unrelevant indices with dots, which decreases the noise:
sage: S = A['^{a.}_{.d}']*B['^d_a']
Or, perhaps better in the long run: Define your own index class that knows about whether indices are upper or lower. Then we can also check that you don't contract two upper indices, and/or automatically insert the metric there:
sage: a, b, c, d = A.indices()
sage: a
Upper index
sage: A[a, b, c, d] * B[d, a]
You are right: in the long run, we should probably introduce an indice class to get rid of the strings. The only advantage of the present notation is that we do not have to spoil some variable names to denote indices: they can be set on the fly, to denote an operation like contraction where index notation is more clear, most operations being performed in an index-free setting.
comment:22 Changed 4 weeks ago by vbraun
The __init__ docstring is used as the class docstring if you don't define a separate class docstring, and I would recommend using that.
You can document other underscore methods by adding, say,
.. automethod:: __mul__
at the end of the class docstring (possibly derived from the __init__ docstring as above).
Not all underscore methods need to appear in the reference manual, though. The doctests are still tests, even if they are not end-user visible "documentation". And they are documentation for developers reading the source and wondering how to use that method...
comment:23 follow-up: ↓ 24 Changed 4 weeks ago by tscrim
What I generally do is put all of the important info in the class docstring, like the INPUT block and examples showing use-cases. In the __init__ method, it is just creating a common example X and doing TestSuite(X).run() (and possibly repeating for some boarder cases).
Also what Volker is alluding to is that all methods, including underscore ones, must have some doctest.
Some quick comments/questions:
- Please remove the autogenerated files from git tracking (as they will be autogenerated :p).
- The imports from tensor/modules I feel like should be done using tensor/all.py rather than all.py (at the source root).
- I'm wondering if the tensor/modules doc should be built along with the tensor doc (rather than it's own separate thing) as tensor is small to begin with. However, I don't think there's any drawbacks to having it be separate since it's (essentially) disjoint from the other doc.
- Is there anything I can do with or you need from #15726? I'd like to make these compatible as much as possible.
- +1 to having a class for indices (once there is clear a need for it).
I really like the pictures on the Sage manifolds website and think this will be a great addition to Sage. Unfortunately I don't have time right now to do much of a review.
Best,
Travis
PS - You might also be interested in #9439.
comment:24 in reply to: ↑ 23 Changed 4 weeks ago by egourgoulhon
Replying to tscrim:
What I generally do is put all of the important info in the class docstring, like the INPUT block and examples showing use-cases. In the __init__ method, it is just creating a common example X and doing TestSuite(X).run() (and possibly repeating for some boarder cases).
Thanks to you and Volker for your advices.
Also what Volker is alluding to is that all methods, including underscore ones, must have some doctest.
OK got it. Will modify the code accordingly.
Some quick comments/questions:
- Please remove the autogenerated files from git tracking (as they will be autogenerated :p).
OK.
- The imports from tensor/modules I feel like should be done using tensor/all.py rather than all.py (at the source root).
Yes, this would be more consistent with the directory structure.
- I'm wondering if the tensor/modules doc should be built along with the tensor doc (rather than it's own separate thing) as tensor is small to begin with. However, I don't think there's any drawbacks to having it be separate since it's (essentially) disjoint from the other doc.
Actually the current content of tensor (algebra of differential forms defined on a coordinate patch of R^{n}) pertains more to smooth manifolds than to tensor modules over arbitrary commutative rings.
- Is there anything I can do with or you need from #15726? I'd like to make these compatible as much as possible.
Sure! There is clearly some overlap between the two and we should discuss this further. For instance, once a basis is chosen, a tensor from this ticket should be converted into an element of the tensor algebra of #15726. Let us keep in touch about this.
- +1 to having a class for indices (once there is clear a need for it).
I really like the pictures on the Sage manifolds website and think this will be a great addition to Sage. Unfortunately I don't have time right now to do much of a review.
Best,
Travis
PS - You might also be interested in #9439.
Yes this has clearly some connections with SageManifolds, as well as #10132 (now integrated into Sage) and your ticket about Lie algebras (#14901).
comment:25 Changed 2 weeks ago by git
- Commit changed from d8f518ff48c8be2ea73f2b51e067af9e6c87b4bf to 45aaa975d406ade603a15a34f34a9790936e42ab
Branch pushed to git repo; I updated commit sha1. New commits:
45aaa97 | Add doctests and improve documentation in tensor/modules |
comment:26 Changed 2 weeks ago by egourgoulhon
Hi,
- Following Volker's comment, doctests to all underscore methods have been added. Accordingly sage -coverage src/sage/tensor/modules results in 100% coverage.
- Following Travis' one, (i) I've suppressed the spurious mention "autogenerated file" in the rst files (this resulted from some cut-and-paste; actually these files are not autogenerated) and (ii) I've moved the import of tensor/modules to sage/tensor/all.py.
Some simple examples illustrating this ticket are on this page. Concrete examples of use in the framework of fields on a smooth manifold (modules over the algebra of scalar fields on S^{2}) are here (this requires #14865).
comment:27 Changed 2 weeks ago by egourgoulhon
- Description modified (diff)
comment:28 follow-up: ↓ 29 Changed 2 weeks ago by tscrim
You shouldn't need those .rst because there are such files autogenerated by Sage's docbuilder (although they are a little more buried in the /src/doc/en/reference/tensor/sage/, or whatever documentation group you're considering) and you're not doing anything different as far as I can see.
Also on a quick glance through the recent commit, I noticed a colon missing on in these two places:
@@ -984,6 +1179,21 @@ class Components(SageObject): - True if ``self`` is different from ``other``, or False otherwise + EXAMPLES: + + sage: from sage.tensor.modules.comp import Components @@ -176,12 +177,46 @@ class TensorFreeModule(FiniteRankFreeModule): [snip] Element = FreeModuleTensor def __init__(self, fmodule, tensor_type, name=None, latex_name=None): + r""" + TEST: + + sage: from sage.tensor.modules.tensor_free_module import TensorFreeModule
comment:29 in reply to: ↑ 28 Changed 2 weeks ago by egourgoulhon
Replying to tscrim:
Thanks for your comments.
You shouldn't need those .rst because there are such files autogenerated by Sage's docbuilder (although they are a little more buried in the /src/doc/en/reference/tensor/sage/, or whatever documentation group you're considering) and you're not doing anything different as far as I can see.
Actually, I've added these .rst files because they are not autogenerated in the present case. More precisely, the command sage -docbuild tensors_free_module html does not produce any sage subdirectory in src/doc/en/tensors_free_module. On the contrary the command sage -docbuild reference html produces a sage subdirectory in src/doc/en/reference/tensor_free_modules, which contains the autogenerated .rst files. As a result, if I simply copy the file index.rst from src/doc/en/reference/tensor_free_modules to src/doc/en/tensors_free_module and delete all the other .rst files (the "non-autogenerated" ones), I get the error message toctree contains reference to nonexisting document u'sage/tensor/modules/finite_rank_free_module'. Certainly, I am not doing something properly here. Any help on this would be appreciated...
/
Also on a quick glance through the recent commit, I noticed a colon missing on in these two places:
Thanks for pointing this; I'll correct it.
comment:30 follow-up: ↓ 31 Changed 2 weeks ago by vbraun
You should only have the modules/index.rst. The docbuilder will not always process incremental changes correctly, you might have to sage -b && make doc-clean && make doc
Edit: added the "not"
comment:31 in reply to: ↑ 30 Changed 2 weeks ago by egourgoulhon
Replying to vbraun:
You should only have the modules/index.rst. The docbuilder will not always process incremental changes correctly, you might have to sage -b && make doc-clean && make doc
I tried but it did not helped. To make things clear, let me stress that the problem arises because we wanted to have a separate reference manual for tensors on free modules, in a directory that we created for this purpose: src/doc/en/tensors_free_module, which differs from the corresponding section in the main Sage reference manual (directory src/doc/en/reference/tensor_free_modules). For the latter, everything works well: the only .rst file under src/doc/en/reference/tensor_free_modules is index.rst and it suffices for the docbuilder to produce the complete documentation. The problem arises only for src/doc/en/tensors_free_module. So the question might be: "how to produce a separate reference manual for some subpart of Sage library ?".
comment:32 follow-up: ↓ 33 Changed 2 weeks ago by vbraun
You can't and you shouldn't be able to. The top-level sections correspond to the src/sage subdirectories, as they should. You can, however, be quite fancy in src/doc/en/reference/modules/index.rst, see e.g. the combinat section.
comment:33 in reply to: ↑ 32 Changed 2 weeks ago by tscrim
Replying to vbraun:
You can't and you shouldn't be able to. The top-level sections correspond to the src/sage subdirectories, as they should. You can, however, be quite fancy in src/doc/en/reference/modules/index.rst, see e.g. the combinat section.
That's not true, there are significantly more top-level docs than top-level sections in src/sage, the first one that comes to mind is finite_fields. I'm taking a look at it right now to see what's going on.
comment:34 follow-up: ↓ 35 Changed 2 weeks ago by tscrim
- Branch changed from u/egourgoulhon/tensor_modules to public/tensor_modules-15916
- Commit changed from 45aaa975d406ade603a15a34f34a9790936e42ab to a07a21ae1170e224192f9fe6bae34825dae23e1d
I think the problem is you put things in src/doc/en/tensors_free_module, as opposed to src/doc/en/reference/tensors_free_module. So with this branch you should be able to run Volker's commands (or sage -docbuild all html or (what I did to check) sage -docbuild reference/tensor_free_modules inventory and sage -docbuild reference/tensor_free_modules html).
New commits:
93dcad2 | Merge branch 'u/egourgoulhon/tensor_modules' of trac.sagemath.org:sage into public/tensor_modules-15916 |
a07a21a | Fixing the documentation. |
comment:35 in reply to: ↑ 34 Changed 2 weeks ago by egourgoulhon
Replying to tscrim:
It works! Thank you very much Travis. This yields exactly what I had in mind. Moreover, it is nice that one can get rid of the directory src/doc/en/tensors_free_module and stay only with src/doc/en/reference/tensor_free_modules, for duplication is root of all evil ;-)
comment:36 Changed 2 weeks ago by git
- Commit changed from a07a21ae1170e224192f9fe6bae34825dae23e1d to c43321bf78adc4ac6ff324f910a879610742d383
Branch pushed to git repo; I updated commit sha1. New commits:
c43321b | Minor modifications in the documentation of tensor/modules. |
Branch pushed to git repo; I updated commit sha1. New commits: