passagemath-symbolics 10.6.37__cp310-cp310-musllinux_1_2_x86_64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- passagemath_symbolics/__init__.py +3 -0
- passagemath_symbolics-10.6.37.dist-info/METADATA +187 -0
- passagemath_symbolics-10.6.37.dist-info/RECORD +171 -0
- passagemath_symbolics-10.6.37.dist-info/WHEEL +5 -0
- passagemath_symbolics-10.6.37.dist-info/top_level.txt +3 -0
- sage/all__sagemath_symbolics.py +17 -0
- sage/calculus/all.py +14 -0
- sage/calculus/calculus.py +2826 -0
- sage/calculus/desolvers.py +1866 -0
- sage/calculus/predefined.py +51 -0
- sage/calculus/tests.py +225 -0
- sage/calculus/var.cpython-310-x86_64-linux-gnu.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-310-x86_64-linux-gnu.so +0 -0
- sage/dynamics/complex_dynamics/mandel_julia_helper.pyx +1035 -0
- sage/ext/all__sagemath_symbolics.py +1 -0
- sage/ext_data/kenzo/CP2.txt +45 -0
- sage/ext_data/kenzo/CP3.txt +349 -0
- sage/ext_data/kenzo/CP4.txt +4774 -0
- sage/ext_data/kenzo/README.txt +49 -0
- sage/ext_data/kenzo/S4.txt +20 -0
- sage/ext_data/magma/latex/latex.m +1021 -0
- sage/ext_data/magma/latex/latex.spec +1 -0
- sage/ext_data/magma/sage/basic.m +356 -0
- sage/ext_data/magma/sage/sage.spec +1 -0
- sage/ext_data/magma/spec +9 -0
- sage/geometry/all__sagemath_symbolics.py +8 -0
- sage/geometry/hyperbolic_space/all.py +5 -0
- sage/geometry/hyperbolic_space/hyperbolic_coercion.py +743 -0
- sage/geometry/hyperbolic_space/hyperbolic_constants.py +5 -0
- sage/geometry/hyperbolic_space/hyperbolic_geodesic.py +2409 -0
- sage/geometry/hyperbolic_space/hyperbolic_interface.py +206 -0
- sage/geometry/hyperbolic_space/hyperbolic_isometry.py +1082 -0
- sage/geometry/hyperbolic_space/hyperbolic_model.py +1502 -0
- sage/geometry/hyperbolic_space/hyperbolic_point.py +621 -0
- sage/geometry/riemannian_manifolds/all.py +7 -0
- sage/geometry/riemannian_manifolds/parametrized_surface3d.py +1632 -0
- sage/geometry/riemannian_manifolds/surface3d_generators.py +461 -0
- sage/interfaces/all__sagemath_symbolics.py +1 -0
- sage/interfaces/magma.py +3017 -0
- sage/interfaces/magma_free.py +92 -0
- sage/interfaces/maple.py +1397 -0
- sage/interfaces/mathematica.py +1345 -0
- sage/interfaces/mathics.py +1312 -0
- sage/interfaces/sympy.py +1398 -0
- sage/interfaces/sympy_wrapper.py +197 -0
- sage/interfaces/tides.py +938 -0
- sage/libs/all__sagemath_symbolics.py +6 -0
- sage/manifolds/all.py +7 -0
- sage/manifolds/calculus_method.py +555 -0
- sage/manifolds/catalog.py +437 -0
- sage/manifolds/chart.py +4019 -0
- sage/manifolds/chart_func.py +3419 -0
- sage/manifolds/continuous_map.py +2183 -0
- sage/manifolds/continuous_map_image.py +155 -0
- sage/manifolds/differentiable/affine_connection.py +2475 -0
- sage/manifolds/differentiable/all.py +1 -0
- sage/manifolds/differentiable/automorphismfield.py +1383 -0
- sage/manifolds/differentiable/automorphismfield_group.py +604 -0
- sage/manifolds/differentiable/bundle_connection.py +1445 -0
- sage/manifolds/differentiable/characteristic_cohomology_class.py +1840 -0
- sage/manifolds/differentiable/chart.py +1241 -0
- sage/manifolds/differentiable/curve.py +1028 -0
- sage/manifolds/differentiable/de_rham_cohomology.py +541 -0
- sage/manifolds/differentiable/degenerate.py +559 -0
- sage/manifolds/differentiable/degenerate_submanifold.py +1671 -0
- sage/manifolds/differentiable/diff_form.py +1658 -0
- sage/manifolds/differentiable/diff_form_module.py +1062 -0
- sage/manifolds/differentiable/diff_map.py +1315 -0
- sage/manifolds/differentiable/differentiable_submanifold.py +291 -0
- sage/manifolds/differentiable/examples/all.py +1 -0
- sage/manifolds/differentiable/examples/euclidean.py +2517 -0
- sage/manifolds/differentiable/examples/real_line.py +897 -0
- sage/manifolds/differentiable/examples/sphere.py +1186 -0
- sage/manifolds/differentiable/examples/symplectic_space.py +187 -0
- sage/manifolds/differentiable/examples/symplectic_space_test.py +40 -0
- sage/manifolds/differentiable/integrated_curve.py +4035 -0
- sage/manifolds/differentiable/levi_civita_connection.py +841 -0
- sage/manifolds/differentiable/manifold.py +4254 -0
- sage/manifolds/differentiable/manifold_homset.py +1826 -0
- sage/manifolds/differentiable/metric.py +3032 -0
- sage/manifolds/differentiable/mixed_form.py +1507 -0
- sage/manifolds/differentiable/mixed_form_algebra.py +559 -0
- sage/manifolds/differentiable/multivector_module.py +800 -0
- sage/manifolds/differentiable/multivectorfield.py +1520 -0
- sage/manifolds/differentiable/poisson_tensor.py +268 -0
- sage/manifolds/differentiable/pseudo_riemannian.py +755 -0
- sage/manifolds/differentiable/pseudo_riemannian_submanifold.py +1839 -0
- sage/manifolds/differentiable/scalarfield.py +1343 -0
- sage/manifolds/differentiable/scalarfield_algebra.py +472 -0
- sage/manifolds/differentiable/symplectic_form.py +910 -0
- sage/manifolds/differentiable/symplectic_form_test.py +220 -0
- sage/manifolds/differentiable/tangent_space.py +412 -0
- sage/manifolds/differentiable/tangent_vector.py +616 -0
- sage/manifolds/differentiable/tensorfield.py +4665 -0
- sage/manifolds/differentiable/tensorfield_module.py +963 -0
- sage/manifolds/differentiable/tensorfield_paral.py +2450 -0
- sage/manifolds/differentiable/tensorfield_paral_test.py +16 -0
- sage/manifolds/differentiable/vector_bundle.py +1728 -0
- sage/manifolds/differentiable/vectorfield.py +1717 -0
- sage/manifolds/differentiable/vectorfield_module.py +2445 -0
- sage/manifolds/differentiable/vectorframe.py +1832 -0
- sage/manifolds/family.py +270 -0
- sage/manifolds/local_frame.py +1490 -0
- sage/manifolds/manifold.py +3090 -0
- sage/manifolds/manifold_homset.py +452 -0
- sage/manifolds/operators.py +359 -0
- sage/manifolds/point.py +994 -0
- sage/manifolds/scalarfield.py +3718 -0
- sage/manifolds/scalarfield_algebra.py +629 -0
- sage/manifolds/section.py +3111 -0
- sage/manifolds/section_module.py +831 -0
- sage/manifolds/structure.py +229 -0
- sage/manifolds/subset.py +2764 -0
- sage/manifolds/subsets/all.py +1 -0
- sage/manifolds/subsets/closure.py +131 -0
- sage/manifolds/subsets/pullback.py +885 -0
- sage/manifolds/topological_submanifold.py +891 -0
- sage/manifolds/trivialization.py +733 -0
- sage/manifolds/utilities.py +1348 -0
- sage/manifolds/vector_bundle.py +1342 -0
- sage/manifolds/vector_bundle_fiber.py +332 -0
- sage/manifolds/vector_bundle_fiber_element.py +111 -0
- sage/matrix/all__sagemath_symbolics.py +1 -0
- sage/matrix/matrix_symbolic_dense.cpython-310-x86_64-linux-gnu.so +0 -0
- sage/matrix/matrix_symbolic_dense.pxd +6 -0
- sage/matrix/matrix_symbolic_dense.pyx +1022 -0
- sage/matrix/matrix_symbolic_sparse.cpython-310-x86_64-linux-gnu.so +0 -0
- sage/matrix/matrix_symbolic_sparse.pxd +6 -0
- sage/matrix/matrix_symbolic_sparse.pyx +1029 -0
- sage/modules/all__sagemath_symbolics.py +1 -0
- sage/modules/vector_callable_symbolic_dense.py +105 -0
- sage/modules/vector_symbolic_dense.py +116 -0
- sage/modules/vector_symbolic_sparse.py +118 -0
- sage/rings/all__sagemath_symbolics.py +4 -0
- sage/rings/asymptotic/all.py +6 -0
- sage/rings/asymptotic/asymptotic_expansion_generators.py +1485 -0
- sage/rings/asymptotic/asymptotic_ring.py +4858 -0
- sage/rings/asymptotic/asymptotics_multivariate_generating_functions.py +4153 -0
- sage/rings/asymptotic/growth_group.py +5373 -0
- sage/rings/asymptotic/growth_group_cartesian.py +1400 -0
- sage/rings/asymptotic/term_monoid.py +5237 -0
- sage/rings/function_field/all__sagemath_symbolics.py +2 -0
- sage/rings/polynomial/all__sagemath_symbolics.py +1 -0
- sage/symbolic/all.py +15 -0
- sage/symbolic/assumptions.py +985 -0
- sage/symbolic/benchmark.py +93 -0
- sage/symbolic/callable.py +459 -0
- sage/symbolic/complexity_measures.py +35 -0
- sage/symbolic/constants.py +1287 -0
- sage/symbolic/expression_conversion_algebraic.py +310 -0
- sage/symbolic/expression_conversion_sympy.py +317 -0
- sage/symbolic/expression_conversions.py +1713 -0
- sage/symbolic/function_factory.py +355 -0
- sage/symbolic/integration/all.py +1 -0
- sage/symbolic/integration/external.py +270 -0
- sage/symbolic/integration/integral.py +1115 -0
- sage/symbolic/maxima_wrapper.py +162 -0
- sage/symbolic/operators.py +267 -0
- sage/symbolic/random_tests.py +462 -0
- sage/symbolic/relation.py +1907 -0
- sage/symbolic/ring.cpython-310-x86_64-linux-gnu.so +0 -0
- sage/symbolic/ring.pxd +5 -0
- sage/symbolic/ring.pyx +1396 -0
- sage/symbolic/subring.py +1025 -0
- sage/symbolic/symengine.py +19 -0
- sage/symbolic/tests.py +40 -0
- sage/symbolic/units.py +1470 -0
|
@@ -0,0 +1,1728 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-symbolics
|
|
2
|
+
r"""
|
|
3
|
+
Differentiable Vector Bundles
|
|
4
|
+
|
|
5
|
+
Let `K` be a topological field. A `C^k`-differentiable *vector bundle* of rank
|
|
6
|
+
`n` over the field `K` and over a `C^k`-differentiable manifold `M` (base
|
|
7
|
+
space) is a `C^k`-differentiable manifold `E` (total space) together with a
|
|
8
|
+
`C^k` differentiable and surjective map `\pi: E \to M` such that for
|
|
9
|
+
every point `x \in M`:
|
|
10
|
+
|
|
11
|
+
- the set `E_x=\pi^{-1}(x)` has the vector space structure of `K^n`,
|
|
12
|
+
- there is a neighborhood `U \subset M` of `x` and a `C^k`-diffeomorphism
|
|
13
|
+
`\varphi: \pi^{-1}(x) \to U \times K^n` such that
|
|
14
|
+
`v \mapsto \varphi^{-1}(y,v)` is a linear isomorphism for any `y \in U`.
|
|
15
|
+
|
|
16
|
+
An important case of a differentiable vector bundle over a differentiable
|
|
17
|
+
manifold is the tensor bundle (see :class:`TensorBundle`)
|
|
18
|
+
|
|
19
|
+
AUTHORS:
|
|
20
|
+
|
|
21
|
+
- Michael Jung (2019) : initial version
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
#******************************************************************************
|
|
25
|
+
# Copyright (C) 2019 Michael Jung <micjung at uni-potsdam.de>
|
|
26
|
+
#
|
|
27
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
|
28
|
+
# as published by the Free Software Foundation; either version 2 of
|
|
29
|
+
# the License, or (at your option) any later version.
|
|
30
|
+
# https://www.gnu.org/licenses/
|
|
31
|
+
#******************************************************************************
|
|
32
|
+
|
|
33
|
+
from sage.categories.vector_bundles import VectorBundles
|
|
34
|
+
from sage.manifolds.vector_bundle import TopologicalVectorBundle
|
|
35
|
+
from sage.misc.superseded import deprecated_function_alias
|
|
36
|
+
from sage.rings.cc import CC
|
|
37
|
+
from sage.rings.infinity import infinity
|
|
38
|
+
from sage.rings.rational_field import QQ
|
|
39
|
+
from sage.rings.real_mpfr import RR
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class DifferentiableVectorBundle(TopologicalVectorBundle):
|
|
43
|
+
r"""
|
|
44
|
+
An instance of this class represents a differentiable vector bundle
|
|
45
|
+
`E \to M`
|
|
46
|
+
|
|
47
|
+
INPUT:
|
|
48
|
+
|
|
49
|
+
- ``rank`` -- positive integer; rank of the vector bundle
|
|
50
|
+
- ``name`` -- string representation given to the total space
|
|
51
|
+
- ``base_space`` -- the base space (differentiable manifold) `M` over which
|
|
52
|
+
the vector bundle is defined
|
|
53
|
+
- ``field`` -- field `K` which gives the fibers the structure of a
|
|
54
|
+
vector space over `K`; allowed values are
|
|
55
|
+
|
|
56
|
+
- ``'real'`` or an object of type ``RealField`` (e.g., ``RR``) for
|
|
57
|
+
a vector bundle over `\RR`
|
|
58
|
+
- ``'complex'`` or an object of type ``ComplexField`` (e.g., ``CC``)
|
|
59
|
+
for a vector bundle over `\CC`
|
|
60
|
+
- an object in the category of topological fields (see
|
|
61
|
+
:class:`~sage.categories.fields.Fields` and
|
|
62
|
+
:class:`~sage.categories.topological_spaces.TopologicalSpaces`)
|
|
63
|
+
for other types of topological fields
|
|
64
|
+
|
|
65
|
+
- ``latex_name`` -- (default: ``None``) LaTeX representation given to the
|
|
66
|
+
total space
|
|
67
|
+
- ``category`` -- (default: ``None``) to specify the category; if
|
|
68
|
+
``None``, ``VectorBundles(base_space, c_field).Differentiable()`` is
|
|
69
|
+
assumed (see the category
|
|
70
|
+
:class:`~sage.categories.vector_bundles.VectorBundles`)
|
|
71
|
+
|
|
72
|
+
EXAMPLES:
|
|
73
|
+
|
|
74
|
+
A differentiable vector bundle of rank 2 over a 3-dimensional
|
|
75
|
+
differentiable manifold::
|
|
76
|
+
|
|
77
|
+
sage: M = Manifold(3, 'M')
|
|
78
|
+
sage: E = M.vector_bundle(2, 'E', field='complex'); E
|
|
79
|
+
Differentiable complex vector bundle E -> M of rank 2 over the base
|
|
80
|
+
space 3-dimensional differentiable manifold M
|
|
81
|
+
sage: E.category()
|
|
82
|
+
Category of smooth vector bundles over Complex Field with 53 bits of
|
|
83
|
+
precision with base space 3-dimensional differentiable manifold M
|
|
84
|
+
|
|
85
|
+
At this stage, the differentiable vector bundle has the same
|
|
86
|
+
differentiability degree as the base manifold::
|
|
87
|
+
|
|
88
|
+
sage: M.diff_degree() == E.diff_degree()
|
|
89
|
+
True
|
|
90
|
+
"""
|
|
91
|
+
def __init__(self, rank, name, base_space, field='real', latex_name=None,
|
|
92
|
+
category=None, unique_tag=None):
|
|
93
|
+
r"""
|
|
94
|
+
Construct a differentiable vector bundle.
|
|
95
|
+
|
|
96
|
+
TESTS::
|
|
97
|
+
|
|
98
|
+
sage: M = Manifold(2, 'M')
|
|
99
|
+
sage: from sage.manifolds.differentiable.vector_bundle import DifferentiableVectorBundle
|
|
100
|
+
sage: DifferentiableVectorBundle(2, 'E', M)
|
|
101
|
+
Differentiable real vector bundle E -> M of rank 2 over the base
|
|
102
|
+
space 2-dimensional differentiable manifold M
|
|
103
|
+
"""
|
|
104
|
+
diff_degree = base_space._diff_degree
|
|
105
|
+
if category is None:
|
|
106
|
+
if field == 'real':
|
|
107
|
+
field_c = RR
|
|
108
|
+
elif field == 'complex':
|
|
109
|
+
field_c = CC
|
|
110
|
+
else:
|
|
111
|
+
field_c = field
|
|
112
|
+
if diff_degree == infinity:
|
|
113
|
+
category = VectorBundles(base_space, field_c).Smooth()
|
|
114
|
+
else:
|
|
115
|
+
category = VectorBundles(base_space, field_c).Differentiable()
|
|
116
|
+
TopologicalVectorBundle.__init__(self, rank, name, base_space,
|
|
117
|
+
field=field,
|
|
118
|
+
latex_name=latex_name,
|
|
119
|
+
category=category)
|
|
120
|
+
self._diff_degree = diff_degree # Override diff degree
|
|
121
|
+
|
|
122
|
+
def _repr_(self):
|
|
123
|
+
r"""
|
|
124
|
+
String representation of ``self``.
|
|
125
|
+
|
|
126
|
+
TESTS::
|
|
127
|
+
|
|
128
|
+
sage: M = Manifold(2, 'M')
|
|
129
|
+
sage: E = M.vector_bundle(1, 'E')
|
|
130
|
+
sage: E._repr_()
|
|
131
|
+
'Differentiable real vector bundle E -> M of rank 1 over the base
|
|
132
|
+
space 2-dimensional differentiable manifold M'
|
|
133
|
+
"""
|
|
134
|
+
desc = "Differentiable "
|
|
135
|
+
return desc + TopologicalVectorBundle._repr_object_name(self)
|
|
136
|
+
|
|
137
|
+
def bundle_connection(self, name, latex_name=None):
|
|
138
|
+
r"""
|
|
139
|
+
Return a bundle connection on ``self``.
|
|
140
|
+
|
|
141
|
+
OUTPUT:
|
|
142
|
+
|
|
143
|
+
- a bundle connection on ``self`` as an instance of
|
|
144
|
+
:class:`~sage.manifolds.differentiable.bundle_connection.BundleConnection`
|
|
145
|
+
|
|
146
|
+
EXAMPLES::
|
|
147
|
+
|
|
148
|
+
sage: M = Manifold(3, 'M', start_index=1)
|
|
149
|
+
sage: X.<x,y,z> = M.chart()
|
|
150
|
+
sage: E = M.vector_bundle(2, 'E')
|
|
151
|
+
sage: e = E.local_frame('e') # standard frame for E
|
|
152
|
+
sage: nab = E.bundle_connection('nabla', latex_name=r'\nabla'); nab
|
|
153
|
+
Bundle connection nabla on the Differentiable real vector bundle
|
|
154
|
+
E -> M of rank 2 over the base space 3-dimensional differentiable
|
|
155
|
+
manifold M
|
|
156
|
+
|
|
157
|
+
.. SEEALSO::
|
|
158
|
+
|
|
159
|
+
Further examples can be found in
|
|
160
|
+
:class:`~sage.manifolds.differentiable.bundle_connection.BundleConnection`.
|
|
161
|
+
"""
|
|
162
|
+
from sage.manifolds.differentiable.bundle_connection import BundleConnection
|
|
163
|
+
return BundleConnection(self, name, latex_name)
|
|
164
|
+
|
|
165
|
+
def characteristic_cohomology_class_ring(self, base=QQ):
|
|
166
|
+
r"""
|
|
167
|
+
Return the characteristic cohomology class ring of ``self`` over
|
|
168
|
+
a given base.
|
|
169
|
+
|
|
170
|
+
INPUT:
|
|
171
|
+
|
|
172
|
+
- ``base`` -- (default: ``QQ``) base over which the ring should be
|
|
173
|
+
constructed; typically that would be `\ZZ`, `\QQ`, `\RR` or the
|
|
174
|
+
symbolic ring
|
|
175
|
+
|
|
176
|
+
EXAMPLES::
|
|
177
|
+
|
|
178
|
+
sage: M = Manifold(4, 'M', start_index=1)
|
|
179
|
+
sage: R = M.tangent_bundle().characteristic_cohomology_class_ring()
|
|
180
|
+
sage: R
|
|
181
|
+
Algebra of characteristic cohomology classes of the Tangent bundle
|
|
182
|
+
TM over the 4-dimensional differentiable manifold M
|
|
183
|
+
sage: p1 = R.gen(0); p1
|
|
184
|
+
Characteristic cohomology class (p_1)(TM) of the Tangent bundle TM
|
|
185
|
+
over the 4-dimensional differentiable manifold M
|
|
186
|
+
sage: 1 + p1
|
|
187
|
+
Characteristic cohomology class (1 + p_1)(TM) of the Tangent bundle
|
|
188
|
+
TM over the 4-dimensional differentiable manifold M
|
|
189
|
+
"""
|
|
190
|
+
from sage.manifolds.differentiable.characteristic_cohomology_class import (
|
|
191
|
+
CharacteristicCohomologyClassRing,
|
|
192
|
+
)
|
|
193
|
+
|
|
194
|
+
return CharacteristicCohomologyClassRing(base, self)
|
|
195
|
+
|
|
196
|
+
def characteristic_cohomology_class(self, *args, **kwargs):
|
|
197
|
+
r"""
|
|
198
|
+
Return a characteristic cohomology class associated with the input
|
|
199
|
+
data.
|
|
200
|
+
|
|
201
|
+
INPUT:
|
|
202
|
+
|
|
203
|
+
- ``val`` -- the input data associated with the characteristic class
|
|
204
|
+
using the Chern-Weil homomorphism; this argument can be either a
|
|
205
|
+
symbolic expression, a polynomial or one of the following predefined
|
|
206
|
+
classes:
|
|
207
|
+
|
|
208
|
+
- ``'Chern'`` -- total Chern class,
|
|
209
|
+
- ``'ChernChar'`` -- Chern character,
|
|
210
|
+
- ``'Todd'`` -- Todd class,
|
|
211
|
+
- ``'Pontryagin'`` -- total Pontryagin class,
|
|
212
|
+
- ``'Hirzebruch'`` -- Hirzebruch class,
|
|
213
|
+
- ``'AHat'`` -- `\hat{A}` class,
|
|
214
|
+
- ``'Euler'`` -- Euler class.
|
|
215
|
+
|
|
216
|
+
- ``base_ring`` -- (default: ``QQ``) base ring over which the
|
|
217
|
+
characteristic cohomology class ring shall be defined
|
|
218
|
+
- ``name`` -- (default: ``None``) string representation given to the
|
|
219
|
+
characteristic cohomology class; if ``None`` the default algebra
|
|
220
|
+
representation or predefined name is used
|
|
221
|
+
- ``latex_name`` -- (default: ``None``) LaTeX name given to the
|
|
222
|
+
characteristic class; if ``None`` the value of ``name`` is used
|
|
223
|
+
- ``class_type`` -- (default: ``None``) class type of the characteristic
|
|
224
|
+
cohomology class; the following options are possible:
|
|
225
|
+
|
|
226
|
+
- ``'multiplicative'`` -- returns a class of multiplicative type
|
|
227
|
+
- ``'additive'`` -- returns a class of additive type
|
|
228
|
+
- ``'Pfaffian'`` -- returns a class of Pfaffian type
|
|
229
|
+
|
|
230
|
+
This argument must be stated if ``val`` is a polynomial or symbolic
|
|
231
|
+
expression.
|
|
232
|
+
|
|
233
|
+
EXAMPLES:
|
|
234
|
+
|
|
235
|
+
Pontryagin class on the Minkowski space::
|
|
236
|
+
|
|
237
|
+
sage: M = Manifold(4, 'M', structure='Lorentzian', start_index=1)
|
|
238
|
+
sage: X.<t,x,y,z> = M.chart()
|
|
239
|
+
sage: g = M.metric()
|
|
240
|
+
sage: g[1,1] = -1
|
|
241
|
+
sage: g[2,2] = 1
|
|
242
|
+
sage: g[3,3] = 1
|
|
243
|
+
sage: g[4,4] = 1
|
|
244
|
+
sage: g.display()
|
|
245
|
+
g = -dt⊗dt + dx⊗dx + dy⊗dy + dz⊗dz
|
|
246
|
+
|
|
247
|
+
Let us introduce the corresponding Levi-Civita connection::
|
|
248
|
+
|
|
249
|
+
sage: nab = g.connection(); nab
|
|
250
|
+
Levi-Civita connection nabla_g associated with the Lorentzian
|
|
251
|
+
metric g on the 4-dimensional Lorentzian manifold M
|
|
252
|
+
sage: nab.set_immutable() # make nab immutable
|
|
253
|
+
|
|
254
|
+
Of course, `\nabla_g` is flat::
|
|
255
|
+
|
|
256
|
+
sage: nab.display()
|
|
257
|
+
|
|
258
|
+
Let us check the total Pontryagin class which must be the one
|
|
259
|
+
element in the corresponding cohomology ring in this case::
|
|
260
|
+
|
|
261
|
+
sage: # needs sage.combinat
|
|
262
|
+
sage: TM = M.tangent_bundle(); TM
|
|
263
|
+
Tangent bundle TM over the 4-dimensional Lorentzian manifold M
|
|
264
|
+
sage: p = TM.characteristic_cohomology_class('Pontryagin'); p
|
|
265
|
+
Characteristic cohomology class p(TM) of the Tangent bundle TM over
|
|
266
|
+
the 4-dimensional Lorentzian manifold M
|
|
267
|
+
sage: p_form = p.get_form(nab); p_form.display_expansion()
|
|
268
|
+
p(TM, nabla_g) = 1
|
|
269
|
+
|
|
270
|
+
.. SEEALSO::
|
|
271
|
+
|
|
272
|
+
More examples can be found in
|
|
273
|
+
:class:`~sage.manifolds.differentiable.characteristic_class.CharacteristicClass`.
|
|
274
|
+
"""
|
|
275
|
+
base_ring = kwargs.get('base_ring', QQ)
|
|
276
|
+
R = self.characteristic_cohomology_class_ring(base_ring)
|
|
277
|
+
return R(*args, **kwargs)
|
|
278
|
+
|
|
279
|
+
characteristic_class = deprecated_function_alias(29581, characteristic_cohomology_class)
|
|
280
|
+
|
|
281
|
+
def diff_degree(self):
|
|
282
|
+
r"""
|
|
283
|
+
Return the vector bundle's degree of differentiability.
|
|
284
|
+
|
|
285
|
+
The degree of differentiability is the integer `k` (possibly
|
|
286
|
+
`k=\infty`) such that the vector bundle is of class `C^k` over
|
|
287
|
+
its base field. The degree always corresponds to the degree of
|
|
288
|
+
differentiability of it's base space.
|
|
289
|
+
|
|
290
|
+
EXAMPLES::
|
|
291
|
+
|
|
292
|
+
sage: M = Manifold(2, 'M')
|
|
293
|
+
sage: E = M.vector_bundle(2, 'E')
|
|
294
|
+
sage: E.diff_degree()
|
|
295
|
+
+Infinity
|
|
296
|
+
sage: M = Manifold(2, 'M', structure='differentiable',
|
|
297
|
+
....: diff_degree=3)
|
|
298
|
+
sage: E = M.vector_bundle(2, 'E')
|
|
299
|
+
sage: E.diff_degree()
|
|
300
|
+
3
|
|
301
|
+
"""
|
|
302
|
+
return self._diff_degree
|
|
303
|
+
|
|
304
|
+
def total_space(self):
|
|
305
|
+
r"""
|
|
306
|
+
Return the total space of ``self``.
|
|
307
|
+
|
|
308
|
+
.. NOTE::
|
|
309
|
+
|
|
310
|
+
At this stage, the total space does not come with induced charts.
|
|
311
|
+
|
|
312
|
+
OUTPUT:
|
|
313
|
+
|
|
314
|
+
- the total space of ``self`` as an instance of
|
|
315
|
+
:class:`~sage.manifolds.differentiable.manifold.DifferentiableManifold`
|
|
316
|
+
|
|
317
|
+
EXAMPLES::
|
|
318
|
+
|
|
319
|
+
sage: M = Manifold(3, 'M')
|
|
320
|
+
sage: E = M.vector_bundle(2, 'E')
|
|
321
|
+
sage: E.total_space()
|
|
322
|
+
6-dimensional differentiable manifold E
|
|
323
|
+
"""
|
|
324
|
+
if self._total_space is None:
|
|
325
|
+
from sage.manifolds.manifold import Manifold
|
|
326
|
+
base_space = self._base_space
|
|
327
|
+
dim = base_space._dim * self._rank
|
|
328
|
+
sindex = base_space.start_index()
|
|
329
|
+
self._total_space = Manifold(dim, self._name,
|
|
330
|
+
latex_name=self._latex_name,
|
|
331
|
+
field=self._field, structure='differentiable',
|
|
332
|
+
diff_degree=self._diff_degree,
|
|
333
|
+
start_index=sindex)
|
|
334
|
+
|
|
335
|
+
# TODO: if update_atlas: introduce charts via self._atlas
|
|
336
|
+
|
|
337
|
+
return self._total_space
|
|
338
|
+
|
|
339
|
+
# *****************************************************************************
|
|
340
|
+
|
|
341
|
+
|
|
342
|
+
class TensorBundle(DifferentiableVectorBundle):
|
|
343
|
+
r"""
|
|
344
|
+
Tensor bundle over a differentiable manifold along a differentiable map.
|
|
345
|
+
|
|
346
|
+
An instance of this class represents the pullback tensor bundle
|
|
347
|
+
`\Phi^* T^{(k,l)}N` along a differentiable map (called *destination map*)
|
|
348
|
+
|
|
349
|
+
.. MATH::
|
|
350
|
+
|
|
351
|
+
\Phi: M \longrightarrow N
|
|
352
|
+
|
|
353
|
+
between two differentiable manifolds `M` and `N` over the topological field
|
|
354
|
+
`K`.
|
|
355
|
+
|
|
356
|
+
More precisely, `\Phi^* T^{(k,l)}N` consists of all pairs
|
|
357
|
+
`(p,t) \in M \times T^{(k,l)}N` such that `t \in T_q^{(k,l)}N` for
|
|
358
|
+
`q = \Phi(p)`, namely
|
|
359
|
+
|
|
360
|
+
.. MATH::
|
|
361
|
+
|
|
362
|
+
t:\ \underbrace{T_q^*N\times\cdots\times T_q^*N}_{k\ \; \text{times}}
|
|
363
|
+
\times \underbrace{T_q N\times\cdots\times T_q N}_{l\ \; \text{times}}
|
|
364
|
+
\longrightarrow K
|
|
365
|
+
|
|
366
|
+
(`k` is called the *contravariant* and `l` the *covariant* rank of the
|
|
367
|
+
tensor bundle).
|
|
368
|
+
|
|
369
|
+
The trivializations are directly given by charts on the codomain (called
|
|
370
|
+
*ambient domain*) of `\Phi`.
|
|
371
|
+
In particular, let `(V, \varphi)` be a chart of `N` with components
|
|
372
|
+
`(x^1, \dots, x^n)` such that `q=\Phi(p) \in V`. Then, the matrix entries
|
|
373
|
+
of `t \in T_q^{(k,l)}N` are given by
|
|
374
|
+
|
|
375
|
+
.. MATH::
|
|
376
|
+
|
|
377
|
+
t^{a_1 \ldots a_k}_{\phantom{a_1 \ldots a_k} \, b_1 \ldots b_l} =
|
|
378
|
+
t \left( \left.\frac{\partial}{\partial x^{a_1}}\right|_q, \dots,
|
|
379
|
+
\left.\frac{\partial}{\partial x^{a_k}}\right|_q,
|
|
380
|
+
\left.\mathrm{d}x^{b_1}\right|_q, \dots,
|
|
381
|
+
\left.\mathrm{d}x^{b_l}\right|_q \right) \in K
|
|
382
|
+
|
|
383
|
+
and a trivialization over `U=\Phi^{-1}(V) \subset M` is obtained via
|
|
384
|
+
|
|
385
|
+
.. MATH::
|
|
386
|
+
|
|
387
|
+
(p,t) \mapsto \left(p, t^{1 \ldots 1}_{\phantom{1 \ldots 1} \, 1 \ldots 1},
|
|
388
|
+
\dots, t^{n \ldots n}_{\phantom{n \ldots n} \, n \ldots n} \right)
|
|
389
|
+
\in U \times K^{n^{(k+l)}}.
|
|
390
|
+
|
|
391
|
+
The standard case of a tensor bundle over a differentiable manifold
|
|
392
|
+
corresponds to `M=N` and `\Phi = \mathrm{Id}_M`. Other common cases are
|
|
393
|
+
`\Phi` being an immersion and `\Phi` being a curve in `N` (`M` is then an
|
|
394
|
+
open interval of `\RR`).
|
|
395
|
+
|
|
396
|
+
INPUT:
|
|
397
|
+
|
|
398
|
+
- ``base_space`` -- the base space (differentiable manifold) `M` over which
|
|
399
|
+
the tensor bundle is defined
|
|
400
|
+
- ``k`` -- the contravariant rank of the corresponding tensor bundle
|
|
401
|
+
- ``l`` -- the covariant rank of the corresponding tensor bundle
|
|
402
|
+
- ``dest_map`` -- (default: ``None``) destination map
|
|
403
|
+
`\Phi:\ M \rightarrow N`
|
|
404
|
+
(type: :class:`~sage.manifolds.differentiable.diff_map.DiffMap`); if
|
|
405
|
+
``None``, it is assumed that `M=M` and `\Phi` is the identity map of
|
|
406
|
+
`M` (case of the standard tensor bundle over `M`)
|
|
407
|
+
|
|
408
|
+
EXAMPLES:
|
|
409
|
+
|
|
410
|
+
Pullback tangent bundle of `R^2` along a curve `\Phi`::
|
|
411
|
+
|
|
412
|
+
sage: M = Manifold(2, 'M')
|
|
413
|
+
sage: c_cart.<x,y> = M.chart()
|
|
414
|
+
sage: R = Manifold(1, 'R')
|
|
415
|
+
sage: T.<t> = R.chart() # canonical chart on R
|
|
416
|
+
sage: Phi = R.diff_map(M, [cos(t), sin(t)], name='Phi') ; Phi
|
|
417
|
+
Differentiable map Phi from the 1-dimensional differentiable manifold R
|
|
418
|
+
to the 2-dimensional differentiable manifold M
|
|
419
|
+
sage: Phi.display()
|
|
420
|
+
Phi: R → M
|
|
421
|
+
t ↦ (x, y) = (cos(t), sin(t))
|
|
422
|
+
sage: PhiTM = R.tangent_bundle(dest_map=Phi); PhiTM
|
|
423
|
+
Tangent bundle Phi^*TM over the 1-dimensional differentiable manifold R
|
|
424
|
+
along the Differentiable map Phi from the 1-dimensional differentiable
|
|
425
|
+
manifold R to the 2-dimensional differentiable manifold M
|
|
426
|
+
|
|
427
|
+
The section module is the corresponding tensor field module::
|
|
428
|
+
|
|
429
|
+
sage: R_tensor_module = R.tensor_field_module((1,0), dest_map=Phi)
|
|
430
|
+
sage: R_tensor_module is PhiTM.section_module()
|
|
431
|
+
True
|
|
432
|
+
"""
|
|
433
|
+
def __init__(self, base_space, k, l, dest_map=None):
|
|
434
|
+
r"""
|
|
435
|
+
Construct a tensor bundle.
|
|
436
|
+
|
|
437
|
+
TESTS::
|
|
438
|
+
|
|
439
|
+
sage: M = Manifold(2, 'M')
|
|
440
|
+
sage: N = Manifold(2, 'N')
|
|
441
|
+
sage: Phi = M.diff_map(N, name='Phi')
|
|
442
|
+
sage: from sage.manifolds.differentiable.vector_bundle import TensorBundle
|
|
443
|
+
sage: TensorBundle(M, 1, 2, dest_map=Phi)
|
|
444
|
+
Tensor bundle Phi^*T^(1,2)N over the 2-dimensional differentiable
|
|
445
|
+
manifold M along the Differentiable map Phi from the 2-dimensional
|
|
446
|
+
differentiable manifold M to the 2-dimensional differentiable
|
|
447
|
+
manifold N
|
|
448
|
+
"""
|
|
449
|
+
if dest_map is None:
|
|
450
|
+
self._dest_map = base_space.identity_map()
|
|
451
|
+
else:
|
|
452
|
+
self._dest_map = dest_map
|
|
453
|
+
self._ambient_domain = self._dest_map._codomain
|
|
454
|
+
self._tensor_type = (k, l)
|
|
455
|
+
# Set total space name:
|
|
456
|
+
if not self._dest_map.is_identity():
|
|
457
|
+
if self._dest_map._name is None:
|
|
458
|
+
name = "(unnamed map)^*"
|
|
459
|
+
else:
|
|
460
|
+
name = self._dest_map._name + "^*"
|
|
461
|
+
if self._dest_map._latex_name is None:
|
|
462
|
+
latex_name = r'\text{(unnamed map)}^* '
|
|
463
|
+
else:
|
|
464
|
+
latex_name = self._dest_map._latex_name + r'^* '
|
|
465
|
+
else:
|
|
466
|
+
name = ""
|
|
467
|
+
latex_name = ""
|
|
468
|
+
if self._tensor_type == (1, 0):
|
|
469
|
+
name += "T{}".format(self._ambient_domain._name)
|
|
470
|
+
latex_name += r'T{}'.format(self._ambient_domain._latex_name)
|
|
471
|
+
elif self._tensor_type == (0, 1):
|
|
472
|
+
name += "T*{}".format(self._ambient_domain._name)
|
|
473
|
+
latex_name += r'T^*{}'.format(self._ambient_domain._latex_name)
|
|
474
|
+
else:
|
|
475
|
+
name += "T^({},{}){}".format(k, l, self._ambient_domain._name)
|
|
476
|
+
latex_name += r'T^{(' + str(k) + r',' + str(l) + r')}' + \
|
|
477
|
+
self._ambient_domain._latex_name
|
|
478
|
+
# Initialize differentiable vector bundle:
|
|
479
|
+
rank = self._ambient_domain.dim() ** (k + l)
|
|
480
|
+
DifferentiableVectorBundle.__init__(self, rank, name, base_space,
|
|
481
|
+
field=base_space._field,
|
|
482
|
+
latex_name=latex_name)
|
|
483
|
+
|
|
484
|
+
def _init_derived(self):
|
|
485
|
+
r"""
|
|
486
|
+
Initialize the derived quantities.
|
|
487
|
+
|
|
488
|
+
TESTS::
|
|
489
|
+
|
|
490
|
+
sage: M = Manifold(2, 'M')
|
|
491
|
+
sage: TM = M.tangent_bundle()
|
|
492
|
+
sage: TM._init_derived()
|
|
493
|
+
"""
|
|
494
|
+
self._def_frame = None
|
|
495
|
+
|
|
496
|
+
def _repr_(self):
|
|
497
|
+
r"""
|
|
498
|
+
String representation of ``self``.
|
|
499
|
+
|
|
500
|
+
TESTS::
|
|
501
|
+
|
|
502
|
+
sage: M = Manifold(2, 'M')
|
|
503
|
+
sage: TM = M.tangent_bundle()
|
|
504
|
+
sage: TM # indirect doctest
|
|
505
|
+
Tangent bundle TM over the 2-dimensional differentiable manifold M
|
|
506
|
+
sage: repr(TM) # indirect doctest
|
|
507
|
+
'Tangent bundle TM over the 2-dimensional differentiable manifold M'
|
|
508
|
+
sage: TM._repr_()
|
|
509
|
+
'Tangent bundle TM over the 2-dimensional differentiable manifold M'
|
|
510
|
+
sage: cTM = M.cotangent_bundle()
|
|
511
|
+
sage: cTM._repr_()
|
|
512
|
+
'Cotangent bundle T*M over the 2-dimensional differentiable
|
|
513
|
+
manifold M'
|
|
514
|
+
sage: T12M = M.tensor_bundle(1, 2)
|
|
515
|
+
sage: T12M._repr_()
|
|
516
|
+
'Tensor bundle T^(1,2)M over the 2-dimensional differentiable
|
|
517
|
+
manifold M'
|
|
518
|
+
"""
|
|
519
|
+
if self._tensor_type == (1, 0):
|
|
520
|
+
desc = "Tangent bundle "
|
|
521
|
+
elif self._tensor_type == (0, 1):
|
|
522
|
+
desc = "Cotangent bundle "
|
|
523
|
+
else:
|
|
524
|
+
desc = "Tensor bundle "
|
|
525
|
+
desc += self._name + " over the {}".format(self._base_space)
|
|
526
|
+
if not self._dest_map.is_identity():
|
|
527
|
+
desc += " along the {}".format(self._dest_map)
|
|
528
|
+
return desc
|
|
529
|
+
|
|
530
|
+
def fiber(self, point):
|
|
531
|
+
r"""
|
|
532
|
+
Return the tensor bundle fiber over a point.
|
|
533
|
+
|
|
534
|
+
INPUT:
|
|
535
|
+
|
|
536
|
+
- ``point`` -- :class:`~sage.manifolds.point.ManifoldPoint`;
|
|
537
|
+
point `p` of the base manifold of ``self``
|
|
538
|
+
|
|
539
|
+
OUTPUT:
|
|
540
|
+
|
|
541
|
+
- an instance of :class:`~sage.tensor.modules.finite_rank_free_module.FiniteRankFreeModule`
|
|
542
|
+
representing the tensor bundle fiber over `p`
|
|
543
|
+
|
|
544
|
+
EXAMPLES::
|
|
545
|
+
|
|
546
|
+
sage: M = Manifold(3, 'M')
|
|
547
|
+
sage: X.<x,y,z> = M.chart()
|
|
548
|
+
sage: p = M((0,2,1), name='p'); p
|
|
549
|
+
Point p on the 3-dimensional differentiable manifold M
|
|
550
|
+
sage: TM = M.tangent_bundle(); TM
|
|
551
|
+
Tangent bundle TM over the 3-dimensional differentiable manifold M
|
|
552
|
+
sage: TM.fiber(p)
|
|
553
|
+
Tangent space at Point p on the 3-dimensional differentiable
|
|
554
|
+
manifold M
|
|
555
|
+
sage: TM.fiber(p) is M.tangent_space(p)
|
|
556
|
+
True
|
|
557
|
+
|
|
558
|
+
::
|
|
559
|
+
|
|
560
|
+
sage: T11M = M.tensor_bundle(1,1); T11M
|
|
561
|
+
Tensor bundle T^(1,1)M over the 3-dimensional differentiable
|
|
562
|
+
manifold M
|
|
563
|
+
sage: T11M.fiber(p)
|
|
564
|
+
Free module of type-(1,1) tensors on the Tangent space at Point p
|
|
565
|
+
on the 3-dimensional differentiable manifold M
|
|
566
|
+
sage: T11M.fiber(p) is M.tangent_space(p).tensor_module(1,1)
|
|
567
|
+
True
|
|
568
|
+
"""
|
|
569
|
+
amb_point = self._dest_map(point)
|
|
570
|
+
return self._ambient_domain.tangent_space(amb_point).tensor_module(*self._tensor_type)
|
|
571
|
+
|
|
572
|
+
def atlas(self):
|
|
573
|
+
r"""
|
|
574
|
+
Return the list of charts that have been defined on the codomain of the
|
|
575
|
+
destination map.
|
|
576
|
+
|
|
577
|
+
.. NOTE::
|
|
578
|
+
|
|
579
|
+
Since an atlas of charts gives rise to an atlas of trivializations,
|
|
580
|
+
this method directly invokes
|
|
581
|
+
:meth:`~sage.manifolds.manifold.TopologicalManifold.atlas`
|
|
582
|
+
of the class
|
|
583
|
+
:class:`~sage.manifolds.manifold.TopologicalManifold`.
|
|
584
|
+
|
|
585
|
+
EXAMPLES::
|
|
586
|
+
|
|
587
|
+
sage: M = Manifold(2, 'M')
|
|
588
|
+
sage: X.<x,y> = M.chart()
|
|
589
|
+
sage: Y.<u,v> = M.chart()
|
|
590
|
+
sage: TM = M.tangent_bundle()
|
|
591
|
+
sage: TM.atlas()
|
|
592
|
+
[Chart (M, (x, y)), Chart (M, (u, v))]
|
|
593
|
+
"""
|
|
594
|
+
return self._base_space.atlas()
|
|
595
|
+
|
|
596
|
+
def section_module(self, domain=None):
|
|
597
|
+
r"""
|
|
598
|
+
Return the section module on ``domain``, namely the corresponding
|
|
599
|
+
tensor field module, of ``self`` on ``domain``.
|
|
600
|
+
|
|
601
|
+
.. NOTE::
|
|
602
|
+
|
|
603
|
+
This method directly invokes
|
|
604
|
+
:meth:`~sage.manifolds.differentiable.manifold.DifferentiableManifold.tensor_field_module`
|
|
605
|
+
of the class
|
|
606
|
+
:class:`~sage.manifolds.differentiable.manifold.DifferentiableManifold`.
|
|
607
|
+
|
|
608
|
+
INPUT:
|
|
609
|
+
|
|
610
|
+
- ``domain`` -- (default: ``None``) the domain of the corresponding
|
|
611
|
+
section module; if ``None``, the base space is assumed
|
|
612
|
+
|
|
613
|
+
OUTPUT:
|
|
614
|
+
|
|
615
|
+
- a
|
|
616
|
+
:class:`~sage.manifolds.differentiable.tensorfield_module.TensorFieldModule`
|
|
617
|
+
(or if `N` is parallelizable, a
|
|
618
|
+
:class:`~sage.manifolds.differentiable.tensorfield_module.TensorFieldFreeModule`)
|
|
619
|
+
representing the module `\mathcal{T}^{(k,l)}(U,\Phi)` of type-`(k,l)`
|
|
620
|
+
tensor fields on the domain `U \subset M` taking values on
|
|
621
|
+
`\Phi(U) \subset N`
|
|
622
|
+
|
|
623
|
+
EXAMPLES::
|
|
624
|
+
|
|
625
|
+
sage: M = Manifold(2, 'M')
|
|
626
|
+
sage: X.<x,y> = M.chart()
|
|
627
|
+
sage: U = M.open_subset('U')
|
|
628
|
+
sage: TM = M.tangent_bundle()
|
|
629
|
+
sage: TUM = TM.section_module(domain=U); TUM
|
|
630
|
+
Module X(U) of vector fields on the Open subset U of the
|
|
631
|
+
2-dimensional differentiable manifold M
|
|
632
|
+
sage: TUM is U.tensor_field_module((1,0))
|
|
633
|
+
True
|
|
634
|
+
"""
|
|
635
|
+
if domain is None:
|
|
636
|
+
base_space = self.base_space()
|
|
637
|
+
return base_space.tensor_field_module(self._tensor_type,
|
|
638
|
+
dest_map=self._dest_map)
|
|
639
|
+
else:
|
|
640
|
+
return domain.tensor_field_module(self._tensor_type,
|
|
641
|
+
dest_map=self._dest_map.restrict(domain))
|
|
642
|
+
|
|
643
|
+
def section(self, *args, **kwargs):
|
|
644
|
+
r"""
|
|
645
|
+
Return a section of ``self`` on ``domain``, namely a tensor field on
|
|
646
|
+
the subset ``domain`` of the base space.
|
|
647
|
+
|
|
648
|
+
.. NOTE::
|
|
649
|
+
|
|
650
|
+
This method directly invokes
|
|
651
|
+
:meth:`~sage.manifolds.differentiable.manifold.DifferentiableManifold.tensor_field`
|
|
652
|
+
of the class
|
|
653
|
+
:class:`~sage.manifolds.differentiable.manifold.DifferentiableManifold`.
|
|
654
|
+
|
|
655
|
+
INPUT:
|
|
656
|
+
|
|
657
|
+
- ``comp`` -- (optional) either the components of the tensor field
|
|
658
|
+
with respect to the vector frame specified by the argument
|
|
659
|
+
``frame`` or a dictionary of components, the keys of which are vector
|
|
660
|
+
frames or pairs ``(f, c)`` where ``f`` is a vector frame and ``c``
|
|
661
|
+
the chart in which the components are expressed
|
|
662
|
+
- ``frame`` -- (default: ``None``; unused if ``comp`` is not given or
|
|
663
|
+
is a dictionary) vector frame in which the components are given; if
|
|
664
|
+
``None``, the default vector frame of ``self`` is assumed
|
|
665
|
+
- ``chart`` -- (default: ``None``; unused if ``comp`` is not given or
|
|
666
|
+
is a dictionary) coordinate chart in which the components are
|
|
667
|
+
expressed; if ``None``, the default chart on the domain of ``frame``
|
|
668
|
+
is assumed
|
|
669
|
+
- ``domain`` -- (default: ``None``) domain of the section; if ``None``,
|
|
670
|
+
``self.base_space()`` is assumed
|
|
671
|
+
- ``name`` -- (default: ``None``) name given to the tensor field
|
|
672
|
+
- ``latex_name`` -- (default: ``None``) LaTeX symbol to denote the
|
|
673
|
+
tensor field; if ``None``, the LaTeX symbol is set to ``name``
|
|
674
|
+
- ``sym`` -- (default: ``None``) a symmetry or a list of symmetries
|
|
675
|
+
among the tensor arguments: each symmetry is described by a tuple
|
|
676
|
+
containing the positions of the involved arguments, with the
|
|
677
|
+
convention ``position=0`` for the first argument; for instance:
|
|
678
|
+
|
|
679
|
+
* ``sym = (0,1)`` for a symmetry between the 1st and 2nd arguments
|
|
680
|
+
* ``sym = [(0,2), (1,3,4)]`` for a symmetry between the 1st and 3rd
|
|
681
|
+
arguments and a symmetry between the 2nd, 4th and 5th arguments
|
|
682
|
+
|
|
683
|
+
- ``antisym`` -- (default: ``None``) antisymmetry or list of
|
|
684
|
+
antisymmetries among the arguments, with the same convention as for
|
|
685
|
+
``sym``
|
|
686
|
+
|
|
687
|
+
OUTPUT:
|
|
688
|
+
|
|
689
|
+
- a :class:`~sage.manifolds.differentiable.tensorfield.TensorField`
|
|
690
|
+
(or if `N` is parallelizable, a
|
|
691
|
+
:class:`~sage.manifolds.differentiable.tensorfield_paral.TensorFieldParal`)
|
|
692
|
+
representing the defined tensor field on the domain `U \subset M`
|
|
693
|
+
|
|
694
|
+
EXAMPLES::
|
|
695
|
+
|
|
696
|
+
sage: M = Manifold(2, 'M')
|
|
697
|
+
sage: U = M.open_subset('U') ; V = M.open_subset('V')
|
|
698
|
+
sage: M.declare_union(U,V) # M is the union of U and V
|
|
699
|
+
sage: c_xy.<x,y> = U.chart() ; c_uv.<u,v> = V.chart()
|
|
700
|
+
sage: transf = c_xy.transition_map(c_uv, (x+y, x-y),
|
|
701
|
+
....: intersection_name='W',
|
|
702
|
+
....: restrictions1= x>0,
|
|
703
|
+
....: restrictions2= u+v>0)
|
|
704
|
+
sage: inv = transf.inverse()
|
|
705
|
+
sage: W = U.intersection(V)
|
|
706
|
+
sage: eU = c_xy.frame() ; eV = c_uv.frame()
|
|
707
|
+
sage: T11M = M.tensor_bundle(1, 1); T11M
|
|
708
|
+
Tensor bundle T^(1,1)M over the 2-dimensional differentiable
|
|
709
|
+
manifold M
|
|
710
|
+
sage: t = T11M.section({eU: [[1, x], [0, 2]]}, name='t'); t
|
|
711
|
+
Tensor field t of type (1,1) on the 2-dimensional differentiable
|
|
712
|
+
manifold M
|
|
713
|
+
sage: t.display()
|
|
714
|
+
t = ∂/∂x⊗dx + x ∂/∂x⊗dy + 2 ∂/∂y⊗dy
|
|
715
|
+
|
|
716
|
+
An example of use with the arguments ``comp`` and ``domain``::
|
|
717
|
+
|
|
718
|
+
sage: TM = M.tangent_bundle()
|
|
719
|
+
sage: w = TM.section([-y, x], domain=U); w
|
|
720
|
+
Vector field on the Open subset U of the 2-dimensional
|
|
721
|
+
differentiable manifold M
|
|
722
|
+
sage: w.display()
|
|
723
|
+
-y ∂/∂x + x ∂/∂y
|
|
724
|
+
"""
|
|
725
|
+
nargs = [self._tensor_type[0], self._tensor_type[1]]
|
|
726
|
+
nargs.extend(args)
|
|
727
|
+
domain = kwargs.pop('domain', self._base_space)
|
|
728
|
+
kwargs['dest_map'] = self._dest_map.restrict(domain)
|
|
729
|
+
return domain.tensor_field(*nargs, **kwargs)
|
|
730
|
+
|
|
731
|
+
def set_change_of_frame(self, frame1, frame2, change_of_frame,
|
|
732
|
+
compute_inverse=True):
|
|
733
|
+
r"""
|
|
734
|
+
Relate two vector frames by an automorphism.
|
|
735
|
+
|
|
736
|
+
This updates the internal dictionary ``self._frame_changes`` of the
|
|
737
|
+
base space `M`.
|
|
738
|
+
|
|
739
|
+
.. SEEALSO::
|
|
740
|
+
|
|
741
|
+
For further details on frames on ``self`` see
|
|
742
|
+
:meth:`local_frame`.
|
|
743
|
+
|
|
744
|
+
.. NOTE::
|
|
745
|
+
|
|
746
|
+
Since frames on ``self`` are directly induced by vector frames on
|
|
747
|
+
the base space, this method directly invokes
|
|
748
|
+
:meth:`~sage.manifolds.differentiable.manifold.DifferentiableManifold.set_change_of_frame`
|
|
749
|
+
of the class
|
|
750
|
+
:class:`~sage.manifolds.differentiable.manifold.DifferentiableManifold`.
|
|
751
|
+
|
|
752
|
+
INPUT:
|
|
753
|
+
|
|
754
|
+
- ``frame1`` -- frame 1, denoted `(e_i)` below
|
|
755
|
+
- ``frame2`` -- frame 2, denoted `(f_i)` below
|
|
756
|
+
- ``change_of_frame`` -- instance of class
|
|
757
|
+
:class:`~sage.tensor.modules.free_module_automorphism.FreeModuleAutomorphism`
|
|
758
|
+
describing the automorphism `P` that relates the basis `(e_i)` to
|
|
759
|
+
the basis `(f_i)` according to `f_i = P(e_i)`
|
|
760
|
+
- ``compute_inverse`` -- boolean (default: ``True``); if set to ``True``, the inverse
|
|
761
|
+
automorphism is computed and the change from basis `(f_i)` to `(e_i)`
|
|
762
|
+
is set to it in the internal dictionary ``self._frame_changes``
|
|
763
|
+
|
|
764
|
+
EXAMPLES::
|
|
765
|
+
|
|
766
|
+
sage: M = Manifold(2, 'M')
|
|
767
|
+
sage: c_xy.<x,y> = M.chart()
|
|
768
|
+
sage: e = M.vector_frame('e')
|
|
769
|
+
sage: f = M.vector_frame('f')
|
|
770
|
+
sage: a = M.automorphism_field()
|
|
771
|
+
sage: a[e,:] = [[1,2],[0,3]]
|
|
772
|
+
sage: TM = M.tangent_bundle()
|
|
773
|
+
sage: TM.set_change_of_frame(e, f, a)
|
|
774
|
+
sage: f[0].display(e)
|
|
775
|
+
f_0 = e_0
|
|
776
|
+
sage: f[1].display(e)
|
|
777
|
+
f_1 = 2 e_0 + 3 e_1
|
|
778
|
+
sage: e[0].display(f)
|
|
779
|
+
e_0 = f_0
|
|
780
|
+
sage: e[1].display(f)
|
|
781
|
+
e_1 = -2/3 f_0 + 1/3 f_1
|
|
782
|
+
sage: TM.change_of_frame(e,f)[e,:]
|
|
783
|
+
[1 2]
|
|
784
|
+
[0 3]
|
|
785
|
+
"""
|
|
786
|
+
if not frame1._domain.is_subset(self._ambient_domain):
|
|
787
|
+
raise ValueError("the frames must be defined on a subset of "
|
|
788
|
+
"the {}".format(self._ambient_domain))
|
|
789
|
+
frame1._domain.set_change_of_frame(frame1=frame1, frame2=frame2,
|
|
790
|
+
change_of_frame=change_of_frame,
|
|
791
|
+
compute_inverse=compute_inverse)
|
|
792
|
+
|
|
793
|
+
def change_of_frame(self, frame1, frame2):
|
|
794
|
+
r"""
|
|
795
|
+
Return a change of vector frames defined on the base space of ``self``.
|
|
796
|
+
|
|
797
|
+
.. SEEALSO::
|
|
798
|
+
|
|
799
|
+
For further details on frames on ``self`` see
|
|
800
|
+
:meth:`local_frame`.
|
|
801
|
+
|
|
802
|
+
.. NOTE::
|
|
803
|
+
|
|
804
|
+
Since frames on ``self`` are directly induced by vector frames on
|
|
805
|
+
the base space, this method directly invokes
|
|
806
|
+
:meth:`~sage.manifolds.differentiable.manifold.DifferentiableManifold.change_of_frame`
|
|
807
|
+
of the class
|
|
808
|
+
:class:`~sage.manifolds.differentiable.manifold.DifferentiableManifold`.
|
|
809
|
+
|
|
810
|
+
INPUT:
|
|
811
|
+
|
|
812
|
+
- ``frame1`` -- local frame 1
|
|
813
|
+
- ``frame2`` -- local frame 2
|
|
814
|
+
|
|
815
|
+
OUTPUT:
|
|
816
|
+
|
|
817
|
+
- a :class:`~sage.tensor.modules.free_module_automorphism.FreeModuleAutomorphism`
|
|
818
|
+
representing, at each point, the vector space automorphism `P` that
|
|
819
|
+
relates frame 1, `(e_i)` say, to frame 2, `(f_i)` say, according to
|
|
820
|
+
`f_i = P(e_i)`
|
|
821
|
+
|
|
822
|
+
EXAMPLES::
|
|
823
|
+
|
|
824
|
+
sage: M = Manifold(2, 'M')
|
|
825
|
+
sage: c_xy.<x,y> = M.chart()
|
|
826
|
+
sage: c_uv.<u,v> = M.chart()
|
|
827
|
+
sage: c_xy.transition_map(c_uv, (x+y, x-y))
|
|
828
|
+
Change of coordinates from Chart (M, (x, y)) to Chart (M, (u, v))
|
|
829
|
+
sage: TM = M.tangent_bundle()
|
|
830
|
+
sage: TM.change_of_frame(c_xy.frame(), c_uv.frame())
|
|
831
|
+
Field of tangent-space automorphisms on the 2-dimensional
|
|
832
|
+
differentiable manifold M
|
|
833
|
+
sage: TM.change_of_frame(c_xy.frame(), c_uv.frame())[:]
|
|
834
|
+
[ 1/2 1/2]
|
|
835
|
+
[ 1/2 -1/2]
|
|
836
|
+
sage: TM.change_of_frame(c_uv.frame(), c_xy.frame())
|
|
837
|
+
Field of tangent-space automorphisms on the 2-dimensional
|
|
838
|
+
differentiable manifold M
|
|
839
|
+
sage: TM.change_of_frame(c_uv.frame(), c_xy.frame())[:]
|
|
840
|
+
[ 1 1]
|
|
841
|
+
[ 1 -1]
|
|
842
|
+
sage: TM.change_of_frame(c_uv.frame(), c_xy.frame()) == \
|
|
843
|
+
....: M.change_of_frame(c_xy.frame(), c_uv.frame()).inverse()
|
|
844
|
+
True
|
|
845
|
+
"""
|
|
846
|
+
return self._base_space.change_of_frame(frame1=frame1, frame2=frame2)
|
|
847
|
+
|
|
848
|
+
def changes_of_frame(self):
|
|
849
|
+
r"""
|
|
850
|
+
Return the changes of vector frames defined on the base space of
|
|
851
|
+
``self`` with respect to the destination map.
|
|
852
|
+
|
|
853
|
+
.. SEEALSO::
|
|
854
|
+
|
|
855
|
+
For further details on frames on ``self`` see
|
|
856
|
+
:meth:`local_frame`.
|
|
857
|
+
|
|
858
|
+
OUTPUT:
|
|
859
|
+
|
|
860
|
+
- dictionary of automorphisms on the tangent bundle representing
|
|
861
|
+
the changes of frames, the keys being the pair of frames
|
|
862
|
+
|
|
863
|
+
EXAMPLES:
|
|
864
|
+
|
|
865
|
+
Let us consider a first vector frame on a 2-dimensional
|
|
866
|
+
differentiable manifold::
|
|
867
|
+
|
|
868
|
+
sage: M = Manifold(2, 'M')
|
|
869
|
+
sage: X.<x,y> = M.chart()
|
|
870
|
+
sage: TM = M.tangent_bundle()
|
|
871
|
+
sage: e = X.frame(); e
|
|
872
|
+
Coordinate frame (M, (∂/∂x,∂/∂y))
|
|
873
|
+
|
|
874
|
+
At this stage, the dictionary of changes of frame is empty::
|
|
875
|
+
|
|
876
|
+
sage: TM.changes_of_frame()
|
|
877
|
+
{}
|
|
878
|
+
|
|
879
|
+
We introduce a second frame on the manifold, relating it to
|
|
880
|
+
frame ``e`` by a field of tangent space automorphisms::
|
|
881
|
+
|
|
882
|
+
sage: a = M.automorphism_field(name='a')
|
|
883
|
+
sage: a[:] = [[-y, x], [1, 2]]
|
|
884
|
+
sage: f = e.new_frame(a, 'f'); f
|
|
885
|
+
Vector frame (M, (f_0,f_1))
|
|
886
|
+
|
|
887
|
+
Then we have::
|
|
888
|
+
|
|
889
|
+
sage: TM.changes_of_frame() # random (dictionary output)
|
|
890
|
+
{(Coordinate frame (M, (∂/∂x,∂/∂y)),
|
|
891
|
+
Vector frame (M, (f_0,f_1))): Field of tangent-space
|
|
892
|
+
automorphisms on the 2-dimensional differentiable manifold M,
|
|
893
|
+
(Vector frame (M, (f_0,f_1)),
|
|
894
|
+
Coordinate frame (M, (∂/∂x,∂/∂y))): Field of tangent-space
|
|
895
|
+
automorphisms on the 2-dimensional differentiable manifold M}
|
|
896
|
+
|
|
897
|
+
Some checks::
|
|
898
|
+
|
|
899
|
+
sage: TM.changes_of_frame()[(e,f)] == a
|
|
900
|
+
True
|
|
901
|
+
sage: TM.changes_of_frame()[(f,e)] == a^(-1)
|
|
902
|
+
True
|
|
903
|
+
"""
|
|
904
|
+
base_cof = self._base_space.changes_of_frame()
|
|
905
|
+
# Filter out all frames with respect to dest_map:
|
|
906
|
+
cof = {}
|
|
907
|
+
for frames in base_cof:
|
|
908
|
+
if frames[0]._dest_map == self._dest_map:
|
|
909
|
+
cof[(frames[0], frames[1])] = base_cof[frames]
|
|
910
|
+
return cof
|
|
911
|
+
|
|
912
|
+
def frames(self):
|
|
913
|
+
r"""
|
|
914
|
+
Return the list of all vector frames defined on the base space of
|
|
915
|
+
``self`` with respect to the destination map.
|
|
916
|
+
|
|
917
|
+
.. SEEALSO::
|
|
918
|
+
|
|
919
|
+
For further details on frames on ``self`` see
|
|
920
|
+
:meth:`local_frame`.
|
|
921
|
+
|
|
922
|
+
OUTPUT: list of local frames defined on ``self``
|
|
923
|
+
|
|
924
|
+
EXAMPLES:
|
|
925
|
+
|
|
926
|
+
Vector frames on subsets of `\RR^2`::
|
|
927
|
+
|
|
928
|
+
sage: M = Manifold(2, 'R^2')
|
|
929
|
+
sage: c_cart.<x,y> = M.chart() # Cartesian coordinates on R^2
|
|
930
|
+
sage: TM = M.tangent_bundle()
|
|
931
|
+
sage: TM.frames()
|
|
932
|
+
[Coordinate frame (R^2, (∂/∂x,∂/∂y))]
|
|
933
|
+
sage: e = TM.vector_frame('e')
|
|
934
|
+
sage: TM.frames()
|
|
935
|
+
[Coordinate frame (R^2, (∂/∂x,∂/∂y)),
|
|
936
|
+
Vector frame (R^2, (e_0,e_1))]
|
|
937
|
+
sage: U = M.open_subset('U', coord_def={c_cart: x^2+y^2<1})
|
|
938
|
+
sage: TU = U.tangent_bundle()
|
|
939
|
+
sage: TU.frames()
|
|
940
|
+
[Coordinate frame (U, (∂/∂x,∂/∂y))]
|
|
941
|
+
sage: TM.frames()
|
|
942
|
+
[Coordinate frame (R^2, (∂/∂x,∂/∂y)),
|
|
943
|
+
Vector frame (R^2, (e_0,e_1)),
|
|
944
|
+
Coordinate frame (U, (∂/∂x,∂/∂y))]
|
|
945
|
+
|
|
946
|
+
List of vector frames of a tensor bundle of type `(1 ,1)` along a
|
|
947
|
+
curve::
|
|
948
|
+
|
|
949
|
+
sage: M = Manifold(2, 'M')
|
|
950
|
+
sage: c_cart.<x,y> = M.chart()
|
|
951
|
+
sage: e_cart = c_cart.frame() # standard basis
|
|
952
|
+
sage: R = Manifold(1, 'R')
|
|
953
|
+
sage: T.<t> = R.chart() # canonical chart on R
|
|
954
|
+
sage: Phi = R.diff_map(M, [cos(t), sin(t)], name='Phi') ; Phi
|
|
955
|
+
Differentiable map Phi from the 1-dimensional differentiable
|
|
956
|
+
manifold R to the 2-dimensional differentiable manifold M
|
|
957
|
+
sage: Phi.display()
|
|
958
|
+
Phi: R → M
|
|
959
|
+
t ↦ (x, y) = (cos(t), sin(t))
|
|
960
|
+
sage: PhiT11 = R.tensor_bundle(1, 1, dest_map=Phi); PhiT11
|
|
961
|
+
Tensor bundle Phi^*T^(1,1)M over the 1-dimensional differentiable
|
|
962
|
+
manifold R along the Differentiable map Phi from the 1-dimensional
|
|
963
|
+
differentiable manifold R to the 2-dimensional differentiable
|
|
964
|
+
manifold M
|
|
965
|
+
sage: f = PhiT11.local_frame(); f
|
|
966
|
+
Vector frame (R, (∂/∂x,∂/∂y)) with values on the 2-dimensional
|
|
967
|
+
differentiable manifold M
|
|
968
|
+
sage: PhiT11.frames()
|
|
969
|
+
[Vector frame (R, (∂/∂x,∂/∂y)) with values on the 2-dimensional
|
|
970
|
+
differentiable manifold M]
|
|
971
|
+
"""
|
|
972
|
+
if self._dest_map.is_identity():
|
|
973
|
+
return self._base_space.frames()
|
|
974
|
+
else:
|
|
975
|
+
# Filter out all frames with respect to dest_map:
|
|
976
|
+
frames = []
|
|
977
|
+
for frame in self._base_space.frames():
|
|
978
|
+
if frame._dest_map == self._dest_map:
|
|
979
|
+
frames.append(frame)
|
|
980
|
+
return frames
|
|
981
|
+
|
|
982
|
+
def coframes(self):
|
|
983
|
+
r"""
|
|
984
|
+
Return the list of coframes defined on the base manifold of ``self``
|
|
985
|
+
with respect to the destination map.
|
|
986
|
+
|
|
987
|
+
.. SEEALSO::
|
|
988
|
+
|
|
989
|
+
For further details on frames on ``self`` see
|
|
990
|
+
:meth:`local_frame`.
|
|
991
|
+
|
|
992
|
+
OUTPUT: list of coframes defined on ``self``
|
|
993
|
+
|
|
994
|
+
EXAMPLES:
|
|
995
|
+
|
|
996
|
+
Coframes on subsets of `\RR^2`::
|
|
997
|
+
|
|
998
|
+
sage: M = Manifold(2, 'R^2')
|
|
999
|
+
sage: c_cart.<x,y> = M.chart() # Cartesian coordinates on R^2
|
|
1000
|
+
sage: TM = M.tangent_bundle()
|
|
1001
|
+
sage: TM.coframes()
|
|
1002
|
+
[Coordinate coframe (R^2, (dx,dy))]
|
|
1003
|
+
sage: e = TM.vector_frame('e')
|
|
1004
|
+
sage: M.coframes()
|
|
1005
|
+
[Coordinate coframe (R^2, (dx,dy)), Coframe (R^2, (e^0,e^1))]
|
|
1006
|
+
sage: U = M.open_subset('U', coord_def={c_cart: x^2+y^2<1})
|
|
1007
|
+
sage: TU = U.tangent_bundle()
|
|
1008
|
+
sage: TU.coframes()
|
|
1009
|
+
[Coordinate coframe (U, (dx,dy))]
|
|
1010
|
+
sage: e.restrict(U)
|
|
1011
|
+
Vector frame (U, (e_0,e_1))
|
|
1012
|
+
sage: TU.coframes()
|
|
1013
|
+
[Coordinate coframe (U, (dx,dy)), Coframe (U, (e^0,e^1))]
|
|
1014
|
+
sage: TM.coframes()
|
|
1015
|
+
[Coordinate coframe (R^2, (dx,dy)),
|
|
1016
|
+
Coframe (R^2, (e^0,e^1)),
|
|
1017
|
+
Coordinate coframe (U, (dx,dy)),
|
|
1018
|
+
Coframe (U, (e^0,e^1))]
|
|
1019
|
+
"""
|
|
1020
|
+
if self._dest_map.is_identity():
|
|
1021
|
+
return self._base_space.coframes()
|
|
1022
|
+
else:
|
|
1023
|
+
# Filter out all coframes with respect to dest_map:
|
|
1024
|
+
coframes = []
|
|
1025
|
+
for coframe in self._base_space.coframes():
|
|
1026
|
+
if coframe._dest_map == self._dest_map:
|
|
1027
|
+
coframes.append(coframe)
|
|
1028
|
+
return coframes
|
|
1029
|
+
|
|
1030
|
+
def trivialization(self, coordinates='', names=None, calc_method=None):
|
|
1031
|
+
r"""
|
|
1032
|
+
Return a trivialization of ``self`` in terms of a chart on the codomain
|
|
1033
|
+
of the destination map.
|
|
1034
|
+
|
|
1035
|
+
.. NOTE::
|
|
1036
|
+
|
|
1037
|
+
Since a chart gives direct rise to a trivialization, this method is
|
|
1038
|
+
nothing but an invocation of
|
|
1039
|
+
:meth:`~sage.manifolds.manifold.TopologicalManifold.chart` of the
|
|
1040
|
+
class
|
|
1041
|
+
:class:`~sage.manifolds.manifold.TopologicalManifold`.
|
|
1042
|
+
|
|
1043
|
+
|
|
1044
|
+
INPUT:
|
|
1045
|
+
|
|
1046
|
+
- ``coordinates`` -- (default: ``''`` (empty string)) string
|
|
1047
|
+
defining the coordinate symbols, ranges and possible periodicities,
|
|
1048
|
+
see below
|
|
1049
|
+
- ``names`` -- (default: ``None``) unused argument, except if
|
|
1050
|
+
``coordinates`` is not provided; it must then be a tuple containing
|
|
1051
|
+
the coordinate symbols (this is guaranteed if the shortcut operator
|
|
1052
|
+
``<,>`` is used)
|
|
1053
|
+
- ``calc_method`` -- (default: ``None``) string defining the calculus
|
|
1054
|
+
method to be used on this chart; must be one of
|
|
1055
|
+
|
|
1056
|
+
- ``'SR'``: Sage's default symbolic engine (Symbolic Ring)
|
|
1057
|
+
- ``'sympy'``: SymPy
|
|
1058
|
+
- ``None``: the current calculus method defined on the manifold is
|
|
1059
|
+
used (cf.
|
|
1060
|
+
:meth:`~sage.manifolds.manifold.TopologicalManifold.set_calculus_method`)
|
|
1061
|
+
|
|
1062
|
+
The coordinates declared in the string ``coordinates`` are
|
|
1063
|
+
separated by ``' '`` (whitespace) and each coordinate has at most four
|
|
1064
|
+
fields, separated by a colon (``':'``):
|
|
1065
|
+
|
|
1066
|
+
1. The coordinate symbol (a letter or a few letters).
|
|
1067
|
+
2. (optional, only for manifolds over `\RR`) The interval `I`
|
|
1068
|
+
defining the coordinate range: if not provided, the coordinate
|
|
1069
|
+
is assumed to span all `\RR`; otherwise `I` must be provided
|
|
1070
|
+
in the form ``(a,b)`` (or equivalently ``]a,b[``)
|
|
1071
|
+
The bounds ``a`` and ``b`` can be ``+/-Infinity``, ``Inf``,
|
|
1072
|
+
``infinity``, ``inf`` or ``oo``. For *singular* coordinates,
|
|
1073
|
+
non-open intervals such as ``[a,b]`` and
|
|
1074
|
+
``(a,b]`` (or equivalently ``]a,b]``) are allowed. Note that
|
|
1075
|
+
the interval declaration must not contain any space character.
|
|
1076
|
+
3. (optional) Indicator of the periodic character of the coordinate,
|
|
1077
|
+
either as ``period=T``, where ``T`` is the period, or, for manifolds
|
|
1078
|
+
over `\RR` only, as the keyword ``periodic`` (the value of the
|
|
1079
|
+
period is then deduced from the interval `I` declared in field 2;
|
|
1080
|
+
see the example below)
|
|
1081
|
+
4. (optional) The LaTeX spelling of the coordinate; if not provided
|
|
1082
|
+
the coordinate symbol given in the first field will be used.
|
|
1083
|
+
|
|
1084
|
+
The order of fields 2 to 4 does not matter and each of them can
|
|
1085
|
+
be omitted. If it contains any LaTeX expression, the string
|
|
1086
|
+
``coordinates`` must be declared with the prefix 'r' (for "raw") to
|
|
1087
|
+
allow for a proper treatment of the backslash character (see
|
|
1088
|
+
examples below). If no interval range, no period and no LaTeX spelling
|
|
1089
|
+
is to be set for any coordinate, the argument ``coordinates`` can be
|
|
1090
|
+
omitted when the shortcut operator ``<,>`` is used to declare the
|
|
1091
|
+
trivialization.
|
|
1092
|
+
|
|
1093
|
+
OUTPUT:
|
|
1094
|
+
|
|
1095
|
+
- the created chart, as an instance of
|
|
1096
|
+
:class:`~sage.manifolds.chart.Chart` or one of its subclasses, like
|
|
1097
|
+
:class:`~sage.manifolds.differentiable.chart.RealDiffChart` for
|
|
1098
|
+
differentiable manifolds over `\RR`.
|
|
1099
|
+
|
|
1100
|
+
EXAMPLES:
|
|
1101
|
+
|
|
1102
|
+
Chart on a 2-dimensional manifold::
|
|
1103
|
+
|
|
1104
|
+
sage: M = Manifold(2, 'M')
|
|
1105
|
+
sage: TM = M.tangent_bundle()
|
|
1106
|
+
sage: X = TM.trivialization('x y'); X
|
|
1107
|
+
Chart (M, (x, y))
|
|
1108
|
+
sage: X[0]
|
|
1109
|
+
x
|
|
1110
|
+
sage: X[1]
|
|
1111
|
+
y
|
|
1112
|
+
sage: X[:]
|
|
1113
|
+
(x, y)
|
|
1114
|
+
"""
|
|
1115
|
+
return self._ambient_domain.chart(coordinates=coordinates, names=names,
|
|
1116
|
+
calc_method=calc_method)
|
|
1117
|
+
|
|
1118
|
+
def transitions(self):
|
|
1119
|
+
r"""
|
|
1120
|
+
Return the transition maps between trivialization maps in terms of
|
|
1121
|
+
coordinate changes defined via charts on the codomain of the
|
|
1122
|
+
destination map.
|
|
1123
|
+
|
|
1124
|
+
.. NOTE::
|
|
1125
|
+
|
|
1126
|
+
Since a chart gives direct rise to a trivialization, this method is
|
|
1127
|
+
nothing but an invocation of
|
|
1128
|
+
:meth:`~sage.manifolds.manifold.TopologicalManifold.coord_changes`
|
|
1129
|
+
of the class
|
|
1130
|
+
:class:`~sage.manifolds.manifold.TopologicalManifold`.
|
|
1131
|
+
|
|
1132
|
+
EXAMPLES:
|
|
1133
|
+
|
|
1134
|
+
Various changes of coordinates on a 2-dimensional manifold::
|
|
1135
|
+
|
|
1136
|
+
sage: M = Manifold(2, 'M')
|
|
1137
|
+
sage: c_xy.<x,y> = M.chart()
|
|
1138
|
+
sage: c_uv.<u,v> = M.chart()
|
|
1139
|
+
sage: xy_to_uv = c_xy.transition_map(c_uv, [x+y, x-y])
|
|
1140
|
+
sage: TM = M.tangent_bundle()
|
|
1141
|
+
sage: TM.transitions()
|
|
1142
|
+
{(Chart (M, (x, y)),
|
|
1143
|
+
Chart (M, (u, v))): Change of coordinates from Chart (M, (x, y))
|
|
1144
|
+
to Chart (M, (u, v))}
|
|
1145
|
+
sage: uv_to_xy = xy_to_uv.inverse()
|
|
1146
|
+
sage: TM.transitions() # random (dictionary output)
|
|
1147
|
+
{(Chart (M, (u, v)),
|
|
1148
|
+
Chart (M, (x, y))): Change of coordinates from Chart (M, (u, v))
|
|
1149
|
+
to Chart (M, (x, y)),
|
|
1150
|
+
(Chart (M, (x, y)),
|
|
1151
|
+
Chart (M, (u, v))): Change of coordinates from Chart (M, (x, y))
|
|
1152
|
+
to Chart (M, (u, v))}
|
|
1153
|
+
sage: c_rs.<r,s> = M.chart()
|
|
1154
|
+
sage: uv_to_rs = c_uv.transition_map(c_rs, [-u+2*v, 3*u-v])
|
|
1155
|
+
sage: TM.transitions() # random (dictionary output)
|
|
1156
|
+
{(Chart (M, (u, v)),
|
|
1157
|
+
Chart (M, (r, s))): Change of coordinates from Chart (M, (u, v))
|
|
1158
|
+
to Chart (M, (r, s)),
|
|
1159
|
+
(Chart (M, (u, v)),
|
|
1160
|
+
Chart (M, (x, y))): Change of coordinates from Chart (M, (u, v))
|
|
1161
|
+
to Chart (M, (x, y)),
|
|
1162
|
+
(Chart (M, (x, y)),
|
|
1163
|
+
Chart (M, (u, v))): Change of coordinates from Chart (M, (x, y))
|
|
1164
|
+
to Chart (M, (u, v))}
|
|
1165
|
+
sage: xy_to_rs = uv_to_rs * xy_to_uv
|
|
1166
|
+
sage: TM.transitions() # random (dictionary output)
|
|
1167
|
+
{(Chart (M, (u, v)),
|
|
1168
|
+
Chart (M, (r, s))): Change of coordinates from Chart (M, (u, v))
|
|
1169
|
+
to Chart (M, (r, s)),
|
|
1170
|
+
(Chart (M, (u, v)),
|
|
1171
|
+
Chart (M, (x, y))): Change of coordinates from Chart (M, (u, v))
|
|
1172
|
+
to Chart (M, (x, y)),
|
|
1173
|
+
(Chart (M, (x, y)),
|
|
1174
|
+
Chart (M, (u, v))): Change of coordinates from Chart (M, (x, y))
|
|
1175
|
+
to Chart (M, (u, v)),
|
|
1176
|
+
(Chart (M, (x, y)),
|
|
1177
|
+
Chart (M, (r, s))): Change of coordinates from Chart (M, (x, y))
|
|
1178
|
+
to Chart (M, (r, s))}
|
|
1179
|
+
"""
|
|
1180
|
+
return self._ambient_domain.coord_changes()
|
|
1181
|
+
|
|
1182
|
+
def transition(self, chart1, chart2):
|
|
1183
|
+
r"""
|
|
1184
|
+
Return the change of trivializations in terms of a coordinate change
|
|
1185
|
+
between two differentiable charts defined on the codomain of the
|
|
1186
|
+
destination map.
|
|
1187
|
+
|
|
1188
|
+
The differentiable chart must have been defined previously, for
|
|
1189
|
+
instance by the method
|
|
1190
|
+
:meth:`~sage.manifolds.chart.Chart.transition_map`.
|
|
1191
|
+
|
|
1192
|
+
.. NOTE::
|
|
1193
|
+
|
|
1194
|
+
Since a chart gives direct rise to a trivialization, this method is
|
|
1195
|
+
nothing but an invocation of
|
|
1196
|
+
:meth:`~sage.manifolds.manifold.TopologicalManifold.coord_change`
|
|
1197
|
+
of the class :class:`~sage.manifolds.manifold.TopologicalManifold`.
|
|
1198
|
+
|
|
1199
|
+
INPUT:
|
|
1200
|
+
|
|
1201
|
+
- ``chart1`` -- chart 1
|
|
1202
|
+
- ``chart2`` -- chart 2
|
|
1203
|
+
|
|
1204
|
+
OUTPUT:
|
|
1205
|
+
|
|
1206
|
+
- instance of :class:`~sage.manifolds.chart.CoordChange`
|
|
1207
|
+
representing the transition map from chart 1 to chart 2
|
|
1208
|
+
|
|
1209
|
+
EXAMPLES:
|
|
1210
|
+
|
|
1211
|
+
Change of coordinates on a 2-dimensional manifold::
|
|
1212
|
+
|
|
1213
|
+
sage: M = Manifold(2, 'M')
|
|
1214
|
+
sage: c_xy.<x,y> = M.chart()
|
|
1215
|
+
sage: c_uv.<u,v> = M.chart()
|
|
1216
|
+
sage: c_xy.transition_map(c_uv, (x+y, x-y)) # defines coord. change
|
|
1217
|
+
Change of coordinates from Chart (M, (x, y)) to Chart (M, (u, v))
|
|
1218
|
+
sage: TM = M.tangent_bundle()
|
|
1219
|
+
sage: TM.transition(c_xy, c_uv) # returns the coord. change above
|
|
1220
|
+
Change of coordinates from Chart (M, (x, y)) to Chart (M, (u, v))
|
|
1221
|
+
"""
|
|
1222
|
+
return self._ambient_domain.coord_change(chart1, chart2)
|
|
1223
|
+
|
|
1224
|
+
def is_manifestly_trivial(self):
|
|
1225
|
+
r"""
|
|
1226
|
+
Return ``True`` if ``self`` is known to be a trivial and ``False``
|
|
1227
|
+
otherwise.
|
|
1228
|
+
|
|
1229
|
+
If ``False`` is returned, either the tensor bundle is not trivial
|
|
1230
|
+
or no vector frame has been defined on it yet.
|
|
1231
|
+
|
|
1232
|
+
EXAMPLES:
|
|
1233
|
+
|
|
1234
|
+
A just created manifold has a priori no manifestly trivial tangent
|
|
1235
|
+
bundle::
|
|
1236
|
+
|
|
1237
|
+
sage: M = Manifold(2, 'M')
|
|
1238
|
+
sage: TM = M.tangent_bundle()
|
|
1239
|
+
sage: TM.is_manifestly_trivial()
|
|
1240
|
+
False
|
|
1241
|
+
|
|
1242
|
+
Defining a vector frame on it makes it trivial::
|
|
1243
|
+
|
|
1244
|
+
sage: e = TM.vector_frame('e')
|
|
1245
|
+
sage: TM.is_manifestly_trivial()
|
|
1246
|
+
True
|
|
1247
|
+
|
|
1248
|
+
Defining a coordinate chart on the whole manifold also makes it
|
|
1249
|
+
trivial::
|
|
1250
|
+
|
|
1251
|
+
sage: N = Manifold(4, 'N')
|
|
1252
|
+
sage: X.<t,x,y,z> = N.chart()
|
|
1253
|
+
sage: TN = N.tangent_bundle()
|
|
1254
|
+
sage: TN.is_manifestly_trivial()
|
|
1255
|
+
True
|
|
1256
|
+
|
|
1257
|
+
The situation is not so clear anymore when a destination map to a
|
|
1258
|
+
non-parallelizable manifold is stated::
|
|
1259
|
+
|
|
1260
|
+
sage: M = Manifold(2, 'S^2') # the 2-dimensional sphere S^2
|
|
1261
|
+
sage: U = M.open_subset('U') # complement of the North pole
|
|
1262
|
+
sage: c_xy.<x,y> = U.chart() # stereo coord from the North pole
|
|
1263
|
+
sage: V = M.open_subset('V') # complement of the South pole
|
|
1264
|
+
sage: c_uv.<u,v> = V.chart() # stereo coord from the South pole
|
|
1265
|
+
sage: M.declare_union(U,V) # S^2 is the union of U and V
|
|
1266
|
+
sage: xy_to_uv = c_xy.transition_map(c_uv, (x/(x^2+y^2),
|
|
1267
|
+
....: y/(x^2+y^2)),
|
|
1268
|
+
....: intersection_name='W',
|
|
1269
|
+
....: restrictions1= x^2+y^2!=0,
|
|
1270
|
+
....: restrictions2= u^2+v^2!=0)
|
|
1271
|
+
sage: uv_to_xy = xy_to_uv.inverse()
|
|
1272
|
+
sage: W = U.intersection(V)
|
|
1273
|
+
sage: Phi = U.diff_map(M, {(c_xy, c_xy): [x, y]},
|
|
1274
|
+
....: name='Phi') # inclusion map
|
|
1275
|
+
sage: PhiTU = U.tangent_bundle(dest_map=Phi); PhiTU
|
|
1276
|
+
Tangent bundle Phi^*TS^2 over the Open subset U of the
|
|
1277
|
+
2-dimensional differentiable manifold S^2 along the
|
|
1278
|
+
Differentiable map Phi from the Open subset U of the
|
|
1279
|
+
2-dimensional differentiable manifold S^2 to the 2-dimensional
|
|
1280
|
+
differentiable manifold S^2
|
|
1281
|
+
|
|
1282
|
+
A priori, the pullback tangent bundle is not trivial::
|
|
1283
|
+
|
|
1284
|
+
sage: PhiTU.is_manifestly_trivial()
|
|
1285
|
+
False
|
|
1286
|
+
|
|
1287
|
+
But certainly, this bundle must be trivial since `U` is parallelizable.
|
|
1288
|
+
To ensure this, we need to define a local frame on `U` with values
|
|
1289
|
+
in `\Phi^*TS^2`::
|
|
1290
|
+
|
|
1291
|
+
sage: PhiTU.local_frame('e', from_frame=c_xy.frame())
|
|
1292
|
+
Vector frame (U, (e_0,e_1)) with values on the 2-dimensional
|
|
1293
|
+
differentiable manifold S^2
|
|
1294
|
+
sage: PhiTU.is_manifestly_trivial()
|
|
1295
|
+
True
|
|
1296
|
+
"""
|
|
1297
|
+
if self._dest_map.is_identity():
|
|
1298
|
+
# The standard case:
|
|
1299
|
+
return self._base_space.is_manifestly_parallelizable()
|
|
1300
|
+
else:
|
|
1301
|
+
# If the ambient domain is manifestly trivial, the pullback bundle
|
|
1302
|
+
# is certainly trivial:
|
|
1303
|
+
if self._ambient_domain.is_manifestly_parallelizable():
|
|
1304
|
+
return True
|
|
1305
|
+
# Otherwise check whether a global frame on the pullback bundle is
|
|
1306
|
+
# defined:
|
|
1307
|
+
for frame in self.frames():
|
|
1308
|
+
if frame._domain is self._base_space:
|
|
1309
|
+
return True
|
|
1310
|
+
return False
|
|
1311
|
+
|
|
1312
|
+
def local_frame(self, *args, **kwargs):
|
|
1313
|
+
r"""
|
|
1314
|
+
Define a vector frame on ``domain``, possibly with values in the
|
|
1315
|
+
tangent bundle of the ambient domain.
|
|
1316
|
+
|
|
1317
|
+
If the basis specified by the given symbol already exists, it is
|
|
1318
|
+
simply returned.
|
|
1319
|
+
If no argument is provided the vector field module's default frame is
|
|
1320
|
+
returned.
|
|
1321
|
+
|
|
1322
|
+
Notice, that a vector frame automatically induces a local frame on the
|
|
1323
|
+
tensor bundle ``self``. More precisely, if `e: U \to \Phi^*TN` is a
|
|
1324
|
+
vector frame on `U \subset M` with values in `\Phi^*TN` along the
|
|
1325
|
+
destination map
|
|
1326
|
+
|
|
1327
|
+
.. MATH::
|
|
1328
|
+
|
|
1329
|
+
\Phi: M \longrightarrow N
|
|
1330
|
+
|
|
1331
|
+
then the map
|
|
1332
|
+
|
|
1333
|
+
.. MATH::
|
|
1334
|
+
|
|
1335
|
+
p \mapsto \Big(\underbrace{e^*(p), \dots, e^*(p)}_{k\ \; \text{times}},
|
|
1336
|
+
\underbrace{e(p), \dots, e(p)}_{l\ \; \text{times}}\Big) \in
|
|
1337
|
+
T^{(k,l)}_q N ,
|
|
1338
|
+
|
|
1339
|
+
with `q=\Phi(p)`, defines a basis at each point `p \in U` and
|
|
1340
|
+
therefore gives rise to a local frame on `\Phi^* T^{(k,l)}N` on the
|
|
1341
|
+
domain `U`.
|
|
1342
|
+
|
|
1343
|
+
.. SEEALSO::
|
|
1344
|
+
|
|
1345
|
+
:class:`~sage.manifolds.differentiable.vectorframe.VectorFrame`
|
|
1346
|
+
for complete documentation.
|
|
1347
|
+
|
|
1348
|
+
INPUT:
|
|
1349
|
+
|
|
1350
|
+
- ``symbol`` -- (default: ``None``) either a string, to be used as a
|
|
1351
|
+
common base for the symbols of the vector fields constituting the
|
|
1352
|
+
vector frame, or a list/tuple of strings, representing the individual
|
|
1353
|
+
symbols of the vector fields; can be ``None`` only if ``from_frame``
|
|
1354
|
+
is not ``None`` (see below)
|
|
1355
|
+
- ``vector_fields`` -- tuple or list of `n` linearly independent vector
|
|
1356
|
+
fields on ``domain`` (`n` being the dimension of ``domain``)
|
|
1357
|
+
defining the vector frame; can be omitted if the vector frame is
|
|
1358
|
+
created from scratch or if ``from_frame`` is not ``None``
|
|
1359
|
+
- ``latex_symbol`` -- (default: ``None``) either a string, to be used
|
|
1360
|
+
as a common base for the LaTeX symbols of the vector fields
|
|
1361
|
+
constituting the vector frame, or a list/tuple of strings,
|
|
1362
|
+
representing the individual LaTeX symbols of the vector fields;
|
|
1363
|
+
if ``None``, ``symbol`` is used in place of ``latex_symbol``
|
|
1364
|
+
- ``from_frame`` -- (default: ``None``) vector frame `\tilde{e}`
|
|
1365
|
+
on the codomain `N` of the destination map `\Phi`; the returned
|
|
1366
|
+
frame `e` is then such that for all `p \in U`,
|
|
1367
|
+
we have `e(p) = \tilde{e}(\Phi(p))`
|
|
1368
|
+
- ``indices`` -- (default: ``None``; used only if ``symbol`` is a
|
|
1369
|
+
single string) tuple of strings representing the indices labelling
|
|
1370
|
+
the vector fields of the frame; if ``None``, the indices will be
|
|
1371
|
+
generated as integers within the range declared on ``self``
|
|
1372
|
+
- ``latex_indices`` -- (default: ``None``) tuple of strings
|
|
1373
|
+
representing the indices for the LaTeX symbols of the vector fields;
|
|
1374
|
+
if ``None``, ``indices`` is used instead
|
|
1375
|
+
- ``symbol_dual`` -- (default: ``None``) same as ``symbol`` but for the
|
|
1376
|
+
dual coframe; if ``None``, ``symbol`` must be a string and is used
|
|
1377
|
+
for the common base of the symbols of the elements of the dual
|
|
1378
|
+
coframe
|
|
1379
|
+
- ``latex_symbol_dual`` -- (default: ``None``) same as ``latex_symbol``
|
|
1380
|
+
but for the dual coframe
|
|
1381
|
+
- ``domain`` -- (default: ``None``) domain on which the local frame is
|
|
1382
|
+
defined; if ``None`` is provided, the base space of ``self`` is
|
|
1383
|
+
assumed
|
|
1384
|
+
|
|
1385
|
+
OUTPUT:
|
|
1386
|
+
|
|
1387
|
+
- the vector frame corresponding to the above specifications; this is
|
|
1388
|
+
an instance of
|
|
1389
|
+
:class:`~sage.manifolds.differentiable.vectorframe.VectorFrame`.
|
|
1390
|
+
|
|
1391
|
+
EXAMPLES:
|
|
1392
|
+
|
|
1393
|
+
Defining a local frame for the tangent bundle of a 3-dimensional
|
|
1394
|
+
manifold::
|
|
1395
|
+
|
|
1396
|
+
sage: M = Manifold(3, 'M')
|
|
1397
|
+
sage: TM = M.tangent_bundle()
|
|
1398
|
+
sage: e = TM.local_frame('e'); e
|
|
1399
|
+
Vector frame (M, (e_0,e_1,e_2))
|
|
1400
|
+
sage: e[0]
|
|
1401
|
+
Vector field e_0 on the 3-dimensional differentiable manifold M
|
|
1402
|
+
|
|
1403
|
+
Specifying the domain of the vector frame::
|
|
1404
|
+
|
|
1405
|
+
sage: U = M.open_subset('U')
|
|
1406
|
+
sage: f = TM.local_frame('f', domain=U); f
|
|
1407
|
+
Vector frame (U, (f_0,f_1,f_2))
|
|
1408
|
+
sage: f[0]
|
|
1409
|
+
Vector field f_0 on the Open subset U of the 3-dimensional
|
|
1410
|
+
differentiable manifold M
|
|
1411
|
+
|
|
1412
|
+
.. SEEALSO::
|
|
1413
|
+
|
|
1414
|
+
For more options, in particular for the choice of symbols and
|
|
1415
|
+
indices, see
|
|
1416
|
+
:class:`~sage.manifolds.differentiable.vectorframe.VectorFrame`.
|
|
1417
|
+
"""
|
|
1418
|
+
domain = kwargs.pop('domain', None)
|
|
1419
|
+
if domain is None:
|
|
1420
|
+
domain = self._base_space
|
|
1421
|
+
dest_map = self._dest_map.restrict(domain)
|
|
1422
|
+
if not args and not kwargs:
|
|
1423
|
+
# if no argument is provided, the default basis of the
|
|
1424
|
+
# base vector field module is returned:
|
|
1425
|
+
return domain.vector_field_module(dest_map=dest_map,
|
|
1426
|
+
force_free=True).basis()
|
|
1427
|
+
kwargs['dest_map'] = dest_map
|
|
1428
|
+
return domain.vector_frame(*args, **kwargs)
|
|
1429
|
+
|
|
1430
|
+
vector_frame = local_frame
|
|
1431
|
+
|
|
1432
|
+
def ambient_domain(self):
|
|
1433
|
+
r"""
|
|
1434
|
+
Return the codomain of the destination map.
|
|
1435
|
+
|
|
1436
|
+
OUTPUT:
|
|
1437
|
+
|
|
1438
|
+
- a :class:`~sage.manifolds.differentiable.manifold.DifferentiableManifold`
|
|
1439
|
+
representing the codomain of the destination map
|
|
1440
|
+
|
|
1441
|
+
EXAMPLES::
|
|
1442
|
+
|
|
1443
|
+
sage: M = Manifold(2, 'M')
|
|
1444
|
+
sage: c_cart.<x,y> = M.chart()
|
|
1445
|
+
sage: e_cart = c_cart.frame() # standard basis
|
|
1446
|
+
sage: R = Manifold(1, 'R')
|
|
1447
|
+
sage: T.<t> = R.chart() # canonical chart on R
|
|
1448
|
+
sage: Phi = R.diff_map(M, [cos(t), sin(t)], name='Phi') ; Phi
|
|
1449
|
+
Differentiable map Phi from the 1-dimensional differentiable
|
|
1450
|
+
manifold R to the 2-dimensional differentiable manifold M
|
|
1451
|
+
sage: Phi.display()
|
|
1452
|
+
Phi: R → M
|
|
1453
|
+
t ↦ (x, y) = (cos(t), sin(t))
|
|
1454
|
+
sage: PhiT11 = R.tensor_bundle(1, 1, dest_map=Phi)
|
|
1455
|
+
sage: PhiT11.ambient_domain()
|
|
1456
|
+
2-dimensional differentiable manifold M
|
|
1457
|
+
"""
|
|
1458
|
+
return self._ambient_domain
|
|
1459
|
+
|
|
1460
|
+
def destination_map(self):
|
|
1461
|
+
r"""
|
|
1462
|
+
Return the destination map.
|
|
1463
|
+
|
|
1464
|
+
OUTPUT:
|
|
1465
|
+
|
|
1466
|
+
- a :class:`~sage.manifolds.differentiable.diff_map.DifferentialMap`
|
|
1467
|
+
representing the destination map
|
|
1468
|
+
|
|
1469
|
+
EXAMPLES::
|
|
1470
|
+
|
|
1471
|
+
sage: M = Manifold(2, 'M')
|
|
1472
|
+
sage: c_cart.<x,y> = M.chart()
|
|
1473
|
+
sage: e_cart = c_cart.frame() # standard basis
|
|
1474
|
+
sage: R = Manifold(1, 'R')
|
|
1475
|
+
sage: T.<t> = R.chart() # canonical chart on R
|
|
1476
|
+
sage: Phi = R.diff_map(M, [cos(t), sin(t)], name='Phi') ; Phi
|
|
1477
|
+
Differentiable map Phi from the 1-dimensional differentiable
|
|
1478
|
+
manifold R to the 2-dimensional differentiable manifold M
|
|
1479
|
+
sage: Phi.display()
|
|
1480
|
+
Phi: R → M
|
|
1481
|
+
t ↦ (x, y) = (cos(t), sin(t))
|
|
1482
|
+
sage: PhiT11 = R.tensor_bundle(1, 1, dest_map=Phi)
|
|
1483
|
+
sage: PhiT11.destination_map()
|
|
1484
|
+
Differentiable map Phi from the 1-dimensional differentiable
|
|
1485
|
+
manifold R to the 2-dimensional differentiable manifold M
|
|
1486
|
+
"""
|
|
1487
|
+
return self._dest_map
|
|
1488
|
+
|
|
1489
|
+
def default_frame(self):
|
|
1490
|
+
r"""
|
|
1491
|
+
Return the default vector frame defined on ``self``.
|
|
1492
|
+
|
|
1493
|
+
By *vector frame*, it is meant a field on the manifold that provides,
|
|
1494
|
+
at each point `p`, a vector basis of the pulled back tangent space at
|
|
1495
|
+
`p`.
|
|
1496
|
+
|
|
1497
|
+
If the destination map is the identity map, the default frame is the
|
|
1498
|
+
the first one defined on the manifold, usually the coordinate frame,
|
|
1499
|
+
unless it is changed via :meth:`set_default_frame`.
|
|
1500
|
+
|
|
1501
|
+
If the destination map is non-trivial, the default frame usually must
|
|
1502
|
+
be set via :meth:`set_default_frame`.
|
|
1503
|
+
|
|
1504
|
+
OUTPUT:
|
|
1505
|
+
|
|
1506
|
+
- a :class:`~sage.manifolds.differentiable.vectorframe.VectorFrame`
|
|
1507
|
+
representing the default vector frame
|
|
1508
|
+
|
|
1509
|
+
EXAMPLES:
|
|
1510
|
+
|
|
1511
|
+
The default vector frame is often the coordinate frame associated
|
|
1512
|
+
with the first chart defined on the manifold::
|
|
1513
|
+
|
|
1514
|
+
sage: M = Manifold(2, 'M')
|
|
1515
|
+
sage: c_xy.<x,y> = M.chart()
|
|
1516
|
+
sage: TM = M.tangent_bundle()
|
|
1517
|
+
sage: TM.default_frame()
|
|
1518
|
+
Coordinate frame (M, (∂/∂x,∂/∂y))
|
|
1519
|
+
"""
|
|
1520
|
+
def_bframe = self._base_space.default_frame()
|
|
1521
|
+
if self._def_frame is None and def_bframe is not None:
|
|
1522
|
+
if def_bframe._dest_map == self._dest_map:
|
|
1523
|
+
self._def_frame = def_bframe
|
|
1524
|
+
return self._def_frame
|
|
1525
|
+
|
|
1526
|
+
def set_default_frame(self, frame):
|
|
1527
|
+
r"""
|
|
1528
|
+
Changing the default vector frame on ``self``.
|
|
1529
|
+
|
|
1530
|
+
.. NOTE::
|
|
1531
|
+
|
|
1532
|
+
If the destination map is the identity, the default frame of the
|
|
1533
|
+
base manifold gets changed here as well.
|
|
1534
|
+
|
|
1535
|
+
INPUT:
|
|
1536
|
+
|
|
1537
|
+
- ``frame`` --
|
|
1538
|
+
:class:`~sage.manifolds.differentiable.vectorframe.VectorFrame`
|
|
1539
|
+
a vector frame defined on the base manifold
|
|
1540
|
+
|
|
1541
|
+
EXAMPLES:
|
|
1542
|
+
|
|
1543
|
+
Changing the default frame on the tangent bundle of a 2-dimensional
|
|
1544
|
+
manifold::
|
|
1545
|
+
|
|
1546
|
+
sage: M = Manifold(2, 'M')
|
|
1547
|
+
sage: c_xy.<x,y> = M.chart()
|
|
1548
|
+
sage: TM = M.tangent_bundle()
|
|
1549
|
+
sage: e = TM.vector_frame('e')
|
|
1550
|
+
sage: TM.default_frame()
|
|
1551
|
+
Coordinate frame (M, (∂/∂x,∂/∂y))
|
|
1552
|
+
sage: TM.set_default_frame(e)
|
|
1553
|
+
sage: TM.default_frame()
|
|
1554
|
+
Vector frame (M, (e_0,e_1))
|
|
1555
|
+
sage: M.default_frame()
|
|
1556
|
+
Vector frame (M, (e_0,e_1))
|
|
1557
|
+
"""
|
|
1558
|
+
from sage.manifolds.differentiable.vectorframe import VectorFrame
|
|
1559
|
+
if not isinstance(frame, VectorFrame):
|
|
1560
|
+
raise TypeError("{} is not a vector frame".format(frame))
|
|
1561
|
+
if (not frame._domain.is_subset(self._base_space) or
|
|
1562
|
+
frame._dest_map != self._dest_map):
|
|
1563
|
+
raise ValueError("the frame must be defined on " +
|
|
1564
|
+
"the {}".format(self))
|
|
1565
|
+
if self._dest_map.is_identity():
|
|
1566
|
+
self._base_space.set_default_frame(frame)
|
|
1567
|
+
else:
|
|
1568
|
+
frame._fmodule.set_default_basis(frame)
|
|
1569
|
+
self._def_frame = frame
|
|
1570
|
+
|
|
1571
|
+
def set_orientation(self, orientation):
|
|
1572
|
+
r"""
|
|
1573
|
+
Set the preferred orientation of ``self``.
|
|
1574
|
+
|
|
1575
|
+
INPUT:
|
|
1576
|
+
|
|
1577
|
+
- ``orientation`` -- a vector frame or a list of vector frames, covering
|
|
1578
|
+
the base space of ``self``
|
|
1579
|
+
|
|
1580
|
+
.. NOTE::
|
|
1581
|
+
|
|
1582
|
+
If the destination map is the identity, the preferred orientation
|
|
1583
|
+
of the base manifold gets changed here as well.
|
|
1584
|
+
|
|
1585
|
+
.. WARNING::
|
|
1586
|
+
|
|
1587
|
+
It is the user's responsibility that the orientation set here
|
|
1588
|
+
is indeed an orientation. There is no check going on in the
|
|
1589
|
+
background. See :meth:`orientation` for the definition of an
|
|
1590
|
+
orientation.
|
|
1591
|
+
|
|
1592
|
+
EXAMPLES:
|
|
1593
|
+
|
|
1594
|
+
Set an orientation on a tensor bundle::
|
|
1595
|
+
|
|
1596
|
+
sage: M = Manifold(2, 'M')
|
|
1597
|
+
sage: c_xy.<x,y> = M.chart()
|
|
1598
|
+
sage: T11 = M.tensor_bundle(1, 1)
|
|
1599
|
+
sage: e = T11.local_frame('e'); e
|
|
1600
|
+
Vector frame (M, (e_0,e_1))
|
|
1601
|
+
sage: T11.set_orientation(e)
|
|
1602
|
+
sage: T11.orientation()
|
|
1603
|
+
[Vector frame (M, (e_0,e_1))]
|
|
1604
|
+
|
|
1605
|
+
Set an orientation in the non-trivial case::
|
|
1606
|
+
|
|
1607
|
+
sage: M = Manifold(2, 'M')
|
|
1608
|
+
sage: U = M.open_subset('U'); V = M.open_subset('V')
|
|
1609
|
+
sage: M.declare_union(U, V)
|
|
1610
|
+
sage: c_xy.<x,y> = U.chart(); c_uv.<u,v> = V.chart()
|
|
1611
|
+
sage: T12 = M.tensor_bundle(1, 2)
|
|
1612
|
+
sage: e = T12.local_frame('e', domain=U)
|
|
1613
|
+
sage: f = T12.local_frame('f', domain=V)
|
|
1614
|
+
sage: T12.set_orientation([e, f])
|
|
1615
|
+
sage: T12.orientation()
|
|
1616
|
+
[Vector frame (U, (e_0,e_1)), Vector frame (V, (f_0,f_1))]
|
|
1617
|
+
"""
|
|
1618
|
+
if self._dest_map.is_identity():
|
|
1619
|
+
base_space = self._base_space
|
|
1620
|
+
base_space.set_orientation(orientation)
|
|
1621
|
+
self._orientation = base_space._orientation
|
|
1622
|
+
else:
|
|
1623
|
+
super().set_orientation(orientation)
|
|
1624
|
+
|
|
1625
|
+
def orientation(self):
|
|
1626
|
+
r"""
|
|
1627
|
+
Get the preferred orientation of ``self`` if available.
|
|
1628
|
+
|
|
1629
|
+
See :meth:`~sage.manifolds.vector_bundle.TopologicalVectorBundle.orientation`
|
|
1630
|
+
for details regarding orientations on vector bundles.
|
|
1631
|
+
|
|
1632
|
+
The tensor bundle `\Phi^* T^{(k,l)}N` of a manifold is orientable if
|
|
1633
|
+
the manifold `\Phi(M)` is orientable. The converse does not
|
|
1634
|
+
necessarily hold true. The usual case corresponds to `\Phi`
|
|
1635
|
+
being the identity map, where the tensor bundle `T^{(k,l)}M` is
|
|
1636
|
+
orientable if and only if the manifold `M` is orientable.
|
|
1637
|
+
|
|
1638
|
+
.. NOTE::
|
|
1639
|
+
|
|
1640
|
+
Notice that the orientation of a general tensor bundle
|
|
1641
|
+
`\Phi^* T^{(k,l)}N` is canonically induced by the orientation of
|
|
1642
|
+
the tensor bundle `\Phi^* T^{(1,0)}N` as each local frame there
|
|
1643
|
+
induces the frames on `\Phi^* T^{(k,l)}N` in a canonical way.
|
|
1644
|
+
|
|
1645
|
+
If no preferred orientation has been set before, and if the ambient
|
|
1646
|
+
space already admits a preferred orientation, the corresponding
|
|
1647
|
+
orientation is returned and henceforth fixed for the tensor bundle.
|
|
1648
|
+
|
|
1649
|
+
EXAMPLES:
|
|
1650
|
+
|
|
1651
|
+
In the trivial case, i.e. if the destination map is the identity
|
|
1652
|
+
and the tangent bundle is covered by one frame, the orientation is
|
|
1653
|
+
easily obtained::
|
|
1654
|
+
|
|
1655
|
+
sage: M = Manifold(2, 'M')
|
|
1656
|
+
sage: c_xy.<x,y> = M.chart()
|
|
1657
|
+
sage: T11 = M.tensor_bundle(1, 1)
|
|
1658
|
+
sage: T11.orientation()
|
|
1659
|
+
[Coordinate frame (M, (∂/∂x,∂/∂y))]
|
|
1660
|
+
|
|
1661
|
+
The same holds true if the ambient domain admits a trivial
|
|
1662
|
+
orientation::
|
|
1663
|
+
|
|
1664
|
+
sage: M = Manifold(2, 'M')
|
|
1665
|
+
sage: c_xy.<x,y> = M.chart()
|
|
1666
|
+
sage: R = Manifold(1, 'R')
|
|
1667
|
+
sage: c_t.<t> = R.chart()
|
|
1668
|
+
sage: Phi = R.diff_map(M, name='Phi')
|
|
1669
|
+
sage: PhiT22 = R.tensor_bundle(2, 2, dest_map=Phi); PhiT22
|
|
1670
|
+
Tensor bundle Phi^*T^(2,2)M over the 1-dimensional differentiable
|
|
1671
|
+
manifold R along the Differentiable map Phi from the 1-dimensional
|
|
1672
|
+
differentiable manifold R to the 2-dimensional differentiable
|
|
1673
|
+
manifold M
|
|
1674
|
+
sage: PhiT22.local_frame() # initialize frame
|
|
1675
|
+
Vector frame (R, (∂/∂x,∂/∂y)) with values on the 2-dimensional
|
|
1676
|
+
differentiable manifold M
|
|
1677
|
+
sage: PhiT22.orientation()
|
|
1678
|
+
[Vector frame (R, (∂/∂x,∂/∂y)) with values on the 2-dimensional
|
|
1679
|
+
differentiable manifold M]
|
|
1680
|
+
sage: PhiT22.local_frame() is PhiT22.orientation()[0]
|
|
1681
|
+
True
|
|
1682
|
+
|
|
1683
|
+
In the non-trivial case, however, the orientation must be set
|
|
1684
|
+
manually by the user::
|
|
1685
|
+
|
|
1686
|
+
sage: M = Manifold(2, 'M')
|
|
1687
|
+
sage: U = M.open_subset('U'); V = M.open_subset('V')
|
|
1688
|
+
sage: M.declare_union(U, V)
|
|
1689
|
+
sage: c_xy.<x,y> = U.chart(); c_uv.<u,v> = V.chart()
|
|
1690
|
+
sage: T11 = M.tensor_bundle(1, 1); T11
|
|
1691
|
+
Tensor bundle T^(1,1)M over the 2-dimensional differentiable
|
|
1692
|
+
manifold M
|
|
1693
|
+
sage: T11.orientation()
|
|
1694
|
+
[]
|
|
1695
|
+
sage: T11.set_orientation([c_xy.frame(), c_uv.frame()])
|
|
1696
|
+
sage: T11.orientation()
|
|
1697
|
+
[Coordinate frame (U, (∂/∂x,∂/∂y)),
|
|
1698
|
+
Coordinate frame (V, (∂/∂u,∂/∂v))]
|
|
1699
|
+
|
|
1700
|
+
If the destination map is the identity, the orientation is
|
|
1701
|
+
automatically set for the manifold, too::
|
|
1702
|
+
|
|
1703
|
+
sage: M.orientation()
|
|
1704
|
+
[Coordinate frame (U, (∂/∂x,∂/∂y)),
|
|
1705
|
+
Coordinate frame (V, (∂/∂u,∂/∂v))]
|
|
1706
|
+
|
|
1707
|
+
Conversely, if one sets an orientation on the manifold,
|
|
1708
|
+
the orientation on its tensor bundles is set accordingly::
|
|
1709
|
+
|
|
1710
|
+
sage: c_tz.<t,z> = U.chart()
|
|
1711
|
+
sage: M.set_orientation([c_tz, c_uv])
|
|
1712
|
+
sage: T11.orientation()
|
|
1713
|
+
[Coordinate frame (U, (∂/∂t,∂/∂z)),
|
|
1714
|
+
Coordinate frame (V, (∂/∂u,∂/∂v))]
|
|
1715
|
+
"""
|
|
1716
|
+
if self._dest_map.is_identity():
|
|
1717
|
+
self._orientation = self._base_space.orientation()
|
|
1718
|
+
if not self._orientation:
|
|
1719
|
+
if not self._dest_map.is_identity():
|
|
1720
|
+
# try to get orientation from ambient space:
|
|
1721
|
+
ambient_domain = self._ambient_domain
|
|
1722
|
+
amb_orient = ambient_domain.orientation()
|
|
1723
|
+
if amb_orient:
|
|
1724
|
+
for frame in self.frames():
|
|
1725
|
+
from_frame = frame._from_frame
|
|
1726
|
+
if from_frame in amb_orient:
|
|
1727
|
+
self._orientation.append(frame)
|
|
1728
|
+
return list(self._orientation)
|