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,1832 @@
1
+ # sage_setup: distribution = sagemath-symbolics
2
+ r"""
3
+ Vector Frames
4
+
5
+ The class :class:`VectorFrame` implements vector frames on differentiable
6
+ manifolds.
7
+ By *vector frame*, it is meant a field `e` on some
8
+ differentiable manifold `U` endowed with a differentiable map
9
+ `\Phi: U \rightarrow M` to a differentiable manifold `M` such that for each
10
+ `p\in U`, `e(p)` is a vector basis of the tangent space `T_{\Phi(p)}M`.
11
+
12
+ The standard case of a vector frame *on* `U` corresponds to `U = M`
13
+ and `\Phi = \mathrm{Id}_M`. Other common cases are `\Phi` being an
14
+ immersion and `\Phi` being a curve in `M` (`U` is then an open
15
+ interval of `\RR`).
16
+
17
+ A derived class of :class:`VectorFrame` is :class:`CoordFrame`;
18
+ it regards the vector frames associated with a chart, i.e. the
19
+ so-called *coordinate bases*.
20
+
21
+ The vector frame duals, i.e. the coframes, are implemented via the class
22
+ :class:`CoFrame`. The derived class :class:`CoordCoFrame` is devoted to
23
+ coframes deriving from a chart.
24
+
25
+ AUTHORS:
26
+
27
+ - Eric Gourgoulhon, Michal Bejger (2013-2015): initial version
28
+ - Travis Scrimshaw (2016): review tweaks
29
+ - Eric Gourgoulhon (2018): some refactoring and more functionalities in the
30
+ choice of symbols for vector frame elements (:issue:`24792`)
31
+
32
+ REFERENCES:
33
+
34
+ - [Lee2013]_
35
+
36
+ EXAMPLES:
37
+
38
+ Introducing a chart on a manifold automatically endows it with a vector frame:
39
+ the coordinate frame associated to the chart::
40
+
41
+ sage: M = Manifold(3, 'M')
42
+ sage: X.<x,y,z> = M.chart()
43
+ sage: M.frames()
44
+ [Coordinate frame (M, (∂/∂x,∂/∂y,∂/∂z))]
45
+ sage: M.frames()[0] is X.frame()
46
+ True
47
+
48
+ A new vector frame can be defined from a family of 3 linearly independent
49
+ vector fields::
50
+
51
+ sage: e1 = M.vector_field(1, x, y)
52
+ sage: e2 = M.vector_field(z, -2, x*y)
53
+ sage: e3 = M.vector_field(1, 1, 0)
54
+ sage: e = M.vector_frame('e', (e1, e2, e3)); e
55
+ Vector frame (M, (e_0,e_1,e_2))
56
+ sage: latex(e)
57
+ \left(M, \left(e_{0},e_{1},e_{2}\right)\right)
58
+
59
+ The first frame defined on a manifold is its *default frame*; in the present
60
+ case it is the coordinate frame associated to the chart ``X``::
61
+
62
+ sage: M.default_frame()
63
+ Coordinate frame (M, (∂/∂x,∂/∂y,∂/∂z))
64
+
65
+ The default frame can be changed via the method
66
+ :meth:`~sage.manifolds.differentiable.manifold.DifferentiableManifold.set_default_frame`::
67
+
68
+ sage: M.set_default_frame(e)
69
+ sage: M.default_frame()
70
+ Vector frame (M, (e_0,e_1,e_2))
71
+
72
+ The elements of a vector frame are vector fields on the manifold::
73
+
74
+ sage: for vec in e:
75
+ ....: print(vec)
76
+ ....:
77
+ Vector field e_0 on the 3-dimensional differentiable manifold M
78
+ Vector field e_1 on the 3-dimensional differentiable manifold M
79
+ Vector field e_2 on the 3-dimensional differentiable manifold M
80
+
81
+ Each element of a vector frame can be accessed by its index::
82
+
83
+ sage: e[0]
84
+ Vector field e_0 on the 3-dimensional differentiable manifold M
85
+ sage: e[0].display(X.frame())
86
+ e_0 = ∂/∂x + x ∂/∂y + y ∂/∂z
87
+ sage: X.frame()[1]
88
+ Vector field ∂/∂y on the 3-dimensional differentiable manifold M
89
+ sage: X.frame()[1].display(e)
90
+ ∂/∂y = x/(x^2 - x + z + 2) e_0 - 1/(x^2 - x + z + 2) e_1
91
+ - (x - z)/(x^2 - x + z + 2) e_2
92
+
93
+ The slice operator ``:`` can be used to access to more than one element::
94
+
95
+ sage: e[0:2]
96
+ (Vector field e_0 on the 3-dimensional differentiable manifold M,
97
+ Vector field e_1 on the 3-dimensional differentiable manifold M)
98
+ sage: e[:]
99
+ (Vector field e_0 on the 3-dimensional differentiable manifold M,
100
+ Vector field e_1 on the 3-dimensional differentiable manifold M,
101
+ Vector field e_2 on the 3-dimensional differentiable manifold M)
102
+
103
+ Vector frames can be constructed from scratch, without any connection to
104
+ previously defined frames or vector fields (the connection can be performed
105
+ later via the method
106
+ :meth:`~sage.manifolds.differentiable.manifold.DifferentiableManifold.set_change_of_frame`)::
107
+
108
+ sage: f = M.vector_frame('f'); f
109
+ Vector frame (M, (f_0,f_1,f_2))
110
+ sage: M.frames()
111
+ [Coordinate frame (M, (∂/∂x,∂/∂y,∂/∂z)),
112
+ Vector frame (M, (e_0,e_1,e_2)),
113
+ Vector frame (M, (f_0,f_1,f_2))]
114
+
115
+ The index range depends on the starting index defined on the manifold::
116
+
117
+ sage: M = Manifold(3, 'M', start_index=1)
118
+ sage: X.<x,y,z> = M.chart()
119
+ sage: e = M.vector_frame('e')
120
+ sage: [e[i] for i in M.irange()]
121
+ [Vector field e_1 on the 3-dimensional differentiable manifold M,
122
+ Vector field e_2 on the 3-dimensional differentiable manifold M,
123
+ Vector field e_3 on the 3-dimensional differentiable manifold M]
124
+ sage: e[1], e[2], e[3]
125
+ (Vector field e_1 on the 3-dimensional differentiable manifold M,
126
+ Vector field e_2 on the 3-dimensional differentiable manifold M,
127
+ Vector field e_3 on the 3-dimensional differentiable manifold M)
128
+
129
+ Let us check that the vector fields ``e[i]`` are the frame vectors from
130
+ their components with respect to the frame `e`::
131
+
132
+ sage: e[1].comp(e)[:]
133
+ [1, 0, 0]
134
+ sage: e[2].comp(e)[:]
135
+ [0, 1, 0]
136
+ sage: e[3].comp(e)[:]
137
+ [0, 0, 1]
138
+
139
+ Defining a vector frame on a manifold automatically creates the dual
140
+ coframe, which, by default, bares the same name (here `e`)::
141
+
142
+ sage: M.coframes()
143
+ [Coordinate coframe (M, (dx,dy,dz)), Coframe (M, (e^1,e^2,e^3))]
144
+ sage: f = M.coframes()[1] ; f
145
+ Coframe (M, (e^1,e^2,e^3))
146
+ sage: f is e.coframe()
147
+ True
148
+
149
+ Each element of the coframe is a 1-form::
150
+
151
+ sage: f[1], f[2], f[3]
152
+ (1-form e^1 on the 3-dimensional differentiable manifold M,
153
+ 1-form e^2 on the 3-dimensional differentiable manifold M,
154
+ 1-form e^3 on the 3-dimensional differentiable manifold M)
155
+ sage: latex(f[1]), latex(f[2]), latex(f[3])
156
+ (e^{1}, e^{2}, e^{3})
157
+
158
+ Let us check that the coframe `(e^i)` is indeed the dual of the vector
159
+ frame `(e_i)`::
160
+
161
+ sage: f[1](e[1]) # the 1-form e^1 applied to the vector field e_1
162
+ Scalar field e^1(e_1) on the 3-dimensional differentiable manifold M
163
+ sage: f[1](e[1]).expr() # the explicit expression of e^1(e_1)
164
+ 1
165
+ sage: f[1](e[1]).expr(), f[1](e[2]).expr(), f[1](e[3]).expr()
166
+ (1, 0, 0)
167
+ sage: f[2](e[1]).expr(), f[2](e[2]).expr(), f[2](e[3]).expr()
168
+ (0, 1, 0)
169
+ sage: f[3](e[1]).expr(), f[3](e[2]).expr(), f[3](e[3]).expr()
170
+ (0, 0, 1)
171
+
172
+ The coordinate frame associated to spherical coordinates of the
173
+ sphere `S^2`::
174
+
175
+ sage: M = Manifold(2, 'S^2', start_index=1) # Part of S^2 covered by spherical coord.
176
+ sage: c_spher.<th,ph> = M.chart(r'th:[0,pi]:\theta ph:[0,2*pi):\phi')
177
+ sage: b = M.default_frame() ; b
178
+ Coordinate frame (S^2, (∂/∂th,∂/∂ph))
179
+ sage: b[1]
180
+ Vector field ∂/∂th on the 2-dimensional differentiable manifold S^2
181
+ sage: b[2]
182
+ Vector field ∂/∂ph on the 2-dimensional differentiable manifold S^2
183
+
184
+ The orthonormal frame constructed from the coordinate frame::
185
+
186
+ sage: e = M.vector_frame('e', (b[1], b[2]/sin(th))); e
187
+ Vector frame (S^2, (e_1,e_2))
188
+ sage: e[1].display()
189
+ e_1 = ∂/∂th
190
+ sage: e[2].display()
191
+ e_2 = 1/sin(th) ∂/∂ph
192
+
193
+ The change-of-frame automorphisms and their matrices::
194
+
195
+ sage: M.change_of_frame(c_spher.frame(), e)
196
+ Field of tangent-space automorphisms on the 2-dimensional
197
+ differentiable manifold S^2
198
+ sage: M.change_of_frame(c_spher.frame(), e)[:]
199
+ [ 1 0]
200
+ [ 0 1/sin(th)]
201
+ sage: M.change_of_frame(e, c_spher.frame())
202
+ Field of tangent-space automorphisms on the 2-dimensional
203
+ differentiable manifold S^2
204
+ sage: M.change_of_frame(e, c_spher.frame())[:]
205
+ [ 1 0]
206
+ [ 0 sin(th)]
207
+ """
208
+
209
+ # *****************************************************************************
210
+ # Copyright (C) 2013-2018 Eric Gourgoulhon <eric.gourgoulhon@obspm.fr>
211
+ # Copyright (C) 2013, 2014 Michal Bejger <bejger@camk.edu.pl>
212
+ # Copyright (C) 2016 Travis Scrimshaw <tscrimsh@umn.edu>
213
+ #
214
+ # Distributed under the terms of the GNU General Public License (GPL)
215
+ # as published by the Free Software Foundation; either version 2 of
216
+ # the License, or (at your option) any later version.
217
+ # https://www.gnu.org/licenses/
218
+ # *****************************************************************************
219
+
220
+ from sage.misc.cachefunc import cached_method
221
+ from sage.tensor.modules.finite_rank_free_module import FiniteRankFreeModule
222
+ from sage.tensor.modules.free_module_basis import FreeModuleBasis, FreeModuleCoBasis
223
+
224
+
225
+ class CoFrame(FreeModuleCoBasis):
226
+ r"""
227
+ Coframe on a differentiable manifold.
228
+
229
+ By *coframe*, it is meant a field `f` on some differentiable manifold `U`
230
+ endowed with a differentiable map `\Phi: U \rightarrow M` to a
231
+ differentiable manifold `M` such that for each `p\in U`, `f(p)` is a basis
232
+ of the vector space `T^*_{\Phi(p)}M` (the dual to the tangent space
233
+ `T_{\Phi(p)}M`).
234
+
235
+ The standard case of a coframe *on* `U` corresponds to `U = M` and
236
+ `\Phi = \mathrm{Id}_M`. Other common cases are `\Phi` being an
237
+ immersion and `\Phi` being a curve in `M` (`U` is then an open interval
238
+ of `\RR`).
239
+
240
+ INPUT:
241
+
242
+ - ``frame`` -- the vector frame dual to the coframe
243
+ - ``symbol`` -- either a string, to be used as a common base for the
244
+ symbols of the 1-forms constituting the coframe, or a tuple of strings,
245
+ representing the individual symbols of the 1-forms
246
+ - ``latex_symbol`` -- (default: ``None``) either a string, to be used
247
+ as a common base for the LaTeX symbols of the 1-forms constituting the
248
+ coframe, or a tuple of strings, representing the individual LaTeX symbols
249
+ of the 1-forms; if ``None``, ``symbol`` is used in place of
250
+ ``latex_symbol``
251
+ - ``indices`` -- (default: ``None``; used only if ``symbol`` is a single
252
+ string) tuple of strings representing the indices labelling the 1-forms
253
+ of the coframe; if ``None``, the indices will be generated as integers
254
+ within the range declared on the coframe's domain
255
+ - ``latex_indices`` -- (default: ``None``) tuple of strings representing
256
+ the indices for the LaTeX symbols of the 1-forms of the coframe; if
257
+ ``None``, ``indices`` is used instead
258
+
259
+ EXAMPLES:
260
+
261
+ Coframe on a 3-dimensional manifold::
262
+
263
+ sage: M = Manifold(3, 'M', start_index=1)
264
+ sage: X.<x,y,z> = M.chart()
265
+ sage: v = M.vector_frame('v')
266
+ sage: from sage.manifolds.differentiable.vectorframe import CoFrame
267
+ sage: e = CoFrame(v, 'e') ; e
268
+ Coframe (M, (e^1,e^2,e^3))
269
+
270
+ Instead of importing CoFrame in the global namespace, the coframe can be
271
+ obtained by means of the method
272
+ :meth:`~sage.tensor.modules.free_module_basis.FreeModuleBasis.dual_basis`;
273
+ the symbol is then the same as that of the frame::
274
+
275
+ sage: a = v.dual_basis() ; a
276
+ Coframe (M, (v^1,v^2,v^3))
277
+ sage: a[1] == e[1]
278
+ True
279
+ sage: a[1] is e[1]
280
+ False
281
+ sage: e[1].display(v)
282
+ e^1 = v^1
283
+
284
+ The 1-forms composing the coframe are obtained via the operator ``[]``::
285
+
286
+ sage: e[1], e[2], e[3]
287
+ (1-form e^1 on the 3-dimensional differentiable manifold M,
288
+ 1-form e^2 on the 3-dimensional differentiable manifold M,
289
+ 1-form e^3 on the 3-dimensional differentiable manifold M)
290
+
291
+ Checking that `e` is the dual of `v`::
292
+
293
+ sage: e[1](v[1]).expr(), e[1](v[2]).expr(), e[1](v[3]).expr()
294
+ (1, 0, 0)
295
+ sage: e[2](v[1]).expr(), e[2](v[2]).expr(), e[2](v[3]).expr()
296
+ (0, 1, 0)
297
+ sage: e[3](v[1]).expr(), e[3](v[2]).expr(), e[3](v[3]).expr()
298
+ (0, 0, 1)
299
+ """
300
+ def __init__(self, frame, symbol, latex_symbol=None, indices=None,
301
+ latex_indices=None):
302
+ r"""
303
+ Construct a coframe, dual to a given vector frame.
304
+
305
+ TESTS::
306
+
307
+ sage: M = Manifold(2, 'M')
308
+ sage: e = M.vector_frame('e')
309
+ sage: from sage.manifolds.differentiable.vectorframe import CoFrame
310
+ sage: f = CoFrame(e, 'f'); f
311
+ Coframe (M, (f^0,f^1))
312
+ sage: TestSuite(f).run()
313
+ """
314
+ self._domain = frame._domain
315
+ self._manifold = self._domain.manifold()
316
+ FreeModuleCoBasis.__init__(self, frame, symbol,
317
+ latex_symbol=latex_symbol, indices=indices,
318
+ latex_indices=latex_indices)
319
+ # The coframe is added to the domain's set of coframes, as well as to
320
+ # all the superdomains' sets of coframes
321
+ for sd in self._domain.open_supersets():
322
+ sd._coframes.append(self)
323
+
324
+ def _repr_(self):
325
+ r"""
326
+ String representation of ``self``.
327
+
328
+ TESTS::
329
+
330
+ sage: M = Manifold(2, 'M')
331
+ sage: e = M.vector_frame('e')
332
+ sage: f = e.coframe()
333
+ sage: f._repr_()
334
+ 'Coframe (M, (e^0,e^1))'
335
+ sage: repr(f) # indirect doctest
336
+ 'Coframe (M, (e^0,e^1))'
337
+ sage: f # indirect doctest
338
+ Coframe (M, (e^0,e^1))
339
+
340
+ Test with a nontrivial destination map::
341
+
342
+ sage: N = Manifold(3, 'N', start_index=1)
343
+ sage: phi = M.diff_map(N)
344
+ sage: h = M.vector_frame('h', dest_map=phi)
345
+ sage: h.coframe()._repr_()
346
+ 'Coframe (M, (h^1,h^2,h^3)) with values on the 3-dimensional differentiable manifold N'
347
+ """
348
+ description = "Coframe " + self._name
349
+ dest_map = self._basis.destination_map()
350
+ if dest_map is not self._domain.identity_map():
351
+ description += " with values on the {}".format(dest_map.codomain())
352
+ return description
353
+
354
+ def at(self, point):
355
+ r"""
356
+ Return the value of ``self`` at a given point on the manifold, this
357
+ value being a basis of the dual of the tangent space at the point.
358
+
359
+ INPUT:
360
+
361
+ - ``point`` -- :class:`~sage.manifolds.point.ManifoldPoint`;
362
+ point `p` in the domain `U` of the coframe (denoted `f` hereafter)
363
+
364
+ OUTPUT:
365
+
366
+ - :class:`~sage.tensor.modules.free_module_basis.FreeModuleCoBasis`
367
+ representing the basis `f(p)` of the vector space `T^*_{\Phi(p)} M`,
368
+ dual to the tangent space `T_{\Phi(p)} M`, where
369
+ `\Phi: U \to M` is the differentiable map associated with
370
+ `f` (possibly `\Phi = \mathrm{Id}_U`)
371
+
372
+ EXAMPLES:
373
+
374
+ Cobasis of a tangent space on a 2-dimensional manifold::
375
+
376
+ sage: M = Manifold(2, 'M')
377
+ sage: X.<x,y> = M.chart()
378
+ sage: p = M.point((-1,2), name='p')
379
+ sage: f = X.coframe() ; f
380
+ Coordinate coframe (M, (dx,dy))
381
+ sage: fp = f.at(p) ; fp
382
+ Dual basis (dx,dy) on the Tangent space at Point p on the
383
+ 2-dimensional differentiable manifold M
384
+ sage: type(fp)
385
+ <class 'sage.tensor.modules.free_module_basis.FreeModuleCoBasis_with_category'>
386
+ sage: fp[0]
387
+ Linear form dx on the Tangent space at Point p on the 2-dimensional
388
+ differentiable manifold M
389
+ sage: fp[1]
390
+ Linear form dy on the Tangent space at Point p on the 2-dimensional
391
+ differentiable manifold M
392
+ sage: fp is X.frame().at(p).dual_basis()
393
+ True
394
+ """
395
+ return self._basis.at(point).dual_basis()
396
+
397
+ def set_name(self, symbol, latex_symbol=None, indices=None,
398
+ latex_indices=None, index_position='up',
399
+ include_domain=True):
400
+ r"""
401
+ Set (or change) the text name and LaTeX name of ``self``.
402
+
403
+ INPUT:
404
+
405
+ - ``symbol`` -- either a string, to be used as a common base for the
406
+ symbols of the 1-forms constituting the coframe, or a list/tuple of
407
+ strings, representing the individual symbols of the 1-forms
408
+ - ``latex_symbol`` -- (default: ``None``) either a string, to be used
409
+ as a common base for the LaTeX symbols of the 1-forms constituting
410
+ the coframe, or a list/tuple of strings, representing the individual
411
+ LaTeX symbols of the 1-forms; if ``None``, ``symbol`` is used in
412
+ place of ``latex_symbol``
413
+ - ``indices`` -- (default: ``None``; used only if ``symbol`` is a
414
+ single string) tuple of strings representing the indices labelling
415
+ the 1-forms of the coframe; if ``None``, the indices will be
416
+ generated as integers within the range declared on ``self``
417
+ - ``latex_indices`` -- (default: ``None``) tuple of strings
418
+ representing the indices for the LaTeX symbols of the 1-forms;
419
+ if ``None``, ``indices`` is used instead
420
+ - ``index_position`` -- (default: ``'up'``) determines the position
421
+ of the indices labelling the 1-forms of the coframe; can be
422
+ either ``'down'`` or ``'up'``
423
+ - ``include_domain`` -- boolean (default: ``True``); determining whether
424
+ the name of the domain is included in the beginning of the coframe
425
+ name
426
+
427
+ EXAMPLES::
428
+
429
+ sage: M = Manifold(2, 'M')
430
+ sage: e = M.vector_frame('e').coframe(); e
431
+ Coframe (M, (e^0,e^1))
432
+ sage: e.set_name('f'); e
433
+ Coframe (M, (f^0,f^1))
434
+ sage: e.set_name('e', latex_symbol=r'\epsilon')
435
+ sage: latex(e)
436
+ \left(M, \left(\epsilon^{0},\epsilon^{1}\right)\right)
437
+ sage: e.set_name('e', include_domain=False); e
438
+ Coframe (e^0,e^1)
439
+ sage: e.set_name(['a', 'b'], latex_symbol=[r'\alpha', r'\beta']); e
440
+ Coframe (M, (a,b))
441
+ sage: latex(e)
442
+ \left(M, \left(\alpha,\beta\right)\right)
443
+ sage: e.set_name('e', indices=['x','y'],
444
+ ....: latex_indices=[r'\xi', r'\zeta']); e
445
+ Coframe (M, (e^x,e^y))
446
+ sage: latex(e)
447
+ \left(M, \left(e^{\xi},e^{\zeta}\right)\right)
448
+ """
449
+ super().set_name(symbol, latex_symbol=latex_symbol,
450
+ indices=indices,
451
+ latex_indices=latex_indices,
452
+ index_position=index_position)
453
+ if include_domain:
454
+ # Redefinition of the name and the LaTeX name to include the domain
455
+ self._name = "({}, {})".format(self._domain._name, self._name)
456
+ self._latex_name = r"\left({}, {}\right)".format(
457
+ self._domain._latex_name, self._latex_name)
458
+
459
+ # ******************************************************************************
460
+
461
+
462
+ class VectorFrame(FreeModuleBasis):
463
+ r"""
464
+ Vector frame on a differentiable manifold.
465
+
466
+ By *vector frame*, it is meant a field `e` on some
467
+ differentiable manifold `U` endowed with a differentiable map
468
+ `\Phi: U\rightarrow M` to a differentiable manifold `M` such that for
469
+ each `p\in U`, `e(p)` is a vector basis of the tangent space
470
+ `T_{\Phi(p)}M`.
471
+
472
+ The standard case of a vector frame *on* `U` corresponds to `U=M`
473
+ and `\Phi = \mathrm{Id}_M`. Other common cases are `\Phi` being an
474
+ immersion and `\Phi` being a curve in `M` (`U` is then an open interval
475
+ of `\RR`).
476
+
477
+ For each instantiation of a vector frame, a coframe is automatically
478
+ created, as an instance of the class :class:`CoFrame`. It is returned by
479
+ the method :meth:`coframe`.
480
+
481
+ INPUT:
482
+
483
+ - ``vector_field_module`` -- free module `\mathfrak{X}(U, \Phi)`
484
+ of vector fields along `U` with values on `M \supset \Phi(U)`
485
+ - ``symbol`` -- either a string, to be used as a common base for the
486
+ symbols of the vector fields constituting the vector frame, or a tuple
487
+ of strings, representing the individual symbols of the vector fields
488
+ - ``latex_symbol`` -- (default: ``None``) either a string, to be used
489
+ as a common base for the LaTeX symbols of the vector fields constituting
490
+ the vector frame, or a tuple of strings, representing the individual
491
+ LaTeX symbols of the vector fields; if ``None``, ``symbol`` is used in
492
+ place of ``latex_symbol``
493
+ - ``from_frame`` -- (default: ``None``) vector frame `\tilde e` on the
494
+ codomain `M` of the destination map `\Phi`; the constructed frame `e`
495
+ is then such that `\forall p \in U, e(p) = \tilde{e}(\Phi(p))`
496
+ - ``indices`` -- (default: ``None``; used only if ``symbol`` is a single
497
+ string) tuple of strings representing the indices labelling the vector
498
+ fields of the frame; if ``None``, the indices will be generated as
499
+ integers within the range declared on the vector frame's domain
500
+ - ``latex_indices`` -- (default: ``None``) tuple of strings representing
501
+ the indices for the LaTeX symbols of the vector fields; if
502
+ ``None``, ``indices`` is used instead
503
+ - ``symbol_dual`` -- (default: ``None``) same as ``symbol`` but for the
504
+ dual coframe; if ``None``, ``symbol`` must be a string and is used
505
+ for the common base of the symbols of the elements of the dual coframe
506
+ - ``latex_symbol_dual`` -- (default: ``None``) same as ``latex_symbol``
507
+ but for the dual coframe
508
+
509
+ EXAMPLES:
510
+
511
+ Defining a vector frame on a 3-dimensional manifold::
512
+
513
+ sage: M = Manifold(3, 'M', start_index=1)
514
+ sage: X.<x,y,z> = M.chart()
515
+ sage: e = M.vector_frame('e') ; e
516
+ Vector frame (M, (e_1,e_2,e_3))
517
+ sage: latex(e)
518
+ \left(M, \left(e_{1},e_{2},e_{3}\right)\right)
519
+
520
+ The individual elements of the vector frame are accessed via square
521
+ brackets, with the possibility to invoke the slice operator '``:``' to
522
+ get more than a single element::
523
+
524
+ sage: e[2]
525
+ Vector field e_2 on the 3-dimensional differentiable manifold M
526
+ sage: e[1:3]
527
+ (Vector field e_1 on the 3-dimensional differentiable manifold M,
528
+ Vector field e_2 on the 3-dimensional differentiable manifold M)
529
+ sage: e[:]
530
+ (Vector field e_1 on the 3-dimensional differentiable manifold M,
531
+ Vector field e_2 on the 3-dimensional differentiable manifold M,
532
+ Vector field e_3 on the 3-dimensional differentiable manifold M)
533
+
534
+ The LaTeX symbol can be specified::
535
+
536
+ sage: E = M.vector_frame('E', latex_symbol=r"\epsilon")
537
+ sage: latex(E)
538
+ \left(M, \left(\epsilon_{1},\epsilon_{2},\epsilon_{3}\right)\right)
539
+
540
+ By default, the elements of the vector frame are labelled by integers
541
+ within the range specified at the manifold declaration. It is however
542
+ possible to fully customize the labels, via the argument ``indices``::
543
+
544
+ sage: u = M.vector_frame('u', indices=('x', 'y', 'z')) ; u
545
+ Vector frame (M, (u_x,u_y,u_z))
546
+ sage: u[1]
547
+ Vector field u_x on the 3-dimensional differentiable manifold M
548
+ sage: u.coframe()
549
+ Coframe (M, (u^x,u^y,u^z))
550
+
551
+ The LaTeX format of the indices can be adjusted::
552
+
553
+ sage: v = M.vector_frame('v', indices=('a', 'b', 'c'),
554
+ ....: latex_indices=(r'\alpha', r'\beta', r'\gamma'))
555
+ sage: v
556
+ Vector frame (M, (v_a,v_b,v_c))
557
+ sage: latex(v)
558
+ \left(M, \left(v_{\alpha},v_{\beta},v_{\gamma}\right)\right)
559
+ sage: latex(v.coframe())
560
+ \left(M, \left(v^{\alpha},v^{\beta},v^{\gamma}\right)\right)
561
+
562
+ The symbol of each element of the vector frame can also be freely chosen,
563
+ by providing a tuple of symbols as the first argument of ``vector_frame``;
564
+ it is then mandatory to specify as well some symbols for the dual coframe::
565
+
566
+ sage: h = M.vector_frame(('a', 'b', 'c'), symbol_dual=('A', 'B', 'C'))
567
+ sage: h
568
+ Vector frame (M, (a,b,c))
569
+ sage: h[1]
570
+ Vector field a on the 3-dimensional differentiable manifold M
571
+ sage: h.coframe()
572
+ Coframe (M, (A,B,C))
573
+ sage: h.coframe()[1]
574
+ 1-form A on the 3-dimensional differentiable manifold M
575
+
576
+ Example with a non-trivial map `\Phi` (see above); a vector frame along a
577
+ curve::
578
+
579
+ sage: U = Manifold(1, 'U') # open interval (-1,1) as a 1-dimensional manifold
580
+ sage: T.<t> = U.chart('t:(-1,1)') # canonical chart on U
581
+ sage: Phi = U.diff_map(M, [cos(t), sin(t), t], name='Phi',
582
+ ....: latex_name=r'\Phi')
583
+ sage: Phi
584
+ Differentiable map Phi from the 1-dimensional differentiable manifold U
585
+ to the 3-dimensional differentiable manifold M
586
+ sage: f = U.vector_frame('f', dest_map=Phi) ; f
587
+ Vector frame (U, (f_1,f_2,f_3)) with values on the 3-dimensional
588
+ differentiable manifold M
589
+ sage: f.domain()
590
+ 1-dimensional differentiable manifold U
591
+ sage: f.ambient_domain()
592
+ 3-dimensional differentiable manifold M
593
+
594
+ The value of the vector frame at a given point is a basis of the
595
+ corresponding tangent space::
596
+
597
+ sage: p = U((0,), name='p') ; p
598
+ Point p on the 1-dimensional differentiable manifold U
599
+ sage: f.at(p)
600
+ Basis (f_1,f_2,f_3) on the Tangent space at Point Phi(p) on the
601
+ 3-dimensional differentiable manifold M
602
+
603
+ Vector frames are bases of free modules formed by vector fields::
604
+
605
+ sage: e.module()
606
+ Free module X(M) of vector fields on the 3-dimensional differentiable
607
+ manifold M
608
+ sage: e.module().base_ring()
609
+ Algebra of differentiable scalar fields on the 3-dimensional
610
+ differentiable manifold M
611
+ sage: e.module() is M.vector_field_module()
612
+ True
613
+ sage: e in M.vector_field_module().bases()
614
+ True
615
+
616
+ ::
617
+
618
+ sage: f.module()
619
+ Free module X(U,Phi) of vector fields along the 1-dimensional
620
+ differentiable manifold U mapped into the 3-dimensional differentiable
621
+ manifold M
622
+ sage: f.module().base_ring()
623
+ Algebra of differentiable scalar fields on the 1-dimensional
624
+ differentiable manifold U
625
+ sage: f.module() is U.vector_field_module(dest_map=Phi)
626
+ True
627
+ sage: f in U.vector_field_module(dest_map=Phi).bases()
628
+ True
629
+ """
630
+
631
+ # The following class attribute must be redefined by any derived class:
632
+ _cobasis_class = CoFrame
633
+
634
+ @staticmethod
635
+ def __classcall_private__(cls, vector_field_module, symbol,
636
+ latex_symbol=None, from_frame=None, indices=None,
637
+ latex_indices=None, symbol_dual=None,
638
+ latex_symbol_dual=None):
639
+ """
640
+ Transform input lists into tuples for the unique representation of
641
+ VectorFrame.
642
+
643
+ TESTS::
644
+
645
+ sage: M = Manifold(2, 'M')
646
+ sage: XM = M.vector_field_module(force_free=True)
647
+ sage: from sage.manifolds.differentiable.vectorframe import VectorFrame
648
+ sage: e = VectorFrame(XM, ['a', 'b'], symbol_dual=['A', 'B']); e
649
+ Vector frame (M, (a,b))
650
+ sage: e.dual_basis()
651
+ Coframe (M, (A,B))
652
+ sage: e is VectorFrame(XM, ('a', 'b'), symbol_dual=('A', 'B'))
653
+ True
654
+ """
655
+ if isinstance(symbol, list):
656
+ symbol = tuple(symbol)
657
+ if isinstance(latex_symbol, list):
658
+ latex_symbol = tuple(latex_symbol)
659
+ if isinstance(indices, list):
660
+ indices = tuple(indices)
661
+ if isinstance(latex_indices, list):
662
+ latex_indices = tuple(latex_indices)
663
+ if isinstance(symbol_dual, list):
664
+ symbol_dual = tuple(symbol_dual)
665
+ if isinstance(latex_symbol_dual, list):
666
+ latex_symbol_dual = tuple(latex_symbol_dual)
667
+ return super().__classcall__(cls, vector_field_module,
668
+ symbol, latex_symbol=latex_symbol,
669
+ from_frame=from_frame, indices=indices,
670
+ latex_indices=latex_indices,
671
+ symbol_dual=symbol_dual,
672
+ latex_symbol_dual=latex_symbol_dual)
673
+
674
+ def __init__(self, vector_field_module, symbol, latex_symbol=None,
675
+ from_frame=None, indices=None, latex_indices=None,
676
+ symbol_dual=None, latex_symbol_dual=None):
677
+ r"""
678
+ Construct a vector frame on a parallelizable manifold.
679
+
680
+ TESTS::
681
+
682
+ sage: M = Manifold(2, 'M')
683
+ sage: XM = M.vector_field_module(force_free=True) # makes M parallelizable
684
+ sage: from sage.manifolds.differentiable.vectorframe import VectorFrame
685
+ sage: e = VectorFrame(XM, 'e', latex_symbol=r'\epsilon'); e
686
+ Vector frame (M, (e_0,e_1))
687
+ sage: TestSuite(e).run()
688
+ """
689
+ from sage.manifolds.differentiable.manifold import DifferentiableManifold
690
+ # Some sanity check:
691
+ if not isinstance(vector_field_module, FiniteRankFreeModule):
692
+ raise ValueError("the {} has already been constructed as a "
693
+ "non-free module and therefore cannot have "
694
+ "a basis".format(vector_field_module))
695
+ self._domain = vector_field_module._domain
696
+ self._ambient_domain = vector_field_module._ambient_domain
697
+ self._dest_map = vector_field_module._dest_map
698
+ self._from_frame = from_frame
699
+ self._manifold = self._domain.manifold()
700
+ if from_frame is not None:
701
+ if not from_frame._domain.is_subset(self._dest_map._codomain):
702
+ raise ValueError("the domain of the frame 'from_frame' is " +
703
+ "not included in the codomain of the " +
704
+ "destination map")
705
+ if symbol is None:
706
+ if from_frame is None:
707
+ raise TypeError("some frame symbol must be provided")
708
+ symbol = from_frame._symbol
709
+ latex_symbol = from_frame._latex_symbol
710
+ indices = from_frame._indices
711
+ latex_indices = from_frame._latex_indices
712
+ symbol_dual = from_frame._symbol_dual
713
+ latex_symbol_dual = from_frame._latex_symbol_dual
714
+ FreeModuleBasis.__init__(self, vector_field_module,
715
+ symbol, latex_symbol=latex_symbol,
716
+ indices=indices, latex_indices=latex_indices,
717
+ symbol_dual=symbol_dual,
718
+ latex_symbol_dual=latex_symbol_dual)
719
+ # The frame is added to the domain's set of frames, as well as to all
720
+ # the superdomains' sets of frames; moreover the first defined frame
721
+ # is considered as the default one
722
+ dest_map = self._dest_map
723
+ for sd in self._domain.open_supersets():
724
+ sd._frames.append(self)
725
+ sd._top_frames.append(self)
726
+ if sd._def_frame is None:
727
+ sd._def_frame = self
728
+ if isinstance(sd, DifferentiableManifold):
729
+ # Initialization of the zero elements of tensor field modules:
730
+ if dest_map in sd._vector_field_modules:
731
+ xsd = sd._vector_field_modules[dest_map]
732
+ if not isinstance(xsd, FiniteRankFreeModule):
733
+ for t in xsd._tensor_modules.values():
734
+ t.zero()._add_comp_unsafe(self)
735
+ # (since new components are initialized to zero)
736
+ if dest_map is self._domain.identity_map():
737
+ # The frame is added to the list of the domain's covering frames:
738
+ self._domain._set_covering_frame(self)
739
+
740
+ # Dual coframe
741
+ self._coframe = self.dual_basis() # self._coframe = a shortcut for
742
+ # self._dual_basis
743
+
744
+ # Derived quantities:
745
+ # Initialization of the set of frames that are restrictions of the
746
+ # current frame to subdomains of the frame domain:
747
+ self._subframes = set([self])
748
+ # Initialization of the set of frames which the current frame is a
749
+ # restriction of:
750
+ self._superframes = set([self])
751
+
752
+ self._restrictions = {} # dict. of the restrictions of self to
753
+ # subdomains of self._domain, with the
754
+ # subdomains as keys
755
+ # NB: set(self._restrictions.values()) is identical to
756
+ # self._subframes
757
+
758
+ ###### Methods that must be redefined by derived classes of ######
759
+ ###### FreeModuleBasis ######
760
+
761
+ def _repr_(self):
762
+ r"""
763
+ String representation of ``self``.
764
+
765
+ TESTS::
766
+
767
+ sage: M = Manifold(2, 'M')
768
+ sage: e = M.vector_frame('e')
769
+ sage: e._repr_()
770
+ 'Vector frame (M, (e_0,e_1))'
771
+ sage: repr(e) # indirect doctest
772
+ 'Vector frame (M, (e_0,e_1))'
773
+ sage: e # indirect doctest
774
+ Vector frame (M, (e_0,e_1))
775
+
776
+ Test with a nontrivial destination map::
777
+
778
+ sage: N = Manifold(3, 'N', start_index=1)
779
+ sage: phi = M.diff_map(N)
780
+ sage: h = M.vector_frame('h', dest_map=phi)
781
+ sage: h._repr_()
782
+ 'Vector frame (M, (h_1,h_2,h_3)) with values on the 3-dimensional differentiable manifold N'
783
+ """
784
+ description = "Vector frame " + self._name
785
+ if self._dest_map is not self._domain.identity_map():
786
+ description += " with values on the {}".format(self._dest_map.codomain())
787
+ return description
788
+
789
+ def _new_instance(self, symbol, latex_symbol=None, indices=None,
790
+ latex_indices=None, symbol_dual=None,
791
+ latex_symbol_dual=None):
792
+ r"""
793
+ Construct a new vector frame on the same vector field module
794
+ as ``self``.
795
+
796
+ INPUT:
797
+
798
+ - ``symbol`` -- either a string, to be used as a common base for the
799
+ symbols of the vector fields constituting the vector frame, or a
800
+ tuple of strings, representing the individual symbols of the vector
801
+ fields
802
+ - ``latex_symbol`` -- (default: ``None``) either a string, to be used
803
+ as a common base for the LaTeX symbols of the vector fields
804
+ constituting the vector frame, or a tuple of strings, representing
805
+ the individual LaTeX symbols of the vector fields; if ``None``,
806
+ ``symbol`` is used in place of ``latex_symbol``
807
+ - ``from_frame`` -- (default: ``None``) vector frame `\tilde e` on the
808
+ codomain `M` of the destination map `\Phi`; the constructed frame `e`
809
+ is then such that `\forall p \in U, e(p) = \tilde{e}(\Phi(p))`
810
+ - ``indices`` -- (default: ``None``; used only if ``symbol`` is a
811
+ single string) tuple of strings representing the indices labelling
812
+ the vector fields of the frame; if ``None``, the indices will be
813
+ generated as integers within the range declared on the vector frame's
814
+ domain
815
+ - ``latex_indices`` -- (default: ``None``) tuple of strings
816
+ representing the indices for the LaTeX symbols of the vector fields;
817
+ if ``None``, ``indices`` is used instead
818
+ - ``symbol_dual`` -- (default: ``None``) same as ``symbol`` but for the
819
+ dual coframe; if ``None``, ``symbol`` must be a string and is used
820
+ for the common base of the symbols of the elements of the dual
821
+ coframe
822
+ - ``latex_symbol_dual`` -- (default: ``None``) same as ``latex_symbol``
823
+ but for the dual coframe
824
+
825
+ OUTPUT: instance of :class:`VectorFrame`
826
+
827
+ TESTS::
828
+
829
+ sage: M = Manifold(2, 'M')
830
+ sage: e = M.vector_frame('e')
831
+ sage: e._new_instance('f')
832
+ Vector frame (M, (f_0,f_1))
833
+ """
834
+ return VectorFrame(self._fmodule, symbol, latex_symbol=latex_symbol,
835
+ indices=indices, latex_indices=latex_indices,
836
+ symbol_dual=symbol_dual,
837
+ latex_symbol_dual=latex_symbol_dual)
838
+
839
+ ###### End of methods to be redefined by derived classes ######
840
+
841
+ def domain(self):
842
+ r"""
843
+ Return the domain on which ``self`` is defined.
844
+
845
+ OUTPUT:
846
+
847
+ - a :class:`~sage.manifolds.differentiable.manifold.DifferentiableManifold`;
848
+ representing the domain of the vector frame
849
+
850
+ EXAMPLES::
851
+
852
+ sage: M = Manifold(2, 'M')
853
+ sage: e = M.vector_frame('e')
854
+ sage: e.domain()
855
+ 2-dimensional differentiable manifold M
856
+ sage: U = M.open_subset('U')
857
+ sage: f = e.restrict(U)
858
+ sage: f.domain()
859
+ Open subset U of the 2-dimensional differentiable manifold M
860
+ """
861
+ return self._domain
862
+
863
+ def ambient_domain(self):
864
+ r"""
865
+ Return the differentiable manifold in which ``self`` takes its values.
866
+
867
+ The ambient domain is the codomain `M` of the differentiable map
868
+ `\Phi: U \rightarrow M` associated with the frame.
869
+
870
+ OUTPUT:
871
+
872
+ - a :class:`~sage.manifolds.differentiable.manifold.DifferentiableManifold`
873
+ representing `M`
874
+
875
+ EXAMPLES::
876
+
877
+ sage: M = Manifold(2, 'M')
878
+ sage: e = M.vector_frame('e')
879
+ sage: e.ambient_domain()
880
+ 2-dimensional differentiable manifold M
881
+
882
+ In the present case, since `\Phi` is the identity map::
883
+
884
+ sage: e.ambient_domain() == e.domain()
885
+ True
886
+
887
+ An example with a non trivial map `\Phi`::
888
+
889
+ sage: U = Manifold(1, 'U')
890
+ sage: T.<t> = U.chart()
891
+ sage: X.<x,y> = M.chart()
892
+ sage: Phi = U.diff_map(M, {(T,X): [cos(t), t]}, name='Phi',
893
+ ....: latex_name=r'\Phi') ; Phi
894
+ Differentiable map Phi from the 1-dimensional differentiable
895
+ manifold U to the 2-dimensional differentiable manifold M
896
+ sage: f = U.vector_frame('f', dest_map=Phi); f
897
+ Vector frame (U, (f_0,f_1)) with values on the 2-dimensional
898
+ differentiable manifold M
899
+ sage: f.ambient_domain()
900
+ 2-dimensional differentiable manifold M
901
+ sage: f.domain()
902
+ 1-dimensional differentiable manifold U
903
+ """
904
+ return self._ambient_domain
905
+
906
+ def destination_map(self):
907
+ r"""
908
+ Return the differential map associated to this vector frame.
909
+
910
+ Let `e` denote the vector frame; the differential map associated to
911
+ it is the map `\Phi: U\rightarrow M` such that for each `p \in U`,
912
+ `e(p)` is a vector basis of the tangent space `T_{\Phi(p)}M`.
913
+
914
+ OUTPUT:
915
+
916
+ - a :class:`~sage.manifolds.differentiable.diff_map.DiffMap`
917
+ representing the differential map `\Phi`
918
+
919
+ EXAMPLES::
920
+
921
+ sage: M = Manifold(2, 'M')
922
+ sage: e = M.vector_frame('e')
923
+ sage: e.destination_map()
924
+ Identity map Id_M of the 2-dimensional differentiable manifold M
925
+
926
+ An example with a non trivial map `\Phi`::
927
+
928
+ sage: U = Manifold(1, 'U')
929
+ sage: T.<t> = U.chart()
930
+ sage: X.<x,y> = M.chart()
931
+ sage: Phi = U.diff_map(M, {(T,X): [cos(t), t]}, name='Phi',
932
+ ....: latex_name=r'\Phi') ; Phi
933
+ Differentiable map Phi from the 1-dimensional differentiable
934
+ manifold U to the 2-dimensional differentiable manifold M
935
+ sage: f = U.vector_frame('f', dest_map=Phi); f
936
+ Vector frame (U, (f_0,f_1)) with values on the 2-dimensional
937
+ differentiable manifold M
938
+ sage: f.destination_map()
939
+ Differentiable map Phi from the 1-dimensional differentiable
940
+ manifold U to the 2-dimensional differentiable manifold M
941
+ """
942
+ return self._dest_map
943
+
944
+ def coframe(self):
945
+ r"""
946
+ Return the coframe of ``self``.
947
+
948
+ EXAMPLES::
949
+
950
+ sage: M = Manifold(2, 'M')
951
+ sage: e = M.vector_frame('e')
952
+ sage: e.coframe()
953
+ Coframe (M, (e^0,e^1))
954
+ sage: X.<x,y> = M.chart()
955
+ sage: X.frame().coframe()
956
+ Coordinate coframe (M, (dx,dy))
957
+ """
958
+ return self._coframe
959
+
960
+ def new_frame(self, change_of_frame, symbol, latex_symbol=None,
961
+ indices=None, latex_indices=None, symbol_dual=None,
962
+ latex_symbol_dual=None):
963
+ r"""
964
+ Define a new vector frame from ``self``.
965
+
966
+ The new vector frame is defined from a field of tangent-space
967
+ automorphisms; its domain is the same as that of the current frame.
968
+
969
+ INPUT:
970
+
971
+ - ``change_of_frame`` --
972
+ :class:`~sage.manifolds.differentiable.automorphismfield.AutomorphismFieldParal`;
973
+ the field of tangent space automorphisms `P` that relates
974
+ the current frame `(e_i)` to the new frame `(n_i)` according
975
+ to `n_i = P(e_i)`
976
+ - ``symbol`` -- either a string, to be used as a common base for the
977
+ symbols of the vector fields constituting the vector frame, or a
978
+ list/tuple of strings, representing the individual symbols of the
979
+ vector fields
980
+ - ``latex_symbol`` -- (default: ``None``) either a string, to be used
981
+ as a common base for the LaTeX symbols of the vector fields
982
+ constituting the vector frame, or a list/tuple of strings,
983
+ representing the individual LaTeX symbols of the vector fields;
984
+ if ``None``, ``symbol`` is used in place of ``latex_symbol``
985
+ - ``indices`` -- (default: ``None``; used only if ``symbol`` is a
986
+ single string) tuple of strings representing the indices labelling
987
+ the vector fields of the frame; if ``None``, the indices will be
988
+ generated as integers within the range declared on ``self``
989
+ - ``latex_indices`` -- (default: ``None``) tuple of strings
990
+ representing the indices for the LaTeX symbols of the vector fields;
991
+ if ``None``, ``indices`` is used instead
992
+ - ``symbol_dual`` -- (default: ``None``) same as ``symbol`` but for the
993
+ dual coframe; if ``None``, ``symbol`` must be a string and is used
994
+ for the common base of the symbols of the elements of the dual
995
+ coframe
996
+ - ``latex_symbol_dual`` -- (default: ``None``) same as ``latex_symbol``
997
+ but for the dual coframe
998
+
999
+ OUTPUT:
1000
+
1001
+ - the new frame `(n_i)`, as an instance of :class:`VectorFrame`
1002
+
1003
+ EXAMPLES:
1004
+
1005
+ Frame resulting from a `\pi/3`-rotation in the Euclidean plane::
1006
+
1007
+ sage: M = Manifold(2, 'R^2')
1008
+ sage: X.<x,y> = M.chart()
1009
+ sage: e = M.vector_frame('e') ; M.set_default_frame(e)
1010
+ sage: M._frame_changes
1011
+ {}
1012
+ sage: rot = M.automorphism_field()
1013
+ sage: rot[:] = [[sqrt(3)/2, -1/2], [1/2, sqrt(3)/2]]
1014
+ sage: n = e.new_frame(rot, 'n')
1015
+ sage: n[0][:]
1016
+ [1/2*sqrt(3), 1/2]
1017
+ sage: n[1][:]
1018
+ [-1/2, 1/2*sqrt(3)]
1019
+ sage: a = M.change_of_frame(e,n)
1020
+ sage: a[:]
1021
+ [1/2*sqrt(3) -1/2]
1022
+ [ 1/2 1/2*sqrt(3)]
1023
+ sage: a == rot
1024
+ True
1025
+ sage: a is rot
1026
+ False
1027
+ sage: a._components # random (dictionary output)
1028
+ {Vector frame (R^2, (e_0,e_1)): 2-indices components w.r.t.
1029
+ Vector frame (R^2, (e_0,e_1)),
1030
+ Vector frame (R^2, (n_0,n_1)): 2-indices components w.r.t.
1031
+ Vector frame (R^2, (n_0,n_1))}
1032
+ sage: a.comp(n)[:]
1033
+ [1/2*sqrt(3) -1/2]
1034
+ [ 1/2 1/2*sqrt(3)]
1035
+ sage: a1 = M.change_of_frame(n,e)
1036
+ sage: a1[:]
1037
+ [1/2*sqrt(3) 1/2]
1038
+ [ -1/2 1/2*sqrt(3)]
1039
+ sage: a1 == rot.inverse()
1040
+ True
1041
+ sage: a1 is rot.inverse()
1042
+ False
1043
+ sage: e[0].comp(n)[:]
1044
+ [1/2*sqrt(3), -1/2]
1045
+ sage: e[1].comp(n)[:]
1046
+ [1/2, 1/2*sqrt(3)]
1047
+ """
1048
+ the_new_frame = self.new_basis(change_of_frame, symbol,
1049
+ latex_symbol=latex_symbol,
1050
+ indices=indices,
1051
+ latex_indices=latex_indices,
1052
+ symbol_dual=symbol_dual,
1053
+ latex_symbol_dual=latex_symbol_dual)
1054
+ for sdom in self._domain.open_supersets():
1055
+ sdom._frame_changes[(self, the_new_frame)] = \
1056
+ self._fmodule._basis_changes[(self, the_new_frame)]
1057
+ sdom._frame_changes[(the_new_frame, self)] = \
1058
+ self._fmodule._basis_changes[(the_new_frame, self)]
1059
+ return the_new_frame
1060
+
1061
+ def restrict(self, subdomain):
1062
+ r"""
1063
+ Return the restriction of ``self`` to some open subset of its domain.
1064
+
1065
+ If the restriction has not been defined yet, it is constructed here.
1066
+
1067
+ INPUT:
1068
+
1069
+ - ``subdomain`` -- open subset `V` of the current frame domain `U`
1070
+
1071
+ OUTPUT: the restriction of the current frame to `V` as a :class:`VectorFrame`
1072
+
1073
+ EXAMPLES:
1074
+
1075
+ Restriction of a frame defined on `\RR^2` to the unit disk::
1076
+
1077
+ sage: M = Manifold(2, 'R^2', start_index=1)
1078
+ sage: c_cart.<x,y> = M.chart() # Cartesian coordinates on R^2
1079
+ sage: a = M.automorphism_field()
1080
+ sage: a[:] = [[1-y^2,0], [1+x^2, 2]]
1081
+ sage: e = c_cart.frame().new_frame(a, 'e') ; e
1082
+ Vector frame (R^2, (e_1,e_2))
1083
+ sage: U = M.open_subset('U', coord_def={c_cart: x^2+y^2<1})
1084
+ sage: e_U = e.restrict(U) ; e_U
1085
+ Vector frame (U, (e_1,e_2))
1086
+
1087
+ The vectors of the restriction have the same symbols as those of the
1088
+ original frame::
1089
+
1090
+ sage: e_U[1].display()
1091
+ e_1 = (-y^2 + 1) ∂/∂x + (x^2 + 1) ∂/∂y
1092
+ sage: e_U[2].display()
1093
+ e_2 = 2 ∂/∂y
1094
+
1095
+ They are actually the restrictions of the original frame vectors::
1096
+
1097
+ sage: e_U[1] is e[1].restrict(U)
1098
+ True
1099
+ sage: e_U[2] is e[2].restrict(U)
1100
+ True
1101
+ """
1102
+ if subdomain == self._domain:
1103
+ return self
1104
+ if subdomain not in self._restrictions:
1105
+ if not subdomain.is_subset(self._domain):
1106
+ raise ValueError("the provided domain is not a subdomain of " +
1107
+ "the current frame's domain")
1108
+ # First one tries to get the restriction from a tighter domain:
1109
+ for dom, rst in self._restrictions.items():
1110
+ if subdomain.is_subset(dom) and subdomain in rst._restrictions:
1111
+ res = rst._restrictions[subdomain]
1112
+ self._restrictions[subdomain] = res
1113
+ res._superframes.update(self._superframes)
1114
+ for sframe2 in self._superframes:
1115
+ sframe2._subframes.add(res)
1116
+ return self._restrictions[subdomain]
1117
+ # Secondly one tries to get the restriction from one previously
1118
+ # defined on a larger domain:
1119
+ for sframe in self._superframes:
1120
+ if subdomain in sframe._restrictions:
1121
+ res = sframe._restrictions[subdomain]
1122
+ self._restrictions[subdomain] = res
1123
+ res._superframes.update(self._superframes)
1124
+ for sframe2 in self._superframes:
1125
+ sframe2._subframes.add(res)
1126
+ return self._restrictions[subdomain]
1127
+ # If this point is reached, the restriction has to be created
1128
+ # from scratch
1129
+ sdest_map = self._dest_map.restrict(subdomain)
1130
+ resmodule = subdomain.vector_field_module(sdest_map,
1131
+ force_free=True)
1132
+ if subdomain in self._restrictions:
1133
+ # the restriction has been generated during the creation of
1134
+ # resmodule (which may happen if sdest_map is not trivial)
1135
+ return self._restrictions[subdomain]
1136
+ res = VectorFrame(resmodule,
1137
+ self._symbol, latex_symbol=self._latex_symbol,
1138
+ indices=self._indices,
1139
+ latex_indices=self._latex_indices,
1140
+ symbol_dual=self._symbol_dual,
1141
+ latex_symbol_dual=self._latex_symbol_dual)
1142
+
1143
+ res._from_frame = self._from_frame
1144
+
1145
+ for dom in subdomain.open_supersets():
1146
+ if dom is not subdomain:
1147
+ dom._top_frames.remove(res) # since it was added by
1148
+ # VectorFrame constructor
1149
+ new_vectors = list()
1150
+ for i in self._fmodule.irange():
1151
+ vrest = self[i].restrict(subdomain)
1152
+ for j in self._fmodule.irange():
1153
+ vrest.add_comp(res)[j] = 0
1154
+ vrest.add_comp(res)[i] = 1
1155
+ new_vectors.append(vrest)
1156
+ res._vec = tuple(new_vectors)
1157
+ # Update of superframes and subframes:
1158
+ for sframe in self._subframes:
1159
+ if subdomain.is_subset(sframe.domain()):
1160
+ res._superframes.update(sframe._superframes)
1161
+ for sframe in res._superframes:
1162
+ sframe._subframes.add(res)
1163
+ sframe._restrictions[subdomain] = res # includes sframe = self
1164
+ for dom, rst in self._restrictions.items():
1165
+ if dom.is_subset(subdomain):
1166
+ res._restrictions.update(rst._restrictions)
1167
+ res._subframes.update(rst._subframes)
1168
+ rst._superframes.update(res._superframes)
1169
+
1170
+ return self._restrictions[subdomain]
1171
+
1172
+ @cached_method
1173
+ def structure_coeff(self):
1174
+ r"""
1175
+ Evaluate the structure coefficients associated to ``self``.
1176
+
1177
+ `n` being the manifold's dimension, the structure coefficients of the
1178
+ vector frame `(e_i)` are the `n^3` scalar fields `C^k_{\ \, ij}`
1179
+ defined by
1180
+
1181
+ .. MATH::
1182
+
1183
+ [e_i, e_j] = C^k_{\ \, ij} e_k
1184
+
1185
+ OUTPUT:
1186
+
1187
+ - the structure coefficients `C^k_{\ \, ij}`, as an instance of
1188
+ :class:`~sage.tensor.modules.comp.CompWithSym`
1189
+ with 3 indices ordered as `(k,i,j)`.
1190
+
1191
+ EXAMPLES:
1192
+
1193
+ Structure coefficients of the orthonormal frame associated to
1194
+ spherical coordinates in the Euclidean space `\RR^3`::
1195
+
1196
+ sage: M = Manifold(3, 'R^3', r'\RR^3', start_index=1) # Part of R^3 covered by spherical coordinates
1197
+ sage: c_spher.<r,th,ph> = M.chart(r'r:(0,+oo) th:(0,pi):\theta ph:(0,2*pi):\phi')
1198
+ sage: ch_frame = M.automorphism_field()
1199
+ sage: ch_frame[1,1], ch_frame[2,2], ch_frame[3,3] = 1, 1/r, 1/(r*sin(th))
1200
+ sage: M.frames()
1201
+ [Coordinate frame (R^3, (∂/∂r,∂/∂th,∂/∂ph))]
1202
+ sage: e = c_spher.frame().new_frame(ch_frame, 'e')
1203
+ sage: e[1][:] # components of e_1 in the manifold's default frame (∂/∂r, ∂/∂th, ∂/∂th)
1204
+ [1, 0, 0]
1205
+ sage: e[2][:]
1206
+ [0, 1/r, 0]
1207
+ sage: e[3][:]
1208
+ [0, 0, 1/(r*sin(th))]
1209
+ sage: c = e.structure_coeff() ; c
1210
+ 3-indices components w.r.t. Vector frame (R^3, (e_1,e_2,e_3)), with
1211
+ antisymmetry on the index positions (1, 2)
1212
+ sage: c[:]
1213
+ [[[0, 0, 0], [0, 0, 0], [0, 0, 0]],
1214
+ [[0, -1/r, 0], [1/r, 0, 0], [0, 0, 0]],
1215
+ [[0, 0, -1/r], [0, 0, -cos(th)/(r*sin(th))], [1/r, cos(th)/(r*sin(th)), 0]]]
1216
+ sage: c[2,1,2] # C^2_{12}
1217
+ -1/r
1218
+ sage: c[3,1,3] # C^3_{13}
1219
+ -1/r
1220
+ sage: c[3,2,3] # C^3_{23}
1221
+ -cos(th)/(r*sin(th))
1222
+ """
1223
+ from sage.tensor.modules.comp import CompWithSym
1224
+
1225
+ fmodule = self._fmodule
1226
+ structure_coeff = CompWithSym(self._fmodule._ring, self, 3,
1227
+ start_index=fmodule._sindex,
1228
+ output_formatter=fmodule._output_formatter,
1229
+ antisym=(1,2))
1230
+ si = fmodule._sindex
1231
+ nsi = si + fmodule.rank()
1232
+ for k in range(si, nsi):
1233
+ ce_k = self._coframe._vec[k-si]
1234
+ for i in range(si, nsi):
1235
+ e_i = self._vec[i-si]
1236
+ for j in range(i+1, nsi):
1237
+ e_j = self._vec[j-si]
1238
+ structure_coeff[[k,i,j]] = ce_k(e_j.lie_der(e_i))
1239
+ return structure_coeff
1240
+
1241
+ def along(self, mapping):
1242
+ r"""
1243
+ Return the vector frame deduced from the current frame via a
1244
+ differentiable map, the codomain of which is included in the domain of
1245
+ of the current frame.
1246
+
1247
+ If `e` is the current vector frame, `V` its domain and if
1248
+ `\Phi: U \rightarrow V` is a differentiable map from some
1249
+ differentiable manifold `U` to `V`, the returned object is
1250
+ a vector frame `\tilde e` along `U` with values on `V` such that
1251
+
1252
+ .. MATH::
1253
+
1254
+ \forall p \in U,\ \tilde e(p) = e(\Phi(p)).
1255
+
1256
+ INPUT:
1257
+
1258
+ - ``mapping`` -- differentiable map `\Phi: U \rightarrow V`
1259
+
1260
+ OUTPUT: vector frame `\tilde e` along `U` defined above
1261
+
1262
+ EXAMPLES:
1263
+
1264
+ Vector frame along a curve::
1265
+
1266
+ sage: M = Manifold(2, 'M')
1267
+ sage: X.<x,y> = M.chart()
1268
+ sage: R = Manifold(1, 'R') # R as a 1-dimensional manifold
1269
+ sage: T.<t> = R.chart() # canonical chart on R
1270
+ sage: Phi = R.diff_map(M, {(T,X): [cos(t), t]}, name='Phi',
1271
+ ....: latex_name=r'\Phi') ; Phi
1272
+ Differentiable map Phi from the 1-dimensional differentiable
1273
+ manifold R to the 2-dimensional differentiable manifold M
1274
+ sage: e = X.frame() ; e
1275
+ Coordinate frame (M, (∂/∂x,∂/∂y))
1276
+ sage: te = e.along(Phi) ; te
1277
+ Vector frame (R, (∂/∂x,∂/∂y)) with values on the 2-dimensional
1278
+ differentiable manifold M
1279
+
1280
+ Check of the formula `\tilde e(p) = e(\Phi(p))`::
1281
+
1282
+ sage: p = R((pi,)) ; p
1283
+ Point on the 1-dimensional differentiable manifold R
1284
+ sage: te[0].at(p) == e[0].at(Phi(p))
1285
+ True
1286
+ sage: te[1].at(p) == e[1].at(Phi(p))
1287
+ True
1288
+
1289
+ The result is cached::
1290
+
1291
+ sage: te is e.along(Phi)
1292
+ True
1293
+ """
1294
+ dom = self._domain
1295
+ if mapping.codomain().is_subset(dom):
1296
+ rmapping = mapping
1297
+ else:
1298
+ rmapping = None
1299
+ for doms, rest in mapping._restrictions.items():
1300
+ if doms[1].is_subset(dom):
1301
+ rmapping = rest
1302
+ break
1303
+ else:
1304
+ raise ValueError("the codomain of {} is not ".format(mapping) +
1305
+ " included in the domain of {}".format(self))
1306
+ vmodule = rmapping.domain().vector_field_module(dest_map=rmapping)
1307
+ return vmodule.basis(from_frame=self)
1308
+
1309
+ def at(self, point):
1310
+ r"""
1311
+ Return the value of ``self`` at a given point, this value being
1312
+ a basis of the tangent vector space at the point.
1313
+
1314
+ INPUT:
1315
+
1316
+ - ``point`` -- :class:`~sage.manifolds.point.ManifoldPoint`; point
1317
+ `p` in the domain `U` of the vector frame (denoted `e` hereafter)
1318
+
1319
+ OUTPUT:
1320
+
1321
+ - :class:`~sage.tensor.modules.free_module_basis.FreeModuleBasis`
1322
+ representing the basis `e(p)` of the tangent vector space
1323
+ `T_{\Phi(p)} M`, where `\Phi: U \to M` is the differentiable map
1324
+ associated with `e` (possibly `\Phi = \mathrm{Id}_U`)
1325
+
1326
+ EXAMPLES:
1327
+
1328
+ Basis of a tangent space to a 2-dimensional manifold::
1329
+
1330
+ sage: M = Manifold(2, 'M')
1331
+ sage: X.<x,y> = M.chart()
1332
+ sage: p = M.point((-1,2), name='p')
1333
+ sage: e = X.frame() ; e
1334
+ Coordinate frame (M, (∂/∂x,∂/∂y))
1335
+ sage: ep = e.at(p) ; ep
1336
+ Basis (∂/∂x,∂/∂y) on the Tangent space at Point p on the
1337
+ 2-dimensional differentiable manifold M
1338
+ sage: type(ep)
1339
+ <class 'sage.tensor.modules.free_module_basis.FreeModuleBasis_with_category'>
1340
+ sage: ep[0]
1341
+ Tangent vector ∂/∂x at Point p on the 2-dimensional differentiable
1342
+ manifold M
1343
+ sage: ep[1]
1344
+ Tangent vector ∂/∂y at Point p on the 2-dimensional differentiable
1345
+ manifold M
1346
+
1347
+ Note that the symbols used to denote the vectors are same as those
1348
+ for the vector fields of the frame. At this stage, ``ep`` is the unique
1349
+ basis on the tangent space at ``p``::
1350
+
1351
+ sage: Tp = M.tangent_space(p)
1352
+ sage: Tp.bases()
1353
+ [Basis (∂/∂x,∂/∂y) on the Tangent space at Point p on the
1354
+ 2-dimensional differentiable manifold M]
1355
+
1356
+ Let us consider a vector frame that is a not a coordinate one::
1357
+
1358
+ sage: aut = M.automorphism_field()
1359
+ sage: aut[:] = [[1+y^2, 0], [0, 2]]
1360
+ sage: f = e.new_frame(aut, 'f') ; f
1361
+ Vector frame (M, (f_0,f_1))
1362
+ sage: fp = f.at(p) ; fp
1363
+ Basis (f_0,f_1) on the Tangent space at Point p on the
1364
+ 2-dimensional differentiable manifold M
1365
+
1366
+ There are now two bases on the tangent space::
1367
+
1368
+ sage: Tp.bases()
1369
+ [Basis (∂/∂x,∂/∂y) on the Tangent space at Point p on the
1370
+ 2-dimensional differentiable manifold M,
1371
+ Basis (f_0,f_1) on the Tangent space at Point p on the
1372
+ 2-dimensional differentiable manifold M]
1373
+
1374
+ Moreover, the changes of bases in the tangent space have been
1375
+ computed from the known relation between the frames ``e`` and
1376
+ ``f`` (field of automorphisms ``aut`` defined above)::
1377
+
1378
+ sage: Tp.change_of_basis(ep, fp)
1379
+ Automorphism of the Tangent space at Point p on the 2-dimensional
1380
+ differentiable manifold M
1381
+ sage: Tp.change_of_basis(ep, fp).display()
1382
+ 5 ∂/∂x⊗dx + 2 ∂/∂y⊗dy
1383
+ sage: Tp.change_of_basis(fp, ep)
1384
+ Automorphism of the Tangent space at Point p on the 2-dimensional
1385
+ differentiable manifold M
1386
+ sage: Tp.change_of_basis(fp, ep).display()
1387
+ 1/5 ∂/∂x⊗dx + 1/2 ∂/∂y⊗dy
1388
+
1389
+ The dual bases::
1390
+
1391
+ sage: e.coframe()
1392
+ Coordinate coframe (M, (dx,dy))
1393
+ sage: ep.dual_basis()
1394
+ Dual basis (dx,dy) on the Tangent space at Point p on the
1395
+ 2-dimensional differentiable manifold M
1396
+ sage: ep.dual_basis() is e.coframe().at(p)
1397
+ True
1398
+ sage: f.coframe()
1399
+ Coframe (M, (f^0,f^1))
1400
+ sage: fp.dual_basis()
1401
+ Dual basis (f^0,f^1) on the Tangent space at Point p on the
1402
+ 2-dimensional differentiable manifold M
1403
+ sage: fp.dual_basis() is f.coframe().at(p)
1404
+ True
1405
+ """
1406
+ # Case of a non-trivial destination map
1407
+ if self._from_frame is not None:
1408
+ if self._dest_map.is_identity(): # ! # probably not necessary
1409
+ raise ValueError("the destination map should not be the identity")
1410
+ ambient_point = self._dest_map(point)
1411
+ return self._from_frame.at(ambient_point)
1412
+
1413
+ # Determination of the tangent space:
1414
+ if point not in self._domain:
1415
+ raise ValueError("the {} is not a point in the ".format(point) +
1416
+ "domain of {}".format(self))
1417
+
1418
+ if self._dest_map.is_identity():
1419
+ ambient_point = point
1420
+ else:
1421
+ ambient_point = self._dest_map(point)
1422
+ ts = ambient_point._manifold.tangent_space(ambient_point)
1423
+
1424
+ # If the basis has already been constructed, it is simply returned:
1425
+ ts_frame_bases = ts._frame_bases
1426
+ if self in ts_frame_bases:
1427
+ return ts_frame_bases[self]
1428
+ for frame in ts_frame_bases:
1429
+ if self in frame._subframes or self in frame._superframes:
1430
+ return ts_frame_bases[frame]
1431
+
1432
+ # If this point is reached, the basis has to be constructed from
1433
+ # scratch.
1434
+ # The names of the basis vectors set to those of the frame vector
1435
+ # fields:
1436
+ basis = ts.basis(self._symbol, latex_symbol=self._latex_symbol,
1437
+ indices=self._indices,
1438
+ latex_indices=self._latex_indices,
1439
+ symbol_dual=self._symbol_dual,
1440
+ latex_symbol_dual=self._latex_symbol_dual)
1441
+ ts_frame_bases[self] = basis
1442
+ # Update of the change of bases in the tangent space:
1443
+ for frame_pair, automorph in self._domain._frame_changes.items():
1444
+ frame1 = frame_pair[0]
1445
+ frame2 = frame_pair[1]
1446
+ if frame1 is self:
1447
+ fr2 = None
1448
+ for frame in ts_frame_bases:
1449
+ if frame2 in frame._subframes:
1450
+ fr2 = frame
1451
+ break
1452
+ if fr2 is not None:
1453
+ basis1 = basis
1454
+ basis2 = ts_frame_bases[fr2]
1455
+ auto = ts.automorphism()
1456
+ for frame, comp in automorph._components.items():
1457
+ bas = None
1458
+ if frame is frame1:
1459
+ bas = basis1
1460
+ if frame is frame2:
1461
+ bas = basis2
1462
+ if bas is not None:
1463
+ cauto = auto.add_comp(bas)
1464
+ for ind, val in comp._comp.items():
1465
+ cauto._comp[ind] = val(point)
1466
+ ts._basis_changes[(basis1, basis2)] = auto
1467
+ if frame2 is self:
1468
+ fr1 = None
1469
+ for frame in ts_frame_bases:
1470
+ if frame1 in frame._subframes:
1471
+ fr1 = frame
1472
+ break
1473
+ if fr1 is not None:
1474
+ basis1 = ts_frame_bases[fr1]
1475
+ basis2 = basis
1476
+ auto = ts.automorphism()
1477
+ for frame, comp in automorph._components.items():
1478
+ bas = None
1479
+ if frame is frame1:
1480
+ bas = basis1
1481
+ if frame is frame2:
1482
+ bas = basis2
1483
+ if bas is not None:
1484
+ cauto = auto.add_comp(bas)
1485
+ for ind, val in comp._comp.items():
1486
+ cauto._comp[ind] = val(point)
1487
+ ts._basis_changes[(basis1, basis2)] = auto
1488
+ return basis
1489
+
1490
+ def set_name(self, symbol, latex_symbol=None, indices=None,
1491
+ latex_indices=None, index_position='down',
1492
+ include_domain=True):
1493
+ r"""
1494
+ Set (or change) the text name and LaTeX name of ``self``.
1495
+
1496
+ INPUT:
1497
+
1498
+ - ``symbol`` -- either a string, to be used as a common base for the
1499
+ symbols of the vector fields constituting the vector frame, or a
1500
+ list/tuple of strings, representing the individual symbols of the
1501
+ vector fields
1502
+ - ``latex_symbol`` -- (default: ``None``) either a string, to be used
1503
+ as a common base for the LaTeX symbols of the vector fields
1504
+ constituting the vector frame, or a list/tuple of strings,
1505
+ representing the individual LaTeX symbols of the vector fields;
1506
+ if ``None``, ``symbol`` is used in place of ``latex_symbol``
1507
+ - ``indices`` -- (default: ``None``; used only if ``symbol`` is a
1508
+ single string) tuple of strings representing the indices labelling
1509
+ the vector fields of the frame; if ``None``, the indices will be
1510
+ generated as integers within the range declared on ``self``
1511
+ - ``latex_indices`` -- (default: ``None``) tuple of strings
1512
+ representing the indices for the LaTeX symbols of the vector fields;
1513
+ if ``None``, ``indices`` is used instead
1514
+ - ``index_position`` -- (default: ``'down'``) determines the position
1515
+ of the indices labelling the vector fields of the frame; can be
1516
+ either ``'down'`` or ``'up'``
1517
+ - ``include_domain`` -- boolean (default: ``True``); determining whether
1518
+ the name of the domain is included in the beginning of the vector
1519
+ frame name
1520
+
1521
+ EXAMPLES::
1522
+
1523
+ sage: M = Manifold(2, 'M')
1524
+ sage: e = M.vector_frame('e'); e
1525
+ Vector frame (M, (e_0,e_1))
1526
+ sage: e.set_name('f'); e
1527
+ Vector frame (M, (f_0,f_1))
1528
+ sage: e.set_name('e', include_domain=False); e
1529
+ Vector frame (e_0,e_1)
1530
+ sage: e.set_name(['a', 'b']); e
1531
+ Vector frame (M, (a,b))
1532
+ sage: e.set_name('e', indices=['x', 'y']); e
1533
+ Vector frame (M, (e_x,e_y))
1534
+ sage: e.set_name('e', latex_symbol=r'\epsilon')
1535
+ sage: latex(e)
1536
+ \left(M, \left(\epsilon_{0},\epsilon_{1}\right)\right)
1537
+ sage: e.set_name('e', latex_symbol=[r'\alpha', r'\beta'])
1538
+ sage: latex(e)
1539
+ \left(M, \left(\alpha,\beta\right)\right)
1540
+ sage: e.set_name('e', latex_symbol='E',
1541
+ ....: latex_indices=[r'\alpha', r'\beta'])
1542
+ sage: latex(e)
1543
+ \left(M, \left(E_{\alpha},E_{\beta}\right)\right)
1544
+ """
1545
+ super().set_name(symbol, latex_symbol=latex_symbol,
1546
+ indices=indices,
1547
+ latex_indices=latex_indices,
1548
+ index_position=index_position)
1549
+ if include_domain:
1550
+ # Redefinition of the name and the LaTeX name to include the domain
1551
+ self._name = "({}, {})".format(self._domain._name, self._name)
1552
+ self._latex_name = r"\left({}, {}\right)".format(
1553
+ self._domain._latex_name, self._latex_name)
1554
+
1555
+ #******************************************************************************
1556
+
1557
+
1558
+ class CoordCoFrame(CoFrame):
1559
+ r"""
1560
+ Coordinate coframe on a differentiable manifold.
1561
+
1562
+ By *coordinate coframe*, it is meant the `n`-tuple of the
1563
+ differentials of the coordinates of some chart on the manifold,
1564
+ with `n` being the manifold's dimension.
1565
+
1566
+ INPUT:
1567
+
1568
+ - ``coord_frame`` -- coordinate frame dual to the coordinate coframe
1569
+ - ``symbol`` -- either a string, to be used as a common base for the
1570
+ symbols of the 1-forms constituting the coframe, or a tuple of strings,
1571
+ representing the individual symbols of the 1-forms
1572
+ - ``latex_symbol`` -- (default: ``None``) either a string, to be used
1573
+ as a common base for the LaTeX symbols of the 1-forms constituting the
1574
+ coframe, or a tuple of strings, representing the individual LaTeX symbols
1575
+ of the 1-forms; if ``None``, ``symbol`` is used in place of
1576
+ ``latex_symbol``
1577
+ - ``indices`` -- (default: ``None``; used only if ``symbol`` is a single
1578
+ string) tuple of strings representing the indices labelling the 1-forms
1579
+ of the coframe; if ``None``, the indices will be generated as
1580
+ integers within the range declared on the vector frame's domain
1581
+ - ``latex_indices`` -- (default: ``None``) tuple of strings representing
1582
+ the indices for the LaTeX symbols of the 1-forms of the coframe; if
1583
+ ``None``, ``indices`` is used instead
1584
+
1585
+ EXAMPLES:
1586
+
1587
+ Coordinate coframe on a 3-dimensional manifold::
1588
+
1589
+ sage: M = Manifold(3, 'M', start_index=1)
1590
+ sage: X.<x,y,z> = M.chart()
1591
+ sage: M.frames()
1592
+ [Coordinate frame (M, (∂/∂x,∂/∂y,∂/∂z))]
1593
+ sage: M.coframes()
1594
+ [Coordinate coframe (M, (dx,dy,dz))]
1595
+ sage: dX = M.coframes()[0] ; dX
1596
+ Coordinate coframe (M, (dx,dy,dz))
1597
+
1598
+ The 1-forms composing the coframe are obtained via the operator ``[]``::
1599
+
1600
+ sage: dX[1]
1601
+ 1-form dx on the 3-dimensional differentiable manifold M
1602
+ sage: dX[2]
1603
+ 1-form dy on the 3-dimensional differentiable manifold M
1604
+ sage: dX[3]
1605
+ 1-form dz on the 3-dimensional differentiable manifold M
1606
+ sage: dX[1][:]
1607
+ [1, 0, 0]
1608
+ sage: dX[2][:]
1609
+ [0, 1, 0]
1610
+ sage: dX[3][:]
1611
+ [0, 0, 1]
1612
+
1613
+ The coframe is the dual of the coordinate frame::
1614
+
1615
+ sage: e = X.frame() ; e
1616
+ Coordinate frame (M, (∂/∂x,∂/∂y,∂/∂z))
1617
+ sage: dX[1](e[1]).expr(), dX[1](e[2]).expr(), dX[1](e[3]).expr()
1618
+ (1, 0, 0)
1619
+ sage: dX[2](e[1]).expr(), dX[2](e[2]).expr(), dX[2](e[3]).expr()
1620
+ (0, 1, 0)
1621
+ sage: dX[3](e[1]).expr(), dX[3](e[2]).expr(), dX[3](e[3]).expr()
1622
+ (0, 0, 1)
1623
+
1624
+ Each 1-form of a coordinate coframe is closed::
1625
+
1626
+ sage: dX[1].exterior_derivative()
1627
+ 2-form ddx on the 3-dimensional differentiable manifold M
1628
+ sage: dX[1].exterior_derivative() == 0
1629
+ True
1630
+ """
1631
+ def __init__(self, coord_frame, symbol, latex_symbol=None, indices=None,
1632
+ latex_indices=None):
1633
+ r"""
1634
+ Construct a coordinate coframe.
1635
+
1636
+ TESTS::
1637
+
1638
+ sage: M = Manifold(2, 'M')
1639
+ sage: X.<x,y> = M.chart()
1640
+ sage: from sage.manifolds.differentiable.vectorframe import CoordCoFrame
1641
+ sage: f = CoordCoFrame(X.frame(), 'omega'); f
1642
+ Coordinate coframe (M, (omega^0,omega^1))
1643
+ sage: TestSuite(f).run()
1644
+ """
1645
+ if not isinstance(coord_frame, CoordFrame):
1646
+ raise TypeError("the first argument must be a coordinate frame")
1647
+ CoFrame.__init__(self, coord_frame, symbol, latex_symbol=latex_symbol,
1648
+ indices=indices, latex_indices=latex_indices)
1649
+ self._chart = coord_frame._chart
1650
+
1651
+ def _repr_(self):
1652
+ r"""
1653
+ String representation of ``self``.
1654
+
1655
+ TESTS::
1656
+
1657
+ sage: M = Manifold(2, 'M')
1658
+ sage: X.<x,y> = M.chart()
1659
+ sage: f = X.frame().coframe()
1660
+ sage: f._repr_()
1661
+ 'Coordinate coframe (M, (dx,dy))'
1662
+ sage: repr(f) # indirect doctest
1663
+ 'Coordinate coframe (M, (dx,dy))'
1664
+ sage: f # indirect doctest
1665
+ Coordinate coframe (M, (dx,dy))
1666
+ """
1667
+ return "Coordinate coframe " + self._name
1668
+
1669
+ #******************************************************************************
1670
+
1671
+
1672
+ class CoordFrame(VectorFrame):
1673
+ r"""
1674
+ Coordinate frame on a differentiable manifold.
1675
+
1676
+ By *coordinate frame*, it is meant a vector frame on a differentiable
1677
+ manifold `M` that is associated to a coordinate chart on `M`.
1678
+
1679
+ INPUT:
1680
+
1681
+ - ``chart`` -- the chart defining the coordinates
1682
+
1683
+ EXAMPLES:
1684
+
1685
+ The coordinate frame associated to spherical coordinates of the
1686
+ sphere `S^2`::
1687
+
1688
+ sage: M = Manifold(2, 'S^2', start_index=1) # Part of S^2 covered by spherical coord.
1689
+ sage: M.chart(r'th:[0,pi]:\theta ph:[0,2*pi):\phi')
1690
+ Chart (S^2, (th, ph))
1691
+ sage: b = M.default_frame()
1692
+ sage: b
1693
+ Coordinate frame (S^2, (∂/∂th,∂/∂ph))
1694
+ sage: b[1]
1695
+ Vector field ∂/∂th on the 2-dimensional differentiable manifold S^2
1696
+ sage: b[2]
1697
+ Vector field ∂/∂ph on the 2-dimensional differentiable manifold S^2
1698
+ sage: latex(b)
1699
+ \left(S^2, \left(\frac{\partial}{\partial {\theta} },\frac{\partial}{\partial {\phi} }\right)\right)
1700
+ """
1701
+
1702
+ # The following class attribute must be redefined by any derived class:
1703
+ _cobasis_class = CoordCoFrame
1704
+
1705
+ def __init__(self, chart):
1706
+ r"""
1707
+ Construct a coordinate frame.
1708
+
1709
+ TESTS::
1710
+
1711
+ sage: M = Manifold(2, 'M')
1712
+ sage: X.<x,y> = M.chart()
1713
+ sage: from sage.manifolds.differentiable.vectorframe import CoordFrame
1714
+ sage: e = CoordFrame(X); e
1715
+ Coordinate frame (M, (∂/∂x,∂/∂y))
1716
+ sage: TestSuite(e).run()
1717
+ """
1718
+ from sage.manifolds.differentiable.chart import DiffChart
1719
+ from sage.misc.latex import latex
1720
+ from sage.typeset.unicode_characters import unicode_partial
1721
+ if not isinstance(chart, DiffChart):
1722
+ raise TypeError("the first argument must be a chart")
1723
+ dom = chart.domain()
1724
+ # Some sanity check:
1725
+ vmodule = dom._vector_field_modules.get(dom.identity_map())
1726
+ if vmodule and not isinstance(vmodule, FiniteRankFreeModule):
1727
+ raise ValueError("the {} has already been constructed as a "
1728
+ "non-free module, which implies that the {} is "
1729
+ "not parallelizable and hence cannot be the "
1730
+ "domain of a coordinate chart".format(vmodule,
1731
+ dom))
1732
+ self._chart = chart
1733
+ coords = chart[:] # list of all coordinates
1734
+ symbol = tuple(f"{unicode_partial}/{unicode_partial}{x!s}"
1735
+ for x in coords)
1736
+ latex_symbol = tuple(r"\frac{\partial}{\partial" + latex(x) + "}"
1737
+ for x in coords)
1738
+ symbol_dual = tuple("d" + str(x) for x in coords)
1739
+ latex_symbol_dual = tuple(r"\mathrm{d}" + latex(x) for x in coords)
1740
+ VectorFrame.__init__(self,
1741
+ dom.vector_field_module(force_free=True),
1742
+ symbol=symbol, latex_symbol=latex_symbol,
1743
+ symbol_dual=symbol_dual,
1744
+ latex_symbol_dual=latex_symbol_dual)
1745
+ # In the above:
1746
+ # - force_free=True ensures that a free module is constructed in case
1747
+ # it is the first call to the vector field module on chart.domain()
1748
+
1749
+ ###### Methods that must be redefined by derived classes of ######
1750
+ ###### FreeModuleBasis ######
1751
+
1752
+ def _repr_(self):
1753
+ r"""
1754
+ String representation of ``self``.
1755
+
1756
+ TESTS::
1757
+
1758
+ sage: M = Manifold(2, 'M')
1759
+ sage: X.<x,y> = M.chart()
1760
+ sage: e = X.frame()
1761
+ sage: e._repr_()
1762
+ 'Coordinate frame (M, (∂/∂x,∂/∂y))'
1763
+ sage: repr(e) # indirect doctest
1764
+ 'Coordinate frame (M, (∂/∂x,∂/∂y))'
1765
+ sage: e # indirect doctest
1766
+ Coordinate frame (M, (∂/∂x,∂/∂y))
1767
+ """
1768
+ return "Coordinate frame " + self._name
1769
+
1770
+ ###### End of methods redefined by derived classes ######
1771
+
1772
+ def chart(self):
1773
+ r"""
1774
+ Return the chart defining this coordinate frame.
1775
+
1776
+ EXAMPLES::
1777
+
1778
+ sage: M = Manifold(2, 'M')
1779
+ sage: X.<x,y> = M.chart()
1780
+ sage: e = X.frame()
1781
+ sage: e.chart()
1782
+ Chart (M, (x, y))
1783
+ sage: U = M.open_subset('U', coord_def={X: x>0})
1784
+ sage: e.restrict(U).chart()
1785
+ Chart (U, (x, y))
1786
+ """
1787
+ return self._chart
1788
+
1789
+ @cached_method
1790
+ def structure_coeff(self):
1791
+ r"""
1792
+ Return the structure coefficients associated to ``self``.
1793
+
1794
+ `n` being the manifold's dimension, the structure coefficients
1795
+ of the frame `(e_i)` are the `n^3` scalar fields `C^k_{\ \, ij}`
1796
+ defined by
1797
+
1798
+ .. MATH::
1799
+
1800
+ [e_i, e_j] = C^k_{\ \, ij} e_k.
1801
+
1802
+ In the present case, since `(e_i)` is a coordinate frame,
1803
+ `C^k_{\ \, ij}=0`.
1804
+
1805
+ OUTPUT:
1806
+
1807
+ - the structure coefficients `C^k_{\ \, ij}`, as a vanishing instance
1808
+ of :class:`~sage.tensor.modules.comp.CompWithSym` with 3 indices
1809
+ ordered as `(k,i,j)`
1810
+
1811
+ EXAMPLES:
1812
+
1813
+ Structure coefficients of the coordinate frame associated to
1814
+ spherical coordinates in the Euclidean space `\RR^3`::
1815
+
1816
+ sage: M = Manifold(3, 'R^3', r'\RR^3', start_index=1) # Part of R^3 covered by spherical coord.
1817
+ sage: c_spher = M.chart(r'r:(0,+oo) th:(0,pi):\theta ph:(0,2*pi):\phi')
1818
+ sage: b = M.default_frame() ; b
1819
+ Coordinate frame (R^3, (∂/∂r,∂/∂th,∂/∂ph))
1820
+ sage: c = b.structure_coeff() ; c
1821
+ 3-indices components w.r.t. Coordinate frame
1822
+ (R^3, (∂/∂r,∂/∂th,∂/∂ph)), with antisymmetry on the index
1823
+ positions (1, 2)
1824
+ sage: c == 0
1825
+ True
1826
+ """
1827
+ from sage.tensor.modules.comp import CompWithSym
1828
+ # A zero CompWithSym
1829
+ return CompWithSym(self._fmodule._ring, self, 3,
1830
+ start_index=self._fmodule._sindex,
1831
+ output_formatter=self._fmodule._output_formatter,
1832
+ antisym=(1,2))