SageManifolds v0.5: treating sets of tensor fields as modules and making use of Sage coercion model

61 views
Skip to first unread message

Eric Gourgoulhon

unread,
Jul 17, 2014, 11:52:51 AM7/17/14
to sage-...@googlegroups.com
Hi,

We have just released a new version of SageManifolds at http://sagemanifolds.obspm.fr/

With respect to previous version, a whole rewriting of the code has been performed, aiming at a better integration in Sage. In particular, the tensor on free modules stuff, described in this post and on this page has been included in this release to describe both (i) tensor fields on parallelizable domains and (ii) tensor on the tangent spaces. Sage Parent/Element scheme is now employed for Domain/Point, ScalarFieldAlgebra/ScalarField, TensorFieldModule/TensorField and TangentSpace/TangentVector. All the parents inherit from Sage's classes UniqueRepresentation and Parent (some class diagrams are depicted here). Coercions between parents have also been implemented, as illustrated by the following 2-sphere example:

We first construct the S^2 manifold and cover it by a set of two charts:

sage: M = Manifold(2, 'S^2') # declaration as a 2-dimensional manifold
sage
: U = M.open_domain('U') ; V = M.open_domain('V') # the complements of the North pole and South pole, respectively
sage
: M.declare_union(U,V) # the union of U and V is M
sage
: stereoN.<x,y> = U.chart() # stereographic coordinates from the North pole
sage
: stereoS.<u,v> = V.chart() # stereographic coordinates from the South pole
sage
: N_to_S = stereoN.transition_map(stereoS, (x/(x^2+y^2), y/(x^2+y^2)), intersection_name='W', restrictions1= x^2+y^2!=0, restrictions2= u^2+v^2!=0) # the transition map between the two charts
sage
: S_to_N = N_to_S.inverse() # the inverse of the transition map is computed
sage
: M.atlas() # the open set W below is the intersection of U and V
[chart (U, (x, y)), chart (V, (u, v)), chart (W, (x, y)), chart (W, (u, v))]

Points on S^2 have for parent domains on the manifolds; hence they can be constructed by the method __call__ applied to their parent, the argument being their coordinates in some chart:

sage: N = V((0,0), chart=stereoS, name='N') ; N  # the North pole
point
'N' on 2-dimensional manifold 'S^2'
sage
: S = U((0,0), chart=stereoN, name='S') ; S  # the South pole
point
'S' on 2-dimensional manifold 'S^2'
sage
: p = U((1,0), chart=stereoN, name='p') ; p  # some point at the equator
point
'p' on 2-dimensional manifold 'S^2'

Let us consider a (smooth) scalar field on S^2, defined by its coordinate expression in the two charts:

sage: f = M.scalar_field({stereoN: atan(x^2+y^2), stereoS: pi/2-atan(u^2+v^2)}, name='f')
sage
: f.view()
f
: S^2 --> R
on U
: (x, y) |--> arctan(x^2 + y^2)
on V
: (u, v) |--> 1/2*pi - arctan(u^2 + v^2)
sage
: f(N), f(p), f(S)  # scalar fields map manifold points to real numbers
(1/2*pi, 1/4*pi, 0)

The parent of scalar fields is the commutative algebra C^oo(M):

sage: CM = f.parent() ; CM
algebra of scalar fields on the
2-dimensional manifold 'S^2'
sage
: CM.category()
Category of commutative algebras over Symbolic Ring
sage
: TestSuite(CM).run() # the commutative algebra test suite is passed

The set C^oo(U) of scalar fields defined on U is

sage: CU = U.scalar_field_algebra() ; CU
algebra of scalar fields on the open domain
'U' on the 2-dimensional manifold 'S^2'

There is a coercion from C^oo(M) to C^oo(U) but not in the reverse way:

sage: CU.has_coerce_map_from(CM)
True
sage
: CM.has_coerce_map_from(CU)
False

Indeed, the coercion from C^oo(M) to C^oo(U) is nothing but the restriction to U:

sage: g = CU(f) ; g  # f coerced to an element of C^oo(U)
scalar field on the open domain
'U' on the 2-dimensional manifold 'S^2'
sage
: g.view()
U
--> R
(x, y) |--> arctan(x^2 + y^2)
on W
: (u, v) |--> 1/2*pi - arctan(u^2 + v^2)
sage
: g == f.restrict(U)
True

