passagemath-symbolics 10.6.40__cp314-cp314t-macosx_13_0_x86_64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of passagemath-symbolics might be problematic. Click here for more details.

Files changed (172) hide show
  1. passagemath_symbolics/.dylibs/libgmp.10.dylib +0 -0
  2. passagemath_symbolics/__init__.py +3 -0
  3. passagemath_symbolics-10.6.40.dist-info/METADATA +187 -0
  4. passagemath_symbolics-10.6.40.dist-info/RECORD +172 -0
  5. passagemath_symbolics-10.6.40.dist-info/WHEEL +6 -0
  6. passagemath_symbolics-10.6.40.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 +2826 -0
  10. sage/calculus/desolvers.py +1866 -0
  11. sage/calculus/predefined.py +51 -0
  12. sage/calculus/tests.py +225 -0
  13. sage/calculus/var.cpython-314t-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-314t-darwin.so +0 -0
  19. sage/dynamics/complex_dynamics/mandel_julia_helper.pyx +1035 -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 +743 -0
  34. sage/geometry/hyperbolic_space/hyperbolic_constants.py +5 -0
  35. sage/geometry/hyperbolic_space/hyperbolic_geodesic.py +2409 -0
  36. sage/geometry/hyperbolic_space/hyperbolic_interface.py +206 -0
  37. sage/geometry/hyperbolic_space/hyperbolic_isometry.py +1082 -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 +3017 -0
  45. sage/interfaces/magma_free.py +92 -0
  46. sage/interfaces/maple.py +1397 -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 +555 -0
  55. sage/manifolds/catalog.py +437 -0
  56. sage/manifolds/chart.py +4019 -0
  57. sage/manifolds/chart_func.py +3419 -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 +1671 -0
  71. sage/manifolds/differentiable/diff_form.py +1658 -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 +1520 -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 +910 -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 +1728 -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 +2764 -0
  119. sage/manifolds/subsets/all.py +1 -0
  120. sage/manifolds/subsets/closure.py +131 -0
  121. sage/manifolds/subsets/pullback.py +885 -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 +1342 -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-314t-darwin.so +0 -0
  130. sage/matrix/matrix_symbolic_dense.pxd +6 -0
  131. sage/matrix/matrix_symbolic_dense.pyx +1022 -0
  132. sage/matrix/matrix_symbolic_sparse.cpython-314t-darwin.so +0 -0
  133. sage/matrix/matrix_symbolic_sparse.pxd +6 -0
  134. sage/matrix/matrix_symbolic_sparse.pyx +1029 -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 +4153 -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 +5237 -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 +985 -0
  151. sage/symbolic/benchmark.py +93 -0
  152. sage/symbolic/callable.py +459 -0
  153. sage/symbolic/complexity_measures.py +35 -0
  154. sage/symbolic/constants.py +1287 -0
  155. sage/symbolic/expression_conversion_algebraic.py +310 -0
  156. sage/symbolic/expression_conversion_sympy.py +317 -0
  157. sage/symbolic/expression_conversions.py +1713 -0
  158. sage/symbolic/function_factory.py +355 -0
  159. sage/symbolic/integration/all.py +1 -0
  160. sage/symbolic/integration/external.py +270 -0
  161. sage/symbolic/integration/integral.py +1115 -0
  162. sage/symbolic/maxima_wrapper.py +162 -0
  163. sage/symbolic/operators.py +267 -0
  164. sage/symbolic/random_tests.py +462 -0
  165. sage/symbolic/relation.py +1907 -0
  166. sage/symbolic/ring.cpython-314t-darwin.so +0 -0
  167. sage/symbolic/ring.pxd +5 -0
  168. sage/symbolic/ring.pyx +1396 -0
  169. sage/symbolic/subring.py +1025 -0
  170. sage/symbolic/symengine.py +19 -0
  171. sage/symbolic/tests.py +40 -0
  172. sage/symbolic/units.py +1470 -0
