passagemath-symbolics 10.8.1a1__cp314-cp314t-musllinux_1_2_aarch64.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 (181) hide show
  1. passagemath_symbolics/__init__.py +3 -0
  2. passagemath_symbolics-10.8.1a1.dist-info/METADATA +186 -0
  3. passagemath_symbolics-10.8.1a1.dist-info/RECORD +181 -0
  4. passagemath_symbolics-10.8.1a1.dist-info/WHEEL +5 -0
  5. passagemath_symbolics-10.8.1a1.dist-info/top_level.txt +3 -0
  6. sage/all__sagemath_symbolics.py +17 -0
  7. sage/calculus/all.py +14 -0
  8. sage/calculus/calculus.py +2838 -0
  9. sage/calculus/desolvers.py +1864 -0
  10. sage/calculus/predefined.py +51 -0
  11. sage/calculus/tests.py +225 -0
  12. sage/calculus/var.cpython-314t-aarch64-linux-musl.so +0 -0
  13. sage/calculus/var.pyx +401 -0
  14. sage/dynamics/all__sagemath_symbolics.py +6 -0
  15. sage/dynamics/complex_dynamics/all.py +5 -0
  16. sage/dynamics/complex_dynamics/mandel_julia.py +765 -0
  17. sage/dynamics/complex_dynamics/mandel_julia_helper.cpython-314t-aarch64-linux-musl.so +0 -0
  18. sage/dynamics/complex_dynamics/mandel_julia_helper.pyx +1034 -0
  19. sage/ext/all__sagemath_symbolics.py +1 -0
  20. sage/ext_data/kenzo/CP2.txt +45 -0
  21. sage/ext_data/kenzo/CP3.txt +349 -0
  22. sage/ext_data/kenzo/CP4.txt +4774 -0
  23. sage/ext_data/kenzo/README.txt +49 -0
  24. sage/ext_data/kenzo/S4.txt +20 -0
  25. sage/ext_data/magma/latex/latex.m +1021 -0
  26. sage/ext_data/magma/latex/latex.spec +1 -0
  27. sage/ext_data/magma/sage/basic.m +356 -0
  28. sage/ext_data/magma/sage/sage.spec +1 -0
  29. sage/ext_data/magma/spec +9 -0
  30. sage/geometry/all__sagemath_symbolics.py +8 -0
  31. sage/geometry/hyperbolic_space/all.py +5 -0
  32. sage/geometry/hyperbolic_space/hyperbolic_coercion.py +755 -0
  33. sage/geometry/hyperbolic_space/hyperbolic_constants.py +5 -0
  34. sage/geometry/hyperbolic_space/hyperbolic_geodesic.py +2419 -0
  35. sage/geometry/hyperbolic_space/hyperbolic_interface.py +206 -0
  36. sage/geometry/hyperbolic_space/hyperbolic_isometry.py +1083 -0
  37. sage/geometry/hyperbolic_space/hyperbolic_model.py +1502 -0
  38. sage/geometry/hyperbolic_space/hyperbolic_point.py +621 -0
  39. sage/geometry/riemannian_manifolds/all.py +7 -0
  40. sage/geometry/riemannian_manifolds/parametrized_surface3d.py +1632 -0
  41. sage/geometry/riemannian_manifolds/surface3d_generators.py +461 -0
  42. sage/interfaces/all__sagemath_symbolics.py +1 -0
  43. sage/interfaces/magma.py +2991 -0
  44. sage/interfaces/magma_free.py +90 -0
  45. sage/interfaces/maple.py +1402 -0
  46. sage/interfaces/mathematica.py +1345 -0
  47. sage/interfaces/mathics.py +1312 -0
  48. sage/interfaces/sympy.py +1398 -0
  49. sage/interfaces/sympy_wrapper.py +197 -0
  50. sage/interfaces/tides.py +938 -0
  51. sage/libs/all__sagemath_symbolics.py +6 -0
  52. sage/manifolds/all.py +7 -0
  53. sage/manifolds/calculus_method.py +553 -0
  54. sage/manifolds/catalog.py +437 -0
  55. sage/manifolds/chart.py +4010 -0
  56. sage/manifolds/chart_func.py +3416 -0
  57. sage/manifolds/continuous_map.py +2183 -0
  58. sage/manifolds/continuous_map_image.py +155 -0
  59. sage/manifolds/differentiable/affine_connection.py +2475 -0
  60. sage/manifolds/differentiable/all.py +1 -0
  61. sage/manifolds/differentiable/automorphismfield.py +1383 -0
  62. sage/manifolds/differentiable/automorphismfield_group.py +604 -0
  63. sage/manifolds/differentiable/bundle_connection.py +1445 -0
  64. sage/manifolds/differentiable/characteristic_cohomology_class.py +1840 -0
  65. sage/manifolds/differentiable/chart.py +1241 -0
  66. sage/manifolds/differentiable/curve.py +1028 -0
  67. sage/manifolds/differentiable/de_rham_cohomology.py +541 -0
  68. sage/manifolds/differentiable/degenerate.py +559 -0
  69. sage/manifolds/differentiable/degenerate_submanifold.py +1668 -0
  70. sage/manifolds/differentiable/diff_form.py +1660 -0
  71. sage/manifolds/differentiable/diff_form_module.py +1062 -0
  72. sage/manifolds/differentiable/diff_map.py +1315 -0
  73. sage/manifolds/differentiable/differentiable_submanifold.py +291 -0
  74. sage/manifolds/differentiable/examples/all.py +1 -0
  75. sage/manifolds/differentiable/examples/euclidean.py +2517 -0
  76. sage/manifolds/differentiable/examples/real_line.py +897 -0
  77. sage/manifolds/differentiable/examples/sphere.py +1186 -0
  78. sage/manifolds/differentiable/examples/symplectic_space.py +187 -0
  79. sage/manifolds/differentiable/examples/symplectic_space_test.py +40 -0
  80. sage/manifolds/differentiable/integrated_curve.py +4035 -0
  81. sage/manifolds/differentiable/levi_civita_connection.py +841 -0
  82. sage/manifolds/differentiable/manifold.py +4254 -0
  83. sage/manifolds/differentiable/manifold_homset.py +1826 -0
  84. sage/manifolds/differentiable/metric.py +3032 -0
  85. sage/manifolds/differentiable/mixed_form.py +1507 -0
  86. sage/manifolds/differentiable/mixed_form_algebra.py +559 -0
  87. sage/manifolds/differentiable/multivector_module.py +800 -0
  88. sage/manifolds/differentiable/multivectorfield.py +1522 -0
  89. sage/manifolds/differentiable/poisson_tensor.py +268 -0
  90. sage/manifolds/differentiable/pseudo_riemannian.py +755 -0
  91. sage/manifolds/differentiable/pseudo_riemannian_submanifold.py +1839 -0
  92. sage/manifolds/differentiable/scalarfield.py +1343 -0
  93. sage/manifolds/differentiable/scalarfield_algebra.py +472 -0
  94. sage/manifolds/differentiable/symplectic_form.py +912 -0
  95. sage/manifolds/differentiable/symplectic_form_test.py +220 -0
  96. sage/manifolds/differentiable/tangent_space.py +412 -0
  97. sage/manifolds/differentiable/tangent_vector.py +616 -0
  98. sage/manifolds/differentiable/tensorfield.py +4665 -0
  99. sage/manifolds/differentiable/tensorfield_module.py +963 -0
  100. sage/manifolds/differentiable/tensorfield_paral.py +2450 -0
  101. sage/manifolds/differentiable/tensorfield_paral_test.py +16 -0
  102. sage/manifolds/differentiable/vector_bundle.py +1725 -0
  103. sage/manifolds/differentiable/vectorfield.py +1717 -0
  104. sage/manifolds/differentiable/vectorfield_module.py +2445 -0
  105. sage/manifolds/differentiable/vectorframe.py +1832 -0
  106. sage/manifolds/family.py +270 -0
  107. sage/manifolds/local_frame.py +1490 -0
  108. sage/manifolds/manifold.py +3090 -0
  109. sage/manifolds/manifold_homset.py +452 -0
  110. sage/manifolds/operators.py +359 -0
  111. sage/manifolds/point.py +994 -0
  112. sage/manifolds/scalarfield.py +3718 -0
  113. sage/manifolds/scalarfield_algebra.py +629 -0
  114. sage/manifolds/section.py +3111 -0
  115. sage/manifolds/section_module.py +831 -0
  116. sage/manifolds/structure.py +229 -0
  117. sage/manifolds/subset.py +2721 -0
  118. sage/manifolds/subsets/all.py +1 -0
  119. sage/manifolds/subsets/closure.py +131 -0
  120. sage/manifolds/subsets/pullback.py +883 -0
  121. sage/manifolds/topological_submanifold.py +891 -0
  122. sage/manifolds/trivialization.py +733 -0
  123. sage/manifolds/utilities.py +1348 -0
  124. sage/manifolds/vector_bundle.py +1347 -0
  125. sage/manifolds/vector_bundle_fiber.py +332 -0
  126. sage/manifolds/vector_bundle_fiber_element.py +111 -0
  127. sage/matrix/all__sagemath_symbolics.py +1 -0
  128. sage/matrix/matrix_symbolic_dense.cpython-314t-aarch64-linux-musl.so +0 -0
  129. sage/matrix/matrix_symbolic_dense.pxd +6 -0
  130. sage/matrix/matrix_symbolic_dense.pyx +1030 -0
  131. sage/matrix/matrix_symbolic_sparse.cpython-314t-aarch64-linux-musl.so +0 -0
  132. sage/matrix/matrix_symbolic_sparse.pxd +6 -0
  133. sage/matrix/matrix_symbolic_sparse.pyx +1038 -0
  134. sage/modules/all__sagemath_symbolics.py +1 -0
  135. sage/modules/vector_callable_symbolic_dense.py +105 -0
  136. sage/modules/vector_symbolic_dense.py +116 -0
  137. sage/modules/vector_symbolic_sparse.py +118 -0
  138. sage/rings/all__sagemath_symbolics.py +4 -0
  139. sage/rings/asymptotic/all.py +6 -0
  140. sage/rings/asymptotic/asymptotic_expansion_generators.py +1485 -0
  141. sage/rings/asymptotic/asymptotic_ring.py +4858 -0
  142. sage/rings/asymptotic/asymptotics_multivariate_generating_functions.py +4106 -0
  143. sage/rings/asymptotic/growth_group.py +5373 -0
  144. sage/rings/asymptotic/growth_group_cartesian.py +1400 -0
  145. sage/rings/asymptotic/term_monoid.py +5205 -0
  146. sage/rings/function_field/all__sagemath_symbolics.py +2 -0
  147. sage/rings/polynomial/all__sagemath_symbolics.py +1 -0
  148. sage/symbolic/all.py +15 -0
  149. sage/symbolic/assumptions.py +987 -0
  150. sage/symbolic/benchmark.py +93 -0
  151. sage/symbolic/callable.py +456 -0
  152. sage/symbolic/callable.pyi +66 -0
  153. sage/symbolic/comparison_impl.pyi +38 -0
  154. sage/symbolic/complexity_measures.py +35 -0
  155. sage/symbolic/constants.py +1286 -0
  156. sage/symbolic/constants_c_impl.pyi +10 -0
  157. sage/symbolic/expression_conversion_algebraic.py +310 -0
  158. sage/symbolic/expression_conversion_sympy.py +317 -0
  159. sage/symbolic/expression_conversions.py +1727 -0
  160. sage/symbolic/function_factory.py +355 -0
  161. sage/symbolic/function_factory.pyi +41 -0
  162. sage/symbolic/getitem_impl.pyi +24 -0
  163. sage/symbolic/integration/all.py +1 -0
  164. sage/symbolic/integration/external.py +271 -0
  165. sage/symbolic/integration/integral.py +1075 -0
  166. sage/symbolic/maxima_wrapper.py +162 -0
  167. sage/symbolic/operators.py +267 -0
  168. sage/symbolic/operators.pyi +61 -0
  169. sage/symbolic/pynac_constant_impl.pyi +13 -0
  170. sage/symbolic/pynac_function_impl.pyi +8 -0
  171. sage/symbolic/random_tests.py +461 -0
  172. sage/symbolic/relation.py +2062 -0
  173. sage/symbolic/ring.cpython-314t-aarch64-linux-musl.so +0 -0
  174. sage/symbolic/ring.pxd +5 -0
  175. sage/symbolic/ring.pyi +110 -0
  176. sage/symbolic/ring.pyx +1393 -0
  177. sage/symbolic/series_impl.pyi +10 -0
  178. sage/symbolic/subring.py +1025 -0
  179. sage/symbolic/symengine.py +19 -0
  180. sage/symbolic/tests.py +40 -0
  181. sage/symbolic/units.py +1468 -0