The set X(M) of (smooth) vector fields on S^2 is a module over the algebra C^oo(M):

sage: XM = M.vector_field_module() ; XM
module X(S^2) of vector fields on the 2-dimensional manifold 'S^2'
sage
: XM.category()
Category of modules over algebra of scalar fields on the 2-dimensional manifold 'S^2'
sage
: XM.base_ring() is CM
True
sage
: TestSuite(XM).run() # the module test suite is passed

X(M) is not a free module, for M=S^2 is not a parallelizable manifold (i.e. it does not admit any global vector frame):

sage: isinstance(XM, FiniteRankFreeModule)
False
sage
: M.is_manifestly_parallelizable()
False

On the contrary, the set X(U) of vector fields on U is a free module:

sage: XU = U.vector_field_module() ; XU
free
module X(U) of vector fields on the open domain 'U' on the 2-dimensional manifold 'S^2'
sage
: XU.category()
Category of modules over algebra of scalar fields on the open domain 'U' on the 2-dimensional manifold 'S^2'
sage
: XU.base_ring() is CU
True
sage
: TestSuite(XU).run() # the module test suite is passed

Indeed, U admits a global vector frame: the coordinate frame (d/dx, d/dy):

sage: U.is_manifestly_parallelizable()
True
sage
: U.frames()  # list of frames defined on open subsets of U
[coordinate frame (U, (d/dx,d/dy)),
 coordinate frame
(W, (d/dx,d/dy)),
 coordinate frame
(W, (d/du,d/dv))]
sage
: eN = stereoN.frame() ; eN  # the vector frame associated with stereographic coordinates (x,y) from the North pole
coordinate frame
(U, (d/dx,d/dy))
sage
: eS = stereoS.frame() ; eS  # similarly, we define the frame associated with stereographic coordinates from the South pole
coordinate frame
(V, (d/du,d/dv))

There is a coercion from X(M) to X(U), which is the restriction of vector fields to U:

sage: XU.has_coerce_map_from(XM)
True

To illustrate it, let us consider a vector field on S^2, for instance the azimuthal rotation vector d/dphi:

sage: w = M.vector_field(name='w')
sage
: w[eN,:] = [-y, x] # w is defined by its components with respect to the frame eN
sage
: w.add_comp_by_continuation(eS, U.intersection(V), stereoS) # the components in the frame eS are deduced by analytic continuation from the domain common to both eN and eS
sage
: w.view(eN)
w
= -y d/dx + x d/dy
sage
: w.view(eS)
w
= -v d/du + u d/dv
sage
: w(f)  # vector fields act on scalar fields
scalar field
'w(f)' on the 2-dimensional manifold 'S^2'
sage
: w.parent() is XM
True

Let us coerce w to X(U):

sage: wU = XU(w) ; wU
vector field
'w' on the open domain 'U' on the 2-dimensional manifold 'S^2'
sage
: wU.view()  # view in the default frame of U, which is eN
w
= -y d/dx + x d/dy
sage
: wU == w.restrict(U) # the coercion is nothing but the restriction to U
True

This type of coercion is extended to any tensor field module (XM being considered as the module of type-(1,0) tensor fields), for instance, type-(0,1) tensor fields (i.e. 1-forms):

sage: df = f.differential() ; df
1-form 'df' on the 2-dimensional manifold 'S^2'
sage
: df.view(eN)
df
= 2*x/(x^4 + 2*x^2*y^2 + y^4 + 1) dx + 2*y/(x^4 + 2*x^2*y^2 + y^4 + 1) dy
sage
: df.view(eS)
df
= -2*u/(u^4 + 2*u^2*v^2 + v^4 + 1) du - 2*v/(u^4 + 2*u^2*v^2 + v^4 + 1) dv
sage
: df.parent()
module T^(0,1)(S^2) of type-(0,1) tensors fields on the 2-dimensional manifold 'S^2'
sage
: T01M = M.tensor_field_module((0,1)) ; df.parent() is T01M
True
sage
: T01M.category()
Category of modules over algebra of scalar fields on the 2-dimensional manifold 'S^2'
sage
: TestSuite(T01M).run()  # the module test suite is passed
sage
: T01U = U.tensor_field_module((0,1)) ; T01U
free
module T^(0,1)(U) of type-(0,1) tensors fields on the open domain 'U' on the 2-dimensional manifold 'S^2'
sage
: T01U.has_coerce_map_from(T01M)
True

