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