@@ -0,0 +1,4254 @@
1
+ # sage_setup: distribution = sagemath-symbolics
2
+ r"""
3
+ Differentiable Manifolds
4
+
5
+ Given a non-discrete topological field `K` (in most applications, `K = \RR` or
6
+ `K = \CC`; see however [Ser1992]_ for `K = \QQ_p` and [Ber2008]_ for other fields),
7
+ a *differentiable manifold over* `K` is a topological manifold `M` over `K`
8
+ equipped with an atlas whose transitions maps are of class `C^k` (i.e.
9
+ `k`-times continuously differentiable) for a fixed positive integer `k`
10
+ (possibly `k=\infty`). `M` is then called a `C^k`-*manifold over* `K`.
11
+
12
+ Note that
13
+
14
+ - if the mention of `K` is omitted, then `K=\RR` is assumed;
15
+ - if `K=\CC`, any `C^k`-manifold with `k\geq 1` is actually a
16
+ `C^\infty`-manifold (even an analytic manifold);
17
+ - if `K=\RR`, any `C^k`-manifold with `k\geq 1` admits a compatible
18
+ `C^\infty`-structure (Whitney's smoothing theorem).
19
+
20
+ Differentiable manifolds are implemented via the class
21
+ :class:`DifferentiableManifold`.
22
+ Open subsets of differentiable manifolds are also implemented via
23
+ :class:`DifferentiableManifold`, since they are differentiable manifolds by
24
+ themselves.
25
+
26
+ The user interface is provided by the generic function
27
+ :func:`~sage.manifolds.manifold.Manifold`, with
28
+ the argument ``structure`` set to ``'differentiable'`` and the argument
29
+ ``diff_degree`` set to `k`, or the argument ``structure`` set to ``'smooth'``
30
+ (the default value).
31
+
32
+ .. RUBRIC:: Example 1: the 2-sphere as a differentiable manifold of dimension
33
+ 2 over `\RR`
34
+
35
+ One starts by declaring `S^2` as a 2-dimensional differentiable manifold::
36
+
37
+ sage: M = Manifold(2, 'S^2')
38
+ sage: M
39
+ 2-dimensional differentiable manifold S^2
40
+
41
+ Since the base topological field has not been specified in the argument list
42
+ of ``Manifold``, `\RR` is assumed::
43
+
44
+ sage: M.base_field()
45
+ Real Field with 53 bits of precision
46
+ sage: dim(M)
47
+ 2
48
+
49
+ By default, the created object is a smooth manifold::
50
+
51
+ sage: M.diff_degree()
52
+ +Infinity
53
+
54
+ Let us consider the complement of a point, the "North pole" say; this is an
55
+ open subset of `S^2`, which we call `U`::
56
+
57
+ sage: U = M.open_subset('U'); U
58
+ Open subset U of the 2-dimensional differentiable manifold S^2
59
+
60
+ A standard chart on `U` is provided by the stereographic projection from the
61
+ North pole to the equatorial plane::
62
+
63
+ sage: stereoN.<x,y> = U.chart(); stereoN
64
+ Chart (U, (x, y))
65
+
66
+ Thanks to the operator ``<x,y>`` on the left-hand side, the coordinates
67
+ declared in a chart (here `x` and `y`), are accessible by their names; they are
68
+ Sage's symbolic variables::
69
+
70
+ sage: y
71
+ y
72
+ sage: type(y)
73
+ <class 'sage.symbolic.expression.Expression'>
74
+
75
+ The South pole is the point of coordinates `(x,y)=(0,0)` in the above
76
+ chart::
77
+
78
+ sage: S = U.point((0,0), chart=stereoN, name='S'); S
79
+ Point S on the 2-dimensional differentiable manifold S^2
80
+
81
+ Let us call `V` the open subset that is the complement of the South pole and
82
+ let us introduce on it the chart induced by the stereographic projection from
83
+ the South pole to the equatorial plane::
84
+
85
+ sage: V = M.open_subset('V'); V
86
+ Open subset V of the 2-dimensional differentiable manifold S^2
87
+ sage: stereoS.<u,v> = V.chart(); stereoS
88
+ Chart (V, (u, v))
89
+
90
+ The North pole is the point of coordinates `(u,v)=(0,0)` in this chart::
91
+
92
+ sage: N = V.point((0,0), chart=stereoS, name='N'); N
93
+ Point N on the 2-dimensional differentiable manifold S^2
94
+
95
+ To fully construct the manifold, we declare that it is the union of `U`
96
+ and `V`::
97
+
98
+ sage: M.declare_union(U,V)
99
+
100
+ and we provide the transition map between the charts ``stereoN`` = `(U, (x, y))`
101
+ and ``stereoS`` = `(V, (u, v))`, denoting by `W` the intersection of `U` and
102
+ `V` (`W` is the subset of `U` defined by `x^2+y^2\not=0`, as well as the subset
103
+ of `V` defined by `u^2+v^2\not=0`)::
104
+
105
+ sage: stereoN_to_S = stereoN.transition_map(stereoS,
106
+ ....: [x/(x^2+y^2), y/(x^2+y^2)], intersection_name='W',
107
+ ....: restrictions1= x^2+y^2!=0, restrictions2= u^2+v^2!=0)
108
+ sage: stereoN_to_S
109
+ Change of coordinates from Chart (W, (x, y)) to Chart (W, (u, v))
110
+ sage: stereoN_to_S.display()
111
+ u = x/(x^2 + y^2)
112
+ v = y/(x^2 + y^2)
113
+
114
+ We give the name ``W`` to the Python variable representing `W=U\cap V`::
115
+
116
+ sage: W = U.intersection(V)
117
+
118
+ The inverse of the transition map is computed by the method ``inverse()``::
119
+
120
+ sage: stereoN_to_S.inverse()
121
+ Change of coordinates from Chart (W, (u, v)) to Chart (W, (x, y))
122
+ sage: stereoN_to_S.inverse().display()
123
+ x = u/(u^2 + v^2)
124
+ y = v/(u^2 + v^2)
125
+
126
+ At this stage, we have four open subsets on `S^2`::
127
+
128
+ sage: M.subset_family()
129
+ Set {S^2, U, V, W} of open subsets of the 2-dimensional differentiable manifold S^2
130
+
131
+ `W` is the open subset that is the complement of the two poles::
132
+
133
+ sage: N in W or S in W
134
+ False
135
+
136
+ The North pole lies in `V` and the South pole in `U`::
137
+
138
+ sage: N in V, N in U
139
+ (True, False)
140
+ sage: S in U, S in V
141
+ (True, False)
142
+
143
+ The manifold's (user) atlas contains four charts, two of them
144
+ being restrictions of charts to a smaller domain::
145
+
146
+ sage: M.atlas()
147
+ [Chart (U, (x, y)), Chart (V, (u, v)), Chart (W, (x, y)), Chart (W, (u, v))]
148
+
149
+ Let us consider the point of coordinates (1,2) in the chart ``stereoN``::
150
+
151
+ sage: p = M.point((1,2), chart=stereoN, name='p'); p
152
+ Point p on the 2-dimensional differentiable manifold S^2
153
+ sage: p.parent()
154
+ 2-dimensional differentiable manifold S^2
155
+ sage: p in W
156
+ True
157
+
158
+ The coordinates of `p` in the chart ``stereoS`` are computed by letting
159
+ the chart act on the point::
160
+
161
+ sage: stereoS(p)
162
+ (1/5, 2/5)
163
+
164
+ Given the definition of `p`, we have of course::
165
+
166
+ sage: stereoN(p)
167
+ (1, 2)
168
+
169
+ Similarly::
170
+
171
+ sage: stereoS(N)
172
+ (0, 0)
173
+ sage: stereoN(S)
174
+ (0, 0)
175
+
176
+ A differentiable scalar field on the sphere::
177
+
178
+ sage: f = M.scalar_field({stereoN: atan(x^2+y^2), stereoS: pi/2-atan(u^2+v^2)},
179
+ ....: name='f')
180
+ sage: f
181
+ Scalar field f on the 2-dimensional differentiable manifold S^2
182
+ sage: f.display()
183
+ f: S^2 → ℝ
184
+ on U: (x, y) ↦ arctan(x^2 + y^2)
185
+ on V: (u, v) ↦ 1/2*pi - arctan(u^2 + v^2)
186
+ sage: f(p)
187
+ arctan(5)
188
+ sage: f(N)
189
+ 1/2*pi
190
+ sage: f(S)
191
+ 0
192
+ sage: f.parent()
193
+ Algebra of differentiable scalar fields on the 2-dimensional differentiable
194
+ manifold S^2
195
+ sage: f.parent().category()
196
+ Join of Category of commutative algebras over Symbolic Ring and Category of homsets of topological spaces
197
+
198
+ A differentiable manifold has a default vector frame, which, unless otherwise
199
+ specified, is the coordinate frame associated with the first defined chart::
200
+
201
+ sage: M.default_frame()
202
+ Coordinate frame (U, (∂/∂x,∂/∂y))
203
+ sage: latex(M.default_frame())
204
+ \left(U, \left(\frac{\partial}{\partial x },\frac{\partial}{\partial y }\right)\right)
205
+ sage: M.default_frame() is stereoN.frame()
206
+ True
207
+
208
+ A vector field on the sphere::
209
+
210
+ sage: w = M.vector_field(name='w')
211
+ sage: w[stereoN.frame(), :] = [x, y]
212
+ sage: w.add_comp_by_continuation(stereoS.frame(), W, stereoS)
213
+ sage: w.display() # display in the default frame (stereoN.frame())
214
+ w = x ∂/∂x + y ∂/∂y
215
+ sage: w.display(stereoS.frame())
216
+ w = -u ∂/∂u - v ∂/∂v
217
+ sage: w.parent()
218
+ Module X(S^2) of vector fields on the 2-dimensional differentiable
219
+ manifold S^2
220
+ sage: w.parent().category()
221
+ Category of modules over Algebra of differentiable scalar fields on the
222
+ 2-dimensional differentiable manifold S^2
223
+
224
+ Vector fields act on scalar fields::
225
+
226
+ sage: w(f)
227
+ Scalar field w(f) on the 2-dimensional differentiable manifold S^2
228
+ sage: w(f).display()
229
+ w(f): S^2 → ℝ
230
+ on U: (x, y) ↦ 2*(x^2 + y^2)/(x^4 + 2*x^2*y^2 + y^4 + 1)
231
+ on V: (u, v) ↦ 2*(u^2 + v^2)/(u^4 + 2*u^2*v^2 + v^4 + 1)
232
+ sage: w(f) == f.differential()(w)
233
+ True
234
+
235
+ The value of the vector field at point `p` is a vector tangent to the sphere::
236
+
237
+ sage: w.at(p)
238
+ Tangent vector w at Point p on the 2-dimensional differentiable manifold S^2
239
+ sage: w.at(p).display()
240
+ w = ∂/∂x + 2 ∂/∂y
241
+ sage: w.at(p).parent()
242
+ Tangent space at Point p on the 2-dimensional differentiable manifold S^2
243
+
244
+ A 1-form on the sphere::
245
+
246
+ sage: df = f.differential() ; df
247
+ 1-form df on the 2-dimensional differentiable manifold S^2
248
+ sage: df.display()
249
+ df = 2*x/(x^4 + 2*x^2*y^2 + y^4 + 1) dx + 2*y/(x^4 + 2*x^2*y^2 + y^4 + 1) dy
250
+ sage: df.display(stereoS.frame())
251
+ df = -2*u/(u^4 + 2*u^2*v^2 + v^4 + 1) du - 2*v/(u^4 + 2*u^2*v^2 + v^4 + 1) dv
252
+ sage: df.parent()
253
+ Module Omega^1(S^2) of 1-forms on the 2-dimensional differentiable
254
+ manifold S^2
255
+ sage: df.parent().category()
256
+ Category of modules over Algebra of differentiable scalar fields on the
257
+ 2-dimensional differentiable manifold S^2
258
+
259
+ The value of the 1-form at point `p` is a linear form on the tangent space
260
+ at `p`::
261
+
262
+ sage: df.at(p)
263
+ Linear form df on the Tangent space at Point p on the 2-dimensional
264
+ differentiable manifold S^2
265
+ sage: df.at(p).display()
266
+ df = 1/13 dx + 2/13 dy
267
+ sage: df.at(p).parent()
268
+ Dual of the Tangent space at Point p on the 2-dimensional differentiable
269
+ manifold S^2
270
+
271
+
272
+ .. RUBRIC:: Example 2: the Riemann sphere as a differentiable manifold of
273
+ dimension 1 over `\CC`
274
+
275
+ We declare the Riemann sphere `\CC^*` as a 1-dimensional differentiable
276
+ manifold over `\CC`::
277
+
278
+ sage: M = Manifold(1, 'ℂ*', field='complex'); M
279
+ 1-dimensional complex manifold ℂ*
280
+
281
+ We introduce a first open subset, which is actually
282
+ `\CC = \CC^*\setminus\{\infty\}` if we interpret `\CC^*` as the Alexandroff
283
+ one-point compactification of `\CC`::
284
+
285
+ sage: U = M.open_subset('U')
286
+
287
+ A natural chart on `U` is then nothing but the identity map of `\CC`, hence
288
+ we denote the associated coordinate by `z`::
289
+
290
+ sage: Z.<z> = U.chart()
291
+
292
+ The origin of the complex plane is the point of coordinate `z=0`::
293
+
294
+ sage: O = U.point((0,), chart=Z, name='O'); O
295
+ Point O on the 1-dimensional complex manifold ℂ*
296
+
297
+ Another open subset of `\CC^*` is `V = \CC^*\setminus\{O\}`::
298
+
299
+ sage: V = M.open_subset('V')
300
+
301
+ We define a chart on `V` such that the point at infinity is the point of
302
+ coordinate 0 in this chart::
303
+
304
+ sage: W.<w> = V.chart(); W
305
+ Chart (V, (w,))
306
+ sage: inf = M.point((0,), chart=W, name='inf', latex_name=r'\infty')
307
+ sage: inf
308
+ Point inf on the 1-dimensional complex manifold ℂ*
309
+
310
+ To fully construct the Riemann sphere, we declare that it is the union of `U`
311
+ and `V`::
312
+
313
+ sage: M.declare_union(U,V)
314
+
315
+ and we provide the transition map between the two charts as `w=1/z` on
316
+ on `A = U\cap V`::
317
+
318
+ sage: Z_to_W = Z.transition_map(W, 1/z, intersection_name='A',
319
+ ....: restrictions1= z!=0, restrictions2= w!=0)
320
+ sage: Z_to_W
321
+ Change of coordinates from Chart (A, (z,)) to Chart (A, (w,))
322
+ sage: Z_to_W.display()
323
+ w = 1/z
324
+ sage: Z_to_W.inverse()
325
+ Change of coordinates from Chart (A, (w,)) to Chart (A, (z,))
326
+ sage: Z_to_W.inverse().display()
327
+ z = 1/w
328
+
329
+ Let consider the complex number `i` as a point of the Riemann sphere::
330
+
331
+ sage: i = M((I,), chart=Z, name='i'); i
332
+ Point i on the 1-dimensional complex manifold ℂ*
333
+
334
+ Its coordinates with respect to the charts ``Z`` and ``W`` are::
335
+
336
+ sage: Z(i)
337
+ (I,)
338
+ sage: W(i)
339
+ (-I,)
340
+
341
+ and we have::
342
+
343
+ sage: i in U
344
+ True
345
+ sage: i in V
346
+ True
347
+
348
+ The following subsets and charts have been defined::
349
+
350
+ sage: M.subset_family()
351
+ Set {A, U, V, ℂ*} of open subsets of the 1-dimensional complex manifold ℂ*
352
+ sage: M.atlas()
353
+ [Chart (U, (z,)), Chart (V, (w,)), Chart (A, (z,)), Chart (A, (w,))]
354
+
355
+ A constant map `\CC^* \rightarrow \CC`::
356
+
357
+ sage: f = M.constant_scalar_field(3+2*I, name='f'); f
358
+ Scalar field f on the 1-dimensional complex manifold ℂ*
359
+ sage: f.display()
360
+ f: ℂ* → ℂ
361
+ on U: z ↦ 2*I + 3
362
+ on V: w ↦ 2*I + 3
363
+ sage: f(O)
364
+ 2*I + 3
365
+ sage: f(i)
366
+ 2*I + 3
367
+ sage: f(inf)
368
+ 2*I + 3
369
+ sage: f.parent()
370
+ Algebra of differentiable scalar fields on the 1-dimensional complex
371
+ manifold ℂ*
372
+ sage: f.parent().category()
373
+ Join of Category of commutative algebras over Symbolic Ring and Category of homsets of topological spaces
374
+
375
+ A vector field on the Riemann sphere::
376
+
377
+ sage: v = M.vector_field(name='v')
378
+ sage: v[Z.frame(), 0] = z^2
379
+ sage: v.add_comp_by_continuation(W.frame(), U.intersection(V), W)
380
+ sage: v.display(Z.frame())
381
+ v = z^2 ∂/∂z
382
+ sage: v.display(W.frame())
383
+ v = -∂/∂w
384
+ sage: v.parent()
385
+ Module X(ℂ*) of vector fields on the 1-dimensional complex manifold ℂ*
386
+
387
+ The vector field `v` acting on the scalar field `f`::
388
+
389
+ sage: v(f)
390
+ Scalar field zero on the 1-dimensional complex manifold ℂ*
391
+
392
+ Since `f` is constant, `v(f)` is vanishing::
393
+
394
+ sage: v(f).display()
395
+ zero: ℂ* → ℂ
396
+ on U: z ↦ 0
397
+ on V: w ↦ 0
398
+
399
+ The value of the vector field `v` at the point `\infty` is a vector tangent to
400
+ the Riemann sphere::
401
+
402
+ sage: v.at(inf)
403
+ Tangent vector v at Point inf on the 1-dimensional complex manifold ℂ*
404
+ sage: v.at(inf).display()
405
+ v = -∂/∂w
406
+ sage: v.at(inf).parent()
407
+ Tangent space at Point inf on the 1-dimensional complex manifold ℂ*
408
+
409
+ AUTHORS:
410
+
411
+ - Eric Gourgoulhon (2015): initial version
412
+ - Travis Scrimshaw (2016): review tweaks
413
+ - Michael Jung (2020): tensor bundles and orientability
414
+ - Matthias Koeppe (2021): refactoring of subsets code
415
+
416
+ REFERENCES:
417
+
418
+ - [Lee2013]_
419
+ - [KN1963]_
420
+ - [Huy2005]_
421
+ - [Ser1992]_
422
+ - [Ber2008]_
423
+ - [BG1988]_
424
+ """
425
+
426
+ # ****************************************************************************
427
+ # Copyright (C) 2015-2019 Eric Gourgoulhon <eric.gourgoulhon@obspm.fr>
428
+ # Copyright (C) 2015 Michal Bejger <bejger@camk.edu.pl>
429
+ # Copyright (C) 2015-2016 Travis Scrimshaw <tscrimsh@umn.edu>
430
+ # Copyright (C) 2017 Karim Van Aelst
431
+ # Copyright (C) 2019 Hans Fotsing Tetsing
432
+ # Copyright (C) 2019-2020 Michael Jung
433
+ # Copyright (C) 2021 Matthias Koeppe
434
+ #
435
+ # Distributed under the terms of the GNU General Public License (GPL)
436
+ # as published by the Free Software Foundation; either version 2 of
437
+ # the License, or (at your option) any later version.
438
+ # https://www.gnu.org/licenses/
439
+ # ****************************************************************************
440
+
441
+ from __future__ import annotations
442
+
443
+ from typing import TYPE_CHECKING, Optional, Union
444
+
445
+ from sage.categories.homset import Hom
446
+ from sage.categories.manifolds import Manifolds
447
+ from sage.manifolds.differentiable.mixed_form_algebra import MixedFormAlgebra
448
+ from sage.manifolds.manifold import TopologicalManifold
449
+ from sage.rings.cc import CC
450
+ from sage.rings.infinity import infinity, minus_infinity
451
+ from sage.rings.integer import Integer
452
+ from sage.rings.real_mpfr import RR
453
+
454
+ if TYPE_CHECKING:
455
+ from sage.manifolds.differentiable.diff_form import DiffForm
456
+ from sage.manifolds.differentiable.diff_map import DiffMap
457
+ from sage.manifolds.differentiable.metric import PseudoRiemannianMetric
458
+ from sage.manifolds.differentiable.vectorfield_module import (
459
+ VectorFieldFreeModule,
460
+ VectorFieldModule,
461
+ )
462
+ from sage.manifolds.differentiable.vectorframe import VectorFrame
463
+
464
+ ###############################################################################
465
+
466
+
467
+ class DifferentiableManifold(TopologicalManifold):
468
+ r"""
469
+ Differentiable manifold over a topological field `K`.
470
+
471
+ Given a non-discrete topological field `K` (in most applications,
472
+ `K = \RR` or `K = \CC`; see however [Ser1992]_ for `K = \QQ_p` and
473
+ [Ber2008]_ for other fields), a *differentiable manifold over* `K` is a
474
+ topological manifold `M` over `K` equipped with an atlas whose transitions
475
+ maps are of class `C^k` (i.e. `k`-times continuously differentiable) for
476
+ a fixed positive integer `k` (possibly `k=\infty`). `M` is then called a
477
+ `C^k`-*manifold over* `K`.
478
+
479
+ Note that
480
+
481
+ - if the mention of `K` is omitted, then `K=\RR` is assumed;
482
+ - if `K=\CC`, any `C^k`-manifold with `k\geq 1` is actually a
483
+ `C^\infty`-manifold (even an analytic manifold);
484
+ - if `K=\RR`, any `C^k`-manifold with `k\geq 1` admits a compatible
485
+ `C^\infty`-structure (Whitney's smoothing theorem).
486
+
487
+ INPUT:
488
+
489
+ - ``n`` -- positive integer; dimension of the manifold
490
+ - ``name`` -- string; name (symbol) given to the manifold
491
+ - ``field`` -- field `K` on which the manifold is
492
+ defined; allowed values are
493
+
494
+ - ``'real'`` or an object of type ``RealField`` (e.g., ``RR``) for
495
+ a manifold over `\RR`
496
+ - ``'complex'`` or an object of type ``ComplexField`` (e.g., ``CC``)
497
+ for a manifold over `\CC`
498
+ - an object in the category of topological fields (see
499
+ :class:`~sage.categories.fields.Fields` and
500
+ :class:`~sage.categories.topological_spaces.TopologicalSpaces`)
501
+ for other types of manifolds
502
+
503
+ - ``structure`` -- manifold structure (see
504
+ :class:`~sage.manifolds.structure.DifferentialStructure` or
505
+ :class:`~sage.manifolds.structure.RealDifferentialStructure`)
506
+ - ``base_manifold`` -- (default: ``None``) if not ``None``, must be a
507
+ differentiable manifold; the created object is then an open subset of
508
+ ``base_manifold``
509
+ - ``diff_degree`` -- (default: ``infinity``) degree `k` of
510
+ differentiability
511
+ - ``latex_name`` -- (default: ``None``) string; LaTeX symbol to
512
+ denote the manifold; if none is provided, it is set to ``name``
513
+ - ``start_index`` -- (default: 0) integer; lower value of the range of
514
+ indices used for "indexed objects" on the manifold, e.g. coordinates
515
+ in a chart
516
+ - ``category`` -- (default: ``None``) to specify the category; if ``None``,
517
+ ``Manifolds(field).Differentiable()`` (or ``Manifolds(field).Smooth()``
518
+ if ``diff_degree`` = ``infinity``) is assumed (see the category
519
+ :class:`~sage.categories.manifolds.Manifolds`)
520
+ - ``unique_tag`` -- (default: ``None``) tag used to force the construction
521
+ of a new object when all the other arguments have been used previously
522
+ (without ``unique_tag``, the
523
+ :class:`~sage.structure.unique_representation.UniqueRepresentation`
524
+ behavior inherited from
525
+ :class:`~sage.manifolds.subset.ManifoldSubset`,
526
+ via :class:`~sage.manifolds.manifold.TopologicalManifold`,
527
+ would return the previously constructed object corresponding to these
528
+ arguments).
529
+
530
+ EXAMPLES:
531
+
532
+ A 4-dimensional differentiable manifold (over `\RR`)::
533
+
534
+ sage: M = Manifold(4, 'M', latex_name=r'\mathcal{M}'); M
535
+ 4-dimensional differentiable manifold M
536
+ sage: type(M)
537
+ <class 'sage.manifolds.differentiable.manifold.DifferentiableManifold_with_category'>
538
+ sage: latex(M)
539
+ \mathcal{M}
540
+ sage: dim(M)
541
+ 4
542
+
543
+ Since the base field has not been specified, `\RR` has been assumed::
544
+
545
+ sage: M.base_field()
546
+ Real Field with 53 bits of precision
547
+
548
+ Since the degree of differentiability has not been specified, the default
549
+ value, `C^\infty`, has been assumed::
550
+
551
+ sage: M.diff_degree()
552
+ +Infinity
553
+
554
+ The input parameter ``start_index`` defines the range of indices on the
555
+ manifold::
556
+
557
+ sage: M = Manifold(4, 'M')
558
+ sage: list(M.irange())
559
+ [0, 1, 2, 3]
560
+ sage: M = Manifold(4, 'M', start_index=1)
561
+ sage: list(M.irange())
562
+ [1, 2, 3, 4]
563
+ sage: list(Manifold(4, 'M', start_index=-2).irange())
564
+ [-2, -1, 0, 1]
565
+
566
+ A complex manifold::
567
+
568
+ sage: N = Manifold(3, 'N', field='complex'); N
569
+ 3-dimensional complex manifold N
570
+
571
+ A differentiable manifold over `\QQ_5`, the field of 5-adic numbers::
572
+
573
+ sage: # needs sage.rings.padics
574
+ sage: N = Manifold(2, 'N', field=Qp(5)); N
575
+ 2-dimensional differentiable manifold N over the 5-adic Field with
576
+ capped relative precision 20
577
+
578
+ A differentiable manifold is of course a topological manifold::
579
+
580
+ sage: isinstance(M, sage.manifolds.manifold.TopologicalManifold)
581
+ True
582
+ sage: isinstance(N, sage.manifolds.manifold.TopologicalManifold)
583
+ True
584
+
585
+ A differentiable manifold is a Sage *parent* object, in the category of
586
+ differentiable (here smooth) manifolds over a given topological field (see
587
+ :class:`~sage.categories.manifolds.Manifolds`)::
588
+
589
+ sage: isinstance(M, Parent)
590
+ True
591
+ sage: M.category()
592
+ Category of smooth manifolds over Real Field with 53 bits of precision
593
+ sage: from sage.categories.manifolds import Manifolds
594
+ sage: M.category() is Manifolds(RR).Smooth()
595
+ True
596
+ sage: M.category() is Manifolds(M.base_field()).Smooth()
597
+ True
598
+ sage: M in Manifolds(RR).Smooth()
599
+ True
600
+ sage: N in Manifolds(Qp(5)).Smooth() # needs sage.rings.padics
601
+ True
602
+
603
+ The corresponding Sage *elements* are points::
604
+
605
+ sage: X.<t, x, y, z> = M.chart()
606
+ sage: p = M.an_element(); p
607
+ Point on the 4-dimensional differentiable manifold M
608
+ sage: p.parent()
609
+ 4-dimensional differentiable manifold M
610
+ sage: M.is_parent_of(p)
611
+ True
612
+ sage: p in M
613
+ True
614
+
615
+ The manifold's points are instances of class
616
+ :class:`~sage.manifolds.point.ManifoldPoint`::
617
+
618
+ sage: isinstance(p, sage.manifolds.point.ManifoldPoint)
619
+ True
620
+
621
+ Since an open subset of a differentiable manifold `M` is itself a
622
+ differentiable manifold, open subsets of `M` have all attributes of
623
+ manifolds::
624
+
625
+ sage: U = M.open_subset('U', coord_def={X: t>0}); U
626
+ Open subset U of the 4-dimensional differentiable manifold M
627
+ sage: U.category()
628
+ Join of Category of subobjects of sets and Category of smooth manifolds
629
+ over Real Field with 53 bits of precision
630
+ sage: U.base_field() == M.base_field()
631
+ True
632
+ sage: dim(U) == dim(M)
633
+ True
634
+
635
+ The manifold passes all the tests of the test suite relative to its
636
+ category::
637
+
638
+ sage: TestSuite(M).run()
639
+ """
640
+ def __init__(self, n, name, field, structure, base_manifold=None,
641
+ diff_degree=infinity, latex_name=None, start_index=0,
642
+ category=None, unique_tag=None):
643
+ r"""
644
+ Construct a differentiable manifold.
645
+
646
+ TESTS::
647
+
648
+ sage: M = Manifold(3, 'M', latex_name=r'\mathbb{M}',
649
+ ....: start_index=1)
650
+ sage: M
651
+ 3-dimensional differentiable manifold M
652
+ sage: latex(M)
653
+ \mathbb{M}
654
+ sage: dim(M)
655
+ 3
656
+ sage: X.<x,y,z> = M.chart()
657
+ sage: TestSuite(M).run()
658
+
659
+ Tests for open subsets, which are constructed as differentiable
660
+ manifolds::
661
+
662
+ sage: U = M.open_subset('U', coord_def={X: x>0})
663
+ sage: type(U)
664
+ <class 'sage.manifolds.differentiable.manifold.DifferentiableManifold_with_category'>
665
+ sage: U.category() is M.category().Subobjects()
666
+ True
667
+ sage: TestSuite(U).run()
668
+ """
669
+ if base_manifold is None:
670
+ if category is None:
671
+ if field == 'real':
672
+ field_c = RR
673
+ elif field == 'complex':
674
+ field_c = CC
675
+ else:
676
+ field_c = field
677
+ if diff_degree == infinity:
678
+ category = Manifolds(field_c).Smooth()
679
+ else:
680
+ category = Manifolds(field_c).Differentiable()
681
+ elif not isinstance(base_manifold, DifferentiableManifold):
682
+ raise TypeError("the argument 'base_manifold' must be a " +
683
+ "differentiable manifold")
684
+ TopologicalManifold.__init__(self, n, name, field, structure,
685
+ base_manifold=base_manifold,
686
+ latex_name=latex_name,
687
+ start_index=start_index,
688
+ category=category)
689
+ # The degree of differentiability:
690
+ if diff_degree == infinity:
691
+ self._diff_degree = infinity
692
+ elif not isinstance(diff_degree, (int, Integer)):
693
+ raise TypeError("the argument 'diff_degree' must be an integer")
694
+ elif diff_degree < 1:
695
+ raise ValueError("the argument 'diff_degree' must be a positive " +
696
+ "integer")
697
+ else:
698
+ self._diff_degree = diff_degree
699
+ # Vector frames:
700
+ self._frames = [] # list of vector frames defined on subsets of self
701
+ # list of vector frames defined on subsets of self that are
702
+ # not subframes of frames on larger subsets
703
+ self._top_frames = []
704
+ self._def_frame = None # default frame
705
+ self._coframes = [] # list of coframes defined on subsets of self
706
+ # List of vector frames that individually cover self, i.e. whose
707
+ # domains are self (if non-empty, self is parallelizable):
708
+ self._covering_frames = []
709
+ self._parallelizable_parts = set() # parallelizable subsets contained in self
710
+ self._frame_changes = {} # dictionary of changes of frames
711
+ # Dictionary of vector field modules along self
712
+ # (keys = diff. map from self to an open set (possibly the identity map))
713
+ self._vector_field_modules = {} # dict of all established vector field
714
+ # modules
715
+ self._tensor_bundles = {} # dict of dict of all established tensor
716
+ # bundles
717
+
718
+ def diff_degree(self):
719
+ r"""
720
+ Return the manifold's degree of differentiability.
721
+
722
+ The degree of differentiability is the integer `k` (possibly
723
+ `k=\infty`) such that the manifold is a `C^k`-manifold over its base
724
+ field.
725
+
726
+ EXAMPLES::
727
+
728
+ sage: M = Manifold(2, 'M')
729
+ sage: M.diff_degree()
730
+ +Infinity
731
+ sage: M = Manifold(2, 'M', structure='differentiable', diff_degree=3)
732
+ sage: M.diff_degree()
733
+ 3
734
+ """
735
+ return self._diff_degree
736
+
737
+ def open_subset(self, name, latex_name=None, coord_def={}, supersets=None):
738
+ r"""
739
+ Create an open subset of the manifold.
740
+
741
+ An open subset is a set that is (i) included in the manifold and (ii)
742
+ open with respect to the manifold's topology. It is a differentiable
743
+ manifold by itself. Hence the returned object is an instance of
744
+ :class:`DifferentiableManifold`.
745
+
746
+ INPUT:
747
+
748
+ - ``name`` -- name given to the open subset
749
+ - ``latex_name`` -- (default: ``None``) LaTeX symbol to denote the
750
+ subset; if none is provided, it is set to ``name``
751
+ - ``coord_def`` -- (default: {}) definition of the subset in
752
+ terms of coordinates; ``coord_def`` must a be dictionary with keys
753
+ charts in the manifold's atlas and values the symbolic expressions
754
+ formed by the coordinates to define the subset.
755
+ - ``supersets`` -- (default: only ``self``) list of sets that the
756
+ new open subset is a subset of
757
+
758
+ OUTPUT: the open subset, as an instance of :class:`DifferentiableManifold`
759
+
760
+ EXAMPLES:
761
+
762
+ Creating an open subset of a differentiable manifold::
763
+
764
+ sage: M = Manifold(2, 'M')
765
+ sage: A = M.open_subset('A'); A
766
+ Open subset A of the 2-dimensional differentiable manifold M
767
+
768
+ As an open subset of a differentiable manifold, ``A`` is itself a
769
+ differentiable manifold, on the same topological field and of the same
770
+ dimension as ``M``::
771
+
772
+ sage: A.category()
773
+ Join of Category of subobjects of sets and Category of smooth
774
+ manifolds over Real Field with 53 bits of precision
775
+ sage: A.base_field() == M.base_field()
776
+ True
777
+ sage: dim(A) == dim(M)
778
+ True
779
+
780
+ Creating an open subset of ``A``::
781
+
782
+ sage: B = A.open_subset('B'); B
783
+ Open subset B of the 2-dimensional differentiable manifold M
784
+
785
+ We have then::
786
+
787
+ sage: A.subset_family()
788
+ Set {A, B} of open subsets of the 2-dimensional differentiable manifold M
789
+ sage: B.is_subset(A)
790
+ True
791
+ sage: B.is_subset(M)
792
+ True
793
+
794
+ Defining an open subset by some coordinate restrictions: the open
795
+ unit disk in of the Euclidean plane::
796
+
797
+ sage: X.<x,y> = M.chart() # Cartesian coordinates on M
798
+ sage: U = M.open_subset('U', coord_def={X: x^2+y^2<1}); U
799
+ Open subset U of the 2-dimensional differentiable manifold M
800
+
801
+ Since the argument ``coord_def`` has been set, ``U`` is automatically
802
+ endowed with a chart, which is the restriction of ``X``
803
+ to ``U``::
804
+
805
+ sage: U.atlas()
806
+ [Chart (U, (x, y))]
807
+ sage: U.default_chart()
808
+ Chart (U, (x, y))
809
+ sage: U.default_chart() is X.restrict(U)
810
+ True
811
+
812
+ A point in ``U``::
813
+
814
+ sage: p = U.an_element(); p
815
+ Point on the 2-dimensional differentiable manifold M
816
+ sage: X(p) # the coordinates (x,y) of p
817
+ (0, 0)
818
+ sage: p in U
819
+ True
820
+
821
+ Checking whether various points, defined by their coordinates
822
+ with respect to chart ``X``, are in ``U``::
823
+
824
+ sage: M((0,1/2)) in U
825
+ True
826
+ sage: M((0,1)) in U
827
+ False
828
+ sage: M((1/2,1)) in U
829
+ False
830
+ sage: M((-1/2,1/3)) in U
831
+ True
832
+ """
833
+ resu = DifferentiableManifold(self._dim, name, self._field,
834
+ self._structure, base_manifold=self._manifold,
835
+ diff_degree=self._diff_degree,
836
+ latex_name=latex_name,
837
+ start_index=self._sindex)
838
+ if supersets is None:
839
+ supersets = [self]
840
+ for superset in supersets:
841
+ superset._init_open_subset(resu, coord_def=coord_def)
842
+ return resu
843
+
844
+ def _init_open_subset(self, resu, coord_def):
845
+ r"""
846
+ Initialize ``resu`` as an open subset of ``self``.
847
+
848
+ INPUT:
849
+
850
+ - ``resu`` -- an instance of :class:`TopologicalManifold` or
851
+ a subclass
852
+
853
+ - ``coord_def`` -- (default: ``{}``) definition of the subset in
854
+ terms of coordinates; ``coord_def`` must a be dictionary with keys
855
+ charts on the manifold and values the symbolic expressions formed
856
+ by the coordinates to define the subset
857
+
858
+ EXAMPLES::
859
+
860
+ sage: M = Manifold(2, 'R^2', structure='differentiable')
861
+ sage: c_cart.<x,y> = M.chart() # Cartesian coordinates on R^2
862
+ sage: from sage.manifolds.differentiable.manifold import DifferentiableManifold
863
+ sage: U = DifferentiableManifold(2, 'U', field=M._field, structure=M._structure, base_manifold=M)
864
+ sage: M._init_open_subset(U, coord_def={c_cart: x^2+y^2<1})
865
+ sage: U
866
+ Open subset U of the 2-dimensional differentiable manifold R^2
867
+ """
868
+ super()._init_open_subset(resu, coord_def=coord_def)
869
+ #!# update vector frames and change of frames
870
+
871
+ def diff_map(self, codomain, coord_functions=None, chart1=None,
872
+ chart2=None, name=None, latex_name=None):
873
+ r"""
874
+ Define a differentiable map between the current differentiable manifold
875
+ and a differentiable manifold over the same topological field.
876
+
877
+ See :class:`~sage.manifolds.differentiable.diff_map.DiffMap` for a
878
+ complete documentation.
879
+
880
+ INPUT:
881
+
882
+ - ``codomain`` -- the map codomain (a differentiable manifold over the
883
+ same topological field as the current differentiable manifold)
884
+ - ``coord_functions`` -- (default: ``None``) if not ``None``, must be
885
+ either
886
+
887
+ - (i) a dictionary of
888
+ the coordinate expressions (as lists (or tuples) of the
889
+ coordinates of the image expressed in terms of the coordinates of
890
+ the considered point) with the pairs of charts (chart1, chart2)
891
+ as keys (chart1 being a chart on the current manifold and chart2 a
892
+ chart on ``codomain``)
893
+ - (ii) a single coordinate expression in a given pair of charts, the
894
+ latter being provided by the arguments ``chart1`` and ``chart2``
895
+
896
+ In both cases, if the dimension of the arrival manifold is 1,
897
+ a single coordinate expression can be passed instead of a tuple with
898
+ a single element
899
+ - ``chart1`` -- (default: ``None``; used only in case (ii) above) chart
900
+ on the current manifold defining the start coordinates involved in
901
+ ``coord_functions`` for case (ii); if none is provided, the
902
+ coordinates are assumed to refer to the manifold's default chart
903
+ - ``chart2`` -- (default: ``None``; used only in case (ii) above) chart
904
+ on ``codomain`` defining the arrival coordinates involved in
905
+ ``coord_functions`` for case (ii); if none is provided, the
906
+ coordinates are assumed to refer to the default chart of ``codomain``
907
+ - ``name`` -- (default: ``None``) name given to the differentiable
908
+ map
909
+ - ``latex_name`` -- (default: ``None``) LaTeX symbol to denote the
910
+ differentiable map; if none is provided, the LaTeX symbol is set to
911
+ ``name``
912
+
913
+ OUTPUT:
914
+
915
+ - the differentiable map, as an instance of
916
+ :class:`~sage.manifolds.differentiable.diff_map.DiffMap`
917
+
918
+ EXAMPLES:
919
+
920
+ A differentiable map between an open subset of `S^2` covered by regular
921
+ spherical coordinates and `\RR^3`::
922
+
923
+ sage: M = Manifold(2, 'S^2')
924
+ sage: U = M.open_subset('U')
925
+ sage: c_spher.<th,ph> = U.chart(r'th:(0,pi):\theta ph:(0,2*pi):\phi')
926
+ sage: N = Manifold(3, 'R^3', r'\RR^3')
927
+ sage: c_cart.<x,y,z> = N.chart() # Cartesian coord. on R^3
928
+ sage: Phi = U.diff_map(N, (sin(th)*cos(ph), sin(th)*sin(ph), cos(th)),
929
+ ....: name='Phi', latex_name=r'\Phi')
930
+ sage: Phi
931
+ Differentiable map Phi from the Open subset U of the 2-dimensional
932
+ differentiable manifold S^2 to the 3-dimensional differentiable
933
+ manifold R^3
934
+
935
+ The same definition, but with a dictionary with pairs of charts as
936
+ keys (case (i) above)::
937
+
938
+ sage: Phi1 = U.diff_map(N,
939
+ ....: {(c_spher, c_cart): (sin(th)*cos(ph), sin(th)*sin(ph),
940
+ ....: cos(th))}, name='Phi', latex_name=r'\Phi')
941
+ sage: Phi1 == Phi
942
+ True
943
+
944
+ The differentiable map acting on a point::
945
+
946
+ sage: p = U.point((pi/2, pi)) ; p
947
+ Point on the 2-dimensional differentiable manifold S^2
948
+ sage: Phi(p)
949
+ Point on the 3-dimensional differentiable manifold R^3
950
+ sage: Phi(p).coord(c_cart)
951
+ (-1, 0, 0)
952
+ sage: Phi1(p) == Phi(p)
953
+ True
954
+
955
+ See the documentation of class
956
+ :class:`~sage.manifolds.differentiable.diff_map.DiffMap` for more
957
+ examples.
958
+ """
959
+ homset = Hom(self, codomain)
960
+ if coord_functions is None:
961
+ coord_functions = {}
962
+ if not isinstance(coord_functions, dict):
963
+ # Turn coord_functions into a dictionary:
964
+ if chart1 is None:
965
+ chart1 = self._def_chart
966
+ elif chart1 not in self._atlas:
967
+ raise ValueError("{} is not a chart ".format(chart1) +
968
+ "defined on the {}".format(self))
969
+ if chart2 is None:
970
+ chart2 = codomain._def_chart
971
+ elif chart2 not in codomain._atlas:
972
+ raise ValueError("{} is not a chart ".format(chart2) +
973
+ " defined on the {}".format(codomain))
974
+ coord_functions = {(chart1, chart2): coord_functions}
975
+ return homset(coord_functions, name=name, latex_name=latex_name)
976
+
977
+ def diffeomorphism(self, codomain=None, coord_functions=None, chart1=None,
978
+ chart2=None, name=None, latex_name=None):
979
+ r"""
980
+ Define a diffeomorphism between the current manifold and another one.
981
+
982
+ See :class:`~sage.manifolds.differentiable.diff_map.DiffMap` for a
983
+ complete documentation.
984
+
985
+ INPUT:
986
+
987
+ - ``codomain`` -- (default: ``None``) codomain of the diffeomorphism (the arrival manifold
988
+ or some subset of it). If ``None``, the current manifold is taken.
989
+ - ``coord_functions`` -- (default: ``None``) if not ``None``, must be
990
+ either
991
+
992
+ - (i) a dictionary of
993
+ the coordinate expressions (as lists (or tuples) of the
994
+ coordinates of the image expressed in terms of the coordinates of
995
+ the considered point) with the pairs of charts (chart1, chart2)
996
+ as keys (chart1 being a chart on the current manifold and chart2
997
+ a chart on ``codomain``)
998
+ - (ii) a single coordinate expression in a given pair of charts, the
999
+ latter being provided by the arguments ``chart1`` and ``chart2``
1000
+
1001
+ In both cases, if the dimension of the arrival manifold is 1,
1002
+ a single coordinate expression can be passed instead of a tuple with
1003
+ a single element
1004
+ - ``chart1`` -- (default: ``None``; used only in case (ii) above) chart
1005
+ on the current manifold defining the start coordinates involved in
1006
+ ``coord_functions`` for case (ii); if none is provided, the
1007
+ coordinates are assumed to refer to the manifold's default chart
1008
+ - ``chart2`` -- (default: ``None``; used only in case (ii) above) chart
1009
+ on ``codomain`` defining the arrival coordinates involved in
1010
+ ``coord_functions`` for case (ii); if none is provided, the
1011
+ coordinates are assumed to refer to the default chart of ``codomain``
1012
+ - ``name`` -- (default: ``None``) name given to the diffeomorphism
1013
+ - ``latex_name`` -- (default: ``None``) LaTeX symbol to denote the
1014
+ diffeomorphism; if none is provided, the LaTeX symbol is set to
1015
+ ``name``
1016
+
1017
+ OUTPUT:
1018
+
1019
+ - the diffeomorphism, as an instance of
1020
+ :class:`~sage.manifolds.differentiable.diff_map.DiffMap`
1021
+
1022
+ EXAMPLES:
1023
+
1024
+ Diffeomorphism between the open unit disk in `\RR^2` and `\RR^2`::
1025
+
1026
+ sage: M = Manifold(2, 'M') # the open unit disk
1027
+ sage: forget() # for doctests only
1028
+ sage: c_xy.<x,y> = M.chart('x:(-1,1) y:(-1,1)', coord_restrictions=lambda x,y: x^2+y^2<1)
1029
+ ....: # Cartesian coord on M
1030
+ sage: N = Manifold(2, 'N') # R^2
1031
+ sage: c_XY.<X,Y> = N.chart() # canonical coordinates on R^2
1032
+ sage: Phi = M.diffeomorphism(N, [x/sqrt(1-x^2-y^2), y/sqrt(1-x^2-y^2)],
1033
+ ....: name='Phi', latex_name=r'\Phi')
1034
+ sage: Phi
1035
+ Diffeomorphism Phi from the 2-dimensional differentiable manifold M
1036
+ to the 2-dimensional differentiable manifold N
1037
+ sage: Phi.display()
1038
+ Phi: M → N
1039
+ (x, y) ↦ (X, Y) = (x/sqrt(-x^2 - y^2 + 1), y/sqrt(-x^2 - y^2 + 1))
1040
+
1041
+ The inverse diffeomorphism::
1042
+
1043
+ sage: Phi^(-1)
1044
+ Diffeomorphism Phi^(-1) from the 2-dimensional differentiable
1045
+ manifold N to the 2-dimensional differentiable manifold M
1046
+ sage: (Phi^(-1)).display()
1047
+ Phi^(-1): N → M
1048
+ (X, Y) ↦ (x, y) = (X/sqrt(X^2 + Y^2 + 1), Y/sqrt(X^2 + Y^2 + 1))
1049
+
1050
+ See the documentation of class
1051
+ :class:`~sage.manifolds.differentiable.diff_map.DiffMap` for more
1052
+ examples.
1053
+ """
1054
+ if codomain is None:
1055
+ codomain = self
1056
+
1057
+ homset = Hom(self, codomain)
1058
+ if coord_functions is None:
1059
+ coord_functions = {}
1060
+ if not isinstance(coord_functions, dict):
1061
+ # Turn coord_functions into a dictionary:
1062
+ if chart1 is None:
1063
+ chart1 = self._def_chart
1064
+ elif chart1 not in self._atlas:
1065
+ raise ValueError("{} is not a chart ".format(chart1) +
1066
+ "defined on the {}".format(self))
1067
+ if chart2 is None:
1068
+ chart2 = codomain._def_chart
1069
+ elif chart2 not in codomain._atlas:
1070
+ raise ValueError("{} is not a chart ".format(chart2) +
1071
+ " defined on the {}".format(codomain))
1072
+ coord_functions = {(chart1, chart2): coord_functions}
1073
+ return homset(coord_functions, name=name, latex_name=latex_name,
1074
+ is_isomorphism=True)
1075
+
1076
+ def vector_bundle(self, rank, name, field='real', latex_name=None):
1077
+ r"""
1078
+ Return a differentiable vector bundle over the given field with given
1079
+ rank over this differentiable manifold of the same differentiability
1080
+ class as the manifold.
1081
+
1082
+ INPUT:
1083
+
1084
+ - ``rank`` -- rank of the vector bundle
1085
+ - ``name`` -- name given to the total space
1086
+ - ``field`` -- (default: ``'real'``) topological field giving the
1087
+ vector space structure to the fibers
1088
+ - ``latex_name`` -- (optional) LaTeX name for the total space
1089
+
1090
+ OUTPUT:
1091
+
1092
+ - a differentiable vector bundle as an instance of
1093
+ :class:`~sage.manifolds.differentiable.vector_bundle.DifferentiableVectorBundle`
1094
+
1095
+ EXAMPLES::
1096
+
1097
+ sage: M = Manifold(2, 'M')
1098
+ sage: M.vector_bundle(2, 'E')
1099
+ Differentiable real vector bundle E -> M of rank 2 over the base
1100
+ space 2-dimensional differentiable manifold M
1101
+ """
1102
+ from sage.manifolds.differentiable.vector_bundle import (
1103
+ DifferentiableVectorBundle,
1104
+ )
1105
+ return DifferentiableVectorBundle(rank, name, self, field=field,
1106
+ latex_name=latex_name)
1107
+
1108
+ def tangent_bundle(self, dest_map=None):
1109
+ r"""
1110
+ Return the tangent bundle possibly along a destination map with base
1111
+ space ``self``.
1112
+
1113
+ .. SEEALSO::
1114
+
1115
+ :class:`~sage.manifolds.differentiable.vector_bundle.TensorBundle`
1116
+ for complete documentation.
1117
+
1118
+ INPUT:
1119
+
1120
+ - ``dest_map`` -- (default: ``None``) destination map
1121
+ `\Phi:\ M \rightarrow N`
1122
+ (type: :class:`~sage.manifolds.differentiable.diff_map.DiffMap`) from
1123
+ which the tangent bundle is pulled back; if
1124
+ ``None``, it is assumed that `N=M` and `\Phi` is the identity map of
1125
+ `M` (case of the standard tangent bundle over `M`)
1126
+
1127
+ EXAMPLES::
1128
+
1129
+ sage: M = Manifold(2, 'M')
1130
+ sage: TM = M.tangent_bundle(); TM
1131
+ Tangent bundle TM over the 2-dimensional differentiable manifold M
1132
+ """
1133
+ return self.tensor_bundle(1, 0, dest_map=dest_map)
1134
+
1135
+ def cotangent_bundle(self, dest_map=None):
1136
+ r"""
1137
+ Return the cotangent bundle possibly along a destination map with base
1138
+ space ``self``.
1139
+
1140
+ .. SEEALSO::
1141
+
1142
+ :class:`~sage.manifolds.differentiable.vector_bundle.TensorBundle`
1143
+ for complete documentation.
1144
+
1145
+ INPUT:
1146
+
1147
+ - ``dest_map`` -- (default: ``None``) destination map
1148
+ `\Phi:\ M \rightarrow N`
1149
+ (type: :class:`~sage.manifolds.differentiable.diff_map.DiffMap`) from
1150
+ which the cotangent bundle is pulled back; if
1151
+ ``None``, it is assumed that `N=M` and `\Phi` is the identity map of
1152
+ `M` (case of the standard tangent bundle over `M`)
1153
+
1154
+ EXAMPLES::
1155
+
1156
+ sage: M = Manifold(2, 'M')
1157
+ sage: cTM = M.cotangent_bundle(); cTM
1158
+ Cotangent bundle T*M over the 2-dimensional differentiable
1159
+ manifold M
1160
+ """
1161
+ return self.tensor_bundle(0, 1, dest_map=dest_map)
1162
+
1163
+ def tensor_bundle(self, k, l, dest_map=None):
1164
+ r"""
1165
+ Return a tensor bundle of type `(k, l)` defined over ``self``, possibly
1166
+ along a destination map.
1167
+
1168
+ INPUT:
1169
+
1170
+ - ``k`` -- the contravariant rank of the tensor bundle
1171
+ - ``l`` -- the covariant rank of the tensor bundle
1172
+ - ``dest_map`` -- (default: ``None``) destination map
1173
+ `\Phi:\ M \rightarrow N`
1174
+ (type: :class:`~sage.manifolds.differentiable.diff_map.DiffMap`) from
1175
+ which the tensor bundle is pulled back; if
1176
+ ``None``, it is assumed that `N=M` and `\Phi` is the identity map of
1177
+ `M` (case of the standard tangent bundle over `M`)
1178
+
1179
+ OUTPUT:
1180
+
1181
+ - a
1182
+ :class:`~sage.manifolds.differentiable.vector_bundle.TensorBundle`
1183
+ representing a tensor bundle of type-`(k,l)` over ``self``
1184
+
1185
+ EXAMPLES:
1186
+
1187
+ A tensor bundle over a parallelizable 2-dimensional differentiable
1188
+ manifold::
1189
+
1190
+ sage: M = Manifold(2, 'M')
1191
+ sage: X.<x,y> = M.chart() # makes M parallelizable
1192
+ sage: M.tensor_bundle(1, 2)
1193
+ Tensor bundle T^(1,2)M over the 2-dimensional differentiable
1194
+ manifold M
1195
+
1196
+ The special case of the tangent bundle as tensor bundle of type (1,0)::
1197
+
1198
+ sage: M.tensor_bundle(1,0)
1199
+ Tangent bundle TM over the 2-dimensional differentiable manifold M
1200
+
1201
+ The result is cached::
1202
+
1203
+ sage: M.tensor_bundle(1, 2) is M.tensor_bundle(1, 2)
1204
+ True
1205
+
1206
+ .. SEEALSO::
1207
+
1208
+ :class:`~sage.manifolds.differentiable.vector_bundle.TensorBundle`
1209
+ for more examples and documentation.
1210
+ """
1211
+ if dest_map is None:
1212
+ dest_map = self.identity_map()
1213
+ if dest_map not in self._tensor_bundles:
1214
+ from sage.manifolds.differentiable.vector_bundle import TensorBundle
1215
+ self._tensor_bundles[dest_map] = {(k, l):
1216
+ TensorBundle(self, k, l,
1217
+ dest_map=dest_map)}
1218
+ else:
1219
+ if (k, l) not in self._tensor_bundles[dest_map]:
1220
+ from sage.manifolds.differentiable.vector_bundle import TensorBundle
1221
+ self._tensor_bundles[dest_map][(k, l)] = TensorBundle(self, k,
1222
+ l, dest_map=dest_map)
1223
+ return self._tensor_bundles[dest_map][(k, l)]
1224
+
1225
+ def vector_field_module(
1226
+ self, dest_map: Optional[DiffMap] = None, force_free: bool = False
1227
+ ) -> Union[VectorFieldModule, VectorFieldFreeModule]:
1228
+ r"""
1229
+ Return the set of vector fields defined on ``self``, possibly
1230
+ with values in another differentiable manifold, as a module over the
1231
+ algebra of scalar fields defined on the manifold.
1232
+
1233
+ See :class:`~sage.manifolds.differentiable.vectorfield_module.VectorFieldModule`
1234
+ for a complete documentation.
1235
+
1236
+ INPUT:
1237
+
1238
+ - ``dest_map`` -- (default: ``None``) destination map, i.e. a
1239
+ differentiable map `\Phi:\ M \rightarrow N`, where `M` is the
1240
+ current manifold and `N` a differentiable manifold;
1241
+ if ``None``, it is assumed that `N = M` and that `\Phi` is the
1242
+ identity map (case of vector fields *on* `M`), otherwise
1243
+ ``dest_map`` must be a
1244
+ :class:`~sage.manifolds.differentiable.diff_map.DiffMap`
1245
+ - ``force_free`` -- boolean (default: ``False``); if set to ``True``, force
1246
+ the construction of a *free* module (this implies that `N` is
1247
+ parallelizable)
1248
+
1249
+ OUTPUT:
1250
+
1251
+ - a
1252
+ :class:`~sage.manifolds.differentiable.vectorfield_module.VectorFieldModule`
1253
+ (or if `N` is parallelizable, a
1254
+ :class:`~sage.manifolds.differentiable.vectorfield_module.VectorFieldFreeModule`)
1255
+ representing the `C^k(M)`-module `\mathfrak{X}(M,\Phi)` of vector
1256
+ fields on `M` taking values on `\Phi(M)\subset N`
1257
+
1258
+ EXAMPLES:
1259
+
1260
+ Vector field module `\mathfrak{X}(U) := \mathfrak{X}(U,\mathrm{Id}_U)`
1261
+ of the complement `U` of the two poles on the sphere `\mathbb{S}^2`::
1262
+
1263
+ sage: S2 = Manifold(2, 'S^2')
1264
+ sage: U = S2.open_subset('U') # the complement of the two poles
1265
+ sage: spher_coord.<th,ph> = U.chart(r'th:(0,pi):\theta ph:(0,2*pi):\phi') # spherical coordinates
1266
+ sage: XU = U.vector_field_module() ; XU
1267
+ Free module X(U) of vector fields on the Open subset U of
1268
+ the 2-dimensional differentiable manifold S^2
1269
+ sage: XU.category()
1270
+ Category of finite dimensional modules over Algebra of
1271
+ differentiable scalar fields on the Open subset U of
1272
+ the 2-dimensional differentiable manifold S^2
1273
+ sage: XU.base_ring()
1274
+ Algebra of differentiable scalar fields on the Open subset U of
1275
+ the 2-dimensional differentiable manifold S^2
1276
+ sage: XU.base_ring() is U.scalar_field_algebra()
1277
+ True
1278
+
1279
+ `\mathfrak{X}(U)` is a free module because `U` is parallelizable
1280
+ (being a chart domain)::
1281
+
1282
+ sage: U.is_manifestly_parallelizable()
1283
+ True
1284
+
1285
+ Its rank is the manifold's dimension::
1286
+
1287
+ sage: XU.rank()
1288
+ 2
1289
+
1290
+ The elements of `\mathfrak{X}(U)` are vector fields on `U`::
1291
+
1292
+ sage: XU.an_element()
1293
+ Vector field on the Open subset U of the 2-dimensional
1294
+ differentiable manifold S^2
1295
+ sage: XU.an_element().display()
1296
+ 2 ∂/∂th + 2 ∂/∂ph
1297
+
1298
+ Vector field module `\mathfrak{X}(U,\Phi)` of the
1299
+ `\RR^3`-valued vector fields along `U`, associated with the
1300
+ embedding `\Phi` of `\mathbb{S}^2` into `\RR^3`::
1301
+
1302
+ sage: R3 = Manifold(3, 'R^3')
1303
+ sage: cart_coord.<x, y, z> = R3.chart()
1304
+ sage: Phi = U.diff_map(R3,
1305
+ ....: [sin(th)*cos(ph), sin(th)*sin(ph), cos(th)], name='Phi')
1306
+ sage: XU_R3 = U.vector_field_module(dest_map=Phi) ; XU_R3
1307
+ Free module X(U,Phi) of vector fields along the Open subset U of
1308
+ the 2-dimensional differentiable manifold S^2 mapped into the
1309
+ 3-dimensional differentiable manifold R^3
1310
+ sage: XU_R3.base_ring()
1311
+ Algebra of differentiable scalar fields on the Open subset U of the
1312
+ 2-dimensional differentiable manifold S^2
1313
+
1314
+ `\mathfrak{X}(U,\Phi)` is a free module because `\RR^3`
1315
+ is parallelizable and its rank is 3::
1316
+
1317
+ sage: XU_R3.rank()
1318
+ 3
1319
+
1320
+ Without any information on the manifold, the vector field module is
1321
+ not free by default::
1322
+
1323
+ sage: M = Manifold(2, 'M')
1324
+ sage: XM = M.vector_field_module()
1325
+ sage: isinstance(XM, FiniteRankFreeModule)
1326
+ False
1327
+
1328
+ In particular, declaring a coordinate chart on ``M`` would yield an
1329
+ error::
1330
+
1331
+ sage: X.<x,y> = M.chart()
1332
+ Traceback (most recent call last):
1333
+ ...
1334
+ ValueError: the Module X(M) of vector fields on the 2-dimensional
1335
+ differentiable manifold M has already been constructed as a
1336
+ non-free module, which implies that the 2-dimensional
1337
+ differentiable manifold M is not parallelizable and hence cannot
1338
+ be the domain of a coordinate chart
1339
+
1340
+ Similarly, one cannot declare a vector frame on `M`::
1341
+
1342
+ sage: e = M.vector_frame('e')
1343
+ Traceback (most recent call last):
1344
+ ...
1345
+ ValueError: the Module X(M) of vector fields on the 2-dimensional
1346
+ differentiable manifold M has already been constructed as a
1347
+ non-free module and therefore cannot have a basis
1348
+
1349
+ One shall use the keyword ``force_free=True`` to construct a free
1350
+ module before declaring the chart::
1351
+
1352
+ sage: M = Manifold(2, 'M')
1353
+ sage: XM = M.vector_field_module(force_free=True)
1354
+ sage: X.<x,y> = M.chart() # OK
1355
+ sage: e = M.vector_frame('e') # OK
1356
+
1357
+ If one declares the chart or the vector frame before asking for the
1358
+ vector field module, the latter is initialized as a free module,
1359
+ without the need to specify ``force_free=True``. Indeed, the
1360
+ information that `M` is the domain of a chart or a vector frame implies
1361
+ that `M` is parallelizable and is therefore sufficient to assert that
1362
+ `\mathfrak{X}(M)` is a free module over `C^k(M)`::
1363
+
1364
+ sage: M = Manifold(2, 'M')
1365
+ sage: X.<x,y> = M.chart()
1366
+ sage: XM = M.vector_field_module()
1367
+ sage: isinstance(XM, FiniteRankFreeModule)
1368
+ True
1369
+ sage: M.is_manifestly_parallelizable()
1370
+ True
1371
+ """
1372
+ from sage.manifolds.differentiable.vectorfield_module import (
1373
+ VectorFieldFreeModule,
1374
+ VectorFieldModule,
1375
+ )
1376
+ if dest_map is None:
1377
+ dest_map = self.identity_map()
1378
+ codomain = dest_map._codomain
1379
+ if dest_map not in self._vector_field_modules:
1380
+ if codomain.is_manifestly_parallelizable() or force_free:
1381
+ self._vector_field_modules[dest_map] = \
1382
+ VectorFieldFreeModule(self, dest_map=dest_map)
1383
+ else:
1384
+ self._vector_field_modules[dest_map] = \
1385
+ VectorFieldModule(self, dest_map=dest_map)
1386
+ return self._vector_field_modules[dest_map]
1387
+
1388
+ def tensor_field_module(self, tensor_type, dest_map=None):
1389
+ r"""
1390
+ Return the set of tensor fields of a given type defined on ``self``,
1391
+ possibly with values in another manifold, as a module over
1392
+ the algebra of scalar fields defined on ``self``.
1393
+
1394
+ .. SEEALSO::
1395
+
1396
+ :class:`~sage.manifolds.differentiable.tensorfield_module.TensorFieldModule`
1397
+ for a complete documentation.
1398
+
1399
+ INPUT:
1400
+
1401
+ - ``tensor_type`` -- pair `(k,l)` with `k` being the contravariant
1402
+ rank and `l` the covariant rank
1403
+ - ``dest_map`` -- (default: ``None``) destination map, i.e. a
1404
+ differentiable map `\Phi:\ M \rightarrow N`, where `M` is the
1405
+ current manifold and `N` a differentiable manifold;
1406
+ if ``None``, it is assumed that `N = M` and that `\Phi` is the
1407
+ identity map (case of tensor fields *on* `M`), otherwise
1408
+ ``dest_map`` must be a
1409
+ :class:`~sage.manifolds.differentiable.diff_map.DiffMap`
1410
+
1411
+ OUTPUT:
1412
+
1413
+ - a
1414
+ :class:`~sage.manifolds.differentiable.tensorfield_module.TensorFieldModule`
1415
+ (or if `N` is parallelizable, a
1416
+ :class:`~sage.manifolds.differentiable.tensorfield_module.TensorFieldFreeModule`)
1417
+ representing the module `\mathcal{T}^{(k,l)}(M,\Phi)` of type-`(k,l)`
1418
+ tensor fields on `M` taking values on `\Phi(M)\subset N`
1419
+
1420
+ EXAMPLES:
1421
+
1422
+ Module of type-`(2,1)` tensor fields on a 3-dimensional open subset of
1423
+ a differentiable manifold::
1424
+
1425
+ sage: M = Manifold(3, 'M')
1426
+ sage: U = M.open_subset('U')
1427
+ sage: c_xyz.<x,y,z> = U.chart()
1428
+ sage: TU = U.tensor_field_module((2,1)) ; TU
1429
+ Free module T^(2,1)(U) of type-(2,1) tensors fields on the Open
1430
+ subset U of the 3-dimensional differentiable manifold M
1431
+ sage: TU.category()
1432
+ Category of tensor products of finite dimensional modules
1433
+ over Algebra of differentiable scalar fields
1434
+ on the Open subset U of the 3-dimensional differentiable manifold M
1435
+ sage: TU.base_ring()
1436
+ Algebra of differentiable scalar fields on the Open subset U of
1437
+ the 3-dimensional differentiable manifold M
1438
+ sage: TU.base_ring() is U.scalar_field_algebra()
1439
+ True
1440
+ sage: TU.an_element()
1441
+ Tensor field of type (2,1) on the Open subset U of the
1442
+ 3-dimensional differentiable manifold M
1443
+ sage: TU.an_element().display()
1444
+ 2 ∂/∂x⊗∂/∂x⊗dx
1445
+ """
1446
+ return self.vector_field_module(dest_map=dest_map).tensor_module(*tensor_type)
1447
+
1448
+ def diff_form_module(self, degree, dest_map=None):
1449
+ r"""
1450
+ Return the set of differential forms of a given degree defined on
1451
+ ``self``, possibly with values in another manifold, as a module
1452
+ over the algebra of scalar fields defined on ``self``.
1453
+
1454
+ .. SEEALSO::
1455
+
1456
+ :class:`~sage.manifolds.differentiable.diff_form_module.DiffFormModule`
1457
+ for complete documentation.
1458
+
1459
+ INPUT:
1460
+
1461
+ - ``degree`` -- positive integer; the degree `p` of the
1462
+ differential forms
1463
+ - ``dest_map`` -- (default: ``None``) destination map, i.e. a
1464
+ differentiable map `\Phi:\ M \rightarrow N`, where `M` is the
1465
+ current manifold and `N` a differentiable manifold;
1466
+ if ``None``, it is assumed that `N = M` and that `\Phi` is the
1467
+ identity map (case of differential forms *on* `M`), otherwise
1468
+ ``dest_map`` must be a
1469
+ :class:`~sage.manifolds.differentiable.diff_map.DiffMap`
1470
+
1471
+ OUTPUT:
1472
+
1473
+ - a
1474
+ :class:`~sage.manifolds.differentiable.diff_form_module.DiffFormModule`
1475
+ (or if `N` is parallelizable, a
1476
+ :class:`~sage.manifolds.differentiable.diff_form_module.DiffFormFreeModule`)
1477
+ representing the module `\Omega^p(M,\Phi)` of `p`-forms on `M`
1478
+ taking values on `\Phi(M)\subset N`
1479
+
1480
+ EXAMPLES:
1481
+
1482
+ Module of 2-forms on a 3-dimensional parallelizable manifold::
1483
+
1484
+ sage: M = Manifold(3, 'M')
1485
+ sage: X.<x,y,z> = M.chart()
1486
+ sage: M.diff_form_module(2)
1487
+ Free module Omega^2(M) of 2-forms on the 3-dimensional
1488
+ differentiable manifold M
1489
+ sage: M.diff_form_module(2).category()
1490
+ Category of finite dimensional modules over Algebra of
1491
+ differentiable scalar fields on the 3-dimensional
1492
+ differentiable manifold M
1493
+ sage: M.diff_form_module(2).base_ring()
1494
+ Algebra of differentiable scalar fields on the 3-dimensional
1495
+ differentiable manifold M
1496
+ sage: M.diff_form_module(2).rank()
1497
+ 3
1498
+
1499
+ The outcome is cached::
1500
+
1501
+ sage: M.diff_form_module(2) is M.diff_form_module(2)
1502
+ True
1503
+ """
1504
+ return self.vector_field_module(dest_map=dest_map).dual_exterior_power(degree)
1505
+
1506
+ def mixed_form_algebra(self, dest_map=None):
1507
+ r"""
1508
+ Return the set of mixed forms defined on ``self``, possibly with values
1509
+ in another manifold, as a graded algebra.
1510
+
1511
+ .. SEEALSO::
1512
+
1513
+ :class:`~sage.manifolds.differentiable.mixed_form_algebra.MixedFormAlgebra`
1514
+ for complete documentation.
1515
+
1516
+ INPUT:
1517
+
1518
+ - ``dest_map`` -- (default: ``None``) destination map, i.e. a
1519
+ differentiable map `\Phi:\ M \rightarrow N`, where `M` is the
1520
+ current manifold and `N` a differentiable manifold;
1521
+ if ``None``, it is assumed that `N = M` and that `\Phi` is the
1522
+ identity map (case of mixed forms *on* `M`), otherwise
1523
+ ``dest_map`` must be a
1524
+ :class:`~sage.manifolds.differentiable.diff_map.DiffMap`
1525
+
1526
+ OUTPUT:
1527
+
1528
+ - a
1529
+ :class:`~sage.manifolds.differentiable.mixed_form_algebra.MixedFormAlgebra`
1530
+ representing the graded algebra `\Omega^*(M,\Phi)` of mixed forms on `M`
1531
+ taking values on `\Phi(M)\subset N`
1532
+
1533
+ EXAMPLES:
1534
+
1535
+ Graded algebra of mixed forms on a 2-dimensional manifold::
1536
+
1537
+ sage: M = Manifold(2, 'M')
1538
+ sage: X.<x,y> = M.chart()
1539
+ sage: M.mixed_form_algebra()
1540
+ Graded algebra Omega^*(M) of mixed differential forms on the
1541
+ 2-dimensional differentiable manifold M
1542
+ sage: M.mixed_form_algebra().category()
1543
+ Join of Category of graded algebras over Symbolic Ring and Category of chain complexes over Symbolic Ring
1544
+ sage: M.mixed_form_algebra().base_ring()
1545
+ Symbolic Ring
1546
+
1547
+ The outcome is cached::
1548
+
1549
+ sage: M.mixed_form_algebra() is M.mixed_form_algebra()
1550
+ True
1551
+ """
1552
+ vmodule = self.vector_field_module(dest_map=dest_map)
1553
+ return MixedFormAlgebra(vmodule)
1554
+
1555
+ de_rham_complex = mixed_form_algebra
1556
+
1557
+ def multivector_module(self, degree, dest_map=None):
1558
+ r"""
1559
+ Return the set of multivector fields of a given degree defined
1560
+ on ``self``, possibly with values in another manifold, as a
1561
+ module over the algebra of scalar fields defined on ``self``.
1562
+
1563
+ .. SEEALSO::
1564
+
1565
+ :class:`~sage.manifolds.differentiable.multivector_module.MultivectorModule`
1566
+ for complete documentation.
1567
+
1568
+ INPUT:
1569
+
1570
+ - ``degree`` -- positive integer; the degree `p` of the
1571
+ multivector fields
1572
+ - ``dest_map`` -- (default: ``None``) destination map, i.e. a
1573
+ differentiable map `\Phi:\ M \rightarrow N`, where `M` is the
1574
+ current manifold and `N` a differentiable manifold;
1575
+ if ``None``, it is assumed that `N = M` and that `\Phi` is the
1576
+ identity map (case of multivector fields *on* `M`), otherwise
1577
+ ``dest_map`` must be a
1578
+ :class:`~sage.manifolds.differentiable.diff_map.DiffMap`
1579
+
1580
+ OUTPUT:
1581
+
1582
+ - a
1583
+ :class:`~sage.manifolds.differentiable.multivector_module.MultivectorModule`
1584
+ (or if `N` is parallelizable, a
1585
+ :class:`~sage.manifolds.differentiable.multivector_module.MultivectorFreeModule`)
1586
+ representing the module `\Omega^p(M,\Phi)` of `p`-forms on `M`
1587
+ taking values on `\Phi(M)\subset N`
1588
+
1589
+ EXAMPLES:
1590
+
1591
+ Module of 2-vector fields on a 3-dimensional parallelizable
1592
+ manifold::
1593
+
1594
+ sage: M = Manifold(3, 'M')
1595
+ sage: X.<x,y,z> = M.chart()
1596
+ sage: M.multivector_module(2)
1597
+ Free module A^2(M) of 2-vector fields on the 3-dimensional
1598
+ differentiable manifold M
1599
+ sage: M.multivector_module(2).category()
1600
+ Category of finite dimensional modules over Algebra of
1601
+ differentiable scalar fields on the 3-dimensional
1602
+ differentiable manifold M
1603
+ sage: M.multivector_module(2).base_ring()
1604
+ Algebra of differentiable scalar fields on the 3-dimensional
1605
+ differentiable manifold M
1606
+ sage: M.multivector_module(2).rank()
1607
+ 3
1608
+
1609
+ The outcome is cached::
1610
+
1611
+ sage: M.multivector_module(2) is M.multivector_module(2)
1612
+ True
1613
+ """
1614
+ return self.vector_field_module(dest_map=dest_map).exterior_power(degree)
1615
+
1616
+ def automorphism_field_group(self, dest_map=None):
1617
+ r"""
1618
+ Return the group of tangent-space automorphism fields defined on
1619
+ ``self``, possibly with values in another manifold, as a module
1620
+ over the algebra of scalar fields defined on ``self``.
1621
+
1622
+ If `M` is the current manifold and `\Phi` a differentiable map
1623
+ `\Phi: M \rightarrow N`, where `N` is a differentiable manifold,
1624
+ this method called with ``dest_map`` being `\Phi` returns the
1625
+ general linear group `\mathrm{GL}(\mathfrak{X}(M, \Phi))` of the module
1626
+ `\mathfrak{X}(M, \Phi)` of vector fields along `M` with values in
1627
+ `\Phi(M) \subset N`.
1628
+
1629
+ INPUT:
1630
+
1631
+ - ``dest_map`` -- (default: ``None``) destination map, i.e. a
1632
+ differentiable map `\Phi:\ M \rightarrow N`, where `M` is the
1633
+ current manifold and `N` a differentiable manifold;
1634
+ if ``None``, it is assumed that `N = M` and that `\Phi` is the
1635
+ identity map, otherwise ``dest_map`` must be a
1636
+ :class:`~sage.manifolds.differentiable.diff_map.DiffMap`
1637
+
1638
+ OUTPUT:
1639
+
1640
+ - a
1641
+ :class:`~sage.manifolds.differentiable.automorphismfield_group.AutomorphismFieldParalGroup`
1642
+ (if `N` is parallelizable) or a
1643
+ :class:`~sage.manifolds.differentiable.automorphismfield_group.AutomorphismFieldGroup`
1644
+ (if `N` is not parallelizable) representing
1645
+ `\mathrm{GL}(\mathfrak{X}(U, \Phi))`
1646
+
1647
+ EXAMPLES:
1648
+
1649
+ Group of tangent-space automorphism fields of a 2-dimensional
1650
+ differentiable manifold::
1651
+
1652
+ sage: M = Manifold(2, 'M')
1653
+ sage: M.automorphism_field_group()
1654
+ General linear group of the Module X(M) of vector fields on the
1655
+ 2-dimensional differentiable manifold M
1656
+ sage: M.automorphism_field_group().category()
1657
+ Category of groups
1658
+
1659
+ .. SEEALSO::
1660
+
1661
+ For more examples, see
1662
+ :class:`~sage.manifolds.differentiable.automorphismfield_group.AutomorphismFieldParalGroup`
1663
+ and
1664
+ :class:`~sage.manifolds.differentiable.automorphismfield_group.AutomorphismFieldGroup`.
1665
+ """
1666
+ return self.vector_field_module(dest_map=dest_map).general_linear_group()
1667
+
1668
+ def vector_field(self, *comp, **kwargs):
1669
+ r"""
1670
+ Define a vector field on ``self``.
1671
+
1672
+ Via the argument ``dest_map``, it is possible to let the vector field
1673
+ take its values on another manifold. More precisely, if `M` is
1674
+ the current manifold, `N` a differentiable manifold and
1675
+ `\Phi:\ M \rightarrow N` a differentiable map, a *vector field
1676
+ along* `M` *with values on* `N` is a differentiable map
1677
+
1678
+ .. MATH::
1679
+
1680
+ v:\ M \longrightarrow TN
1681
+
1682
+ (`TN` being the tangent bundle of `N`) such that
1683
+
1684
+ .. MATH::
1685
+
1686
+ \forall p \in M,\ v(p) \in T_{\Phi(p)} N,
1687
+
1688
+ where `T_{\Phi(p)} N` is the tangent space to `N` at the
1689
+ point `\Phi(p)`.
1690
+
1691
+ The standard case of vector fields *on* `M` corresponds
1692
+ to `N = M` and `\Phi = \mathrm{Id}_M`. Other common cases are `\Phi`
1693
+ being an immersion and `\Phi` being a curve in `N` (`M` is then
1694
+ an open interval of `\RR`).
1695
+
1696
+ .. SEEALSO::
1697
+
1698
+ :class:`~sage.manifolds.differentiable.vectorfield.VectorField`
1699
+ and
1700
+ :class:`~sage.manifolds.differentiable.vectorfield.VectorFieldParal`
1701
+ for a complete documentation.
1702
+
1703
+ INPUT:
1704
+
1705
+ - ``comp`` -- (optional) either the components of the vector field
1706
+ with respect to the vector frame specified by the argument ``frame``
1707
+ or a dictionary of components, the keys of which are vector frames or
1708
+ pairs ``(f, c)`` where ``f`` is a vector frame and ``c`` the chart
1709
+ in which the components are expressed
1710
+ - ``frame`` -- (default: ``None``; unused if ``comp`` is not given or
1711
+ is a dictionary) vector frame in which the components are given; if
1712
+ ``None``, the default vector frame of ``self`` is assumed
1713
+ - ``chart`` -- (default: ``None``; unused if ``comp`` is not given or
1714
+ is a dictionary) coordinate chart in which the components are
1715
+ expressed; if ``None``, the default chart on the domain of ``frame``
1716
+ is assumed
1717
+ - ``name`` -- (default: ``None``) name given to the vector field
1718
+ - ``latex_name`` -- (default: ``None``) LaTeX symbol to denote the
1719
+ vector field; if none is provided, the LaTeX symbol is set to
1720
+ ``name``
1721
+ - ``dest_map`` -- (default: ``None``) the destination map
1722
+ `\Phi:\ M \rightarrow N`; if ``None``, it is assumed that `N = M`
1723
+ and that `\Phi` is the identity map (case of a vector field
1724
+ *on* `M`), otherwise ``dest_map`` must be a
1725
+ :class:`~sage.manifolds.differentiable.diff_map.DiffMap`
1726
+
1727
+ OUTPUT:
1728
+
1729
+ - a
1730
+ :class:`~sage.manifolds.differentiable.vectorfield.VectorField`
1731
+ (or if `N` is parallelizable, a
1732
+ :class:`~sage.manifolds.differentiable.vectorfield.VectorFieldParal`)
1733
+ representing the defined vector field
1734
+
1735
+ EXAMPLES:
1736
+
1737
+ A vector field on a open subset of a 3-dimensional differentiable
1738
+ manifold::
1739
+
1740
+ sage: M = Manifold(3, 'M')
1741
+ sage: U = M.open_subset('U')
1742
+ sage: c_xyz.<x,y,z> = U.chart()
1743
+ sage: v = U.vector_field(y, -x*z, 1+y, name='v'); v
1744
+ Vector field v on the Open subset U of the 3-dimensional
1745
+ differentiable manifold M
1746
+ sage: v.display()
1747
+ v = y ∂/∂x - x*z ∂/∂y + (y + 1) ∂/∂z
1748
+
1749
+ The vector fields on `U` form the set `\mathfrak{X}(U)`, which is a
1750
+ module over the algebra `C^k(U)` of differentiable scalar fields
1751
+ on `U`::
1752
+
1753
+ sage: v.parent()
1754
+ Free module X(U) of vector fields on the Open subset U of the
1755
+ 3-dimensional differentiable manifold M
1756
+ sage: v in U.vector_field_module()
1757
+ True
1758
+
1759
+ For more examples, see
1760
+ :class:`~sage.manifolds.differentiable.vectorfield.VectorField` and
1761
+ :class:`~sage.manifolds.differentiable.vectorfield.VectorFieldParal`.
1762
+ """
1763
+ name = kwargs.pop('name', None)
1764
+ latex_name = kwargs.pop('latex_name', None)
1765
+ dest_map = kwargs.pop('dest_map', None)
1766
+ vmodule = self.vector_field_module(dest_map) # the parent
1767
+ resu = vmodule.element_class(vmodule, name=name, latex_name=latex_name)
1768
+ if comp:
1769
+ # Some components are to be initialized
1770
+ resu._init_components(*comp, **kwargs)
1771
+ return resu
1772
+
1773
+ def tensor_field(self, *args, **kwargs):
1774
+ r"""
1775
+ Define a tensor field on ``self``.
1776
+
1777
+ Via the argument ``dest_map``, it is possible to let the tensor field
1778
+ take its values on another manifold. More precisely, if `M` is
1779
+ the current manifold, `N` a differentiable manifold,
1780
+ `\Phi:\ M \rightarrow N` a differentiable map and `(k,l)`
1781
+ a pair of nonnegative integers, a *tensor field of type* `(k,l)`
1782
+ *along* `M` *with values on* `N` is a differentiable map
1783
+
1784
+ .. MATH::
1785
+
1786
+ t:\ M \longrightarrow T^{(k,l)} N
1787
+
1788
+ (`T^{(k,l)}N` being the tensor bundle of type `(k,l)` over `N`)
1789
+ such that
1790
+
1791
+ .. MATH::
1792
+
1793
+ \forall p \in M,\ t(p) \in T^{(k,l)}(T_{\Phi(p)} N),
1794
+
1795
+ where `T^{(k,l)}(T_{\Phi(p)} N)` is the space of tensors of type
1796
+ `(k,l)` on the tangent space `T_{\Phi(p)} N`.
1797
+
1798
+ The standard case of tensor fields *on* `M` corresponds
1799
+ to `N=M` and `\Phi = \mathrm{Id}_M`. Other common cases are `\Phi`
1800
+ being an immersion and `\Phi` being a curve in `N` (`M` is then
1801
+ an open interval of `\RR`).
1802
+
1803
+ .. SEEALSO::
1804
+
1805
+ :class:`~sage.manifolds.differentiable.tensorfield.TensorField`
1806
+ and
1807
+ :class:`~sage.manifolds.differentiable.tensorfield_paral.TensorFieldParal`
1808
+ for a complete documentation.
1809
+
1810
+ INPUT:
1811
+
1812
+ - ``k`` -- the contravariant rank `k`, the tensor type being `(k,l)`
1813
+ - ``l`` -- the covariant rank `l`, the tensor type being `(k,l)`
1814
+ - ``comp`` -- (optional) either the components of the tensor field
1815
+ with respect to the vector frame specified by the argument
1816
+ ``frame`` or a dictionary of components, the keys of which are vector
1817
+ frames or pairs ``(f, c)`` where ``f`` is a vector frame and ``c``
1818
+ the chart in which the components are expressed
1819
+ - ``frame`` -- (default: ``None``; unused if ``comp`` is not given or
1820
+ is a dictionary) vector frame in which the components are given; if
1821
+ ``None``, the default vector frame of ``self`` is assumed
1822
+ - ``chart`` -- (default: ``None``; unused if ``comp`` is not given or
1823
+ is a dictionary) coordinate chart in which the components are
1824
+ expressed; if ``None``, the default chart on the domain of ``frame``
1825
+ is assumed
1826
+ - ``name`` -- (default: ``None``) name given to the tensor field
1827
+ - ``latex_name`` -- (default: ``None``) LaTeX symbol to denote the
1828
+ tensor field; if ``None``, the LaTeX symbol is set to ``name``
1829
+ - ``sym`` -- (default: ``None``) a symmetry or a list of symmetries
1830
+ among the tensor arguments: each symmetry is described by a tuple
1831
+ containing the positions of the involved arguments, with the
1832
+ convention ``position=0`` for the first argument; for instance:
1833
+
1834
+ * ``sym = (0,1)`` for a symmetry between the 1st and 2nd arguments
1835
+ * ``sym = [(0,2), (1,3,4)]`` for a symmetry between the 1st and 3rd
1836
+ arguments and a symmetry between the 2nd, 4th and 5th arguments
1837
+
1838
+ - ``antisym`` -- (default: ``None``) antisymmetry or list of
1839
+ antisymmetries among the arguments, with the same convention as for
1840
+ ``sym``
1841
+ - ``dest_map`` -- (default: ``None``) the destination map
1842
+ `\Phi:\ M \rightarrow N`; if ``None``, it is assumed that `N = M`
1843
+ and that `\Phi` is the identity map (case of a tensor field
1844
+ *on* `M`), otherwise ``dest_map`` must be a
1845
+ :class:`~sage.manifolds.differentiable.diff_map.DiffMap`
1846
+
1847
+ OUTPUT:
1848
+
1849
+ - a :class:`~sage.manifolds.differentiable.tensorfield.TensorField`
1850
+ (or if `N` is parallelizable, a
1851
+ :class:`~sage.manifolds.differentiable.tensorfield_paral.TensorFieldParal`)
1852
+ representing the defined tensor field
1853
+
1854
+ EXAMPLES:
1855
+
1856
+ A tensor field of type `(2,0)` on a 2-dimensional differentiable
1857
+ manifold::
1858
+
1859
+ sage: M = Manifold(2, 'M')
1860
+ sage: X.<x,y> = M.chart()
1861
+ sage: t = M.tensor_field(2, 0, [[1+x, -y], [0, x*y]], name='T'); t
1862
+ Tensor field T of type (2,0) on the 2-dimensional differentiable
1863
+ manifold M
1864
+ sage: t.display()
1865
+ T = (x + 1) ∂/∂x⊗∂/∂x - y ∂/∂x⊗∂/∂y + x*y ∂/∂y⊗∂/∂y
1866
+
1867
+ The type `(2,0)` tensor fields on `M` form the set
1868
+ `\mathcal{T}^{(2,0)}(M)`, which is a module over the algebra `C^k(M)`
1869
+ of differentiable scalar fields on `M`::
1870
+
1871
+ sage: t.parent()
1872
+ Free module T^(2,0)(M) of type-(2,0) tensors fields on the
1873
+ 2-dimensional differentiable manifold M
1874
+ sage: t in M.tensor_field_module((2,0))
1875
+ True
1876
+
1877
+ For more examples, see
1878
+ :class:`~sage.manifolds.differentiable.tensorfield.TensorField` and
1879
+ :class:`~sage.manifolds.differentiable.tensorfield_paral.TensorFieldParal`.
1880
+ """
1881
+ k = args[0]
1882
+ l = args[1]
1883
+ name = kwargs.pop('name', None)
1884
+ latex_name = kwargs.pop('latex_name', None)
1885
+ sym = kwargs.pop('sym', None)
1886
+ antisym = kwargs.pop('antisym', None)
1887
+ dest_map = kwargs.pop('dest_map', None)
1888
+ vmodule = self.vector_field_module(dest_map)
1889
+ resu = vmodule.tensor((k, l), name=name, latex_name=latex_name,
1890
+ sym=sym, antisym=antisym)
1891
+ if len(args) > 2:
1892
+ # Some components are to be initialized
1893
+ resu._init_components(args[2], **kwargs)
1894
+ return resu
1895
+
1896
+ def sym_bilin_form_field(self, *comp, **kwargs):
1897
+ r"""
1898
+ Define a field of symmetric bilinear forms on ``self``.
1899
+
1900
+ Via the argument ``dest_map``, it is possible to let the field
1901
+ take its values on another manifold. More precisely, if `M` is
1902
+ the current manifold, `N` a differentiable manifold and
1903
+ `\Phi:\ M \rightarrow N` a differentiable map, a *field of
1904
+ symmetric bilinear forms along* `M` *with values on* `N` is a
1905
+ differentiable map
1906
+
1907
+ .. MATH::
1908
+
1909
+ t:\ M \longrightarrow T^{(0,2)}N
1910
+
1911
+ (`T^{(0,2)} N` being the tensor bundle of type `(0,2)` over `N`)
1912
+ such that
1913
+
1914
+ .. MATH::
1915
+
1916
+ \forall p \in M,\ t(p) \in S(T_{\Phi(p)} N),
1917
+
1918
+ where `S(T_{\Phi(p)} N)` is the space of symmetric bilinear forms on
1919
+ the tangent space `T_{\Phi(p)} N`.
1920
+
1921
+ The standard case of fields of symmetric bilinear forms *on* `M`
1922
+ corresponds to `N = M` and `\Phi = \mathrm{Id}_M`. Other common
1923
+ cases are `\Phi` being an immersion and `\Phi` being a curve in `N`
1924
+ (`M` is then an open interval of `\RR`).
1925
+
1926
+ INPUT:
1927
+
1928
+ - ``comp`` -- (optional) either the components of the field of
1929
+ symmetric bilinear forms with respect to the vector frame specified
1930
+ by the argument ``frame`` or a dictionary of components, the keys of
1931
+ which are vector frames or pairs ``(f, c)`` where ``f`` is a vector
1932
+ frame and ``c`` the chart in which the components are expressed
1933
+ - ``frame`` -- (default: ``None``; unused if ``comp`` is not given or
1934
+ is a dictionary) vector frame in which the components are given; if
1935
+ ``None``, the default vector frame of ``self`` is assumed
1936
+ - ``chart`` -- (default: ``None``; unused if ``comp`` is not given or
1937
+ is a dictionary) coordinate chart in which the components are
1938
+ expressed; if ``None``, the default chart on the domain of ``frame``
1939
+ is assumed
1940
+ - ``name`` -- (default: ``None``) name given to the field
1941
+ - ``latex_name`` -- (default: ``None``) LaTeX symbol to denote the
1942
+ field; if none is provided, the LaTeX symbol is set to ``name``
1943
+ - ``dest_map`` -- (default: ``None``) the destination map
1944
+ `\Phi:\ M \rightarrow N`; if ``None``, it is assumed that `N = M`
1945
+ and that `\Phi` is the identity map (case of a field *on* `M`),
1946
+ otherwise ``dest_map`` must be an instance of instance of
1947
+ class :class:`~sage.manifolds.differentiable.diff_map.DiffMap`
1948
+
1949
+ OUTPUT:
1950
+
1951
+ - a :class:`~sage.manifolds.differentiable.tensorfield.TensorField`
1952
+ (or if `N` is parallelizable, a
1953
+ :class:`~sage.manifolds.differentiable.tensorfield_paral.TensorFieldParal`)
1954
+ of tensor type `(0,2)` and symmetric representing the defined
1955
+ field of symmetric bilinear forms
1956
+
1957
+ EXAMPLES:
1958
+
1959
+ A field of symmetric bilinear forms on a 2-dimensional manifold::
1960
+
1961
+ sage: M = Manifold(2, 'M')
1962
+ sage: X.<x,y> = M.chart()
1963
+ sage: t = M.sym_bilin_form_field(name='T'); t
1964
+ Field of symmetric bilinear forms T on the 2-dimensional
1965
+ differentiable manifold M
1966
+
1967
+ Such a object is a tensor field of rank 2 and type `(0,2)`::
1968
+
1969
+ sage: t.parent()
1970
+ Free module T^(0,2)(M) of type-(0,2) tensors fields on the
1971
+ 2-dimensional differentiable manifold M
1972
+ sage: t.tensor_rank()
1973
+ 2
1974
+ sage: t.tensor_type()
1975
+ (0, 2)
1976
+
1977
+ The LaTeX symbol is deduced from the name or can be specified when
1978
+ creating the object::
1979
+
1980
+ sage: latex(t)
1981
+ T
1982
+ sage: om = M.sym_bilin_form_field(name='Omega', latex_name=r'\Omega')
1983
+ sage: latex(om)
1984
+ \Omega
1985
+
1986
+ Setting the components in the manifold's default vector frame::
1987
+
1988
+ sage: t[0,0], t[0,1], t[1,1] = -1, x, x*y
1989
+
1990
+ The unset components are either zero or deduced by symmetry::
1991
+
1992
+ sage: t[1, 0]
1993
+ x
1994
+ sage: t[:]
1995
+ [ -1 x]
1996
+ [ x x*y]
1997
+
1998
+ One can also set the components while defining the field of symmetric
1999
+ bilinear forms::
2000
+
2001
+ sage: t = M.sym_bilin_form_field([[-1, x], [x, x*y]], name='T')
2002
+
2003
+ A symmetric bilinear form acts on vector pairs::
2004
+
2005
+ sage: v1 = M.vector_field(y, x, name='V_1')
2006
+ sage: v2 = M.vector_field(x+y, 2, name='V_2')
2007
+ sage: s = t(v1,v2) ; s
2008
+ Scalar field T(V_1,V_2) on the 2-dimensional differentiable
2009
+ manifold M
2010
+ sage: s.expr()
2011
+ x^3 + (3*x^2 + x)*y - y^2
2012
+ sage: s.expr() - t[0,0]*v1[0]*v2[0] - \
2013
+ ....: t[0,1]*(v1[0]*v2[1]+v1[1]*v2[0]) - t[1,1]*v1[1]*v2[1]
2014
+ 0
2015
+ sage: latex(s)
2016
+ T\left(V_1,V_2\right)
2017
+
2018
+ Adding two symmetric bilinear forms results in another symmetric
2019
+ bilinear form::
2020
+
2021
+ sage: a = M.sym_bilin_form_field([[1, 2], [2, 3]])
2022
+ sage: b = M.sym_bilin_form_field([[-1, 4], [4, 5]])
2023
+ sage: s = a + b ; s
2024
+ Field of symmetric bilinear forms on the 2-dimensional
2025
+ differentiable manifold M
2026
+ sage: s[:]
2027
+ [0 6]
2028
+ [6 8]
2029
+
2030
+ But adding a symmetric bilinear from with a non-symmetric bilinear
2031
+ form results in a generic type `(0,2)` tensor::
2032
+
2033
+ sage: c = M.tensor_field(0, 2, [[-2, -3], [1,7]])
2034
+ sage: s1 = a + c ; s1
2035
+ Tensor field of type (0,2) on the 2-dimensional differentiable
2036
+ manifold M
2037
+ sage: s1[:]
2038
+ [-1 -1]
2039
+ [ 3 10]
2040
+ sage: s2 = c + a ; s2
2041
+ Tensor field of type (0,2) on the 2-dimensional differentiable
2042
+ manifold M
2043
+ sage: s2[:]
2044
+ [-1 -1]
2045
+ [ 3 10]
2046
+ """
2047
+ name = kwargs.pop('name', None)
2048
+ latex_name = kwargs.pop('latex_name', None)
2049
+ dest_map = kwargs.pop('dest_map', None)
2050
+ vmodule = self.vector_field_module(dest_map)
2051
+ resu = vmodule.tensor((0, 2), name=name, latex_name=latex_name,
2052
+ sym=(0,1))
2053
+ if comp:
2054
+ # Some components are to be initialized
2055
+ resu._init_components(*comp, **kwargs)
2056
+ return resu
2057
+
2058
+ def multivector_field(self, *args, **kwargs):
2059
+ r"""
2060
+ Define a multivector field on ``self``.
2061
+
2062
+ Via the argument ``dest_map``, it is possible to let the
2063
+ multivector field take its values on another manifold. More
2064
+ precisely, if `M` is the current manifold, `N` a differentiable
2065
+ manifold, `\Phi:\ M \rightarrow N` a differentiable map and `p`
2066
+ a nonnegative integer, a *multivector field of degree* `p` (or
2067
+ `p`-*vector field*) *along* `M` *with values on* `N` is a
2068
+ differentiable map
2069
+
2070
+ .. MATH::
2071
+
2072
+ t:\ M \longrightarrow T^{(p,0)} N
2073
+
2074
+ (`T^{(p,0)} N` being the tensor bundle of type `(p,0)` over `N`)
2075
+ such that
2076
+
2077
+ .. MATH::
2078
+
2079
+ \forall x \in M,\quad t(x) \in \Lambda^p(T_{\Phi(x)} N),
2080
+
2081
+ where `\Lambda^p(T_{\Phi(x)} N)` is the `p`-th exterior power
2082
+ of the tangent vector space `T_{\Phi(x)} N`.
2083
+
2084
+ The standard case of a `p`-vector field *on* `M` corresponds
2085
+ to `N = M` and `\Phi = \mathrm{Id}_M`. Other common cases are
2086
+ `\Phi` being an immersion and `\Phi` being a curve in `N` (`M`
2087
+ is then an open interval of `\RR`).
2088
+
2089
+ For `p = 1`, one can use the method
2090
+ :meth:`~sage.manifolds.differentiable.manifold.DifferentiableManifold.vector_field`
2091
+ instead.
2092
+
2093
+ .. SEEALSO::
2094
+
2095
+ :class:`~sage.manifolds.differentiable.multivectorfield.MultivectorField`
2096
+ and
2097
+ :class:`~sage.manifolds.differentiable.multivectorfield.MultivectorFieldParal`
2098
+ for a complete documentation.
2099
+
2100
+ INPUT:
2101
+
2102
+ - ``degree`` -- the degree `p` of the multivector field (i.e.
2103
+ its tensor rank)
2104
+ - ``comp`` -- (optional) either the components of the multivector field
2105
+ with respect to the vector frame specified by the argument ``frame``
2106
+ or a dictionary of components, the keys of which are vector frames
2107
+ or pairs ``(f, c)`` where ``f`` is a vector frame and ``c`` the chart
2108
+ in which the components are expressed
2109
+ - ``frame`` -- (default: ``None``; unused if ``comp`` is not given or
2110
+ is a dictionary) vector frame in which the components are given; if
2111
+ ``None``, the default vector frame of ``self`` is assumed
2112
+ - ``chart`` -- (default: ``None``; unused if ``comp`` is not given or
2113
+ is a dictionary) coordinate chart in which the components are
2114
+ expressed; if ``None``, the default chart on the domain of ``frame``
2115
+ is assumed
2116
+ - ``name`` -- (default: ``None``) name given to the multivector
2117
+ field
2118
+ - ``latex_name`` -- (default: ``None``) LaTeX symbol to denote
2119
+ the multivector field; if none is provided, the LaTeX symbol
2120
+ is set to ``name``
2121
+ - ``dest_map`` -- (default: ``None``) the destination map
2122
+ `\Phi:\ M \rightarrow N`; if ``None``, it is assumed that
2123
+ `N = M` and that `\Phi` is the identity map (case of a
2124
+ multivector field *on* `M`), otherwise ``dest_map`` must be a
2125
+ :class:`~sage.manifolds.differentiable.diff_map.DiffMap`
2126
+
2127
+ OUTPUT:
2128
+
2129
+ - the `p`-vector field as a
2130
+ :class:`~sage.manifolds.differentiable.multivectorfield.MultivectorField`
2131
+ (or if `N` is parallelizable, a
2132
+ :class:`~sage.manifolds.differentiable.multivectorfield.MultivectorFieldParal`)
2133
+
2134
+ EXAMPLES:
2135
+
2136
+ A 2-vector field on a 3-dimensional differentiable manifold::
2137
+
2138
+ sage: M = Manifold(3, 'M')
2139
+ sage: X.<x,y,z> = M.chart()
2140
+ sage: h = M.multivector_field(2, name='H'); h
2141
+ 2-vector field H on the 3-dimensional differentiable manifold M
2142
+ sage: h[0,1], h[0,2], h[1,2] = x+y, x*z, -3
2143
+ sage: h.display()
2144
+ H = (x + y) ∂/∂x∧∂/∂y + x*z ∂/∂x∧∂/∂z - 3 ∂/∂y∧∂/∂z
2145
+
2146
+ For more examples, see
2147
+ :class:`~sage.manifolds.differentiable.multivectorfield.MultivectorField`
2148
+ and
2149
+ :class:`~sage.manifolds.differentiable.multivectorfield.MultivectorFieldParal`.
2150
+ """
2151
+ degree = args[0]
2152
+ name = kwargs.pop('name', None)
2153
+ latex_name = kwargs.pop('latex_name', None)
2154
+ dest_map = kwargs.pop('dest_map', None)
2155
+ vmodule = self.vector_field_module(dest_map)
2156
+ resu = vmodule.alternating_contravariant_tensor(degree, name=name,
2157
+ latex_name=latex_name)
2158
+ if len(args) > 1:
2159
+ # Some components are to be initialized
2160
+ resu._init_components(args[1], **kwargs)
2161
+ return resu
2162
+
2163
+ def diff_form(self, *args, **kwargs) -> DiffForm:
2164
+ r"""
2165
+ Define a differential form on ``self``.
2166
+
2167
+ Via the argument ``dest_map``, it is possible to let the
2168
+ differential form take its values on another manifold. More
2169
+ precisely, if `M` is the current manifold, `N` a differentiable
2170
+ manifold, `\Phi:\ M \rightarrow N` a differentiable map and `p`
2171
+ a nonnegative integer, a *differential form of degree* `p` (or
2172
+ `p`-*form*) *along* `M` *with values on* `N` is a differentiable
2173
+ map
2174
+
2175
+ .. MATH::
2176
+
2177
+ t:\ M \longrightarrow T^{(0,p)}N
2178
+
2179
+ (`T^{(0,p)} N` being the tensor bundle of type `(0,p)` over `N`)
2180
+ such that
2181
+
2182
+ .. MATH::
2183
+
2184
+ \forall x \in M,\quad t(x) \in \Lambda^p(T^*_{\Phi(x)} N),
2185
+
2186
+ where `\Lambda^p(T^*_{\Phi(x)} N)` is the `p`-th exterior power
2187
+ of the dual of the tangent space `T_{\Phi(x)} N`.
2188
+
2189
+ The standard case of a differential form *on* `M` corresponds
2190
+ to `N = M` and `\Phi = \mathrm{Id}_M`. Other common cases are
2191
+ `\Phi` being an immersion and `\Phi` being a curve in `N` (`M`
2192
+ is then an open interval of `\RR`).
2193
+
2194
+ For `p = 1`, one can use the method
2195
+ :meth:`~sage.manifolds.differentiable.manifold.DifferentiableManifold.one_form`
2196
+ instead.
2197
+
2198
+ .. SEEALSO::
2199
+
2200
+ :class:`~sage.manifolds.differentiable.diff_form.DiffForm` and
2201
+ :class:`~sage.manifolds.differentiable.diff_form.DiffFormParal`
2202
+ for a complete documentation.
2203
+
2204
+ INPUT:
2205
+
2206
+ - ``degree`` -- the degree `p` of the differential form (i.e.
2207
+ its tensor rank)
2208
+ - ``comp`` -- (optional) either the components of the differential
2209
+ form with respect to the vector frame specified by the argument
2210
+ ``frame`` or a dictionary of components, the keys of which are vector
2211
+ frames or pairs ``(f, c)`` where ``f`` is a vector frame and ``c``
2212
+ the chart in which the components are expressed
2213
+ - ``frame`` -- (default: ``None``; unused if ``comp`` is not given or
2214
+ is a dictionary) vector frame in which the components are given; if
2215
+ ``None``, the default vector frame of ``self`` is assumed
2216
+ - ``chart`` -- (default: ``None``; unused if ``comp`` is not given or
2217
+ is a dictionary) coordinate chart in which the components are
2218
+ expressed; if ``None``, the default chart on the domain of ``frame``
2219
+ is assumed
2220
+ - ``name`` -- (default: ``None``) name given to the differential
2221
+ form
2222
+ - ``latex_name`` -- (default: ``None``) LaTeX symbol to denote
2223
+ the differential form; if none is provided, the LaTeX symbol
2224
+ is set to ``name``
2225
+ - ``dest_map`` -- (default: ``None``) the destination map
2226
+ `\Phi:\ M \rightarrow N`; if ``None``, it is assumed that
2227
+ `N = M` and that `\Phi` is the identity map (case of a
2228
+ differential form *on* `M`), otherwise ``dest_map`` must be a
2229
+ :class:`~sage.manifolds.differentiable.diff_map.DiffMap`
2230
+
2231
+ OUTPUT:
2232
+
2233
+ - the `p`-form as a
2234
+ :class:`~sage.manifolds.differentiable.diff_form.DiffForm`
2235
+ (or if `N` is parallelizable, a
2236
+ :class:`~sage.manifolds.differentiable.diff_form.DiffFormParal`)
2237
+
2238
+ EXAMPLES:
2239
+
2240
+ A 2-form on a 3-dimensional differentiable manifold::
2241
+
2242
+ sage: M = Manifold(3, 'M')
2243
+ sage: X.<x,y,z> = M.chart()
2244
+ sage: f = M.diff_form(2, name='F'); f
2245
+ 2-form F on the 3-dimensional differentiable manifold M
2246
+ sage: f[0,1], f[1,2] = x+y, x*z
2247
+ sage: f.display()
2248
+ F = (x + y) dx∧dy + x*z dy∧dz
2249
+
2250
+ For more examples, see
2251
+ :class:`~sage.manifolds.differentiable.diff_form.DiffForm` and
2252
+ :class:`~sage.manifolds.differentiable.diff_form.DiffFormParal`.
2253
+ """
2254
+ degree = args[0]
2255
+ name = kwargs.pop('name', None)
2256
+ latex_name = kwargs.pop('latex_name', None)
2257
+ dest_map = kwargs.pop('dest_map', None)
2258
+ vmodule = self.vector_field_module(dest_map)
2259
+ resu = vmodule.alternating_form(degree, name=name,
2260
+ latex_name=latex_name)
2261
+ if len(args) > 1:
2262
+ # Some components are to be initialized
2263
+ resu._init_components(args[1], **kwargs)
2264
+ return resu
2265
+
2266
+ def one_form(self, *comp, **kwargs) -> DiffForm:
2267
+ r"""
2268
+ Define a 1-form on the manifold.
2269
+
2270
+ Via the argument ``dest_map``, it is possible to let the
2271
+ 1-form take its values on another manifold. More precisely,
2272
+ if `M` is the current manifold, `N` a differentiable
2273
+ manifold and `\Phi:\ M \rightarrow N` a differentiable map,
2274
+ a *1-form along* `M` *with values on* `N` is a differentiable
2275
+ map
2276
+
2277
+ .. MATH::
2278
+
2279
+ t:\ M \longrightarrow T^* N
2280
+
2281
+ (`T^* N` being the cotangent bundle of `N`) such that
2282
+
2283
+ .. MATH::
2284
+
2285
+ \forall p \in M,\quad t(p) \in T^*_{\Phi(p)}N,
2286
+
2287
+ where `T^*_{\Phi(p)}` is the dual of the tangent space
2288
+ `T_{\Phi(p)} N`.
2289
+
2290
+ The standard case of a 1-form *on* `M` corresponds to `N = M`
2291
+ and `\Phi = \mathrm{Id}_M`. Other common cases are `\Phi`
2292
+ being an immersion and `\Phi` being a curve in `N` (`M` is then
2293
+ an open interval of `\RR`).
2294
+
2295
+ .. SEEALSO::
2296
+
2297
+ :class:`~sage.manifolds.differentiable.diff_form.DiffForm` and
2298
+ :class:`~sage.manifolds.differentiable.diff_form.DiffFormParal`
2299
+ for a complete documentation.
2300
+
2301
+ INPUT:
2302
+
2303
+ - ``comp`` -- (optional) either the components of 1-form with respect
2304
+ to the vector frame specified by the argument ``frame`` or a
2305
+ dictionary of components, the keys of which are vector frames or
2306
+ pairs ``(f, c)`` where ``f`` is a vector frame and ``c`` the chart
2307
+ in which the components are expressed
2308
+ - ``frame`` -- (default: ``None``; unused if ``comp`` is not given or
2309
+ is a dictionary) vector frame in which the components are given; if
2310
+ ``None``, the default vector frame of ``self`` is assumed
2311
+ - ``chart`` -- (default: ``None``; unused if ``comp`` is not given or
2312
+ is a dictionary) coordinate chart in which the components are
2313
+ expressed; if ``None``, the default chart on the domain of ``frame``
2314
+ is assumed
2315
+ - ``name`` -- (default: ``None``) name given to the 1-form
2316
+ - ``latex_name`` -- (default: ``None``) LaTeX symbol to denote
2317
+ the 1-form; if none is provided, the LaTeX symbol is set to
2318
+ ``name``
2319
+ - ``dest_map`` -- (default: ``None``) the destination map
2320
+ `\Phi:\ M \rightarrow N`; if ``None``, it is assumed that
2321
+ `N = M` and that `\Phi` is the identity map (case of a 1-form
2322
+ *on* `M`), otherwise ``dest_map`` must be a
2323
+ :class:`~sage.manifolds.differentiable.diff_map.DiffMap`
2324
+
2325
+ OUTPUT:
2326
+
2327
+ - the 1-form as a
2328
+ :class:`~sage.manifolds.differentiable.diff_form.DiffForm`
2329
+ (or if `N` is parallelizable, a
2330
+ :class:`~sage.manifolds.differentiable.diff_form.DiffFormParal`)
2331
+
2332
+ EXAMPLES:
2333
+
2334
+ A 1-form on a 2-dimensional manifold::
2335
+
2336
+ sage: M = Manifold(2, 'M')
2337
+ sage: X.<x,y> = M.chart()
2338
+ sage: om = M.one_form(-y, 2+x, name='omega', latex_name=r'\omega')
2339
+ sage: om
2340
+ 1-form omega on the 2-dimensional differentiable manifold M
2341
+ sage: om.display()
2342
+ omega = -y dx + (x + 2) dy
2343
+ sage: om.parent()
2344
+ Free module Omega^1(M) of 1-forms on the 2-dimensional
2345
+ differentiable manifold M
2346
+
2347
+ For more examples, see
2348
+ :class:`~sage.manifolds.differentiable.diff_form.DiffForm` and
2349
+ :class:`~sage.manifolds.differentiable.diff_form.DiffFormParal`.
2350
+ """
2351
+ name = kwargs.pop('name', None)
2352
+ latex_name = kwargs.pop('latex_name', None)
2353
+ dest_map = kwargs.pop('dest_map', None)
2354
+ vmodule = self.vector_field_module(dest_map)
2355
+ resu = vmodule.linear_form(name=name, latex_name=latex_name)
2356
+ if comp:
2357
+ # Some components are to be initialized
2358
+ resu._init_components(*comp, **kwargs)
2359
+ return resu
2360
+
2361
+ def mixed_form(self, comp=None, name=None, latex_name=None, dest_map=None):
2362
+ r"""
2363
+ Define a mixed form on ``self``.
2364
+
2365
+ Via the argument ``dest_map``, it is possible to let the
2366
+ mixed form take its values on another manifold. More
2367
+ precisely, if `M` is the current manifold, `N` a differentiable
2368
+ manifold, `\Phi:\ M \rightarrow N` a differentiable map, a
2369
+ *mixed form along* `\Phi` can be considered as a differentiable map
2370
+
2371
+ .. MATH::
2372
+
2373
+ a: M \longrightarrow \bigoplus^n_{k=0} T^{(0,k)}N
2374
+
2375
+ (`T^{(0,k)} N` being the tensor bundle of type `(0,k)` over `N`, `\oplus`
2376
+ being the Whitney sum and `n` being the dimension of `N`) such that
2377
+
2378
+ .. MATH::
2379
+
2380
+ \forall x \in M,\quad a(x) \in \bigoplus^n_{k=0} \Lambda^k(T^*_{\Phi(x)} N),
2381
+
2382
+ where `\Lambda^k(T^*_{\Phi(x)} N)` is the `k`-th exterior power
2383
+ of the dual of the tangent space `T_{\Phi(x)} N`.
2384
+
2385
+ The standard case of a mixed form *on* `M` corresponds
2386
+ to `N = M` and `\Phi = \mathrm{Id}_M`.
2387
+
2388
+ .. SEEALSO::
2389
+
2390
+ :class:`~sage.manifolds.differentiable.mixed_form.MixedForm`
2391
+ for complete documentation.
2392
+
2393
+ INPUT:
2394
+
2395
+ - ``comp`` -- (default: ``None``) homogeneous components of the mixed
2396
+ form as a list; if none is provided, the components are set to
2397
+ innocent unnamed differential forms
2398
+ - ``name`` -- (default: ``None``) name given to the differential form
2399
+ - ``latex_name`` -- (default: ``None``) LaTeX symbol to denote
2400
+ the differential form; if none is provided, the LaTeX symbol
2401
+ is set to ``name``
2402
+ - ``dest_map`` -- (default: ``None``) the destination map
2403
+ `\Phi:\ M \rightarrow N`; if ``None``, it is assumed that
2404
+ `N = M` and that `\Phi` is the identity map (case of a
2405
+ differential form *on* `M`), otherwise ``dest_map`` must be a
2406
+ :class:`~sage.manifolds.differentiable.diff_map.DiffMap`
2407
+
2408
+ OUTPUT:
2409
+
2410
+ - the mixed form as a
2411
+ :class:`~sage.manifolds.differentiable.mixed_form.MixedForm`
2412
+
2413
+ EXAMPLES:
2414
+
2415
+ A mixed form on an open subset of a 3-dimensional differentiable
2416
+ manifold::
2417
+
2418
+ sage: M = Manifold(3, 'M')
2419
+ sage: U = M.open_subset('U', latex_name=r'\mathcal{U}'); U
2420
+ Open subset U of the 3-dimensional differentiable manifold M
2421
+ sage: c_xyz.<x,y,z> = U.chart()
2422
+ sage: f = U.mixed_form(name='F'); f
2423
+ Mixed differential form F on the Open subset U of the 3-dimensional
2424
+ differentiable manifold M
2425
+
2426
+ See the documentation of class
2427
+ :class:`~sage.manifolds.differentiable.mixed_form.MixedForm` for
2428
+ more examples.
2429
+ """
2430
+ algebra = self.mixed_form_algebra(dest_map=dest_map)
2431
+ resu = algebra.element_class(algebra, name=name, latex_name=latex_name)
2432
+ if comp is not None:
2433
+ resu[:] = comp
2434
+ return resu
2435
+
2436
+ def symplectic_form(
2437
+ self, name: Optional[str] = None, latex_name: Optional[str] = None
2438
+ ):
2439
+ r"""
2440
+ Construct a symplectic form on the current manifold.
2441
+
2442
+ OUTPUT:
2443
+
2444
+ - instance of
2445
+ :class:`~sage.manifolds.differentiable.symplectic_form.SymplecticForm`
2446
+
2447
+ EXAMPLES:
2448
+
2449
+ Standard symplectic form on `\RR^2`::
2450
+
2451
+ sage: M.<q, p> = EuclideanSpace(2)
2452
+ sage: omega = M.symplectic_form('omega', r'\omega')
2453
+ sage: omega.set_comp()[1,2] = -1
2454
+ sage: omega.display()
2455
+ omega = -dq∧dp
2456
+ """
2457
+ return self.vector_field_module().symplectic_form(name, latex_name)
2458
+
2459
+ def poisson_tensor(
2460
+ self, name: Optional[str] = None, latex_name: Optional[str] = None
2461
+ ):
2462
+ r"""
2463
+ Construct a Poisson tensor on the current manifold.
2464
+
2465
+ OUTPUT:
2466
+
2467
+ - instance of
2468
+ :class:`~sage.manifolds.differentiable.poisson_tensor.PoissonTensorField`
2469
+
2470
+ EXAMPLES:
2471
+
2472
+ Standard Poisson tensor on `\RR^2`::
2473
+
2474
+ sage: M.<q, p> = EuclideanSpace(2)
2475
+ sage: poisson = M.poisson_tensor('varpi')
2476
+ sage: poisson.set_comp()[1,2] = -1
2477
+ sage: poisson.display()
2478
+ varpi = -e_q∧e_p
2479
+ """
2480
+ return self.vector_field_module().poisson_tensor(name, latex_name)
2481
+
2482
+ def automorphism_field(self, *comp, **kwargs):
2483
+ r"""
2484
+ Define a field of automorphisms (invertible endomorphisms in each
2485
+ tangent space) on ``self``.
2486
+
2487
+ Via the argument ``dest_map``, it is possible to let the
2488
+ field take its values on another manifold. More precisely,
2489
+ if `M` is the current manifold, `N` a differentiable
2490
+ manifold and `\Phi:\ M \rightarrow N` a differentiable map,
2491
+ a *field of automorphisms along* `M` *with values on* `N` is a
2492
+ differentiable map
2493
+
2494
+ .. MATH::
2495
+
2496
+ t:\ M \longrightarrow T^{(1,1)} N
2497
+
2498
+ (`T^{(1,1)} N` being the tensor bundle of type `(1,1)` over `N`)
2499
+ such that
2500
+
2501
+ .. MATH::
2502
+
2503
+ \forall p \in M,\ t(p) \in \mathrm{GL}\left(T_{\Phi(p)} N \right),
2504
+
2505
+ where `\mathrm{GL}\left(T_{\Phi(p)} N \right)` is the general linear
2506
+ group of the tangent space `T_{\Phi(p)} N`.
2507
+
2508
+ The standard case of a field of automorphisms *on* `M` corresponds
2509
+ to `N = M` and `\Phi = \mathrm{Id}_M`. Other common cases are `\Phi`
2510
+ being an immersion and `\Phi` being a curve in `N` (`M` is then
2511
+ an open interval of `\RR`).
2512
+
2513
+ .. SEEALSO::
2514
+
2515
+ :class:`~sage.manifolds.differentiable.automorphismfield.AutomorphismField`
2516
+ and
2517
+ :class:`~sage.manifolds.differentiable.automorphismfield.AutomorphismFieldParal`
2518
+ for a complete documentation.
2519
+
2520
+ INPUT:
2521
+
2522
+ - ``comp`` -- (optional) either the components of the field of
2523
+ automorphisms with respect to the vector frame specified by the
2524
+ argument ``frame`` or a dictionary of components, the keys of which
2525
+ are vector frames or pairs ``(f, c)`` where ``f`` is a vector frame
2526
+ and ``c`` the chart in which the components are expressed
2527
+ - ``frame`` -- (default: ``None``; unused if ``comp`` is not given or
2528
+ is a dictionary) vector frame in which the components are given; if
2529
+ ``None``, the default vector frame of ``self`` is assumed
2530
+ - ``chart`` -- (default: ``None``; unused if ``comp`` is not given or
2531
+ is a dictionary) coordinate chart in which the components are
2532
+ expressed; if ``None``, the default chart on the domain of ``frame``
2533
+ is assumed
2534
+ - ``name`` -- (default: ``None``) name given to the field
2535
+ - ``latex_name`` -- (default: ``None``) LaTeX symbol to denote the
2536
+ field; if none is provided, the LaTeX symbol is set to ``name``
2537
+ - ``dest_map`` -- (default: ``None``) the destination map
2538
+ `\Phi:\ M \rightarrow N`; if ``None``, it is assumed that `N = M`
2539
+ and that `\Phi` is the identity map (case of a field of
2540
+ automorphisms *on* `M`), otherwise ``dest_map`` must be a
2541
+ :class:`~sage.manifolds.differentiable.diff_map.DiffMap`
2542
+
2543
+ OUTPUT:
2544
+
2545
+ - a
2546
+ :class:`~sage.manifolds.differentiable.automorphismfield.AutomorphismField`
2547
+ (or if `N` is parallelizable, a
2548
+ :class:`~sage.manifolds.differentiable.automorphismfield.AutomorphismFieldParal`)
2549
+ representing the defined field of automorphisms
2550
+
2551
+ EXAMPLES:
2552
+
2553
+ A field of automorphisms on a 2-dimensional manifold::
2554
+
2555
+ sage: M = Manifold(2,'M')
2556
+ sage: X.<x,y> = M.chart()
2557
+ sage: a = M.automorphism_field([[1+x^2, 0], [0, 1+y^2]], name='A')
2558
+ sage: a
2559
+ Field of tangent-space automorphisms A on the 2-dimensional
2560
+ differentiable manifold M
2561
+ sage: a.parent()
2562
+ General linear group of the Free module X(M) of vector fields on
2563
+ the 2-dimensional differentiable manifold M
2564
+ sage: a(X.frame()[0]).display()
2565
+ A(∂/∂x) = (x^2 + 1) ∂/∂x
2566
+ sage: a(X.frame()[1]).display()
2567
+ A(∂/∂y) = (y^2 + 1) ∂/∂y
2568
+
2569
+ For more examples, see
2570
+ :class:`~sage.manifolds.differentiable.automorphismfield.AutomorphismField`
2571
+ and
2572
+ :class:`~sage.manifolds.differentiable.automorphismfield.AutomorphismFieldParal`.
2573
+ """
2574
+ name = kwargs.pop('name', None)
2575
+ latex_name = kwargs.pop('latex_name', None)
2576
+ dest_map = kwargs.pop('dest_map', None)
2577
+ vmodule = self.vector_field_module(dest_map)
2578
+ resu = vmodule.automorphism(name=name, latex_name=latex_name)
2579
+ if comp:
2580
+ # Some components are to be initialized
2581
+ resu._init_components(*comp, **kwargs)
2582
+ return resu
2583
+
2584
+ def tangent_identity_field(self, dest_map=None):
2585
+ r"""
2586
+ Return the field of identity maps in the tangent spaces on ``self``.
2587
+
2588
+ Via the argument ``dest_map``, it is possible to let the
2589
+ field take its values on another manifold. More precisely,
2590
+ if `M` is the current manifold, `N` a differentiable
2591
+ manifold and `\Phi:\ M \rightarrow N` a differentiable map,
2592
+ a *field of identity maps along* `M` *with values on* `N` is a
2593
+ differentiable map
2594
+
2595
+ .. MATH::
2596
+
2597
+ t:\ M \longrightarrow T^{(1,1)} N
2598
+
2599
+ (`T^{(1,1)} N` being the tensor bundle of type `(1,1)` over `N`) such
2600
+ that
2601
+
2602
+ .. MATH::
2603
+
2604
+ \forall p \in M,\ t(p) = \mathrm{Id}_{T_{\Phi(p)} N},
2605
+
2606
+ where `\mathrm{Id}_{T_{\Phi(p)} N}` is the identity map of the
2607
+ tangent space `T_{\Phi(p)} N`.
2608
+
2609
+ The standard case of a field of identity maps *on* `M` corresponds
2610
+ to `N = M` and `\Phi = \mathrm{Id}_M`. Other common cases are `\Phi`
2611
+ being an immersion and `\Phi` being a curve in `N` (`M` is then
2612
+ an open interval of `\RR`).
2613
+
2614
+ INPUT:
2615
+
2616
+ - ``name`` -- (string; default: 'Id') name given to the field of
2617
+ identity maps
2618
+ - ``latex_name`` -- (string; default: ``None``) LaTeX symbol to denote
2619
+ the field of identity map; if none is provided, the LaTeX symbol is
2620
+ set to '\mathrm{Id}' if ``name`` is 'Id' and to ``name`` otherwise
2621
+ - ``dest_map`` -- (default: ``None``) the destination map
2622
+ `\Phi:\ M \rightarrow N`; if ``None``, it is assumed that `N = M`
2623
+ and that `\Phi` is the identity map (case of a field of identity
2624
+ maps *on* `M`), otherwise ``dest_map`` must be a
2625
+ :class:`~sage.manifolds.differentiable.diff_map.DiffMap`
2626
+
2627
+ OUTPUT:
2628
+
2629
+ - a
2630
+ :class:`~sage.manifolds.differentiable.automorphismfield.AutomorphismField`
2631
+ (or if `N` is parallelizable, a
2632
+ :class:`~sage.manifolds.differentiable.automorphismfield.AutomorphismFieldParal`)
2633
+ representing the field of identity maps
2634
+
2635
+ EXAMPLES:
2636
+
2637
+ Field of tangent-space identity maps on a 3-dimensional manifold::
2638
+
2639
+ sage: M = Manifold(3, 'M', start_index=1)
2640
+ sage: c_xyz.<x,y,z> = M.chart()
2641
+ sage: a = M.tangent_identity_field(); a
2642
+ Field of tangent-space identity maps on the 3-dimensional
2643
+ differentiable manifold M
2644
+ sage: a.comp()
2645
+ Kronecker delta of size 3x3
2646
+
2647
+ For more examples, see
2648
+ :class:`~sage.manifolds.differentiable.automorphismfield.AutomorphismField`.
2649
+ """
2650
+ vmodule = self.vector_field_module(dest_map)
2651
+ return vmodule.identity_map()
2652
+
2653
+ def set_orientation(self, orientation):
2654
+ r"""
2655
+ Set the preferred orientation of ``self``.
2656
+
2657
+ INPUT:
2658
+
2659
+ - ``orientation`` -- either a chart / list of charts, or a vector
2660
+ frame / list of vector frames, covering ``self``
2661
+
2662
+ .. WARNING::
2663
+
2664
+ It is the user's responsibility that the orientation set here
2665
+ is indeed an orientation. There is no check going on in the
2666
+ background. See :meth:`orientation` for the definition of an
2667
+ orientation.
2668
+
2669
+ EXAMPLES:
2670
+
2671
+ Set an orientation on a manifold::
2672
+
2673
+ sage: M = Manifold(2, 'M')
2674
+ sage: c_xy.<x,y> = M.chart(); c_uv.<u,v> = M.chart()
2675
+ sage: M.set_orientation(c_uv)
2676
+ sage: M.orientation()
2677
+ [Coordinate frame (M, (∂/∂u,∂/∂v))]
2678
+
2679
+ Instead of a chart, a vector frame can be given, too::
2680
+
2681
+ sage: M.set_orientation(c_xy.frame())
2682
+ sage: M.orientation()
2683
+ [Coordinate frame (M, (∂/∂x,∂/∂y))]
2684
+
2685
+ Set an orientation in the non-trivial case::
2686
+
2687
+ sage: M = Manifold(2, 'M')
2688
+ sage: U = M.open_subset('U'); V = M.open_subset('V')
2689
+ sage: M.declare_union(U, V)
2690
+ sage: c_xy.<x,y> = U.chart(); c_uv.<u,v> = V.chart()
2691
+ sage: M.set_orientation([c_xy, c_uv])
2692
+ sage: M.orientation()
2693
+ [Coordinate frame (U, (∂/∂x,∂/∂y)),
2694
+ Coordinate frame (V, (∂/∂u,∂/∂v))]
2695
+
2696
+ Again, the vector frame notion can be used instead::
2697
+
2698
+ sage: M.set_orientation([c_xy.frame(), c_uv.frame()])
2699
+ sage: M.orientation()
2700
+ [Coordinate frame (U, (∂/∂x,∂/∂y)),
2701
+ Coordinate frame (V, (∂/∂u,∂/∂v))]
2702
+ """
2703
+ from sage.manifolds.differentiable.vectorframe import VectorFrame
2704
+ chart_type = self._structure.chart
2705
+ if isinstance(orientation, chart_type):
2706
+ orientation = [orientation.frame()]
2707
+ elif isinstance(orientation, VectorFrame):
2708
+ orientation = [orientation]
2709
+ elif isinstance(orientation, (list, tuple)):
2710
+ if isinstance(orientation[0], chart_type):
2711
+ orientation = [c.frame() for c in orientation]
2712
+ else:
2713
+ orientation = list(orientation)
2714
+ else:
2715
+ raise TypeError("orientation must be a chart/frame or a "
2716
+ "list/tuple of charts/frames")
2717
+ dom_union = None
2718
+ for frame in orientation:
2719
+ if not isinstance(frame, VectorFrame):
2720
+ raise ValueError("orientation must consist of vector frames")
2721
+ dom = frame._domain
2722
+ if not dom.is_subset(self):
2723
+ raise ValueError("{} must be defined ".format(frame) +
2724
+ "on a subset of {}".format(self))
2725
+ if dom_union is not None:
2726
+ dom_union = dom.union(dom_union)
2727
+ else:
2728
+ dom_union = dom
2729
+ if dom_union != self:
2730
+ raise ValueError("frame domains must cover {}".format(self))
2731
+ self._orientation = orientation
2732
+
2733
+ def orientation(self):
2734
+ r"""
2735
+ Get the preferred orientation of ``self`` if available.
2736
+
2737
+ An *orientation* on a differentiable manifold is an atlas of charts
2738
+ whose transition maps are pairwise orientation preserving, i.e. whose
2739
+ Jacobian determinants are pairwise positive.
2740
+
2741
+ A differentiable manifold with an orientation is called *orientable*.
2742
+
2743
+ A differentiable manifold is orientable if and only if the tangent
2744
+ bundle is orientable in terms of a vector bundle,
2745
+ see :meth:`~sage.manifolds.vector_bundle.TopologicalVectorBundle.orientation`.
2746
+
2747
+ .. NOTE::
2748
+
2749
+ In contrast to topological manifolds,
2750
+ see :meth:`~sage.manifolds.manifold.TopologicalManifold.orientation`,
2751
+ differentiable manifolds preferably use the notion of
2752
+ orientability in terms of the tangent bundle.
2753
+
2754
+ The trivial case corresponds to the manifold being parallelizable,
2755
+ i.e. admitting a frame covering the whole manifold. In that case,
2756
+ if no preferred orientation has been manually set before, one of those
2757
+ frames (usually the default frame) is set to the preferred
2758
+ orientation on ``self`` and returned here.
2759
+
2760
+ EXAMPLES:
2761
+
2762
+ In case one frame already covers the manifold, an orientation
2763
+ is readily obtained::
2764
+
2765
+ sage: M = Manifold(3, 'M')
2766
+ sage: c.<x,y,z> = M.chart()
2767
+ sage: M.orientation()
2768
+ [Coordinate frame (M, (∂/∂x,∂/∂y,∂/∂z))]
2769
+
2770
+ However, orientations are usually not easy to obtain::
2771
+
2772
+ sage: M = Manifold(2, 'M')
2773
+ sage: U = M.open_subset('U'); V = M.open_subset('V')
2774
+ sage: M.declare_union(U, V)
2775
+ sage: c_xy.<x,y> = U.chart(); c_uv.<u,v> = V.chart()
2776
+ sage: M.orientation()
2777
+ []
2778
+
2779
+ In that case, the orientation can be set by the user; either in
2780
+ terms of charts or in terms of frames::
2781
+
2782
+ sage: M.set_orientation([c_xy, c_uv])
2783
+ sage: M.orientation()
2784
+ [Coordinate frame (U, (∂/∂x,∂/∂y)),
2785
+ Coordinate frame (V, (∂/∂u,∂/∂v))]
2786
+ sage: M.set_orientation([c_xy.frame(), c_uv.frame()])
2787
+ sage: M.orientation()
2788
+ [Coordinate frame (U, (∂/∂x,∂/∂y)),
2789
+ Coordinate frame (V, (∂/∂u,∂/∂v))]
2790
+
2791
+ The orientation on submanifolds are inherited from the ambient
2792
+ manifold::
2793
+
2794
+ sage: W = U.intersection(V, name='W')
2795
+ sage: W.orientation()
2796
+ [Vector frame (W, (∂/∂x,∂/∂y))]
2797
+ """
2798
+ if not self._orientation:
2799
+ # try to get an orientation from super domains:
2800
+ for sdom in self.open_supersets():
2801
+ sorient = sdom._orientation
2802
+ if sorient:
2803
+ rst_orient = [f.restrict(self) for f in sorient]
2804
+ # clear multiple domains:
2805
+ rst_orient = list(self._get_min_covering(rst_orient))
2806
+ self._orientation = rst_orient
2807
+ break
2808
+ else:
2809
+ # Trivial case:
2810
+ if self.is_manifestly_parallelizable():
2811
+ # Try the default frame:
2812
+ def_frame = self._def_frame
2813
+ if def_frame is not None:
2814
+ if def_frame._domain is self:
2815
+ self._orientation = [def_frame]
2816
+ # Still no orientation? Choose arbitrary frame:
2817
+ if not self._orientation:
2818
+ for frame in self._covering_frames:
2819
+ dest_map = frame.destination_map()
2820
+ if dest_map.is_identity():
2821
+ self._orientation = [frame]
2822
+ break
2823
+ return list(self._orientation)
2824
+
2825
+ def default_frame(self):
2826
+ r"""
2827
+ Return the default vector frame defined on ``self``.
2828
+
2829
+ By *vector frame*, it is meant a field on the manifold that provides,
2830
+ at each point `p`, a vector basis of the tangent space at `p`.
2831
+
2832
+ Unless changed via :meth:`set_default_frame`, the default frame is
2833
+ the first one defined on the manifold, usually implicitly as the
2834
+ coordinate basis associated with the first chart defined on the
2835
+ manifold.
2836
+
2837
+ OUTPUT:
2838
+
2839
+ - a :class:`~sage.manifolds.differentiable.vectorframe.VectorFrame`
2840
+ representing the default vector frame
2841
+
2842
+ EXAMPLES:
2843
+
2844
+ The default vector frame is often the coordinate frame associated
2845
+ with the first chart defined on the manifold::
2846
+
2847
+ sage: M = Manifold(2, 'M')
2848
+ sage: c_xy.<x,y> = M.chart()
2849
+ sage: M.default_frame()
2850
+ Coordinate frame (M, (∂/∂x,∂/∂y))
2851
+ """
2852
+ return self._def_frame
2853
+
2854
+ def set_default_frame(self, frame):
2855
+ r"""
2856
+ Changing the default vector frame on ``self``.
2857
+
2858
+ INPUT:
2859
+
2860
+ - ``frame`` --
2861
+ :class:`~sage.manifolds.differentiable.vectorframe.VectorFrame`
2862
+ a vector frame defined on some subset of ``self``
2863
+
2864
+ EXAMPLES:
2865
+
2866
+ Changing the default frame on a 2-dimensional manifold::
2867
+
2868
+ sage: M = Manifold(2, 'M')
2869
+ sage: c_xy.<x,y> = M.chart()
2870
+ sage: e = M.vector_frame('e')
2871
+ sage: M.default_frame()
2872
+ Coordinate frame (M, (∂/∂x,∂/∂y))
2873
+ sage: M.set_default_frame(e)
2874
+ sage: M.default_frame()
2875
+ Vector frame (M, (e_0,e_1))
2876
+ """
2877
+ from sage.manifolds.differentiable.vectorframe import VectorFrame
2878
+ if not isinstance(frame, VectorFrame):
2879
+ raise TypeError("{} is not a vector frame".format(frame))
2880
+ if not frame._domain.is_subset(self):
2881
+ raise ValueError("the frame must be defined on the {}".format(self))
2882
+ self._def_frame = frame
2883
+ frame._fmodule.set_default_basis(frame)
2884
+
2885
+ def change_of_frame(self, frame1, frame2):
2886
+ r"""
2887
+ Return a change of vector frames defined on ``self``.
2888
+
2889
+ INPUT:
2890
+
2891
+ - ``frame1`` -- vector frame 1
2892
+ - ``frame2`` -- vector frame 2
2893
+
2894
+ OUTPUT:
2895
+
2896
+ - a
2897
+ :class:`~sage.manifolds.differentiable.automorphismfield.AutomorphismField`
2898
+ representing, at each point, the vector space automorphism `P`
2899
+ that relates frame 1, `(e_i)` say, to frame 2, `(n_i)` say,
2900
+ according to `n_i = P(e_i)`
2901
+
2902
+ EXAMPLES:
2903
+
2904
+ Change of vector frames induced by a change of coordinates::
2905
+
2906
+ sage: M = Manifold(2, 'M')
2907
+ sage: c_xy.<x,y> = M.chart()
2908
+ sage: c_uv.<u,v> = M.chart()
2909
+ sage: c_xy.transition_map(c_uv, (x+y, x-y))
2910
+ Change of coordinates from Chart (M, (x, y)) to Chart (M, (u, v))
2911
+ sage: M.change_of_frame(c_xy.frame(), c_uv.frame())
2912
+ Field of tangent-space automorphisms on the 2-dimensional
2913
+ differentiable manifold M
2914
+ sage: M.change_of_frame(c_xy.frame(), c_uv.frame())[:]
2915
+ [ 1/2 1/2]
2916
+ [ 1/2 -1/2]
2917
+ sage: M.change_of_frame(c_uv.frame(), c_xy.frame())
2918
+ Field of tangent-space automorphisms on the 2-dimensional
2919
+ differentiable manifold M
2920
+ sage: M.change_of_frame(c_uv.frame(), c_xy.frame())[:]
2921
+ [ 1 1]
2922
+ [ 1 -1]
2923
+ sage: M.change_of_frame(c_uv.frame(), c_xy.frame()) == \
2924
+ ....: M.change_of_frame(c_xy.frame(), c_uv.frame()).inverse()
2925
+ True
2926
+
2927
+ In the present example, the manifold `M` is parallelizable, so
2928
+ that the module `X(M)` of vector fields on `M` is free. A change
2929
+ of frame on `M` is then identical to a change of basis in `X(M)`::
2930
+
2931
+ sage: XM = M.vector_field_module() ; XM
2932
+ Free module X(M) of vector fields on the 2-dimensional
2933
+ differentiable manifold M
2934
+ sage: XM.print_bases()
2935
+ Bases defined on the Free module X(M) of vector fields on the
2936
+ 2-dimensional differentiable manifold M:
2937
+ - (M, (∂/∂x,∂/∂y)) (default basis)
2938
+ - (M, (∂/∂u,∂/∂v))
2939
+ sage: XM.change_of_basis(c_xy.frame(), c_uv.frame())
2940
+ Field of tangent-space automorphisms on the 2-dimensional
2941
+ differentiable manifold M
2942
+ sage: M.change_of_frame(c_xy.frame(), c_uv.frame()) is \
2943
+ ....: XM.change_of_basis(c_xy.frame(), c_uv.frame())
2944
+ True
2945
+ """
2946
+ if (frame1, frame2) not in self._frame_changes:
2947
+ raise ValueError("the change of frame from {} to {}".format(frame1, frame2) +
2948
+ " has not been defined on the {}".format(self))
2949
+ return self._frame_changes[(frame1, frame2)]
2950
+
2951
+ def set_change_of_frame(self, frame1, frame2, change_of_frame,
2952
+ compute_inverse=True):
2953
+ r"""
2954
+ Relate two vector frames by an automorphism.
2955
+
2956
+ This updates the internal dictionary ``self._frame_changes``.
2957
+
2958
+ INPUT:
2959
+
2960
+ - ``frame1`` -- frame 1, denoted `(e_i)` below
2961
+ - ``frame2`` -- frame 2, denoted `(f_i)` below
2962
+ - ``change_of_frame`` -- instance of class
2963
+ :class:`~sage.manifolds.differentiable.automorphismfield.AutomorphismFieldParal`
2964
+ describing the automorphism `P` that relates the basis `(e_i)` to
2965
+ the basis `(f_i)` according to `f_i = P(e_i)`
2966
+ - ``compute_inverse`` -- boolean (default: ``True``); if set to True, the inverse
2967
+ automorphism is computed and the change from basis `(f_i)` to `(e_i)`
2968
+ is set to it in the internal dictionary ``self._frame_changes``
2969
+
2970
+ EXAMPLES:
2971
+
2972
+ Connecting two vector frames on a 2-dimensional manifold::
2973
+
2974
+ sage: M = Manifold(2, 'M')
2975
+ sage: c_xy.<x,y> = M.chart()
2976
+ sage: e = M.vector_frame('e')
2977
+ sage: f = M.vector_frame('f')
2978
+ sage: a = M.automorphism_field()
2979
+ sage: a[e,:] = [[1,2],[0,3]]
2980
+ sage: M.set_change_of_frame(e, f, a)
2981
+ sage: f[0].display(e)
2982
+ f_0 = e_0
2983
+ sage: f[1].display(e)
2984
+ f_1 = 2 e_0 + 3 e_1
2985
+ sage: e[0].display(f)
2986
+ e_0 = f_0
2987
+ sage: e[1].display(f)
2988
+ e_1 = -2/3 f_0 + 1/3 f_1
2989
+ sage: M.change_of_frame(e,f)[e,:]
2990
+ [1 2]
2991
+ [0 3]
2992
+ """
2993
+ from sage.manifolds.differentiable.automorphismfield import (
2994
+ AutomorphismFieldParal,
2995
+ )
2996
+ fmodule = frame1._fmodule
2997
+ if frame2._fmodule != fmodule:
2998
+ raise ValueError("the two frames are not defined on the same " +
2999
+ "vector field module")
3000
+ if not isinstance(change_of_frame, AutomorphismFieldParal):
3001
+ raise TypeError("the argument change_of_frame must be some " +
3002
+ "instance of AutomorphismFieldParal")
3003
+ fmodule.set_change_of_basis(frame1, frame2, change_of_frame,
3004
+ compute_inverse=compute_inverse)
3005
+ for sdom in self.open_supersets():
3006
+ sdom._frame_changes[(frame1, frame2)] = change_of_frame
3007
+ if compute_inverse:
3008
+ if (frame2, frame1) not in self._frame_changes:
3009
+ for sdom in self.open_supersets():
3010
+ sdom._frame_changes[(frame2, frame1)] = change_of_frame.inverse()
3011
+
3012
+ def vector_frame(self, *args, **kwargs) -> VectorFrame:
3013
+ r"""
3014
+ Define a vector frame on ``self``.
3015
+
3016
+ A *vector frame* is a field on the manifold that provides, at each
3017
+ point `p` of the manifold, a vector basis of the tangent space at `p`
3018
+ (or at `\Phi(p)` when ``dest_map`` is not ``None``, see below).
3019
+
3020
+ The vector frame can be defined from a set of `n` linearly independent
3021
+ vector fields, `n` being the dimension of ``self``.
3022
+
3023
+ .. SEEALSO::
3024
+
3025
+ :class:`~sage.manifolds.differentiable.vectorframe.VectorFrame`
3026
+ for complete documentation.
3027
+
3028
+ INPUT:
3029
+
3030
+ - ``symbol`` -- either a string, to be used as a
3031
+ common base for the symbols of the vector fields constituting the
3032
+ vector frame, or a list/tuple of strings, representing the individual
3033
+ symbols of the vector fields; can be omitted only if ``from_frame``
3034
+ is not ``None`` (see below)
3035
+ - ``vector_fields`` -- tuple or list of `n` linearly independent vector
3036
+ fields on the manifold ``self`` (`n` being the dimension of ``self``)
3037
+ defining the vector frame; can be omitted if the vector frame is
3038
+ created from scratch or if ``from_frame`` is not ``None``
3039
+ - ``latex_symbol`` -- (default: ``None``) either a string, to be used
3040
+ as a common base for the LaTeX symbols of the vector fields
3041
+ constituting the vector frame, or a list/tuple of strings,
3042
+ representing the individual LaTeX symbols of the vector fields;
3043
+ if ``None``, ``symbol`` is used in place of ``latex_symbol``
3044
+ - ``dest_map`` -- (default: ``None``)
3045
+ :class:`~sage.manifolds.differentiable.diff_map.DiffMap`;
3046
+ destination map `\Phi:\ U \rightarrow M`, where `U` is ``self`` and
3047
+ `M` is a differentiable manifold; for each `p\in U`, the vector
3048
+ frame evaluated at `p` is a basis of the tangent space
3049
+ `T_{\Phi(p)}M`; if ``dest_map`` is ``None``, the identity map is
3050
+ assumed (case of a vector frame *on* `U`)
3051
+ - ``from_frame`` -- (default: ``None``) vector frame `\tilde{e}`
3052
+ on the codomain `M` of the destination map `\Phi`; the returned
3053
+ frame `e` is then such that for all `p \in U`,
3054
+ we have `e(p) = \tilde{e}(\Phi(p))`
3055
+ - ``indices`` -- (default: ``None``; used only if ``symbol`` is a
3056
+ single string) tuple of strings representing the indices labelling
3057
+ the vector fields of the frame; if ``None``, the indices will be
3058
+ generated as integers within the range declared on ``self``
3059
+ - ``latex_indices`` -- (default: ``None``) tuple of strings
3060
+ representing the indices for the LaTeX symbols of the vector fields;
3061
+ if ``None``, ``indices`` is used instead
3062
+ - ``symbol_dual`` -- (default: ``None``) same as ``symbol`` but for the
3063
+ dual coframe; if ``None``, ``symbol`` must be a string and is used
3064
+ for the common base of the symbols of the elements of the dual
3065
+ coframe
3066
+ - ``latex_symbol_dual`` -- (default: ``None``) same as ``latex_symbol``
3067
+ but for the dual coframe
3068
+
3069
+ OUTPUT:
3070
+
3071
+ - a :class:`~sage.manifolds.differentiable.vectorframe.VectorFrame`
3072
+ representing the defined vector frame
3073
+
3074
+ EXAMPLES:
3075
+
3076
+ Defining a vector frame from two linearly independent vector
3077
+ fields on a 2-dimensional manifold::
3078
+
3079
+ sage: M = Manifold(2, 'M')
3080
+ sage: X.<x,y> = M.chart()
3081
+ sage: e0 = M.vector_field(1+x^2, 1+y^2)
3082
+ sage: e1 = M.vector_field(2, -x*y)
3083
+ sage: e = M.vector_frame('e', (e0, e1)); e
3084
+ Vector frame (M, (e_0,e_1))
3085
+ sage: e[0].display()
3086
+ e_0 = (x^2 + 1) ∂/∂x + (y^2 + 1) ∂/∂y
3087
+ sage: e[1].display()
3088
+ e_1 = 2 ∂/∂x - x*y ∂/∂y
3089
+ sage: (e[0], e[1]) == (e0, e1)
3090
+ True
3091
+
3092
+ If the vector fields are not linearly independent, an error is
3093
+ raised::
3094
+
3095
+ sage: z = M.vector_frame('z', (e0, -e0))
3096
+ Traceback (most recent call last):
3097
+ ...
3098
+ ValueError: the provided vector fields are not linearly
3099
+ independent
3100
+
3101
+ Another example, involving a pair vector fields along a curve::
3102
+
3103
+ sage: R.<t> = manifolds.RealLine()
3104
+ sage: c = M.curve([sin(t), sin(2*t)/2], (t, 0, 2*pi), name='c')
3105
+ sage: I = c.domain(); I
3106
+ Real interval (0, 2*pi)
3107
+ sage: v = c.tangent_vector_field()
3108
+ sage: v.display()
3109
+ c' = cos(t) ∂/∂x + (2*cos(t)^2 - 1) ∂/∂y
3110
+ sage: w = I.vector_field(1-2*cos(t)^2, cos(t), dest_map=c)
3111
+ sage: u = I.vector_frame('u', (v, w))
3112
+ sage: u[0].display()
3113
+ u_0 = cos(t) ∂/∂x + (2*cos(t)^2 - 1) ∂/∂y
3114
+ sage: u[1].display()
3115
+ u_1 = (-2*cos(t)^2 + 1) ∂/∂x + cos(t) ∂/∂y
3116
+ sage: (u[0], u[1]) == (v, w)
3117
+ True
3118
+
3119
+ It is also possible to create a vector frame from scratch, without
3120
+ connecting it to previously defined vector frames or vector fields
3121
+ (this can still be performed later via the method
3122
+ :meth:`~sage.manifolds.differentiable.manifold.DifferentiableManifold.set_change_of_frame`)::
3123
+
3124
+ sage: f = M.vector_frame('f'); f
3125
+ Vector frame (M, (f_0,f_1))
3126
+ sage: f[0]
3127
+ Vector field f_0 on the 2-dimensional differentiable manifold M
3128
+
3129
+ Thanks to the keywords ``dest_map`` and ``from_frame``, one can also
3130
+ define a vector frame from one preexisting on another manifold, via a
3131
+ differentiable map (here provided by the curve ``c``)::
3132
+
3133
+ sage: fc = I.vector_frame(dest_map=c, from_frame=f); fc
3134
+ Vector frame ((0, 2*pi), (f_0,f_1)) with values on the
3135
+ 2-dimensional differentiable manifold M
3136
+ sage: fc[0]
3137
+ Vector field f_0 along the Real interval (0, 2*pi) with values on
3138
+ the 2-dimensional differentiable manifold M
3139
+
3140
+ Note that the symbol for ``fc``, namely `f`, is inherited from ``f``,
3141
+ the original vector frame.
3142
+
3143
+ .. SEEALSO::
3144
+
3145
+ For more options, in particular for the choice of symbols and
3146
+ indices, see
3147
+ :class:`~sage.manifolds.differentiable.vectorframe.VectorFrame`.
3148
+ """
3149
+ from sage.manifolds.differentiable.vectorframe import VectorFrame
3150
+ # Input processing
3151
+ symbol = None
3152
+ vector_fields = None
3153
+ n_args = len(args)
3154
+ if n_args >= 1:
3155
+ symbol = args[0]
3156
+ if n_args == 2:
3157
+ vector_fields = args[1]
3158
+ elif n_args > 2:
3159
+ raise TypeError("vector_frame() takes at most two positional "
3160
+ "arguments")
3161
+ latex_symbol = kwargs.pop('latex_symbol', None)
3162
+ dest_map = kwargs.pop('dest_map', None)
3163
+ from_frame = kwargs.pop('from_frame', None)
3164
+ indices = kwargs.pop('indices', None)
3165
+ latex_indices = kwargs.pop('latex_indices', None)
3166
+ symbol_dual = kwargs.pop('symbol_dual', None)
3167
+ latex_symbol_dual = kwargs.pop('latex_symbol_dual', None)
3168
+
3169
+ if vector_fields:
3170
+ dest_map0 = vector_fields[0].parent().destination_map()
3171
+ if dest_map and dest_map is not dest_map0:
3172
+ raise ValueError("incompatible values of destination maps")
3173
+ dest_map = dest_map0
3174
+ resu = VectorFrame(self.vector_field_module(dest_map=dest_map,
3175
+ force_free=True),
3176
+ symbol=symbol, latex_symbol=latex_symbol,
3177
+ from_frame=from_frame, indices=indices,
3178
+ latex_indices=latex_indices, symbol_dual=symbol_dual,
3179
+ latex_symbol_dual=latex_symbol_dual)
3180
+ if vector_fields:
3181
+ linked = False
3182
+ try:
3183
+ resu._init_from_family(vector_fields)
3184
+ except ArithmeticError as err:
3185
+ linked = str(err) in ["non-invertible matrix",
3186
+ "input matrix must be nonsingular"]
3187
+ if linked:
3188
+ raise ValueError("the provided vector fields are not "
3189
+ "linearly independent")
3190
+ # Adding the newly generated changes of frame to the
3191
+ # dictionary _frame_changes of self and its supersets:
3192
+ for frame_pair, chge in resu._fmodule._basis_changes.items():
3193
+ if resu in frame_pair:
3194
+ for sdom in self.open_supersets():
3195
+ sdom._frame_changes[frame_pair] = chge
3196
+ return resu
3197
+
3198
+ def _set_covering_frame(self, frame):
3199
+ r"""
3200
+ Declare a frame covering ``self``.
3201
+
3202
+ This helper method is invoked by the frame constructor.
3203
+
3204
+ TESTS::
3205
+
3206
+ sage: M = Manifold(2, 'M')
3207
+ sage: M._covering_frames
3208
+ []
3209
+ sage: e = M.vector_frame('e')
3210
+ sage: M._covering_frames
3211
+ [Vector frame (M, (e_0,e_1))]
3212
+ sage: M._covering_frames = []
3213
+ sage: M._set_covering_frame(e)
3214
+ sage: M._covering_frames
3215
+ [Vector frame (M, (e_0,e_1))]
3216
+ """
3217
+ self._covering_frames.append(frame)
3218
+ self._parallelizable_parts = set([self])
3219
+ # if self contained smaller parallelizable parts, they are forgotten
3220
+ for sd in self.open_supersets():
3221
+ if not sd.is_manifestly_parallelizable():
3222
+ sd._parallelizable_parts.add(self)
3223
+
3224
+ def frames(self):
3225
+ r"""
3226
+ Return the list of vector frames defined on open subsets of ``self``.
3227
+
3228
+ OUTPUT: list of vector frames defined on open subsets of ``self``
3229
+
3230
+ EXAMPLES:
3231
+
3232
+ Vector frames on subsets of `\RR^2`::
3233
+
3234
+ sage: M = Manifold(2, 'R^2')
3235
+ sage: c_cart.<x,y> = M.chart() # Cartesian coordinates on R^2
3236
+ sage: M.frames()
3237
+ [Coordinate frame (R^2, (∂/∂x,∂/∂y))]
3238
+ sage: e = M.vector_frame('e')
3239
+ sage: M.frames()
3240
+ [Coordinate frame (R^2, (∂/∂x,∂/∂y)),
3241
+ Vector frame (R^2, (e_0,e_1))]
3242
+ sage: U = M.open_subset('U', coord_def={c_cart: x^2+y^2<1}) # unit disk
3243
+ sage: U.frames()
3244
+ [Coordinate frame (U, (∂/∂x,∂/∂y))]
3245
+ sage: M.frames()
3246
+ [Coordinate frame (R^2, (∂/∂x,∂/∂y)),
3247
+ Vector frame (R^2, (e_0,e_1)),
3248
+ Coordinate frame (U, (∂/∂x,∂/∂y))]
3249
+ """
3250
+ return list(self._frames)
3251
+
3252
+ def coframes(self):
3253
+ r"""
3254
+ Return the list of coframes defined on open subsets of ``self``.
3255
+
3256
+ OUTPUT: list of coframes defined on open subsets of ``self``
3257
+
3258
+ EXAMPLES:
3259
+
3260
+ Coframes on subsets of `\RR^2`::
3261
+
3262
+ sage: M = Manifold(2, 'R^2')
3263
+ sage: c_cart.<x,y> = M.chart() # Cartesian coordinates on R^2
3264
+ sage: M.coframes()
3265
+ [Coordinate coframe (R^2, (dx,dy))]
3266
+ sage: e = M.vector_frame('e')
3267
+ sage: M.coframes()
3268
+ [Coordinate coframe (R^2, (dx,dy)), Coframe (R^2, (e^0,e^1))]
3269
+ sage: U = M.open_subset('U', coord_def={c_cart: x^2+y^2<1}) # unit disk
3270
+ sage: U.coframes()
3271
+ [Coordinate coframe (U, (dx,dy))]
3272
+ sage: e.restrict(U)
3273
+ Vector frame (U, (e_0,e_1))
3274
+ sage: U.coframes()
3275
+ [Coordinate coframe (U, (dx,dy)), Coframe (U, (e^0,e^1))]
3276
+ sage: M.coframes()
3277
+ [Coordinate coframe (R^2, (dx,dy)),
3278
+ Coframe (R^2, (e^0,e^1)),
3279
+ Coordinate coframe (U, (dx,dy)),
3280
+ Coframe (U, (e^0,e^1))]
3281
+ """
3282
+ return list(self._coframes)
3283
+
3284
+ def changes_of_frame(self):
3285
+ r"""
3286
+ Return all the changes of vector frames defined on ``self``.
3287
+
3288
+ OUTPUT:
3289
+
3290
+ - dictionary of fields of tangent-space automorphisms representing
3291
+ the changes of frames, the keys being the pair of frames
3292
+
3293
+ EXAMPLES:
3294
+
3295
+ Let us consider a first vector frame on a 2-dimensional
3296
+ differentiable manifold::
3297
+
3298
+ sage: M = Manifold(2, 'M')
3299
+ sage: X.<x,y> = M.chart()
3300
+ sage: e = X.frame(); e
3301
+ Coordinate frame (M, (∂/∂x,∂/∂y))
3302
+
3303
+ At this stage, the dictionary of changes of frame is empty::
3304
+
3305
+ sage: M.changes_of_frame()
3306
+ {}
3307
+
3308
+ We introduce a second frame on the manifold, relating it to
3309
+ frame ``e`` by a field of tangent space automorphisms::
3310
+
3311
+ sage: a = M.automorphism_field(name='a')
3312
+ sage: a[:] = [[-y, x], [1, 2]]
3313
+ sage: f = e.new_frame(a, 'f'); f
3314
+ Vector frame (M, (f_0,f_1))
3315
+
3316
+ Then we have::
3317
+
3318
+ sage: M.changes_of_frame() # random (dictionary output)
3319
+ {(Coordinate frame (M, (∂/∂x,∂/∂y)),
3320
+ Vector frame (M, (f_0,f_1))): Field of tangent-space
3321
+ automorphisms on the 2-dimensional differentiable manifold M,
3322
+ (Vector frame (M, (f_0,f_1)),
3323
+ Coordinate frame (M, (∂/∂x,∂/∂y))): Field of tangent-space
3324
+ automorphisms on the 2-dimensional differentiable manifold M}
3325
+
3326
+ Some checks::
3327
+
3328
+ sage: M.changes_of_frame()[(e,f)] == a
3329
+ True
3330
+ sage: M.changes_of_frame()[(f,e)] == a^(-1)
3331
+ True
3332
+ """
3333
+ return self._frame_changes.copy()
3334
+
3335
+ def is_manifestly_parallelizable(self):
3336
+ r"""
3337
+ Return ``True`` if ``self`` is known to be a parallelizable
3338
+ and ``False`` otherwise.
3339
+
3340
+ If ``False`` is returned, either the manifold is not parallelizable
3341
+ or no vector frame has been defined on it yet.
3342
+
3343
+ EXAMPLES:
3344
+
3345
+ A just created manifold is a priori not manifestly parallelizable::
3346
+
3347
+ sage: M = Manifold(2, 'M')
3348
+ sage: M.is_manifestly_parallelizable()
3349
+ False
3350
+
3351
+ Defining a vector frame on it makes it parallelizable::
3352
+
3353
+ sage: e = M.vector_frame('e')
3354
+ sage: M.is_manifestly_parallelizable()
3355
+ True
3356
+
3357
+ Defining a coordinate chart on the whole manifold also makes it
3358
+ parallelizable::
3359
+
3360
+ sage: N = Manifold(4, 'N')
3361
+ sage: X.<t,x,y,z> = N.chart()
3362
+ sage: N.is_manifestly_parallelizable()
3363
+ True
3364
+ """
3365
+ return bool(self._covering_frames)
3366
+
3367
+ def tangent_space(self, point, base_ring=None):
3368
+ r"""
3369
+ Tangent space to ``self`` at a given point.
3370
+
3371
+ INPUT:
3372
+
3373
+ - ``point`` -- :class:`~sage.manifolds.point.ManifoldPoint`;
3374
+ point `p` on the manifold
3375
+
3376
+ - ``base_ring`` -- (default: the symbolic ring) the base ring
3377
+
3378
+ OUTPUT:
3379
+
3380
+ - :class:`~sage.manifolds.differentiable.tangent_space.TangentSpace`
3381
+ representing the tangent vector space `T_{p} M`, where `M` is the
3382
+ current manifold
3383
+
3384
+ EXAMPLES:
3385
+
3386
+ A tangent space to a 2-dimensional manifold::
3387
+
3388
+ sage: M = Manifold(2, 'M')
3389
+ sage: X.<x,y> = M.chart()
3390
+ sage: p = M.point((2, -3), name='p')
3391
+ sage: Tp = M.tangent_space(p); Tp
3392
+ Tangent space at Point p on the 2-dimensional differentiable
3393
+ manifold M
3394
+ sage: Tp.category()
3395
+ Category of finite dimensional vector spaces over Symbolic Ring
3396
+ sage: dim(Tp)
3397
+ 2
3398
+
3399
+ .. SEEALSO::
3400
+
3401
+ :class:`~sage.manifolds.differentiable.tangent_space.TangentSpace`
3402
+ for more examples.
3403
+ """
3404
+ from sage.manifolds.differentiable.tangent_space import TangentSpace
3405
+ from sage.manifolds.point import ManifoldPoint
3406
+ if not isinstance(point, ManifoldPoint):
3407
+ raise TypeError("{} is not a manifold point".format(point))
3408
+ if point not in self:
3409
+ raise ValueError("{} is not a point on the {}".format(point, self))
3410
+ return TangentSpace(point, base_ring=base_ring)
3411
+
3412
+ def curve(self, coord_expression, param, chart=None,
3413
+ name=None, latex_name=None):
3414
+ r"""
3415
+ Define a differentiable curve in the manifold.
3416
+
3417
+ .. SEEALSO::
3418
+
3419
+ :class:`~sage.manifolds.differentiable.curve.DifferentiableCurve`
3420
+ for details.
3421
+
3422
+ INPUT:
3423
+
3424
+ - ``coord_expression`` -- either
3425
+
3426
+ - (i) a dictionary whose keys are charts on the manifold and values
3427
+ the coordinate expressions (as lists or tuples) of the curve in
3428
+ the given chart
3429
+ - (ii) a single coordinate expression in a given chart on the
3430
+ manifold, the latter being provided by the argument ``chart``
3431
+
3432
+ in both cases, if the dimension of the manifold is 1, a single
3433
+ coordinate expression can be passed instead of a tuple with
3434
+ a single element
3435
+ - ``param`` -- tuple of the type ``(t, t_min, t_max)``, where
3436
+
3437
+ * ``t`` is the curve parameter used in ``coord_expression``;
3438
+ * ``t_min`` is its minimal value;
3439
+ * ``t_max`` its maximal value;
3440
+
3441
+ if ``t_min=-Infinity`` and ``t_max=+Infinity``, they can be
3442
+ omitted and ``t`` can be passed for ``param`` instead of the
3443
+ tuple ``(t, t_min, t_max)``
3444
+ - ``chart`` -- (default: ``None``) chart on the manifold used for
3445
+ case (ii) above; if ``None`` the default chart of the manifold is
3446
+ assumed
3447
+ - ``name`` -- (default: ``None``) string; symbol given to the curve
3448
+ - ``latex_name`` -- (default: ``None``) string; LaTeX symbol to denote
3449
+ the curve; if none is provided, ``name`` will be used
3450
+
3451
+ OUTPUT: :class:`~sage.manifolds.differentiable.curve.DifferentiableCurve`
3452
+
3453
+ EXAMPLES:
3454
+
3455
+ The lemniscate of Gerono in the 2-dimensional Euclidean plane::
3456
+
3457
+ sage: M = Manifold(2, 'M')
3458
+ sage: X.<x,y> = M.chart()
3459
+ sage: R.<t> = manifolds.RealLine()
3460
+ sage: c = M.curve([sin(t), sin(2*t)/2], (t, 0, 2*pi), name='c') ; c
3461
+ Curve c in the 2-dimensional differentiable manifold M
3462
+
3463
+ The same definition with the coordinate expression passed as a
3464
+ dictionary::
3465
+
3466
+ sage: c = M.curve({X: [sin(t), sin(2*t)/2]}, (t, 0, 2*pi), name='c') ; c
3467
+ Curve c in the 2-dimensional differentiable manifold M
3468
+
3469
+ An example of definition with ``t_min`` and ``t_max`` omitted: a helix
3470
+ in `\RR^3`::
3471
+
3472
+ sage: R3 = Manifold(3, 'R^3')
3473
+ sage: X.<x,y,z> = R3.chart()
3474
+ sage: c = R3.curve([cos(t), sin(t), t], t, name='c') ; c
3475
+ Curve c in the 3-dimensional differentiable manifold R^3
3476
+ sage: c.domain() # check that t is unbounded
3477
+ Real number line ℝ
3478
+
3479
+ .. SEEALSO::
3480
+
3481
+ :class:`~sage.manifolds.differentiable.curve.DifferentiableCurve`
3482
+ for more examples, including plots.
3483
+ """
3484
+ from sage.manifolds.differentiable.examples.real_line import RealLine
3485
+ if not isinstance(param, (tuple, list)):
3486
+ param = (param, minus_infinity, infinity)
3487
+ elif len(param) != 3:
3488
+ raise ValueError("the argument 'param' must be of the form " +
3489
+ "(t, t_min, t_max)")
3490
+ t = param[0]
3491
+ t_min = param[1]
3492
+ t_max = param[2]
3493
+ real_field = RealLine(names=(repr(t),))
3494
+ interval = real_field.open_interval(t_min, t_max)
3495
+ curve_set = Hom(interval, self)
3496
+ if not isinstance(coord_expression, dict):
3497
+ # Turn coord_expression into a dictionary:
3498
+ if chart is None:
3499
+ chart = self._def_chart
3500
+ elif chart not in self._atlas:
3501
+ raise ValueError("the {} has not been ".format(chart) +
3502
+ "defined on the {}".format(self))
3503
+ if isinstance(coord_expression, (tuple, list)):
3504
+ coord_expression = {chart: coord_expression}
3505
+ else:
3506
+ # case self.dim()=1
3507
+ coord_expression = {chart: (coord_expression,)}
3508
+ return curve_set(coord_expression, name=name, latex_name=latex_name)
3509
+
3510
+ def integrated_curve(self, equations_rhs, velocities, curve_param,
3511
+ initial_tangent_vector, chart=None, name=None,
3512
+ latex_name=None, verbose=False, across_charts=False):
3513
+ r"""
3514
+ Construct a curve defined by a system of second order
3515
+ differential equations in the coordinate functions.
3516
+
3517
+ .. SEEALSO::
3518
+
3519
+ :class:`~sage.manifolds.differentiable.integrated_curve.IntegratedCurve`
3520
+ for details.
3521
+
3522
+ INPUT:
3523
+
3524
+ - ``equations_rhs`` -- list of the right-hand sides of the
3525
+ equations on the velocities only
3526
+ - ``velocities`` -- list of the symbolic expressions used in
3527
+ ``equations_rhs`` to denote the velocities
3528
+ - ``curve_param`` -- tuple of the type ``(t, t_min, t_max)``,
3529
+ where
3530
+
3531
+ * ``t`` is the symbolic variable used in ``equations_rhs`` to
3532
+ denote the parameter of the curve;
3533
+ * ``t_min`` is its minimal (finite) value;
3534
+ * ``t_max`` its maximal (finite) value.
3535
+
3536
+ - ``initial_tangent_vector`` --
3537
+ :class:`~sage.manifolds.differentiable.tangent_vector.TangentVector`;
3538
+ initial tangent vector of the curve
3539
+ - ``chart`` -- (default: ``None``) chart on the manifold in
3540
+ which the equations are given; if ``None`` the default chart
3541
+ of the manifold is assumed
3542
+ - ``name`` -- (default: ``None``) string; symbol given to the curve
3543
+ - ``latex_name`` -- (default: ``None``) string; LaTeX symbol to denote
3544
+ the curve; if none is provided, ``name`` will be used
3545
+
3546
+ OUTPUT: :class:`~sage.manifolds.differentiable.integrated_curve.IntegratedCurve`
3547
+
3548
+ EXAMPLES:
3549
+
3550
+ Trajectory of a particle of unit mass and unit charge in a
3551
+ unit, uniform, stationary magnetic field::
3552
+
3553
+ sage: # needs scipy
3554
+ sage: M = Manifold(3, 'M')
3555
+ sage: X.<x1,x2,x3> = M.chart()
3556
+ sage: t = var('t')
3557
+ sage: D = X.symbolic_velocities()
3558
+ sage: eqns = [D[1], -D[0], SR(0)]
3559
+ sage: p = M.point((0,0,0), name='p')
3560
+ sage: Tp = M.tangent_space(p)
3561
+ sage: v = Tp((1,0,1))
3562
+ sage: c = M.integrated_curve(eqns, D, (t,0,6), v, name='c'); c
3563
+ Integrated curve c in the 3-dimensional differentiable
3564
+ manifold M
3565
+ sage: sys = c.system(verbose=True)
3566
+ Curve c in the 3-dimensional differentiable manifold M
3567
+ integrated over the Real interval (0, 6) as a solution to
3568
+ the following system, written with respect to
3569
+ Chart (M, (x1, x2, x3)):
3570
+ <BLANKLINE>
3571
+ Initial point: Point p on the 3-dimensional differentiable
3572
+ manifold M with coordinates [0, 0, 0] with respect to
3573
+ Chart (M, (x1, x2, x3))
3574
+ Initial tangent vector: Tangent vector at Point p on the
3575
+ 3-dimensional differentiable manifold M with
3576
+ components [1, 0, 1] with respect to Chart (M, (x1, x2, x3))
3577
+ <BLANKLINE>
3578
+ d(x1)/dt = Dx1
3579
+ d(x2)/dt = Dx2
3580
+ d(x3)/dt = Dx3
3581
+ d(Dx1)/dt = Dx2
3582
+ d(Dx2)/dt = -Dx1
3583
+ d(Dx3)/dt = 0
3584
+ <BLANKLINE>
3585
+ sage: sol = c.solve()
3586
+ sage: interp = c.interpolate()
3587
+ sage: p = c(1.3, verbose=True)
3588
+ Evaluating point coordinates from the interpolation
3589
+ associated with the key 'cubic spline-interp-odeint'
3590
+ by default...
3591
+ sage: p
3592
+ Point on the 3-dimensional differentiable manifold M
3593
+ sage: p.coordinates() # abs tol 1e-12
3594
+ (0.9635581599167499, -0.7325011788437327, 1.3)
3595
+ sage: tgt_vec = c.tangent_vector_eval_at(3.7, verbose=True)
3596
+ Evaluating tangent vector components from the interpolation
3597
+ associated with the key 'cubic spline-interp-odeint'
3598
+ by default...
3599
+ sage: tgt_vec[:] # abs tol 1e-12
3600
+ [-0.8481007454066425, 0.5298350137284363, 1.0]
3601
+ """
3602
+
3603
+ from sage.manifolds.differentiable.examples.real_line import RealLine
3604
+ from sage.manifolds.differentiable.manifold_homset import IntegratedCurveSet
3605
+
3606
+ if len(curve_param) != 3:
3607
+ raise ValueError("the argument 'curve_param' must be of the form " +
3608
+ "(t, t_min, t_max)")
3609
+ t = curve_param[0]
3610
+ t_min = curve_param[1]
3611
+ t_max = curve_param[2]
3612
+ real_field = RealLine(names=(repr(t),))
3613
+ interval = real_field.open_interval(t_min, t_max)
3614
+ integrated_curve_set = IntegratedCurveSet(interval, self) # not
3615
+ # possible to use Hom(interval, self)
3616
+ return integrated_curve_set(equations_rhs, velocities, t,
3617
+ initial_tangent_vector, chart=chart,
3618
+ name=name, latex_name=latex_name,
3619
+ verbose=verbose, across_charts=across_charts)
3620
+
3621
+ def integrated_autoparallel_curve(self, affine_connection,
3622
+ curve_param, initial_tangent_vector, chart=None,
3623
+ name=None, latex_name=None, verbose=False,
3624
+ across_charts=False):
3625
+ r"""
3626
+ Construct an autoparallel curve on the manifold with respect to
3627
+ a given affine connection.
3628
+
3629
+ .. SEEALSO::
3630
+
3631
+ :class:`~sage.manifolds.differentiable.integrated_curve.IntegratedAutoparallelCurve`
3632
+ for details.
3633
+
3634
+ INPUT:
3635
+
3636
+ - ``affine_connection`` --
3637
+ :class:`~sage.manifolds.differentiable.affine_connection.AffineConnection`;
3638
+ affine connection with respect to which the curve is autoparallel
3639
+ - ``curve_param`` -- tuple of the type ``(t, t_min, t_max)``,
3640
+ where
3641
+
3642
+ * ``t`` is the symbolic variable to be used as the parameter
3643
+ of the curve (the equations defining an instance of
3644
+ :class:`~sage.manifolds.differentiable.integrated_curve.IntegratedAutoparallelCurve`
3645
+ are such that ``t`` will actually be an affine parameter
3646
+ of the curve);
3647
+ * ``t_min`` is its minimal (finite) value;
3648
+ * ``t_max`` its maximal (finite) value.
3649
+
3650
+ - ``initial_tangent_vector`` --
3651
+ :class:`~sage.manifolds.differentiable.tangent_vector.TangentVector`;
3652
+ initial tangent vector of the curve
3653
+ - ``chart`` -- (default: ``None``) chart on the manifold in
3654
+ which the equations are given ; if ``None`` the default chart
3655
+ of the manifold is assumed
3656
+ - ``name`` -- (default: ``None``) string; symbol given to the curve
3657
+ - ``latex_name`` -- (default: ``None``) string; LaTeX symbol to denote
3658
+ the curve; if none is provided, ``name`` will be used
3659
+
3660
+ OUTPUT: :class:`~sage.manifolds.differentiable.integrated_curve.IntegratedAutoparallelCurve`
3661
+
3662
+ EXAMPLES:
3663
+
3664
+ Autoparallel curves associated with the Mercator projection of
3665
+ the 2-sphere `\mathbb{S}^{2}`::
3666
+
3667
+ sage: S2 = Manifold(2, 'S^2', start_index=1)
3668
+ sage: polar.<th,ph> = S2.chart('th ph')
3669
+ sage: epolar = polar.frame()
3670
+ sage: ch_basis = S2.automorphism_field()
3671
+ sage: ch_basis[1,1], ch_basis[2,2] = 1, 1/sin(th)
3672
+ sage: epolar_ON=S2.default_frame().new_frame(ch_basis,'epolar_ON')
3673
+
3674
+ Set the affine connection associated with Mercator projection;
3675
+ it is metric compatible but it has non-vanishing torsion::
3676
+
3677
+ sage: nab = S2.affine_connection('nab')
3678
+ sage: nab.set_coef(epolar_ON)[:]
3679
+ [[[0, 0], [0, 0]], [[0, 0], [0, 0]]]
3680
+ sage: g = S2.metric('g')
3681
+ sage: g[1,1], g[2,2] = 1, (sin(th))^2
3682
+ sage: nab(g)[:]
3683
+ [[[0, 0], [0, 0]], [[0, 0], [0, 0]]]
3684
+ sage: nab.torsion()[:]
3685
+ [[[0, 0], [0, 0]], [[0, cos(th)/sin(th)], [-cos(th)/sin(th), 0]]]
3686
+
3687
+ Declare an integrated autoparallel curve with respect to this
3688
+ connection::
3689
+
3690
+ sage: # needs scipy
3691
+ sage: p = S2.point((pi/4, 0), name='p')
3692
+ sage: Tp = S2.tangent_space(p)
3693
+ sage: v = Tp((1,1), basis=epolar_ON.at(p))
3694
+ sage: t = var('t')
3695
+ sage: c = S2.integrated_autoparallel_curve(nab, (t, 0, 2.3),
3696
+ ....: v, chart=polar, name='c')
3697
+ sage: sys = c.system(verbose=True)
3698
+ Autoparallel curve c in the 2-dimensional differentiable
3699
+ manifold S^2 equipped with Affine connection nab on the
3700
+ 2-dimensional differentiable manifold S^2, and integrated
3701
+ over the Real interval (0, 2.30000000000000) as a solution to the
3702
+ following equations, written with respect to
3703
+ Chart (S^2, (th, ph)):
3704
+ <BLANKLINE>
3705
+ Initial point: Point p on the 2-dimensional differentiable
3706
+ manifold S^2 with coordinates [1/4*pi, 0] with respect to
3707
+ Chart (S^2, (th, ph))
3708
+ Initial tangent vector: Tangent vector at Point p on the
3709
+ 2-dimensional differentiable manifold S^2 with
3710
+ components [1, sqrt(2)] with respect to
3711
+ Chart (S^2, (th, ph))
3712
+ <BLANKLINE>
3713
+ d(th)/dt = Dth
3714
+ d(ph)/dt = Dph
3715
+ d(Dth)/dt = 0
3716
+ d(Dph)/dt = -Dph*Dth*cos(th)/sin(th)
3717
+ <BLANKLINE>
3718
+ sage: sol = c.solve()
3719
+ sage: interp = c.interpolate()
3720
+ sage: p = c(1.3, verbose=True)
3721
+ Evaluating point coordinates from the interpolation
3722
+ associated with the key 'cubic spline-interp-odeint'
3723
+ by default...
3724
+ sage: p
3725
+ Point on the 2-dimensional differentiable manifold S^2
3726
+ sage: polar(p) # abs tol 1e-12
3727
+ (2.0853981633974477, 1.4203177070475606)
3728
+ sage: tgt_vec = c.tangent_vector_eval_at(1.3, verbose=True)
3729
+ Evaluating tangent vector components from the interpolation
3730
+ associated with the key 'cubic spline-interp-odeint'
3731
+ by default...
3732
+ sage: tgt_vec[:] # abs tol 1e-12
3733
+ [1.000000000000011, 1.148779968412235]
3734
+ """
3735
+
3736
+ from sage.manifolds.differentiable.examples.real_line import RealLine
3737
+ from sage.manifolds.differentiable.manifold_homset import (
3738
+ IntegratedAutoparallelCurveSet,
3739
+ )
3740
+
3741
+ if len(curve_param) != 3:
3742
+ raise ValueError("the argument 'curve_param' must be " +
3743
+ "of the form (t, t_min, t_max)")
3744
+ t = curve_param[0]
3745
+ t_min = curve_param[1]
3746
+ t_max = curve_param[2]
3747
+ real_field = RealLine(names=(repr(t),))
3748
+ interval = real_field.open_interval(t_min, t_max)
3749
+ autoparallel_curve_set = IntegratedAutoparallelCurveSet(interval,
3750
+ self)
3751
+ # not possible to use Hom(interval, self)
3752
+ return autoparallel_curve_set(affine_connection, t,
3753
+ initial_tangent_vector,
3754
+ chart=chart, name=name,
3755
+ latex_name=latex_name,
3756
+ verbose=verbose,
3757
+ across_charts=across_charts)
3758
+
3759
+ def integrated_geodesic(self, metric, curve_param,
3760
+ initial_tangent_vector, chart=None,
3761
+ name=None, latex_name=None, verbose=False,
3762
+ across_charts=False):
3763
+ r"""
3764
+ Construct a geodesic on the manifold with respect to a given metric.
3765
+
3766
+ .. SEEALSO::
3767
+
3768
+ :class:`~sage.manifolds.differentiable.integrated_curve.IntegratedGeodesic`
3769
+ for details.
3770
+
3771
+ INPUT:
3772
+
3773
+ - ``metric`` --
3774
+ :class:`~sage.manifolds.differentiable.metric.PseudoRiemannianMetric`
3775
+ metric with respect to which the curve is a geodesic
3776
+ - ``curve_param`` -- tuple of the type ``(t, t_min, t_max)``,
3777
+ where
3778
+
3779
+ * ``t`` is the symbolic variable to be used as the parameter
3780
+ of the curve (the equations defining an instance of
3781
+ :class:`~sage.manifolds.differentiable.integrated_curve.IntegratedGeodesic`
3782
+ are such that ``t`` will actually be an affine parameter
3783
+ of the curve);
3784
+ * ``t_min`` is its minimal (finite) value;
3785
+ * ``t_max`` its maximal (finite) value.
3786
+
3787
+ - ``initial_tangent_vector`` --
3788
+ :class:`~sage.manifolds.differentiable.tangent_vector.TangentVector`;
3789
+ initial tangent vector of the curve
3790
+ - ``chart`` -- (default: ``None``) chart on the manifold in
3791
+ which the equations are given; if ``None`` the default chart
3792
+ of the manifold is assumed
3793
+ - ``name`` -- (default: ``None``) string; symbol given to the curve
3794
+ - ``latex_name`` -- (default: ``None``) string; LaTeX symbol to denote
3795
+ the curve; if none is provided, ``name`` will be used
3796
+
3797
+ OUTPUT: :class:`~sage.manifolds.differentiable.integrated_curve.IntegratedGeodesic`
3798
+
3799
+ EXAMPLES:
3800
+
3801
+ Geodesics of the unit 2-sphere `\mathbb{S}^{2}`::
3802
+
3803
+ sage: S2 = Manifold(2, 'S^2', start_index=1)
3804
+ sage: polar.<th,ph> = S2.chart('th ph')
3805
+ sage: epolar = polar.frame()
3806
+
3807
+ Set the standard metric tensor `g` on `\mathbb{S}^{2}`::
3808
+
3809
+ sage: g = S2.metric('g')
3810
+ sage: g[1,1], g[2,2] = 1, (sin(th))^2
3811
+
3812
+ Declare an integrated geodesic with respect to this metric::
3813
+
3814
+ sage: # needs scipy
3815
+ sage: p = S2.point((pi/4, 0), name='p')
3816
+ sage: Tp = S2.tangent_space(p)
3817
+ sage: v = Tp((1, 1), basis=epolar.at(p))
3818
+ sage: t = var('t')
3819
+ sage: c = S2.integrated_geodesic(g, (t, 0, 6), v,
3820
+ ....: chart=polar, name='c')
3821
+ sage: sys = c.system(verbose=True)
3822
+ Geodesic c in the 2-dimensional differentiable manifold S^2
3823
+ equipped with Riemannian metric g on the 2-dimensional
3824
+ differentiable manifold S^2, and integrated over the Real
3825
+ interval (0, 6) as a solution to the following geodesic
3826
+ equations, written with respect to Chart (S^2, (th, ph)):
3827
+ <BLANKLINE>
3828
+ Initial point: Point p on the 2-dimensional differentiable
3829
+ manifold S^2 with coordinates [1/4*pi, 0] with respect to
3830
+ Chart (S^2, (th, ph))
3831
+ Initial tangent vector: Tangent vector at Point p on the
3832
+ 2-dimensional differentiable manifold S^2 with
3833
+ components [1, 1] with respect to Chart (S^2, (th, ph))
3834
+ <BLANKLINE>
3835
+ d(th)/dt = Dth
3836
+ d(ph)/dt = Dph
3837
+ d(Dth)/dt = Dph^2*cos(th)*sin(th)
3838
+ d(Dph)/dt = -2*Dph*Dth*cos(th)/sin(th)
3839
+ <BLANKLINE>
3840
+ sage: sol = c.solve()
3841
+ sage: interp = c.interpolate()
3842
+ sage: p = c(1.3, verbose=True)
3843
+ Evaluating point coordinates from the interpolation
3844
+ associated with the key 'cubic spline-interp-odeint'
3845
+ by default...
3846
+ sage: p
3847
+ Point on the 2-dimensional differentiable manifold S^2
3848
+ sage: p.coordinates() # abs tol 1e-12
3849
+ (2.2047435672397526, 0.7986602654406825)
3850
+ sage: tgt_vec = c.tangent_vector_eval_at(3.7, verbose=True)
3851
+ Evaluating tangent vector components from the interpolation
3852
+ associated with the key 'cubic spline-interp-odeint'
3853
+ by default...
3854
+ sage: tgt_vec[:] # abs tol 1e-12
3855
+ [-1.0907409234671228, 0.6205670379855032]
3856
+ """
3857
+ from sage.manifolds.differentiable.examples.real_line import RealLine
3858
+ from sage.manifolds.differentiable.manifold_homset import IntegratedGeodesicSet
3859
+
3860
+ if len(curve_param) != 3:
3861
+ raise ValueError("the argument 'curve_param' must be of " +
3862
+ "the form (t, t_min, t_max)")
3863
+ t = curve_param[0]
3864
+ t_min = curve_param[1]
3865
+ t_max = curve_param[2]
3866
+ real_field = RealLine(names=(repr(t),))
3867
+ interval = real_field.open_interval(t_min, t_max)
3868
+ integrated_geodesic_set = IntegratedGeodesicSet(interval, self)
3869
+ return integrated_geodesic_set(metric, t, initial_tangent_vector,
3870
+ chart=chart, name=name,
3871
+ latex_name=latex_name,
3872
+ verbose=verbose,
3873
+ across_charts=across_charts)
3874
+
3875
+ def affine_connection(self, name, latex_name=None):
3876
+ r"""
3877
+ Define an affine connection on the manifold.
3878
+
3879
+ See :class:`~sage.manifolds.differentiable.affine_connection.AffineConnection`
3880
+ for a complete documentation.
3881
+
3882
+ INPUT:
3883
+
3884
+ - ``name`` -- name given to the affine connection
3885
+ - ``latex_name`` -- (default: ``None``) LaTeX symbol to denote the
3886
+ affine connection
3887
+
3888
+ OUTPUT:
3889
+
3890
+ - the affine connection, as an instance of
3891
+ :class:`~sage.manifolds.differentiable.affine_connection.AffineConnection`
3892
+
3893
+ EXAMPLES:
3894
+
3895
+ Affine connection on an open subset of a 3-dimensional smooth manifold::
3896
+
3897
+ sage: M = Manifold(3, 'M', start_index=1)
3898
+ sage: A = M.open_subset('A', latex_name=r'\mathcal{A}')
3899
+ sage: nab = A.affine_connection('nabla', r'\nabla') ; nab
3900
+ Affine connection nabla on the Open subset A of the 3-dimensional
3901
+ differentiable manifold M
3902
+
3903
+ .. SEEALSO::
3904
+
3905
+ :class:`~sage.manifolds.differentiable.affine_connection.AffineConnection`
3906
+ for more examples.
3907
+ """
3908
+ from sage.manifolds.differentiable.affine_connection import AffineConnection
3909
+ return AffineConnection(self, name, latex_name)
3910
+
3911
+ def metric(self, name: str, signature: Optional[int] = None,
3912
+ latex_name: Optional[str] = None,
3913
+ dest_map: Optional[DiffMap] = None) -> PseudoRiemannianMetric:
3914
+ r"""
3915
+ Define a pseudo-Riemannian metric on the manifold.
3916
+
3917
+ A *pseudo-Riemannian metric* is a field of nondegenerate symmetric
3918
+ bilinear forms acting in the tangent spaces. See
3919
+ :class:`~sage.manifolds.differentiable.metric.PseudoRiemannianMetric`
3920
+ for a complete documentation.
3921
+
3922
+ INPUT:
3923
+
3924
+ - ``name`` -- name given to the metric
3925
+ - ``signature`` -- (default: ``None``) signature `S` of the metric as a
3926
+ single integer: `S = n_+ - n_-`, where `n_+` (resp. `n_-`) is the
3927
+ number of positive terms (resp. number of negative terms) in any
3928
+ diagonal writing of the metric components; if ``signature`` is not
3929
+ provided, `S` is set to the manifold's dimension (Riemannian
3930
+ signature)
3931
+ - ``latex_name`` -- (default: ``None``) LaTeX symbol to denote the
3932
+ metric; if ``None``, it is formed from ``name``
3933
+ - ``dest_map`` -- (default: ``None``) instance of
3934
+ class :class:`~sage.manifolds.differentiable.diff_map.DiffMap`
3935
+ representing the destination map `\Phi:\ U \rightarrow M`, where `U`
3936
+ is the current manifold; if ``None``, the identity map is assumed
3937
+ (case of a metric tensor field *on* `U`)
3938
+
3939
+ OUTPUT:
3940
+
3941
+ - instance of
3942
+ :class:`~sage.manifolds.differentiable.metric.PseudoRiemannianMetric`
3943
+ representing the defined pseudo-Riemannian metric.
3944
+
3945
+ EXAMPLES:
3946
+
3947
+ Metric on a 3-dimensional manifold::
3948
+
3949
+ sage: M = Manifold(3, 'M', start_index=1)
3950
+ sage: c_xyz.<x,y,z> = M.chart()
3951
+ sage: g = M.metric('g'); g
3952
+ Riemannian metric g on the 3-dimensional differentiable manifold M
3953
+
3954
+ .. SEEALSO::
3955
+
3956
+ :class:`~sage.manifolds.differentiable.metric.PseudoRiemannianMetric`
3957
+ for more examples.
3958
+ """
3959
+ vmodule = self.vector_field_module(dest_map)
3960
+ return vmodule.metric(name, signature=signature, latex_name=latex_name)
3961
+
3962
+ def degenerate_metric(self, name, latex_name=None, dest_map=None):
3963
+ r"""
3964
+ Define a degenerate (or null or lightlike) metric on the manifold.
3965
+
3966
+ A *degenerate metric* is a field of degenerate symmetric
3967
+ bilinear forms acting in the tangent spaces.
3968
+
3969
+ See
3970
+ :class:`~sage.manifolds.differentiable.metric.DegenerateMetric`
3971
+ for a complete documentation.
3972
+
3973
+ INPUT:
3974
+
3975
+ - ``name`` -- name given to the metric
3976
+ - ``latex_name`` -- (default: ``None``) LaTeX symbol to denote the
3977
+ metric; if ``None``, it is formed from ``name``
3978
+ - ``dest_map`` -- (default: ``None``) instance of
3979
+ class :class:`~sage.manifolds.differentiable.diff_map.DiffMap`
3980
+ representing the destination map `\Phi:\ U \rightarrow M`, where `U`
3981
+ is the current manifold; if ``None``, the identity map is assumed
3982
+ (case of a metric tensor field *on* `U`)
3983
+
3984
+ OUTPUT:
3985
+
3986
+ - instance of
3987
+ :class:`~sage.manifolds.differentiable.metric.DegenerateMetric`
3988
+ representing the defined degenerate metric.
3989
+
3990
+ EXAMPLES:
3991
+
3992
+ Lightlike cone::
3993
+
3994
+ sage: M = Manifold(3, 'M'); X.<x,y,z> = M.chart()
3995
+ sage: g = M.degenerate_metric('g'); g
3996
+ degenerate metric g on the 3-dimensional differentiable manifold M
3997
+ sage: det(g)
3998
+ Scalar field zero on the 3-dimensional differentiable manifold M
3999
+ sage: g.parent()
4000
+ Free module T^(0,2)(M) of type-(0,2) tensors fields on the
4001
+ 3-dimensional differentiable manifold M
4002
+ sage: g[0,0], g[0,1], g[0,2] = (y^2 + z^2)/(x^2 + y^2 + z^2), \
4003
+ ....: - x*y/(x^2 + y^2 + z^2), - x*z/(x^2 + y^2 + z^2)
4004
+ sage: g[1,1], g[1,2], g[2,2] = (x^2 + z^2)/(x^2 + y^2 + z^2), \
4005
+ ....: - y*z/(x^2 + y^2 + z^2), (x^2 + y^2)/(x^2 + y^2 + z^2)
4006
+ sage: g.disp()
4007
+ g = (y^2 + z^2)/(x^2 + y^2 + z^2) dx⊗dx - x*y/(x^2 + y^2 + z^2) dx⊗dy
4008
+ - x*z/(x^2 + y^2 + z^2) dx⊗dz - x*y/(x^2 + y^2 + z^2) dy⊗dx
4009
+ + (x^2 + z^2)/(x^2 + y^2 + z^2) dy⊗dy - y*z/(x^2 + y^2 + z^2) dy⊗dz
4010
+ - x*z/(x^2 + y^2 + z^2) dz⊗dx - y*z/(x^2 + y^2 + z^2) dz⊗dy
4011
+ + (x^2 + y^2)/(x^2 + y^2 + z^2) dz⊗dz
4012
+
4013
+ .. SEEALSO::
4014
+
4015
+ :class:`~sage.manifolds.differentiable.metric.DegenerateMetric`
4016
+ for more examples.
4017
+ """
4018
+ vmodule = self.vector_field_module(dest_map)
4019
+ dim = vmodule.ambient_domain().dimension()
4020
+ return vmodule.metric(name, signature=(0,dim-1,1), latex_name=latex_name)
4021
+
4022
+ def riemannian_metric(self, name, latex_name=None, dest_map=None):
4023
+ r"""
4024
+ Define a Riemannian metric on the manifold.
4025
+
4026
+ A *Riemannian metric* is a field of positive definite symmetric
4027
+ bilinear forms acting in the tangent spaces.
4028
+
4029
+ See
4030
+ :class:`~sage.manifolds.differentiable.metric.PseudoRiemannianMetric`
4031
+ for a complete documentation.
4032
+
4033
+ INPUT:
4034
+
4035
+ - ``name`` -- name given to the metric
4036
+ - ``latex_name`` -- (default: ``None``) LaTeX symbol to denote the
4037
+ metric; if ``None``, it is formed from ``name``
4038
+ - ``dest_map`` -- (default: ``None``) instance of
4039
+ class :class:`~sage.manifolds.differentiable.diff_map.DiffMap`
4040
+ representing the destination map `\Phi:\ U \rightarrow M`, where `U`
4041
+ is the current manifold; if ``None``, the identity map is assumed
4042
+ (case of a metric tensor field *on* `U`)
4043
+
4044
+ OUTPUT:
4045
+
4046
+ - instance of
4047
+ :class:`~sage.manifolds.differentiable.metric.PseudoRiemannianMetric`
4048
+ representing the defined Riemannian metric.
4049
+
4050
+ EXAMPLES:
4051
+
4052
+ Metric of the hyperbolic plane `H^2`::
4053
+
4054
+ sage: H2 = Manifold(2, 'H^2', start_index=1)
4055
+ sage: X.<x,y> = H2.chart('x y:(0,+oo)') # Poincaré half-plane coord.
4056
+ sage: g = H2.riemannian_metric('g')
4057
+ sage: g[1,1], g[2,2] = 1/y^2, 1/y^2
4058
+ sage: g
4059
+ Riemannian metric g on the 2-dimensional differentiable manifold H^2
4060
+ sage: g.display()
4061
+ g = y^(-2) dx⊗dx + y^(-2) dy⊗dy
4062
+ sage: g.signature()
4063
+ 2
4064
+
4065
+ .. SEEALSO::
4066
+
4067
+ :class:`~sage.manifolds.differentiable.metric.PseudoRiemannianMetric`
4068
+ for more examples.
4069
+ """
4070
+ vmodule = self.vector_field_module(dest_map)
4071
+ dim = vmodule.ambient_domain().dimension()
4072
+ return vmodule.metric(name, signature=dim, latex_name=latex_name)
4073
+
4074
+ def lorentzian_metric(self, name, signature='positive', latex_name=None,
4075
+ dest_map=None):
4076
+ r"""
4077
+ Define a Lorentzian metric on the manifold.
4078
+
4079
+ A *Lorentzian metric* is a field of nondegenerate symmetric bilinear
4080
+ forms acting in the tangent spaces, with signature `(-,+,\cdots,+)` or
4081
+ `(+,-,\cdots,-)`.
4082
+
4083
+ See
4084
+ :class:`~sage.manifolds.differentiable.metric.PseudoRiemannianMetric`
4085
+ for a complete documentation.
4086
+
4087
+ INPUT:
4088
+
4089
+ - ``name`` -- name given to the metric
4090
+ - ``signature`` -- (default: ``'positive'``) sign of the metric
4091
+ signature:
4092
+
4093
+ * if set to 'positive', the signature is n-2, where n is the
4094
+ manifold's dimension, i.e. `(-,+,\cdots,+)`
4095
+ * if set to 'negative', the signature is -n+2, i.e. `(+,-,\cdots,-)`
4096
+
4097
+ - ``latex_name`` -- (default: ``None``) LaTeX symbol to denote the
4098
+ metric; if ``None``, it is formed from ``name``
4099
+ - ``dest_map`` -- (default: ``None``) instance of
4100
+ class :class:`~sage.manifolds.differentiable.diff_map.DiffMap`
4101
+ representing the destination map `\Phi:\ U \rightarrow M`, where `U`
4102
+ is the current manifold; if ``None``, the identity map is assumed
4103
+ (case of a metric tensor field *on* `U`)
4104
+
4105
+ OUTPUT:
4106
+
4107
+ - instance of
4108
+ :class:`~sage.manifolds.differentiable.metric.PseudoRiemannianMetric`
4109
+ representing the defined Lorentzian metric.
4110
+
4111
+ EXAMPLES:
4112
+
4113
+ Metric of Minkowski spacetime::
4114
+
4115
+ sage: M = Manifold(4, 'M')
4116
+ sage: X.<t,x,y,z> = M.chart()
4117
+ sage: g = M.lorentzian_metric('g'); g
4118
+ Lorentzian metric g on the 4-dimensional differentiable manifold M
4119
+ sage: g[0,0], g[1,1], g[2,2], g[3,3] = -1, 1, 1, 1
4120
+ sage: g.display()
4121
+ g = -dt⊗dt + dx⊗dx + dy⊗dy + dz⊗dz
4122
+ sage: g.signature()
4123
+ 2
4124
+
4125
+ Choice of a negative signature::
4126
+
4127
+ sage: g = M.lorentzian_metric('g', signature='negative'); g
4128
+ Lorentzian metric g on the 4-dimensional differentiable manifold M
4129
+ sage: g[0,0], g[1,1], g[2,2], g[3,3] = 1, -1, -1, -1
4130
+ sage: g.display()
4131
+ g = dt⊗dt - dx⊗dx - dy⊗dy - dz⊗dz
4132
+ sage: g.signature()
4133
+ -2
4134
+ """
4135
+ vmodule = self.vector_field_module(dest_map)
4136
+ dim = vmodule.ambient_domain().dimension()
4137
+ if signature == 'positive':
4138
+ signat = dim - 2
4139
+ else:
4140
+ signat = 2 - dim
4141
+ return vmodule.metric(name, signature=signat, latex_name=latex_name)
4142
+
4143
+ def tangent_vector(self, *args, **kwargs):
4144
+ r"""
4145
+ Define a tangent vector at a given point of ``self``.
4146
+
4147
+ INPUT:
4148
+
4149
+ - ``point`` -- :class:`~sage.manifolds.point.ManifoldPoint`;
4150
+ point `p` on ``self``
4151
+ - ``comp`` -- components of the vector with respect to the basis
4152
+ specified by the argument ``basis``, either as an iterable or as a
4153
+ sequence of `n` components, `n` being the dimension of ``self`` (see
4154
+ examples below)
4155
+ - ``basis`` -- (default: ``None``)
4156
+ :class:`~sage.tensor.modules.free_module_basis.FreeModuleBasis`;
4157
+ basis of the tangent space at `p` with respect to which the
4158
+ components are defined; if ``None``, the default basis of the tangent
4159
+ space is used
4160
+ - ``name`` -- (default: ``None``) string; symbol given to the vector
4161
+ - ``latex_name`` -- (default: ``None``) string; LaTeX symbol to denote
4162
+ the vector; if ``None``, ``name`` will be used
4163
+
4164
+ OUTPUT:
4165
+
4166
+ - :class:`~sage.manifolds.differentiable.tangent_vector.TangentVector`
4167
+ representing the tangent vector at point `p`
4168
+
4169
+ EXAMPLES:
4170
+
4171
+ Vector at a point `p` of the Euclidean plane::
4172
+
4173
+ sage: E.<x,y>= EuclideanSpace()
4174
+ sage: p = E((1, 2), name='p')
4175
+ sage: v = E.tangent_vector(p, -1, 3, name='v'); v
4176
+ Vector v at Point p on the Euclidean plane E^2
4177
+ sage: v.display()
4178
+ v = -e_x + 3 e_y
4179
+ sage: v.parent()
4180
+ Tangent space at Point p on the Euclidean plane E^2
4181
+ sage: v in E.tangent_space(p)
4182
+ True
4183
+
4184
+ An alias of ``tangent_vector`` is ``vector``::
4185
+
4186
+ sage: v = E.vector(p, -1, 3, name='v'); v
4187
+ Vector v at Point p on the Euclidean plane E^2
4188
+
4189
+ The components can be passed as a tuple or a list::
4190
+
4191
+ sage: v1 = E.vector(p, (-1, 3)); v1
4192
+ Vector at Point p on the Euclidean plane E^2
4193
+ sage: v1 == v
4194
+ True
4195
+
4196
+ or as an object created by the ``vector`` function::
4197
+
4198
+ sage: v2 = E.vector(p, vector([-1, 3])); v2
4199
+ Vector at Point p on the Euclidean plane E^2
4200
+ sage: v2 == v
4201
+ True
4202
+
4203
+ Example of use with the options ``basis`` and ``latex_name``::
4204
+
4205
+ sage: polar_basis = E.polar_frame().at(p)
4206
+ sage: polar_basis
4207
+ Basis (e_r,e_ph) on the Tangent space at Point p on the Euclidean plane E^2
4208
+ sage: v = E.vector(p, 2, -1, basis=polar_basis, name='v',
4209
+ ....: latex_name=r'\vec{v}')
4210
+ sage: v
4211
+ Vector v at Point p on the Euclidean plane E^2
4212
+ sage: v.display(polar_basis)
4213
+ v = 2 e_r - e_ph
4214
+ sage: v.display()
4215
+ v = 4/5*sqrt(5) e_x + 3/5*sqrt(5) e_y
4216
+ sage: latex(v)
4217
+ \vec{v}
4218
+
4219
+ TESTS::
4220
+
4221
+ sage: E.vector(-1, 3)
4222
+ Traceback (most recent call last):
4223
+ ...
4224
+ TypeError: -1 is not a manifold point
4225
+ sage: E.vector([-1, 3])
4226
+ Traceback (most recent call last):
4227
+ ...
4228
+ TypeError: a point and a set of components must be provided
4229
+ sage: E.vector(p, 4, 2, 1)
4230
+ Traceback (most recent call last):
4231
+ ...
4232
+ ValueError: 2 components must be provided
4233
+ """
4234
+ basis = kwargs.pop('basis', None)
4235
+ name = kwargs.pop('name', None)
4236
+ latex_name = kwargs.pop('latex_name', None)
4237
+ if len(args) < 2:
4238
+ raise TypeError("a point and a set of components must be provided")
4239
+ point = args[0]
4240
+ tspace = self.tangent_space(point) # checks on point are performed here
4241
+ comp0 = args[1]
4242
+ if hasattr(comp0, '__len__') and hasattr(comp0, '__getitem__'):
4243
+ # comp0 is a list/vector of components
4244
+ comp = comp0
4245
+ else:
4246
+ # the components are provided as args[1], args[2], ..., args[dim]
4247
+ dim = self._dim
4248
+ if len(args) != dim + 1:
4249
+ raise ValueError(f"{dim} components must be provided")
4250
+ comp = args[1:dim + 1]
4251
+ return tspace._element_constructor_(comp=comp, basis=basis, name=name,
4252
+ latex_name=latex_name)
4253
+
4254
+ vector = tangent_vector