passagemath-symbolics 10.8.1a1__cp311-cp311-macosx_13_0_arm64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (182) hide show
  1. passagemath_symbolics/.dylibs/libgmp.10.dylib +0 -0
  2. passagemath_symbolics/__init__.py +3 -0
  3. passagemath_symbolics-10.8.1a1.dist-info/METADATA +186 -0
  4. passagemath_symbolics-10.8.1a1.dist-info/RECORD +182 -0
  5. passagemath_symbolics-10.8.1a1.dist-info/WHEEL +6 -0
  6. passagemath_symbolics-10.8.1a1.dist-info/top_level.txt +3 -0
  7. sage/all__sagemath_symbolics.py +17 -0
  8. sage/calculus/all.py +14 -0
  9. sage/calculus/calculus.py +2838 -0
  10. sage/calculus/desolvers.py +1864 -0
  11. sage/calculus/predefined.py +51 -0
  12. sage/calculus/tests.py +225 -0
  13. sage/calculus/var.cpython-311-darwin.so +0 -0
  14. sage/calculus/var.pyx +401 -0
  15. sage/dynamics/all__sagemath_symbolics.py +6 -0
  16. sage/dynamics/complex_dynamics/all.py +5 -0
  17. sage/dynamics/complex_dynamics/mandel_julia.py +765 -0
  18. sage/dynamics/complex_dynamics/mandel_julia_helper.cpython-311-darwin.so +0 -0
  19. sage/dynamics/complex_dynamics/mandel_julia_helper.pyx +1034 -0
  20. sage/ext/all__sagemath_symbolics.py +1 -0
  21. sage/ext_data/kenzo/CP2.txt +45 -0
  22. sage/ext_data/kenzo/CP3.txt +349 -0
  23. sage/ext_data/kenzo/CP4.txt +4774 -0
  24. sage/ext_data/kenzo/README.txt +49 -0
  25. sage/ext_data/kenzo/S4.txt +20 -0
  26. sage/ext_data/magma/latex/latex.m +1021 -0
  27. sage/ext_data/magma/latex/latex.spec +1 -0
  28. sage/ext_data/magma/sage/basic.m +356 -0
  29. sage/ext_data/magma/sage/sage.spec +1 -0
  30. sage/ext_data/magma/spec +9 -0
  31. sage/geometry/all__sagemath_symbolics.py +8 -0
  32. sage/geometry/hyperbolic_space/all.py +5 -0
  33. sage/geometry/hyperbolic_space/hyperbolic_coercion.py +755 -0
  34. sage/geometry/hyperbolic_space/hyperbolic_constants.py +5 -0
  35. sage/geometry/hyperbolic_space/hyperbolic_geodesic.py +2419 -0
  36. sage/geometry/hyperbolic_space/hyperbolic_interface.py +206 -0
  37. sage/geometry/hyperbolic_space/hyperbolic_isometry.py +1083 -0
  38. sage/geometry/hyperbolic_space/hyperbolic_model.py +1502 -0
  39. sage/geometry/hyperbolic_space/hyperbolic_point.py +621 -0
  40. sage/geometry/riemannian_manifolds/all.py +7 -0
  41. sage/geometry/riemannian_manifolds/parametrized_surface3d.py +1632 -0
  42. sage/geometry/riemannian_manifolds/surface3d_generators.py +461 -0
  43. sage/interfaces/all__sagemath_symbolics.py +1 -0
  44. sage/interfaces/magma.py +2991 -0
  45. sage/interfaces/magma_free.py +90 -0
  46. sage/interfaces/maple.py +1402 -0
  47. sage/interfaces/mathematica.py +1345 -0
  48. sage/interfaces/mathics.py +1312 -0
  49. sage/interfaces/sympy.py +1398 -0
  50. sage/interfaces/sympy_wrapper.py +197 -0
  51. sage/interfaces/tides.py +938 -0
  52. sage/libs/all__sagemath_symbolics.py +6 -0
  53. sage/manifolds/all.py +7 -0
  54. sage/manifolds/calculus_method.py +553 -0
  55. sage/manifolds/catalog.py +437 -0
  56. sage/manifolds/chart.py +4010 -0
  57. sage/manifolds/chart_func.py +3416 -0
  58. sage/manifolds/continuous_map.py +2183 -0
  59. sage/manifolds/continuous_map_image.py +155 -0
  60. sage/manifolds/differentiable/affine_connection.py +2475 -0
  61. sage/manifolds/differentiable/all.py +1 -0
  62. sage/manifolds/differentiable/automorphismfield.py +1383 -0
  63. sage/manifolds/differentiable/automorphismfield_group.py +604 -0
  64. sage/manifolds/differentiable/bundle_connection.py +1445 -0
  65. sage/manifolds/differentiable/characteristic_cohomology_class.py +1840 -0
  66. sage/manifolds/differentiable/chart.py +1241 -0
  67. sage/manifolds/differentiable/curve.py +1028 -0
  68. sage/manifolds/differentiable/de_rham_cohomology.py +541 -0
  69. sage/manifolds/differentiable/degenerate.py +559 -0
  70. sage/manifolds/differentiable/degenerate_submanifold.py +1668 -0
  71. sage/manifolds/differentiable/diff_form.py +1660 -0
  72. sage/manifolds/differentiable/diff_form_module.py +1062 -0
  73. sage/manifolds/differentiable/diff_map.py +1315 -0
  74. sage/manifolds/differentiable/differentiable_submanifold.py +291 -0
  75. sage/manifolds/differentiable/examples/all.py +1 -0
  76. sage/manifolds/differentiable/examples/euclidean.py +2517 -0
  77. sage/manifolds/differentiable/examples/real_line.py +897 -0
  78. sage/manifolds/differentiable/examples/sphere.py +1186 -0
  79. sage/manifolds/differentiable/examples/symplectic_space.py +187 -0
  80. sage/manifolds/differentiable/examples/symplectic_space_test.py +40 -0
  81. sage/manifolds/differentiable/integrated_curve.py +4035 -0
  82. sage/manifolds/differentiable/levi_civita_connection.py +841 -0
  83. sage/manifolds/differentiable/manifold.py +4254 -0
  84. sage/manifolds/differentiable/manifold_homset.py +1826 -0
  85. sage/manifolds/differentiable/metric.py +3032 -0
  86. sage/manifolds/differentiable/mixed_form.py +1507 -0
  87. sage/manifolds/differentiable/mixed_form_algebra.py +559 -0
  88. sage/manifolds/differentiable/multivector_module.py +800 -0
  89. sage/manifolds/differentiable/multivectorfield.py +1522 -0
  90. sage/manifolds/differentiable/poisson_tensor.py +268 -0
  91. sage/manifolds/differentiable/pseudo_riemannian.py +755 -0
  92. sage/manifolds/differentiable/pseudo_riemannian_submanifold.py +1839 -0
  93. sage/manifolds/differentiable/scalarfield.py +1343 -0
  94. sage/manifolds/differentiable/scalarfield_algebra.py +472 -0
  95. sage/manifolds/differentiable/symplectic_form.py +912 -0
  96. sage/manifolds/differentiable/symplectic_form_test.py +220 -0
  97. sage/manifolds/differentiable/tangent_space.py +412 -0
  98. sage/manifolds/differentiable/tangent_vector.py +616 -0
  99. sage/manifolds/differentiable/tensorfield.py +4665 -0
  100. sage/manifolds/differentiable/tensorfield_module.py +963 -0
  101. sage/manifolds/differentiable/tensorfield_paral.py +2450 -0
  102. sage/manifolds/differentiable/tensorfield_paral_test.py +16 -0
  103. sage/manifolds/differentiable/vector_bundle.py +1725 -0
  104. sage/manifolds/differentiable/vectorfield.py +1717 -0
  105. sage/manifolds/differentiable/vectorfield_module.py +2445 -0
  106. sage/manifolds/differentiable/vectorframe.py +1832 -0
  107. sage/manifolds/family.py +270 -0
  108. sage/manifolds/local_frame.py +1490 -0
  109. sage/manifolds/manifold.py +3090 -0
  110. sage/manifolds/manifold_homset.py +452 -0
  111. sage/manifolds/operators.py +359 -0
  112. sage/manifolds/point.py +994 -0
  113. sage/manifolds/scalarfield.py +3718 -0
  114. sage/manifolds/scalarfield_algebra.py +629 -0
  115. sage/manifolds/section.py +3111 -0
  116. sage/manifolds/section_module.py +831 -0
  117. sage/manifolds/structure.py +229 -0
  118. sage/manifolds/subset.py +2721 -0
  119. sage/manifolds/subsets/all.py +1 -0
  120. sage/manifolds/subsets/closure.py +131 -0
  121. sage/manifolds/subsets/pullback.py +883 -0
  122. sage/manifolds/topological_submanifold.py +891 -0
  123. sage/manifolds/trivialization.py +733 -0
  124. sage/manifolds/utilities.py +1348 -0
  125. sage/manifolds/vector_bundle.py +1347 -0
  126. sage/manifolds/vector_bundle_fiber.py +332 -0
  127. sage/manifolds/vector_bundle_fiber_element.py +111 -0
  128. sage/matrix/all__sagemath_symbolics.py +1 -0
  129. sage/matrix/matrix_symbolic_dense.cpython-311-darwin.so +0 -0
  130. sage/matrix/matrix_symbolic_dense.pxd +6 -0
  131. sage/matrix/matrix_symbolic_dense.pyx +1030 -0
  132. sage/matrix/matrix_symbolic_sparse.cpython-311-darwin.so +0 -0
  133. sage/matrix/matrix_symbolic_sparse.pxd +6 -0
  134. sage/matrix/matrix_symbolic_sparse.pyx +1038 -0
  135. sage/modules/all__sagemath_symbolics.py +1 -0
  136. sage/modules/vector_callable_symbolic_dense.py +105 -0
  137. sage/modules/vector_symbolic_dense.py +116 -0
  138. sage/modules/vector_symbolic_sparse.py +118 -0
  139. sage/rings/all__sagemath_symbolics.py +4 -0
  140. sage/rings/asymptotic/all.py +6 -0
  141. sage/rings/asymptotic/asymptotic_expansion_generators.py +1485 -0
  142. sage/rings/asymptotic/asymptotic_ring.py +4858 -0
  143. sage/rings/asymptotic/asymptotics_multivariate_generating_functions.py +4106 -0
  144. sage/rings/asymptotic/growth_group.py +5373 -0
  145. sage/rings/asymptotic/growth_group_cartesian.py +1400 -0
  146. sage/rings/asymptotic/term_monoid.py +5205 -0
  147. sage/rings/function_field/all__sagemath_symbolics.py +2 -0
  148. sage/rings/polynomial/all__sagemath_symbolics.py +1 -0
  149. sage/symbolic/all.py +15 -0
  150. sage/symbolic/assumptions.py +987 -0
  151. sage/symbolic/benchmark.py +93 -0
  152. sage/symbolic/callable.py +456 -0
  153. sage/symbolic/callable.pyi +66 -0
  154. sage/symbolic/comparison_impl.pyi +38 -0
  155. sage/symbolic/complexity_measures.py +35 -0
  156. sage/symbolic/constants.py +1286 -0
  157. sage/symbolic/constants_c_impl.pyi +10 -0
  158. sage/symbolic/expression_conversion_algebraic.py +310 -0
  159. sage/symbolic/expression_conversion_sympy.py +317 -0
  160. sage/symbolic/expression_conversions.py +1727 -0
  161. sage/symbolic/function_factory.py +355 -0
  162. sage/symbolic/function_factory.pyi +41 -0
  163. sage/symbolic/getitem_impl.pyi +24 -0
  164. sage/symbolic/integration/all.py +1 -0
  165. sage/symbolic/integration/external.py +271 -0
  166. sage/symbolic/integration/integral.py +1075 -0
  167. sage/symbolic/maxima_wrapper.py +162 -0
  168. sage/symbolic/operators.py +267 -0
  169. sage/symbolic/operators.pyi +61 -0
  170. sage/symbolic/pynac_constant_impl.pyi +13 -0
  171. sage/symbolic/pynac_function_impl.pyi +8 -0
  172. sage/symbolic/random_tests.py +461 -0
  173. sage/symbolic/relation.py +2062 -0
  174. sage/symbolic/ring.cpython-311-darwin.so +0 -0
  175. sage/symbolic/ring.pxd +5 -0
  176. sage/symbolic/ring.pyi +110 -0
  177. sage/symbolic/ring.pyx +1393 -0
  178. sage/symbolic/series_impl.pyi +10 -0
  179. sage/symbolic/subring.py +1025 -0
  180. sage/symbolic/symengine.py +19 -0
  181. sage/symbolic/tests.py +40 -0
  182. sage/symbolic/units.py +1468 -0
