passagemath-symbolics 10.8.1a1__cp311-cp311-macosx_13_0_arm64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- passagemath_symbolics/.dylibs/libgmp.10.dylib +0 -0
- passagemath_symbolics/__init__.py +3 -0
- passagemath_symbolics-10.8.1a1.dist-info/METADATA +186 -0
- passagemath_symbolics-10.8.1a1.dist-info/RECORD +182 -0
- passagemath_symbolics-10.8.1a1.dist-info/WHEEL +6 -0
- passagemath_symbolics-10.8.1a1.dist-info/top_level.txt +3 -0
- sage/all__sagemath_symbolics.py +17 -0
- sage/calculus/all.py +14 -0
- sage/calculus/calculus.py +2838 -0
- sage/calculus/desolvers.py +1864 -0
- sage/calculus/predefined.py +51 -0
- sage/calculus/tests.py +225 -0
- sage/calculus/var.cpython-311-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-311-darwin.so +0 -0
- sage/dynamics/complex_dynamics/mandel_julia_helper.pyx +1034 -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 +755 -0
- sage/geometry/hyperbolic_space/hyperbolic_constants.py +5 -0
- sage/geometry/hyperbolic_space/hyperbolic_geodesic.py +2419 -0
- sage/geometry/hyperbolic_space/hyperbolic_interface.py +206 -0
- sage/geometry/hyperbolic_space/hyperbolic_isometry.py +1083 -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 +2991 -0
- sage/interfaces/magma_free.py +90 -0
- sage/interfaces/maple.py +1402 -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 +553 -0
- sage/manifolds/catalog.py +437 -0
- sage/manifolds/chart.py +4010 -0
- sage/manifolds/chart_func.py +3416 -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 +1668 -0
- sage/manifolds/differentiable/diff_form.py +1660 -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 +1522 -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 +912 -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 +1725 -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 +2721 -0
- sage/manifolds/subsets/all.py +1 -0
- sage/manifolds/subsets/closure.py +131 -0
- sage/manifolds/subsets/pullback.py +883 -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 +1347 -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-311-darwin.so +0 -0
- sage/matrix/matrix_symbolic_dense.pxd +6 -0
- sage/matrix/matrix_symbolic_dense.pyx +1030 -0
- sage/matrix/matrix_symbolic_sparse.cpython-311-darwin.so +0 -0
- sage/matrix/matrix_symbolic_sparse.pxd +6 -0
- sage/matrix/matrix_symbolic_sparse.pyx +1038 -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 +4106 -0
- sage/rings/asymptotic/growth_group.py +5373 -0
- sage/rings/asymptotic/growth_group_cartesian.py +1400 -0
- sage/rings/asymptotic/term_monoid.py +5205 -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 +987 -0
- sage/symbolic/benchmark.py +93 -0
- sage/symbolic/callable.py +456 -0
- sage/symbolic/callable.pyi +66 -0
- sage/symbolic/comparison_impl.pyi +38 -0
- sage/symbolic/complexity_measures.py +35 -0
- sage/symbolic/constants.py +1286 -0
- sage/symbolic/constants_c_impl.pyi +10 -0
- sage/symbolic/expression_conversion_algebraic.py +310 -0
- sage/symbolic/expression_conversion_sympy.py +317 -0
- sage/symbolic/expression_conversions.py +1727 -0
- sage/symbolic/function_factory.py +355 -0
- sage/symbolic/function_factory.pyi +41 -0
- sage/symbolic/getitem_impl.pyi +24 -0
- sage/symbolic/integration/all.py +1 -0
- sage/symbolic/integration/external.py +271 -0
- sage/symbolic/integration/integral.py +1075 -0
- sage/symbolic/maxima_wrapper.py +162 -0
- sage/symbolic/operators.py +267 -0
- sage/symbolic/operators.pyi +61 -0
- sage/symbolic/pynac_constant_impl.pyi +13 -0
- sage/symbolic/pynac_function_impl.pyi +8 -0
- sage/symbolic/random_tests.py +461 -0
- sage/symbolic/relation.py +2062 -0
- sage/symbolic/ring.cpython-311-darwin.so +0 -0
- sage/symbolic/ring.pxd +5 -0
- sage/symbolic/ring.pyi +110 -0
- sage/symbolic/ring.pyx +1393 -0
- sage/symbolic/series_impl.pyi +10 -0
- sage/symbolic/subring.py +1025 -0
- sage/symbolic/symengine.py +19 -0
- sage/symbolic/tests.py +40 -0
- sage/symbolic/units.py +1468 -0
|
@@ -0,0 +1,912 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-symbolics
|
|
2
|
+
r"""
|
|
3
|
+
Symplectic structures
|
|
4
|
+
|
|
5
|
+
The class :class:`SymplecticForm` implements symplectic structures
|
|
6
|
+
on differentiable manifolds over `\RR`. The derived class
|
|
7
|
+
:class:`SymplecticFormParal` is devoted to symplectic forms on a
|
|
8
|
+
parallelizable manifold.
|
|
9
|
+
|
|
10
|
+
AUTHORS:
|
|
11
|
+
|
|
12
|
+
- Tobias Diez (2021) : initial version
|
|
13
|
+
|
|
14
|
+
REFERENCES:
|
|
15
|
+
|
|
16
|
+
- [AM1990]_
|
|
17
|
+
- [RS2012]_
|
|
18
|
+
"""
|
|
19
|
+
# *****************************************************************************
|
|
20
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
|
21
|
+
# as published by the Free Software Foundation; either version 2 of
|
|
22
|
+
# the License, or (at your option) any later version.
|
|
23
|
+
# https://www.gnu.org/licenses/
|
|
24
|
+
# *****************************************************************************
|
|
25
|
+
from __future__ import annotations
|
|
26
|
+
|
|
27
|
+
from typing import Optional, Union, TYPE_CHECKING
|
|
28
|
+
|
|
29
|
+
from sage.manifolds.differentiable.diff_form import DiffForm, DiffFormParal
|
|
30
|
+
|
|
31
|
+
if TYPE_CHECKING:
|
|
32
|
+
from sage.manifolds.differentiable.diff_map import DiffMap
|
|
33
|
+
from sage.manifolds.differentiable.manifold import DifferentiableManifold
|
|
34
|
+
from sage.symbolic.expression import Expression
|
|
35
|
+
from sage.manifolds.differentiable.vectorfield_module import VectorFieldModule
|
|
36
|
+
from sage.manifolds.differentiable.vectorfield import VectorField
|
|
37
|
+
from sage.manifolds.differentiable.scalarfield import DiffScalarField
|
|
38
|
+
from sage.manifolds.differentiable.poisson_tensor import PoissonTensorField
|
|
39
|
+
from sage.manifolds.differentiable.tensorfield_paral import TensorFieldParal
|
|
40
|
+
from sage.manifolds.differentiable.tensorfield import TensorField
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class SymplecticForm(DiffForm):
|
|
44
|
+
r"""
|
|
45
|
+
A symplectic form on a differentiable manifold.
|
|
46
|
+
|
|
47
|
+
An instance of this class is a closed nondegenerate differential `2`-form `\omega`
|
|
48
|
+
on a differentiable manifold `M` over `\RR`.
|
|
49
|
+
|
|
50
|
+
In particular, at each point `m \in M`, `\omega_m` is a bilinear map of the type:
|
|
51
|
+
|
|
52
|
+
.. MATH::
|
|
53
|
+
|
|
54
|
+
\omega_m:\ T_m M \times T_m M \to \RR,
|
|
55
|
+
|
|
56
|
+
where `T_m M` stands for the tangent space to the
|
|
57
|
+
manifold `M` at the point `m`, such that `\omega_m` is skew-symmetric:
|
|
58
|
+
`\forall u,v \in T_m M, \ \omega_m(v,u) = - \omega_m(u,v)`
|
|
59
|
+
and nondegenerate:
|
|
60
|
+
`(\forall v \in T_m M,\ \ \omega_m(u,v) = 0) \Longrightarrow u=0`.
|
|
61
|
+
|
|
62
|
+
.. NOTE::
|
|
63
|
+
|
|
64
|
+
If `M` is parallelizable, the class :class:`SymplecticFormParal`
|
|
65
|
+
should be used instead.
|
|
66
|
+
|
|
67
|
+
INPUT:
|
|
68
|
+
|
|
69
|
+
- ``manifold`` -- module `\mathfrak{X}(M)` of vector fields on the
|
|
70
|
+
manifold `M`, or the manifold `M` itself
|
|
71
|
+
- ``name`` -- (default: ``omega``) name given to the symplectic form
|
|
72
|
+
- ``latex_name`` -- (default: ``None``) LaTeX symbol to denote the
|
|
73
|
+
symplectic form; if ``None``, it is formed from ``name``
|
|
74
|
+
|
|
75
|
+
EXAMPLES:
|
|
76
|
+
|
|
77
|
+
A symplectic form on the 2-sphere::
|
|
78
|
+
|
|
79
|
+
sage: M.<x,y> = manifolds.Sphere(2, coordinates='stereographic')
|
|
80
|
+
sage: stereoN = M.stereographic_coordinates(pole='north')
|
|
81
|
+
sage: stereoS = M.stereographic_coordinates(pole='south')
|
|
82
|
+
sage: omega = M.symplectic_form(name='omega', latex_name=r'\omega')
|
|
83
|
+
sage: omega
|
|
84
|
+
Symplectic form omega on the 2-sphere S^2 of radius 1 smoothly embedded
|
|
85
|
+
in the Euclidean space E^3
|
|
86
|
+
|
|
87
|
+
``omega`` is initialized by providing its single nonvanishing component
|
|
88
|
+
w.r.t. the vector frame associated to ``stereoN``, which is the default
|
|
89
|
+
frame on ``M``::
|
|
90
|
+
|
|
91
|
+
sage: omega[1, 2] = 1/(1 + x^2 + y^2)^2
|
|
92
|
+
|
|
93
|
+
The components w.r.t. the vector frame associated to ``stereoS`` are
|
|
94
|
+
obtained thanks to the method
|
|
95
|
+
:meth:`~sage.manifolds.differentiable.tensorfield.TensorField.add_comp_by_continuation`::
|
|
96
|
+
|
|
97
|
+
sage: omega.add_comp_by_continuation(stereoS.frame(),
|
|
98
|
+
....: stereoS.domain().intersection(stereoN.domain()))
|
|
99
|
+
sage: omega.display()
|
|
100
|
+
omega = (x^2 + y^2 + 1)^(-2) dx∧dy
|
|
101
|
+
sage: omega.display(stereoS)
|
|
102
|
+
omega = -1/(xp^4 + yp^4 + 2*(xp^2 + 1)*yp^2 + 2*xp^2 + 1) dxp∧dyp
|
|
103
|
+
|
|
104
|
+
``omega`` is an exact 2-form (this is trivial here, since ``M`` is
|
|
105
|
+
2-dimensional)::
|
|
106
|
+
|
|
107
|
+
sage: diff(omega).display()
|
|
108
|
+
domega = 0
|
|
109
|
+
"""
|
|
110
|
+
|
|
111
|
+
_name: str
|
|
112
|
+
_latex_name: str
|
|
113
|
+
_dim_half: int
|
|
114
|
+
_poisson: Optional[PoissonTensorField]
|
|
115
|
+
_vol_form: Optional[DiffForm]
|
|
116
|
+
_restrictions: dict[DifferentiableManifold, SymplecticForm]
|
|
117
|
+
|
|
118
|
+
def __init__(
|
|
119
|
+
self,
|
|
120
|
+
manifold: Union[DifferentiableManifold, VectorFieldModule],
|
|
121
|
+
name: Optional[str] = None,
|
|
122
|
+
latex_name: Optional[str] = None,
|
|
123
|
+
):
|
|
124
|
+
r"""
|
|
125
|
+
Construct a symplectic form.
|
|
126
|
+
|
|
127
|
+
TESTS::
|
|
128
|
+
|
|
129
|
+
sage: from sage.manifolds.differentiable.symplectic_form import SymplecticForm
|
|
130
|
+
sage: M = manifolds.Sphere(2, coordinates='stereographic')
|
|
131
|
+
sage: omega = SymplecticForm(M, name='omega', latex_name=r'\omega')
|
|
132
|
+
sage: omega
|
|
133
|
+
Symplectic form omega on the 2-sphere S^2 of radius 1 smoothly
|
|
134
|
+
embedded in the Euclidean space E^3
|
|
135
|
+
"""
|
|
136
|
+
try:
|
|
137
|
+
vector_field_module = manifold.vector_field_module()
|
|
138
|
+
except AttributeError:
|
|
139
|
+
vector_field_module = manifold
|
|
140
|
+
|
|
141
|
+
if name is None:
|
|
142
|
+
name = "omega"
|
|
143
|
+
if latex_name is None:
|
|
144
|
+
latex_name = r"\omega"
|
|
145
|
+
|
|
146
|
+
if latex_name is None:
|
|
147
|
+
latex_name = name
|
|
148
|
+
|
|
149
|
+
DiffForm.__init__(
|
|
150
|
+
self, vector_field_module, 2, name=name, latex_name=latex_name
|
|
151
|
+
)
|
|
152
|
+
|
|
153
|
+
# Check that manifold is even dimensional
|
|
154
|
+
dim = self._ambient_domain.dimension()
|
|
155
|
+
if dim % 2 == 1:
|
|
156
|
+
raise ValueError(
|
|
157
|
+
f"the dimension of the manifold must be even but it is {dim}"
|
|
158
|
+
)
|
|
159
|
+
self._dim_half = dim // 2
|
|
160
|
+
|
|
161
|
+
# Initialization of derived quantities
|
|
162
|
+
SymplecticForm._init_derived(self)
|
|
163
|
+
|
|
164
|
+
def _repr_(self):
|
|
165
|
+
r"""
|
|
166
|
+
String representation of the object.
|
|
167
|
+
|
|
168
|
+
TESTS::
|
|
169
|
+
|
|
170
|
+
sage: M.<q, p> = EuclideanSpace(2)
|
|
171
|
+
sage: omega = M.symplectic_form('omega', r'\omega'); omega
|
|
172
|
+
Symplectic form omega on the Euclidean plane E^2
|
|
173
|
+
"""
|
|
174
|
+
return self._final_repr(f"Symplectic form {self._name} ")
|
|
175
|
+
|
|
176
|
+
def _new_instance(self):
|
|
177
|
+
r"""
|
|
178
|
+
Create an instance of the same class as ``self``.
|
|
179
|
+
|
|
180
|
+
TESTS::
|
|
181
|
+
|
|
182
|
+
sage: M.<q, p> = EuclideanSpace(2)
|
|
183
|
+
sage: omega = M.symplectic_form('omega', r'\omega')._new_instance(); omega
|
|
184
|
+
Symplectic form unnamed symplectic form on the Euclidean plane E^2
|
|
185
|
+
"""
|
|
186
|
+
return type(self)(
|
|
187
|
+
self._vmodule,
|
|
188
|
+
"unnamed symplectic form",
|
|
189
|
+
latex_name=r"\text{unnamed symplectic form}",
|
|
190
|
+
)
|
|
191
|
+
|
|
192
|
+
def _init_derived(self):
|
|
193
|
+
r"""
|
|
194
|
+
Initialize the derived quantities.
|
|
195
|
+
|
|
196
|
+
TESTS::
|
|
197
|
+
|
|
198
|
+
sage: M.<q, p> = EuclideanSpace(2)
|
|
199
|
+
sage: omega = M.symplectic_form('omega', r'\omega')._init_derived()
|
|
200
|
+
"""
|
|
201
|
+
# Initialization of quantities pertaining to the mother class
|
|
202
|
+
DiffForm._init_derived(self)
|
|
203
|
+
|
|
204
|
+
self._poisson = None
|
|
205
|
+
self._vol_form = None
|
|
206
|
+
|
|
207
|
+
def _del_derived(self):
|
|
208
|
+
r"""
|
|
209
|
+
Delete the derived quantities.
|
|
210
|
+
|
|
211
|
+
TESTS::
|
|
212
|
+
|
|
213
|
+
sage: M.<q, p> = EuclideanSpace(2)
|
|
214
|
+
sage: omega = M.symplectic_form('omega', r'\omega')._del_derived()
|
|
215
|
+
"""
|
|
216
|
+
# Delete the derived quantities from the mother class
|
|
217
|
+
DiffForm._del_derived(self)
|
|
218
|
+
|
|
219
|
+
# Clear the Poisson tensor
|
|
220
|
+
if self._poisson is not None:
|
|
221
|
+
self._poisson._restrictions.clear()
|
|
222
|
+
self._poisson._del_derived()
|
|
223
|
+
self._poisson = None
|
|
224
|
+
|
|
225
|
+
# Delete the volume form
|
|
226
|
+
if self._vol_form is not None:
|
|
227
|
+
self._vol_form._restrictions.clear()
|
|
228
|
+
self._vol_form._del_derived()
|
|
229
|
+
self._vol_form = None
|
|
230
|
+
|
|
231
|
+
def restrict(
|
|
232
|
+
self, subdomain: DifferentiableManifold, dest_map: Optional[DiffMap] = None
|
|
233
|
+
) -> DiffForm:
|
|
234
|
+
r"""
|
|
235
|
+
Return the restriction of the symplectic form to some subdomain.
|
|
236
|
+
|
|
237
|
+
If the restriction has not been defined yet, it is constructed here.
|
|
238
|
+
|
|
239
|
+
INPUT:
|
|
240
|
+
|
|
241
|
+
- ``subdomain`` -- open subset `U` of the symplectic form's domain
|
|
242
|
+
- ``dest_map`` -- (default: ``None``) smooth destination map
|
|
243
|
+
`\Phi:\ U \to V`, where `V` is a subdomain of the symplectic form's domain
|
|
244
|
+
If ``None``, the restriction of the initial vector field module is used.
|
|
245
|
+
|
|
246
|
+
OUTPUT: the restricted symplectic form
|
|
247
|
+
|
|
248
|
+
EXAMPLES::
|
|
249
|
+
|
|
250
|
+
sage: M = Manifold(6, 'M')
|
|
251
|
+
sage: omega = M.symplectic_form()
|
|
252
|
+
sage: U = M.open_subset('U')
|
|
253
|
+
sage: omega.restrict(U)
|
|
254
|
+
2-form omega on the Open subset U of the 6-dimensional differentiable manifold M
|
|
255
|
+
"""
|
|
256
|
+
if subdomain == self._domain:
|
|
257
|
+
return self
|
|
258
|
+
|
|
259
|
+
if subdomain not in self._restrictions:
|
|
260
|
+
# Construct the restriction at the tensor field level
|
|
261
|
+
restriction = DiffForm.restrict(self, subdomain, dest_map=dest_map)
|
|
262
|
+
|
|
263
|
+
# Restrictions of derived quantities
|
|
264
|
+
if self._poisson is not None:
|
|
265
|
+
restriction._poisson = self._poisson.restrict(subdomain)
|
|
266
|
+
if self._vol_form is not None:
|
|
267
|
+
restriction._vol_form = self._vol_form.restrict(subdomain)
|
|
268
|
+
|
|
269
|
+
# The restriction is ready
|
|
270
|
+
self._restrictions[subdomain] = restriction
|
|
271
|
+
return restriction
|
|
272
|
+
else:
|
|
273
|
+
return self._restrictions[subdomain]
|
|
274
|
+
|
|
275
|
+
@staticmethod
|
|
276
|
+
def wrap(
|
|
277
|
+
form: DiffForm, name: Optional[str] = None, latex_name: Optional[str] = None
|
|
278
|
+
) -> SymplecticForm:
|
|
279
|
+
r"""
|
|
280
|
+
Define the symplectic form from a differential form.
|
|
281
|
+
|
|
282
|
+
INPUT:
|
|
283
|
+
|
|
284
|
+
- ``form`` -- differential `2`-form
|
|
285
|
+
|
|
286
|
+
EXAMPLES:
|
|
287
|
+
|
|
288
|
+
Volume form on the sphere as a symplectic form::
|
|
289
|
+
|
|
290
|
+
sage: from sage.manifolds.differentiable.symplectic_form import SymplecticForm
|
|
291
|
+
sage: M = manifolds.Sphere(2, coordinates='stereographic')
|
|
292
|
+
sage: vol_form = M.induced_metric().volume_form() # long time
|
|
293
|
+
sage: omega = SymplecticForm.wrap(vol_form, 'omega', r'\omega') # long time
|
|
294
|
+
sage: omega.display() # long time
|
|
295
|
+
omega = -4/(y1^4 + y2^4 + 2*(y1^2 + 1)*y2^2 + 2*y1^2 + 1) dy1∧dy2
|
|
296
|
+
"""
|
|
297
|
+
if form.degree() != 2:
|
|
298
|
+
raise TypeError("the argument must be a form of degree 2")
|
|
299
|
+
|
|
300
|
+
if name is None:
|
|
301
|
+
name = form._name
|
|
302
|
+
if latex_name is None:
|
|
303
|
+
latex_name = form._latex_name
|
|
304
|
+
|
|
305
|
+
symplectic_form = form.base_module().symplectic_form(name, latex_name)
|
|
306
|
+
|
|
307
|
+
for dom, rst in form._restrictions.items():
|
|
308
|
+
symplectic_form._restrictions[dom] = SymplecticForm.wrap(
|
|
309
|
+
rst, name, latex_name
|
|
310
|
+
)
|
|
311
|
+
|
|
312
|
+
if isinstance(form, DiffFormParal):
|
|
313
|
+
for frame in form._components:
|
|
314
|
+
symplectic_form._components[frame] = form._components[frame].copy()
|
|
315
|
+
|
|
316
|
+
return symplectic_form
|
|
317
|
+
|
|
318
|
+
def poisson(
|
|
319
|
+
self, expansion_symbol: Optional[Expression] = None, order: int = 1
|
|
320
|
+
) -> PoissonTensorField:
|
|
321
|
+
r"""
|
|
322
|
+
Return the Poisson tensor associated with the symplectic form.
|
|
323
|
+
|
|
324
|
+
INPUT:
|
|
325
|
+
|
|
326
|
+
- ``expansion_symbol`` -- (default: ``None``) symbolic variable; if
|
|
327
|
+
specified, the inverse will be expanded in power series with respect
|
|
328
|
+
to this variable (around its zero value)
|
|
329
|
+
- ``order`` -- integer (default: 1); the order of the expansion
|
|
330
|
+
if ``expansion_symbol`` is not ``None``; the *order* is defined as
|
|
331
|
+
the degree of the polynomial representing the truncated power series
|
|
332
|
+
in ``expansion_symbol``; currently only first order inverse is
|
|
333
|
+
supported
|
|
334
|
+
|
|
335
|
+
If ``expansion_symbol`` is set, then the zeroth order symplectic form must be
|
|
336
|
+
invertible. Moreover, subsequent calls to this method will return
|
|
337
|
+
a cached value, even when called with the default value (to enable
|
|
338
|
+
computation of derived quantities). To reset, use :meth:`_del_derived`.
|
|
339
|
+
|
|
340
|
+
OUTPUT:
|
|
341
|
+
|
|
342
|
+
- the Poisson tensor, as an instance of
|
|
343
|
+
:meth:`~sage.manifolds.differentiable.poisson_tensor.PoissonTensorField`
|
|
344
|
+
|
|
345
|
+
EXAMPLES:
|
|
346
|
+
|
|
347
|
+
Poisson tensor of `2`-dimensional symplectic vector space::
|
|
348
|
+
|
|
349
|
+
sage: M = manifolds.StandardSymplecticSpace(2)
|
|
350
|
+
sage: omega = M.symplectic_form()
|
|
351
|
+
sage: poisson = omega.poisson(); poisson
|
|
352
|
+
2-vector field poisson_omega on the Standard symplectic space R2
|
|
353
|
+
sage: poisson.display()
|
|
354
|
+
poisson_omega = -e_q∧e_p
|
|
355
|
+
"""
|
|
356
|
+
if self._poisson is None:
|
|
357
|
+
# Initialize the Poisson tensor
|
|
358
|
+
poisson_name = f"poisson_{self._name}"
|
|
359
|
+
poisson_latex_name = f"{self._latex_name}^{{-1}}"
|
|
360
|
+
self._poisson = self._vmodule.poisson_tensor(
|
|
361
|
+
poisson_name, poisson_latex_name
|
|
362
|
+
)
|
|
363
|
+
|
|
364
|
+
# Update the Poisson tensor
|
|
365
|
+
# TODO: Should this be done instead when a new restriction is added?
|
|
366
|
+
for domain, restriction in self._restrictions.items():
|
|
367
|
+
# Forces the update of the restriction
|
|
368
|
+
self._poisson._restrictions[domain] = restriction.poisson(
|
|
369
|
+
expansion_symbol=expansion_symbol, order=order
|
|
370
|
+
)
|
|
371
|
+
return self._poisson
|
|
372
|
+
|
|
373
|
+
def hamiltonian_vector_field(self, function: DiffScalarField) -> VectorField:
|
|
374
|
+
r"""
|
|
375
|
+
The Hamiltonian vector field `X_f` generated by a function `f: M \to \RR`.
|
|
376
|
+
|
|
377
|
+
The Hamiltonian vector field is defined by
|
|
378
|
+
|
|
379
|
+
.. MATH::
|
|
380
|
+
|
|
381
|
+
X_f \lrcorner \omega + df = 0.
|
|
382
|
+
|
|
383
|
+
INPUT:
|
|
384
|
+
|
|
385
|
+
- ``function`` -- the function generating the Hamiltonian vector field
|
|
386
|
+
|
|
387
|
+
EXAMPLES::
|
|
388
|
+
|
|
389
|
+
sage: M = manifolds.StandardSymplecticSpace(2)
|
|
390
|
+
sage: omega = M.symplectic_form()
|
|
391
|
+
sage: f = M.scalar_field({ chart: function('f')(*chart[:]) for chart in M.atlas() }, name='f')
|
|
392
|
+
sage: f.display()
|
|
393
|
+
f: R2 → ℝ
|
|
394
|
+
(q, p) ↦ f(q, p)
|
|
395
|
+
sage: Xf = omega.hamiltonian_vector_field(f)
|
|
396
|
+
sage: Xf.display()
|
|
397
|
+
Xf = d(f)/dp e_q - d(f)/dq e_p
|
|
398
|
+
"""
|
|
399
|
+
return self.poisson().hamiltonian_vector_field(function)
|
|
400
|
+
|
|
401
|
+
def flat(self, vector_field: VectorField) -> DiffForm:
|
|
402
|
+
r"""
|
|
403
|
+
Return the image of the given differential form under the
|
|
404
|
+
map `\omega^\flat: T M \to T^*M` defined by
|
|
405
|
+
|
|
406
|
+
.. MATH::
|
|
407
|
+
|
|
408
|
+
<\omega^\flat(X), Y> = \omega_m (X, Y)
|
|
409
|
+
|
|
410
|
+
for all `X, Y \in T_m M`.
|
|
411
|
+
|
|
412
|
+
In indices, `X_i = \omega_{ji} X^j`.
|
|
413
|
+
|
|
414
|
+
INPUT:
|
|
415
|
+
|
|
416
|
+
- ``vector_field`` -- the vector field to calculate its flat of
|
|
417
|
+
|
|
418
|
+
EXAMPLES::
|
|
419
|
+
|
|
420
|
+
sage: M = manifolds.StandardSymplecticSpace(2)
|
|
421
|
+
sage: omega = M.symplectic_form()
|
|
422
|
+
sage: X = M.vector_field_module().an_element()
|
|
423
|
+
sage: X.set_name('X')
|
|
424
|
+
sage: X.display()
|
|
425
|
+
X = 2 e_q + 2 e_p
|
|
426
|
+
sage: omega.flat(X).display()
|
|
427
|
+
X_flat = 2 dq - 2 dp
|
|
428
|
+
"""
|
|
429
|
+
form = vector_field.down(self)
|
|
430
|
+
form.set_name(
|
|
431
|
+
vector_field._name + "_flat", vector_field._latex_name + "^\\flat"
|
|
432
|
+
)
|
|
433
|
+
return form
|
|
434
|
+
|
|
435
|
+
def sharp(self, form: DiffForm) -> VectorField:
|
|
436
|
+
r"""
|
|
437
|
+
Return the image of the given differential form under the map
|
|
438
|
+
`\omega^\sharp: T^* M \to TM` defined by
|
|
439
|
+
|
|
440
|
+
.. MATH::
|
|
441
|
+
|
|
442
|
+
\omega (\omega^\sharp(\alpha), X) = \alpha(X)
|
|
443
|
+
|
|
444
|
+
for all `X \in T_m M` and `\alpha \in T^*_m M`.
|
|
445
|
+
The sharp map is inverse to the flat map.
|
|
446
|
+
|
|
447
|
+
In indices, `\alpha^i = \varpi^{ij} \alpha_j`, where `\varpi` is
|
|
448
|
+
the Poisson tensor associated with the symplectic form.
|
|
449
|
+
|
|
450
|
+
INPUT:
|
|
451
|
+
|
|
452
|
+
- ``form`` -- the differential form to calculate its sharp of
|
|
453
|
+
|
|
454
|
+
EXAMPLES::
|
|
455
|
+
|
|
456
|
+
sage: M = manifolds.StandardSymplecticSpace(2)
|
|
457
|
+
sage: omega = M.symplectic_form()
|
|
458
|
+
sage: X = M.vector_field_module().an_element()
|
|
459
|
+
sage: alpha = omega.flat(X)
|
|
460
|
+
sage: alpha.set_name('alpha')
|
|
461
|
+
sage: alpha.display()
|
|
462
|
+
alpha = 2 dq - 2 dp
|
|
463
|
+
sage: omega.sharp(alpha).display()
|
|
464
|
+
alpha_sharp = 2 e_q + 2 e_p
|
|
465
|
+
"""
|
|
466
|
+
return self.poisson().sharp(form)
|
|
467
|
+
|
|
468
|
+
def poisson_bracket(
|
|
469
|
+
self, f: DiffScalarField, g: DiffScalarField
|
|
470
|
+
) -> DiffScalarField:
|
|
471
|
+
r"""
|
|
472
|
+
Return the Poisson bracket
|
|
473
|
+
|
|
474
|
+
.. MATH::
|
|
475
|
+
|
|
476
|
+
\{f, g\} = \omega(X_f, X_g)
|
|
477
|
+
|
|
478
|
+
of the given functions.
|
|
479
|
+
|
|
480
|
+
INPUT:
|
|
481
|
+
|
|
482
|
+
- ``f`` -- function inserted in the first slot
|
|
483
|
+
- ``g`` -- function inserted in the second slot
|
|
484
|
+
|
|
485
|
+
EXAMPLES::
|
|
486
|
+
|
|
487
|
+
sage: M.<q, p> = EuclideanSpace(2)
|
|
488
|
+
sage: poisson = M.poisson_tensor('varpi')
|
|
489
|
+
sage: poisson.set_comp()[1,2] = -1
|
|
490
|
+
sage: f = M.scalar_field({ chart: function('f')(*chart[:]) for chart in M.atlas() }, name='f')
|
|
491
|
+
sage: g = M.scalar_field({ chart: function('g')(*chart[:]) for chart in M.atlas() }, name='g')
|
|
492
|
+
sage: poisson.poisson_bracket(f, g).display()
|
|
493
|
+
poisson(f, g): E^2 → ℝ
|
|
494
|
+
(q, p) ↦ d(f)/dp*d(g)/dq - d(f)/dq*d(g)/dp
|
|
495
|
+
"""
|
|
496
|
+
return self.poisson().poisson_bracket(f, g)
|
|
497
|
+
|
|
498
|
+
def volume_form(self, contra: int = 0) -> TensorField:
|
|
499
|
+
r"""
|
|
500
|
+
Liouville volume form `\frac{1}{n!}\omega^n` associated with the
|
|
501
|
+
symplectic form `\omega`, where `2n` is the dimension of the manifold.
|
|
502
|
+
|
|
503
|
+
INPUT:
|
|
504
|
+
|
|
505
|
+
- ``contra`` -- (default: 0) number of contravariant indices of the
|
|
506
|
+
returned tensor
|
|
507
|
+
|
|
508
|
+
OUTPUT:
|
|
509
|
+
|
|
510
|
+
- if ``contra = 0``: volume form associated with the symplectic form
|
|
511
|
+
- if ``contra = k``, with `1\leq k \leq n`, the tensor field of type
|
|
512
|
+
(k,n-k) formed from `\epsilon` by raising the first k indices with
|
|
513
|
+
the symplectic form (see method
|
|
514
|
+
:meth:`~sage.manifolds.differentiable.tensorfield.TensorField.up`)
|
|
515
|
+
|
|
516
|
+
EXAMPLES:
|
|
517
|
+
|
|
518
|
+
Volume form on `\RR^4`::
|
|
519
|
+
|
|
520
|
+
sage: M = manifolds.StandardSymplecticSpace(4)
|
|
521
|
+
sage: omega = M.symplectic_form()
|
|
522
|
+
sage: vol = omega.volume_form() ; vol
|
|
523
|
+
4-form mu_omega on the Standard symplectic space R4
|
|
524
|
+
sage: vol.display()
|
|
525
|
+
mu_omega = dq1∧dp1∧dq2∧dp2
|
|
526
|
+
"""
|
|
527
|
+
if self._vol_form is None:
|
|
528
|
+
from sage.functions.other import factorial
|
|
529
|
+
|
|
530
|
+
vol_form = self
|
|
531
|
+
for _ in range(1, self._dim_half):
|
|
532
|
+
vol_form = vol_form.wedge(self)
|
|
533
|
+
vol_form = vol_form / factorial(self._dim_half)
|
|
534
|
+
|
|
535
|
+
volume_name = f"mu_{self._name}"
|
|
536
|
+
volume_latex_name = f"\\mu_{self._latex_name}"
|
|
537
|
+
vol_form.set_name(volume_name, volume_latex_name)
|
|
538
|
+
self._vol_form = vol_form
|
|
539
|
+
|
|
540
|
+
result = self._vol_form
|
|
541
|
+
for k in range(contra):
|
|
542
|
+
result = result.up(self, k)
|
|
543
|
+
if contra > 1:
|
|
544
|
+
# restoring the antisymmetry after the up operation:
|
|
545
|
+
result = result.antisymmetrize(*range(contra))
|
|
546
|
+
return result
|
|
547
|
+
|
|
548
|
+
def hodge_star(self, pform: DiffForm) -> DiffForm:
|
|
549
|
+
r"""
|
|
550
|
+
Compute the Hodge dual of a differential form with respect to the
|
|
551
|
+
symplectic form.
|
|
552
|
+
|
|
553
|
+
See :meth:`~sage.manifolds.differentiable.diff_form.DiffForm.hodge_dual`
|
|
554
|
+
for the definition and more details.
|
|
555
|
+
|
|
556
|
+
INPUT:
|
|
557
|
+
|
|
558
|
+
- ``pform`` -- a `p`-form `A`; must be an instance of
|
|
559
|
+
:class:`~sage.manifolds.differentiable.scalarfield.DiffScalarField`
|
|
560
|
+
for `p=0` and of
|
|
561
|
+
:class:`~sage.manifolds.differentiable.diff_form.DiffForm` or
|
|
562
|
+
:class:`~sage.manifolds.differentiable.diff_form.DiffFormParal`
|
|
563
|
+
for `p\geq 1`.
|
|
564
|
+
|
|
565
|
+
OUTPUT:
|
|
566
|
+
|
|
567
|
+
- the `(n-p)`-form `*A`
|
|
568
|
+
|
|
569
|
+
EXAMPLES:
|
|
570
|
+
|
|
571
|
+
Hodge dual of any form on the symplectic vector space `R^2`::
|
|
572
|
+
|
|
573
|
+
sage: M = manifolds.StandardSymplecticSpace(2)
|
|
574
|
+
sage: omega = M.symplectic_form()
|
|
575
|
+
sage: a = M.one_form(1, 0, name='a')
|
|
576
|
+
sage: omega.hodge_star(a).display()
|
|
577
|
+
*a = dq
|
|
578
|
+
sage: b = M.one_form(0, 1, name='b')
|
|
579
|
+
sage: omega.hodge_star(b).display()
|
|
580
|
+
*b = dp
|
|
581
|
+
sage: f = M.scalar_field(1, name='f')
|
|
582
|
+
sage: omega.hodge_star(f).display()
|
|
583
|
+
*f = -dq∧dp
|
|
584
|
+
sage: omega.hodge_star(omega).display()
|
|
585
|
+
*omega: R2 → ℝ
|
|
586
|
+
(q, p) ↦ 1
|
|
587
|
+
"""
|
|
588
|
+
return pform.hodge_dual(self)
|
|
589
|
+
|
|
590
|
+
def on_forms(self, first: DiffForm, second: DiffForm) -> DiffScalarField:
|
|
591
|
+
r"""
|
|
592
|
+
Return the contraction of the two forms with respect to the symplectic form.
|
|
593
|
+
|
|
594
|
+
The symplectic form `\omega` gives rise to a bilinear form,
|
|
595
|
+
also denoted by `\omega` on the space of `1`-forms by
|
|
596
|
+
|
|
597
|
+
.. MATH::
|
|
598
|
+
\omega(\alpha, \beta) = \omega(\alpha^\sharp, \beta^\sharp),
|
|
599
|
+
|
|
600
|
+
where `\alpha^\sharp` is the dual of `\alpha` with respect to `\omega`, see
|
|
601
|
+
:meth:`~sage.manifolds.differentiable.tensor_field.TensorField.up`.
|
|
602
|
+
This bilinear form induces a bilinear form on the space of all forms determined
|
|
603
|
+
by its value on decomposable elements as:
|
|
604
|
+
|
|
605
|
+
.. MATH::
|
|
606
|
+
\omega(\alpha_1 \wedge \ldots \wedge\alpha_p, \beta_1 \wedge \ldots \wedge\beta_p)
|
|
607
|
+
= det(\omega(\alpha_i, \beta_j)).
|
|
608
|
+
|
|
609
|
+
INPUT:
|
|
610
|
+
|
|
611
|
+
- ``first`` -- a `p`-form `\alpha`
|
|
612
|
+
- ``second`` -- a `p`-form `\beta`
|
|
613
|
+
|
|
614
|
+
OUTPUT:
|
|
615
|
+
|
|
616
|
+
- the scalar field `\omega(\alpha, \beta)`
|
|
617
|
+
|
|
618
|
+
EXAMPLES:
|
|
619
|
+
|
|
620
|
+
sage: M = manifolds.StandardSymplecticSpace(2)
|
|
621
|
+
sage: omega = M.symplectic_form()
|
|
622
|
+
sage: a = M.one_form(1, 0, name='a')
|
|
623
|
+
sage: b = M.one_form(0, 1, name='b')
|
|
624
|
+
sage: omega.on_forms(a, b).display()
|
|
625
|
+
R2 → ℝ
|
|
626
|
+
(q, p) ↦ -1
|
|
627
|
+
"""
|
|
628
|
+
from sage.arith.misc import factorial
|
|
629
|
+
|
|
630
|
+
if first.degree() != second.degree():
|
|
631
|
+
raise ValueError("the two forms must have the same degree")
|
|
632
|
+
|
|
633
|
+
all_positions = range(first.degree())
|
|
634
|
+
return first.contract(
|
|
635
|
+
*all_positions, second.up(self), *all_positions
|
|
636
|
+
) / factorial(first.degree())
|
|
637
|
+
|
|
638
|
+
|
|
639
|
+
class SymplecticFormParal(SymplecticForm, DiffFormParal):
|
|
640
|
+
r"""
|
|
641
|
+
A symplectic form on a parallelizable manifold.
|
|
642
|
+
|
|
643
|
+
.. NOTE::
|
|
644
|
+
|
|
645
|
+
If `M` is not parallelizable, the class :class:`SymplecticForm`
|
|
646
|
+
should be used instead.
|
|
647
|
+
|
|
648
|
+
INPUT:
|
|
649
|
+
|
|
650
|
+
- ``manifold`` -- module `\mathfrak{X}(M)` of vector fields on the
|
|
651
|
+
manifold `M`, or the manifold `M` itself
|
|
652
|
+
- ``name`` -- (default: ``omega``) name given to the symplectic form
|
|
653
|
+
- ``latex_name`` -- (default: ``None``) LaTeX symbol to denote the
|
|
654
|
+
symplectic form; if ``None``, it is formed from ``name``
|
|
655
|
+
|
|
656
|
+
EXAMPLES:
|
|
657
|
+
|
|
658
|
+
Standard symplectic form on `\RR^2`::
|
|
659
|
+
|
|
660
|
+
sage: M.<q, p> = EuclideanSpace(name='R2', latex_name=r"\mathbb{R}^2")
|
|
661
|
+
sage: omega = M.symplectic_form(name='omega', latex_name=r'\omega')
|
|
662
|
+
sage: omega
|
|
663
|
+
Symplectic form omega on the Euclidean plane R2
|
|
664
|
+
sage: omega.set_comp()[1,2] = -1
|
|
665
|
+
sage: omega.display()
|
|
666
|
+
omega = -dq∧dp
|
|
667
|
+
"""
|
|
668
|
+
_poisson: TensorFieldParal
|
|
669
|
+
|
|
670
|
+
def __init__(
|
|
671
|
+
self,
|
|
672
|
+
manifold: Union[VectorFieldModule, DifferentiableManifold],
|
|
673
|
+
name: Optional[str],
|
|
674
|
+
latex_name: Optional[str] = None,
|
|
675
|
+
):
|
|
676
|
+
r"""
|
|
677
|
+
Construct a symplectic form.
|
|
678
|
+
|
|
679
|
+
TESTS::
|
|
680
|
+
|
|
681
|
+
sage: from sage.manifolds.differentiable.symplectic_form import SymplecticFormParal
|
|
682
|
+
sage: M = EuclideanSpace(2)
|
|
683
|
+
sage: omega = SymplecticFormParal(M, name='omega', latex_name=r'\omega')
|
|
684
|
+
sage: omega
|
|
685
|
+
Symplectic form omega on the Euclidean plane E^2
|
|
686
|
+
"""
|
|
687
|
+
try:
|
|
688
|
+
vector_field_module = manifold.vector_field_module()
|
|
689
|
+
except AttributeError:
|
|
690
|
+
vector_field_module = manifold
|
|
691
|
+
|
|
692
|
+
if name is None:
|
|
693
|
+
name = "omega"
|
|
694
|
+
|
|
695
|
+
DiffFormParal.__init__(
|
|
696
|
+
self, vector_field_module, 2, name=name, latex_name=latex_name
|
|
697
|
+
)
|
|
698
|
+
|
|
699
|
+
# Check that manifold is even dimensional
|
|
700
|
+
dim = self._ambient_domain.dimension()
|
|
701
|
+
if dim % 2 == 1:
|
|
702
|
+
raise ValueError(
|
|
703
|
+
f"the dimension of the manifold must be even but it is {dim}"
|
|
704
|
+
)
|
|
705
|
+
self._dim_half = dim // 2
|
|
706
|
+
|
|
707
|
+
# Initialization of derived quantities
|
|
708
|
+
SymplecticFormParal._init_derived(self)
|
|
709
|
+
|
|
710
|
+
def _init_derived(self):
|
|
711
|
+
r"""
|
|
712
|
+
Initialize the derived quantities.
|
|
713
|
+
|
|
714
|
+
TESTS::
|
|
715
|
+
|
|
716
|
+
sage: from sage.manifolds.differentiable.symplectic_form import SymplecticFormParal
|
|
717
|
+
sage: M = EuclideanSpace(2)
|
|
718
|
+
sage: omega = SymplecticFormParal(M, 'omega', r'\omega')
|
|
719
|
+
sage: omega._init_derived()
|
|
720
|
+
"""
|
|
721
|
+
# Initialization of quantities pertaining to mother classes
|
|
722
|
+
DiffFormParal._init_derived(self)
|
|
723
|
+
SymplecticForm._init_derived(self)
|
|
724
|
+
|
|
725
|
+
def _del_derived(self, del_restrictions: bool = True):
|
|
726
|
+
r"""
|
|
727
|
+
Delete the derived quantities.
|
|
728
|
+
|
|
729
|
+
INPUT:
|
|
730
|
+
|
|
731
|
+
- ``del_restrictions`` -- boolean (default: ``True``); determines whether the
|
|
732
|
+
restrictions of ``self`` to subdomains are deleted
|
|
733
|
+
|
|
734
|
+
TESTS::
|
|
735
|
+
|
|
736
|
+
sage: from sage.manifolds.differentiable.symplectic_form import SymplecticFormParal
|
|
737
|
+
sage: M.<q, p> = EuclideanSpace(2, "R2", r"\mathbb{R}^2", symbols=r"q:q p:p")
|
|
738
|
+
sage: omega = SymplecticFormParal(M, 'omega', r'\omega')
|
|
739
|
+
sage: omega._del_derived(del_restrictions=False)
|
|
740
|
+
sage: omega._del_derived()
|
|
741
|
+
"""
|
|
742
|
+
# Delete derived quantities from mother classes
|
|
743
|
+
DiffFormParal._del_derived(self, del_restrictions=del_restrictions)
|
|
744
|
+
|
|
745
|
+
# Clear the Poisson tensor
|
|
746
|
+
if self._poisson is not None:
|
|
747
|
+
self._poisson._components.clear()
|
|
748
|
+
self._poisson._del_derived()
|
|
749
|
+
|
|
750
|
+
SymplecticForm._del_derived(self)
|
|
751
|
+
|
|
752
|
+
def restrict(
|
|
753
|
+
self, subdomain: DifferentiableManifold, dest_map: Optional[DiffMap] = None
|
|
754
|
+
) -> SymplecticFormParal:
|
|
755
|
+
r"""
|
|
756
|
+
Return the restriction of the symplectic form to some subdomain.
|
|
757
|
+
|
|
758
|
+
If the restriction has not been defined yet, it is constructed here.
|
|
759
|
+
|
|
760
|
+
INPUT:
|
|
761
|
+
|
|
762
|
+
- ``subdomain`` -- open subset `U` of the symplectic form's domain
|
|
763
|
+
- ``dest_map`` -- (default: ``None``) smooth destination map
|
|
764
|
+
`\Phi:\ U \rightarrow V`, where `V` is a subdomain of the symplectic form's domain.
|
|
765
|
+
If ``None``, the restriction of the initial vector field module is used.
|
|
766
|
+
|
|
767
|
+
OUTPUT: the restricted symplectic form
|
|
768
|
+
|
|
769
|
+
EXAMPLES:
|
|
770
|
+
|
|
771
|
+
Restriction of the standard symplectic form on `\RR^2` to the upper half plane::
|
|
772
|
+
|
|
773
|
+
sage: from sage.manifolds.differentiable.symplectic_form import SymplecticFormParal
|
|
774
|
+
sage: M = EuclideanSpace(2, "R2", r"\mathbb{R}^2", symbols=r"q:q p:p")
|
|
775
|
+
sage: X.<q, p> = M.chart()
|
|
776
|
+
sage: omega = SymplecticFormParal(M, 'omega', r'\omega')
|
|
777
|
+
sage: omega[1,2] = -1
|
|
778
|
+
sage: U = M.open_subset('U', coord_def={X: q>0})
|
|
779
|
+
sage: omegaU = omega.restrict(U); omegaU
|
|
780
|
+
Symplectic form omega on the Open subset U of the Euclidean plane R2
|
|
781
|
+
sage: omegaU.display()
|
|
782
|
+
omega = -dq∧dp
|
|
783
|
+
"""
|
|
784
|
+
if subdomain == self._domain:
|
|
785
|
+
return self
|
|
786
|
+
if subdomain not in self._restrictions:
|
|
787
|
+
# Construct the restriction at the tensor field level:
|
|
788
|
+
resu = DiffFormParal.restrict(self, subdomain, dest_map=dest_map)
|
|
789
|
+
|
|
790
|
+
self._restrictions[subdomain] = SymplecticFormParal.wrap(resu)
|
|
791
|
+
return self._restrictions[subdomain]
|
|
792
|
+
|
|
793
|
+
def poisson(
|
|
794
|
+
self, expansion_symbol: Optional[Expression] = None, order: int = 1
|
|
795
|
+
) -> TensorFieldParal:
|
|
796
|
+
r"""
|
|
797
|
+
Return the Poisson tensor associated with the symplectic form.
|
|
798
|
+
|
|
799
|
+
INPUT:
|
|
800
|
+
|
|
801
|
+
- ``expansion_symbol`` -- (default: ``None``) symbolic variable; if
|
|
802
|
+
specified, the inverse will be expanded in power series with respect
|
|
803
|
+
to this variable (around its zero value)
|
|
804
|
+
- ``order`` -- integer (default: 1); the order of the expansion
|
|
805
|
+
if ``expansion_symbol`` is not ``None``; the *order* is defined as
|
|
806
|
+
the degree of the polynomial representing the truncated power series
|
|
807
|
+
in ``expansion_symbol``; currently only first order inverse is
|
|
808
|
+
supported
|
|
809
|
+
|
|
810
|
+
If ``expansion_symbol`` is set, then the zeroth order symplectic form must be
|
|
811
|
+
invertible. Moreover, subsequent calls to this method will return
|
|
812
|
+
a cached value, even when called with the default value (to enable
|
|
813
|
+
computation of derived quantities). To reset, use :meth:`_del_derived`.
|
|
814
|
+
|
|
815
|
+
OUTPUT:
|
|
816
|
+
|
|
817
|
+
- the Poisson tensor, , as an instance of
|
|
818
|
+
:meth:`~sage.manifolds.differentiable.poisson_tensor.PoissonTensorFieldParal`
|
|
819
|
+
|
|
820
|
+
EXAMPLES:
|
|
821
|
+
|
|
822
|
+
Poisson tensor of `2`-dimensional symplectic vector space::
|
|
823
|
+
|
|
824
|
+
sage: from sage.manifolds.differentiable.symplectic_form import SymplecticFormParal
|
|
825
|
+
sage: M.<q, p> = EuclideanSpace(2, "R2", r"\mathbb{R}^2", symbols=r"q:q p:p")
|
|
826
|
+
sage: omega = SymplecticFormParal(M, 'omega', r'\omega')
|
|
827
|
+
sage: omega[1,2] = -1
|
|
828
|
+
sage: poisson = omega.poisson(); poisson
|
|
829
|
+
2-vector field poisson_omega on the Euclidean plane R2
|
|
830
|
+
sage: poisson.display()
|
|
831
|
+
poisson_omega = -e_q∧e_p
|
|
832
|
+
"""
|
|
833
|
+
super().poisson()
|
|
834
|
+
|
|
835
|
+
if expansion_symbol is not None:
|
|
836
|
+
if (
|
|
837
|
+
self._poisson is not None
|
|
838
|
+
and bool(self._poisson._components)
|
|
839
|
+
and list(self._poisson._components.values())[0][0, 0]._expansion_symbol
|
|
840
|
+
== expansion_symbol
|
|
841
|
+
and list(self._poisson._components.values())[0][0, 0]._order == order
|
|
842
|
+
):
|
|
843
|
+
return self._poisson
|
|
844
|
+
|
|
845
|
+
if order != 1:
|
|
846
|
+
raise NotImplementedError("only first order inverse is implemented")
|
|
847
|
+
decompo = self.series_expansion(expansion_symbol, order)
|
|
848
|
+
g0 = decompo[0]
|
|
849
|
+
g1 = decompo[1]
|
|
850
|
+
|
|
851
|
+
g0m = self._new_instance() # needed because only metrics have
|
|
852
|
+
g0m.set_comp()[:] = g0[:] # an "inverse" method.
|
|
853
|
+
|
|
854
|
+
contraction = g1.contract(0, g0m.inverse(), 0)
|
|
855
|
+
contraction = contraction.contract(1, g0m.inverse(), 1)
|
|
856
|
+
self._poisson = -(g0m.inverse() - expansion_symbol * contraction)
|
|
857
|
+
self._poisson.set_calc_order(expansion_symbol, order)
|
|
858
|
+
return self._poisson
|
|
859
|
+
|
|
860
|
+
from sage.matrix.constructor import matrix
|
|
861
|
+
from sage.tensor.modules.comp import CompFullyAntiSym
|
|
862
|
+
|
|
863
|
+
# Is the inverse metric up to date ?
|
|
864
|
+
for frame in self._components:
|
|
865
|
+
if frame not in self._poisson._components:
|
|
866
|
+
# the computation is necessary
|
|
867
|
+
fmodule = self._fmodule
|
|
868
|
+
si = fmodule._sindex
|
|
869
|
+
nsi = fmodule.rank() + si
|
|
870
|
+
dom = self._domain
|
|
871
|
+
comp_poisson = CompFullyAntiSym(
|
|
872
|
+
fmodule._ring,
|
|
873
|
+
frame,
|
|
874
|
+
2,
|
|
875
|
+
start_index=si,
|
|
876
|
+
output_formatter=fmodule._output_formatter,
|
|
877
|
+
)
|
|
878
|
+
comp_poisson_scal = (
|
|
879
|
+
{}
|
|
880
|
+
) # dict. of scalars representing the components of the poisson tensor (keys: comp. indices)
|
|
881
|
+
for i in fmodule.irange():
|
|
882
|
+
for j in range(i, nsi): # symmetry taken into account
|
|
883
|
+
comp_poisson_scal[(i, j)] = dom.scalar_field()
|
|
884
|
+
for chart in dom.top_charts():
|
|
885
|
+
# TODO: do the computation without the 'SR' enforcement
|
|
886
|
+
try:
|
|
887
|
+
self_matrix = matrix(
|
|
888
|
+
[
|
|
889
|
+
[
|
|
890
|
+
self.comp(frame)[i, j, chart].expr(method='SR')
|
|
891
|
+
for j in fmodule.irange()
|
|
892
|
+
]
|
|
893
|
+
for i in fmodule.irange()
|
|
894
|
+
]
|
|
895
|
+
)
|
|
896
|
+
self_matrix_inv = self_matrix.inverse()
|
|
897
|
+
except (KeyError, ValueError):
|
|
898
|
+
continue
|
|
899
|
+
for i in fmodule.irange():
|
|
900
|
+
for j in range(i, nsi):
|
|
901
|
+
val = chart.simplify(
|
|
902
|
+
-self_matrix_inv[i - si, j - si], method="SR"
|
|
903
|
+
)
|
|
904
|
+
comp_poisson_scal[(i, j)].add_expr(val, chart=chart)
|
|
905
|
+
for i in range(si, nsi):
|
|
906
|
+
for j in range(i, nsi):
|
|
907
|
+
comp_poisson[i, j] = comp_poisson_scal[(i, j)]
|
|
908
|
+
self._poisson._components[frame] = comp_poisson
|
|
909
|
+
return self._poisson
|
|
910
|
+
|
|
911
|
+
|
|
912
|
+
# ****************************************************************************************
|