@@ -0,0 +1,1445 @@
1
+ # sage_setup: distribution = sagemath-symbolics
2
+ r"""
3
+ Bundle Connections
4
+
5
+ Let `E \to M` be a smooth vector bundle of rank `n` over a smooth manifold `M`
6
+ and over a non-discrete topological field `K` (typically `K=\RR` or `K=\CC`). A
7
+ *bundle connection* on this vector bundle is a `K`-linear map
8
+
9
+ .. MATH::
10
+
11
+ \nabla : C^\infty(M;E) \to C^\infty(M;E \otimes T^*M)
12
+
13
+ such that the Leibniz rule applies for each scalar field `f \in C^\infty(M)` and
14
+ section `s \in C^\infty(M;E)`:
15
+
16
+ .. MATH::
17
+
18
+ \nabla(f \, s) = f \cdot \nabla s + s \otimes \mathrm{d}f .
19
+
20
+ If `e` is a local frame on `E`, we have
21
+
22
+ .. MATH::
23
+
24
+ \nabla e_i = \sum^n_{j=1} e_j \otimes \omega^j_i ,
25
+
26
+ and the corresponding `n \times n`-matrix `(\omega^j_i)_{i,j}` consisting of
27
+ one forms is called *connection matrix of* `\nabla` *with respect to* `e`.
28
+
29
+ AUTHORS:
30
+
31
+ - Michael Jung (2019) : initial version
32
+ """
33
+ # ******************************************************************************
34
+ # Copyright (C) 2019 Michael Jung <micjung@uni-potsdam.de>
35
+ #
36
+ # Distributed under the terms of the GNU General Public License (GPL)
37
+ # as published by the Free Software Foundation; either version 2 of
38
+ # the License, or (at your option) any later version.
39
+ # https://www.gnu.org/licenses/
40
+ # ******************************************************************************
41
+
42
+ from sage.manifolds.differentiable.vector_bundle import DifferentiableVectorBundle
43
+ from sage.rings.integer import Integer
44
+ from sage.structure.mutability import Mutability
45
+ from sage.structure.sage_object import SageObject
46
+
47
+
48
+ class BundleConnection(SageObject, Mutability):
49
+ r"""
50
+ An instance of this class represents a bundle connection `\nabla` on a
51
+ smooth vector bundle `E \to M`.
52
+
53
+ INPUT:
54
+
55
+ - ``vbundle`` -- the vector bundle on which the connection is defined
56
+ (must be an instance of class
57
+ :class:`~sage.manifolds.differentiable.vector_bundle.DifferentiableVectorBundle`)
58
+ - ``name`` -- name given to the bundle connection
59
+ - ``latex_name`` -- (default: ``None``) LaTeX symbol to denote the bundle
60
+ connection; if ``None``, it is set to ``name``
61
+
62
+ EXAMPLES:
63
+
64
+ Define a bundle connection on a rank 2 vector bundle over some
65
+ 3-dimensional smooth manifold::
66
+
67
+ sage: M = Manifold(3, 'M', start_index=1)
68
+ sage: X.<x,y,z> = M.chart()
69
+ sage: E = M.vector_bundle(2, 'E')
70
+ sage: e = E.local_frame('e') # standard frame for E
71
+ sage: nab = E.bundle_connection('nabla'); nab
72
+ Bundle connection nabla on the Differentiable real vector bundle E -> M
73
+ of rank 2 over the base space 3-dimensional differentiable manifold M
74
+
75
+ First, let us initialize all connection 1-forms w.r.t. the frame ``e`` to
76
+ zero::
77
+
78
+ sage: nab[e, :] = [[0, 0], [0, 0]]
79
+
80
+ This line can be shortened by the following::
81
+
82
+ sage: nab[e, :] = 0 # initialize to zero
83
+
84
+ The connection 1-forms are now initialized being differential 1-forms::
85
+
86
+ sage: nab[e, 1, 1].parent()
87
+ Free module Omega^1(M) of 1-forms on the 3-dimensional differentiable
88
+ manifold M
89
+ sage: nab[e, 1, 1].display()
90
+ connection (1,1) of bundle connection nabla w.r.t. Local frame
91
+ (E|_M, (e_1,e_2)) = 0
92
+
93
+ Now, we want to specify some nonzero entries::
94
+
95
+ sage: nab[e, 1, 2][:] = [x*z, y*z, z^2]
96
+ sage: nab[e, 2, 1][:] = [x, x^2, x^3]
97
+ sage: nab[e, 1, 1][:] = [x+z, y-z, x*y*z]
98
+ sage: nab.display()
99
+ connection (1,1) of bundle connection nabla w.r.t. Local frame
100
+ (E|_M, (e_1,e_2)) = (x + z) dx + (y - z) dy + x*y*z dz
101
+ connection (1,2) of bundle connection nabla w.r.t. Local frame
102
+ (E|_M, (e_1,e_2)) = x*z dx + y*z dy + z^2 dz
103
+ connection (2,1) of bundle connection nabla w.r.t. Local frame
104
+ (E|_M, (e_1,e_2)) = x dx + x^2 dy + x^3 dz
105
+
106
+ Notice, when we omit the frame, the default frame of the vector bundle is
107
+ assumed (in this case ``e``)::
108
+
109
+ sage: nab[2, 2].display()
110
+ connection (2,2) of bundle connection nabla w.r.t. Local frame
111
+ (E|_M, (e_1,e_2)) = 0
112
+
113
+ The same holds for the assignment::
114
+
115
+ sage: nab[1, 2] = 0
116
+ sage: nab[e, 1, 2].display()
117
+ connection (1,2) of bundle connection nabla w.r.t. Local frame
118
+ (E|_M, (e_1,e_2)) = 0
119
+
120
+ Keep noticed that item assignments for bundle connections only copy the
121
+ right-hand-side and never create a binding to the original instance::
122
+
123
+ sage: omega = M.one_form('omega')
124
+ sage: omega[:] = [x*z, y*z, z^2]
125
+ sage: nab[1, 2] = omega
126
+ sage: nab[1, 2] == omega
127
+ True
128
+ sage: nab[1, 2] is omega
129
+ False
130
+
131
+ Hence, this is therefore equivalent to::
132
+
133
+ sage: nab[2, 2].copy_from(omega)
134
+
135
+ Preferably, we use :meth:`set_connection_form` to specify the connection
136
+ 1-forms::
137
+
138
+ sage: nab[:] = 0 # re-initialize to zero
139
+ sage: nab.set_connection_form(1, 2)[:] = [x*z, y*z, z^2]
140
+ sage: nab.set_connection_form(2, 1)[:] = [x, x^2, x^3]
141
+ sage: nab[1, 2].display()
142
+ connection (1,2) of bundle connection nabla w.r.t. Local frame
143
+ (E|_M, (e_1,e_2)) = x*z dx + y*z dy + z^2 dz
144
+ sage: nab[2, 1].display()
145
+ connection (2,1) of bundle connection nabla w.r.t. Local frame
146
+ (E|_M, (e_1,e_2)) = x dx + x^2 dy + x^3 dz
147
+
148
+ .. NOTE::
149
+
150
+ Notice that item assignments and :meth:`set_connection_form` delete
151
+ the connection 1-forms w.r.t. other frames for consistency reasons. To
152
+ avoid this behavior, :meth:`add_connection_form` must be used instead.
153
+
154
+ In conclusion, the connection 1-forms of a bundle connection are mutable
155
+ until the connection itself is set immutable::
156
+
157
+ sage: nab.set_immutable()
158
+ sage: nab[1, 2] = omega
159
+ Traceback (most recent call last):
160
+ ...
161
+ ValueError: object is immutable; please change a copy instead
162
+
163
+ By definition, a bundle connection acts on vector fields and sections::
164
+
165
+ sage: v = M.vector_field((x^2,y^2,z^2), name='v'); v.display()
166
+ v = x^2 ∂/∂x + y^2 ∂/∂y + z^2 ∂/∂z
167
+ sage: s = E.section((x-y^2, -z), name='s'); s.display()
168
+ s = (-y^2 + x) e_1 - z e_2
169
+ sage: nab_vs = nab(v, s); nab_vs
170
+ Section nabla_v(s) on the 3-dimensional differentiable manifold M with
171
+ values in the real vector bundle E of rank 2
172
+ sage: nab_vs.display()
173
+ nabla_v(s) = (-x^3*z^3 - 2*y^3 + x^2 - (x^2*y^2 + x^3)*z) e_1 +
174
+ (-(y^2 - x)*z^4 - (x^3*y^2 + y^5 - x^4 - x*y^3)*z - z^2) e_2
175
+
176
+ The bundle connection action certainly obeys the defining formula for
177
+ the connection 1-forms::
178
+
179
+ sage: vframe = X.frame()
180
+ sage: all(nab(vframe[k], e[i]) == sum(nab[e, i, j](vframe[k])*e[j]
181
+ ....: for j in E.irange())
182
+ ....: for i in E.irange() for k in M.irange())
183
+ True
184
+
185
+ The connection 1-forms are computed automatically for different frames::
186
+
187
+ sage: f = E.local_frame('f', ((1+x^2)*e[1], e[1]-e[2]))
188
+ sage: nab.display(frame=f)
189
+ connection (1,1) of bundle connection nabla w.r.t. Local frame
190
+ (E|_M, (f_1,f_2)) = ((x^3 + x)*z + 2*x)/(x^2 + 1) dx + y*z dy + z^2 dz
191
+ connection (1,2) of bundle connection nabla w.r.t. Local frame
192
+ (E|_M, (f_1,f_2)) = -(x^3 + x)*z dx - (x^2 + 1)*y*z dy -
193
+ (x^2 + 1)*z^2 dz
194
+ connection (2,1) of bundle connection nabla w.r.t. Local frame
195
+ (E|_M, (f_1,f_2)) = (x*z - x)/(x^2 + 1) dx -
196
+ (x^2 - y*z)/(x^2 + 1) dy - (x^3 - z^2)/(x^2 + 1) dz
197
+ connection (2,2) of bundle connection nabla w.r.t. Local frame
198
+ (E|_M, (f_1,f_2)) = -x*z dx - y*z dy - z^2 dz
199
+
200
+ The new connection 1-forms obey the defining formula, too::
201
+
202
+ sage: all(nab(vframe[k], f[i]) == sum(nab[f, i, j](vframe[k])*f[j]
203
+ ....: for j in E.irange())
204
+ ....: for i in E.irange() for k in M.irange())
205
+ True
206
+
207
+ After the connection has been specified, the curvature 2-forms can be
208
+ derived::
209
+
210
+ sage: Omega = nab.curvature_form
211
+ sage: for i in E.irange():
212
+ ....: for j in E.irange():
213
+ ....: print(Omega(i ,j, e).display())
214
+ curvature (1,1) of bundle connection nabla w.r.t. Local frame
215
+ (E|_M, (e_1,e_2)) = -(x^3 - x*y)*z dx∧dy + (-x^4*z + x*z^2) dx∧dz +
216
+ (-x^3*y*z + x^2*z^2) dy∧dz
217
+ curvature (1,2) of bundle connection nabla w.r.t. Local frame
218
+ (E|_M, (e_1,e_2)) = -x dx∧dz - y dy∧dz
219
+ curvature (2,1) of bundle connection nabla w.r.t. Local frame
220
+ (E|_M, (e_1,e_2)) = 2*x dx∧dy + 3*x^2 dx∧dz
221
+ curvature (2,2) of bundle connection nabla w.r.t. Local frame
222
+ (E|_M, (e_1,e_2)) = (x^3 - x*y)*z dx∧dy + (x^4*z - x*z^2) dx∧dz +
223
+ (x^3*y*z - x^2*z^2) dy∧dz
224
+
225
+ The derived forms certainly obey the structure equations, see
226
+ :meth:`curvature_form` for details::
227
+
228
+ sage: omega = nab.connection_form
229
+ sage: check = []
230
+ sage: for i in E.irange(): # long time
231
+ ....: for j in E.irange():
232
+ ....: check.append(Omega(i,j,e) == \
233
+ ....: omega(i,j,e).exterior_derivative() + \
234
+ ....: sum(omega(k,j,e).wedge(omega(i,k,e))
235
+ ....: for k in E.irange()))
236
+ sage: check # long time
237
+ [True, True, True, True]
238
+ """
239
+
240
+ def __init__(self, vbundle, name, latex_name=None):
241
+ r"""
242
+ Construct a bundle connection.
243
+
244
+ TESTS::
245
+
246
+ sage: M = Manifold(3, 'M')
247
+ sage: E = M.vector_bundle(2, 'E')
248
+ sage: from sage.manifolds.differentiable.bundle_connection \
249
+ ....: import BundleConnection
250
+ sage: nab = BundleConnection(E, 'nabla', latex_name=r'\nabla')
251
+ sage: nab
252
+ Bundle connection nabla on the Differentiable real vector bundle
253
+ E -> M of rank 2 over the base space 3-dimensional differentiable
254
+ manifold M
255
+ sage: X.<x,y,z> = M.chart()
256
+ sage: e = E.local_frame('e')
257
+ sage: nab[:] = 0
258
+ sage: nab.set_connection_form(1, 0)[:] = [x*z, y*z, z^2]
259
+ sage: TestSuite(nab).run()
260
+ """
261
+ if not isinstance(vbundle, DifferentiableVectorBundle):
262
+ raise TypeError("the first argument must be a differentiable " +
263
+ "vector bundle")
264
+ Mutability.__init__(self)
265
+ self._vbundle = vbundle
266
+ self._domain = vbundle.base_space()
267
+ self._name = name
268
+ if latex_name is None:
269
+ self._latex_name = self._name
270
+ else:
271
+ self._latex_name = latex_name
272
+ self._connection_forms = {} # dict. of con. forms, with frames as keys
273
+ self._coefficients = self._connection_forms
274
+ # Initialization of derived quantities:
275
+ self._init_derived()
276
+
277
+ def _repr_(self):
278
+ r"""
279
+ String representation of the object.
280
+
281
+ TESTS::
282
+
283
+ sage: M = Manifold(5, 'M')
284
+ sage: E = M.vector_bundle(3, 'E')
285
+ sage: nab = E.bundle_connection('nabla', latex_name=r'\nabla')
286
+ sage: nab._repr_()
287
+ 'Bundle connection nabla on the Differentiable real vector bundle
288
+ E -> M of rank 3 over the base space 5-dimensional differentiable
289
+ manifold M'
290
+ sage: repr(nab) # indirect doctest
291
+ 'Bundle connection nabla on the Differentiable real vector bundle
292
+ E -> M of rank 3 over the base space 5-dimensional differentiable
293
+ manifold M'
294
+ """
295
+ description = "Bundle connection"
296
+ if self._name is not None:
297
+ description += " " + self._name
298
+ description += " on the {}".format(self._vbundle)
299
+ return description
300
+
301
+ def _latex_(self):
302
+ r"""
303
+ LaTeX representation of the object.
304
+
305
+ TESTS::
306
+
307
+ sage: M = Manifold(5, 'M')
308
+ sage: E = M.vector_bundle(3, 'E')
309
+ sage: nab = E.bundle_connection('nabla', latex_name=r'\nabla')
310
+ sage: nab._latex_()
311
+ '\\nabla'
312
+ sage: latex(nab) # indirect doctest
313
+ \nabla
314
+ sage: nab = E.bundle_connection('D')
315
+ sage: nab._latex_()
316
+ 'D'
317
+ sage: latex(nab) # indirect doctest
318
+ D
319
+ """
320
+ return self._latex_name
321
+
322
+ def _init_derived(self):
323
+ r"""
324
+ Initialize the derived quantities.
325
+
326
+ TESTS::
327
+
328
+ sage: M = Manifold(4, 'M')
329
+ sage: E = M.vector_bundle(2, 'E')
330
+ sage: nab = E.bundle_connection('nabla', latex_name=r'\nabla')
331
+ sage: nab._init_derived()
332
+ """
333
+ self._curvature_forms = {} # dict. of dict. of curvature forms
334
+ # (key: local frame)
335
+ self._hash = -1
336
+
337
+ def _del_derived(self):
338
+ r"""
339
+ Delete the derived quantities.
340
+
341
+ TESTS::
342
+
343
+ sage: M = Manifold(4, 'M')
344
+ sage: E = M.vector_bundle(2, 'E')
345
+ sage: nab = E.bundle_connection('nabla', latex_name=r'\nabla')
346
+ sage: nab._del_derived()
347
+ """
348
+ self._curvature_forms.clear()
349
+
350
+ def __eq__(self, other):
351
+ r"""
352
+ Comparison (equality) operator.
353
+
354
+ INPUT:
355
+
356
+ - ``other`` -- a bundle connection
357
+
358
+ OUTPUT: ``True`` if ``self`` is equal to ``other`` and ``False`` otherwise
359
+
360
+ TESTS::
361
+
362
+ sage: M = Manifold(2, 'M')
363
+ sage: X.<x,y> = M.chart()
364
+ sage: E = M.vector_bundle(2, 'E')
365
+ sage: e = E.local_frame('e') # standard frame for E
366
+ sage: nab = E.bundle_connection('nabla', latex_name=r'\nabla')
367
+ sage: nab[:] = 0
368
+ sage: nab[0, 1][:] = [x^2, x]
369
+ sage: nab[1, 0][:] = [y^2, y]
370
+ sage: nab1 = E.bundle_connection('nabla', latex_name=r'\nabla')
371
+ sage: nab1[:] = 0
372
+ sage: (nab1 == nab) or (nab == nab1)
373
+ False
374
+ sage: nab1[0, 1][:] = [x, x^2]
375
+ sage: nab1[1, 0][:] = [y, y^2]
376
+ sage: (nab1 == nab) or (nab == nab1)
377
+ False
378
+ sage: nab1[0, 1][:] = [x^2, x]
379
+ sage: nab1[1, 0][:] = [y^2, y]
380
+ sage: (nab1 == nab) and (nab == nab1)
381
+ True
382
+ """
383
+ if other is self:
384
+ return True
385
+ if not isinstance(other, BundleConnection):
386
+ return False
387
+ if other._domain != self._domain:
388
+ return False
389
+ if self._connection_forms == {}:
390
+ return False
391
+ for frame in self._connection_forms:
392
+ if frame not in other._connection_forms:
393
+ return False
394
+ for ind in self._connection_forms[frame]:
395
+ if (other._connection_forms[frame][ind] !=
396
+ self._connection_forms[frame][ind]):
397
+ return False
398
+ return True
399
+
400
+ def __ne__(self, other):
401
+ r"""
402
+ Inequality operator.
403
+
404
+ INPUT:
405
+
406
+ - ``other`` -- an affine connection
407
+
408
+ OUTPUT:
409
+
410
+ - ``True`` if ``self`` is different from ``other`` and ``False``
411
+ otherwise
412
+
413
+ TESTS::
414
+
415
+ sage: M = Manifold(2, 'M')
416
+ sage: X.<x,y> = M.chart()
417
+ sage: E = M.vector_bundle(2, 'E')
418
+ sage: e = E.local_frame('e') # standard frame for E
419
+ sage: nab = E.bundle_connection('nabla', latex_name=r'\nabla')
420
+ sage: nab[:] = 0
421
+ sage: nab[0, 1][:] = [x^2, x]
422
+ sage: nab[1, 0][:] = [y^2, y]
423
+ sage: nab1 = E.bundle_connection('nabla', latex_name=r'\nabla')
424
+ sage: nab1[:] = 0
425
+ sage: (nab1 != nab) and (nab != nab1)
426
+ True
427
+ sage: nab1[0, 1][:] = [x, x^2]
428
+ sage: nab1[1, 0][:] = [y, y^2]
429
+ sage: (nab1 != nab) and (nab != nab1)
430
+ True
431
+ sage: nab1[0, 1][:] = [x^2, x]
432
+ sage: nab1[1, 0][:] = [y^2, y]
433
+ sage: (nab1 != nab) or (nab != nab1)
434
+ False
435
+ """
436
+ return not (self == other)
437
+
438
+ def vector_bundle(self):
439
+ r"""
440
+ Return the vector bundle on which the bundle connection is defined.
441
+
442
+ OUTPUT:
443
+
444
+ - instance of class
445
+ :class:`~sage.manifolds.differentiable.vector_bundle.DifferentiableVectorBundle`
446
+ representing the vector bundle on which ``self`` is defined.
447
+
448
+ EXAMPLES::
449
+
450
+ sage: M = Manifold(3, 'M', start_index=1)
451
+ sage: c_xyz.<x,y,z> = M.chart()
452
+ sage: E = M.vector_bundle(2, 'E')
453
+ sage: nab = E.bundle_connection('nabla', r'\nabla')
454
+ sage: nab.vector_bundle()
455
+ Differentiable real vector bundle E -> M of rank 2 over the base
456
+ space 3-dimensional differentiable manifold M
457
+ """
458
+ return self._vbundle
459
+
460
+ def _new_forms(self, frame):
461
+ r"""
462
+ Create the connection forms w.r.t. the given frame.
463
+
464
+ TESTS::
465
+
466
+ sage: M = Manifold(2, 'M', start_index=1)
467
+ sage: X.<x,y> = M.chart()
468
+ sage: E = M.vector_bundle(2, 'E')
469
+ sage: e = E.local_frame('e')
470
+ sage: nab = E.bundle_connection('nabla', latex_name=r'\nabla')
471
+ sage: forms = nab._new_forms(e)
472
+ sage: [forms[k] for k in sorted(forms)]
473
+ [1-form connection (1,1) of bundle connection nabla w.r.t. Local
474
+ frame (E|_M, (e_1,e_2)) on the 2-dimensional differentiable
475
+ manifold M,
476
+ 1-form connection (1,2) of bundle connection nabla w.r.t. Local
477
+ frame (E|_M, (e_1,e_2)) on the 2-dimensional differentiable
478
+ manifold M,
479
+ 1-form connection (2,1) of bundle connection nabla w.r.t. Local
480
+ frame (E|_M, (e_1,e_2)) on the 2-dimensional differentiable
481
+ manifold M,
482
+ 1-form connection (2,2) of bundle connection nabla w.r.t. Local
483
+ frame (E|_M, (e_1,e_2)) on the 2-dimensional differentiable
484
+ manifold M]
485
+ """
486
+ dom = frame._domain
487
+ forms_dict = {}
488
+ for i in self._vbundle.irange():
489
+ for j in self._vbundle.irange():
490
+ # set names:
491
+ name = "connection ({},{}) of bundle ".format(i, j)
492
+ name += "connection " + self._name + " w.r.t. {}".format(frame)
493
+ latex_name = r"\omega^" + str(j) + r"_{\ \, " + str(i) + "}"
494
+ form = dom.diff_form(1, name=name, latex_name=latex_name)
495
+ forms_dict[(i, j)] = form
496
+ return forms_dict
497
+
498
+ def connection_forms(self, frame=None):
499
+ r"""
500
+ Return the connection forms relative to the given frame.
501
+
502
+ If `e` is a local frame on `E`, we have
503
+
504
+ .. MATH::
505
+
506
+ \nabla e_i = \sum^n_{j=1} e_j \otimes \omega^j_i ,
507
+
508
+ and the corresponding `n \times n`-matrix `(\omega^j_i)_{i,j}`
509
+ consisting of one forms is called *connection matrix of* `\nabla` *with
510
+ respect to* `e`.
511
+
512
+ If the connection coefficients are not known already, they are computed
513
+ from the above formula.
514
+
515
+ INPUT:
516
+
517
+ - ``frame`` -- (default: ``None``) local frame relative to which the
518
+ connection forms are required; if none is provided, the
519
+ vector bundle's default frame is assumed
520
+
521
+ OUTPUT:
522
+
523
+ - connection forms relative to the frame ``frame``, as a dictionary
524
+ with tuples `(i, j)` as key and one forms as instances of
525
+ :class:`~sage.manifolds.differentiable.diff_form` as value
526
+ representing the matrix entries.
527
+
528
+ EXAMPLES:
529
+
530
+ Connection forms of a bundle connection on a rank 2 vector bundle
531
+ over a 3-dimensional manifold::
532
+
533
+ sage: M = Manifold(3, 'M', start_index=1)
534
+ sage: c_xyz.<x,y,z> = M.chart()
535
+ sage: E = M.vector_bundle(2, 'E')
536
+ sage: e = E.local_frame('e')
537
+ sage: nab = E.bundle_connection('nabla', r'\nabla')
538
+ sage: nab[:] = 0 # initialize curvature forms
539
+ sage: forms = nab.connection_forms()
540
+ sage: [forms[k] for k in sorted(forms)]
541
+ [1-form connection (1,1) of bundle connection nabla w.r.t. Local
542
+ frame (E|_M, (e_1,e_2)) on the 3-dimensional differentiable
543
+ manifold M,
544
+ 1-form connection (1,2) of bundle connection nabla w.r.t. Local
545
+ frame (E|_M, (e_1,e_2)) on the 3-dimensional differentiable
546
+ manifold M,
547
+ 1-form connection (2,1) of bundle connection nabla w.r.t. Local
548
+ frame (E|_M, (e_1,e_2)) on the 3-dimensional differentiable
549
+ manifold M,
550
+ 1-form connection (2,2) of bundle connection nabla w.r.t. Local
551
+ frame (E|_M, (e_1,e_2)) on the 3-dimensional differentiable
552
+ manifold M]
553
+ """
554
+ if frame is None:
555
+ smodule = self._vbundle.section_module(domain=self._domain)
556
+ frame = smodule.default_frame()
557
+ if frame is None:
558
+ raise ValueError("a frame must be provided")
559
+ if frame not in self._connection_forms:
560
+ # the connection forms must be computed
561
+ #
562
+ # Check whether frame is a subframe of a frame in which the
563
+ # forms are already known:
564
+ for oframe in self._connection_forms:
565
+ if frame in oframe._subframes:
566
+ self._connection_forms[frame] = self._new_forms(frame)
567
+ comp_store = self._connection_forms[frame]
568
+ ocomp_store = self._connection_forms[oframe]
569
+ for ind, value in ocomp_store.items():
570
+ comp_store[ind] = value.restrict(frame._domain)
571
+ break
572
+ else:
573
+ # If not, the forms must be computed from scratch:
574
+ vb = self._vbundle
575
+ dom = frame._domain
576
+ vframe = dom.default_frame()
577
+ # it is important to use _new_forms instead of
578
+ # self.set_connection_form:
579
+ omega = self._new_forms(frame)
580
+ for d in dom.irange():
581
+ for i in vb.irange():
582
+ sec_nab = self(vframe[d], frame[i])
583
+ for j in vb.irange():
584
+ omega[(i, j)][vframe, d] = sec_nab[[frame, j]]
585
+ self._connection_forms[frame] = omega
586
+ return self._connection_forms[frame]
587
+
588
+ def connection_form(self, i, j, frame=None):
589
+ r"""
590
+ Return the connection 1-form corresponding to the given index and
591
+ local frame.
592
+
593
+ .. SEEALSO::
594
+
595
+ Consult :meth:`connection_forms` for detailed information.
596
+
597
+ INPUT:
598
+
599
+ - ``i``, ``j`` -- indices identifying the 1-form `\omega^j_i`
600
+ - ``frame`` -- (default: ``None``) local frame relative to which the
601
+ connection 1-forms are defined; if ``None``, the default frame of the
602
+ vector bundle's corresponding section module is assumed.
603
+
604
+ OUTPUT:
605
+
606
+ - the 1-form `\omega^j_i`, as an instance of
607
+ :class:`~sage.manifolds.differentiable.diff_form.DiffForm`
608
+
609
+ EXAMPLES::
610
+
611
+ sage: M = Manifold(2, 'M')
612
+ sage: X.<x,y> = M.chart()
613
+ sage: E = M.vector_bundle(2, 'E')
614
+ sage: e = E.local_frame('e') # standard frame for E
615
+ sage: nab = E.bundle_connection('nabla', latex_name=r'\nabla')
616
+ sage: nab.set_connection_form(0, 1)[:] = [x^2, x]
617
+ sage: nab.set_connection_form(1, 0)[:] = [y^2, y]
618
+ sage: nab.connection_form(0, 1).display()
619
+ connection (0,1) of bundle connection nabla w.r.t. Local frame
620
+ (E|_M, (e_0,e_1)) = x^2 dx + x dy
621
+ sage: nab.connection_form(1, 0).display()
622
+ connection (1,0) of bundle connection nabla w.r.t. Local frame
623
+ (E|_M, (e_0,e_1)) = y^2 dx + y dy
624
+ """
625
+ return self.connection_forms(frame)[(i, j)]
626
+
627
+ def __call__(self, v, s):
628
+ r"""
629
+ Action of the connection on a vector field and local section.
630
+
631
+ INPUT:
632
+
633
+ - ``v`` -- a vector field `v` on the base space
634
+ - ``s`` -- a local section `s`
635
+
636
+ OUTPUT: local section `\nabla_v s`
637
+
638
+ TESTS::
639
+
640
+ sage: M = Manifold(2, 'M', start_index=1)
641
+ sage: X.<x,y> = M.chart()
642
+ sage: E = M.vector_bundle(2, 'E')
643
+ sage: e = E.local_frame('e')
644
+ sage: nab = E.bundle_connection('nabla', latex_name=r'\nabla')
645
+ sage: nab[:] = 0
646
+ sage: nab[1,2][1] = x*y
647
+ sage: v = M.vector_field('v')
648
+ sage: v[:] = [-y, x]
649
+ sage: s = E.section('s')
650
+ sage: s[:] = [y, -x]
651
+ sage: nab.__call__(v, s)
652
+ Section nabla_v(s) on the 2-dimensional differentiable manifold M
653
+ with values in the real vector bundle E of rank 2
654
+ """
655
+ from sage.manifolds.section import TrivialSection
656
+ from sage.tensor.modules.format_utilities import format_unop_latex
657
+ if isinstance(s, TrivialSection):
658
+ return self._derive_trivial(v, s)
659
+ # Resulting section
660
+ vb = self._vbundle
661
+ dom = s.domain()
662
+ if s._name is None or v._name:
663
+ name_resu = None
664
+ else:
665
+ name_resu = self._name + '_' + v._name + '(' + s._name + ')'
666
+ if s._latex_name is None or v._latex_name is None:
667
+ latex_name_resu = None
668
+ else:
669
+ nab_v_latex = self._latex_name + '_{' + v._latex_name + '} '
670
+ latex_name_resu = format_unop_latex(nab_v_latex, s._latex_name)
671
+ resu = vb.section(domain=dom, name=name_resu,
672
+ latex_name=latex_name_resu)
673
+ # gluing process
674
+ for dom, rst in s._restrictions.items():
675
+ # the computation is performed only if dom is not a subdomain
676
+ # of another restriction:
677
+ for odom in s._restrictions:
678
+ if dom in odom._subsets and dom is not odom:
679
+ break
680
+ else:
681
+ # dom is not a subdomain and the computation is performed:
682
+ resu._restrictions[rst._domain] = self(rst)
683
+ return resu
684
+
685
+ def _derive_trivial(self, v, s):
686
+ r"""
687
+ Action of the connection on a local section whose module is free.
688
+
689
+ INPUT:
690
+
691
+ - ``v`` -- a vector field `v` on the base space
692
+ - ``s`` -- a local section `s` whose module is free
693
+
694
+ OUTPUT: local section `\nabla_v s`
695
+
696
+ TESTS::
697
+
698
+ sage: M = Manifold(2, 'M', start_index=1)
699
+ sage: X.<x,y> = M.chart()
700
+ sage: E = M.vector_bundle(2, 'E')
701
+ sage: e = E.local_frame('e')
702
+ sage: nab = E.bundle_connection('nabla', latex_name=r'\nabla')
703
+ sage: nab[:] = 0
704
+ sage: nab[1,2][1] = x*y
705
+ sage: v = M.vector_field('v')
706
+ sage: v[:] = [-y, x]
707
+ sage: s = E.section('s')
708
+ sage: s[:] = [y, -x]
709
+ sage: nab._derive_trivial(v, s)
710
+ Section nabla_v(s) on the 2-dimensional differentiable manifold M
711
+ with values in the real vector bundle E of rank 2
712
+ """
713
+ vb = self._vbundle
714
+ dom = s.domain()
715
+ # pick the first frame whose forms of self on dom are known
716
+ for frame in self._connection_forms:
717
+ if dom.is_subset(frame.domain()):
718
+ frame = frame.restrict(dom)
719
+ break
720
+ else:
721
+ raise ValueError("no local frame found for the computation")
722
+ # Resulting section
723
+ from sage.tensor.modules.format_utilities import format_unop_latex
724
+ if s._name is None or v._name is None:
725
+ name_resu = None
726
+ else:
727
+ name_resu = self._name + '_' + v._name + '(' + s._name + ')'
728
+ if s._latex_name is None or v._latex_name is None:
729
+ latex_name_resu = None
730
+ else:
731
+ nab_v_latex = self._latex_name + '_{' + v._latex_name + '} '
732
+ latex_name_resu = format_unop_latex(nab_v_latex, s._latex_name)
733
+ res = vb.section(domain=dom, name=name_resu,
734
+ latex_name=latex_name_resu)
735
+ for j in vb.irange():
736
+ ds_comp = s[[frame, j]].differential()
737
+ res_comp = ds_comp(v)
738
+ res_comp += sum(s[[frame, i]] * self[frame, i, j](v)
739
+ for i in vb.irange())
740
+ res[frame, j] = res_comp
741
+ return res
742
+
743
+ def add_connection_form(self, i, j, frame=None):
744
+ r"""
745
+ Return the connection form `\omega^j_i` in a given frame for
746
+ assignment.
747
+
748
+ See method :meth:`connection_forms` for details about the definition of
749
+ the connection forms.
750
+
751
+ To delete the connection forms in other frames, use the method
752
+ :meth:`set_connection_form` instead.
753
+
754
+ INPUT:
755
+
756
+ - ``i``, ``j`` -- indices identifying the 1-form `\omega^j_i`
757
+ - ``frame`` -- (default: ``None``) local frame in which the connection
758
+ 1-form is defined; if ``None``, the default frame of the vector
759
+ bundle is assumed.
760
+
761
+ .. WARNING::
762
+
763
+ If the connection has already forms in other frames, it is the
764
+ user's responsibility to make sure that the 1-forms to be added
765
+ are consistent with them.
766
+
767
+ OUTPUT:
768
+
769
+ - connection 1-form `\omega^j_i` in the given frame, as an instance of
770
+ the class :class:`~sage.manifolds.differentiable.diff_form.DiffForm`;
771
+ if such connection 1-form did not exist previously, it is created.
772
+ See method :meth:`connection_forms` for the storage convention of the
773
+ connection 1-forms.
774
+
775
+ EXAMPLES::
776
+
777
+ sage: M = Manifold(2, 'M')
778
+ sage: X.<x,y> = M.chart()
779
+ sage: E = M.vector_bundle(2, 'E')
780
+ sage: e = E.local_frame('e') # standard frame for E
781
+ sage: nab = E.bundle_connection('nabla', latex_name=r'\nabla')
782
+ sage: nab.add_connection_form(0, 1, frame=e)[:] = [x^2, x]
783
+ sage: nab[e, 0, 1].display()
784
+ connection (0,1) of bundle connection nabla w.r.t. Local frame
785
+ (E|_M, (e_0,e_1)) = x^2 dx + x dy
786
+
787
+ Since ``e`` is the vector bundle's default local frame, its mention may
788
+ be omitted::
789
+
790
+ sage: nab.add_connection_form(1, 0)[:] = [y^2, y]
791
+ sage: nab[1, 0].display()
792
+ connection (1,0) of bundle connection nabla w.r.t. Local frame
793
+ (E|_M, (e_0,e_1)) = y^2 dx + y dy
794
+
795
+ Adding connection 1-forms w.r.t. to another local frame::
796
+
797
+ sage: f = E.local_frame('f')
798
+ sage: nab.add_connection_form(1, 1, frame=f)[:] = [x, y]
799
+ sage: nab[f, 1, 1].display()
800
+ connection (1,1) of bundle connection nabla w.r.t. Local frame
801
+ (E|_M, (f_0,f_1)) = x dx + y dy
802
+
803
+ The forms w.r.t. the frame ``e`` have been kept::
804
+
805
+ sage: nab[e, 0, 1].display()
806
+ connection (0,1) of bundle connection nabla w.r.t. Local frame
807
+ (E|_M, (e_0,e_1)) = x^2 dx + x dy
808
+
809
+ To delete them, use the method :meth:`set_connection_form` instead.
810
+ """
811
+ self._require_mutable()
812
+ if frame is None:
813
+ smodule = self._vbundle.section_module(domain=self._domain)
814
+ frame = smodule.default_frame()
815
+ if frame is None:
816
+ raise ValueError("a frame must be provided")
817
+ # Are the components already known?
818
+ if frame not in self._connection_forms:
819
+ if frame not in self._vbundle._frames:
820
+ raise ValueError("the {} is not".format(frame) +
821
+ " a frame on the {}".format(self._domain))
822
+ self._connection_forms[frame] = self._new_forms(frame)
823
+ self._del_derived() # deletes the derived quantities
824
+ return self._connection_forms[frame][(i, j)]
825
+
826
+ def set_connection_form(self, i, j, frame=None):
827
+ r"""
828
+ Return the connection form `\omega^j_i` in a given frame for
829
+ assignment.
830
+
831
+ See method :meth:`connection_forms` for details about the definition of
832
+ the connection forms.
833
+
834
+ The connection forms with respect to other frames are deleted,
835
+ in order to avoid any inconsistency. To keep them, use the method
836
+ :meth:`add_connection_form` instead.
837
+
838
+ INPUT:
839
+
840
+ - ``i``, ``j`` -- indices identifying the 1-form `\omega^j_i`
841
+ - ``frame`` -- (default: ``None``) local frame in which the connection
842
+ 1-form is defined; if ``None``, the default frame of the vector
843
+ bundle is assumed.
844
+
845
+ OUTPUT:
846
+
847
+ - connection 1-form `\omega^j_i` in the given frame, as an instance of
848
+ the class :class:`~sage.manifolds.differentiable.diff_form.DiffForm`;
849
+ if such connection 1-form did not exist previously, it is created.
850
+ See method :meth:`connection_forms` for the storage convention of the
851
+ connection 1-forms.
852
+
853
+ EXAMPLES:
854
+
855
+ Setting the connection forms of a bundle connection w.r.t. some local
856
+ frame::
857
+
858
+ sage: M = Manifold(2, 'M')
859
+ sage: X.<x,y> = M.chart()
860
+ sage: E = M.vector_bundle(2, 'E')
861
+ sage: e = E.local_frame('e') # standard frame for E
862
+ sage: nab = E.bundle_connection('nabla', latex_name=r'\nabla')
863
+ sage: nab.set_connection_form(0, 1)[:] = [x^2, x]
864
+ sage: nab[0, 1].display()
865
+ connection (0,1) of bundle connection nabla w.r.t. Local frame
866
+ (E|_M, (e_0,e_1)) = x^2 dx + x dy
867
+
868
+ Since ``e`` is the vector bundle's default local frame, its mention may
869
+ be omitted::
870
+
871
+ sage: nab.set_connection_form(1, 0)[:] = [y^2, y]
872
+ sage: nab[1, 0].display()
873
+ connection (1,0) of bundle connection nabla w.r.t. Local frame
874
+ (E|_M, (e_0,e_1)) = y^2 dx + y dy
875
+
876
+ Setting connection 1-forms w.r.t. to another local frame::
877
+
878
+ sage: f = E.local_frame('f')
879
+ sage: nab.set_connection_form(1, 1, frame=f)[:] = [x, y]
880
+ sage: nab[f, 1, 1].display()
881
+ connection (1,1) of bundle connection nabla w.r.t. Local frame
882
+ (E|_M, (f_0,f_1)) = x dx + y dy
883
+
884
+ The forms w.r.t. the frame ``e`` have been deleted::
885
+
886
+ sage: nab[e, 0, 1].display()
887
+ Traceback (most recent call last):
888
+ ...
889
+ ValueError: no basis could be found for computing the components in
890
+ the Local frame (E|_M, (f_0,f_1))
891
+
892
+ To keep them, use the method :meth:`add_connection_form` instead.
893
+ """
894
+ self._require_mutable()
895
+ omega = self.add_connection_form(i, j, frame=frame)
896
+ self.del_other_forms(frame)
897
+ return omega
898
+
899
+ def del_other_forms(self, frame=None):
900
+ r"""
901
+ Delete all the connection forms but those corresponding to ``frame``.
902
+
903
+ INPUT:
904
+
905
+ - ``frame`` -- (default: ``None``) local frame, the connection forms
906
+ w.r.t. which are to be kept; if ``None``, the default frame of the
907
+ vector bundle is assumed.
908
+
909
+ EXAMPLES:
910
+
911
+ We first create two sets of connection forms::
912
+
913
+ sage: M = Manifold(2, 'M', start_index=1)
914
+ sage: X.<x,y> = M.chart()
915
+ sage: E = M.vector_bundle(2, 'E')
916
+ sage: nab = E.bundle_connection('nabla', latex_name=r'\nabla')
917
+ sage: e = E.local_frame('e')
918
+ sage: nab.set_connection_form(1, 1, frame=e)[:] = [x^2, x]
919
+ sage: f = E.local_frame('f')
920
+ sage: nab.add_connection_form(1, 1, frame=f)[:] = [y^2, y]
921
+ sage: nab[e, 1, 1].display()
922
+ connection (1,1) of bundle connection nabla w.r.t. Local frame
923
+ (E|_M, (e_1,e_2)) = x^2 dx + x dy
924
+ sage: nab[f, 1, 1].display()
925
+ connection (1,1) of bundle connection nabla w.r.t. Local frame
926
+ (E|_M, (f_1,f_2)) = y^2 dx + y dy
927
+
928
+ Let us delete the connection forms w.r.t. all frames except for
929
+ frame ``e``::
930
+
931
+ sage: nab.del_other_forms(e)
932
+ sage: nab[e, 1, 1].display()
933
+ connection (1,1) of bundle connection nabla w.r.t. Local frame
934
+ (E|_M, (e_1,e_2)) = x^2 dx + x dy
935
+
936
+ The connection forms w.r.t. frame ``e`` have indeed been
937
+ deleted::
938
+
939
+ sage: nab[f, :]
940
+ Traceback (most recent call last):
941
+ ...
942
+ ValueError: no basis could be found for computing the components in
943
+ the Local frame (E|_M, (e_1,e_2))
944
+ """
945
+ if frame is None:
946
+ smodule = self._vbundle.section_module(domain=self._domain)
947
+ frame = smodule.default_frame()
948
+ if frame is None:
949
+ raise ValueError("a frame must be provided")
950
+ if frame not in self._connection_forms:
951
+ raise ValueError("the coefficients w.r.t. {}".format(frame) +
952
+ " have not been defined")
953
+ to_be_deleted = []
954
+ for other_frame in self._connection_forms:
955
+ if other_frame != frame:
956
+ to_be_deleted.append(other_frame)
957
+ for other_frame in to_be_deleted:
958
+ del self._connection_forms[other_frame]
959
+
960
+ def curvature_form(self, i, j, frame=None):
961
+ r"""
962
+ Return the curvature 2-form corresponding to the given index and local
963
+ frame.
964
+
965
+ The *curvature 2-forms* with respect to the frame `e` are the 2-forms
966
+ `\Omega^j_i` given by the formula
967
+
968
+ .. MATH::
969
+
970
+ \Omega^j_i = \mathrm{d} \omega^j_i + \sum^n_{k=1} \omega^j_k
971
+ \wedge \omega^k_i
972
+
973
+ INPUT:
974
+
975
+ - ``i``, ``j`` -- indices identifying the 2-form `\Omega^j_i`
976
+ - ``frame`` -- (default: ``None``) local frame relative to which the
977
+ curvature 2-forms are defined; if ``None``, the default frame
978
+ of the vector bundle is assumed.
979
+
980
+ OUTPUT:
981
+
982
+ - the 2-form `\Omega^j_i`, as an instance of
983
+ :class:`~sage.manifolds.differentiable.diff_form.DiffForm`
984
+
985
+ EXAMPLES::
986
+
987
+ sage: M = Manifold(2, 'M', start_index=1)
988
+ sage: X.<x,y> = M.chart()
989
+ sage: E = M.vector_bundle(1, 'E')
990
+ sage: nab = E.bundle_connection('nabla', latex_name=r'\nabla')
991
+ sage: e = E.local_frame('e')
992
+ sage: nab.set_connection_form(1, 1)[:] = [x^2, x]
993
+ sage: curv = nab.curvature_form(1, 1); curv
994
+ 2-form curvature (1,1) of bundle connection nabla w.r.t. Local
995
+ frame (E|_M, (e_1)) on the 2-dimensional differentiable manifold M
996
+ sage: curv.display()
997
+ curvature (1,1) of bundle connection nabla w.r.t. Local frame
998
+ (E|_M, (e_1)) = dx∧dy
999
+ """
1000
+ if frame is None:
1001
+ smodule = self._vbundle.section_module(domain=self._domain)
1002
+ frame = smodule.default_frame()
1003
+ if frame is None:
1004
+ raise ValueError("a frame must be provided")
1005
+ if frame not in self._curvature_forms:
1006
+ self._curvature_forms[frame] = {}
1007
+ if (i, j) not in self._curvature_forms[frame]:
1008
+ name = "curvature ({},{}) of bundle connection ".format(i, j) + \
1009
+ self._name + " w.r.t. {}".format(frame)
1010
+ latex_name = r"\Omega^" + str(i) + r"_{\ \, " + \
1011
+ str(j) + "}"
1012
+ omega = self.connection_form
1013
+ curv_form = omega(i, j, frame).exterior_derivative()
1014
+ curv_form += sum(omega(k, j, frame).wedge(omega(i, k, frame))
1015
+ for k in self._vbundle.irange())
1016
+ curv_form.set_name(name=name, latex_name=latex_name)
1017
+ self._curvature_forms[frame][(i, j)] = curv_form
1018
+ return self._curvature_forms[frame][(i, j)]
1019
+
1020
+ def __hash__(self):
1021
+ r"""
1022
+ Hash function.
1023
+
1024
+ TESTS::
1025
+
1026
+ sage: M = Manifold(2, 'M')
1027
+ sage: X.<x,y> = M.chart()
1028
+ sage: E = M.vector_bundle(2, 'E')
1029
+ sage: nab = E.bundle_connection('nabla', latex_name=r'\nabla')
1030
+ sage: hash(nab)
1031
+ Traceback (most recent call last):
1032
+ ...
1033
+ ValueError: object is mutable; please make it immutable first
1034
+ sage: nab.set_immutable()
1035
+ sage: hash(nab) == nab.__hash__()
1036
+ True
1037
+
1038
+ Let us check that ``nab`` can be used as a dictionary key::
1039
+
1040
+ sage: {nab: 1}[nab]
1041
+ 1
1042
+ """
1043
+ self._require_immutable()
1044
+ if self._hash == -1:
1045
+ self._hash = hash((type(self).__name__, self._vbundle))
1046
+ return self._hash
1047
+
1048
+ def __getitem__(self, args):
1049
+ r"""
1050
+ Return a component of ``self`` with respect to some frame.
1051
+
1052
+ INPUT:
1053
+
1054
+ - ``args`` -- list of indices defining the component; if ``[:]`` is
1055
+ provided, all the components are returned
1056
+
1057
+ TESTS::
1058
+
1059
+ sage: M = Manifold(2, 'M', start_index=1)
1060
+ sage: X.<x,y> = M.chart()
1061
+ sage: E = M.vector_bundle(2, 'E')
1062
+ sage: nab = E.bundle_connection('nabla')
1063
+ sage: e = E.local_frame('e')
1064
+ sage: nab[:] = 0
1065
+ sage: nab[1, 2][:] = [x^2, x]
1066
+ sage: nab[1, 1][:] = [y, y]
1067
+ sage: nab[1, 1].display()
1068
+ connection (1,1) of bundle connection nabla w.r.t. Local frame
1069
+ (E|_M, (e_1,e_2)) = y dx + y dy
1070
+ sage: nab[e, 1, 2].display()
1071
+ connection (1,2) of bundle connection nabla w.r.t. Local frame
1072
+ (E|_M, (e_1,e_2)) = x^2 dx + x dy
1073
+ sage: nab[e, :]
1074
+ [[1-form connection (1,1) of bundle connection nabla w.r.t. Local
1075
+ frame (E|_M, (e_1,e_2)) on the 2-dimensional differentiable
1076
+ manifold M,
1077
+ 1-form connection (1,2) of bundle connection nabla w.r.t. Local
1078
+ frame (E|_M, (e_1,e_2)) on the 2-dimensional differentiable
1079
+ manifold M],
1080
+ [1-form connection (2,1) of bundle connection nabla w.r.t. Local
1081
+ frame (E|_M, (e_1,e_2)) on the 2-dimensional differentiable
1082
+ manifold M,
1083
+ 1-form connection (2,2) of bundle connection nabla w.r.t. Local
1084
+ frame (E|_M, (e_1,e_2)) on the 2-dimensional differentiable
1085
+ manifold M]]
1086
+ sage: nab[:]
1087
+ [[1-form connection (1,1) of bundle connection nabla w.r.t. Local
1088
+ frame (E|_M, (e_1,e_2)) on the 2-dimensional differentiable
1089
+ manifold M,
1090
+ 1-form connection (1,2) of bundle connection nabla w.r.t. Local
1091
+ frame (E|_M, (e_1,e_2)) on the 2-dimensional differentiable
1092
+ manifold M],
1093
+ [1-form connection (2,1) of bundle connection nabla w.r.t. Local
1094
+ frame (E|_M, (e_1,e_2)) on the 2-dimensional differentiable
1095
+ manifold M,
1096
+ 1-form connection (2,2) of bundle connection nabla w.r.t. Local
1097
+ frame (E|_M, (e_1,e_2)) on the 2-dimensional differentiable
1098
+ manifold M]]
1099
+ """
1100
+ # extract frame from first index:
1101
+ vb = self._vbundle
1102
+ if isinstance(args, (int, Integer, slice)):
1103
+ smodule = vb.section_module(domain=self._domain)
1104
+ frame = smodule.default_frame()
1105
+ elif not isinstance(args[0], (int, Integer, slice)):
1106
+ frame = args[0]
1107
+ args = args[1:]
1108
+ else:
1109
+ smodule = vb.section_module(domain=self._domain)
1110
+ frame = smodule.default_frame()
1111
+ # indexing:
1112
+ if isinstance(args, slice):
1113
+ indices = args
1114
+ elif isinstance(args[0], slice):
1115
+ indices = args[0]
1116
+ else:
1117
+ indices = args
1118
+ if isinstance(indices, slice):
1119
+ if indices.start is None and indices.stop is None:
1120
+ return [[self.connection_form(i, j, frame=frame)
1121
+ for j in vb.irange()] for i in vb.irange()]
1122
+ else:
1123
+ raise NotImplementedError("[start:stop] syntax not "
1124
+ "implemented")
1125
+ if len(indices) != 2:
1126
+ raise ValueError("index must be a pair of integers")
1127
+ (i, j) = indices
1128
+ if i not in vb.irange() or j not in vb.irange():
1129
+ raise IndexError("index out of range")
1130
+ form = self.connection_form(indices[0], indices[1], frame=frame)
1131
+ return form
1132
+
1133
+ def __setitem__(self, args, value):
1134
+ r"""
1135
+ Set the components of ``self`` corresponding to the given indices.
1136
+
1137
+ INPUT:
1138
+
1139
+ - ``args`` -- list of indices (usually a pair of integers); if ``[:]``
1140
+ is provided, all the components are set
1141
+ - ``value`` -- the value to be set or a list of values if
1142
+ ``args = [:]``
1143
+
1144
+ TESTS::
1145
+
1146
+ sage: M = Manifold(2, 'M', start_index=1)
1147
+ sage: X.<x,y> = M.chart()
1148
+ sage: E = M.vector_bundle(2, 'E')
1149
+ sage: nab = E.bundle_connection('nabla')
1150
+ sage: e = E.local_frame('e')
1151
+ sage: a = M.one_form([x^2, x], name='a')
1152
+ sage: a.display()
1153
+ a = x^2 dx + x dy
1154
+ sage: nab[:] = 0
1155
+ sage: nab[1, 1] = a
1156
+ sage: nab[1, 1].display()
1157
+ connection (1,1) of bundle connection nabla w.r.t. Local frame
1158
+ (E|_M, (e_1,e_2)) = x^2 dx + x dy
1159
+ sage: nab[e, 2, 2] = a
1160
+ sage: nab[e, 2, 2].display()
1161
+ connection (2,2) of bundle connection nabla w.r.t. Local frame
1162
+ (E|_M, (e_1,e_2)) = x^2 dx + x dy
1163
+ sage: nab[:] = [[0, 0], [a, a]]
1164
+ sage: nab[e, 2, 1].display()
1165
+ connection (2,1) of bundle connection nabla w.r.t. Local frame
1166
+ (E|_M, (e_1,e_2)) = x^2 dx + x dy
1167
+ sage: nab[e, :] = [[a, a], [0, 0]]
1168
+ sage: nab[e, 1, 2].display()
1169
+ connection (1,2) of bundle connection nabla w.r.t. Local frame
1170
+ (E|_M, (e_1,e_2)) = x^2 dx + x dy
1171
+ """
1172
+ # extract frame from first index:
1173
+ vb = self._vbundle
1174
+ if isinstance(args, (int, Integer, slice)):
1175
+ smodule = vb.section_module(domain=self._domain)
1176
+ frame = smodule.default_frame()
1177
+ elif not isinstance(args[0], (int, Integer, slice)):
1178
+ frame = args[0]
1179
+ args = args[1:]
1180
+ else:
1181
+ smodule = vb.section_module(domain=self._domain)
1182
+ frame = smodule.default_frame()
1183
+ # determine indices:
1184
+ if isinstance(args, slice):
1185
+ indices = args
1186
+ elif isinstance(args[0], slice):
1187
+ indices = args[0]
1188
+ else:
1189
+ indices = args
1190
+ # set values:
1191
+ if isinstance(indices, (list, tuple)):
1192
+ if len(indices) != 2:
1193
+ raise IndexError("a tuple of integers must be provided")
1194
+ (i, j) = indices
1195
+ if i not in vb.irange() or j not in vb.irange():
1196
+ raise IndexError("index out of range")
1197
+ omega = self.set_connection_form(i, j, frame=frame)
1198
+ dom = frame.domain()
1199
+ dmodule = dom.diff_form_module(1)
1200
+ try:
1201
+ form = dmodule(value)
1202
+ except (TypeError, ValueError):
1203
+ msg = "{} must be convertible ".format(value)
1204
+ msg += "into an element of {}".format(dmodule)
1205
+ raise TypeError(msg)
1206
+ omega.copy_from(form) # copy all components from value
1207
+ if isinstance(indices, slice):
1208
+ if indices.start is None and indices.stop is None:
1209
+ # check types:
1210
+ if isinstance(value, (int, Integer)) and value == 0:
1211
+ for i in vb.irange():
1212
+ for j in vb.irange():
1213
+ self[frame, i, j] = 0
1214
+ elif not isinstance(value, (list, tuple)):
1215
+ raise TypeError("in case of [:] syntax, zero or a "
1216
+ "list/tuple as value should be provided")
1217
+ elif any(not isinstance(row, (list, tuple)) for row in value):
1218
+ raise TypeError("in case of [:] syntax, the list/tuple "
1219
+ "of value must contain lists/tuples")
1220
+ else:
1221
+ # check lengths:
1222
+ rk = vb._rank
1223
+ if len(value) != rk:
1224
+ raise ValueError("value must have "
1225
+ "length {}".format(rk))
1226
+ if any(len(row) != rk for row in value):
1227
+ raise ValueError("lists in value must have length "
1228
+ "{}".format(rk))
1229
+ # perform designation:
1230
+ sind = vb._base_space._sindex
1231
+ for i in vb.irange():
1232
+ for j in vb.irange():
1233
+ self[frame, i, j] = value[i - sind][j - sind]
1234
+ else:
1235
+ raise NotImplementedError("[start:stop] syntax not "
1236
+ "implemented")
1237
+
1238
+ def display(self, frame=None, vector_frame=None, chart=None,
1239
+ only_nonzero=True):
1240
+ r"""
1241
+ Display all the connection 1-forms w.r.t. to a given local frame, one
1242
+ per line.
1243
+
1244
+ The output is either text-formatted (console mode) or LaTeX-formatted
1245
+ (notebook mode).
1246
+
1247
+ INPUT:
1248
+
1249
+ - ``frame`` -- (default: ``None``) local frame of the vector bundle
1250
+ relative to which the connection 1-forms are defined; if ``None``,
1251
+ the default frame of the bundle is used
1252
+ - ``vector_frame`` -- (default: ``None``) vector frame of the manifold
1253
+ relative to which the connection 1-forms should be displayed; if
1254
+ ``None``, the default frame of the local frame's domain is used
1255
+ - ``chart`` -- (default: ``None``) chart specifying the coordinate
1256
+ expression of the connection 1-forms; if ``None``,
1257
+ the default chart of the domain of ``frame`` is used
1258
+ - ``only_nonzero`` -- boolean (default: ``True``); if ``True``, only
1259
+ nonzero connection coefficients are displayed
1260
+
1261
+ EXAMPLES:
1262
+
1263
+ Set connection 1-forms::
1264
+
1265
+ sage: M = Manifold(3, 'M', start_index=1)
1266
+ sage: X.<x,y,z> = M.chart()
1267
+ sage: E = M.vector_bundle(2, 'E')
1268
+ sage: e = E.local_frame('e') # standard frame for E
1269
+ sage: nab = E.bundle_connection('nabla', latex_name=r'\nabla'); nab
1270
+ Bundle connection nabla on the Differentiable real vector bundle
1271
+ E -> M of rank 2 over the base space 3-dimensional differentiable
1272
+ manifold M
1273
+ sage: nab[:] = 0
1274
+ sage: nab[1, 1][:] = [x, y, z]
1275
+ sage: nab[2, 2][:] = [x^2, y^2, z^2]
1276
+
1277
+ By default, only the nonzero connection coefficients are displayed::
1278
+
1279
+ sage: nab.display()
1280
+ connection (1,1) of bundle connection nabla w.r.t. Local frame
1281
+ (E|_M, (e_1,e_2)) = x dx + y dy + z dz
1282
+ connection (2,2) of bundle connection nabla w.r.t. Local frame
1283
+ (E|_M, (e_1,e_2)) = x^2 dx + y^2 dy + z^2 dz
1284
+ sage: latex(nab.display())
1285
+ \begin{array}{lcl} \omega^1_{\ \, 1} = x \mathrm{d} x +
1286
+ y \mathrm{d} y + z \mathrm{d} z \\ \omega^2_{\ \, 2} = x^{2}
1287
+ \mathrm{d} x + y^{2} \mathrm{d} y + z^{2} \mathrm{d} z \end{array}
1288
+
1289
+ By default, the displayed connection 1-forms are those w.r.t.
1290
+ the default frame of the vector bundle. The aforementioned is
1291
+ therefore equivalent to::
1292
+
1293
+ sage: nab.display(frame=E.default_frame())
1294
+ connection (1,1) of bundle connection nabla w.r.t. Local frame
1295
+ (E|_M, (e_1,e_2)) = x dx + y dy + z dz
1296
+ connection (2,2) of bundle connection nabla w.r.t. Local frame
1297
+ (E|_M, (e_1,e_2)) = x^2 dx + y^2 dy + z^2 dz
1298
+
1299
+ Moreover, the connection 1-forms are displayed w.r.t. the default
1300
+ vector frame on the local frame's domain, i.e.::
1301
+
1302
+ sage: domain = e.domain()
1303
+ sage: nab.display(vector_frame=domain.default_frame())
1304
+ connection (1,1) of bundle connection nabla w.r.t. Local frame
1305
+ (E|_M, (e_1,e_2)) = x dx + y dy + z dz
1306
+ connection (2,2) of bundle connection nabla w.r.t. Local frame
1307
+ (E|_M, (e_1,e_2)) = x^2 dx + y^2 dy + z^2 dz
1308
+
1309
+ By default, the parameter ``only_nonzero`` is set to ``True``.
1310
+ Otherwise, the connection 1-forms being zero are shown as well::
1311
+
1312
+ sage: nab.display(only_nonzero=False)
1313
+ connection (1,1) of bundle connection nabla w.r.t. Local frame
1314
+ (E|_M, (e_1,e_2)) = x dx + y dy + z dz
1315
+ connection (1,2) of bundle connection nabla w.r.t. Local frame
1316
+ (E|_M, (e_1,e_2)) = 0
1317
+ connection (2,1) of bundle connection nabla w.r.t. Local frame
1318
+ (E|_M, (e_1,e_2)) = 0
1319
+ connection (2,2) of bundle connection nabla w.r.t. Local frame
1320
+ (E|_M, (e_1,e_2)) = x^2 dx + y^2 dy + z^2 dz
1321
+ """
1322
+ vb = self._vbundle
1323
+ if frame is None:
1324
+ smodule = vb.section_module(domain=self._domain)
1325
+ frame = smodule.default_frame()
1326
+ if frame is None:
1327
+ raise ValueError("a local frame must be provided")
1328
+ dom = frame.domain()
1329
+ if frame is None:
1330
+ vmodule = dom.vector_field_module()
1331
+ vector_frame = vmodule.default_frame()
1332
+ if vector_frame is None:
1333
+ raise ValueError("a vector frame must be provided")
1334
+ if chart is None:
1335
+ chart = dom.default_chart()
1336
+ if chart is None:
1337
+ raise ValueError("a chart must be provided")
1338
+ # create output:
1339
+ from sage.misc.latex import latex
1340
+ from sage.tensor.modules.format_utilities import FormattedExpansion
1341
+
1342
+ rlatex = r'\begin{array}{lcl}'
1343
+ rtxt = ''
1344
+ for i in vb.irange():
1345
+ for j in vb.irange():
1346
+ omega = self[frame, i, j]
1347
+ if only_nonzero and (omega == 0):
1348
+ continue
1349
+ omega_out = omega.display(vector_frame, chart)
1350
+ rlatex += latex(omega_out) + r' \\'
1351
+ rtxt += str(omega_out) + ' \n'
1352
+ rtxt = rtxt[:-1] # remove the last new line
1353
+ rlatex = rlatex[:-2] + r'\end{array}'
1354
+ return FormattedExpansion(rtxt, rlatex)
1355
+
1356
+ def copy(self, name, latex_name=None):
1357
+ r"""
1358
+ Return an exact copy of ``self``.
1359
+
1360
+ INPUT:
1361
+
1362
+ - ``name`` -- name given to the copy
1363
+ - ``latex_name`` -- (default: ``None``) LaTeX symbol to denote the
1364
+ copy; if none is provided, the LaTeX symbol is set to ``name``
1365
+
1366
+ .. NOTE::
1367
+
1368
+ The name and the derived quantities are not copied.
1369
+
1370
+ EXAMPLES::
1371
+
1372
+ sage: M = Manifold(3, 'M', start_index=1)
1373
+ sage: X.<x,y,z> = M.chart()
1374
+ sage: E = M.vector_bundle(2, 'E')
1375
+ sage: e = E.local_frame('e')
1376
+ sage: nab = E.bundle_connection('nabla')
1377
+ sage: nab.set_connection_form(1, 1)[:] = [x^2, x-z, y^3]
1378
+ sage: nab.set_connection_form(1, 2)[:] = [1, x, z*y^3]
1379
+ sage: nab.set_connection_form(2, 1)[:] = [1, 2, 3]
1380
+ sage: nab.set_connection_form(2, 2)[:] = [0, 0, 0]
1381
+ sage: nab.display()
1382
+ connection (1,1) of bundle connection nabla w.r.t. Local frame
1383
+ (E|_M, (e_1,e_2)) = x^2 dx + (x - z) dy + y^3 dz
1384
+ connection (1,2) of bundle connection nabla w.r.t. Local frame
1385
+ (E|_M, (e_1,e_2)) = dx + x dy + y^3*z dz
1386
+ connection (2,1) of bundle connection nabla w.r.t. Local frame
1387
+ (E|_M, (e_1,e_2)) = dx + 2 dy + 3 dz
1388
+ sage: nab_copy = nab.copy('nablo'); nab_copy
1389
+ Bundle connection nablo on the Differentiable real vector bundle
1390
+ E -> M of rank 2 over the base space 3-dimensional differentiable
1391
+ manifold M
1392
+ sage: nab is nab_copy
1393
+ False
1394
+ sage: nab == nab_copy
1395
+ True
1396
+ sage: nab_copy.display()
1397
+ connection (1,1) of bundle connection nablo w.r.t. Local frame
1398
+ (E|_M, (e_1,e_2)) = x^2 dx + (x - z) dy + y^3 dz
1399
+ connection (1,2) of bundle connection nablo w.r.t. Local frame
1400
+ (E|_M, (e_1,e_2)) = dx + x dy + y^3*z dz
1401
+ connection (2,1) of bundle connection nablo w.r.t. Local frame
1402
+ (E|_M, (e_1,e_2)) = dx + 2 dy + 3 dz
1403
+ """
1404
+ copy = type(self)(self._vbundle, name, latex_name=latex_name)
1405
+ for frame, form_dict in self._connection_forms.items():
1406
+ copy._coefficients[frame] = copy._new_forms(frame=frame)
1407
+ for ind, form in form_dict.items():
1408
+ copy._coefficients[frame][ind].copy_from(form)
1409
+ return copy
1410
+
1411
+ def set_immutable(self):
1412
+ r"""
1413
+ Set ``self`` and all restrictions of ``self`` immutable.
1414
+
1415
+ EXAMPLES:
1416
+
1417
+ An affine connection can be set immutable::
1418
+
1419
+ sage: M = Manifold(3, 'M', start_index=1)
1420
+ sage: X.<x,y,z> = M.chart()
1421
+ sage: E = M.vector_bundle(2, 'E')
1422
+ sage: e = E.local_frame('e')
1423
+ sage: nab = E.bundle_connection('nabla')
1424
+ sage: nab.set_connection_form(1, 1)[:] = [x^2, x-z, y^3]
1425
+ sage: nab.set_connection_form(1, 2)[:] = [1, x, z*y^3]
1426
+ sage: nab.set_connection_form(2, 1)[:] = [1, 2, 3]
1427
+ sage: nab.set_connection_form(2, 2)[:] = [0, 0, 0]
1428
+ sage: nab.is_immutable()
1429
+ False
1430
+ sage: nab.set_immutable()
1431
+ sage: nab.is_immutable()
1432
+ True
1433
+
1434
+ The coefficients of immutable elements cannot be changed::
1435
+
1436
+ sage: f = E.local_frame('f')
1437
+ sage: nab.add_connection_form(1, 1, frame=f)[:] = [x, y, z]
1438
+ Traceback (most recent call last):
1439
+ ...
1440
+ ValueError: object is immutable; please change a copy instead
1441
+ """
1442
+ for form_dict in self._connection_forms.values():
1443
+ for form in form_dict.values():
1444
+ form.set_immutable()
1445
+ Mutability.set_immutable(self)