sagemath / sage

Main repository of SageMath
https://www.sagemath.org
Other
1.45k stars 481 forks source link

Deprecate CoordinatePatch and DifferentialForm to keep a single version of differential forms #24444

Closed egourgoulhon closed 6 years ago

egourgoulhon commented 6 years ago

At present differential forms are dealt with by different and incompatible parts of Sage: the CoordinatePatch version (implemented in #9650) and the manifold version (implemented in #18843).

All functionalities of the CoordinatePatch version (like wedge product and exterior derivative) are implemented in the manifold version, but the manifold one is more recent and provides more functionalities, like

It is also more flexible:

As this ask.sagemath question reveals, keeping both versions is confusing and the current ticket is devoted to deprecate the CoordinatePatch version.

CC: @jvkersch @tscrim @nilesjohnson @jasongrout @sagetrac-mhampton

Component: geometry

Keywords: differential forms

Author: Eric Gourgoulhon

Branch/Commit: 520ee73

Reviewer: Travis Scrimshaw

Issue created by migration from https://trac.sagemath.org/ticket/24444

egourgoulhon commented 6 years ago
comment:1

Illustration of similarities and differences

Let us declare a differential form of degree 2 with the CoordinatePatch version:

sage: x, y, z = var('x, y, z')
sage: U = CoordinatePatch((x, y, z))
sage: F = DifferentialForms(U)
sage: f = DifferentialForm(F, 2)
sage: f[0,1] = x*sin(z)
sage: f[1,2] = y*z
sage: f
x*sin(z)*dx/\dy + y*z*dy/\dz

To perform the same thing with the manifold version, one should write (using a different Sage session to avoid any confusion):

sage: U = Manifold(3, 'U')
sage: X.<x,y,z> = U.chart()
sage: f = U.diff_form(2, 'f')
sage: f[0,1] = x*sin(z)
sage: f[1,2] = y*z
sage: f
2-form f on the 3-dimensional differentiable manifold U
sage: f.display()
f = x*sin(z) dx/\dy + y*z dy/\dz

Let us introduce another differential form, as a 1-form; in the CoordinatePatch version:

sage: g = DifferentialForm(F, 1)
sage: g[0], g[1], g[2] = (y^2, -z, 2*x-y)
sage: g
(2*x - y)*dz + y^2*dx + -z*dy

In the manifold version, one may use the shortcut notation g[:] to set the components of g:

sage: g = U.diff_form(1, 'g')
sage: g[:] = (y^2, -z, 2*x-y)
sage: g.display()
g = y^2 dx - z dy + (2*x - y) dz

The wedge product of f by g is obtained in the same way in both methods: for CoordinatePatch:

sage: f.wedge(g)
(y^3*z + (2*x - y)*x*sin(z))*dx/\dy/\dz

while for the manifold version:

sage: f.wedge(g)
3-form f/\g on the 3-dimensional differentiable manifold U
sage: f.wedge(g).display()
f/\g = (y^3*z + (2*x^2 - x*y)*sin(z)) dx/\dy/\dz

The exterior derivative is computed via the method diff() in the CoordinatePatch version:

sage: f.diff()
x*cos(z)*dx/\dy/\dz

and via the method exterior_derivative() in the manifold version:

sage: f.exterior_derivative().display()
df = x*cos(z) dx/\dy/\dz

A shortcut is provided by the function xder, to be used as the operator d to compute df:

sage: from sage.manifolds.utilities import xder
sage: xder(f) == f.exterior_derivative()
True

A difference regards the parents: in the CoordinatePatch version, the 2-form f and the 1-form g have the same parent, which is the graded algebra Omega(U) of all differential forms defined on U, and declared as F = DifferentialForms(U) at the beginning of the session:

sage: f.parent()
Algebra of differential forms in the variables x, y, z
sage: f.parent() is F
True
sage: g.parent() is F
True

In the manifold case, the parent of f is the set Omega2(U) of 2-forms on U, which is considered as a free module of rank 3 on the algebra Coo(U) of scalar fields on U, while the parent of g is the set Omega1(U) of 1-forms on U, which is considered as another free module of rank 3 on Coo(U):

sage: f.parent()
Free module Omega^2(U) of 2-forms on the 3-dimensional differentiable manifold U
sage: f.parent().base_ring()
Algebra of differentiable scalar fields on the 3-dimensional differentiable manifold U
sage: f.parent().rank()
3
sage: g.parent()
Free module Omega^1(U) of 1-forms on the 3-dimensional differentiable manifold U
sage: g.parent().rank()
3
egourgoulhon commented 6 years ago
comment:2

Examples of functionalities avalaible only in the manifold version

The capability to access directly to the coordinate basis 1-forms:

sage: X.coframe()
Coordinate coframe (U, (dx,dy,dz))
sage: dx = X.coframe()[0]
sage: dy = X.coframe()[1]
sage: a = sin(z)*dx.wedge(dy)
sage: a.display()
sin(z) dx/\dy

The interior product with a vector field:

sage: v = U.vector_field('v')
sage: v[:] = (-y, z, x^2)
sage: v.interior_product(f)
1-form i_v f on the 3-dimensional differentiable manifold U
sage: v.interior_product(f).display()
i_v f = -x*z*sin(z) dx + (-x^2*y*z - x*y*sin(z)) dy + y*z^2 dz

The Lie derivative with respect to a vector field:

sage: f.lie_derivative(v)
2-form on the 3-dimensional differentiable manifold U
sage: f.lie_derivative(v).display()
(x^3*cos(z) - 2*x*y*z - y*sin(z)) dx/\dy + x*sin(z) dx/\dz + (x^2*y + z^2) dy/\dz

As an illustration, we may check that Cartan's identity Liev f = d(iv f) + iv df holds:

sage: f.lie_derivative(v) == (v.interior_product(f)).exterior_derivative() + \
....:                        v.interior_product(f.exterior_derivative())
True

Computing the Hodge dual with respect to a given metric:

sage: h = U.metric('h')
sage: h[0,0] = 1+y^2
sage: h[1,1] = 1+z^2
sage: h[2,2] = 1+x^2
sage: h.display()
h = (y^2 + 1) dx*dx + (z^2 + 1) dy*dy + (x^2 + 1) dz*dz
sage: f.hodge_dual(h)
1-form *f on the 3-dimensional differentiable manifold U
sage: f.hodge_dual(h).display()
*f = sqrt(y^2 + 1)*y*z/(sqrt(x^2 + 1)*sqrt(z^2 + 1)) dx + sqrt(x^2 + 1)*x*sin(z)/(sqrt(y^2 + 1)*sqrt(z^2 + 1)) dz

Computing new components under a change of coordinates:

sage: X2.<u,v,w> = U.chart()
sage: X_to_X2 = X.transition_map(X2, [y+z, z+x, x+y])
sage: X_to_X2.inverse()
Change of coordinates from Chart (U, (u, v, w)) to Chart (U, (x, y, z))
sage: g.display()  # the default for g.display(X.frame(), X)
g = y^2 dx - z dy + (2*x - y) dz
sage: g.display(X2.frame(), X2)
g = (-1/8*u^2 + 1/4*(u + 2)*v - 1/8*v^2 - 1/4*(u - v - 2)*w - 1/8*w^2 - u) du + (1/8*u^2 - 1/4*(u - 4)*v + 1/8*v^2 + 1/4*(u - v)*w + 1/8*w^2 - 1/2*u) dv + (1/8*u^2 - 1/4*(u + 4)*v + 1/8*v^2 + 1/4*(u - v)*w + 1/8*w^2 + 1/2*u) dw

Using the function display_comp, which is more convenient for lengthy expressions:

sage: g.display_comp()   # the default for g.display_comp(X.frame(), X)
g_x = y^2
g_y = -z
g_z = 2*x - y
sage: g.display_comp(X2.frame(), X2)
g_u = -1/8*u^2 + 1/4*(u + 2)*v - 1/8*v^2 - 1/4*(u - v - 2)*w - 1/8*w^2 - u
g_v = 1/8*u^2 - 1/4*(u - 4)*v + 1/8*v^2 + 1/4*(u - v)*w + 1/8*w^2 - 1/2*u
g_w = 1/8*u^2 - 1/4*(u + 4)*v + 1/8*v^2 + 1/4*(u - v)*w + 1/8*w^2 + 1/2*u
egourgoulhon commented 6 years ago
comment:3

Regarding the code, both versions share the same trick for the storage of components: a dictionary whose keys are the indices, limited to nonredundant ones (i.e. only the components that cannot be deduced by antisymmetry). For the CoordinatePatch version and the same example as above, we have

sage: f
x*sin(z)*dx/\dy + y*z*dy/\dz
sage: f._components
{(0, 1): x*sin(z), (1, 2): y*z}
sage: f[1,0]  # a component not stored but deduced by antisymmetry
-x*sin(z)

while for the manifold version, we have

sage: f.display()
f = x*sin(z) dx/\dy + y*z dy/\dz
sage: f.components()
Fully antisymmetric 2-indices components w.r.t. Coordinate frame (U, (d/dx,d/dy,d/dz))
sage: f.components()._comp
{(0, 1): Scalar field on the 3-dimensional differentiable manifold U,
 (1, 2): Scalar field on the 3-dimensional differentiable manifold U}
sage: for i, c in f.components()._comp.items():
....:     print("{}: {}".format(i, c.expr()))
....:     
(0, 1): x*sin(z)
(1, 2): y*z
sage: f[1,0]  # a component not stored but deduced by antisymmetry
-x*sin(z)

Actually, the storage method of the CoordinatePatch version inspired the manifold one ;-), as acknowledged in the AUTHORS section of the documentation.

