passagemath-symbolics 10.6.43__cp314-cp314t-musllinux_1_2_x86_64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of passagemath-symbolics might be problematic. Click here for more details.

Files changed (171) hide show
  1. passagemath_symbolics/__init__.py +3 -0
  2. passagemath_symbolics-10.6.43.dist-info/METADATA +187 -0
  3. passagemath_symbolics-10.6.43.dist-info/RECORD +171 -0
  4. passagemath_symbolics-10.6.43.dist-info/WHEEL +5 -0
  5. passagemath_symbolics-10.6.43.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 +2826 -0
  9. sage/calculus/desolvers.py +1866 -0
  10. sage/calculus/predefined.py +51 -0
  11. sage/calculus/tests.py +225 -0
  12. sage/calculus/var.cpython-314t-x86_64-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-x86_64-linux-musl.so +0 -0
  18. sage/dynamics/complex_dynamics/mandel_julia_helper.pyx +1035 -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 +743 -0
  33. sage/geometry/hyperbolic_space/hyperbolic_constants.py +5 -0
  34. sage/geometry/hyperbolic_space/hyperbolic_geodesic.py +2409 -0
  35. sage/geometry/hyperbolic_space/hyperbolic_interface.py +206 -0
  36. sage/geometry/hyperbolic_space/hyperbolic_isometry.py +1082 -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 +3017 -0
  44. sage/interfaces/magma_free.py +92 -0
  45. sage/interfaces/maple.py +1397 -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 +555 -0
  54. sage/manifolds/catalog.py +437 -0
  55. sage/manifolds/chart.py +4019 -0
  56. sage/manifolds/chart_func.py +3419 -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 +1671 -0
  70. sage/manifolds/differentiable/diff_form.py +1658 -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 +1520 -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 +910 -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 +1728 -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 +2764 -0
  118. sage/manifolds/subsets/all.py +1 -0
  119. sage/manifolds/subsets/closure.py +131 -0
  120. sage/manifolds/subsets/pullback.py +885 -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 +1342 -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-x86_64-linux-musl.so +0 -0
  129. sage/matrix/matrix_symbolic_dense.pxd +6 -0
  130. sage/matrix/matrix_symbolic_dense.pyx +1022 -0
  131. sage/matrix/matrix_symbolic_sparse.cpython-314t-x86_64-linux-musl.so +0 -0
  132. sage/matrix/matrix_symbolic_sparse.pxd +6 -0
  133. sage/matrix/matrix_symbolic_sparse.pyx +1029 -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 +4153 -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 +5237 -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 +985 -0
  150. sage/symbolic/benchmark.py +93 -0
  151. sage/symbolic/callable.py +459 -0
  152. sage/symbolic/complexity_measures.py +35 -0
  153. sage/symbolic/constants.py +1287 -0
  154. sage/symbolic/expression_conversion_algebraic.py +310 -0
  155. sage/symbolic/expression_conversion_sympy.py +317 -0
  156. sage/symbolic/expression_conversions.py +1713 -0
  157. sage/symbolic/function_factory.py +355 -0
  158. sage/symbolic/integration/all.py +1 -0
  159. sage/symbolic/integration/external.py +270 -0
  160. sage/symbolic/integration/integral.py +1115 -0
  161. sage/symbolic/maxima_wrapper.py +162 -0
  162. sage/symbolic/operators.py +267 -0
  163. sage/symbolic/random_tests.py +462 -0
  164. sage/symbolic/relation.py +1907 -0
  165. sage/symbolic/ring.cpython-314t-x86_64-linux-musl.so +0 -0
  166. sage/symbolic/ring.pxd +5 -0
  167. sage/symbolic/ring.pyx +1396 -0
  168. sage/symbolic/subring.py +1025 -0
  169. sage/symbolic/symengine.py +19 -0
  170. sage/symbolic/tests.py +40 -0
  171. sage/symbolic/units.py +1470 -0