Another algebraic structure introduced in SageManifolds 0.5 is the tangent vector spaces at points on the manifold:

sage: Tp = p.tangent_space() ; Tp
tangent space at point
'p' on 2-dimensional manifold 'S^2'
sage
: Tp.category()
Category of vector spaces over Symbolic Ring
sage
: isinstance(Tp, FiniteRankFreeModule) # a finite-dimensional vector space is of course a free module of finite rank
True
sage
: Tp.dim()
2

The value of a vector field at a given point is a vector in the tangent space:

sage:  wp = w.at(p) ; wp
tangent vector w at point
'p' on 2-dimensional manifold 'S^2'
sage
: wp.parent() is Tp
True

while the value of a 1-form is an element of the dual vector space:

sage: dfp = df.at(p) ; dfp
linear form df on the tangent space at point
'p' on 2-dimensional manifold 'S^2'
sage
: dfp.parent() is Tp.dual()
True

The 2-sphere example is more detailed (in particular its Riemannian structure) in this page.

Other changes in this release, which follow from discussion on this list, are

- All class attributes are now hidden (underscore prefix) and the corresponding accessor methods have been added (e.g. Tp.dim() returns Tp._rank)

- Only the classes Manifold, RealLine and FiniteRankFreeModule are now imported in the global name space of a Sage session. All constructions of objects not belonging to these classes are performed by specific method calls on other objects.

SageManifolds 0.5 is submitted to Sage trac in two parts:

- ticket #15916: the pure algebraic part (tensors on free modules)
- ticket #14865: the differential part (manifolds and tensor fields)

As usual, comments and suggestions are welcome, not speaking about help in the code development ! (future directions should involve graphical outputs, parallelization of tensor computations, curves and immersed submanifolds, geodesics, integration)

Simon King

unread,
Jul 18, 2014, 6:53:22 AM7/18/14
to sage-...@googlegroups.com
Hi Eric,

On 2014-07-17, Eric Gourgoulhon <egourg...@gmail.com> wrote:
> ... as illustrated by the following
> 2-sphere example:

Quite impressive!

> As usual, comments and suggestions are welcome, not speaking about help in
> the code development ! (future directions should involve graphical outputs,
> parallelization of tensor computations, curves and immersed submanifolds,
> geodesics, integration)

Is there any initiative towards PL structures? Probably out of scope in
general, but totally natural out to dimension three. Specifically, do
you think one should seek mutual benefit of your work and, say, the Google
Summer of Code project on "knots in Sage"?

Best regards,
Simon


Eric Gourgoulhon

unread,
Jul 18, 2014, 8:53:56 AM7/18/14
to sage-...@googlegroups.com
Hi Simon,


Le vendredi 18 juillet 2014 12:53:22 UTC+2, Simon King a écrit :

Is there any initiative towards PL structures?

No, but feel free to implement it! More generally, some work should be done for topological manifolds (or even topological  spaces) first. Then both differentiable manifolds and PL manifolds could benefit from it. At present, topological concepts are implement in SageManifolds via the python class OpenDomain, which is a Parent in the category of Sets (see this diagram and this page). This is a workaround. It would be nice to have the  category of topological spaces in Sage instead.

Probably out of scope in
general, but totally natural out to dimension three. Specifically, do
you think one should seek mutual benefit of your work and, say, the Google
Summer of Code project on "knots in Sage"?


Yes of course, we should share things and mix them to build ahead, in the spirit of open source.

Best wishes,

Eric.


 
Best regards,
Simon


Eric Gourgoulhon

unread,
Jul 18, 2014, 9:00:14 AM7/18/14
to sage-...@googlegroups.com


Le vendredi 18 juillet 2014 12:53:22 UTC+2, Simon King a écrit :
Hi Eric,

On 2014-07-17, Eric Gourgoulhon <egourg...@gmail.com> wrote:
> ... as illustrated by the following
> 2-sphere example:

Quite impressive!


We tried to follow your nice tutorial ;-)
Reply all
Reply to author
Forward
0 new messages