passagemath-symbolics 10.8.1a1__cp311-cp311-macosx_13_0_arm64.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.
Files changed (182) hide show
  1. passagemath_symbolics/.dylibs/libgmp.10.dylib +0 -0
  2. passagemath_symbolics/__init__.py +3 -0
  3. passagemath_symbolics-10.8.1a1.dist-info/METADATA +186 -0
  4. passagemath_symbolics-10.8.1a1.dist-info/RECORD +182 -0
  5. passagemath_symbolics-10.8.1a1.dist-info/WHEEL +6 -0
  6. passagemath_symbolics-10.8.1a1.dist-info/top_level.txt +3 -0
  7. sage/all__sagemath_symbolics.py +17 -0
  8. sage/calculus/all.py +14 -0
  9. sage/calculus/calculus.py +2838 -0
  10. sage/calculus/desolvers.py +1864 -0
  11. sage/calculus/predefined.py +51 -0
  12. sage/calculus/tests.py +225 -0
  13. sage/calculus/var.cpython-311-darwin.so +0 -0
  14. sage/calculus/var.pyx +401 -0
  15. sage/dynamics/all__sagemath_symbolics.py +6 -0
  16. sage/dynamics/complex_dynamics/all.py +5 -0
  17. sage/dynamics/complex_dynamics/mandel_julia.py +765 -0
  18. sage/dynamics/complex_dynamics/mandel_julia_helper.cpython-311-darwin.so +0 -0
  19. sage/dynamics/complex_dynamics/mandel_julia_helper.pyx +1034 -0
  20. sage/ext/all__sagemath_symbolics.py +1 -0
  21. sage/ext_data/kenzo/CP2.txt +45 -0
  22. sage/ext_data/kenzo/CP3.txt +349 -0
  23. sage/ext_data/kenzo/CP4.txt +4774 -0
  24. sage/ext_data/kenzo/README.txt +49 -0
  25. sage/ext_data/kenzo/S4.txt +20 -0
  26. sage/ext_data/magma/latex/latex.m +1021 -0
  27. sage/ext_data/magma/latex/latex.spec +1 -0
  28. sage/ext_data/magma/sage/basic.m +356 -0
  29. sage/ext_data/magma/sage/sage.spec +1 -0
  30. sage/ext_data/magma/spec +9 -0
  31. sage/geometry/all__sagemath_symbolics.py +8 -0
  32. sage/geometry/hyperbolic_space/all.py +5 -0
  33. sage/geometry/hyperbolic_space/hyperbolic_coercion.py +755 -0
  34. sage/geometry/hyperbolic_space/hyperbolic_constants.py +5 -0
  35. sage/geometry/hyperbolic_space/hyperbolic_geodesic.py +2419 -0
  36. sage/geometry/hyperbolic_space/hyperbolic_interface.py +206 -0
  37. sage/geometry/hyperbolic_space/hyperbolic_isometry.py +1083 -0
  38. sage/geometry/hyperbolic_space/hyperbolic_model.py +1502 -0
  39. sage/geometry/hyperbolic_space/hyperbolic_point.py +621 -0
  40. sage/geometry/riemannian_manifolds/all.py +7 -0
  41. sage/geometry/riemannian_manifolds/parametrized_surface3d.py +1632 -0
  42. sage/geometry/riemannian_manifolds/surface3d_generators.py +461 -0
  43. sage/interfaces/all__sagemath_symbolics.py +1 -0
  44. sage/interfaces/magma.py +2991 -0
  45. sage/interfaces/magma_free.py +90 -0
  46. sage/interfaces/maple.py +1402 -0
  47. sage/interfaces/mathematica.py +1345 -0
  48. sage/interfaces/mathics.py +1312 -0
  49. sage/interfaces/sympy.py +1398 -0
  50. sage/interfaces/sympy_wrapper.py +197 -0
  51. sage/interfaces/tides.py +938 -0
  52. sage/libs/all__sagemath_symbolics.py +6 -0
  53. sage/manifolds/all.py +7 -0
  54. sage/manifolds/calculus_method.py +553 -0
  55. sage/manifolds/catalog.py +437 -0
  56. sage/manifolds/chart.py +4010 -0
  57. sage/manifolds/chart_func.py +3416 -0
  58. sage/manifolds/continuous_map.py +2183 -0
  59. sage/manifolds/continuous_map_image.py +155 -0
  60. sage/manifolds/differentiable/affine_connection.py +2475 -0
  61. sage/manifolds/differentiable/all.py +1 -0
  62. sage/manifolds/differentiable/automorphismfield.py +1383 -0
  63. sage/manifolds/differentiable/automorphismfield_group.py +604 -0
  64. sage/manifolds/differentiable/bundle_connection.py +1445 -0
  65. sage/manifolds/differentiable/characteristic_cohomology_class.py +1840 -0
  66. sage/manifolds/differentiable/chart.py +1241 -0
  67. sage/manifolds/differentiable/curve.py +1028 -0
  68. sage/manifolds/differentiable/de_rham_cohomology.py +541 -0
  69. sage/manifolds/differentiable/degenerate.py +559 -0
  70. sage/manifolds/differentiable/degenerate_submanifold.py +1668 -0
  71. sage/manifolds/differentiable/diff_form.py +1660 -0
  72. sage/manifolds/differentiable/diff_form_module.py +1062 -0
  73. sage/manifolds/differentiable/diff_map.py +1315 -0
  74. sage/manifolds/differentiable/differentiable_submanifold.py +291 -0
  75. sage/manifolds/differentiable/examples/all.py +1 -0
  76. sage/manifolds/differentiable/examples/euclidean.py +2517 -0
  77. sage/manifolds/differentiable/examples/real_line.py +897 -0
  78. sage/manifolds/differentiable/examples/sphere.py +1186 -0
  79. sage/manifolds/differentiable/examples/symplectic_space.py +187 -0
  80. sage/manifolds/differentiable/examples/symplectic_space_test.py +40 -0
  81. sage/manifolds/differentiable/integrated_curve.py +4035 -0
  82. sage/manifolds/differentiable/levi_civita_connection.py +841 -0
  83. sage/manifolds/differentiable/manifold.py +4254 -0
  84. sage/manifolds/differentiable/manifold_homset.py +1826 -0
  85. sage/manifolds/differentiable/metric.py +3032 -0
  86. sage/manifolds/differentiable/mixed_form.py +1507 -0
  87. sage/manifolds/differentiable/mixed_form_algebra.py +559 -0
  88. sage/manifolds/differentiable/multivector_module.py +800 -0
  89. sage/manifolds/differentiable/multivectorfield.py +1522 -0
  90. sage/manifolds/differentiable/poisson_tensor.py +268 -0
  91. sage/manifolds/differentiable/pseudo_riemannian.py +755 -0
  92. sage/manifolds/differentiable/pseudo_riemannian_submanifold.py +1839 -0
  93. sage/manifolds/differentiable/scalarfield.py +1343 -0
  94. sage/manifolds/differentiable/scalarfield_algebra.py +472 -0
  95. sage/manifolds/differentiable/symplectic_form.py +912 -0
  96. sage/manifolds/differentiable/symplectic_form_test.py +220 -0
  97. sage/manifolds/differentiable/tangent_space.py +412 -0
  98. sage/manifolds/differentiable/tangent_vector.py +616 -0
  99. sage/manifolds/differentiable/tensorfield.py +4665 -0
  100. sage/manifolds/differentiable/tensorfield_module.py +963 -0
  101. sage/manifolds/differentiable/tensorfield_paral.py +2450 -0
  102. sage/manifolds/differentiable/tensorfield_paral_test.py +16 -0
  103. sage/manifolds/differentiable/vector_bundle.py +1725 -0
  104. sage/manifolds/differentiable/vectorfield.py +1717 -0
  105. sage/manifolds/differentiable/vectorfield_module.py +2445 -0
  106. sage/manifolds/differentiable/vectorframe.py +1832 -0
  107. sage/manifolds/family.py +270 -0
  108. sage/manifolds/local_frame.py +1490 -0
  109. sage/manifolds/manifold.py +3090 -0
  110. sage/manifolds/manifold_homset.py +452 -0
  111. sage/manifolds/operators.py +359 -0
  112. sage/manifolds/point.py +994 -0
  113. sage/manifolds/scalarfield.py +3718 -0
  114. sage/manifolds/scalarfield_algebra.py +629 -0
  115. sage/manifolds/section.py +3111 -0
  116. sage/manifolds/section_module.py +831 -0
  117. sage/manifolds/structure.py +229 -0
  118. sage/manifolds/subset.py +2721 -0
  119. sage/manifolds/subsets/all.py +1 -0
  120. sage/manifolds/subsets/closure.py +131 -0
  121. sage/manifolds/subsets/pullback.py +883 -0
  122. sage/manifolds/topological_submanifold.py +891 -0
  123. sage/manifolds/trivialization.py +733 -0
  124. sage/manifolds/utilities.py +1348 -0
  125. sage/manifolds/vector_bundle.py +1347 -0
  126. sage/manifolds/vector_bundle_fiber.py +332 -0
  127. sage/manifolds/vector_bundle_fiber_element.py +111 -0
  128. sage/matrix/all__sagemath_symbolics.py +1 -0
  129. sage/matrix/matrix_symbolic_dense.cpython-311-darwin.so +0 -0
  130. sage/matrix/matrix_symbolic_dense.pxd +6 -0
  131. sage/matrix/matrix_symbolic_dense.pyx +1030 -0
  132. sage/matrix/matrix_symbolic_sparse.cpython-311-darwin.so +0 -0
  133. sage/matrix/matrix_symbolic_sparse.pxd +6 -0
  134. sage/matrix/matrix_symbolic_sparse.pyx +1038 -0
  135. sage/modules/all__sagemath_symbolics.py +1 -0
  136. sage/modules/vector_callable_symbolic_dense.py +105 -0
  137. sage/modules/vector_symbolic_dense.py +116 -0
  138. sage/modules/vector_symbolic_sparse.py +118 -0
  139. sage/rings/all__sagemath_symbolics.py +4 -0
  140. sage/rings/asymptotic/all.py +6 -0
  141. sage/rings/asymptotic/asymptotic_expansion_generators.py +1485 -0
  142. sage/rings/asymptotic/asymptotic_ring.py +4858 -0
  143. sage/rings/asymptotic/asymptotics_multivariate_generating_functions.py +4106 -0
  144. sage/rings/asymptotic/growth_group.py +5373 -0
  145. sage/rings/asymptotic/growth_group_cartesian.py +1400 -0
  146. sage/rings/asymptotic/term_monoid.py +5205 -0
  147. sage/rings/function_field/all__sagemath_symbolics.py +2 -0
  148. sage/rings/polynomial/all__sagemath_symbolics.py +1 -0
  149. sage/symbolic/all.py +15 -0
  150. sage/symbolic/assumptions.py +987 -0
  151. sage/symbolic/benchmark.py +93 -0
  152. sage/symbolic/callable.py +456 -0
  153. sage/symbolic/callable.pyi +66 -0
  154. sage/symbolic/comparison_impl.pyi +38 -0
  155. sage/symbolic/complexity_measures.py +35 -0
  156. sage/symbolic/constants.py +1286 -0
  157. sage/symbolic/constants_c_impl.pyi +10 -0
  158. sage/symbolic/expression_conversion_algebraic.py +310 -0
  159. sage/symbolic/expression_conversion_sympy.py +317 -0
  160. sage/symbolic/expression_conversions.py +1727 -0
  161. sage/symbolic/function_factory.py +355 -0
  162. sage/symbolic/function_factory.pyi +41 -0
  163. sage/symbolic/getitem_impl.pyi +24 -0
  164. sage/symbolic/integration/all.py +1 -0
  165. sage/symbolic/integration/external.py +271 -0
  166. sage/symbolic/integration/integral.py +1075 -0
  167. sage/symbolic/maxima_wrapper.py +162 -0
  168. sage/symbolic/operators.py +267 -0
  169. sage/symbolic/operators.pyi +61 -0
  170. sage/symbolic/pynac_constant_impl.pyi +13 -0
  171. sage/symbolic/pynac_function_impl.pyi +8 -0
  172. sage/symbolic/random_tests.py +461 -0
  173. sage/symbolic/relation.py +2062 -0
  174. sage/symbolic/ring.cpython-311-darwin.so +0 -0
  175. sage/symbolic/ring.pxd +5 -0
  176. sage/symbolic/ring.pyi +110 -0
  177. sage/symbolic/ring.pyx +1393 -0
  178. sage/symbolic/series_impl.pyi +10 -0
  179. sage/symbolic/subring.py +1025 -0
  180. sage/symbolic/symengine.py +19 -0
  181. sage/symbolic/tests.py +40 -0
  182. sage/symbolic/units.py +1468 -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)