passagemath-symbolics 10.6.40__cp314-cp314t-macosx_13_0_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.
- passagemath_symbolics/.dylibs/libgmp.10.dylib +0 -0
- passagemath_symbolics/__init__.py +3 -0
- passagemath_symbolics-10.6.40.dist-info/METADATA +187 -0
- passagemath_symbolics-10.6.40.dist-info/RECORD +172 -0
- passagemath_symbolics-10.6.40.dist-info/WHEEL +6 -0
- passagemath_symbolics-10.6.40.dist-info/top_level.txt +3 -0
- sage/all__sagemath_symbolics.py +17 -0
- sage/calculus/all.py +14 -0
- sage/calculus/calculus.py +2826 -0
- sage/calculus/desolvers.py +1866 -0
- sage/calculus/predefined.py +51 -0
- sage/calculus/tests.py +225 -0
- sage/calculus/var.cpython-314t-darwin.so +0 -0
- sage/calculus/var.pyx +401 -0
- sage/dynamics/all__sagemath_symbolics.py +6 -0
- sage/dynamics/complex_dynamics/all.py +5 -0
- sage/dynamics/complex_dynamics/mandel_julia.py +765 -0
- sage/dynamics/complex_dynamics/mandel_julia_helper.cpython-314t-darwin.so +0 -0
- sage/dynamics/complex_dynamics/mandel_julia_helper.pyx +1035 -0
- sage/ext/all__sagemath_symbolics.py +1 -0
- sage/ext_data/kenzo/CP2.txt +45 -0
- sage/ext_data/kenzo/CP3.txt +349 -0
- sage/ext_data/kenzo/CP4.txt +4774 -0
- sage/ext_data/kenzo/README.txt +49 -0
- sage/ext_data/kenzo/S4.txt +20 -0
- sage/ext_data/magma/latex/latex.m +1021 -0
- sage/ext_data/magma/latex/latex.spec +1 -0
- sage/ext_data/magma/sage/basic.m +356 -0
- sage/ext_data/magma/sage/sage.spec +1 -0
- sage/ext_data/magma/spec +9 -0
- sage/geometry/all__sagemath_symbolics.py +8 -0
- sage/geometry/hyperbolic_space/all.py +5 -0
- sage/geometry/hyperbolic_space/hyperbolic_coercion.py +743 -0
- sage/geometry/hyperbolic_space/hyperbolic_constants.py +5 -0
- sage/geometry/hyperbolic_space/hyperbolic_geodesic.py +2409 -0
- sage/geometry/hyperbolic_space/hyperbolic_interface.py +206 -0
- sage/geometry/hyperbolic_space/hyperbolic_isometry.py +1082 -0
- sage/geometry/hyperbolic_space/hyperbolic_model.py +1502 -0
- sage/geometry/hyperbolic_space/hyperbolic_point.py +621 -0
- sage/geometry/riemannian_manifolds/all.py +7 -0
- sage/geometry/riemannian_manifolds/parametrized_surface3d.py +1632 -0
- sage/geometry/riemannian_manifolds/surface3d_generators.py +461 -0
- sage/interfaces/all__sagemath_symbolics.py +1 -0
- sage/interfaces/magma.py +3017 -0
- sage/interfaces/magma_free.py +92 -0
- sage/interfaces/maple.py +1397 -0
- sage/interfaces/mathematica.py +1345 -0
- sage/interfaces/mathics.py +1312 -0
- sage/interfaces/sympy.py +1398 -0
- sage/interfaces/sympy_wrapper.py +197 -0
- sage/interfaces/tides.py +938 -0
- sage/libs/all__sagemath_symbolics.py +6 -0
- sage/manifolds/all.py +7 -0
- sage/manifolds/calculus_method.py +555 -0
- sage/manifolds/catalog.py +437 -0
- sage/manifolds/chart.py +4019 -0
- sage/manifolds/chart_func.py +3419 -0
- sage/manifolds/continuous_map.py +2183 -0
- sage/manifolds/continuous_map_image.py +155 -0
- sage/manifolds/differentiable/affine_connection.py +2475 -0
- sage/manifolds/differentiable/all.py +1 -0
- sage/manifolds/differentiable/automorphismfield.py +1383 -0
- sage/manifolds/differentiable/automorphismfield_group.py +604 -0
- sage/manifolds/differentiable/bundle_connection.py +1445 -0
- sage/manifolds/differentiable/characteristic_cohomology_class.py +1840 -0
- sage/manifolds/differentiable/chart.py +1241 -0
- sage/manifolds/differentiable/curve.py +1028 -0
- sage/manifolds/differentiable/de_rham_cohomology.py +541 -0
- sage/manifolds/differentiable/degenerate.py +559 -0
- sage/manifolds/differentiable/degenerate_submanifold.py +1671 -0
- sage/manifolds/differentiable/diff_form.py +1658 -0
- sage/manifolds/differentiable/diff_form_module.py +1062 -0
- sage/manifolds/differentiable/diff_map.py +1315 -0
- sage/manifolds/differentiable/differentiable_submanifold.py +291 -0
- sage/manifolds/differentiable/examples/all.py +1 -0
- sage/manifolds/differentiable/examples/euclidean.py +2517 -0
- sage/manifolds/differentiable/examples/real_line.py +897 -0
- sage/manifolds/differentiable/examples/sphere.py +1186 -0
- sage/manifolds/differentiable/examples/symplectic_space.py +187 -0
- sage/manifolds/differentiable/examples/symplectic_space_test.py +40 -0
- sage/manifolds/differentiable/integrated_curve.py +4035 -0
- sage/manifolds/differentiable/levi_civita_connection.py +841 -0
- sage/manifolds/differentiable/manifold.py +4254 -0
- sage/manifolds/differentiable/manifold_homset.py +1826 -0
- sage/manifolds/differentiable/metric.py +3032 -0
- sage/manifolds/differentiable/mixed_form.py +1507 -0
- sage/manifolds/differentiable/mixed_form_algebra.py +559 -0
- sage/manifolds/differentiable/multivector_module.py +800 -0
- sage/manifolds/differentiable/multivectorfield.py +1520 -0
- sage/manifolds/differentiable/poisson_tensor.py +268 -0
- sage/manifolds/differentiable/pseudo_riemannian.py +755 -0
- sage/manifolds/differentiable/pseudo_riemannian_submanifold.py +1839 -0
- sage/manifolds/differentiable/scalarfield.py +1343 -0
- sage/manifolds/differentiable/scalarfield_algebra.py +472 -0
- sage/manifolds/differentiable/symplectic_form.py +910 -0
- sage/manifolds/differentiable/symplectic_form_test.py +220 -0
- sage/manifolds/differentiable/tangent_space.py +412 -0
- sage/manifolds/differentiable/tangent_vector.py +616 -0
- sage/manifolds/differentiable/tensorfield.py +4665 -0
- sage/manifolds/differentiable/tensorfield_module.py +963 -0
- sage/manifolds/differentiable/tensorfield_paral.py +2450 -0
- sage/manifolds/differentiable/tensorfield_paral_test.py +16 -0
- sage/manifolds/differentiable/vector_bundle.py +1728 -0
- sage/manifolds/differentiable/vectorfield.py +1717 -0
- sage/manifolds/differentiable/vectorfield_module.py +2445 -0
- sage/manifolds/differentiable/vectorframe.py +1832 -0
- sage/manifolds/family.py +270 -0
- sage/manifolds/local_frame.py +1490 -0
- sage/manifolds/manifold.py +3090 -0
- sage/manifolds/manifold_homset.py +452 -0
- sage/manifolds/operators.py +359 -0
- sage/manifolds/point.py +994 -0
- sage/manifolds/scalarfield.py +3718 -0
- sage/manifolds/scalarfield_algebra.py +629 -0
- sage/manifolds/section.py +3111 -0
- sage/manifolds/section_module.py +831 -0
- sage/manifolds/structure.py +229 -0
- sage/manifolds/subset.py +2764 -0
- sage/manifolds/subsets/all.py +1 -0
- sage/manifolds/subsets/closure.py +131 -0
- sage/manifolds/subsets/pullback.py +885 -0
- sage/manifolds/topological_submanifold.py +891 -0
- sage/manifolds/trivialization.py +733 -0
- sage/manifolds/utilities.py +1348 -0
- sage/manifolds/vector_bundle.py +1342 -0
- sage/manifolds/vector_bundle_fiber.py +332 -0
- sage/manifolds/vector_bundle_fiber_element.py +111 -0
- sage/matrix/all__sagemath_symbolics.py +1 -0
- sage/matrix/matrix_symbolic_dense.cpython-314t-darwin.so +0 -0
- sage/matrix/matrix_symbolic_dense.pxd +6 -0
- sage/matrix/matrix_symbolic_dense.pyx +1022 -0
- sage/matrix/matrix_symbolic_sparse.cpython-314t-darwin.so +0 -0
- sage/matrix/matrix_symbolic_sparse.pxd +6 -0
- sage/matrix/matrix_symbolic_sparse.pyx +1029 -0
- sage/modules/all__sagemath_symbolics.py +1 -0
- sage/modules/vector_callable_symbolic_dense.py +105 -0
- sage/modules/vector_symbolic_dense.py +116 -0
- sage/modules/vector_symbolic_sparse.py +118 -0
- sage/rings/all__sagemath_symbolics.py +4 -0
- sage/rings/asymptotic/all.py +6 -0
- sage/rings/asymptotic/asymptotic_expansion_generators.py +1485 -0
- sage/rings/asymptotic/asymptotic_ring.py +4858 -0
- sage/rings/asymptotic/asymptotics_multivariate_generating_functions.py +4153 -0
- sage/rings/asymptotic/growth_group.py +5373 -0
- sage/rings/asymptotic/growth_group_cartesian.py +1400 -0
- sage/rings/asymptotic/term_monoid.py +5237 -0
- sage/rings/function_field/all__sagemath_symbolics.py +2 -0
- sage/rings/polynomial/all__sagemath_symbolics.py +1 -0
- sage/symbolic/all.py +15 -0
- sage/symbolic/assumptions.py +985 -0
- sage/symbolic/benchmark.py +93 -0
- sage/symbolic/callable.py +459 -0
- sage/symbolic/complexity_measures.py +35 -0
- sage/symbolic/constants.py +1287 -0
- sage/symbolic/expression_conversion_algebraic.py +310 -0
- sage/symbolic/expression_conversion_sympy.py +317 -0
- sage/symbolic/expression_conversions.py +1713 -0
- sage/symbolic/function_factory.py +355 -0
- sage/symbolic/integration/all.py +1 -0
- sage/symbolic/integration/external.py +270 -0
- sage/symbolic/integration/integral.py +1115 -0
- sage/symbolic/maxima_wrapper.py +162 -0
- sage/symbolic/operators.py +267 -0
- sage/symbolic/random_tests.py +462 -0
- sage/symbolic/relation.py +1907 -0
- sage/symbolic/ring.cpython-314t-darwin.so +0 -0
- sage/symbolic/ring.pxd +5 -0
- sage/symbolic/ring.pyx +1396 -0
- sage/symbolic/subring.py +1025 -0
- sage/symbolic/symengine.py +19 -0
- sage/symbolic/tests.py +40 -0
- sage/symbolic/units.py +1470 -0
|
@@ -0,0 +1,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
|