egourgoulhon commented 6 years ago

Description changed:

--- 
+++ 
@@ -2,6 +2,7 @@

 All functionalities of the CoordinatePatch version (like wedge product and exterior derivative) are implemented in the manifold version, but the manifold one is more recent and provides more functionalities, like

+- better display capabilities
 - changing the coordinates (the CoordinatePatch version assumes a fixed coordinate system)
 - evaluating the Lie derivative with respect to a vector field
 - performing the interior product with a p-vector
@@ -9,7 +10,8 @@

 It is also more flexible:

-- the indices may be chosen to start from 1 instead of 0
-- one may use index notation with summation on repeated indices.
+- the indices may be chosen to start from 1 (or any other value) instead of 0
+- one may use index notation with Einstein convention of summation on repeated indices
+- the base ring is not limited to the Symbolic Ring.

 As this [ask.sagemath question](https://ask.sagemath.org/question/40345/differential-forms-best-package/) reveals, keeping both versions is confusing and the current ticket is devoted to deprecate the CoordinatePatch version.
egourgoulhon commented 6 years ago

Description changed:

--- 
+++ 
@@ -1,4 +1,5 @@
-At present differential forms are dealt with by different and incompatible parts of Sage: the [CoordinatePatch version](http://doc.sagemath.org/html/en/reference/tensor/sage/tensor/differential_form_element.html) and the [manifold version](http://doc.sagemath.org/html/en/reference/manifolds/sage/manifolds/differentiable/diff_form.html). 
+At present differential forms are dealt with by different and incompatible parts of Sage: the [CoordinatePatch version](http://doc.sagemath.org/html/en/reference/tensor/sage/tensor/differential_form_element.html) (implemented in #9650) and the [manifold version](http://doc.sagemath.org/html/en/reference/manifolds/sage/manifolds/differentiable/diff_form.html)
+(implemented in #18843).

 All functionalities of the CoordinatePatch version (like wedge product and exterior derivative) are implemented in the manifold version, but the manifold one is more recent and provides more functionalities, like
egourgoulhon commented 6 years ago

Author: Eric Gourgoulhon

egourgoulhon commented 6 years ago

Commit: 520ee73

egourgoulhon commented 6 years ago

New commits:

520ee73Deprecate CoordinatePatch and DifferentialForm (trac #24444)
egourgoulhon commented 6 years ago

Branch: public/manifolds/deprecate_DifferentialForm-24444

egourgoulhon commented 6 years ago
comment:7

The deprecation is implemented in the attached branch. Please review.

tscrim commented 6 years ago

Reviewer: Travis Scrimshaw

tscrim commented 6 years ago
comment:8

LGTM.

egourgoulhon commented 6 years ago
comment:9

Thanks for the review!

vbraun commented 6 years ago

Changed branch from public/manifolds/deprecate_DifferentialForm-24444 to 520ee73