@@ -0,0 +1,1725 @@
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.rings.cc import CC
36
+ from sage.rings.infinity import infinity
37
+ from sage.rings.rational_field import QQ
38
+ from sage.rings.real_mpfr import RR
39
+
40
+
41
+ class DifferentiableVectorBundle(TopologicalVectorBundle):
42
+ r"""
43
+ An instance of this class represents a differentiable vector bundle
44
+ `E \to M`
45
+
46
+ INPUT:
47
+
48
+ - ``rank`` -- positive integer; rank of the vector bundle
49
+ - ``name`` -- string representation given to the total space
50
+ - ``base_space`` -- the base space (differentiable manifold) `M` over which
51
+ the vector bundle is defined
52
+ - ``field`` -- field `K` which gives the fibers the structure of a
53
+ vector space over `K`; allowed values are
54
+
55
+ - ``'real'`` or an object of type ``RealField`` (e.g., ``RR``) for
56
+ a vector bundle over `\RR`
57
+ - ``'complex'`` or an object of type ``ComplexField`` (e.g., ``CC``)
58
+ for a vector bundle over `\CC`
59
+ - an object in the category of topological fields (see
60
+ :class:`~sage.categories.fields.Fields` and
61
+ :class:`~sage.categories.topological_spaces.TopologicalSpaces`)
62
+ for other types of topological fields
63
+
64
+ - ``latex_name`` -- (default: ``None``) LaTeX representation given to the
65
+ total space
66
+ - ``category`` -- (default: ``None``) to specify the category; if
67
+ ``None``, ``VectorBundles(base_space, c_field).Differentiable()`` is
68
+ assumed (see the category
69
+ :class:`~sage.categories.vector_bundles.VectorBundles`)
70
+
71
+ EXAMPLES:
72
+
73
+ A differentiable vector bundle of rank 2 over a 3-dimensional
74
+ differentiable manifold::
75
+
76
+ sage: M = Manifold(3, 'M')
77
+ sage: E = M.vector_bundle(2, 'E', field='complex'); E
78
+ Differentiable complex vector bundle E -> M of rank 2 over the base
79
+ space 3-dimensional differentiable manifold M
80
+ sage: E.category()
81
+ Category of smooth vector bundles over Complex Field with 53 bits of
82
+ precision with base space 3-dimensional differentiable manifold M
83
+
84
+ At this stage, the differentiable vector bundle has the same
85
+ differentiability degree as the base manifold::
86
+
87
+ sage: M.diff_degree() == E.diff_degree()
88
+ True
89
+ """
90
+ def __init__(self, rank, name, base_space, field='real', latex_name=None,
91
+ category=None, unique_tag=None) -> None:
92
+ r"""
93
+ Construct a differentiable vector bundle.
94
+
95
+ TESTS::
96
+
97
+ sage: M = Manifold(2, 'M')
98
+ sage: from sage.manifolds.differentiable.vector_bundle import DifferentiableVectorBundle
99
+ sage: DifferentiableVectorBundle(2, 'E', M)
100
+ Differentiable real vector bundle E -> M of rank 2 over the base
101
+ space 2-dimensional differentiable manifold M
102
+ """
103
+ diff_degree = base_space._diff_degree
104
+ if category is None:
105
+ if field == 'real':
106
+ field_c = RR
107
+ elif field == 'complex':
108
+ field_c = CC
109
+ else:
110
+ field_c = field
111
+ if diff_degree == infinity:
112
+ category = VectorBundles(base_space, field_c).Smooth()
113
+ else:
114
+ category = VectorBundles(base_space, field_c).Differentiable()
115
+ TopologicalVectorBundle.__init__(self, rank, name, base_space,
116
+ field=field,
117
+ latex_name=latex_name,
118
+ category=category)
119
+ self._diff_degree = diff_degree # Override diff degree
120
+
121
+ def _repr_(self) -> str:
122
+ r"""
123
+ String representation of ``self``.
124
+
125
+ TESTS::
126
+
127
+ sage: M = Manifold(2, 'M')
128
+ sage: E = M.vector_bundle(1, 'E')
129
+ sage: E._repr_()
130
+ 'Differentiable real vector bundle E -> M of rank 1 over the base
131
+ space 2-dimensional differentiable manifold M'
132
+ """
133
+ desc = "Differentiable "
134
+ return desc + TopologicalVectorBundle._repr_object_name(self)
135
+
136
+ def bundle_connection(self, name, latex_name=None):
137
+ r"""
138
+ Return a bundle connection on ``self``.
139
+
140
+ OUTPUT:
141
+
142
+ - a bundle connection on ``self`` as an instance of
143
+ :class:`~sage.manifolds.differentiable.bundle_connection.BundleConnection`
144
+
145
+ EXAMPLES::
146
+
147
+ sage: M = Manifold(3, 'M', start_index=1)
148
+ sage: X.<x,y,z> = M.chart()
149
+ sage: E = M.vector_bundle(2, 'E')
150
+ sage: e = E.local_frame('e') # standard frame for E
151
+ sage: nab = E.bundle_connection('nabla', latex_name=r'\nabla'); nab
152
+ Bundle connection nabla on the Differentiable real vector bundle
153
+ E -> M of rank 2 over the base space 3-dimensional differentiable
154
+ manifold M
155
+
156
+ .. SEEALSO::
157
+
158
+ Further examples can be found in
159
+ :class:`~sage.manifolds.differentiable.bundle_connection.BundleConnection`.
160
+ """
161
+ from sage.manifolds.differentiable.bundle_connection import BundleConnection
162
+ return BundleConnection(self, name, latex_name)
163
+
164
+ def characteristic_cohomology_class_ring(self, base=QQ):
165
+ r"""
166
+ Return the characteristic cohomology class ring of ``self`` over
167
+ a given base.
168
+
169
+ INPUT:
170
+
171
+ - ``base`` -- (default: ``QQ``) base over which the ring should be
172
+ constructed; typically that would be `\ZZ`, `\QQ`, `\RR` or the
173
+ symbolic ring
174
+
175
+ EXAMPLES::
176
+
177
+ sage: M = Manifold(4, 'M', start_index=1)
178
+ sage: R = M.tangent_bundle().characteristic_cohomology_class_ring()
179
+ sage: R
180
+ Algebra of characteristic cohomology classes of the Tangent bundle
181
+ TM over the 4-dimensional differentiable manifold M
182
+ sage: p1 = R.gen(0); p1
183
+ Characteristic cohomology class (p_1)(TM) of the Tangent bundle TM
184
+ over the 4-dimensional differentiable manifold M
185
+ sage: 1 + p1
186
+ Characteristic cohomology class (1 + p_1)(TM) of the Tangent bundle
187
+ TM over the 4-dimensional differentiable manifold M
188
+ """
189
+ from sage.manifolds.differentiable.characteristic_cohomology_class import (
190
+ CharacteristicCohomologyClassRing,
191
+ )
192
+
193
+ return CharacteristicCohomologyClassRing(base, self)
194
+
195
+ def characteristic_cohomology_class(self, *args, **kwargs):
196
+ r"""
197
+ Return a characteristic cohomology class associated with the input
198
+ data.
199
+
200
+ INPUT:
201
+
202
+ - ``val`` -- the input data associated with the characteristic class
203
+ using the Chern-Weil homomorphism; this argument can be either a
204
+ symbolic expression, a polynomial or one of the following predefined
205
+ classes:
206
+
207
+ - ``'Chern'`` -- total Chern class,
208
+ - ``'ChernChar'`` -- Chern character,
209
+ - ``'Todd'`` -- Todd class,
210
+ - ``'Pontryagin'`` -- total Pontryagin class,
211
+ - ``'Hirzebruch'`` -- Hirzebruch class,
212
+ - ``'AHat'`` -- `\hat{A}` class,
213
+ - ``'Euler'`` -- Euler class.
214
+
215
+ - ``base_ring`` -- (default: ``QQ``) base ring over which the
216
+ characteristic cohomology class ring shall be defined
217
+ - ``name`` -- (default: ``None``) string representation given to the
218
+ characteristic cohomology class; if ``None`` the default algebra
219
+ representation or predefined name is used
220
+ - ``latex_name`` -- (default: ``None``) LaTeX name given to the
221
+ characteristic class; if ``None`` the value of ``name`` is used
222
+ - ``class_type`` -- (default: ``None``) class type of the characteristic
223
+ cohomology class; the following options are possible:
224
+
225
+ - ``'multiplicative'`` -- returns a class of multiplicative type
226
+ - ``'additive'`` -- returns a class of additive type
227
+ - ``'Pfaffian'`` -- returns a class of Pfaffian type
228
+
229
+ This argument must be stated if ``val`` is a polynomial or symbolic
230
+ expression.
231
+
232
+ EXAMPLES:
233
+
234
+ Pontryagin class on the Minkowski space::
235
+
236
+ sage: M = Manifold(4, 'M', structure='Lorentzian', start_index=1)
237
+ sage: X.<t,x,y,z> = M.chart()
238
+ sage: g = M.metric()
239
+ sage: g[1,1] = -1
240
+ sage: g[2,2] = 1
241
+ sage: g[3,3] = 1
242
+ sage: g[4,4] = 1
243
+ sage: g.display()
244
+ g = -dt⊗dt + dx⊗dx + dy⊗dy + dz⊗dz
245
+
246
+ Let us introduce the corresponding Levi-Civita connection::
247
+
248
+ sage: nab = g.connection(); nab
249
+ Levi-Civita connection nabla_g associated with the Lorentzian
250
+ metric g on the 4-dimensional Lorentzian manifold M
251
+ sage: nab.set_immutable() # make nab immutable
252
+
253
+ Of course, `\nabla_g` is flat::
254
+
255
+ sage: nab.display()
256
+
257
+ Let us check the total Pontryagin class which must be the one
258
+ element in the corresponding cohomology ring in this case::
259
+
260
+ sage: # needs sage.combinat
261
+ sage: TM = M.tangent_bundle(); TM
262
+ Tangent bundle TM over the 4-dimensional Lorentzian manifold M
263
+ sage: p = TM.characteristic_cohomology_class('Pontryagin'); p
264
+ Characteristic cohomology class p(TM) of the Tangent bundle TM over
265
+ the 4-dimensional Lorentzian manifold M
266
+ sage: p_form = p.get_form(nab); p_form.display_expansion()
267
+ p(TM, nabla_g) = 1
268
+
269
+ .. SEEALSO::
270
+
271
+ More examples can be found in
272
+ :class:`~sage.manifolds.differentiable.characteristic_class.CharacteristicClass`.
273
+ """
274
+ base_ring = kwargs.get('base_ring', QQ)
275
+ R = self.characteristic_cohomology_class_ring(base_ring)
276
+ return R(*args, **kwargs)
277
+
278
+ def diff_degree(self):
279
+ r"""
280
+ Return the vector bundle's degree of differentiability.
281
+
282
+ The degree of differentiability is the integer `k` (possibly
283
+ `k=\infty`) such that the vector bundle is of class `C^k` over
284
+ its base field. The degree always corresponds to the degree of
285
+ differentiability of it's base space.
286
+
287
+ EXAMPLES::
288
+
289
+ sage: M = Manifold(2, 'M')
290
+ sage: E = M.vector_bundle(2, 'E')
291
+ sage: E.diff_degree()
292
+ +Infinity
293
+ sage: M = Manifold(2, 'M', structure='differentiable',
294
+ ....: diff_degree=3)
295
+ sage: E = M.vector_bundle(2, 'E')
296
+ sage: E.diff_degree()
297
+ 3
298
+ """
299
+ return self._diff_degree
300
+
301
+ def total_space(self):
302
+ r"""
303
+ Return the total space of ``self``.
304
+
305
+ .. NOTE::
306
+
307
+ At this stage, the total space does not come with induced charts.
308
+
309
+ OUTPUT:
310
+
311
+ - the total space of ``self`` as an instance of
312
+ :class:`~sage.manifolds.differentiable.manifold.DifferentiableManifold`
313
+
314
+ EXAMPLES::
315
+
316
+ sage: M = Manifold(3, 'M')
317
+ sage: E = M.vector_bundle(2, 'E')
318
+ sage: E.total_space()
319
+ 5-dimensional differentiable manifold E
320
+ """
321
+ if self._total_space is None:
322
+ from sage.manifolds.manifold import Manifold
323
+ base_space = self._base_space
324
+ dim = base_space._dim + self._rank
325
+ sindex = base_space.start_index()
326
+ self._total_space = Manifold(
327
+ dim, self._name,
328
+ latex_name=self._latex_name,
329
+ field=self._field, structure='differentiable',
330
+ diff_degree=self._diff_degree,
331
+ start_index=sindex
332
+ )
333
+
334
+ # TODO: if update_atlas: introduce charts via self._atlas
335
+
336
+ return self._total_space
337
+
338
+ # *****************************************************************************
339
+
340
+
341
+ class TensorBundle(DifferentiableVectorBundle):
342
+ r"""
343
+ Tensor bundle over a differentiable manifold along a differentiable map.
344
+
345
+ An instance of this class represents the pullback tensor bundle
346
+ `\Phi^* T^{(k,l)}N` along a differentiable map (called *destination map*)
347
+
348
+ .. MATH::
349
+
350
+ \Phi: M \longrightarrow N
351
+
352
+ between two differentiable manifolds `M` and `N` over the topological field
353
+ `K`.
354
+
355
+ More precisely, `\Phi^* T^{(k,l)}N` consists of all pairs
356
+ `(p,t) \in M \times T^{(k,l)}N` such that `t \in T_q^{(k,l)}N` for
357
+ `q = \Phi(p)`, namely
358
+
359
+ .. MATH::
360
+
361
+ t:\ \underbrace{T_q^*N\times\cdots\times T_q^*N}_{k\ \; \text{times}}
362
+ \times \underbrace{T_q N\times\cdots\times T_q N}_{l\ \; \text{times}}
363
+ \longrightarrow K
364
+
365
+ (`k` is called the *contravariant* and `l` the *covariant* rank of the
366
+ tensor bundle).
367
+
368
+ The trivializations are directly given by charts on the codomain (called
369
+ *ambient domain*) of `\Phi`.
370
+ In particular, let `(V, \varphi)` be a chart of `N` with components
371
+ `(x^1, \dots, x^n)` such that `q=\Phi(p) \in V`. Then, the matrix entries
372
+ of `t \in T_q^{(k,l)}N` are given by
373
+
374
+ .. MATH::
375
+
376
+ t^{a_1 \ldots a_k}_{\phantom{a_1 \ldots a_k} \, b_1 \ldots b_l} =
377
+ t \left( \left.\frac{\partial}{\partial x^{a_1}}\right|_q, \dots,
378
+ \left.\frac{\partial}{\partial x^{a_k}}\right|_q,
379
+ \left.\mathrm{d}x^{b_1}\right|_q, \dots,
380
+ \left.\mathrm{d}x^{b_l}\right|_q \right) \in K
381
+
382
+ and a trivialization over `U=\Phi^{-1}(V) \subset M` is obtained via
383
+
384
+ .. MATH::
385
+
386
+ (p,t) \mapsto \left(p, t^{1 \ldots 1}_{\phantom{1 \ldots 1} \, 1 \ldots 1},
387
+ \dots, t^{n \ldots n}_{\phantom{n \ldots n} \, n \ldots n} \right)
388
+ \in U \times K^{n^{(k+l)}}.
389
+
390
+ The standard case of a tensor bundle over a differentiable manifold
391
+ corresponds to `M=N` and `\Phi = \mathrm{Id}_M`. Other common cases are
392
+ `\Phi` being an immersion and `\Phi` being a curve in `N` (`M` is then an
393
+ open interval of `\RR`).
394
+
395
+ INPUT:
396
+
397
+ - ``base_space`` -- the base space (differentiable manifold) `M` over which
398
+ the tensor bundle is defined
399
+ - ``k`` -- the contravariant rank of the corresponding tensor bundle
400
+ - ``l`` -- the covariant rank of the corresponding tensor bundle
401
+ - ``dest_map`` -- (default: ``None``) destination map
402
+ `\Phi:\ M \rightarrow N`
403
+ (type: :class:`~sage.manifolds.differentiable.diff_map.DiffMap`); if
404
+ ``None``, it is assumed that `M=M` and `\Phi` is the identity map of
405
+ `M` (case of the standard tensor bundle over `M`)
406
+
407
+ EXAMPLES:
408
+
409
+ Pullback tangent bundle of `R^2` along a curve `\Phi`::
410
+
411
+ sage: M = Manifold(2, 'M')
412
+ sage: c_cart.<x,y> = M.chart()
413
+ sage: R = Manifold(1, 'R')
414
+ sage: T.<t> = R.chart() # canonical chart on R
415
+ sage: Phi = R.diff_map(M, [cos(t), sin(t)], name='Phi') ; Phi
416
+ Differentiable map Phi from the 1-dimensional differentiable manifold R
417
+ to the 2-dimensional differentiable manifold M
418
+ sage: Phi.display()
419
+ Phi: R → M
420
+ t ↦ (x, y) = (cos(t), sin(t))
421
+ sage: PhiTM = R.tangent_bundle(dest_map=Phi); PhiTM
422
+ Tangent bundle Phi^*TM over the 1-dimensional differentiable manifold R
423
+ along the Differentiable map Phi from the 1-dimensional differentiable
424
+ manifold R to the 2-dimensional differentiable manifold M
425
+
426
+ The section module is the corresponding tensor field module::
427
+
428
+ sage: R_tensor_module = R.tensor_field_module((1,0), dest_map=Phi)
429
+ sage: R_tensor_module is PhiTM.section_module()
430
+ True
431
+ """
432
+ def __init__(self, base_space, k, l, dest_map=None) -> None:
433
+ r"""
434
+ Construct a tensor bundle.
435
+
436
+ TESTS::
437
+
438
+ sage: M = Manifold(2, 'M')
439
+ sage: N = Manifold(2, 'N')
440
+ sage: Phi = M.diff_map(N, name='Phi')
441
+ sage: from sage.manifolds.differentiable.vector_bundle import TensorBundle
442
+ sage: TensorBundle(M, 1, 2, dest_map=Phi)
443
+ Tensor bundle Phi^*T^(1,2)N over the 2-dimensional differentiable
444
+ manifold M along the Differentiable map Phi from the 2-dimensional
445
+ differentiable manifold M to the 2-dimensional differentiable
446
+ manifold N
447
+ """
448
+ if dest_map is None:
449
+ self._dest_map = base_space.identity_map()
450
+ else:
451
+ self._dest_map = dest_map
452
+ self._ambient_domain = self._dest_map._codomain
453
+ self._tensor_type = (k, l)
454
+ # Set total space name:
455
+ if not self._dest_map.is_identity():
456
+ if self._dest_map._name is None:
457
+ name = "(unnamed map)^*"
458
+ else:
459
+ name = self._dest_map._name + "^*"
460
+ if self._dest_map._latex_name is None:
461
+ latex_name = r'\text{(unnamed map)}^* '
462
+ else:
463
+ latex_name = self._dest_map._latex_name + r'^* '
464
+ else:
465
+ name = ""
466
+ latex_name = ""
467
+ if self._tensor_type == (1, 0):
468
+ name += "T{}".format(self._ambient_domain._name)
469
+ latex_name += r'T{}'.format(self._ambient_domain._latex_name)
470
+ elif self._tensor_type == (0, 1):
471
+ name += "T*{}".format(self._ambient_domain._name)
472
+ latex_name += r'T^*{}'.format(self._ambient_domain._latex_name)
473
+ else:
474
+ name += "T^({},{}){}".format(k, l, self._ambient_domain._name)
475
+ latex_name += r'T^{(' + str(k) + r',' + str(l) + r')}' + \
476
+ self._ambient_domain._latex_name
477
+ # Initialize differentiable vector bundle:
478
+ rank = self._ambient_domain.dim() ** (k + l)
479
+ DifferentiableVectorBundle.__init__(self, rank, name, base_space,
480
+ field=base_space._field,
481
+ latex_name=latex_name)
482
+
483
+ def _init_derived(self):
484
+ r"""
485
+ Initialize the derived quantities.
486
+
487
+ TESTS::
488
+
489
+ sage: M = Manifold(2, 'M')
490
+ sage: TM = M.tangent_bundle()
491
+ sage: TM._init_derived()
492
+ """
493
+ self._def_frame = None
494
+
495
+ def _repr_(self) -> str:
496
+ r"""
497
+ String representation of ``self``.
498
+
499
+ TESTS::
500
+
501
+ sage: M = Manifold(2, 'M')
502
+ sage: TM = M.tangent_bundle()
503
+ sage: TM # indirect doctest
504
+ Tangent bundle TM over the 2-dimensional differentiable manifold M
505
+ sage: repr(TM) # indirect doctest
506
+ 'Tangent bundle TM over the 2-dimensional differentiable manifold M'
507
+ sage: TM._repr_()
508
+ 'Tangent bundle TM over the 2-dimensional differentiable manifold M'
509
+ sage: cTM = M.cotangent_bundle()
510
+ sage: cTM._repr_()
511
+ 'Cotangent bundle T*M over the 2-dimensional differentiable
512
+ manifold M'
513
+ sage: T12M = M.tensor_bundle(1, 2)
514
+ sage: T12M._repr_()
515
+ 'Tensor bundle T^(1,2)M over the 2-dimensional differentiable
516
+ manifold M'
517
+ """
518
+ if self._tensor_type == (1, 0):
519
+ desc = "Tangent bundle "
520
+ elif self._tensor_type == (0, 1):
521
+ desc = "Cotangent bundle "
522
+ else:
523
+ desc = "Tensor bundle "
524
+ desc += self._name + " over the {}".format(self._base_space)
525
+ if not self._dest_map.is_identity():
526
+ desc += " along the {}".format(self._dest_map)
527
+ return desc
528
+
529
+ def fiber(self, point):
530
+ r"""
531
+ Return the tensor bundle fiber over a point.
532
+
533
+ INPUT:
534
+
535
+ - ``point`` -- :class:`~sage.manifolds.point.ManifoldPoint`;
536
+ point `p` of the base manifold of ``self``
537
+
538
+ OUTPUT:
539
+
540
+ - an instance of :class:`~sage.tensor.modules.finite_rank_free_module.FiniteRankFreeModule`
541
+ representing the tensor bundle fiber over `p`
542
+
543
+ EXAMPLES::
544
+
545
+ sage: M = Manifold(3, 'M')
546
+ sage: X.<x,y,z> = M.chart()
547
+ sage: p = M((0,2,1), name='p'); p
548
+ Point p on the 3-dimensional differentiable manifold M
549
+ sage: TM = M.tangent_bundle(); TM
550
+ Tangent bundle TM over the 3-dimensional differentiable manifold M
551
+ sage: TM.fiber(p)
552
+ Tangent space at Point p on the 3-dimensional differentiable
553
+ manifold M
554
+ sage: TM.fiber(p) is M.tangent_space(p)
555
+ True
556
+
557
+ ::
558
+
559
+ sage: T11M = M.tensor_bundle(1,1); T11M
560
+ Tensor bundle T^(1,1)M over the 3-dimensional differentiable
561
+ manifold M
562
+ sage: T11M.fiber(p)
563
+ Free module of type-(1,1) tensors on the Tangent space at Point p
564
+ on the 3-dimensional differentiable manifold M
565
+ sage: T11M.fiber(p) is M.tangent_space(p).tensor_module(1,1)
566
+ True
567
+ """
568
+ amb_point = self._dest_map(point)
569
+ return self._ambient_domain.tangent_space(amb_point).tensor_module(*self._tensor_type)
570
+
571
+ def atlas(self):
572
+ r"""
573
+ Return the list of charts that have been defined on the codomain of the
574
+ destination map.
575
+
576
+ .. NOTE::
577
+
578
+ Since an atlas of charts gives rise to an atlas of trivializations,
579
+ this method directly invokes
580
+ :meth:`~sage.manifolds.manifold.TopologicalManifold.atlas`
581
+ of the class
582
+ :class:`~sage.manifolds.manifold.TopologicalManifold`.
583
+
584
+ EXAMPLES::
585
+
586
+ sage: M = Manifold(2, 'M')
587
+ sage: X.<x,y> = M.chart()
588
+ sage: Y.<u,v> = M.chart()
589
+ sage: TM = M.tangent_bundle()
590
+ sage: TM.atlas()
591
+ [Chart (M, (x, y)), Chart (M, (u, v))]
592
+ """
593
+ return self._base_space.atlas()
594
+
595
+ def section_module(self, domain=None):
596
+ r"""
597
+ Return the section module on ``domain``, namely the corresponding
598
+ tensor field module, of ``self`` on ``domain``.
599
+
600
+ .. NOTE::
601
+
602
+ This method directly invokes
603
+ :meth:`~sage.manifolds.differentiable.manifold.DifferentiableManifold.tensor_field_module`
604
+ of the class
605
+ :class:`~sage.manifolds.differentiable.manifold.DifferentiableManifold`.
606
+
607
+ INPUT:
608
+
609
+ - ``domain`` -- (default: ``None``) the domain of the corresponding
610
+ section module; if ``None``, the base space is assumed
611
+
612
+ OUTPUT:
613
+
614
+ - a
615
+ :class:`~sage.manifolds.differentiable.tensorfield_module.TensorFieldModule`
616
+ (or if `N` is parallelizable, a
617
+ :class:`~sage.manifolds.differentiable.tensorfield_module.TensorFieldFreeModule`)
618
+ representing the module `\mathcal{T}^{(k,l)}(U,\Phi)` of type-`(k,l)`
619
+ tensor fields on the domain `U \subset M` taking values on
620
+ `\Phi(U) \subset N`
621
+
622
+ EXAMPLES::
623
+
624
+ sage: M = Manifold(2, 'M')
625
+ sage: X.<x,y> = M.chart()
626
+ sage: U = M.open_subset('U')
627
+ sage: TM = M.tangent_bundle()
628
+ sage: TUM = TM.section_module(domain=U); TUM
629
+ Module X(U) of vector fields on the Open subset U of the
630
+ 2-dimensional differentiable manifold M
631
+ sage: TUM is U.tensor_field_module((1,0))
632
+ True
633
+ """
634
+ if domain is None:
635
+ base_space = self.base_space()
636
+ return base_space.tensor_field_module(self._tensor_type,
637
+ dest_map=self._dest_map)
638
+ return domain.tensor_field_module(
639
+ self._tensor_type,
640
+ dest_map=self._dest_map.restrict(domain)
641
+ )
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
+ return any(frame._domain is self._base_space for frame in self.frames())
1308
+
1309
+ def local_frame(self, *args, **kwargs):
1310
+ r"""
1311
+ Define a vector frame on ``domain``, possibly with values in the
1312
+ tangent bundle of the ambient domain.
1313
+
1314
+ If the basis specified by the given symbol already exists, it is
1315
+ simply returned.
1316
+ If no argument is provided the vector field module's default frame is
1317
+ returned.
1318
+
1319
+ Notice, that a vector frame automatically induces a local frame on the
1320
+ tensor bundle ``self``. More precisely, if `e: U \to \Phi^*TN` is a
1321
+ vector frame on `U \subset M` with values in `\Phi^*TN` along the
1322
+ destination map
1323
+
1324
+ .. MATH::
1325
+
1326
+ \Phi: M \longrightarrow N
1327
+
1328
+ then the map
1329
+
1330
+ .. MATH::
1331
+
1332
+ p \mapsto \Big(\underbrace{e^*(p), \dots, e^*(p)}_{k\ \; \text{times}},
1333
+ \underbrace{e(p), \dots, e(p)}_{l\ \; \text{times}}\Big) \in
1334
+ T^{(k,l)}_q N ,
1335
+
1336
+ with `q=\Phi(p)`, defines a basis at each point `p \in U` and
1337
+ therefore gives rise to a local frame on `\Phi^* T^{(k,l)}N` on the
1338
+ domain `U`.
1339
+
1340
+ .. SEEALSO::
1341
+
1342
+ :class:`~sage.manifolds.differentiable.vectorframe.VectorFrame`
1343
+ for complete documentation.
1344
+
1345
+ INPUT:
1346
+
1347
+ - ``symbol`` -- (default: ``None``) either a string, to be used as a
1348
+ common base for the symbols of the vector fields constituting the
1349
+ vector frame, or a list/tuple of strings, representing the individual
1350
+ symbols of the vector fields; can be ``None`` only if ``from_frame``
1351
+ is not ``None`` (see below)
1352
+ - ``vector_fields`` -- tuple or list of `n` linearly independent vector
1353
+ fields on ``domain`` (`n` being the dimension of ``domain``)
1354
+ defining the vector frame; can be omitted if the vector frame is
1355
+ created from scratch or if ``from_frame`` is not ``None``
1356
+ - ``latex_symbol`` -- (default: ``None``) either a string, to be used
1357
+ as a common base for the LaTeX symbols of the vector fields
1358
+ constituting the vector frame, or a list/tuple of strings,
1359
+ representing the individual LaTeX symbols of the vector fields;
1360
+ if ``None``, ``symbol`` is used in place of ``latex_symbol``
1361
+ - ``from_frame`` -- (default: ``None``) vector frame `\tilde{e}`
1362
+ on the codomain `N` of the destination map `\Phi`; the returned
1363
+ frame `e` is then such that for all `p \in U`,
1364
+ we have `e(p) = \tilde{e}(\Phi(p))`
1365
+ - ``indices`` -- (default: ``None``; used only if ``symbol`` is a
1366
+ single string) tuple of strings representing the indices labelling
1367
+ the vector fields of the frame; if ``None``, the indices will be
1368
+ generated as integers within the range declared on ``self``
1369
+ - ``latex_indices`` -- (default: ``None``) tuple of strings
1370
+ representing the indices for the LaTeX symbols of the vector fields;
1371
+ if ``None``, ``indices`` is used instead
1372
+ - ``symbol_dual`` -- (default: ``None``) same as ``symbol`` but for the
1373
+ dual coframe; if ``None``, ``symbol`` must be a string and is used
1374
+ for the common base of the symbols of the elements of the dual
1375
+ coframe
1376
+ - ``latex_symbol_dual`` -- (default: ``None``) same as ``latex_symbol``
1377
+ but for the dual coframe
1378
+ - ``domain`` -- (default: ``None``) domain on which the local frame is
1379
+ defined; if ``None`` is provided, the base space of ``self`` is
1380
+ assumed
1381
+
1382
+ OUTPUT:
1383
+
1384
+ - the vector frame corresponding to the above specifications; this is
1385
+ an instance of
1386
+ :class:`~sage.manifolds.differentiable.vectorframe.VectorFrame`.
1387
+
1388
+ EXAMPLES:
1389
+
1390
+ Defining a local frame for the tangent bundle of a 3-dimensional
1391
+ manifold::
1392
+
1393
+ sage: M = Manifold(3, 'M')
1394
+ sage: TM = M.tangent_bundle()
1395
+ sage: e = TM.local_frame('e'); e
1396
+ Vector frame (M, (e_0,e_1,e_2))
1397
+ sage: e[0]
1398
+ Vector field e_0 on the 3-dimensional differentiable manifold M
1399
+
1400
+ Specifying the domain of the vector frame::
1401
+
1402
+ sage: U = M.open_subset('U')
1403
+ sage: f = TM.local_frame('f', domain=U); f
1404
+ Vector frame (U, (f_0,f_1,f_2))
1405
+ sage: f[0]
1406
+ Vector field f_0 on the Open subset U of the 3-dimensional
1407
+ differentiable manifold M
1408
+
1409
+ .. SEEALSO::
1410
+
1411
+ For more options, in particular for the choice of symbols and
1412
+ indices, see
1413
+ :class:`~sage.manifolds.differentiable.vectorframe.VectorFrame`.
1414
+ """
1415
+ domain = kwargs.pop('domain', None)
1416
+ if domain is None:
1417
+ domain = self._base_space
1418
+ dest_map = self._dest_map.restrict(domain)
1419
+ if not args and not kwargs:
1420
+ # if no argument is provided, the default basis of the
1421
+ # base vector field module is returned:
1422
+ return domain.vector_field_module(dest_map=dest_map,
1423
+ force_free=True).basis()
1424
+ kwargs['dest_map'] = dest_map
1425
+ return domain.vector_frame(*args, **kwargs)
1426
+
1427
+ vector_frame = local_frame
1428
+
1429
+ def ambient_domain(self):
1430
+ r"""
1431
+ Return the codomain of the destination map.
1432
+
1433
+ OUTPUT:
1434
+
1435
+ - a :class:`~sage.manifolds.differentiable.manifold.DifferentiableManifold`
1436
+ representing the codomain of the destination map
1437
+
1438
+ EXAMPLES::
1439
+
1440
+ sage: M = Manifold(2, 'M')
1441
+ sage: c_cart.<x,y> = M.chart()
1442
+ sage: e_cart = c_cart.frame() # standard basis
1443
+ sage: R = Manifold(1, 'R')
1444
+ sage: T.<t> = R.chart() # canonical chart on R
1445
+ sage: Phi = R.diff_map(M, [cos(t), sin(t)], name='Phi') ; Phi
1446
+ Differentiable map Phi from the 1-dimensional differentiable
1447
+ manifold R to the 2-dimensional differentiable manifold M
1448
+ sage: Phi.display()
1449
+ Phi: R → M
1450
+ t ↦ (x, y) = (cos(t), sin(t))
1451
+ sage: PhiT11 = R.tensor_bundle(1, 1, dest_map=Phi)
1452
+ sage: PhiT11.ambient_domain()
1453
+ 2-dimensional differentiable manifold M
1454
+ """
1455
+ return self._ambient_domain
1456
+
1457
+ def destination_map(self):
1458
+ r"""
1459
+ Return the destination map.
1460
+
1461
+ OUTPUT:
1462
+
1463
+ - a :class:`~sage.manifolds.differentiable.diff_map.DifferentialMap`
1464
+ representing the destination map
1465
+
1466
+ EXAMPLES::
1467
+
1468
+ sage: M = Manifold(2, 'M')
1469
+ sage: c_cart.<x,y> = M.chart()
1470
+ sage: e_cart = c_cart.frame() # standard basis
1471
+ sage: R = Manifold(1, 'R')
1472
+ sage: T.<t> = R.chart() # canonical chart on R
1473
+ sage: Phi = R.diff_map(M, [cos(t), sin(t)], name='Phi') ; Phi
1474
+ Differentiable map Phi from the 1-dimensional differentiable
1475
+ manifold R to the 2-dimensional differentiable manifold M
1476
+ sage: Phi.display()
1477
+ Phi: R → M
1478
+ t ↦ (x, y) = (cos(t), sin(t))
1479
+ sage: PhiT11 = R.tensor_bundle(1, 1, dest_map=Phi)
1480
+ sage: PhiT11.destination_map()
1481
+ Differentiable map Phi from the 1-dimensional differentiable
1482
+ manifold R to the 2-dimensional differentiable manifold M
1483
+ """
1484
+ return self._dest_map
1485
+
1486
+ def default_frame(self):
1487
+ r"""
1488
+ Return the default vector frame defined on ``self``.
1489
+
1490
+ By *vector frame*, it is meant a field on the manifold that provides,
1491
+ at each point `p`, a vector basis of the pulled back tangent space at
1492
+ `p`.
1493
+
1494
+ If the destination map is the identity map, the default frame is the
1495
+ the first one defined on the manifold, usually the coordinate frame,
1496
+ unless it is changed via :meth:`set_default_frame`.
1497
+
1498
+ If the destination map is non-trivial, the default frame usually must
1499
+ be set via :meth:`set_default_frame`.
1500
+
1501
+ OUTPUT:
1502
+
1503
+ - a :class:`~sage.manifolds.differentiable.vectorframe.VectorFrame`
1504
+ representing the default vector frame
1505
+
1506
+ EXAMPLES:
1507
+
1508
+ The default vector frame is often the coordinate frame associated
1509
+ with the first chart defined on the manifold::
1510
+
1511
+ sage: M = Manifold(2, 'M')
1512
+ sage: c_xy.<x,y> = M.chart()
1513
+ sage: TM = M.tangent_bundle()
1514
+ sage: TM.default_frame()
1515
+ Coordinate frame (M, (∂/∂x,∂/∂y))
1516
+ """
1517
+ def_bframe = self._base_space.default_frame()
1518
+ if self._def_frame is None and def_bframe is not None:
1519
+ if def_bframe._dest_map == self._dest_map:
1520
+ self._def_frame = def_bframe
1521
+ return self._def_frame
1522
+
1523
+ def set_default_frame(self, frame):
1524
+ r"""
1525
+ Changing the default vector frame on ``self``.
1526
+
1527
+ .. NOTE::
1528
+
1529
+ If the destination map is the identity, the default frame of the
1530
+ base manifold gets changed here as well.
1531
+
1532
+ INPUT:
1533
+
1534
+ - ``frame`` --
1535
+ :class:`~sage.manifolds.differentiable.vectorframe.VectorFrame`
1536
+ a vector frame defined on the base manifold
1537
+
1538
+ EXAMPLES:
1539
+
1540
+ Changing the default frame on the tangent bundle of a 2-dimensional
1541
+ manifold::
1542
+
1543
+ sage: M = Manifold(2, 'M')
1544
+ sage: c_xy.<x,y> = M.chart()
1545
+ sage: TM = M.tangent_bundle()
1546
+ sage: e = TM.vector_frame('e')
1547
+ sage: TM.default_frame()
1548
+ Coordinate frame (M, (∂/∂x,∂/∂y))
1549
+ sage: TM.set_default_frame(e)
1550
+ sage: TM.default_frame()
1551
+ Vector frame (M, (e_0,e_1))
1552
+ sage: M.default_frame()
1553
+ Vector frame (M, (e_0,e_1))
1554
+ """
1555
+ from sage.manifolds.differentiable.vectorframe import VectorFrame
1556
+ if not isinstance(frame, VectorFrame):
1557
+ raise TypeError("{} is not a vector frame".format(frame))
1558
+ if (not frame._domain.is_subset(self._base_space) or
1559
+ frame._dest_map != self._dest_map):
1560
+ raise ValueError("the frame must be defined on " +
1561
+ "the {}".format(self))
1562
+ if self._dest_map.is_identity():
1563
+ self._base_space.set_default_frame(frame)
1564
+ else:
1565
+ frame._fmodule.set_default_basis(frame)
1566
+ self._def_frame = frame
1567
+
1568
+ def set_orientation(self, orientation):
1569
+ r"""
1570
+ Set the preferred orientation of ``self``.
1571
+
1572
+ INPUT:
1573
+
1574
+ - ``orientation`` -- a vector frame or a list of vector frames, covering
1575
+ the base space of ``self``
1576
+
1577
+ .. NOTE::
1578
+
1579
+ If the destination map is the identity, the preferred orientation
1580
+ of the base manifold gets changed here as well.
1581
+
1582
+ .. WARNING::
1583
+
1584
+ It is the user's responsibility that the orientation set here
1585
+ is indeed an orientation. There is no check going on in the
1586
+ background. See :meth:`orientation` for the definition of an
1587
+ orientation.
1588
+
1589
+ EXAMPLES:
1590
+
1591
+ Set an orientation on a tensor bundle::
1592
+
1593
+ sage: M = Manifold(2, 'M')
1594
+ sage: c_xy.<x,y> = M.chart()
1595
+ sage: T11 = M.tensor_bundle(1, 1)
1596
+ sage: e = T11.local_frame('e'); e
1597
+ Vector frame (M, (e_0,e_1))
1598
+ sage: T11.set_orientation(e)
1599
+ sage: T11.orientation()
1600
+ [Vector frame (M, (e_0,e_1))]
1601
+
1602
+ Set an orientation in the non-trivial case::
1603
+
1604
+ sage: M = Manifold(2, 'M')
1605
+ sage: U = M.open_subset('U'); V = M.open_subset('V')
1606
+ sage: M.declare_union(U, V)
1607
+ sage: c_xy.<x,y> = U.chart(); c_uv.<u,v> = V.chart()
1608
+ sage: T12 = M.tensor_bundle(1, 2)
1609
+ sage: e = T12.local_frame('e', domain=U)
1610
+ sage: f = T12.local_frame('f', domain=V)
1611
+ sage: T12.set_orientation([e, f])
1612
+ sage: T12.orientation()
1613
+ [Vector frame (U, (e_0,e_1)), Vector frame (V, (f_0,f_1))]
1614
+ """
1615
+ if self._dest_map.is_identity():
1616
+ base_space = self._base_space
1617
+ base_space.set_orientation(orientation)
1618
+ self._orientation = base_space._orientation
1619
+ else:
1620
+ super().set_orientation(orientation)
1621
+
1622
+ def orientation(self):
1623
+ r"""
1624
+ Get the preferred orientation of ``self`` if available.
1625
+
1626
+ See :meth:`~sage.manifolds.vector_bundle.TopologicalVectorBundle.orientation`
1627
+ for details regarding orientations on vector bundles.
1628
+
1629
+ The tensor bundle `\Phi^* T^{(k,l)}N` of a manifold is orientable if
1630
+ the manifold `\Phi(M)` is orientable. The converse does not
1631
+ necessarily hold true. The usual case corresponds to `\Phi`
1632
+ being the identity map, where the tensor bundle `T^{(k,l)}M` is
1633
+ orientable if and only if the manifold `M` is orientable.
1634
+
1635
+ .. NOTE::
1636
+
1637
+ Notice that the orientation of a general tensor bundle
1638
+ `\Phi^* T^{(k,l)}N` is canonically induced by the orientation of
1639
+ the tensor bundle `\Phi^* T^{(1,0)}N` as each local frame there
1640
+ induces the frames on `\Phi^* T^{(k,l)}N` in a canonical way.
1641
+
1642
+ If no preferred orientation has been set before, and if the ambient
1643
+ space already admits a preferred orientation, the corresponding
1644
+ orientation is returned and henceforth fixed for the tensor bundle.
1645
+
1646
+ EXAMPLES:
1647
+
1648
+ In the trivial case, i.e. if the destination map is the identity
1649
+ and the tangent bundle is covered by one frame, the orientation is
1650
+ easily obtained::
1651
+
1652
+ sage: M = Manifold(2, 'M')
1653
+ sage: c_xy.<x,y> = M.chart()
1654
+ sage: T11 = M.tensor_bundle(1, 1)
1655
+ sage: T11.orientation()
1656
+ [Coordinate frame (M, (∂/∂x,∂/∂y))]
1657
+
1658
+ The same holds true if the ambient domain admits a trivial
1659
+ orientation::
1660
+
1661
+ sage: M = Manifold(2, 'M')
1662
+ sage: c_xy.<x,y> = M.chart()
1663
+ sage: R = Manifold(1, 'R')
1664
+ sage: c_t.<t> = R.chart()
1665
+ sage: Phi = R.diff_map(M, name='Phi')
1666
+ sage: PhiT22 = R.tensor_bundle(2, 2, dest_map=Phi); PhiT22
1667
+ Tensor bundle Phi^*T^(2,2)M over the 1-dimensional differentiable
1668
+ manifold R along the Differentiable map Phi from the 1-dimensional
1669
+ differentiable manifold R to the 2-dimensional differentiable
1670
+ manifold M
1671
+ sage: PhiT22.local_frame() # initialize frame
1672
+ Vector frame (R, (∂/∂x,∂/∂y)) with values on the 2-dimensional
1673
+ differentiable manifold M
1674
+ sage: PhiT22.orientation()
1675
+ [Vector frame (R, (∂/∂x,∂/∂y)) with values on the 2-dimensional
1676
+ differentiable manifold M]
1677
+ sage: PhiT22.local_frame() is PhiT22.orientation()[0]
1678
+ True
1679
+
1680
+ In the non-trivial case, however, the orientation must be set
1681
+ manually by the user::
1682
+
1683
+ sage: M = Manifold(2, 'M')
1684
+ sage: U = M.open_subset('U'); V = M.open_subset('V')
1685
+ sage: M.declare_union(U, V)
1686
+ sage: c_xy.<x,y> = U.chart(); c_uv.<u,v> = V.chart()
1687
+ sage: T11 = M.tensor_bundle(1, 1); T11
1688
+ Tensor bundle T^(1,1)M over the 2-dimensional differentiable
1689
+ manifold M
1690
+ sage: T11.orientation()
1691
+ []
1692
+ sage: T11.set_orientation([c_xy.frame(), c_uv.frame()])
1693
+ sage: T11.orientation()
1694
+ [Coordinate frame (U, (∂/∂x,∂/∂y)),
1695
+ Coordinate frame (V, (∂/∂u,∂/∂v))]
1696
+
1697
+ If the destination map is the identity, the orientation is
1698
+ automatically set for the manifold, too::
1699
+
1700
+ sage: M.orientation()
1701
+ [Coordinate frame (U, (∂/∂x,∂/∂y)),
1702
+ Coordinate frame (V, (∂/∂u,∂/∂v))]
1703
+
1704
+ Conversely, if one sets an orientation on the manifold,
1705
+ the orientation on its tensor bundles is set accordingly::
1706
+
1707
+ sage: c_tz.<t,z> = U.chart()
1708
+ sage: M.set_orientation([c_tz, c_uv])
1709
+ sage: T11.orientation()
1710
+ [Coordinate frame (U, (∂/∂t,∂/∂z)),
1711
+ Coordinate frame (V, (∂/∂u,∂/∂v))]
1712
+ """
1713
+ if self._dest_map.is_identity():
1714
+ self._orientation = self._base_space.orientation()
1715
+ if not self._orientation:
1716
+ if not self._dest_map.is_identity():
1717
+ # try to get orientation from ambient space:
1718
+ ambient_domain = self._ambient_domain
1719
+ amb_orient = ambient_domain.orientation()
1720
+ if amb_orient:
1721
+ for frame in self.frames():
1722
+ from_frame = frame._from_frame
1723
+ if from_frame in amb_orient:
1724
+ self._orientation.append(frame)
1725
+ return list(self._orientation)