@@ -0,0 +1,1343 @@
1
+ # sage_setup: distribution = sagemath-symbolics
2
+ r"""
3
+ Differentiable Scalar Fields
4
+
5
+ Given a differentiable manifold `M` of class `C^k` over a topological field `K`
6
+ (in most applications, `K = \RR` or `K = \CC`), a *differentiable scalar field*
7
+ on `M` is a map
8
+
9
+ .. MATH::
10
+
11
+ f: M \longrightarrow K
12
+
13
+ of class `C^k`.
14
+
15
+ Differentiable scalar fields are implemented by the class
16
+ :class:`DiffScalarField`.
17
+
18
+ AUTHORS:
19
+
20
+ - Eric Gourgoulhon, Michal Bejger (2013-2015): initial version
21
+ - Eric Gourgoulhon (2018): operators gradient, Laplacian and d'Alembertian
22
+
23
+ REFERENCES:
24
+
25
+ - [KN1963]_
26
+ - [Lee2013]_
27
+ - [ONe1983]_
28
+ """
29
+
30
+ #******************************************************************************
31
+ # Copyright (C) 2015, 2018 Eric Gourgoulhon <eric.gourgoulhon@obspm.fr>
32
+ # Copyright (C) 2015 Michal Bejger <bejger@camk.edu.pl>
33
+ #
34
+ # Distributed under the terms of the GNU General Public License (GPL)
35
+ # as published by the Free Software Foundation; either version 2 of
36
+ # the License, or (at your option) any later version.
37
+ # http://www.gnu.org/licenses/
38
+ #******************************************************************************
39
+
40
+ from __future__ import annotations
41
+
42
+ from typing import TYPE_CHECKING, Union
43
+
44
+ from sage.manifolds.scalarfield import ScalarField
45
+
46
+ if TYPE_CHECKING:
47
+ from sage.manifolds.differentiable.diff_form import DiffForm
48
+ from sage.manifolds.differentiable.metric import PseudoRiemannianMetric
49
+ from sage.manifolds.differentiable.symplectic_form import SymplecticForm
50
+
51
+
52
+ class DiffScalarField(ScalarField):
53
+ r"""
54
+ Differentiable scalar field on a differentiable manifold.
55
+
56
+ Given a differentiable manifold `M` of class `C^k` over a topological field
57
+ `K` (in most applications, `K = \RR` or `K = \CC`), a *differentiable
58
+ scalar field* defined on `M` is a map
59
+
60
+ .. MATH::
61
+
62
+ f: M \longrightarrow K
63
+
64
+ that is `k`-times continuously differentiable.
65
+
66
+ The class :class:`DiffScalarField` is a Sage *element* class, whose
67
+ *parent* class is
68
+ :class:`~sage.manifolds.differentiable.scalarfield_algebra.DiffScalarFieldAlgebra`.
69
+ It inherits from the class :class:`~sage.manifolds.scalarfield.ScalarField`
70
+ devoted to generic continuous scalar fields on topological manifolds.
71
+
72
+ INPUT:
73
+
74
+ - ``parent`` -- the algebra of scalar fields containing the scalar field
75
+ (must be an instance of class
76
+ :class:`~sage.manifolds.differentiable.scalarfield_algebra.DiffScalarFieldAlgebra`)
77
+ - ``coord_expression`` -- (default: ``None``) coordinate expression(s) of
78
+ the scalar field; this can be either
79
+
80
+ - a dictionary of coordinate expressions in various charts on the domain,
81
+ with the charts as keys;
82
+ - a single coordinate expression; if the argument ``chart`` is
83
+ ``'all'``, this expression is set to all the charts defined
84
+ on the open set; otherwise, the expression is set in the
85
+ specific chart provided by the argument ``chart``
86
+
87
+ NB: If ``coord_expression`` is ``None`` or incomplete, coordinate
88
+ expressions can be added after the creation of the object, by means of
89
+ the methods
90
+ :meth:`~sage.manifolds.scalarfield.ScalarField.add_expr`,
91
+ :meth:`~sage.manifolds.scalarfield.ScalarField.add_expr_by_continuation`
92
+ and :meth:`~sage.manifolds.scalarfield.ScalarField.set_expr`
93
+ - ``chart`` -- (default: ``None``) chart defining the coordinates used
94
+ in ``coord_expression`` when the latter is a single coordinate
95
+ expression; if none is provided (default), the default chart of the
96
+ open set is assumed. If ``chart=='all'``, ``coord_expression`` is
97
+ assumed to be independent of the chart (constant scalar field).
98
+ - ``name`` -- (default: ``None``) string; name (symbol) given to the
99
+ scalar field
100
+ - ``latex_name`` -- (default: ``None``) string; LaTeX symbol to denote the
101
+ scalar field; if none is provided, the LaTeX symbol is set to ``name``
102
+
103
+ EXAMPLES:
104
+
105
+ A scalar field on the 2-sphere::
106
+
107
+ sage: M = Manifold(2, 'M') # the 2-dimensional sphere S^2
108
+ sage: U = M.open_subset('U') # complement of the North pole
109
+ sage: c_xy.<x,y> = U.chart() # stereographic coordinates from the North pole
110
+ sage: V = M.open_subset('V') # complement of the South pole
111
+ sage: c_uv.<u,v> = V.chart() # stereographic coordinates from the South pole
112
+ sage: M.declare_union(U,V) # S^2 is the union of U and V
113
+ sage: xy_to_uv = c_xy.transition_map(c_uv, (x/(x^2+y^2), y/(x^2+y^2)),
114
+ ....: intersection_name='W',
115
+ ....: restrictions1= x^2+y^2!=0,
116
+ ....: restrictions2= u^2+v^2!=0)
117
+ sage: uv_to_xy = xy_to_uv.inverse()
118
+ sage: f = M.scalar_field({c_xy: 1/(1+x^2+y^2), c_uv: (u^2+v^2)/(1+u^2+v^2)},
119
+ ....: name='f') ; f
120
+ Scalar field f on the 2-dimensional differentiable manifold M
121
+ sage: f.display()
122
+ f: M → ℝ
123
+ on U: (x, y) ↦ 1/(x^2 + y^2 + 1)
124
+ on V: (u, v) ↦ (u^2 + v^2)/(u^2 + v^2 + 1)
125
+
126
+ For scalar fields defined by a single coordinate expression, the latter
127
+ can be passed instead of the dictionary over the charts::
128
+
129
+ sage: g = U.scalar_field(x*y, chart=c_xy, name='g') ; g
130
+ Scalar field g on the Open subset U of the 2-dimensional differentiable
131
+ manifold M
132
+
133
+ The above is indeed equivalent to::
134
+
135
+ sage: g = U.scalar_field({c_xy: x*y}, name='g') ; g
136
+ Scalar field g on the Open subset U of the 2-dimensional differentiable
137
+ manifold M
138
+
139
+ Since ``c_xy`` is the default chart of ``U``, the argument ``chart`` can
140
+ be skipped::
141
+
142
+ sage: g = U.scalar_field(x*y, name='g') ; g
143
+ Scalar field g on the Open subset U of the 2-dimensional differentiable
144
+ manifold M
145
+
146
+ The scalar field `g` is defined on `U` and has an expression in terms of
147
+ the coordinates `(u,v)` on `W=U\cap V`::
148
+
149
+ sage: g.display()
150
+ g: U → ℝ
151
+ (x, y) ↦ x*y
152
+ on W: (u, v) ↦ u*v/(u^4 + 2*u^2*v^2 + v^4)
153
+
154
+ Scalar fields on `M` can also be declared with a single chart::
155
+
156
+ sage: f = M.scalar_field(1/(1+x^2+y^2), chart=c_xy, name='f') ; f
157
+ Scalar field f on the 2-dimensional differentiable manifold M
158
+
159
+ Their definition must then be completed by providing the expressions on
160
+ other charts, via the method
161
+ :meth:`~sage.manifolds.scalarfield.ScalarField.add_expr`, to get a global
162
+ cover of the manifold::
163
+
164
+ sage: f.add_expr((u^2+v^2)/(1+u^2+v^2), chart=c_uv)
165
+ sage: f.display()
166
+ f: M → ℝ
167
+ on U: (x, y) ↦ 1/(x^2 + y^2 + 1)
168
+ on V: (u, v) ↦ (u^2 + v^2)/(u^2 + v^2 + 1)
169
+
170
+ We can even first declare the scalar field without any coordinate
171
+ expression and provide them subsequently::
172
+
173
+ sage: f = M.scalar_field(name='f')
174
+ sage: f.add_expr(1/(1+x^2+y^2), chart=c_xy)
175
+ sage: f.add_expr((u^2+v^2)/(1+u^2+v^2), chart=c_uv)
176
+ sage: f.display()
177
+ f: M → ℝ
178
+ on U: (x, y) ↦ 1/(x^2 + y^2 + 1)
179
+ on V: (u, v) ↦ (u^2 + v^2)/(u^2 + v^2 + 1)
180
+
181
+ We may also use the method
182
+ :meth:`~sage.manifolds.scalarfield.ScalarField.add_expr_by_continuation`
183
+ to complete the coordinate definition using the analytic continuation from
184
+ domains in which charts overlap::
185
+
186
+ sage: f = M.scalar_field(1/(1+x^2+y^2), chart=c_xy, name='f') ; f
187
+ Scalar field f on the 2-dimensional differentiable manifold M
188
+ sage: f.add_expr_by_continuation(c_uv, U.intersection(V))
189
+ sage: f.display()
190
+ f: M → ℝ
191
+ on U: (x, y) ↦ 1/(x^2 + y^2 + 1)
192
+ on V: (u, v) ↦ (u^2 + v^2)/(u^2 + v^2 + 1)
193
+
194
+ A scalar field can also be defined by some unspecified function of the
195
+ coordinates::
196
+
197
+ sage: h = U.scalar_field(function('H')(x, y), name='h') ; h
198
+ Scalar field h on the Open subset U of the 2-dimensional differentiable
199
+ manifold M
200
+ sage: h.display()
201
+ h: U → ℝ
202
+ (x, y) ↦ H(x, y)
203
+ on W: (u, v) ↦ H(u/(u^2 + v^2), v/(u^2 + v^2))
204
+
205
+ We may use the argument ``latex_name`` to specify the LaTeX symbol denoting
206
+ the scalar field if the latter is different from ``name``::
207
+
208
+ sage: latex(f)
209
+ f
210
+ sage: f = M.scalar_field({c_xy: 1/(1+x^2+y^2), c_uv: (u^2+v^2)/(1+u^2+v^2)},
211
+ ....: name='f', latex_name=r'\mathcal{F}')
212
+ sage: latex(f)
213
+ \mathcal{F}
214
+
215
+ The coordinate expression in a given chart is obtained via the method
216
+ :meth:`~sage.manifolds.scalarfield.ScalarField.expr`, which returns a
217
+ symbolic expression::
218
+
219
+ sage: f.expr(c_uv)
220
+ (u^2 + v^2)/(u^2 + v^2 + 1)
221
+ sage: type(f.expr(c_uv))
222
+ <class 'sage.symbolic.expression.Expression'>
223
+
224
+ The method :meth:`~sage.manifolds.scalarfield.ScalarField.coord_function`
225
+ returns instead a function of the chart coordinates, i.e. an instance of
226
+ :class:`~sage.manifolds.chart_func.ChartFunction`::
227
+
228
+ sage: f.coord_function(c_uv)
229
+ (u^2 + v^2)/(u^2 + v^2 + 1)
230
+ sage: type(f.coord_function(c_uv))
231
+ <class 'sage.manifolds.chart_func.ChartFunctionRing_with_category.element_class'>
232
+ sage: f.coord_function(c_uv).display()
233
+ (u, v) ↦ (u^2 + v^2)/(u^2 + v^2 + 1)
234
+
235
+ The value returned by the method
236
+ :meth:`~sage.manifolds.scalarfield.ScalarField.expr`
237
+ is actually the coordinate expression of the chart function::
238
+
239
+ sage: f.expr(c_uv) is f.coord_function(c_uv).expr()
240
+ True
241
+
242
+ A constant scalar field is declared by setting the argument ``chart`` to
243
+ ``'all'``::
244
+
245
+ sage: c = M.scalar_field(2, chart='all', name='c') ; c
246
+ Scalar field c on the 2-dimensional differentiable manifold M
247
+ sage: c.display()
248
+ c: M → ℝ
249
+ on U: (x, y) ↦ 2
250
+ on V: (u, v) ↦ 2
251
+
252
+ A shortcut is to use the method
253
+ :meth:`~sage.manifolds.manifold.TopologicalManifold.constant_scalar_field`::
254
+
255
+ sage: c == M.constant_scalar_field(2)
256
+ True
257
+
258
+ The constant value can be some unspecified parameter::
259
+
260
+ sage: var('a')
261
+ a
262
+ sage: c = M.constant_scalar_field(a, name='c') ; c
263
+ Scalar field c on the 2-dimensional differentiable manifold M
264
+ sage: c.display()
265
+ c: M → ℝ
266
+ on U: (x, y) ↦ a
267
+ on V: (u, v) ↦ a
268
+
269
+ A special case of constant field is the zero scalar field::
270
+
271
+ sage: zer = M.constant_scalar_field(0) ; zer
272
+ Scalar field zero on the 2-dimensional differentiable manifold M
273
+ sage: zer.display()
274
+ zero: M → ℝ
275
+ on U: (x, y) ↦ 0
276
+ on V: (u, v) ↦ 0
277
+
278
+ It can be obtained directly by means of the function
279
+ :meth:`~sage.manifolds.manifold.TopologicalManifold.zero_scalar_field`::
280
+
281
+ sage: zer is M.zero_scalar_field()
282
+ True
283
+
284
+ A third way is to get it as the zero element of the algebra `C^k(M)`
285
+ of scalar fields on `M` (see below)::
286
+
287
+ sage: zer is M.scalar_field_algebra().zero()
288
+ True
289
+
290
+ By definition, a scalar field acts on the manifold's points, sending
291
+ them to elements of the manifold's base field (real numbers in the
292
+ present case)::
293
+
294
+ sage: N = M.point((0,0), chart=c_uv) # the North pole
295
+ sage: S = M.point((0,0), chart=c_xy) # the South pole
296
+ sage: E = M.point((1,0), chart=c_xy) # a point at the equator
297
+ sage: f(N)
298
+ 0
299
+ sage: f(S)
300
+ 1
301
+ sage: f(E)
302
+ 1/2
303
+ sage: h(E)
304
+ H(1, 0)
305
+ sage: c(E)
306
+ a
307
+ sage: zer(E)
308
+ 0
309
+
310
+ A scalar field can be compared to another scalar field::
311
+
312
+ sage: f == g
313
+ False
314
+
315
+ ...to a symbolic expression::
316
+
317
+ sage: f == x*y
318
+ False
319
+ sage: g == x*y
320
+ True
321
+ sage: c == a
322
+ True
323
+
324
+ ...to a number::
325
+
326
+ sage: f == 2
327
+ False
328
+ sage: zer == 0
329
+ True
330
+
331
+ ...to anything else::
332
+
333
+ sage: f == M
334
+ False
335
+
336
+ Standard mathematical functions are implemented::
337
+
338
+ sage: sqrt(f)
339
+ Scalar field sqrt(f) on the 2-dimensional differentiable manifold M
340
+ sage: sqrt(f).display()
341
+ sqrt(f): M → ℝ
342
+ on U: (x, y) ↦ 1/sqrt(x^2 + y^2 + 1)
343
+ on V: (u, v) ↦ sqrt(u^2 + v^2)/sqrt(u^2 + v^2 + 1)
344
+
345
+ ::
346
+
347
+ sage: tan(f)
348
+ Scalar field tan(f) on the 2-dimensional differentiable manifold M
349
+ sage: tan(f).display()
350
+ tan(f): M → ℝ
351
+ on U: (x, y) ↦ sin(1/(x^2 + y^2 + 1))/cos(1/(x^2 + y^2 + 1))
352
+ on V: (u, v) ↦ sin((u^2 + v^2)/(u^2 + v^2 + 1))/cos((u^2 + v^2)/(u^2 + v^2 + 1))
353
+
354
+ .. RUBRIC:: Arithmetics of scalar fields
355
+
356
+ Scalar fields on `M` (resp. `U`) belong to the algebra `C^k(M)`
357
+ (resp. `C^k(U)`)::
358
+
359
+ sage: f.parent()
360
+ Algebra of differentiable scalar fields on the 2-dimensional
361
+ differentiable manifold M
362
+ sage: f.parent() is M.scalar_field_algebra()
363
+ True
364
+ sage: g.parent()
365
+ Algebra of differentiable scalar fields on the Open subset U of the
366
+ 2-dimensional differentiable manifold M
367
+ sage: g.parent() is U.scalar_field_algebra()
368
+ True
369
+
370
+ Consequently, scalar fields can be added::
371
+
372
+ sage: s = f + c ; s
373
+ Scalar field f+c on the 2-dimensional differentiable manifold M
374
+ sage: s.display()
375
+ f+c: M → ℝ
376
+ on U: (x, y) ↦ (a*x^2 + a*y^2 + a + 1)/(x^2 + y^2 + 1)
377
+ on V: (u, v) ↦ ((a + 1)*u^2 + (a + 1)*v^2 + a)/(u^2 + v^2 + 1)
378
+
379
+ and subtracted::
380
+
381
+ sage: s = f - c ; s
382
+ Scalar field f-c on the 2-dimensional differentiable manifold M
383
+ sage: s.display()
384
+ f-c: M → ℝ
385
+ on U: (x, y) ↦ -(a*x^2 + a*y^2 + a - 1)/(x^2 + y^2 + 1)
386
+ on V: (u, v) ↦ -((a - 1)*u^2 + (a - 1)*v^2 + a)/(u^2 + v^2 + 1)
387
+
388
+ Some tests::
389
+
390
+ sage: f + zer == f
391
+ True
392
+ sage: f - f == zer
393
+ True
394
+ sage: f + (-f) == zer
395
+ True
396
+ sage: (f+c)-f == c
397
+ True
398
+ sage: (f-c)+c == f
399
+ True
400
+
401
+ We may add a number (interpreted as a constant scalar field) to a scalar
402
+ field::
403
+
404
+ sage: s = f + 1 ; s
405
+ Scalar field f+1 on the 2-dimensional differentiable manifold M
406
+ sage: s.display()
407
+ f+1: M → ℝ
408
+ on U: (x, y) ↦ (x^2 + y^2 + 2)/(x^2 + y^2 + 1)
409
+ on V: (u, v) ↦ (2*u^2 + 2*v^2 + 1)/(u^2 + v^2 + 1)
410
+ sage: (f+1)-1 == f
411
+ True
412
+
413
+ The number can represented by a symbolic variable::
414
+
415
+ sage: s = a + f ; s
416
+ Scalar field on the 2-dimensional differentiable manifold M
417
+ sage: s == c + f
418
+ True
419
+
420
+ However if the symbolic variable is a chart coordinate, the addition
421
+ is performed only on the chart domain::
422
+
423
+ sage: s = f + x; s
424
+ Scalar field on the 2-dimensional differentiable manifold M
425
+ sage: s.display()
426
+ M → ℝ
427
+ on U: (x, y) ↦ (x^3 + x*y^2 + x + 1)/(x^2 + y^2 + 1)
428
+ on W: (u, v) ↦ (u^4 + v^4 + u^3 + (2*u^2 + u)*v^2 + u)/(u^4 + v^4 + (2*u^2 + 1)*v^2 + u^2)
429
+ sage: s = f + u; s
430
+ Scalar field on the 2-dimensional differentiable manifold M
431
+ sage: s.display()
432
+ M → ℝ
433
+ on W: (x, y) ↦ (x^3 + (x + 1)*y^2 + x^2 + x)/(x^4 + y^4 + (2*x^2 + 1)*y^2 + x^2)
434
+ on V: (u, v) ↦ (u^3 + (u + 1)*v^2 + u^2 + u)/(u^2 + v^2 + 1)
435
+
436
+ The addition of two scalar fields with different domains is possible if
437
+ the domain of one of them is a subset of the domain of the other; the
438
+ domain of the result is then this subset::
439
+
440
+ sage: f.domain()
441
+ 2-dimensional differentiable manifold M
442
+ sage: g.domain()
443
+ Open subset U of the 2-dimensional differentiable manifold M
444
+ sage: s = f + g ; s
445
+ Scalar field f+g on the Open subset U of the 2-dimensional
446
+ differentiable manifold M
447
+ sage: s.domain()
448
+ Open subset U of the 2-dimensional differentiable manifold M
449
+ sage: s.display()
450
+ f+g: U → ℝ
451
+ (x, y) ↦ (x*y^3 + (x^3 + x)*y + 1)/(x^2 + y^2 + 1)
452
+ on W: (u, v) ↦ (u^6 + 3*u^4*v^2 + 3*u^2*v^4 + v^6 + u*v^3
453
+ + (u^3 + u)*v)/(u^6 + v^6 + (3*u^2 + 1)*v^4 + u^4 + (3*u^4 + 2*u^2)*v^2)
454
+
455
+ The operation actually performed is `f|_U + g`::
456
+
457
+ sage: s == f.restrict(U) + g
458
+ True
459
+
460
+ In Sage framework, the addition of `f` and `g` is permitted because
461
+ there is a *coercion* of the parent of `f`, namely `C^k(M)`, to
462
+ the parent of `g`, namely `C^k(U)` (see
463
+ :class:`~sage.manifolds.differentiable.scalarfield_algebra.DiffScalarFieldAlgebra`)::
464
+
465
+ sage: CM = M.scalar_field_algebra()
466
+ sage: CU = U.scalar_field_algebra()
467
+ sage: CU.has_coerce_map_from(CM)
468
+ True
469
+
470
+ The coercion map is nothing but the restriction to domain `U`::
471
+
472
+ sage: CU.coerce(f) == f.restrict(U)
473
+ True
474
+
475
+ Since the algebra `C^k(M)` is a vector space over `\RR`, scalar fields
476
+ can be multiplied by a number, either an explicit one::
477
+
478
+ sage: s = 2*f ; s
479
+ Scalar field on the 2-dimensional differentiable manifold M
480
+ sage: s.display()
481
+ M → ℝ
482
+ on U: (x, y) ↦ 2/(x^2 + y^2 + 1)
483
+ on V: (u, v) ↦ 2*(u^2 + v^2)/(u^2 + v^2 + 1)
484
+
485
+ or a symbolic one::
486
+
487
+ sage: s = a*f ; s
488
+ Scalar field on the 2-dimensional differentiable manifold M
489
+ sage: s.display()
490
+ M → ℝ
491
+ on U: (x, y) ↦ a/(x^2 + y^2 + 1)
492
+ on V: (u, v) ↦ (u^2 + v^2)*a/(u^2 + v^2 + 1)
493
+
494
+ However, if the symbolic variable is a chart coordinate, the multiplication
495
+ is performed only in the corresponding chart::
496
+
497
+ sage: s = x*f; s
498
+ Scalar field on the 2-dimensional differentiable manifold M
499
+ sage: s.display()
500
+ M → ℝ
501
+ on U: (x, y) ↦ x/(x^2 + y^2 + 1)
502
+ on W: (u, v) ↦ u/(u^2 + v^2 + 1)
503
+ sage: s = u*f; s
504
+ Scalar field on the 2-dimensional differentiable manifold M
505
+ sage: s.display()
506
+ M → ℝ
507
+ on W: (x, y) ↦ x/(x^4 + y^4 + (2*x^2 + 1)*y^2 + x^2)
508
+ on V: (u, v) ↦ (u^2 + v^2)*u/(u^2 + v^2 + 1)
509
+
510
+ Some tests::
511
+
512
+ sage: 0*f == 0
513
+ True
514
+ sage: 0*f == zer
515
+ True
516
+ sage: 1*f == f
517
+ True
518
+ sage: (-2)*f == - f - f
519
+ True
520
+
521
+ The ring multiplication of the algebras `C^k(M)` and `C^k(U)`
522
+ is the pointwise multiplication of functions::
523
+
524
+ sage: s = f*f ; s
525
+ Scalar field f*f on the 2-dimensional differentiable manifold M
526
+ sage: s.display()
527
+ f*f: M → ℝ
528
+ on U: (x, y) ↦ 1/(x^4 + y^4 + 2*(x^2 + 1)*y^2 + 2*x^2 + 1)
529
+ on V: (u, v) ↦ (u^4 + 2*u^2*v^2 + v^4)/(u^4 + v^4 + 2*(u^2 + 1)*v^2 + 2*u^2 + 1)
530
+ sage: s = g*h ; s
531
+ Scalar field g*h on the Open subset U of the 2-dimensional
532
+ differentiable manifold M
533
+ sage: s.display()
534
+ g*h: U → ℝ
535
+ (x, y) ↦ x*y*H(x, y)
536
+ on W: (u, v) ↦ u*v*H(u/(u^2 + v^2), v/(u^2 + v^2))/(u^4 + 2*u^2*v^2 + v^4)
537
+
538
+ Thanks to the coercion `C^k(M)\rightarrow C^k(U)` mentioned
539
+ above, it is possible to multiply a scalar field defined on `M` by a
540
+ scalar field defined on `U`, the result being a scalar field defined on
541
+ `U`::
542
+
543
+ sage: f.domain(), g.domain()
544
+ (2-dimensional differentiable manifold M,
545
+ Open subset U of the 2-dimensional differentiable manifold M)
546
+ sage: s = f*g ; s
547
+ Scalar field f*g on the Open subset U of the 2-dimensional
548
+ differentiable manifold M
549
+ sage: s.display()
550
+ f*g: U → ℝ
551
+ (x, y) ↦ x*y/(x^2 + y^2 + 1)
552
+ on W: (u, v) ↦ u*v/(u^4 + v^4 + (2*u^2 + 1)*v^2 + u^2)
553
+ sage: s == f.restrict(U)*g
554
+ True
555
+
556
+ Scalar fields can be divided (pointwise division)::
557
+
558
+ sage: s = f/c ; s
559
+ Scalar field f/c on the 2-dimensional differentiable manifold M
560
+ sage: s.display()
561
+ f/c: M → ℝ
562
+ on U: (x, y) ↦ 1/(a*x^2 + a*y^2 + a)
563
+ on V: (u, v) ↦ (u^2 + v^2)/(a*u^2 + a*v^2 + a)
564
+ sage: s = g/h ; s
565
+ Scalar field g/h on the Open subset U of the 2-dimensional
566
+ differentiable manifold M
567
+ sage: s.display()
568
+ g/h: U → ℝ
569
+ (x, y) ↦ x*y/H(x, y)
570
+ on W: (u, v) ↦ u*v/((u^4 + 2*u^2*v^2 + v^4)*H(u/(u^2 + v^2), v/(u^2 + v^2)))
571
+ sage: s = f/g ; s
572
+ Scalar field f/g on the Open subset U of the 2-dimensional
573
+ differentiable manifold M
574
+ sage: s.display()
575
+ f/g: U → ℝ
576
+ (x, y) ↦ 1/(x*y^3 + (x^3 + x)*y)
577
+ on W: (u, v) ↦ (u^6 + 3*u^4*v^2 + 3*u^2*v^4 + v^6)/(u*v^3 + (u^3 + u)*v)
578
+ sage: s == f.restrict(U)/g
579
+ True
580
+
581
+ For scalar fields defined on a single chart domain, we may perform some
582
+ arithmetics with symbolic expressions involving the chart coordinates::
583
+
584
+ sage: s = g + x^2 - y ; s
585
+ Scalar field on the Open subset U of the 2-dimensional differentiable
586
+ manifold M
587
+ sage: s.display()
588
+ U → ℝ
589
+ (x, y) ↦ x^2 + (x - 1)*y
590
+ on W: (u, v) ↦ -(v^3 - u^2 + (u^2 - u)*v)/(u^4 + 2*u^2*v^2 + v^4)
591
+
592
+ ::
593
+
594
+ sage: s = g*x ; s
595
+ Scalar field on the Open subset U of the 2-dimensional differentiable
596
+ manifold M
597
+ sage: s.display()
598
+ U → ℝ
599
+ (x, y) ↦ x^2*y
600
+ on W: (u, v) ↦ u^2*v/(u^6 + 3*u^4*v^2 + 3*u^2*v^4 + v^6)
601
+
602
+ ::
603
+
604
+ sage: s = g/x ; s
605
+ Scalar field on the Open subset U of the 2-dimensional differentiable
606
+ manifold M
607
+ sage: s.display()
608
+ U → ℝ
609
+ (x, y) ↦ y
610
+ on W: (u, v) ↦ v/(u^2 + v^2)
611
+ sage: s = x/g ; s
612
+ Scalar field on the Open subset U of the 2-dimensional differentiable
613
+ manifold M
614
+ sage: s.display()
615
+ U → ℝ
616
+ (x, y) ↦ 1/y
617
+ on W: (u, v) ↦ (u^2 + v^2)/v
618
+
619
+ The test suite is passed::
620
+
621
+ sage: TestSuite(f).run()
622
+ sage: TestSuite(zer).run()
623
+ """
624
+ def __init__(self, parent, coord_expression=None, chart=None, name=None,
625
+ latex_name=None):
626
+ r"""
627
+ Construct a scalar field.
628
+
629
+ TESTS::
630
+
631
+ sage: M = Manifold(2, 'M')
632
+ sage: X.<x,y> = M.chart()
633
+ sage: f = M.scalar_field({X: x+y}, name='f') ; f
634
+ Scalar field f on the 2-dimensional differentiable manifold M
635
+ sage: from sage.manifolds.scalarfield import ScalarField
636
+ sage: isinstance(f, ScalarField)
637
+ True
638
+ sage: f.parent()
639
+ Algebra of differentiable scalar fields on the 2-dimensional
640
+ differentiable manifold M
641
+ sage: TestSuite(f).run()
642
+ """
643
+ ScalarField.__init__(self, parent, coord_expression=coord_expression,
644
+ chart=chart, name=name, latex_name=latex_name)
645
+ self._tensor_type = (0,0)
646
+ self._tensor_rank = 0
647
+
648
+ ####### Required methods for an algebra element (beside arithmetic) #######
649
+
650
+ def _init_derived(self):
651
+ r"""
652
+ Initialize the derived quantities.
653
+
654
+ TESTS::
655
+
656
+ sage: M = Manifold(2, 'M')
657
+ sage: X.<x,y> = M.chart()
658
+ sage: f = M.scalar_field({X: x+y})
659
+ sage: f._init_derived()
660
+ """
661
+ ScalarField._init_derived(self) # derived quantities of the parent class
662
+ self._differential = None # differential 1-form of the scalar field
663
+ self._lie_derivatives = {} # dict. of Lie derivatives of self, (keys: id(vector))
664
+
665
+ def _del_derived(self):
666
+ r"""
667
+ Delete the derived quantities.
668
+
669
+ TESTS::
670
+
671
+ sage: M = Manifold(2, 'M')
672
+ sage: X.<x,y> = M.chart()
673
+ sage: f = M.scalar_field({X: x+y})
674
+ sage: U = M.open_subset('U', coord_def={X: x>0})
675
+ sage: f.restrict(U)
676
+ Scalar field on the Open subset U of the 2-dimensional
677
+ differentiable manifold M
678
+ sage: f._restrictions
679
+ {Open subset U of the 2-dimensional differentiable manifold M:
680
+ Scalar field on the Open subset U of the 2-dimensional
681
+ differentiable manifold M}
682
+ sage: f._del_derived()
683
+ sage: f._restrictions # restrictions are derived quantities
684
+ {}
685
+ """
686
+ ScalarField._del_derived(self) # derived quantities of the mother class
687
+ self._differential = None # reset of the differential
688
+ # First deletes any reference to self in the vectors' dictionaries:
689
+ for val in self._lie_derivatives.values():
690
+ del val[0]._lie_der_along_self[id(self)]
691
+ # Then clears the dictionary of Lie derivatives
692
+ self._lie_derivatives.clear()
693
+
694
+ def tensor_type(self):
695
+ r"""
696
+ Return the tensor type of ``self``, when the latter is considered
697
+ as a tensor field on the manifold. This is always `(0, 0)`.
698
+
699
+ OUTPUT:
700
+
701
+ - always `(0, 0)`
702
+
703
+ EXAMPLES::
704
+
705
+ sage: M = Manifold(2, 'M')
706
+ sage: c_xy.<x,y> = M.chart()
707
+ sage: f = M.scalar_field(x+2*y)
708
+ sage: f.tensor_type()
709
+ (0, 0)
710
+ """
711
+ return self._tensor_type
712
+
713
+ def differential(self) -> DiffForm:
714
+ r"""
715
+ Return the differential of ``self``.
716
+
717
+ OUTPUT:
718
+
719
+ - a :class:`~sage.manifolds.differentiable.diff_form.DiffForm` (or of
720
+ :class:`~sage.manifolds.differentiable.diff_form.DiffFormParal` if
721
+ the scalar field's domain is parallelizable) representing the 1-form
722
+ that is the differential of the scalar field
723
+
724
+ EXAMPLES:
725
+
726
+ Differential of a scalar field on a 3-dimensional differentiable
727
+ manifold::
728
+
729
+ sage: M = Manifold(3, 'M')
730
+ sage: c_xyz.<x,y,z> = M.chart()
731
+ sage: f = M.scalar_field(cos(x)*z^3 + exp(y)*z^2, name='f')
732
+ sage: df = f.differential() ; df
733
+ 1-form df on the 3-dimensional differentiable manifold M
734
+ sage: df.display()
735
+ df = -z^3*sin(x) dx + z^2*e^y dy + (3*z^2*cos(x) + 2*z*e^y) dz
736
+ sage: latex(df)
737
+ \mathrm{d}f
738
+ sage: df.parent()
739
+ Free module Omega^1(M) of 1-forms on the 3-dimensional
740
+ differentiable manifold M
741
+
742
+ The result is cached, i.e. is not recomputed unless ``f`` is changed::
743
+
744
+ sage: f.differential() is df
745
+ True
746
+
747
+ Instead of invoking the method :meth:`differential`, one may apply the
748
+ function ``diff`` to the scalar field::
749
+
750
+ sage: diff(f) is f.differential()
751
+ True
752
+
753
+ Since the exterior derivative of a scalar field (considered a 0-form)
754
+ is nothing but its differential, ``exterior_derivative()`` is an
755
+ alias of ``differential()``::
756
+
757
+ sage: df = f.exterior_derivative() ; df
758
+ 1-form df on the 3-dimensional differentiable manifold M
759
+ sage: df.display()
760
+ df = -z^3*sin(x) dx + z^2*e^y dy + (3*z^2*cos(x) + 2*z*e^y) dz
761
+ sage: latex(df)
762
+ \mathrm{d}f
763
+
764
+ Differential computed on a chart that is not the default one::
765
+
766
+ sage: c_uvw.<u,v,w> = M.chart()
767
+ sage: g = M.scalar_field(u*v^2*w^3, c_uvw, name='g')
768
+ sage: dg = g.differential() ; dg
769
+ 1-form dg on the 3-dimensional differentiable manifold M
770
+ sage: dg._components
771
+ {Coordinate frame (M, (∂/∂u,∂/∂v,∂/∂w)): 1-index components w.r.t.
772
+ Coordinate frame (M, (∂/∂u,∂/∂v,∂/∂w))}
773
+ sage: dg.comp(c_uvw.frame())[:, c_uvw]
774
+ [v^2*w^3, 2*u*v*w^3, 3*u*v^2*w^2]
775
+ sage: dg.display(c_uvw)
776
+ dg = v^2*w^3 du + 2*u*v*w^3 dv + 3*u*v^2*w^2 dw
777
+
778
+ The exterior derivative is nilpotent::
779
+
780
+ sage: ddf = df.exterior_derivative() ; ddf
781
+ 2-form ddf on the 3-dimensional differentiable manifold M
782
+ sage: ddf == 0
783
+ True
784
+ sage: ddf[:] # for the incredule
785
+ [0 0 0]
786
+ [0 0 0]
787
+ [0 0 0]
788
+ sage: ddg = dg.exterior_derivative() ; ddg
789
+ 2-form ddg on the 3-dimensional differentiable manifold M
790
+ sage: ddg == 0
791
+ True
792
+ """
793
+ from sage.tensor.modules.format_utilities import (
794
+ format_unop_latex,
795
+ format_unop_txt,
796
+ )
797
+ if self._differential is None:
798
+ # A new computation is necessary:
799
+ rname = format_unop_txt('d', self._name)
800
+ rlname = format_unop_latex(r'\mathrm{d}', self._latex_name)
801
+ self._differential = self._domain.one_form(name=rname,
802
+ latex_name=rlname)
803
+ if self._is_zero:
804
+ for chart in self._domain._atlas:
805
+ self._differential.add_comp(chart._frame) # since a newly
806
+ # created set of components is zero
807
+ else:
808
+ for chart, func in self._express.items():
809
+ diff_func = self._differential.add_comp(chart._frame)
810
+ for i in self._manifold.irange():
811
+ diff_func[i, chart] = func.diff(i)
812
+ return self._differential
813
+
814
+ exterior_derivative = differential # a scalar field being a 0-form
815
+ derivative = differential # allows one to use functional notation,
816
+ # e.g. diff(f) for f.differential()
817
+
818
+ def lie_derivative(self, vector):
819
+ r"""
820
+ Compute the Lie derivative with respect to a vector field.
821
+
822
+ In the present case (scalar field), the Lie derivative is equal to
823
+ the scalar field resulting from the action of the vector field on
824
+ the scalar field.
825
+
826
+ INPUT:
827
+
828
+ - ``vector`` -- vector field with respect to which the Lie derivative
829
+ is to be taken
830
+
831
+ OUTPUT:
832
+
833
+ - the scalar field that is the Lie derivative of the scalar field with
834
+ respect to ``vector``
835
+
836
+ EXAMPLES:
837
+
838
+ Lie derivative on a 2-dimensional manifold::
839
+
840
+ sage: M = Manifold(2, 'M')
841
+ sage: c_xy.<x,y> = M.chart()
842
+ sage: f = M.scalar_field(x^2*cos(y))
843
+ sage: v = M.vector_field(name='v')
844
+ sage: v[:] = (-y, x)
845
+ sage: f.lie_derivative(v)
846
+ Scalar field on the 2-dimensional differentiable manifold M
847
+ sage: f.lie_derivative(v).expr()
848
+ -x^3*sin(y) - 2*x*y*cos(y)
849
+
850
+ The result is cached::
851
+
852
+ sage: f.lie_derivative(v) is f.lie_derivative(v)
853
+ True
854
+
855
+ An alias is ``lie_der``::
856
+
857
+ sage: f.lie_der(v) is f.lie_derivative(v)
858
+ True
859
+
860
+ Alternative expressions of the Lie derivative of a scalar field::
861
+
862
+ sage: f.lie_der(v) == v(f) # the vector acting on f
863
+ True
864
+ sage: f.lie_der(v) == f.differential()(v) # the differential of f acting on the vector
865
+ True
866
+
867
+ A vanishing Lie derivative::
868
+
869
+ sage: f.set_expr(x^2 + y^2)
870
+ sage: f.lie_der(v).display()
871
+ M → ℝ
872
+ (x, y) ↦ 0
873
+ """
874
+ # The Lie derivative is cached in _lie_derivatives if neither
875
+ # the scalar field nor ``vector`` have been modified.
876
+ if id(vector) not in self._lie_derivatives:
877
+ # A new computation must be performed
878
+ res = vector(self)
879
+ self._lie_derivatives[id(vector)] = (vector, res)
880
+ vector._lie_der_along_self[id(self)] = self
881
+ return self._lie_derivatives[id(vector)][1]
882
+
883
+ lie_der = lie_derivative
884
+
885
+ def hodge_dual(
886
+ self, nondegenerate_tensor: Union[PseudoRiemannianMetric, SymplecticForm]
887
+ ) -> DiffForm:
888
+ r"""
889
+ Compute the Hodge dual of the scalar field with respect to some non-degenerate
890
+ bilinear form (Riemannian metric or symplectic form).
891
+
892
+ If `M` is the domain of the scalar field (denoted by `f`), `n` is the
893
+ dimension of `M` and `g` is a non-degenerate bilinear form on `M`, the
894
+ *Hodge dual* of `f` w.r.t. `g` is the `n`-form `*f` defined by
895
+
896
+ .. MATH::
897
+
898
+ *f = f \epsilon,
899
+
900
+ where `\epsilon` is the volume `n`-form associated with `g` (see
901
+ :meth:`~sage.manifolds.differentiable.metric.PseudoRiemannianMetric.volume_form`).
902
+
903
+ INPUT:
904
+
905
+ - ``nondegenerate_tensor`` -- a non-degenerate bilinear form defined on the same manifold
906
+ as the current differential form; must be an instance of
907
+ :class:`~sage.manifolds.differentiable.metric.PseudoRiemannianMetric` or
908
+ :class:`~sage.manifolds.differentiable.symplectic_form.SymplecticForm`.
909
+
910
+ OUTPUT: the `n`-form `*f`
911
+
912
+ EXAMPLES:
913
+
914
+ Hodge dual of a scalar field in the Euclidean space `R^3`::
915
+
916
+ sage: M = Manifold(3, 'M', start_index=1)
917
+ sage: X.<x,y,z> = M.chart()
918
+ sage: g = M.metric('g')
919
+ sage: g[1,1], g[2,2], g[3,3] = 1, 1, 1
920
+ sage: f = M.scalar_field(function('F')(x,y,z), name='f')
921
+ sage: sf = f.hodge_dual(g) ; sf
922
+ 3-form *f on the 3-dimensional differentiable manifold M
923
+ sage: sf.display()
924
+ *f = F(x, y, z) dx∧dy∧dz
925
+ sage: ssf = sf.hodge_dual(g) ; ssf
926
+ Scalar field **f on the 3-dimensional differentiable manifold M
927
+ sage: ssf.display()
928
+ **f: M → ℝ
929
+ (x, y, z) ↦ F(x, y, z)
930
+ sage: ssf == f # must hold for a Riemannian metric
931
+ True
932
+
933
+ Instead of calling the method :meth:`hodge_dual` on the scalar field,
934
+ one can invoke the method
935
+ :meth:`~sage.manifolds.differentiable.metric.PseudoRiemannianMetric.hodge_star`
936
+ of the metric::
937
+
938
+ sage: f.hodge_dual(g) == g.hodge_star(f)
939
+ True
940
+ """
941
+ from sage.tensor.modules.format_utilities import (
942
+ format_unop_latex,
943
+ format_unop_txt,
944
+ )
945
+
946
+ result = self * nondegenerate_tensor.volume_form()
947
+ result.set_name(
948
+ name=format_unop_txt("*", self._name),
949
+ latex_name=format_unop_latex(r"\star ", self._latex_name),
950
+ )
951
+ return result
952
+
953
+ def bracket(self, other):
954
+ r"""
955
+ Return the Schouten-Nijenhuis bracket of ``self``, considered as a
956
+ multivector field of degree 0, with a multivector field.
957
+
958
+ See
959
+ :meth:`~sage.manifolds.differentiable.multivectorfield.MultivectorFieldParal.bracket`
960
+ for details.
961
+
962
+ INPUT:
963
+
964
+ - ``other`` -- a multivector field of degree `p`
965
+
966
+ OUTPUT:
967
+
968
+ - if `p=0`, a zero scalar field
969
+ - if `p=1`, an instance of :class:`DiffScalarField` representing
970
+ the Schouten-Nijenhuis bracket ``[self,other]``
971
+ - if `p\geq 2`, an instance of
972
+ :class:`~sage.manifolds.differentiable.multivectorfield.MultivectorField`
973
+ representing the Schouten-Nijenhuis bracket ``[self,other]``
974
+
975
+ EXAMPLES:
976
+
977
+ The Schouten-Nijenhuis bracket of two scalar fields is identically
978
+ zero::
979
+
980
+ sage: M = Manifold(2, 'M')
981
+ sage: X.<x,y> = M.chart()
982
+ sage: f = M.scalar_field({X: x+y^2}, name='f')
983
+ sage: g = M.scalar_field({X: y-x}, name='g')
984
+ sage: s = f.bracket(g); s
985
+ Scalar field zero on the 2-dimensional differentiable manifold M
986
+ sage: s.display()
987
+ zero: M → ℝ
988
+ (x, y) ↦ 0
989
+
990
+ while the Schouten-Nijenhuis bracket of a scalar field `f` with a
991
+ multivector field `a` is equal to minus the interior product of the
992
+ differential of `f` with `a`::
993
+
994
+ sage: a = M.multivector_field(2, name='a')
995
+ sage: a[0,1] = x*y ; a.display()
996
+ a = x*y ∂/∂x∧∂/∂y
997
+ sage: s = f.bracket(a); s
998
+ Vector field -i_df a on the 2-dimensional differentiable manifold M
999
+ sage: s.display()
1000
+ -i_df a = 2*x*y^2 ∂/∂x - x*y ∂/∂y
1001
+
1002
+ See
1003
+ :meth:`~sage.manifolds.differentiable.multivectorfield.MultivectorFieldParal.bracket`
1004
+ for other examples.
1005
+ """
1006
+ if isinstance(other, DiffScalarField):
1007
+ return self._domain.intersection(other._domain).zero_scalar_field()
1008
+ return - self.differential().interior_product(other)
1009
+
1010
+ def wedge(self, other):
1011
+ r"""
1012
+ Return the exterior product of ``self``, considered as a differential
1013
+ form of degree 0 or a multivector field of degree 0, with ``other``.
1014
+
1015
+ See
1016
+ :meth:`~sage.manifolds.differentiable.diff_form.DiffFormParal.wedge`
1017
+ (exterior product of differential forms) or
1018
+ :meth:`~sage.manifolds.differentiable.multivectorfield.MultivectorFieldParal.wedge`
1019
+ (exterior product of multivector fields) for details.
1020
+
1021
+ For a scalar field `f` and a `p`-form (or `p`-vector field) `a`, the
1022
+ exterior product reduces to the standard product on the left by an
1023
+ element of the base ring of the module of `p`-forms (or `p`-vector
1024
+ fields): `f\wedge a = f a`.
1025
+
1026
+ INPUT:
1027
+
1028
+ - ``other`` -- a differential form or a multivector field `a`
1029
+
1030
+ OUTPUT: the product `f a`, where `f` is ``self``
1031
+
1032
+ EXAMPLES::
1033
+
1034
+ sage: M = Manifold(2, 'M')
1035
+ sage: X.<x,y> = M.chart()
1036
+ sage: f = M.scalar_field({X: x+y^2}, name='f')
1037
+ sage: a = M.diff_form(2, name='a')
1038
+ sage: a[0,1] = x*y
1039
+ sage: s = f.wedge(a); s
1040
+ 2-form f*a on the 2-dimensional differentiable manifold M
1041
+ sage: s.display()
1042
+ f*a = (x*y^3 + x^2*y) dx∧dy
1043
+ """
1044
+ return self * other
1045
+
1046
+ def degree(self):
1047
+ r"""
1048
+ Return the degree of ``self``, considered as a differential
1049
+ form or a multivector field, i.e. zero.
1050
+
1051
+ This trivial method is provided for consistency with the exterior
1052
+ calculus scheme, cf. the methods
1053
+ :meth:`~sage.manifolds.differentiable.diff_form.DiffForm.degree`
1054
+ (differential forms) and
1055
+ :meth:`~sage.manifolds.differentiable.multivectorfield.MultivectorField.degree`
1056
+ (multivector fields).
1057
+
1058
+ OUTPUT: 0
1059
+
1060
+ EXAMPLES::
1061
+
1062
+ sage: M = Manifold(2, 'M')
1063
+ sage: X.<x,y> = M.chart()
1064
+ sage: f = M.scalar_field({X: x+y^2})
1065
+ sage: f.degree()
1066
+ 0
1067
+ """
1068
+ return self._tensor_rank
1069
+
1070
+ def gradient(self, metric=None):
1071
+ r"""
1072
+ Return the gradient of ``self`` (with respect to a given metric).
1073
+
1074
+ The *gradient* of a scalar field `f` with respect to a metric `g`
1075
+ is the vector field `\mathrm{grad}\, f` whose components in any
1076
+ coordinate frame are
1077
+
1078
+ .. MATH::
1079
+
1080
+ (\mathrm{grad}\, f)^i = g^{ij} \frac{\partial F}{\partial x^j}
1081
+
1082
+ where the `x^j`'s are the coordinates with respect to which the
1083
+ frame is defined and `F` is the chart function representing `f` in
1084
+ these coordinates: `f(p) = F(x^1(p),\ldots,x^n(p))` for any point `p`
1085
+ in the chart domain.
1086
+ In other words, the gradient of `f` is the vector field that is the
1087
+ `g`-dual of the differential of `f`.
1088
+
1089
+ INPUT:
1090
+
1091
+ - ``metric`` -- (default: ``None``) the pseudo-Riemannian metric `g`
1092
+ involved in the definition of the gradient; if none is provided, the
1093
+ domain of ``self`` is supposed to be endowed with a default metric
1094
+ (i.e. is supposed to be pseudo-Riemannian manifold, see
1095
+ :class:`~sage.manifolds.differentiable.pseudo_riemannian.PseudoRiemannianManifold`)
1096
+ and the latter is used to define the gradient
1097
+
1098
+ OUTPUT:
1099
+
1100
+ - instance of
1101
+ :class:`~sage.manifolds.differentiable.vectorfield.VectorField`
1102
+ representing the gradient of ``self``
1103
+
1104
+ EXAMPLES:
1105
+
1106
+ Gradient of a scalar field in the Euclidean plane::
1107
+
1108
+ sage: M.<x,y> = EuclideanSpace()
1109
+ sage: f = M.scalar_field(cos(x*y), name='f')
1110
+ sage: v = f.gradient(); v
1111
+ Vector field grad(f) on the Euclidean plane E^2
1112
+ sage: v.display()
1113
+ grad(f) = -y*sin(x*y) e_x - x*sin(x*y) e_y
1114
+ sage: v[:]
1115
+ [-y*sin(x*y), -x*sin(x*y)]
1116
+
1117
+ Gradient in polar coordinates::
1118
+
1119
+ sage: M.<r,phi> = EuclideanSpace(coordinates='polar')
1120
+ sage: f = M.scalar_field(r*cos(phi), name='f')
1121
+ sage: f.gradient().display()
1122
+ grad(f) = cos(phi) e_r - sin(phi) e_phi
1123
+ sage: f.gradient()[:]
1124
+ [cos(phi), -sin(phi)]
1125
+
1126
+ Note that ``(e_r, e_phi)`` is the orthonormal vector frame associated
1127
+ with polar coordinates (see
1128
+ :meth:`~sage.manifolds.differentiable.examples.euclidean.EuclideanPlane.polar_frame`);
1129
+ the gradient expressed in the coordinate frame is::
1130
+
1131
+ sage: f.gradient().display(M.polar_coordinates().frame())
1132
+ grad(f) = cos(phi) ∂/∂r - sin(phi)/r ∂/∂phi
1133
+
1134
+ The function :func:`~sage.manifolds.operators.grad` from the
1135
+ :mod:`~sage.manifolds.operators` module can be used instead of the
1136
+ method :meth:`gradient`::
1137
+
1138
+ sage: from sage.manifolds.operators import grad
1139
+ sage: grad(f) == f.gradient()
1140
+ True
1141
+
1142
+ The gradient can be taken with respect to a metric tensor that is
1143
+ not the default one::
1144
+
1145
+ sage: h = M.lorentzian_metric('h')
1146
+ sage: h[1,1], h[2,2] = -1, 1/(1+r^2)
1147
+ sage: h.display(M.polar_coordinates().frame())
1148
+ h = -dr⊗dr + r^2/(r^2 + 1) dphi⊗dphi
1149
+ sage: v = f.gradient(h); v
1150
+ Vector field grad_h(f) on the Euclidean plane E^2
1151
+ sage: v.display()
1152
+ grad_h(f) = -cos(phi) e_r + (-r^2*sin(phi) - sin(phi)) e_phi
1153
+ """
1154
+ default_metric = metric is None
1155
+ if default_metric:
1156
+ metric = self._domain.metric()
1157
+ resu = self.differential().up(metric)
1158
+ if self._name is not None:
1159
+ if default_metric:
1160
+ resu._name = "grad({})".format(self._name)
1161
+ resu._latex_name = r"\mathrm{grad}\left(" + \
1162
+ self._latex_name + r"\right)"
1163
+ else:
1164
+ resu._name = "grad_{}({})".format(metric._name, self._name)
1165
+ resu._latex_name = r"\mathrm{grad}_{" + metric._latex_name + \
1166
+ r"}\left(" + self._latex_name + r"\right)"
1167
+ # The name is propagated to possible restrictions of self:
1168
+ for restrict in resu._restrictions.values():
1169
+ restrict.set_name(resu._name, latex_name=resu._latex_name)
1170
+ return resu
1171
+
1172
+ def laplacian(self, metric=None):
1173
+ r"""
1174
+ Return the Laplacian of ``self`` with respect to a given
1175
+ metric (Laplace-Beltrami operator).
1176
+
1177
+ The *Laplacian* of a scalar field `f` with respect to a metric `g`
1178
+ is the scalar field
1179
+
1180
+ .. MATH::
1181
+
1182
+ \Delta f = g^{ij} \nabla_i \nabla_j f = \nabla_i \nabla^i f
1183
+
1184
+ where `\nabla` is the Levi-Civita connection of `g`.
1185
+ `\Delta` is also called the *Laplace-Beltrami operator*.
1186
+
1187
+ INPUT:
1188
+
1189
+ - ``metric`` -- (default: ``None``) the pseudo-Riemannian metric `g`
1190
+ involved in the definition of the Laplacian; if none is provided, the
1191
+ domain of ``self`` is supposed to be endowed with a default metric
1192
+ (i.e. is supposed to be pseudo-Riemannian manifold, see
1193
+ :class:`~sage.manifolds.differentiable.pseudo_riemannian.PseudoRiemannianManifold`)
1194
+ and the latter is used to define the Laplacian
1195
+
1196
+ OUTPUT:
1197
+
1198
+ - instance of :class:`DiffScalarField` representing the Laplacian of
1199
+ ``self``
1200
+
1201
+ EXAMPLES:
1202
+
1203
+ Laplacian of a scalar field on the Euclidean plane::
1204
+
1205
+ sage: M.<x,y> = EuclideanSpace()
1206
+ sage: f = M.scalar_field(function('F')(x,y), name='f')
1207
+ sage: s = f.laplacian(); s
1208
+ Scalar field Delta(f) on the Euclidean plane E^2
1209
+ sage: s.display()
1210
+ Delta(f): E^2 → ℝ
1211
+ (x, y) ↦ d^2(F)/dx^2 + d^2(F)/dy^2
1212
+
1213
+ The function :func:`~sage.manifolds.operators.laplacian` from the
1214
+ :mod:`~sage.manifolds.operators` module can be used instead of the
1215
+ method :meth:`laplacian`::
1216
+
1217
+ sage: from sage.manifolds.operators import laplacian
1218
+ sage: laplacian(f) == s
1219
+ True
1220
+
1221
+ The Laplacian can be taken with respect to a metric tensor that is
1222
+ not the default one::
1223
+
1224
+ sage: h = M.lorentzian_metric('h')
1225
+ sage: h[1,1], h[2,2] = -1, 1/(1+x^2+y^2)
1226
+ sage: s = f.laplacian(h); s
1227
+ Scalar field Delta_h(f) on the Euclidean plane E^2
1228
+ sage: s.display()
1229
+ Delta_h(f): E^2 → ℝ
1230
+ (x, y) ↦ (y^4*d^2(F)/dy^2 + y^3*d(F)/dy
1231
+ + (2*(x^2 + 1)*d^2(F)/dy^2 - d^2(F)/dx^2)*y^2
1232
+ + (x^2 + 1)*y*d(F)/dy + x*d(F)/dx - (x^2 + 1)*d^2(F)/dx^2
1233
+ + (x^4 + 2*x^2 + 1)*d^2(F)/dy^2)/(x^2 + y^2 + 1)
1234
+
1235
+ The Laplacian of `f` is equal to the divergence of the gradient of `f`:
1236
+
1237
+ .. MATH::
1238
+
1239
+ \Delta f = \mathrm{div}( \mathrm{grad}\, f )
1240
+
1241
+ Let us check this formula::
1242
+
1243
+ sage: s == f.gradient(h).div(h)
1244
+ True
1245
+ """
1246
+ default_metric = metric is None
1247
+ if default_metric:
1248
+ metric = self._domain.metric()
1249
+ nabla = metric.connection()
1250
+ resu = nabla(self.differential().up(metric)).trace()
1251
+ if self._name is not None:
1252
+ if default_metric:
1253
+ resu._name = "Delta({})".format(self._name)
1254
+ resu._latex_name = r"\Delta\left(" + self._latex_name + \
1255
+ r"\right)"
1256
+ else:
1257
+ resu._name = "Delta_{}({})".format(metric._name, self._name)
1258
+ resu._latex_name = r"\Delta_{" + metric._latex_name + \
1259
+ r"}\left(" + self._latex_name + r"\right)"
1260
+ # The name is propagated to possible restrictions of self:
1261
+ for restrict in resu._restrictions.values():
1262
+ restrict.set_name(resu._name, latex_name=resu._latex_name)
1263
+ return resu
1264
+
1265
+ def dalembertian(self, metric=None):
1266
+ r"""
1267
+ Return the d'Alembertian of ``self`` with respect to a given
1268
+ Lorentzian metric.
1269
+
1270
+ The *d'Alembertian* of a scalar field `f` with respect to a Lorentzian
1271
+ metric `g` is nothing but the Laplacian (see :meth:`laplacian`) of `f`
1272
+ with respect to that metric:
1273
+
1274
+ .. MATH::
1275
+
1276
+ \Box f = g^{ij} \nabla_i \nabla_j f = \nabla_i \nabla^i f
1277
+
1278
+ where `\nabla` is the Levi-Civita connection of `g`.
1279
+
1280
+ .. NOTE::
1281
+
1282
+ If the metric `g` is not Lorentzian, the name *d'Alembertian* is
1283
+ not appropriate and one should use :meth:`laplacian` instead.
1284
+
1285
+ INPUT:
1286
+
1287
+ - ``metric`` -- (default: ``None``) the Lorentzian metric `g`
1288
+ involved in the definition of the d'Alembertian; if none is provided,
1289
+ the domain of ``self`` is supposed to be endowed with a default
1290
+ Lorentzian metric (i.e. is supposed to be Lorentzian manifold, see
1291
+ :class:`~sage.manifolds.differentiable.pseudo_riemannian.PseudoRiemannianManifold`)
1292
+ and the latter is used to define the d'Alembertian
1293
+
1294
+ OUTPUT:
1295
+
1296
+ - instance of :class:`DiffScalarField` representing the d'Alembertian
1297
+ of ``self``
1298
+
1299
+ EXAMPLES:
1300
+
1301
+ d'Alembertian of a scalar field in Minkowski spacetime::
1302
+
1303
+ sage: M = Manifold(4, 'M', structure='Lorentzian')
1304
+ sage: X.<t,x,y,z> = M.chart()
1305
+ sage: g = M.metric()
1306
+ sage: g[0,0], g[1,1], g[2,2], g[3,3] = -1, 1, 1, 1
1307
+ sage: f = M.scalar_field(t + x^2 + t^2*y^3 - x*z^4, name='f')
1308
+ sage: s = f.dalembertian(); s
1309
+ Scalar field Box(f) on the 4-dimensional Lorentzian manifold M
1310
+ sage: s.display()
1311
+ Box(f): M → ℝ
1312
+ (t, x, y, z) ↦ 6*t^2*y - 2*y^3 - 12*x*z^2 + 2
1313
+
1314
+ The function :func:`~sage.manifolds.operators.dalembertian` from the
1315
+ :mod:`~sage.manifolds.operators` module can be used instead of the
1316
+ method :meth:`dalembertian`::
1317
+
1318
+ sage: from sage.manifolds.operators import dalembertian
1319
+ sage: dalembertian(f) == s
1320
+ True
1321
+ """
1322
+ default_metric = metric is None
1323
+ if default_metric:
1324
+ metric = self._domain.metric()
1325
+ nm2 = self._manifold.dim() - 2
1326
+ if metric.signature() not in [nm2, -nm2]:
1327
+ raise TypeError("the {} is not a Lorentzian ".format(metric) +
1328
+ "metric; use laplacian() instead")
1329
+ nabla = metric.connection()
1330
+ resu = nabla(self.differential().up(metric)).trace()
1331
+ if self._name is not None:
1332
+ if default_metric:
1333
+ resu._name = "Box({})".format(self._name)
1334
+ resu._latex_name = r"\Box\left(" + self._latex_name + \
1335
+ r"\right)"
1336
+ else:
1337
+ resu._name = "Box_{}({})".format(metric._name, self._name)
1338
+ resu._latex_name = r"\Box_{" + metric._latex_name + \
1339
+ r"}\left(" + self._latex_name + r"\right)"
1340
+ # The name is propagated to possible restrictions of self:
1341
+ for restrict in resu._restrictions.values():
1342
+ restrict.set_name(resu._name, latex_name=resu._latex_name)
1343
+ return resu