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,841 @@
1
+ # sage_setup: distribution = sagemath-symbolics
2
+ r"""
3
+ Levi-Civita Connections
4
+
5
+ The class :class:`LeviCivitaConnection` implements the Levi-Civita
6
+ connection associated with some pseudo-Riemannian metric on a smooth
7
+ manifold.
8
+
9
+ AUTHORS:
10
+
11
+ - Eric Gourgoulhon, Michal Bejger (2013-2015) : initial version
12
+ - Marco Mancini (2015) : parallelization of some computations
13
+ - Marius Gerbershagen (2022) : use the first Bianchi identity in the
14
+ computation of the Riemann tensor
15
+
16
+ REFERENCES:
17
+
18
+ - [KN1963]_
19
+ - [Lee1997]_
20
+ - [ONe1983]_
21
+ """
22
+ #******************************************************************************
23
+ # Copyright (C) 2015 Eric Gourgoulhon <eric.gourgoulhon@obspm.fr>
24
+ # Copyright (C) 2015 Michal Bejger <bejger@camk.edu.pl>
25
+ # Copyright (C) 2015 Marco Mancini <marco.mancini@obspm.fr>
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
+ # http://www.gnu.org/licenses/
31
+ #******************************************************************************
32
+
33
+ from sage.manifolds.differentiable.affine_connection import AffineConnection
34
+ from sage.manifolds.differentiable.vectorframe import CoordFrame
35
+ from sage.parallel.decorate import parallel
36
+ from sage.parallel.parallelism import Parallelism
37
+
38
+
39
+ class LeviCivitaConnection(AffineConnection):
40
+ r"""
41
+ Levi-Civita connection on a pseudo-Riemannian manifold.
42
+
43
+ Let `M` be a differentiable manifold of class `C^\infty` (smooth manifold)
44
+ over `\RR` endowed with a pseudo-Riemannian metric `g`.
45
+ Let `C^\infty(M)` be the algebra of smooth functions
46
+ `M\rightarrow \RR` (cf.
47
+ :class:`~sage.manifolds.differentiable.scalarfield_algebra.DiffScalarFieldAlgebra`)
48
+ and let `\mathfrak{X}(M)` be the `C^\infty(M)`-module of vector fields on
49
+ `M` (cf.
50
+ :class:`~sage.manifolds.differentiable.vectorfield_module.VectorFieldModule`).
51
+ The *Levi-Civita connection associated with* `g` is the unique operator
52
+
53
+ .. MATH::
54
+
55
+ \begin{array}{cccc}
56
+ \nabla: & \mathfrak{X}(M)\times \mathfrak{X}(M) & \longrightarrow &
57
+ \mathfrak{X}(M) \\
58
+ & (u,v) & \longmapsto & \nabla_u v
59
+ \end{array}
60
+
61
+ that
62
+
63
+ - is `\RR`-bilinear, i.e. is bilinear when considering `\mathfrak{X}(M)` as
64
+ a vector space over `\RR`
65
+ - is `C^\infty(M)`-linear w.r.t. the first argument:
66
+ `\forall f\in C^\infty(M),\ \nabla_{fu} v = f\nabla_u v`
67
+ - obeys Leibniz rule w.r.t. the second argument:
68
+ `\forall f\in C^\infty(M),\ \nabla_u (f v) = \mathrm{d}f(u)\, v + f \nabla_u v`
69
+ - is torsion-free
70
+ - is compatible with `g`:
71
+ `\forall (u,v,w)\in \mathfrak{X}(M)^3,\ u(g(v,w)) = g(\nabla_u v, w) + g(v, \nabla_u w)`
72
+
73
+ The Levi-Civita connection `\nabla` gives birth to the *covariant derivative
74
+ operator* acting on tensor fields, denoted by the same symbol:
75
+
76
+ .. MATH::
77
+
78
+ \begin{array}{cccc}
79
+ \nabla: & T^{(k,l)}(M) & \longrightarrow & T^{(k,l+1)}(M)\\
80
+ & t & \longmapsto & \nabla t
81
+ \end{array}
82
+
83
+ where `T^{(k,l)}(M)` stands for the `C^\infty(M)`-module of tensor fields
84
+ of type `(k,l)` on `M` (cf.
85
+ :class:`~sage.manifolds.differentiable.tensorfield_module.TensorFieldModule`),
86
+ with the convention `T^{(0,0)}(M):=C^\infty(M)`.
87
+ For a vector field `v`, the covariant derivative `\nabla v` is a
88
+ type-(1,1) tensor field such that
89
+
90
+ .. MATH::
91
+
92
+ \forall u \in\mathfrak{X}(M), \ \nabla_u v = \nabla v(., u)
93
+
94
+ More generally for any tensor field `t\in T^{(k,l)}(M)`, we have
95
+
96
+ .. MATH::
97
+
98
+ \forall u \in\mathfrak{X}(M), \ \nabla_u t = \nabla t(\ldots, u)
99
+
100
+
101
+ .. NOTE::
102
+
103
+ The above convention means that, in terms of index notation,
104
+ the "derivation index" in `\nabla t` is the *last* one:
105
+
106
+ .. MATH::
107
+
108
+ \nabla_c t^{a_1\ldots a_k}_{\quad\quad b_1\ldots b_l} =
109
+ (\nabla t)^{a_1\ldots a_k}_{\quad\quad b_1\ldots b_l c}
110
+
111
+
112
+ INPUT:
113
+
114
+ - ``metric`` -- the metric `g` defining the Levi-Civita connection, as an
115
+ instance of class
116
+ :class:`~sage.manifolds.differentiable.metric.PseudoRiemannianMetric`
117
+ - ``name`` -- name given to the connection
118
+ - ``latex_name`` -- (default: ``None``) LaTeX symbol to denote the
119
+ connection
120
+ - ``init_coef`` -- boolean (default: ``True``); determines whether the Christoffel
121
+ symbols are initialized (in the top charts on the domain, i.e.
122
+ disregarding the subcharts)
123
+
124
+ EXAMPLES:
125
+
126
+ Levi-Civita connection associated with the Euclidean metric on `\RR^3`
127
+ expressed in spherical coordinates::
128
+
129
+ sage: forget() # for doctests only
130
+ sage: M = Manifold(3, 'R^3', start_index=1)
131
+ sage: c_spher.<r,th,ph> = M.chart(r'r:(0,+oo) th:(0,pi):\theta ph:(0,2*pi):\phi')
132
+ sage: g = M.metric('g')
133
+ sage: g[1,1], g[2,2], g[3,3] = 1, r^2 , (r*sin(th))^2
134
+ sage: g.display()
135
+ g = dr⊗dr + r^2 dth⊗dth + r^2*sin(th)^2 dph⊗dph
136
+ sage: nab = g.connection(name='nabla', latex_name=r'\nabla') ; nab
137
+ Levi-Civita connection nabla associated with the Riemannian metric g on
138
+ the 3-dimensional differentiable manifold R^3
139
+
140
+ Let us check that the connection is compatible with the metric::
141
+
142
+ sage: Dg = nab(g) ; Dg
143
+ Tensor field nabla(g) of type (0,3) on the 3-dimensional
144
+ differentiable manifold R^3
145
+ sage: Dg == 0
146
+ True
147
+
148
+ and that it is torsionless::
149
+
150
+ sage: nab.torsion() == 0
151
+ True
152
+
153
+ As a check, let us enforce the computation of the torsion::
154
+
155
+ sage: sage.manifolds.differentiable.affine_connection.AffineConnection.torsion(nab) == 0
156
+ True
157
+
158
+ The connection coefficients in the manifold's default frame are Christoffel
159
+ symbols, since the default frame is a coordinate frame::
160
+
161
+ sage: M.default_frame()
162
+ Coordinate frame (R^3, (∂/∂r,∂/∂th,∂/∂ph))
163
+ sage: nab.coef()
164
+ 3-indices components w.r.t. Coordinate frame (R^3, (∂/∂r,∂/∂th,∂/∂ph)),
165
+ with symmetry on the index positions (1, 2)
166
+
167
+ We note that the Christoffel symbols are symmetric with respect to their
168
+ last two indices (positions (1,2)); their expression is::
169
+
170
+ sage: nab.coef()[:] # display as a array
171
+ [[[0, 0, 0], [0, -r, 0], [0, 0, -r*sin(th)^2]],
172
+ [[0, 1/r, 0], [1/r, 0, 0], [0, 0, -cos(th)*sin(th)]],
173
+ [[0, 0, 1/r], [0, 0, cos(th)/sin(th)], [1/r, cos(th)/sin(th), 0]]]
174
+ sage: nab.display() # display only the non-vanishing symbols
175
+ Gam^r_th,th = -r
176
+ Gam^r_ph,ph = -r*sin(th)^2
177
+ Gam^th_r,th = 1/r
178
+ Gam^th_th,r = 1/r
179
+ Gam^th_ph,ph = -cos(th)*sin(th)
180
+ Gam^ph_r,ph = 1/r
181
+ Gam^ph_th,ph = cos(th)/sin(th)
182
+ Gam^ph_ph,r = 1/r
183
+ Gam^ph_ph,th = cos(th)/sin(th)
184
+ sage: nab.display(only_nonredundant=True) # skip redundancy due to symmetry
185
+ Gam^r_th,th = -r
186
+ Gam^r_ph,ph = -r*sin(th)^2
187
+ Gam^th_r,th = 1/r
188
+ Gam^th_ph,ph = -cos(th)*sin(th)
189
+ Gam^ph_r,ph = 1/r
190
+ Gam^ph_th,ph = cos(th)/sin(th)
191
+
192
+ The same display can be obtained via the function
193
+ :meth:`~sage.manifolds.differentiable.metric.PseudoRiemannianMetric.christoffel_symbols_display`
194
+ acting on the metric::
195
+
196
+ sage: g.christoffel_symbols_display(chart=c_spher)
197
+ Gam^r_th,th = -r
198
+ Gam^r_ph,ph = -r*sin(th)^2
199
+ Gam^th_r,th = 1/r
200
+ Gam^th_ph,ph = -cos(th)*sin(th)
201
+ Gam^ph_r,ph = 1/r
202
+ Gam^ph_th,ph = cos(th)/sin(th)
203
+ """
204
+ def __init__(self, metric, name, latex_name=None, init_coef=True):
205
+ r"""
206
+ Construct a Levi-Civita connection.
207
+
208
+ TESTS:
209
+
210
+ Levi-Civita connection of the hyperbolic plane::
211
+
212
+ sage: M = Manifold(2, 'M')
213
+ sage: X.<r,ph> = M.chart(r'r:(0,+oo) ph:(0,2*pi)')
214
+ sage: g = M.metric('g')
215
+ sage: g[0,0], g[1,1] = 1/(1+r^2), r^2
216
+ sage: from sage.manifolds.differentiable.levi_civita_connection \
217
+ ....: import LeviCivitaConnection
218
+ sage: nab = LeviCivitaConnection(g, 'nabla', latex_name=r'\nabla')
219
+ sage: nab
220
+ Levi-Civita connection nabla associated with the Riemannian metric
221
+ g on the 2-dimensional differentiable manifold M
222
+ sage: TestSuite(nab).run()
223
+ """
224
+ AffineConnection.__init__(self, metric.domain(), name, latex_name)
225
+ self._metric = metric
226
+ # Initialization of the derived quantities:
227
+ LeviCivitaConnection._init_derived(self)
228
+ if init_coef:
229
+ # Initialization of the Christoffel symbols in the top charts on
230
+ # the domain (i.e. disregarding the subcharts)
231
+ for chart in self._domain.top_charts():
232
+ self.coef(chart._frame)
233
+
234
+ def _repr_(self):
235
+ r"""
236
+ String representation of the object.
237
+
238
+ TESTS::
239
+
240
+ sage: M = Manifold(5, 'M')
241
+ sage: g = M.metric('g')
242
+ sage: nab = g.connection()
243
+ sage: nab._repr_()
244
+ 'Levi-Civita connection nabla_g associated with the Riemannian metric g on the 5-dimensional differentiable manifold M'
245
+ sage: repr(nab) # indirect doctest
246
+ 'Levi-Civita connection nabla_g associated with the Riemannian metric g on the 5-dimensional differentiable manifold M'
247
+ """
248
+ description = "Levi-Civita connection"
249
+ if self._name is not None:
250
+ description += " " + self._name
251
+ description += " associated with the {}".format(self._metric)
252
+ return description
253
+
254
+ def _init_derived(self):
255
+ r"""
256
+ Initialize the derived quantities.
257
+
258
+ TESTS::
259
+
260
+ sage: M = Manifold(5, 'M')
261
+ sage: g = M.metric('g')
262
+ sage: nab = g.connection()
263
+ sage: nab._init_derived()
264
+ """
265
+ AffineConnection._init_derived(self)
266
+
267
+ def _del_derived(self):
268
+ r"""
269
+ Delete the derived quantities.
270
+
271
+ TESTS::
272
+
273
+ sage: M = Manifold(5, 'M')
274
+ sage: g = M.metric('g')
275
+ sage: nab = g.connection()
276
+ sage: nab._del_derived()
277
+ """
278
+ AffineConnection._del_derived(self)
279
+
280
+ def restrict(self, subdomain):
281
+ r"""
282
+ Return the restriction of the connection to some subdomain.
283
+
284
+ If such restriction has not been defined yet, it is constructed here.
285
+
286
+ INPUT:
287
+
288
+ - ``subdomain`` -- open subset `U` of the connection's domain (must be
289
+ an instance of
290
+ :class:`~sage.manifolds.differentiable.manifold.DifferentiableManifold`)
291
+
292
+ OUTPUT:
293
+
294
+ - instance of :class:`LeviCivitaConnection` representing the
295
+ restriction.
296
+
297
+ EXAMPLES::
298
+
299
+ sage: M = Manifold(2, 'M')
300
+ sage: X.<x,y> = M.chart()
301
+ sage: g = M.metric('g')
302
+ sage: g[0,0], g[1,1] = 1+y^2, 1+x^2
303
+ sage: nab = g.connection()
304
+ sage: nab[:]
305
+ [[[0, y/(y^2 + 1)], [y/(y^2 + 1), -x/(y^2 + 1)]],
306
+ [[-y/(x^2 + 1), x/(x^2 + 1)], [x/(x^2 + 1), 0]]]
307
+ sage: U = M.open_subset('U', coord_def={X: x>0})
308
+ sage: nabU = nab.restrict(U); nabU
309
+ Levi-Civita connection nabla_g associated with the Riemannian
310
+ metric g on the Open subset U of the 2-dimensional differentiable
311
+ manifold M
312
+ sage: nabU[:]
313
+ [[[0, y/(y^2 + 1)], [y/(y^2 + 1), -x/(y^2 + 1)]],
314
+ [[-y/(x^2 + 1), x/(x^2 + 1)], [x/(x^2 + 1), 0]]]
315
+
316
+ Let us check that the restriction is the connection compatible with the
317
+ restriction of the metric::
318
+
319
+ sage: nabU(g.restrict(U)).display()
320
+ nabla_g(g) = 0
321
+ """
322
+ if subdomain == self._domain:
323
+ return self
324
+ if subdomain not in self._restrictions:
325
+ if not subdomain.is_subset(self._domain):
326
+ raise ValueError("the provided domain is not a subdomain of " +
327
+ "the current connection's domain")
328
+ resu = LeviCivitaConnection(self._metric.restrict(subdomain),
329
+ name=self._name,
330
+ latex_name=self._latex_name,
331
+ init_coef=False)
332
+ for frame in self._coefficients:
333
+ for sframe in subdomain._top_frames:
334
+ if sframe in frame._subframes:
335
+ comp_store = self._coefficients[frame]._comp
336
+ scoef = resu._new_coef(sframe)
337
+ scomp_store = scoef._comp
338
+ # the coefficients of the restriction are evaluated
339
+ # index by index:
340
+ for ind, value in comp_store.items():
341
+ scomp_store[ind] = value.restrict(sframe._domain)
342
+ resu._coefficients[sframe] = scoef
343
+ if self._riemann is not None:
344
+ resu._riemann = self._riemann.restrict(subdomain)
345
+ if self._ricci is not None:
346
+ resu._ricci = self._ricci.restrict(subdomain)
347
+ self._restrictions[subdomain] = resu
348
+ return self._restrictions[subdomain]
349
+
350
+ def _new_coef(self, frame):
351
+ r"""
352
+ Create the connection coefficients w.r.t. the given frame.
353
+
354
+ TESTS::
355
+
356
+ sage: M = Manifold(2, 'M')
357
+ sage: X.<x,y> = M.chart()
358
+ sage: g = M.metric('g')
359
+ sage: g[0,0], g[1,1] = 1, 1
360
+ sage: nab = g.connection()
361
+ sage: nab._new_coef(X.frame())
362
+ 3-indices components w.r.t. Coordinate frame (M, (∂/∂x,∂/∂y)), with
363
+ symmetry on the index positions (1, 2)
364
+ sage: e = M.vector_frame('e')
365
+ sage: nab._new_coef(e)
366
+ 3-indices components w.r.t. Vector frame (M, (e_0,e_1))
367
+ """
368
+ from sage.manifolds.differentiable.scalarfield import DiffScalarField
369
+ from sage.manifolds.differentiable.vectorframe import CoordFrame
370
+ from sage.tensor.modules.comp import Components, CompWithSym
371
+ if isinstance(frame, CoordFrame):
372
+ # the Christoffel symbols are symmetric:
373
+ return CompWithSym(frame._domain.scalar_field_algebra(), frame, 3,
374
+ start_index=self._domain._sindex,
375
+ output_formatter=DiffScalarField.coord_function,
376
+ sym=(1,2))
377
+ else:
378
+ # a priori no symmetry in a generic frame:
379
+ return Components(frame._domain.scalar_field_algebra(), frame, 3,
380
+ start_index=self._domain._sindex,
381
+ output_formatter=DiffScalarField.coord_function)
382
+
383
+ def coef(self, frame=None):
384
+ r"""
385
+ Return the connection coefficients relative to the given frame.
386
+
387
+ `n` being the manifold's dimension, the connection coefficients
388
+ relative to the vector frame `(e_i)` are the `n^3` scalar fields
389
+ `\Gamma^k_{\ \, ij}` defined by
390
+
391
+ .. MATH::
392
+
393
+ \nabla_{e_j} e_i = \Gamma^k_{\ \, ij} e_k
394
+
395
+ If the connection coefficients are not known already, they are computed
396
+
397
+ * as Christoffel symbols if the frame `(e_i)` is a coordinate frame
398
+ * from the above formula otherwise
399
+
400
+ INPUT:
401
+
402
+ - ``frame`` -- (default: ``None``) vector frame relative to which the
403
+ connection coefficients are required; if none is provided, the
404
+ domain's default frame is assumed
405
+
406
+ OUTPUT:
407
+
408
+ - connection coefficients relative to the frame ``frame``, as an
409
+ instance of the class :class:`~sage.tensor.modules.comp.Components`
410
+ with 3 indices ordered as `(k,i,j)`; for Christoffel symbols,
411
+ an instance of the subclass
412
+ :class:`~sage.tensor.modules.comp.CompWithSym` is returned.
413
+
414
+ EXAMPLES:
415
+
416
+ Christoffel symbols of the Levi-Civita connection associated to
417
+ the Euclidean metric on `\RR^3` expressed in spherical coordinates::
418
+
419
+ sage: M = Manifold(3, 'R^3', start_index=1)
420
+ sage: c_spher.<r,th,ph> = M.chart(r'r:(0,+oo) th:(0,pi):\theta ph:(0,2*pi):\phi')
421
+ sage: g = M.metric('g')
422
+ sage: g[1,1], g[2,2], g[3,3] = 1, r^2 , (r*sin(th))^2
423
+ sage: g.display()
424
+ g = dr⊗dr + r^2 dth⊗dth + r^2*sin(th)^2 dph⊗dph
425
+ sage: nab = g.connection()
426
+ sage: gam = nab.coef() ; gam
427
+ 3-indices components w.r.t. Coordinate frame (R^3, (∂/∂r,∂/∂th,∂/∂ph)),
428
+ with symmetry on the index positions (1, 2)
429
+ sage: gam[:]
430
+ [[[0, 0, 0], [0, -r, 0], [0, 0, -r*sin(th)^2]],
431
+ [[0, 1/r, 0], [1/r, 0, 0], [0, 0, -cos(th)*sin(th)]],
432
+ [[0, 0, 1/r], [0, 0, cos(th)/sin(th)], [1/r, cos(th)/sin(th), 0]]]
433
+
434
+ The only nonzero Christoffel symbols::
435
+
436
+ sage: gam[1,2,2], gam[1,3,3]
437
+ (-r, -r*sin(th)^2)
438
+ sage: gam[2,1,2], gam[2,3,3]
439
+ (1/r, -cos(th)*sin(th))
440
+ sage: gam[3,1,3], gam[3,2,3]
441
+ (1/r, cos(th)/sin(th))
442
+
443
+ Connection coefficients of the same connection with respect to the
444
+ orthonormal frame associated to spherical coordinates::
445
+
446
+ sage: ch_basis = M.automorphism_field()
447
+ sage: ch_basis[1,1], ch_basis[2,2], ch_basis[3,3] = 1, 1/r, 1/(r*sin(th))
448
+ sage: e = c_spher.frame().new_frame(ch_basis, 'e')
449
+ sage: gam_e = nab.coef(e) ; gam_e
450
+ 3-indices components w.r.t. Vector frame (R^3, (e_1,e_2,e_3))
451
+ sage: gam_e[:]
452
+ [[[0, 0, 0], [0, -1/r, 0], [0, 0, -1/r]],
453
+ [[0, 1/r, 0], [0, 0, 0], [0, 0, -cos(th)/(r*sin(th))]],
454
+ [[0, 0, 1/r], [0, 0, cos(th)/(r*sin(th))], [0, 0, 0]]]
455
+
456
+ The only nonzero connection coefficients::
457
+
458
+ sage: gam_e[1,2,2], gam_e[2,1,2]
459
+ (-1/r, 1/r)
460
+ sage: gam_e[1,3,3], gam_e[3,1,3]
461
+ (-1/r, 1/r)
462
+ sage: gam_e[2,3,3], gam_e[3,2,3]
463
+ (-cos(th)/(r*sin(th)), cos(th)/(r*sin(th)))
464
+ """
465
+ from sage.manifolds.differentiable.vectorframe import CoordFrame
466
+ if frame is None:
467
+ frame = self._domain._def_frame
468
+ if frame not in self._coefficients:
469
+ # the coefficients must be computed
470
+ #
471
+ # Check whether frame is a subframe of a frame in which the
472
+ # coefficients are already known:
473
+ for oframe in self._coefficients:
474
+ if frame in oframe._subframes:
475
+ self._coefficients[frame] = self._new_coef(frame)
476
+ comp_store = self._coefficients[frame]._comp
477
+ ocomp_store = self._coefficients[oframe]._comp
478
+ for ind, value in ocomp_store.items():
479
+ comp_store[ind] = value.restrict(frame._domain)
480
+ break
481
+ else:
482
+ # If not, the coefficients must be computed from scratch:
483
+ manif = self._domain
484
+ if isinstance(frame, CoordFrame):
485
+ # Christoffel symbols
486
+ chart = frame._chart
487
+ gam = self._new_coef(frame)
488
+ gg = self._metric.comp(frame)
489
+ ginv = self._metric.inverse().comp(frame)
490
+
491
+ if Parallelism().get('tensor') != 1:
492
+ # parallel computation
493
+ nproc = Parallelism().get('tensor')
494
+ lol = lambda lst, sz: [lst[i:i+sz] for i in
495
+ range(0, len(lst), sz)]
496
+
497
+ ind_list = []
498
+ for ind in gam.non_redundant_index_generator():
499
+ i, j, k = ind
500
+ ind_list.append((i,j,k))
501
+ ind_step = max(1,int(len(ind_list)/nproc/2))
502
+ local_list = lol(ind_list,ind_step)
503
+
504
+ # definition of the list of input parameters
505
+ listParalInput = []
506
+ for ind_part in local_list:
507
+ listParalInput.append((ind_part,chart,ginv,gg,manif))
508
+
509
+ # definition of the parallel function
510
+ @parallel(p_iter='multiprocessing',ncpus=nproc)
511
+ def make_Connect(local_list_ijk, chart, ginv, gg, manif):
512
+ partial = []
513
+ for i,j,k in local_list_ijk:
514
+ rsum = 0
515
+ for s in manif.irange():
516
+ if ginv[i,s, chart] != 0:
517
+ rsum += ginv[i,s, chart] * (
518
+ gg[s,k, chart].diff(j)
519
+ + gg[j,s, chart].diff(k)
520
+ - gg[j,k, chart].diff(s) )
521
+ partial.append([i,j,k,rsum / 2])
522
+ return partial
523
+
524
+ # Computation and Assignation of values
525
+ for ii, val in make_Connect(listParalInput):
526
+ for jj in val:
527
+ gam[jj[0],jj[1],jj[2],ii[0][1]] = jj[3]
528
+
529
+ else:
530
+ # sequential
531
+ for ind in gam.non_redundant_index_generator():
532
+ i, j, k = ind
533
+ # The computation is performed at the ChartFunction level:
534
+ rsum = 0
535
+ for s in manif.irange():
536
+ rsum += ginv[i,s, chart] * (
537
+ gg[s,k, chart].diff(j)
538
+ + gg[j,s, chart].diff(k)
539
+ - gg[j,k, chart].diff(s) )
540
+ gam[i,j,k, chart] = rsum / 2
541
+
542
+ # Assignation of results
543
+ self._coefficients[frame] = gam
544
+
545
+ else:
546
+ # Computation from the formula defining the connection coef.
547
+ return AffineConnection.coef(self, frame)
548
+ return self._coefficients[frame]
549
+
550
+ def torsion(self):
551
+ r"""
552
+ Return the connection's torsion tensor (identically zero for a
553
+ Levi-Civita connection).
554
+
555
+ See
556
+ :meth:`sage.manifolds.differentiable.affine_connection.AffineConnection.torsion`
557
+ for the general definition of the torsion tensor.
558
+
559
+ OUTPUT:
560
+
561
+ - the torsion tensor `T`, as a vanishing instance of
562
+ :class:`~sage.manifolds.differentiable.tensorfield.TensorField`
563
+
564
+ EXAMPLES::
565
+
566
+ sage: M = Manifold(2, 'M')
567
+ sage: X.<x,y> = M.chart()
568
+ sage: g = M.metric('g')
569
+ sage: g[0,0], g[1,1] = 1+y^2, 1+x^2
570
+ sage: nab = g.connection()
571
+ sage: t = nab.torsion(); t
572
+ Tensor field of type (1,2) on the 2-dimensional differentiable
573
+ manifold M
574
+
575
+ The torsion of a Levi-Civita connection is always zero::
576
+
577
+ sage: t.display()
578
+ 0
579
+ """
580
+ if self._torsion is None:
581
+ resu = self._domain.tensor_field(1, 2, antisym=(1,2))
582
+ for frame in self._coefficients:
583
+ # Initialization of the frame components to zero:
584
+ resu.add_comp(frame)
585
+ self._torsion = resu
586
+ return self._torsion
587
+
588
+ def riemann(self, name=None, latex_name=None):
589
+ r"""
590
+ Return the Riemann curvature tensor of the connection.
591
+
592
+ This method redefines
593
+ :meth:`sage.manifolds.differentiable.affine_connection.AffineConnection.riemann`
594
+ to take into account the symmetry of the Riemann tensor for a
595
+ Levi-Civita connection.
596
+
597
+ The Riemann curvature tensor is the tensor field `R` of type (1,3)
598
+ defined by
599
+
600
+ .. MATH::
601
+
602
+ R(\omega, w, u, v) = \left\langle \omega, \nabla_u \nabla_v w
603
+ - \nabla_v \nabla_u w - \nabla_{[u, v]} w \right\rangle
604
+
605
+ for any 1-form `\omega` and any vector fields `u`, `v` and `w`.
606
+
607
+ INPUT:
608
+
609
+ - ``name`` -- (default: ``None``) name given to the Riemann tensor;
610
+ if none, it is set to "Riem(g)", where "g" is the metric's name
611
+ - ``latex_name`` -- (default: ``None``) LaTeX symbol to denote the
612
+ Riemann tensor; if none, it is set to "\\mathrm{Riem}(g)", where "g"
613
+ is the metric's name
614
+
615
+ OUTPUT:
616
+
617
+ - the Riemann curvature tensor `R`, as an instance of
618
+ :class:`~sage.manifolds.differentiable.tensorfield.TensorField`
619
+
620
+ EXAMPLES:
621
+
622
+ Riemann tensor of the Levi-Civita connection associated with the
623
+ metric of the hyperbolic plane (Poincaré disk model)::
624
+
625
+ sage: M = Manifold(2, 'M', start_index=1)
626
+ sage: X.<x,y> = M.chart('x:(-1,1) y:(-1,1)', coord_restrictions=lambda x,y: x^2+y^2<1)
627
+ ....: # Cartesian coord. on the Poincaré disk
628
+ sage: g = M.metric('g')
629
+ sage: g[1,1], g[2,2] = 4/(1-x^2-y^2)^2, 4/(1-x^2-y^2)^2
630
+ sage: nab = g.connection()
631
+ sage: riem = nab.riemann(); riem
632
+ Tensor field Riem(g) of type (1,3) on the 2-dimensional
633
+ differentiable manifold M
634
+ sage: riem.display_comp()
635
+ Riem(g)^x_yxy = -4/(x^4 + y^4 + 2*(x^2 - 1)*y^2 - 2*x^2 + 1)
636
+ Riem(g)^x_yyx = 4/(x^4 + y^4 + 2*(x^2 - 1)*y^2 - 2*x^2 + 1)
637
+ Riem(g)^y_xxy = 4/(x^4 + y^4 + 2*(x^2 - 1)*y^2 - 2*x^2 + 1)
638
+ Riem(g)^y_xyx = -4/(x^4 + y^4 + 2*(x^2 - 1)*y^2 - 2*x^2 + 1)
639
+
640
+ The same computation parallelized on 2 cores::
641
+
642
+ sage: Parallelism().set(nproc=2)
643
+ sage: riem_backup = riem
644
+ sage: g = M.metric('g')
645
+ sage: g[1,1], g[2,2] = 4/(1-x^2-y^2)^2, 4/(1-x^2-y^2)^2
646
+ sage: nab = g.connection()
647
+ sage: riem = nab.riemann(); riem
648
+ Tensor field Riem(g) of type (1,3) on the 2-dimensional
649
+ differentiable manifold M
650
+ sage: riem == riem_backup
651
+ True
652
+ sage: Parallelism().set(nproc=1) # switch off parallelization
653
+ """
654
+ if self._riemann is None:
655
+ if name is None:
656
+ name = "Riem(" + self._metric._name + ")"
657
+ if latex_name is None:
658
+ latex_name = (r"\mathrm{Riem}\left(" + self._metric._latex_name
659
+ + r"\right)")
660
+ manif = self._domain
661
+ resu = manif.tensor_field(1, 3, antisym=(2,3), name=name,
662
+ latex_name=latex_name)
663
+ for frame, gam in self._coefficients.items():
664
+ # The computation is performed only on the top frames:
665
+ for oframe in self._coefficients:
666
+ if frame in oframe._subframes and frame is not oframe:
667
+ break
668
+ else:
669
+ # frame in not a subframe and the computation is performed:
670
+ sc = frame.structure_coeff()
671
+ gam_gam = gam.contract(1, gam, 0)
672
+ gam_sc = gam.contract(2, sc, 0)
673
+ res = resu.add_comp(frame)
674
+ use_Bianchi = isinstance(frame,CoordFrame)
675
+ if Parallelism().get('tensor') != 1:
676
+ # parallel computation
677
+ nproc = Parallelism().get('tensor')
678
+ lol = lambda lst, sz: [lst[i:i+sz] for i in range(0,
679
+ len(lst), sz)]
680
+ ind_list = []
681
+ for i in manif.irange():
682
+ for j in manif.irange():
683
+ for k in manif.irange(start=j):
684
+ for l in manif.irange(start=k+1):
685
+ ind_list.append((i,j,k,l))
686
+ ind_step = max(1, int(len(ind_list)/nproc/2))
687
+ local_list = lol(ind_list, ind_step)
688
+ # definition of the list of input parameters
689
+ listParalInput = []
690
+ for ind_part in local_list:
691
+ listParalInput.append((frame, gam, gam_gam, gam_sc,
692
+ use_Bianchi, ind_part))
693
+
694
+ # definition of the parallel function
695
+ @parallel(p_iter='multiprocessing', ncpus=nproc)
696
+ def make_Riem(frame, gam, gam_gam, gam_sc, use_Bianchi,
697
+ local_list_ijkl):
698
+ def compute_component(i,j,k,l, frame, gam, gam_gam, gam_sc):
699
+ return frame[k](gam[[i,j,l]]) - frame[l](gam[[i,j,k]]) + \
700
+ gam_gam[[i,k,j,l]] - gam_gam[[i,l,j,k]] - gam_sc[[i,j,k,l]]
701
+ partial = []
702
+ for i,j,k,l in local_list_ijkl:
703
+ R_ijkl = compute_component(i,j,k,l, frame, gam, gam_gam, gam_sc)
704
+ partial.append([i,j,k,l, R_ijkl])
705
+ if j == k:
706
+ partial.append([i,l,k,l, compute_component(i,l,k,l, frame,
707
+ gam, gam_gam, gam_sc)])
708
+ else:
709
+ R_ikjl = compute_component(i,k,j,l, frame, gam, gam_gam, gam_sc)
710
+ partial.append([i,k,j,l, R_ikjl])
711
+ if use_Bianchi:
712
+ partial.append([i,l,j,k, R_ikjl - R_ijkl])
713
+ else:
714
+ partial.append([i,l,j,k, compute_component(i,l,j,k, frame,
715
+ gam, gam_gam, gam_sc)])
716
+ return partial
717
+ # Computation and assignation of values
718
+ for ii,val in make_Riem(listParalInput):
719
+ for jj in val:
720
+ res[jj[0], jj[1], jj[2], jj[3]] = jj[4]
721
+
722
+ else:
723
+ # sequential
724
+ for i in manif.irange():
725
+ for j in manif.irange():
726
+ for k in manif.irange():
727
+ # antisymmetry of the Riemann tensor taken
728
+ # into account by l>k:
729
+ for l in manif.irange(start=k+1):
730
+ if not use_Bianchi or (j <= k or j <= l):
731
+ res[i,j,k,l] = frame[k](gam[[i,j,l]]) - \
732
+ frame[l](gam[[i,j,k]]) + \
733
+ gam_gam[[i,k,j,l]] - \
734
+ gam_gam[[i,l,j,k]] - \
735
+ gam_sc[[i,j,k,l]]
736
+ if use_Bianchi:
737
+ # first Bianchi identity
738
+ for j in manif.irange():
739
+ for k in manif.irange(end=j-1):
740
+ for l in manif.irange(start=k+1,end=j-1):
741
+ # j > k and j > l:
742
+ res[i,j,k,l] = res[i,l,k,j] - res[i,k,l,j]
743
+ self._riemann = resu
744
+ return self._riemann
745
+
746
+ def ricci(self, name=None, latex_name=None):
747
+ r"""
748
+ Return the connection's Ricci tensor.
749
+
750
+ This method redefines
751
+ :meth:`sage.manifolds.differentiable.affine_connection.AffineConnection.ricci`
752
+ to take into account the symmetry of the Ricci tensor for a
753
+ Levi-Civita connection.
754
+
755
+ The Ricci tensor is the tensor field `Ric` of type (0,2)
756
+ defined from the Riemann curvature tensor `R` by
757
+
758
+ .. MATH::
759
+
760
+ Ric(u, v) = R(e^i, u, e_i, v)
761
+
762
+ for any vector fields `u` and `v`, `(e_i)` being any vector frame and
763
+ `(e^i)` the dual coframe.
764
+
765
+ INPUT:
766
+
767
+ - ``name`` -- (default: ``None``) name given to the Ricci tensor;
768
+ if none, it is set to "Ric(g)", where "g" is the metric's name
769
+ - ``latex_name`` -- (default: ``None``) LaTeX symbol to denote the
770
+ Ricci tensor; if none, it is set to "\\mathrm{Ric}(g)", where "g"
771
+ is the metric's name
772
+
773
+ OUTPUT:
774
+
775
+ - the Ricci tensor `Ric`, as an instance of
776
+ :class:`~sage.manifolds.differentiable.tensorfield.TensorField` of tensor
777
+ type (0,2) and symmetric
778
+
779
+ EXAMPLES:
780
+
781
+ Ricci tensor of the standard connection on the 2-dimensional sphere::
782
+
783
+ sage: M = Manifold(2, 'S^2', start_index=1)
784
+ sage: c_spher.<th,ph> = M.chart(r'th:(0,pi):\theta ph:(0,2*pi):\phi')
785
+ sage: g = M.metric('g')
786
+ sage: g[1,1], g[2,2] = 1, sin(th)^2
787
+ sage: g.display() # standard metric on S^2:
788
+ g = dth⊗dth + sin(th)^2 dph⊗dph
789
+ sage: nab = g.connection() ; nab
790
+ Levi-Civita connection nabla_g associated with the Riemannian
791
+ metric g on the 2-dimensional differentiable manifold S^2
792
+ sage: ric = nab.ricci() ; ric
793
+ Field of symmetric bilinear forms Ric(g) on the 2-dimensional
794
+ differentiable manifold S^2
795
+ sage: ric.display()
796
+ Ric(g) = dth⊗dth + sin(th)^2 dph⊗dph
797
+
798
+ Checking that the Ricci tensor of the Levi-Civita connection associated
799
+ to Schwarzschild metric is identically zero (as a solution of the
800
+ Einstein equation)::
801
+
802
+ sage: M = Manifold(4, 'M')
803
+ sage: c_BL.<t,r,th,ph> = M.chart(r't r:(0,+oo) th:(0,pi):\theta ph:(0,2*pi):\phi') # Schwarzschild-Droste coordinates
804
+ sage: g = M.lorentzian_metric('g')
805
+ sage: m = var('m') # mass in Schwarzschild metric
806
+ sage: g[0,0], g[1,1] = -(1-2*m/r), 1/(1-2*m/r)
807
+ sage: g[2,2], g[3,3] = r^2, (r*sin(th))^2
808
+ sage: g.display()
809
+ g = (2*m/r - 1) dt⊗dt - 1/(2*m/r - 1) dr⊗dr + r^2 dth⊗dth
810
+ + r^2*sin(th)^2 dph⊗dph
811
+ sage: nab = g.connection() ; nab
812
+ Levi-Civita connection nabla_g associated with the Lorentzian
813
+ metric g on the 4-dimensional differentiable manifold M
814
+ sage: ric = nab.ricci() ; ric
815
+ Field of symmetric bilinear forms Ric(g) on the 4-dimensional
816
+ differentiable manifold M
817
+ sage: ric == 0
818
+ True
819
+ """
820
+ if self._ricci is None:
821
+ if name is None:
822
+ name = "Ric(" + self._metric._name + ")"
823
+ if latex_name is None:
824
+ latex_name = r"\mathrm{Ric}\left(" + \
825
+ self._metric._latex_name + r"\right)"
826
+ manif = self._domain
827
+ riem = self.riemann()
828
+ resu = manif.tensor_field(0, 2, sym=(0,1), name=name,
829
+ latex_name=latex_name)
830
+ for frame in self._coefficients:
831
+ cric = resu.add_comp(frame)
832
+ criem = riem.comp(frame)
833
+ for i in manif.irange():
834
+ # symmetry of the Ricci tensor taken into account by j>=i:
835
+ for j in manif.irange(start=i):
836
+ rsum = 0
837
+ for k in manif.irange():
838
+ rsum += criem[[k,i,k,j]]
839
+ cric[i,j] = rsum
840
+ self._ricci = resu
841
+ return self._ricci