passagemath-symbolics 10.6.37__cp310-cp310-musllinux_1_2_x86_64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- passagemath_symbolics/__init__.py +3 -0
- passagemath_symbolics-10.6.37.dist-info/METADATA +187 -0
- passagemath_symbolics-10.6.37.dist-info/RECORD +171 -0
- passagemath_symbolics-10.6.37.dist-info/WHEEL +5 -0
- passagemath_symbolics-10.6.37.dist-info/top_level.txt +3 -0
- sage/all__sagemath_symbolics.py +17 -0
- sage/calculus/all.py +14 -0
- sage/calculus/calculus.py +2826 -0
- sage/calculus/desolvers.py +1866 -0
- sage/calculus/predefined.py +51 -0
- sage/calculus/tests.py +225 -0
- sage/calculus/var.cpython-310-x86_64-linux-gnu.so +0 -0
- sage/calculus/var.pyx +401 -0
- sage/dynamics/all__sagemath_symbolics.py +6 -0
- sage/dynamics/complex_dynamics/all.py +5 -0
- sage/dynamics/complex_dynamics/mandel_julia.py +765 -0
- sage/dynamics/complex_dynamics/mandel_julia_helper.cpython-310-x86_64-linux-gnu.so +0 -0
- sage/dynamics/complex_dynamics/mandel_julia_helper.pyx +1035 -0
- sage/ext/all__sagemath_symbolics.py +1 -0
- sage/ext_data/kenzo/CP2.txt +45 -0
- sage/ext_data/kenzo/CP3.txt +349 -0
- sage/ext_data/kenzo/CP4.txt +4774 -0
- sage/ext_data/kenzo/README.txt +49 -0
- sage/ext_data/kenzo/S4.txt +20 -0
- sage/ext_data/magma/latex/latex.m +1021 -0
- sage/ext_data/magma/latex/latex.spec +1 -0
- sage/ext_data/magma/sage/basic.m +356 -0
- sage/ext_data/magma/sage/sage.spec +1 -0
- sage/ext_data/magma/spec +9 -0
- sage/geometry/all__sagemath_symbolics.py +8 -0
- sage/geometry/hyperbolic_space/all.py +5 -0
- sage/geometry/hyperbolic_space/hyperbolic_coercion.py +743 -0
- sage/geometry/hyperbolic_space/hyperbolic_constants.py +5 -0
- sage/geometry/hyperbolic_space/hyperbolic_geodesic.py +2409 -0
- sage/geometry/hyperbolic_space/hyperbolic_interface.py +206 -0
- sage/geometry/hyperbolic_space/hyperbolic_isometry.py +1082 -0
- sage/geometry/hyperbolic_space/hyperbolic_model.py +1502 -0
- sage/geometry/hyperbolic_space/hyperbolic_point.py +621 -0
- sage/geometry/riemannian_manifolds/all.py +7 -0
- sage/geometry/riemannian_manifolds/parametrized_surface3d.py +1632 -0
- sage/geometry/riemannian_manifolds/surface3d_generators.py +461 -0
- sage/interfaces/all__sagemath_symbolics.py +1 -0
- sage/interfaces/magma.py +3017 -0
- sage/interfaces/magma_free.py +92 -0
- sage/interfaces/maple.py +1397 -0
- sage/interfaces/mathematica.py +1345 -0
- sage/interfaces/mathics.py +1312 -0
- sage/interfaces/sympy.py +1398 -0
- sage/interfaces/sympy_wrapper.py +197 -0
- sage/interfaces/tides.py +938 -0
- sage/libs/all__sagemath_symbolics.py +6 -0
- sage/manifolds/all.py +7 -0
- sage/manifolds/calculus_method.py +555 -0
- sage/manifolds/catalog.py +437 -0
- sage/manifolds/chart.py +4019 -0
- sage/manifolds/chart_func.py +3419 -0
- sage/manifolds/continuous_map.py +2183 -0
- sage/manifolds/continuous_map_image.py +155 -0
- sage/manifolds/differentiable/affine_connection.py +2475 -0
- sage/manifolds/differentiable/all.py +1 -0
- sage/manifolds/differentiable/automorphismfield.py +1383 -0
- sage/manifolds/differentiable/automorphismfield_group.py +604 -0
- sage/manifolds/differentiable/bundle_connection.py +1445 -0
- sage/manifolds/differentiable/characteristic_cohomology_class.py +1840 -0
- sage/manifolds/differentiable/chart.py +1241 -0
- sage/manifolds/differentiable/curve.py +1028 -0
- sage/manifolds/differentiable/de_rham_cohomology.py +541 -0
- sage/manifolds/differentiable/degenerate.py +559 -0
- sage/manifolds/differentiable/degenerate_submanifold.py +1671 -0
- sage/manifolds/differentiable/diff_form.py +1658 -0
- sage/manifolds/differentiable/diff_form_module.py +1062 -0
- sage/manifolds/differentiable/diff_map.py +1315 -0
- sage/manifolds/differentiable/differentiable_submanifold.py +291 -0
- sage/manifolds/differentiable/examples/all.py +1 -0
- sage/manifolds/differentiable/examples/euclidean.py +2517 -0
- sage/manifolds/differentiable/examples/real_line.py +897 -0
- sage/manifolds/differentiable/examples/sphere.py +1186 -0
- sage/manifolds/differentiable/examples/symplectic_space.py +187 -0
- sage/manifolds/differentiable/examples/symplectic_space_test.py +40 -0
- sage/manifolds/differentiable/integrated_curve.py +4035 -0
- sage/manifolds/differentiable/levi_civita_connection.py +841 -0
- sage/manifolds/differentiable/manifold.py +4254 -0
- sage/manifolds/differentiable/manifold_homset.py +1826 -0
- sage/manifolds/differentiable/metric.py +3032 -0
- sage/manifolds/differentiable/mixed_form.py +1507 -0
- sage/manifolds/differentiable/mixed_form_algebra.py +559 -0
- sage/manifolds/differentiable/multivector_module.py +800 -0
- sage/manifolds/differentiable/multivectorfield.py +1520 -0
- sage/manifolds/differentiable/poisson_tensor.py +268 -0
- sage/manifolds/differentiable/pseudo_riemannian.py +755 -0
- sage/manifolds/differentiable/pseudo_riemannian_submanifold.py +1839 -0
- sage/manifolds/differentiable/scalarfield.py +1343 -0
- sage/manifolds/differentiable/scalarfield_algebra.py +472 -0
- sage/manifolds/differentiable/symplectic_form.py +910 -0
- sage/manifolds/differentiable/symplectic_form_test.py +220 -0
- sage/manifolds/differentiable/tangent_space.py +412 -0
- sage/manifolds/differentiable/tangent_vector.py +616 -0
- sage/manifolds/differentiable/tensorfield.py +4665 -0
- sage/manifolds/differentiable/tensorfield_module.py +963 -0
- sage/manifolds/differentiable/tensorfield_paral.py +2450 -0
- sage/manifolds/differentiable/tensorfield_paral_test.py +16 -0
- sage/manifolds/differentiable/vector_bundle.py +1728 -0
- sage/manifolds/differentiable/vectorfield.py +1717 -0
- sage/manifolds/differentiable/vectorfield_module.py +2445 -0
- sage/manifolds/differentiable/vectorframe.py +1832 -0
- sage/manifolds/family.py +270 -0
- sage/manifolds/local_frame.py +1490 -0
- sage/manifolds/manifold.py +3090 -0
- sage/manifolds/manifold_homset.py +452 -0
- sage/manifolds/operators.py +359 -0
- sage/manifolds/point.py +994 -0
- sage/manifolds/scalarfield.py +3718 -0
- sage/manifolds/scalarfield_algebra.py +629 -0
- sage/manifolds/section.py +3111 -0
- sage/manifolds/section_module.py +831 -0
- sage/manifolds/structure.py +229 -0
- sage/manifolds/subset.py +2764 -0
- sage/manifolds/subsets/all.py +1 -0
- sage/manifolds/subsets/closure.py +131 -0
- sage/manifolds/subsets/pullback.py +885 -0
- sage/manifolds/topological_submanifold.py +891 -0
- sage/manifolds/trivialization.py +733 -0
- sage/manifolds/utilities.py +1348 -0
- sage/manifolds/vector_bundle.py +1342 -0
- sage/manifolds/vector_bundle_fiber.py +332 -0
- sage/manifolds/vector_bundle_fiber_element.py +111 -0
- sage/matrix/all__sagemath_symbolics.py +1 -0
- sage/matrix/matrix_symbolic_dense.cpython-310-x86_64-linux-gnu.so +0 -0
- sage/matrix/matrix_symbolic_dense.pxd +6 -0
- sage/matrix/matrix_symbolic_dense.pyx +1022 -0
- sage/matrix/matrix_symbolic_sparse.cpython-310-x86_64-linux-gnu.so +0 -0
- sage/matrix/matrix_symbolic_sparse.pxd +6 -0
- sage/matrix/matrix_symbolic_sparse.pyx +1029 -0
- sage/modules/all__sagemath_symbolics.py +1 -0
- sage/modules/vector_callable_symbolic_dense.py +105 -0
- sage/modules/vector_symbolic_dense.py +116 -0
- sage/modules/vector_symbolic_sparse.py +118 -0
- sage/rings/all__sagemath_symbolics.py +4 -0
- sage/rings/asymptotic/all.py +6 -0
- sage/rings/asymptotic/asymptotic_expansion_generators.py +1485 -0
- sage/rings/asymptotic/asymptotic_ring.py +4858 -0
- sage/rings/asymptotic/asymptotics_multivariate_generating_functions.py +4153 -0
- sage/rings/asymptotic/growth_group.py +5373 -0
- sage/rings/asymptotic/growth_group_cartesian.py +1400 -0
- sage/rings/asymptotic/term_monoid.py +5237 -0
- sage/rings/function_field/all__sagemath_symbolics.py +2 -0
- sage/rings/polynomial/all__sagemath_symbolics.py +1 -0
- sage/symbolic/all.py +15 -0
- sage/symbolic/assumptions.py +985 -0
- sage/symbolic/benchmark.py +93 -0
- sage/symbolic/callable.py +459 -0
- sage/symbolic/complexity_measures.py +35 -0
- sage/symbolic/constants.py +1287 -0
- sage/symbolic/expression_conversion_algebraic.py +310 -0
- sage/symbolic/expression_conversion_sympy.py +317 -0
- sage/symbolic/expression_conversions.py +1713 -0
- sage/symbolic/function_factory.py +355 -0
- sage/symbolic/integration/all.py +1 -0
- sage/symbolic/integration/external.py +270 -0
- sage/symbolic/integration/integral.py +1115 -0
- sage/symbolic/maxima_wrapper.py +162 -0
- sage/symbolic/operators.py +267 -0
- sage/symbolic/random_tests.py +462 -0
- sage/symbolic/relation.py +1907 -0
- sage/symbolic/ring.cpython-310-x86_64-linux-gnu.so +0 -0
- sage/symbolic/ring.pxd +5 -0
- sage/symbolic/ring.pyx +1396 -0
- sage/symbolic/subring.py +1025 -0
- sage/symbolic/symengine.py +19 -0
- sage/symbolic/tests.py +40 -0
- sage/symbolic/units.py +1470 -0
|
@@ -0,0 +1,1062 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-symbolics
|
|
2
|
+
r"""
|
|
3
|
+
Differential Form Modules
|
|
4
|
+
|
|
5
|
+
The set `\Omega^p(U, \Phi)` of `p`-forms along a differentiable manifold `U`
|
|
6
|
+
with values on a differentiable manifold `M` via a differentiable map
|
|
7
|
+
`\Phi:\ U \rightarrow M` (possibly `U = M` and `\Phi = \mathrm{Id}_M`)
|
|
8
|
+
is a module over the algebra `C^k(U)` of differentiable scalar fields on `U`.
|
|
9
|
+
It is a free module if and only if `M` is parallelizable. Accordingly,
|
|
10
|
+
two classes implement `\Omega^p(U, \Phi)`:
|
|
11
|
+
|
|
12
|
+
- :class:`DiffFormModule` for differential forms with values on a generic
|
|
13
|
+
(in practice, not parallelizable) differentiable manifold `M`
|
|
14
|
+
- :class:`DiffFormFreeModule` for differential forms with values on a
|
|
15
|
+
parallelizable manifold `M`
|
|
16
|
+
(the subclass :class:`VectorFieldDualFreeModule` implements the special
|
|
17
|
+
case of differential 1-forms on a parallelizable manifold `M`)
|
|
18
|
+
|
|
19
|
+
AUTHORS:
|
|
20
|
+
|
|
21
|
+
- Eric Gourgoulhon (2015): initial version
|
|
22
|
+
- Travis Scrimshaw (2016): review tweaks
|
|
23
|
+
- Matthias Koeppe (2022): :class:`VectorFieldDualFreeModule`
|
|
24
|
+
|
|
25
|
+
REFERENCES:
|
|
26
|
+
|
|
27
|
+
- [KN1963]_
|
|
28
|
+
- [Lee2013]_
|
|
29
|
+
"""
|
|
30
|
+
# *****************************************************************************
|
|
31
|
+
# Copyright (C) 2015-2021 Eric Gourgoulhon <eric.gourgoulhon@obspm.fr>
|
|
32
|
+
# 2016 Travis Scrimshaw <tscrimsh@umn.edu>
|
|
33
|
+
# 2020 Michael Jung
|
|
34
|
+
# 2022 Matthias Koeppe
|
|
35
|
+
#
|
|
36
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
|
37
|
+
# as published by the Free Software Foundation; either version 2 of
|
|
38
|
+
# the License, or (at your option) any later version.
|
|
39
|
+
# https://www.gnu.org/licenses/
|
|
40
|
+
# *****************************************************************************
|
|
41
|
+
|
|
42
|
+
from sage.categories.modules import Modules
|
|
43
|
+
from sage.manifolds.differentiable.diff_form import DiffForm, DiffFormParal
|
|
44
|
+
from sage.manifolds.differentiable.tensorfield import TensorField
|
|
45
|
+
from sage.manifolds.differentiable.tensorfield_paral import TensorFieldParal
|
|
46
|
+
from sage.misc.cachefunc import cached_method
|
|
47
|
+
from sage.structure.parent import Parent
|
|
48
|
+
from sage.structure.unique_representation import UniqueRepresentation
|
|
49
|
+
from sage.tensor.modules.ext_pow_free_module import ExtPowerDualFreeModule
|
|
50
|
+
from sage.tensor.modules.reflexive_module import ReflexiveModule_abstract
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
class DiffFormModule(UniqueRepresentation, Parent):
|
|
54
|
+
r"""
|
|
55
|
+
Module of differential forms of a given degree `p` (`p`-forms) along a
|
|
56
|
+
differentiable manifold `U` with values on a differentiable manifold `M`.
|
|
57
|
+
|
|
58
|
+
Given a differentiable manifold `U` and a differentiable map
|
|
59
|
+
`\Phi: U \rightarrow M` to a differentiable manifold `M`, the set
|
|
60
|
+
`\Omega^p(U, \Phi)` of `p`-forms along `U` with values on `M` is
|
|
61
|
+
a module over `C^k(U)`, the commutative algebra of differentiable
|
|
62
|
+
scalar fields on `U` (see
|
|
63
|
+
:class:`~sage.manifolds.differentiable.scalarfield_algebra.DiffScalarFieldAlgebra`).
|
|
64
|
+
The standard case of `p`-forms *on* a differentiable manifold `M`
|
|
65
|
+
corresponds to `U = M` and `\Phi = \mathrm{Id}_M`. Other common cases
|
|
66
|
+
are `\Phi` being an immersion and `\Phi` being a curve in `M`
|
|
67
|
+
(`U` is then an open interval of `\RR`).
|
|
68
|
+
|
|
69
|
+
.. NOTE::
|
|
70
|
+
|
|
71
|
+
This class implements `\Omega^p(U,\Phi)` in the case where `M` is
|
|
72
|
+
not assumed to be parallelizable; the module `\Omega^p(U, \Phi)`
|
|
73
|
+
is then not necessarily free. If `M` is parallelizable, the class
|
|
74
|
+
:class:`DiffFormFreeModule` must be used instead.
|
|
75
|
+
|
|
76
|
+
INPUT:
|
|
77
|
+
|
|
78
|
+
- ``vector_field_module`` -- module `\mathfrak{X}(U, \Phi)` of vector
|
|
79
|
+
fields along `U` with values on `M` via the map `\Phi: U \rightarrow M`
|
|
80
|
+
- ``degree`` -- positive integer; the degree `p` of the differential forms
|
|
81
|
+
|
|
82
|
+
EXAMPLES:
|
|
83
|
+
|
|
84
|
+
Module of 2-forms on a non-parallelizable 2-dimensional manifold::
|
|
85
|
+
|
|
86
|
+
sage: M = Manifold(2, 'M')
|
|
87
|
+
sage: U = M.open_subset('U') ; V = M.open_subset('V')
|
|
88
|
+
sage: M.declare_union(U,V) # M is the union of U and V
|
|
89
|
+
sage: c_xy.<x,y> = U.chart() ; c_uv.<u,v> = V.chart()
|
|
90
|
+
sage: transf = c_xy.transition_map(c_uv, (x+y, x-y),
|
|
91
|
+
....: intersection_name='W', restrictions1= x>0, restrictions2= u+v>0)
|
|
92
|
+
sage: inv = transf.inverse()
|
|
93
|
+
sage: W = U.intersection(V)
|
|
94
|
+
sage: eU = c_xy.frame() ; eV = c_uv.frame()
|
|
95
|
+
sage: XM = M.vector_field_module() ; XM
|
|
96
|
+
Module X(M) of vector fields on the 2-dimensional differentiable
|
|
97
|
+
manifold M
|
|
98
|
+
sage: A = M.diff_form_module(2) ; A
|
|
99
|
+
Module Omega^2(M) of 2-forms on the 2-dimensional differentiable
|
|
100
|
+
manifold M
|
|
101
|
+
sage: latex(A)
|
|
102
|
+
\Omega^{2}\left(M\right)
|
|
103
|
+
|
|
104
|
+
``A`` is nothing but the second exterior power of the dual of ``XM``, i.e.
|
|
105
|
+
we have `\Omega^{2}(M) = \Lambda^2(\mathfrak{X}(M)^*)`::
|
|
106
|
+
|
|
107
|
+
sage: A is XM.dual_exterior_power(2)
|
|
108
|
+
True
|
|
109
|
+
|
|
110
|
+
Modules of differential forms are unique::
|
|
111
|
+
|
|
112
|
+
sage: A is M.diff_form_module(2)
|
|
113
|
+
True
|
|
114
|
+
|
|
115
|
+
`\Omega^2(M)` is a module over the algebra `C^k(M)` of (differentiable)
|
|
116
|
+
scalar fields on `M`::
|
|
117
|
+
|
|
118
|
+
sage: A.category()
|
|
119
|
+
Category of modules over Algebra of differentiable scalar fields on
|
|
120
|
+
the 2-dimensional differentiable manifold M
|
|
121
|
+
sage: CM = M.scalar_field_algebra() ; CM
|
|
122
|
+
Algebra of differentiable scalar fields on the 2-dimensional
|
|
123
|
+
differentiable manifold M
|
|
124
|
+
sage: A in Modules(CM)
|
|
125
|
+
True
|
|
126
|
+
sage: A.base_ring() is CM
|
|
127
|
+
True
|
|
128
|
+
sage: A.base_module()
|
|
129
|
+
Module X(M) of vector fields on the 2-dimensional differentiable
|
|
130
|
+
manifold M
|
|
131
|
+
sage: A.base_module() is XM
|
|
132
|
+
True
|
|
133
|
+
|
|
134
|
+
Elements can be constructed from ``A()``. In particular, ``0`` yields
|
|
135
|
+
the zero element of ``A``::
|
|
136
|
+
|
|
137
|
+
sage: z = A(0) ; z
|
|
138
|
+
2-form zero on the 2-dimensional differentiable manifold M
|
|
139
|
+
sage: z.display(eU)
|
|
140
|
+
zero = 0
|
|
141
|
+
sage: z.display(eV)
|
|
142
|
+
zero = 0
|
|
143
|
+
sage: z is A.zero()
|
|
144
|
+
True
|
|
145
|
+
|
|
146
|
+
while nonzero elements are constructed by providing their components in a
|
|
147
|
+
given vector frame::
|
|
148
|
+
|
|
149
|
+
sage: a = A([[0,3*x],[-3*x,0]], frame=eU, name='a') ; a
|
|
150
|
+
2-form a on the 2-dimensional differentiable manifold M
|
|
151
|
+
sage: a.add_comp_by_continuation(eV, W, c_uv) # finishes initializ. of a
|
|
152
|
+
sage: a.display(eU)
|
|
153
|
+
a = 3*x dx∧dy
|
|
154
|
+
sage: a.display(eV)
|
|
155
|
+
a = (-3/4*u - 3/4*v) du∧dv
|
|
156
|
+
|
|
157
|
+
An alternative is to construct the 2-form from an empty list of
|
|
158
|
+
components and to set the nonzero nonredundant components afterwards::
|
|
159
|
+
|
|
160
|
+
sage: a = A([], name='a')
|
|
161
|
+
sage: a[eU,0,1] = 3*x
|
|
162
|
+
sage: a.add_comp_by_continuation(eV, W, c_uv)
|
|
163
|
+
sage: a.display(eU)
|
|
164
|
+
a = 3*x dx∧dy
|
|
165
|
+
sage: a.display(eV)
|
|
166
|
+
a = (-3/4*u - 3/4*v) du∧dv
|
|
167
|
+
|
|
168
|
+
The module `\Omega^1(M)` is nothing but the dual of `\mathfrak{X}(M)`
|
|
169
|
+
(the module of vector fields on `M`)::
|
|
170
|
+
|
|
171
|
+
sage: L1 = M.diff_form_module(1) ; L1
|
|
172
|
+
Module Omega^1(M) of 1-forms on the 2-dimensional differentiable
|
|
173
|
+
manifold M
|
|
174
|
+
sage: L1 is XM.dual()
|
|
175
|
+
True
|
|
176
|
+
|
|
177
|
+
Since any tensor field of type `(0,1)` is a 1-form, there is a coercion
|
|
178
|
+
map from the set `T^{(0,1)}(M)` of such tensors to `\Omega^1(M)`::
|
|
179
|
+
|
|
180
|
+
sage: T01 = M.tensor_field_module((0,1)) ; T01
|
|
181
|
+
Module T^(0,1)(M) of type-(0,1) tensors fields on the 2-dimensional
|
|
182
|
+
differentiable manifold M
|
|
183
|
+
sage: L1.has_coerce_map_from(T01)
|
|
184
|
+
True
|
|
185
|
+
|
|
186
|
+
There is also a coercion map in the reverse direction::
|
|
187
|
+
|
|
188
|
+
sage: T01.has_coerce_map_from(L1)
|
|
189
|
+
True
|
|
190
|
+
|
|
191
|
+
For a degree `p \geq 2`, the coercion holds only in the direction
|
|
192
|
+
`\Omega^p(M)\rightarrow T^{(0,p)}(M)`::
|
|
193
|
+
|
|
194
|
+
sage: T02 = M.tensor_field_module((0,2)) ; T02
|
|
195
|
+
Module T^(0,2)(M) of type-(0,2) tensors fields on the 2-dimensional
|
|
196
|
+
differentiable manifold M
|
|
197
|
+
sage: T02.has_coerce_map_from(A)
|
|
198
|
+
True
|
|
199
|
+
sage: A.has_coerce_map_from(T02)
|
|
200
|
+
False
|
|
201
|
+
|
|
202
|
+
The coercion map `T^{(0,1)}(M) \rightarrow \Omega^1(M)` in action::
|
|
203
|
+
|
|
204
|
+
sage: b = T01([y,x], frame=eU, name='b') ; b
|
|
205
|
+
Tensor field b of type (0,1) on the 2-dimensional differentiable
|
|
206
|
+
manifold M
|
|
207
|
+
sage: b.add_comp_by_continuation(eV, W, c_uv)
|
|
208
|
+
sage: b.display(eU)
|
|
209
|
+
b = y dx + x dy
|
|
210
|
+
sage: b.display(eV)
|
|
211
|
+
b = 1/2*u du - 1/2*v dv
|
|
212
|
+
sage: lb = L1(b) ; lb
|
|
213
|
+
1-form b on the 2-dimensional differentiable manifold M
|
|
214
|
+
sage: lb.display(eU)
|
|
215
|
+
b = y dx + x dy
|
|
216
|
+
sage: lb.display(eV)
|
|
217
|
+
b = 1/2*u du - 1/2*v dv
|
|
218
|
+
|
|
219
|
+
The coercion map `\Omega^1(M) \rightarrow T^{(0,1)}(M)` in action::
|
|
220
|
+
|
|
221
|
+
sage: tlb = T01(lb) ; tlb
|
|
222
|
+
Tensor field b of type (0,1) on the 2-dimensional differentiable
|
|
223
|
+
manifold M
|
|
224
|
+
sage: tlb.display(eU)
|
|
225
|
+
b = y dx + x dy
|
|
226
|
+
sage: tlb.display(eV)
|
|
227
|
+
b = 1/2*u du - 1/2*v dv
|
|
228
|
+
sage: tlb == b
|
|
229
|
+
True
|
|
230
|
+
|
|
231
|
+
The coercion map `\Omega^2(M) \rightarrow T^{(0,2)}(M)` in action::
|
|
232
|
+
|
|
233
|
+
sage: ta = T02(a) ; ta
|
|
234
|
+
Tensor field a of type (0,2) on the 2-dimensional differentiable
|
|
235
|
+
manifold M
|
|
236
|
+
sage: ta.display(eU)
|
|
237
|
+
a = 3*x dx⊗dy - 3*x dy⊗dx
|
|
238
|
+
sage: a.display(eU)
|
|
239
|
+
a = 3*x dx∧dy
|
|
240
|
+
sage: ta.display(eV)
|
|
241
|
+
a = (-3/4*u - 3/4*v) du⊗dv + (3/4*u + 3/4*v) dv⊗du
|
|
242
|
+
sage: a.display(eV)
|
|
243
|
+
a = (-3/4*u - 3/4*v) du∧dv
|
|
244
|
+
|
|
245
|
+
There is also coercion to subdomains, which is nothing but the restriction
|
|
246
|
+
of the differential form to some subset of its domain::
|
|
247
|
+
|
|
248
|
+
sage: L2U = U.diff_form_module(2) ; L2U
|
|
249
|
+
Free module Omega^2(U) of 2-forms on the Open subset U of the
|
|
250
|
+
2-dimensional differentiable manifold M
|
|
251
|
+
sage: L2U.has_coerce_map_from(A)
|
|
252
|
+
True
|
|
253
|
+
sage: a_U = L2U(a) ; a_U
|
|
254
|
+
2-form a on the Open subset U of the 2-dimensional differentiable
|
|
255
|
+
manifold M
|
|
256
|
+
sage: a_U.display(eU)
|
|
257
|
+
a = 3*x dx∧dy
|
|
258
|
+
"""
|
|
259
|
+
Element = DiffForm
|
|
260
|
+
|
|
261
|
+
def __init__(self, vector_field_module, degree):
|
|
262
|
+
r"""
|
|
263
|
+
Construction a module of differential forms.
|
|
264
|
+
|
|
265
|
+
TESTS:
|
|
266
|
+
|
|
267
|
+
Module of 2-forms on a non-parallelizable 2-dimensional manifold::
|
|
268
|
+
|
|
269
|
+
sage: M = Manifold(2, 'M')
|
|
270
|
+
sage: U = M.open_subset('U') ; V = M.open_subset('V')
|
|
271
|
+
sage: M.declare_union(U,V) # M is the union of U and V
|
|
272
|
+
sage: c_xy.<x,y> = U.chart() ; c_uv.<u,v> = V.chart()
|
|
273
|
+
sage: transf = c_xy.transition_map(c_uv, (x+y, x-y),
|
|
274
|
+
....: intersection_name='W', restrictions1= x>0,
|
|
275
|
+
....: restrictions2= u+v>0)
|
|
276
|
+
sage: inv = transf.inverse()
|
|
277
|
+
sage: from sage.manifolds.differentiable.diff_form_module import \
|
|
278
|
+
....: DiffFormModule
|
|
279
|
+
sage: A = DiffFormModule(M.vector_field_module(), 2) ; A
|
|
280
|
+
Module Omega^2(M) of 2-forms on the 2-dimensional differentiable
|
|
281
|
+
manifold M
|
|
282
|
+
sage: TestSuite(A).run(skip='_test_elements')
|
|
283
|
+
|
|
284
|
+
In the above test suite, ``_test_elements`` is skipped because of the
|
|
285
|
+
``_test_pickling`` error of the elements (to be fixed in
|
|
286
|
+
:class:`sage.manifolds.differentiable.tensorfield.TensorField`)
|
|
287
|
+
"""
|
|
288
|
+
domain = vector_field_module._domain
|
|
289
|
+
dest_map = vector_field_module._dest_map
|
|
290
|
+
name = "Omega^{}(".format(degree) + domain._name
|
|
291
|
+
latex_name = r"\Omega^{{{}}}\left({}".format(degree, domain._latex_name)
|
|
292
|
+
if dest_map is not domain.identity_map():
|
|
293
|
+
dm_name = dest_map._name
|
|
294
|
+
dm_latex_name = dest_map._latex_name
|
|
295
|
+
if dm_name is None:
|
|
296
|
+
dm_name = "unnamed map"
|
|
297
|
+
if dm_latex_name is None:
|
|
298
|
+
dm_latex_name = r"\mathrm{unnamed\; map}"
|
|
299
|
+
name += "," + dm_name
|
|
300
|
+
latex_name += "," + dm_latex_name
|
|
301
|
+
self._name = name + ")"
|
|
302
|
+
self._latex_name = latex_name + r"\right)"
|
|
303
|
+
self._vmodule = vector_field_module
|
|
304
|
+
self._degree = degree
|
|
305
|
+
# the member self._ring is created for efficiency (to avoid calls to
|
|
306
|
+
# self.base_ring()):
|
|
307
|
+
self._ring = domain.scalar_field_algebra()
|
|
308
|
+
Parent.__init__(self, base=self._ring, category=Modules(self._ring))
|
|
309
|
+
self._domain = domain
|
|
310
|
+
self._dest_map = dest_map
|
|
311
|
+
self._ambient_domain = vector_field_module._ambient_domain
|
|
312
|
+
# NB: self._zero_element is not constructed here, since no element
|
|
313
|
+
# can be constructed here, to avoid some infinite recursion.
|
|
314
|
+
|
|
315
|
+
#### Parent methods
|
|
316
|
+
|
|
317
|
+
def _element_constructor_(self, comp=[], frame=None, name=None,
|
|
318
|
+
latex_name=None):
|
|
319
|
+
r"""
|
|
320
|
+
Construct a differential form.
|
|
321
|
+
|
|
322
|
+
TESTS::
|
|
323
|
+
|
|
324
|
+
sage: M = Manifold(2, 'M')
|
|
325
|
+
sage: U = M.open_subset('U'); V = M.open_subset('V')
|
|
326
|
+
sage: c_xy.<x,y> = U.chart(); c_uv.<u,v> = V.chart()
|
|
327
|
+
sage: M.declare_union(U,V)
|
|
328
|
+
sage: A = M.diff_form_module(2)
|
|
329
|
+
sage: a = A([[0, x*y], [-x*y, 0]], name='a'); a
|
|
330
|
+
2-form a on the 2-dimensional differentiable manifold M
|
|
331
|
+
sage: a.display(c_xy.frame())
|
|
332
|
+
a = x*y dx∧dy
|
|
333
|
+
sage: A(0) is A.zero()
|
|
334
|
+
True
|
|
335
|
+
"""
|
|
336
|
+
try:
|
|
337
|
+
if comp.is_trivial_zero():
|
|
338
|
+
return self.zero()
|
|
339
|
+
except AttributeError:
|
|
340
|
+
if comp == 0:
|
|
341
|
+
return self.zero()
|
|
342
|
+
if isinstance(comp, (DiffForm, DiffFormParal)):
|
|
343
|
+
# coercion by domain restriction
|
|
344
|
+
if (self._degree == comp._tensor_type[1]
|
|
345
|
+
and self._domain.is_subset(comp._domain)
|
|
346
|
+
and self._ambient_domain.is_subset(comp._ambient_domain)):
|
|
347
|
+
return comp.restrict(self._domain)
|
|
348
|
+
else:
|
|
349
|
+
raise TypeError("cannot convert the {} ".format(comp) +
|
|
350
|
+
"to an element of {}".format(self))
|
|
351
|
+
if isinstance(comp, TensorField):
|
|
352
|
+
# coercion of a tensor of type (0,1) to a linear form
|
|
353
|
+
tensor = comp # for readability
|
|
354
|
+
if (tensor.tensor_type() == (0,1) and self._degree == 1
|
|
355
|
+
and tensor._vmodule is self._vmodule):
|
|
356
|
+
resu = self.element_class(self._vmodule, 1, name=tensor._name,
|
|
357
|
+
latex_name=tensor._latex_name)
|
|
358
|
+
for dom, rst in tensor._restrictions.items():
|
|
359
|
+
resu._restrictions[dom] = dom.diff_form_module(1)(rst)
|
|
360
|
+
return resu
|
|
361
|
+
else:
|
|
362
|
+
raise TypeError("cannot convert the {} ".format(tensor) +
|
|
363
|
+
"to an element of {}".format(self))
|
|
364
|
+
if not isinstance(comp, (list, tuple)):
|
|
365
|
+
raise TypeError("cannot convert the {} ".format(comp) +
|
|
366
|
+
"to an element of {}".format(self))
|
|
367
|
+
# standard construction
|
|
368
|
+
resu = self.element_class(self._vmodule, self._degree, name=name,
|
|
369
|
+
latex_name=latex_name)
|
|
370
|
+
if comp:
|
|
371
|
+
resu.set_comp(frame)[:] = comp
|
|
372
|
+
return resu
|
|
373
|
+
|
|
374
|
+
def _an_element_(self):
|
|
375
|
+
r"""
|
|
376
|
+
Construct some (unnamed) differential form.
|
|
377
|
+
|
|
378
|
+
TESTS::
|
|
379
|
+
|
|
380
|
+
sage: M = Manifold(2, 'M')
|
|
381
|
+
sage: U = M.open_subset('U'); V = M.open_subset('V')
|
|
382
|
+
sage: c_xy.<x,y> = U.chart(); c_uv.<u,v> = V.chart()
|
|
383
|
+
sage: M.declare_union(U,V)
|
|
384
|
+
sage: A = M.diff_form_module(2)
|
|
385
|
+
sage: A._an_element_()
|
|
386
|
+
2-form on the 2-dimensional differentiable manifold M
|
|
387
|
+
"""
|
|
388
|
+
resu = self.element_class(self._vmodule, self._degree)
|
|
389
|
+
for oc in self._domain.open_covers(trivial=False):
|
|
390
|
+
# the first non-trivial open cover is selected
|
|
391
|
+
for dom in oc:
|
|
392
|
+
vmodule_dom = dom.vector_field_module(
|
|
393
|
+
dest_map=self._dest_map.restrict(dom))
|
|
394
|
+
dmodule_dom = vmodule_dom.dual_exterior_power(self._degree)
|
|
395
|
+
resu.set_restriction(dmodule_dom._an_element_())
|
|
396
|
+
return resu
|
|
397
|
+
return resu
|
|
398
|
+
|
|
399
|
+
def _coerce_map_from_(self, other):
|
|
400
|
+
r"""
|
|
401
|
+
Determine whether coercion to ``self`` exists from other parent.
|
|
402
|
+
|
|
403
|
+
TESTS::
|
|
404
|
+
|
|
405
|
+
sage: M = Manifold(3, 'M')
|
|
406
|
+
sage: A1 = M.diff_form_module(1)
|
|
407
|
+
sage: A1._coerce_map_from_(M.tensor_field_module((0,1)))
|
|
408
|
+
True
|
|
409
|
+
sage: A2 = M.diff_form_module(2)
|
|
410
|
+
sage: A2._coerce_map_from_(M.tensor_field_module((0,2)))
|
|
411
|
+
False
|
|
412
|
+
sage: U = M.open_subset('U')
|
|
413
|
+
sage: A2U = U.diff_form_module(2)
|
|
414
|
+
sage: A2U._coerce_map_from_(A2)
|
|
415
|
+
True
|
|
416
|
+
sage: A2._coerce_map_from_(A2U)
|
|
417
|
+
False
|
|
418
|
+
"""
|
|
419
|
+
if isinstance(other, (DiffFormModule, DiffFormFreeModule)):
|
|
420
|
+
# coercion by domain restriction
|
|
421
|
+
return (self._degree == other._degree
|
|
422
|
+
and self._domain.is_subset(other._domain)
|
|
423
|
+
and self._ambient_domain.is_subset(other._ambient_domain))
|
|
424
|
+
|
|
425
|
+
from sage.manifolds.differentiable.tensorfield_module import TensorFieldModule
|
|
426
|
+
if isinstance(other, TensorFieldModule):
|
|
427
|
+
# coercion of a type-(0,1) tensor to a linear form
|
|
428
|
+
return (self._vmodule is other._vmodule and self._degree == 1
|
|
429
|
+
and other.tensor_type() == (0,1))
|
|
430
|
+
|
|
431
|
+
return False
|
|
432
|
+
|
|
433
|
+
@cached_method
|
|
434
|
+
def zero(self):
|
|
435
|
+
"""
|
|
436
|
+
Return the zero of ``self``.
|
|
437
|
+
|
|
438
|
+
EXAMPLES::
|
|
439
|
+
|
|
440
|
+
sage: M = Manifold(3, 'M')
|
|
441
|
+
sage: A2 = M.diff_form_module(2)
|
|
442
|
+
sage: A2.zero()
|
|
443
|
+
2-form zero on the 3-dimensional differentiable manifold M
|
|
444
|
+
"""
|
|
445
|
+
zero = self._element_constructor_(name='zero', latex_name='0')
|
|
446
|
+
for frame in self._domain._frames:
|
|
447
|
+
if self._dest_map.restrict(frame._domain) == frame._dest_map:
|
|
448
|
+
zero.add_comp(frame)
|
|
449
|
+
# (since new components are initialized to zero)
|
|
450
|
+
zero._is_zero = True # This element is certainly zero
|
|
451
|
+
zero.set_immutable()
|
|
452
|
+
return zero
|
|
453
|
+
|
|
454
|
+
#### End of Parent methods
|
|
455
|
+
|
|
456
|
+
def _repr_(self):
|
|
457
|
+
r"""
|
|
458
|
+
Return a string representation of the object.
|
|
459
|
+
|
|
460
|
+
TESTS::
|
|
461
|
+
|
|
462
|
+
sage: M = Manifold(3, 'M')
|
|
463
|
+
sage: A2 = M.diff_form_module(2)
|
|
464
|
+
sage: A2
|
|
465
|
+
Module Omega^2(M) of 2-forms on
|
|
466
|
+
the 3-dimensional differentiable manifold M
|
|
467
|
+
"""
|
|
468
|
+
description = "Module "
|
|
469
|
+
if self._name is not None:
|
|
470
|
+
description += self._name + " "
|
|
471
|
+
description += "of {}-forms ".format(self._degree)
|
|
472
|
+
if self._dest_map is self._domain.identity_map():
|
|
473
|
+
description += "on the {}".format(self._domain)
|
|
474
|
+
else:
|
|
475
|
+
description += "along the {} mapped into the {}".format(
|
|
476
|
+
self._domain, self._ambient_domain)
|
|
477
|
+
return description
|
|
478
|
+
|
|
479
|
+
def _latex_(self):
|
|
480
|
+
r"""
|
|
481
|
+
Return a LaTeX representation of the object.
|
|
482
|
+
|
|
483
|
+
TESTS::
|
|
484
|
+
|
|
485
|
+
sage: M = Manifold(3, 'M', latex_name=r'\mathcal{M}')
|
|
486
|
+
sage: A2 = M.diff_form_module(2)
|
|
487
|
+
sage: A2._latex_()
|
|
488
|
+
'\\Omega^{2}\\left(\\mathcal{M}\\right)'
|
|
489
|
+
sage: latex(A2) # indirect doctest
|
|
490
|
+
\Omega^{2}\left(\mathcal{M}\right)
|
|
491
|
+
"""
|
|
492
|
+
if self._latex_name is None:
|
|
493
|
+
return r'\text{' + str(self) + r'}'
|
|
494
|
+
else:
|
|
495
|
+
return self._latex_name
|
|
496
|
+
|
|
497
|
+
def base_module(self):
|
|
498
|
+
r"""
|
|
499
|
+
Return the vector field module on which the differential form module
|
|
500
|
+
``self`` is constructed.
|
|
501
|
+
|
|
502
|
+
OUTPUT:
|
|
503
|
+
|
|
504
|
+
- a
|
|
505
|
+
:class:`~sage.manifolds.differentiable.vectorfield_module.VectorFieldModule`
|
|
506
|
+
representing the module on which ``self`` is defined
|
|
507
|
+
|
|
508
|
+
EXAMPLES::
|
|
509
|
+
|
|
510
|
+
sage: M = Manifold(3, 'M')
|
|
511
|
+
sage: A2 = M.diff_form_module(2) ; A2
|
|
512
|
+
Module Omega^2(M) of 2-forms on the 3-dimensional differentiable
|
|
513
|
+
manifold M
|
|
514
|
+
sage: A2.base_module()
|
|
515
|
+
Module X(M) of vector fields on the 3-dimensional differentiable
|
|
516
|
+
manifold M
|
|
517
|
+
sage: A2.base_module() is M.vector_field_module()
|
|
518
|
+
True
|
|
519
|
+
sage: U = M.open_subset('U')
|
|
520
|
+
sage: A2U = U.diff_form_module(2) ; A2U
|
|
521
|
+
Module Omega^2(U) of 2-forms on the Open subset U of the
|
|
522
|
+
3-dimensional differentiable manifold M
|
|
523
|
+
sage: A2U.base_module()
|
|
524
|
+
Module X(U) of vector fields on the Open subset U of the
|
|
525
|
+
3-dimensional differentiable manifold M
|
|
526
|
+
"""
|
|
527
|
+
return self._vmodule
|
|
528
|
+
|
|
529
|
+
tensor = tensor_product = ReflexiveModule_abstract.tensor_product
|
|
530
|
+
|
|
531
|
+
def tensor_type(self):
|
|
532
|
+
r"""
|
|
533
|
+
Return the tensor type of ``self`` if ``self`` is a module of 1-forms.
|
|
534
|
+
|
|
535
|
+
In this case, the pair `(0, 1)` is returned, indicating that the module
|
|
536
|
+
is identified with the dual of the base module.
|
|
537
|
+
|
|
538
|
+
For differential forms of other degrees, an exception is raised.
|
|
539
|
+
|
|
540
|
+
EXAMPLES::
|
|
541
|
+
|
|
542
|
+
sage: M = Manifold(3, 'M')
|
|
543
|
+
sage: M.diff_form_module(1).tensor_type()
|
|
544
|
+
(0, 1)
|
|
545
|
+
sage: M.diff_form_module(2).tensor_type()
|
|
546
|
+
Traceback (most recent call last):
|
|
547
|
+
...
|
|
548
|
+
NotImplementedError
|
|
549
|
+
"""
|
|
550
|
+
if self._degree == 1:
|
|
551
|
+
return (0, 1)
|
|
552
|
+
raise NotImplementedError
|
|
553
|
+
|
|
554
|
+
def degree(self):
|
|
555
|
+
r"""
|
|
556
|
+
Return the degree of the differential forms in ``self``.
|
|
557
|
+
|
|
558
|
+
OUTPUT: integer `p` such that ``self`` is a set of `p`-forms
|
|
559
|
+
|
|
560
|
+
EXAMPLES::
|
|
561
|
+
|
|
562
|
+
sage: M = Manifold(3, 'M')
|
|
563
|
+
sage: M.diff_form_module(1).degree()
|
|
564
|
+
1
|
|
565
|
+
sage: M.diff_form_module(2).degree()
|
|
566
|
+
2
|
|
567
|
+
sage: M.diff_form_module(3).degree()
|
|
568
|
+
3
|
|
569
|
+
"""
|
|
570
|
+
return self._degree
|
|
571
|
+
|
|
572
|
+
# *****************************************************************************
|
|
573
|
+
|
|
574
|
+
|
|
575
|
+
class DiffFormFreeModule(ExtPowerDualFreeModule):
|
|
576
|
+
r"""
|
|
577
|
+
Free module of differential forms of a given degree `p` (`p`-forms) along
|
|
578
|
+
a differentiable manifold `U` with values on a parallelizable manifold `M`.
|
|
579
|
+
|
|
580
|
+
Given a differentiable manifold `U` and a differentiable map
|
|
581
|
+
`\Phi:\; U \rightarrow M` to a parallelizable manifold `M` of dimension
|
|
582
|
+
`n`, the set `\Omega^p(U, \Phi)` of `p`-forms along `U` with values on `M`
|
|
583
|
+
is a free module of rank `\binom{n}{p}` over `C^k(U)`, the commutative
|
|
584
|
+
algebra of differentiable scalar fields on `U` (see
|
|
585
|
+
:class:`~sage.manifolds.differentiable.scalarfield_algebra.DiffScalarFieldAlgebra`).
|
|
586
|
+
The standard case of `p`-forms *on* a differentiable manifold `M`
|
|
587
|
+
corresponds to `U = M` and `\Phi = \mathrm{Id}_M`. Other common cases are
|
|
588
|
+
`\Phi` being an immersion and `\Phi` being a curve in `M` (`U` is then an
|
|
589
|
+
open interval of `\RR`).
|
|
590
|
+
|
|
591
|
+
.. NOTE::
|
|
592
|
+
|
|
593
|
+
This class implements `\Omega^p(U, \Phi)` in the case where `M` is
|
|
594
|
+
parallelizable; `\Omega^p(U, \Phi)` is then a *free* module. If `M`
|
|
595
|
+
is not parallelizable, the class :class:`DiffFormModule` must be used
|
|
596
|
+
instead.
|
|
597
|
+
|
|
598
|
+
For the special case of 1-forms, use the class :class:`VectorFieldDualFreeModule`.
|
|
599
|
+
|
|
600
|
+
INPUT:
|
|
601
|
+
|
|
602
|
+
- ``vector_field_module`` -- free module `\mathfrak{X}(U,\Phi)` of vector
|
|
603
|
+
fields along `U` associated with the map `\Phi: U \rightarrow V`
|
|
604
|
+
- ``degree`` -- positive integer; the degree `p` of the differential forms
|
|
605
|
+
|
|
606
|
+
EXAMPLES:
|
|
607
|
+
|
|
608
|
+
Free module of 2-forms on a parallelizable 3-dimensional manifold::
|
|
609
|
+
|
|
610
|
+
sage: M = Manifold(3, 'M')
|
|
611
|
+
sage: X.<x,y,z> = M.chart()
|
|
612
|
+
sage: XM = M.vector_field_module() ; XM
|
|
613
|
+
Free module X(M) of vector fields on the 3-dimensional differentiable
|
|
614
|
+
manifold M
|
|
615
|
+
sage: A = M.diff_form_module(2) ; A
|
|
616
|
+
Free module Omega^2(M) of 2-forms on the 3-dimensional differentiable
|
|
617
|
+
manifold M
|
|
618
|
+
sage: latex(A)
|
|
619
|
+
\Omega^{2}\left(M\right)
|
|
620
|
+
|
|
621
|
+
``A`` is nothing but the second exterior power of the dual of ``XM``, i.e.
|
|
622
|
+
we have `\Omega^{2}(M) = \Lambda^2(\mathfrak{X}(M)^*)` (see
|
|
623
|
+
:class:`~sage.tensor.modules.ext_pow_free_module.ExtPowerDualFreeModule`)::
|
|
624
|
+
|
|
625
|
+
sage: A is XM.dual_exterior_power(2)
|
|
626
|
+
True
|
|
627
|
+
|
|
628
|
+
`\Omega^{2}(M)` is a module over the algebra `C^k(M)` of (differentiable)
|
|
629
|
+
scalar fields on `M`::
|
|
630
|
+
|
|
631
|
+
sage: A.category()
|
|
632
|
+
Category of finite dimensional modules over Algebra of differentiable
|
|
633
|
+
scalar fields on the 3-dimensional differentiable manifold M
|
|
634
|
+
sage: CM = M.scalar_field_algebra() ; CM
|
|
635
|
+
Algebra of differentiable scalar fields on the 3-dimensional
|
|
636
|
+
differentiable manifold M
|
|
637
|
+
sage: A in Modules(CM)
|
|
638
|
+
True
|
|
639
|
+
sage: A.base_ring()
|
|
640
|
+
Algebra of differentiable scalar fields on
|
|
641
|
+
the 3-dimensional differentiable manifold M
|
|
642
|
+
sage: A.base_module()
|
|
643
|
+
Free module X(M) of vector fields on
|
|
644
|
+
the 3-dimensional differentiable manifold M
|
|
645
|
+
sage: A.base_module() is XM
|
|
646
|
+
True
|
|
647
|
+
sage: A.rank()
|
|
648
|
+
3
|
|
649
|
+
|
|
650
|
+
Elements can be constructed from `A`. In particular, ``0`` yields
|
|
651
|
+
the zero element of `A`::
|
|
652
|
+
|
|
653
|
+
sage: A(0)
|
|
654
|
+
2-form zero on the 3-dimensional differentiable manifold M
|
|
655
|
+
sage: A(0) is A.zero()
|
|
656
|
+
True
|
|
657
|
+
|
|
658
|
+
while nonzero elements are constructed by providing their components
|
|
659
|
+
in a given vector frame::
|
|
660
|
+
|
|
661
|
+
sage: comp = [[0,3*x,-z],[-3*x,0,4],[z,-4,0]]
|
|
662
|
+
sage: a = A(comp, frame=X.frame(), name='a') ; a
|
|
663
|
+
2-form a on the 3-dimensional differentiable manifold M
|
|
664
|
+
sage: a.display()
|
|
665
|
+
a = 3*x dx∧dy - z dx∧dz + 4 dy∧dz
|
|
666
|
+
|
|
667
|
+
An alternative is to construct the 2-form from an empty list of
|
|
668
|
+
components and to set the nonzero nonredundant components afterwards::
|
|
669
|
+
|
|
670
|
+
sage: a = A([], name='a')
|
|
671
|
+
sage: a[0,1] = 3*x # component in the manifold's default frame
|
|
672
|
+
sage: a[0,2] = -z
|
|
673
|
+
sage: a[1,2] = 4
|
|
674
|
+
sage: a.display()
|
|
675
|
+
a = 3*x dx∧dy - z dx∧dz + 4 dy∧dz
|
|
676
|
+
|
|
677
|
+
The module `\Omega^1(M)` is nothing but the dual of `\mathfrak{X}(M)`
|
|
678
|
+
(the free module of vector fields on `M`)::
|
|
679
|
+
|
|
680
|
+
sage: L1 = M.diff_form_module(1) ; L1
|
|
681
|
+
Free module Omega^1(M) of 1-forms on the 3-dimensional differentiable
|
|
682
|
+
manifold M
|
|
683
|
+
sage: L1 is XM.dual()
|
|
684
|
+
True
|
|
685
|
+
|
|
686
|
+
Since any tensor field of type `(0,1)` is a 1-form, it is also equal to
|
|
687
|
+
the set `T^{(0,1)}(M)` of such tensors to `\Omega^1(M)`::
|
|
688
|
+
|
|
689
|
+
sage: T01 = M.tensor_field_module((0,1)) ; T01
|
|
690
|
+
Free module Omega^1(M) of 1-forms on the 3-dimensional differentiable manifold M
|
|
691
|
+
sage: L1 is T01
|
|
692
|
+
True
|
|
693
|
+
|
|
694
|
+
For a degree `p \geq 2`, the coercion holds only in the direction
|
|
695
|
+
`\Omega^p(M) \rightarrow T^{(0,p)}(M)`::
|
|
696
|
+
|
|
697
|
+
sage: T02 = M.tensor_field_module((0,2)); T02
|
|
698
|
+
Free module T^(0,2)(M) of type-(0,2) tensors fields on the
|
|
699
|
+
3-dimensional differentiable manifold M
|
|
700
|
+
sage: T02.has_coerce_map_from(A)
|
|
701
|
+
True
|
|
702
|
+
sage: A.has_coerce_map_from(T02)
|
|
703
|
+
False
|
|
704
|
+
|
|
705
|
+
The coercion map `\Omega^2(M) \rightarrow T^{(0,2)}(M)` in action::
|
|
706
|
+
|
|
707
|
+
sage: T02 = M.tensor_field_module((0,2)) ; T02
|
|
708
|
+
Free module T^(0,2)(M) of type-(0,2) tensors fields on the
|
|
709
|
+
3-dimensional differentiable manifold M
|
|
710
|
+
sage: ta = T02(a) ; ta
|
|
711
|
+
Tensor field a of type (0,2) on the 3-dimensional differentiable
|
|
712
|
+
manifold M
|
|
713
|
+
sage: ta.display()
|
|
714
|
+
a = 3*x dx⊗dy - z dx⊗dz - 3*x dy⊗dx + 4 dy⊗dz + z dz⊗dx - 4 dz⊗dy
|
|
715
|
+
sage: a.display()
|
|
716
|
+
a = 3*x dx∧dy - z dx∧dz + 4 dy∧dz
|
|
717
|
+
sage: ta.symmetries() # the antisymmetry is preserved
|
|
718
|
+
no symmetry; antisymmetry: (0, 1)
|
|
719
|
+
|
|
720
|
+
There is also coercion to subdomains, which is nothing but the
|
|
721
|
+
restriction of the differential form to some subset of its domain::
|
|
722
|
+
|
|
723
|
+
sage: U = M.open_subset('U', coord_def={X: x^2+y^2<1})
|
|
724
|
+
sage: B = U.diff_form_module(2) ; B
|
|
725
|
+
Free module Omega^2(U) of 2-forms on the Open subset U of the
|
|
726
|
+
3-dimensional differentiable manifold M
|
|
727
|
+
sage: B.has_coerce_map_from(A)
|
|
728
|
+
True
|
|
729
|
+
sage: a_U = B(a) ; a_U
|
|
730
|
+
2-form a on the Open subset U of the 3-dimensional differentiable
|
|
731
|
+
manifold M
|
|
732
|
+
sage: a_U.display()
|
|
733
|
+
a = 3*x dx∧dy - z dx∧dz + 4 dy∧dz
|
|
734
|
+
"""
|
|
735
|
+
|
|
736
|
+
Element = DiffFormParal
|
|
737
|
+
|
|
738
|
+
def __init__(self, vector_field_module, degree):
|
|
739
|
+
r"""
|
|
740
|
+
Construct a free module of differential forms.
|
|
741
|
+
|
|
742
|
+
TESTS::
|
|
743
|
+
|
|
744
|
+
sage: M = Manifold(3, 'M')
|
|
745
|
+
sage: X.<x,y,z> = M.chart()
|
|
746
|
+
sage: from sage.manifolds.differentiable.diff_form_module import DiffFormFreeModule
|
|
747
|
+
sage: A = DiffFormFreeModule(M.vector_field_module(), 2) ; A
|
|
748
|
+
Free module Omega^2(M) of 2-forms on
|
|
749
|
+
the 3-dimensional differentiable manifold M
|
|
750
|
+
sage: TestSuite(A).run()
|
|
751
|
+
"""
|
|
752
|
+
domain = vector_field_module._domain
|
|
753
|
+
dest_map = vector_field_module._dest_map
|
|
754
|
+
name = "Omega^{}(".format(degree) + domain._name
|
|
755
|
+
latex_name = r"\Omega^{{{}}}\left({}".format(degree, domain._latex_name)
|
|
756
|
+
if dest_map is not domain.identity_map():
|
|
757
|
+
dm_name = dest_map._name
|
|
758
|
+
dm_latex_name = dest_map._latex_name
|
|
759
|
+
if dm_name is None:
|
|
760
|
+
dm_name = "unnamed map"
|
|
761
|
+
if dm_latex_name is None:
|
|
762
|
+
dm_latex_name = r"\mathrm{unnamed\; map}"
|
|
763
|
+
name += "," + dm_name
|
|
764
|
+
latex_name += "," + dm_latex_name
|
|
765
|
+
name += ")"
|
|
766
|
+
latex_name += r"\right)"
|
|
767
|
+
ExtPowerDualFreeModule.__init__(self, vector_field_module, degree,
|
|
768
|
+
name=name, latex_name=latex_name)
|
|
769
|
+
self._domain = domain
|
|
770
|
+
self._dest_map = dest_map
|
|
771
|
+
self._ambient_domain = vector_field_module._ambient_domain
|
|
772
|
+
|
|
773
|
+
#### Parent methods
|
|
774
|
+
|
|
775
|
+
def _element_constructor_(self, comp=[], frame=None, name=None,
|
|
776
|
+
latex_name=None):
|
|
777
|
+
r"""
|
|
778
|
+
Construct a differential form.
|
|
779
|
+
|
|
780
|
+
TESTS::
|
|
781
|
+
|
|
782
|
+
sage: M = Manifold(2, 'M')
|
|
783
|
+
sage: X.<x,y> = M.chart() # makes M parallelizable
|
|
784
|
+
sage: A = M.diff_form_module(2)
|
|
785
|
+
sage: a = A([[0, x], [-x, 0]], name='a'); a
|
|
786
|
+
2-form a on the 2-dimensional differentiable manifold M
|
|
787
|
+
sage: a.display()
|
|
788
|
+
a = x dx∧dy
|
|
789
|
+
sage: A(0) is A.zero()
|
|
790
|
+
True
|
|
791
|
+
|
|
792
|
+
Check that :issue:`27658` is fixed::
|
|
793
|
+
|
|
794
|
+
sage: f = M.scalar_field(x)
|
|
795
|
+
sage: f in A
|
|
796
|
+
False
|
|
797
|
+
"""
|
|
798
|
+
try:
|
|
799
|
+
if comp.is_trivial_zero():
|
|
800
|
+
return self.zero()
|
|
801
|
+
except AttributeError:
|
|
802
|
+
if comp == 0:
|
|
803
|
+
return self.zero()
|
|
804
|
+
if isinstance(comp, (DiffForm, DiffFormParal)):
|
|
805
|
+
# coercion by domain restriction
|
|
806
|
+
if (self._degree == comp._tensor_type[1]
|
|
807
|
+
and self._domain.is_subset(comp._domain)
|
|
808
|
+
and self._ambient_domain.is_subset(comp._ambient_domain)):
|
|
809
|
+
return comp.restrict(self._domain)
|
|
810
|
+
else:
|
|
811
|
+
raise TypeError("cannot convert the {} ".format(comp) +
|
|
812
|
+
"to a differential form in {}".format(self))
|
|
813
|
+
if isinstance(comp, TensorFieldParal):
|
|
814
|
+
# coercion of a tensor of type (0,1) to a linear form
|
|
815
|
+
tensor = comp # for readability
|
|
816
|
+
if (tensor.tensor_type() == (0,1) and self._degree == 1
|
|
817
|
+
and tensor._fmodule is self._fmodule):
|
|
818
|
+
resu = self.element_class(self._fmodule, 1, name=tensor._name,
|
|
819
|
+
latex_name=tensor._latex_name)
|
|
820
|
+
for frame, comp in tensor._components.items():
|
|
821
|
+
resu._components[frame] = comp.copy()
|
|
822
|
+
return resu
|
|
823
|
+
else:
|
|
824
|
+
raise TypeError("cannot convert the {} ".format(tensor) +
|
|
825
|
+
"to an element of {}".format(self))
|
|
826
|
+
if not isinstance(comp, (list, tuple)):
|
|
827
|
+
raise TypeError("cannot convert the {} ".format(comp) +
|
|
828
|
+
"to an element of {}".format(self))
|
|
829
|
+
# standard construction
|
|
830
|
+
resu = self.element_class(self._fmodule, self._degree, name=name,
|
|
831
|
+
latex_name=latex_name)
|
|
832
|
+
if comp:
|
|
833
|
+
resu.set_comp(frame)[:] = comp
|
|
834
|
+
return resu
|
|
835
|
+
|
|
836
|
+
# Rem: _an_element_ is declared in the superclass ExtPowerDualFreeModule
|
|
837
|
+
|
|
838
|
+
def _coerce_map_from_(self, other):
|
|
839
|
+
r"""
|
|
840
|
+
Determine whether coercion to ``self`` exists from other parent.
|
|
841
|
+
|
|
842
|
+
TESTS::
|
|
843
|
+
|
|
844
|
+
sage: M = Manifold(3, 'M')
|
|
845
|
+
sage: X.<x,y,z> = M.chart()
|
|
846
|
+
sage: A2 = M.diff_form_module(2)
|
|
847
|
+
sage: U = M.open_subset('U', coord_def = {X: z<0})
|
|
848
|
+
sage: A2U = U.diff_form_module(2)
|
|
849
|
+
sage: A2U._coerce_map_from_(A2)
|
|
850
|
+
True
|
|
851
|
+
sage: A2._coerce_map_from_(A2U)
|
|
852
|
+
False
|
|
853
|
+
sage: A1 = M.diff_form_module(1)
|
|
854
|
+
sage: A2U._coerce_map_from_(A1)
|
|
855
|
+
False
|
|
856
|
+
sage: A1._coerce_map_from_(M.tensor_field_module((0,1)))
|
|
857
|
+
True
|
|
858
|
+
sage: A1._coerce_map_from_(M.tensor_field_module((1,0)))
|
|
859
|
+
False
|
|
860
|
+
"""
|
|
861
|
+
if isinstance(other, (DiffFormModule, DiffFormFreeModule)):
|
|
862
|
+
# coercion by domain restriction
|
|
863
|
+
return (self._degree == other._degree
|
|
864
|
+
and self._domain.is_subset(other._domain)
|
|
865
|
+
and self._ambient_domain.is_subset(other._ambient_domain))
|
|
866
|
+
|
|
867
|
+
from sage.manifolds.differentiable.tensorfield_module import (
|
|
868
|
+
TensorFieldFreeModule,
|
|
869
|
+
)
|
|
870
|
+
if isinstance(other, TensorFieldFreeModule):
|
|
871
|
+
# coercion of a type-(0,1) tensor to a linear form
|
|
872
|
+
return (self._fmodule is other._fmodule and self._degree == 1
|
|
873
|
+
and other.tensor_type() == (0,1))
|
|
874
|
+
return False
|
|
875
|
+
|
|
876
|
+
#### End of Parent methods
|
|
877
|
+
|
|
878
|
+
def _repr_(self):
|
|
879
|
+
r"""
|
|
880
|
+
Return a string representation of ``self``.
|
|
881
|
+
|
|
882
|
+
TESTS::
|
|
883
|
+
|
|
884
|
+
sage: M = Manifold(3, 'M')
|
|
885
|
+
sage: X.<x,y,z> = M.chart()
|
|
886
|
+
sage: A = M.diff_form_module(2)
|
|
887
|
+
sage: A
|
|
888
|
+
Free module Omega^2(M) of 2-forms on
|
|
889
|
+
the 3-dimensional differentiable manifold M
|
|
890
|
+
"""
|
|
891
|
+
description = "Free module "
|
|
892
|
+
if self._name is not None:
|
|
893
|
+
description += self._name + " "
|
|
894
|
+
description += "of {}-forms ".format(self._degree)
|
|
895
|
+
if self._dest_map is self._domain.identity_map():
|
|
896
|
+
description += "on the {}".format(self._domain)
|
|
897
|
+
else:
|
|
898
|
+
description += "along the {} mapped into the {}".format(
|
|
899
|
+
self._domain, self._ambient_domain)
|
|
900
|
+
return description
|
|
901
|
+
|
|
902
|
+
|
|
903
|
+
class VectorFieldDualFreeModule(DiffFormFreeModule):
|
|
904
|
+
r"""
|
|
905
|
+
Free module of differential 1-forms along a differentiable manifold `U`
|
|
906
|
+
with values on a parallelizable manifold `M`.
|
|
907
|
+
|
|
908
|
+
Given a differentiable manifold `U` and a differentiable map
|
|
909
|
+
`\Phi:\; U \rightarrow M` to a parallelizable manifold `M` of dimension
|
|
910
|
+
`n`, the set `\Omega^1(U, \Phi)` of 1-forms along `U` with values on `M`
|
|
911
|
+
is a free module of rank `n` over `C^k(U)`, the commutative
|
|
912
|
+
algebra of differentiable scalar fields on `U` (see
|
|
913
|
+
:class:`~sage.manifolds.differentiable.scalarfield_algebra.DiffScalarFieldAlgebra`).
|
|
914
|
+
The standard case of 1-forms *on* a differentiable manifold `M`
|
|
915
|
+
corresponds to `U = M` and `\Phi = \mathrm{Id}_M`. Other common cases are
|
|
916
|
+
`\Phi` being an immersion and `\Phi` being a curve in `M` (`U` is then an
|
|
917
|
+
open interval of `\RR`).
|
|
918
|
+
|
|
919
|
+
.. NOTE::
|
|
920
|
+
|
|
921
|
+
This class implements `\Omega^1(U, \Phi)` in the case where `M` is
|
|
922
|
+
parallelizable; `\Omega^1(U, \Phi)` is then a *free* module. If `M`
|
|
923
|
+
is not parallelizable, the class :class:`DiffFormModule` must be used
|
|
924
|
+
instead.
|
|
925
|
+
|
|
926
|
+
INPUT:
|
|
927
|
+
|
|
928
|
+
- ``vector_field_module`` -- free module `\mathfrak{X}(U,\Phi)` of vector
|
|
929
|
+
fields along `U` associated with the map `\Phi: U \rightarrow V`
|
|
930
|
+
|
|
931
|
+
EXAMPLES:
|
|
932
|
+
|
|
933
|
+
Free module of 1-forms on a parallelizable 3-dimensional manifold::
|
|
934
|
+
|
|
935
|
+
sage: M = Manifold(3, 'M')
|
|
936
|
+
sage: X.<x,y,z> = M.chart()
|
|
937
|
+
sage: XM = M.vector_field_module() ; XM
|
|
938
|
+
Free module X(M) of vector fields on the 3-dimensional differentiable
|
|
939
|
+
manifold M
|
|
940
|
+
sage: A = M.diff_form_module(1) ; A
|
|
941
|
+
Free module Omega^1(M) of 1-forms on the 3-dimensional differentiable manifold M
|
|
942
|
+
sage: latex(A)
|
|
943
|
+
\Omega^{1}\left(M\right)
|
|
944
|
+
|
|
945
|
+
``A`` is nothing but the dual of ``XM`` (the free module of vector fields on `M`)
|
|
946
|
+
and thus also equal to the 1st exterior
|
|
947
|
+
power of the dual, i.e. we have `\Omega^{1}(M) = \Lambda^1(\mathfrak{X}(M)^*)
|
|
948
|
+
= \mathfrak{X}(M)^*` (See
|
|
949
|
+
:class:`~sage.tensor.modules.ext_pow_free_module.ExtPowerDualFreeModule`)::
|
|
950
|
+
|
|
951
|
+
sage: A is XM.dual_exterior_power(1)
|
|
952
|
+
True
|
|
953
|
+
|
|
954
|
+
`\Omega^{1}(M)` is a module over the algebra `C^k(M)` of (differentiable)
|
|
955
|
+
scalar fields on `M`::
|
|
956
|
+
|
|
957
|
+
sage: A.category()
|
|
958
|
+
Category of finite dimensional modules over Algebra of differentiable
|
|
959
|
+
scalar fields on the 3-dimensional differentiable manifold M
|
|
960
|
+
sage: CM = M.scalar_field_algebra() ; CM
|
|
961
|
+
Algebra of differentiable scalar fields on the 3-dimensional
|
|
962
|
+
differentiable manifold M
|
|
963
|
+
sage: A in Modules(CM)
|
|
964
|
+
True
|
|
965
|
+
sage: A.base_ring()
|
|
966
|
+
Algebra of differentiable scalar fields on
|
|
967
|
+
the 3-dimensional differentiable manifold M
|
|
968
|
+
sage: A.base_module()
|
|
969
|
+
Free module X(M) of vector fields on
|
|
970
|
+
the 3-dimensional differentiable manifold M
|
|
971
|
+
sage: A.base_module() is XM
|
|
972
|
+
True
|
|
973
|
+
sage: A.rank()
|
|
974
|
+
3
|
|
975
|
+
|
|
976
|
+
Elements can be constructed from `A`. In particular, ``0`` yields
|
|
977
|
+
the zero element of `A`::
|
|
978
|
+
|
|
979
|
+
sage: A(0)
|
|
980
|
+
1-form zero on the 3-dimensional differentiable manifold M
|
|
981
|
+
sage: A(0) is A.zero()
|
|
982
|
+
True
|
|
983
|
+
|
|
984
|
+
while nonzero elements are constructed by providing their components
|
|
985
|
+
in a given vector frame::
|
|
986
|
+
|
|
987
|
+
sage: comp = [3*x,-z,4]
|
|
988
|
+
sage: a = A(comp, frame=X.frame(), name='a') ; a
|
|
989
|
+
1-form a on the 3-dimensional differentiable manifold M
|
|
990
|
+
sage: a.display()
|
|
991
|
+
a = 3*x dx - z dy + 4 dz
|
|
992
|
+
|
|
993
|
+
An alternative is to construct the 1-form from an empty list of
|
|
994
|
+
components and to set the nonzero nonredundant components afterwards::
|
|
995
|
+
|
|
996
|
+
sage: a = A([], name='a')
|
|
997
|
+
sage: a[0] = 3*x # component in the manifold's default frame
|
|
998
|
+
sage: a[1] = -z
|
|
999
|
+
sage: a[2] = 4
|
|
1000
|
+
sage: a.display()
|
|
1001
|
+
a = 3*x dx - z dy + 4 dz
|
|
1002
|
+
|
|
1003
|
+
Since any tensor field of type `(0,1)` is a 1-form, there is a coercion
|
|
1004
|
+
map from the set `T^{(0,1)}(M)` of such tensors to `\Omega^1(M)`::
|
|
1005
|
+
|
|
1006
|
+
sage: T01 = M.tensor_field_module((0,1)) ; T01
|
|
1007
|
+
Free module Omega^1(M) of 1-forms on the 3-dimensional differentiable manifold M
|
|
1008
|
+
sage: A.has_coerce_map_from(T01)
|
|
1009
|
+
True
|
|
1010
|
+
|
|
1011
|
+
There is also a coercion map in the reverse direction::
|
|
1012
|
+
|
|
1013
|
+
sage: T01.has_coerce_map_from(A)
|
|
1014
|
+
True
|
|
1015
|
+
|
|
1016
|
+
The coercion map `T^{(0,1)}(M) \rightarrow \Omega^1(M)` in action::
|
|
1017
|
+
|
|
1018
|
+
sage: b = T01([-x,2,3*y], name='b'); b
|
|
1019
|
+
1-form b on the 3-dimensional differentiable manifold M
|
|
1020
|
+
sage: b.display()
|
|
1021
|
+
b = -x dx + 2 dy + 3*y dz
|
|
1022
|
+
sage: lb = A(b) ; lb
|
|
1023
|
+
1-form b on the 3-dimensional differentiable manifold M
|
|
1024
|
+
sage: lb.display()
|
|
1025
|
+
b = -x dx + 2 dy + 3*y dz
|
|
1026
|
+
|
|
1027
|
+
The coercion map `\Omega^1(M) \rightarrow T^{(0,1)}(M)` in action::
|
|
1028
|
+
|
|
1029
|
+
sage: tlb = T01(lb); tlb
|
|
1030
|
+
1-form b on the 3-dimensional differentiable manifold M
|
|
1031
|
+
sage: tlb == b
|
|
1032
|
+
True
|
|
1033
|
+
"""
|
|
1034
|
+
|
|
1035
|
+
def __init__(self, vector_field_module):
|
|
1036
|
+
r"""
|
|
1037
|
+
Construct a free module of differential 1-forms.
|
|
1038
|
+
|
|
1039
|
+
TESTS::
|
|
1040
|
+
|
|
1041
|
+
sage: M = Manifold(3, 'M')
|
|
1042
|
+
sage: X.<x,y,z> = M.chart()
|
|
1043
|
+
sage: A = M.vector_field_module().dual(); A
|
|
1044
|
+
Free module Omega^1(M) of 1-forms on the 3-dimensional differentiable manifold M
|
|
1045
|
+
sage: TestSuite(A).run()
|
|
1046
|
+
"""
|
|
1047
|
+
DiffFormFreeModule.__init__(self, vector_field_module, 1)
|
|
1048
|
+
|
|
1049
|
+
def tensor_type(self):
|
|
1050
|
+
r"""
|
|
1051
|
+
Return the tensor type of ``self``.
|
|
1052
|
+
|
|
1053
|
+
EXAMPLES::
|
|
1054
|
+
|
|
1055
|
+
sage: M = Manifold(3, 'M')
|
|
1056
|
+
sage: X.<x,y,z> = M.chart()
|
|
1057
|
+
sage: A = M.vector_field_module().dual(); A
|
|
1058
|
+
Free module Omega^1(M) of 1-forms on the 3-dimensional differentiable manifold M
|
|
1059
|
+
sage: A.tensor_type()
|
|
1060
|
+
(0, 1)
|
|
1061
|
+
"""
|
|
1062
|
+
return (0, 1)
|