passagemath-symbolics 10.8.1a1__cp314-cp314t-musllinux_1_2_aarch64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- passagemath_symbolics/__init__.py +3 -0
- passagemath_symbolics-10.8.1a1.dist-info/METADATA +186 -0
- passagemath_symbolics-10.8.1a1.dist-info/RECORD +181 -0
- passagemath_symbolics-10.8.1a1.dist-info/WHEEL +5 -0
- passagemath_symbolics-10.8.1a1.dist-info/top_level.txt +3 -0
- sage/all__sagemath_symbolics.py +17 -0
- sage/calculus/all.py +14 -0
- sage/calculus/calculus.py +2838 -0
- sage/calculus/desolvers.py +1864 -0
- sage/calculus/predefined.py +51 -0
- sage/calculus/tests.py +225 -0
- sage/calculus/var.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/calculus/var.pyx +401 -0
- sage/dynamics/all__sagemath_symbolics.py +6 -0
- sage/dynamics/complex_dynamics/all.py +5 -0
- sage/dynamics/complex_dynamics/mandel_julia.py +765 -0
- sage/dynamics/complex_dynamics/mandel_julia_helper.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/dynamics/complex_dynamics/mandel_julia_helper.pyx +1034 -0
- sage/ext/all__sagemath_symbolics.py +1 -0
- sage/ext_data/kenzo/CP2.txt +45 -0
- sage/ext_data/kenzo/CP3.txt +349 -0
- sage/ext_data/kenzo/CP4.txt +4774 -0
- sage/ext_data/kenzo/README.txt +49 -0
- sage/ext_data/kenzo/S4.txt +20 -0
- sage/ext_data/magma/latex/latex.m +1021 -0
- sage/ext_data/magma/latex/latex.spec +1 -0
- sage/ext_data/magma/sage/basic.m +356 -0
- sage/ext_data/magma/sage/sage.spec +1 -0
- sage/ext_data/magma/spec +9 -0
- sage/geometry/all__sagemath_symbolics.py +8 -0
- sage/geometry/hyperbolic_space/all.py +5 -0
- sage/geometry/hyperbolic_space/hyperbolic_coercion.py +755 -0
- sage/geometry/hyperbolic_space/hyperbolic_constants.py +5 -0
- sage/geometry/hyperbolic_space/hyperbolic_geodesic.py +2419 -0
- sage/geometry/hyperbolic_space/hyperbolic_interface.py +206 -0
- sage/geometry/hyperbolic_space/hyperbolic_isometry.py +1083 -0
- sage/geometry/hyperbolic_space/hyperbolic_model.py +1502 -0
- sage/geometry/hyperbolic_space/hyperbolic_point.py +621 -0
- sage/geometry/riemannian_manifolds/all.py +7 -0
- sage/geometry/riemannian_manifolds/parametrized_surface3d.py +1632 -0
- sage/geometry/riemannian_manifolds/surface3d_generators.py +461 -0
- sage/interfaces/all__sagemath_symbolics.py +1 -0
- sage/interfaces/magma.py +2991 -0
- sage/interfaces/magma_free.py +90 -0
- sage/interfaces/maple.py +1402 -0
- sage/interfaces/mathematica.py +1345 -0
- sage/interfaces/mathics.py +1312 -0
- sage/interfaces/sympy.py +1398 -0
- sage/interfaces/sympy_wrapper.py +197 -0
- sage/interfaces/tides.py +938 -0
- sage/libs/all__sagemath_symbolics.py +6 -0
- sage/manifolds/all.py +7 -0
- sage/manifolds/calculus_method.py +553 -0
- sage/manifolds/catalog.py +437 -0
- sage/manifolds/chart.py +4010 -0
- sage/manifolds/chart_func.py +3416 -0
- sage/manifolds/continuous_map.py +2183 -0
- sage/manifolds/continuous_map_image.py +155 -0
- sage/manifolds/differentiable/affine_connection.py +2475 -0
- sage/manifolds/differentiable/all.py +1 -0
- sage/manifolds/differentiable/automorphismfield.py +1383 -0
- sage/manifolds/differentiable/automorphismfield_group.py +604 -0
- sage/manifolds/differentiable/bundle_connection.py +1445 -0
- sage/manifolds/differentiable/characteristic_cohomology_class.py +1840 -0
- sage/manifolds/differentiable/chart.py +1241 -0
- sage/manifolds/differentiable/curve.py +1028 -0
- sage/manifolds/differentiable/de_rham_cohomology.py +541 -0
- sage/manifolds/differentiable/degenerate.py +559 -0
- sage/manifolds/differentiable/degenerate_submanifold.py +1668 -0
- sage/manifolds/differentiable/diff_form.py +1660 -0
- sage/manifolds/differentiable/diff_form_module.py +1062 -0
- sage/manifolds/differentiable/diff_map.py +1315 -0
- sage/manifolds/differentiable/differentiable_submanifold.py +291 -0
- sage/manifolds/differentiable/examples/all.py +1 -0
- sage/manifolds/differentiable/examples/euclidean.py +2517 -0
- sage/manifolds/differentiable/examples/real_line.py +897 -0
- sage/manifolds/differentiable/examples/sphere.py +1186 -0
- sage/manifolds/differentiable/examples/symplectic_space.py +187 -0
- sage/manifolds/differentiable/examples/symplectic_space_test.py +40 -0
- sage/manifolds/differentiable/integrated_curve.py +4035 -0
- sage/manifolds/differentiable/levi_civita_connection.py +841 -0
- sage/manifolds/differentiable/manifold.py +4254 -0
- sage/manifolds/differentiable/manifold_homset.py +1826 -0
- sage/manifolds/differentiable/metric.py +3032 -0
- sage/manifolds/differentiable/mixed_form.py +1507 -0
- sage/manifolds/differentiable/mixed_form_algebra.py +559 -0
- sage/manifolds/differentiable/multivector_module.py +800 -0
- sage/manifolds/differentiable/multivectorfield.py +1522 -0
- sage/manifolds/differentiable/poisson_tensor.py +268 -0
- sage/manifolds/differentiable/pseudo_riemannian.py +755 -0
- sage/manifolds/differentiable/pseudo_riemannian_submanifold.py +1839 -0
- sage/manifolds/differentiable/scalarfield.py +1343 -0
- sage/manifolds/differentiable/scalarfield_algebra.py +472 -0
- sage/manifolds/differentiable/symplectic_form.py +912 -0
- sage/manifolds/differentiable/symplectic_form_test.py +220 -0
- sage/manifolds/differentiable/tangent_space.py +412 -0
- sage/manifolds/differentiable/tangent_vector.py +616 -0
- sage/manifolds/differentiable/tensorfield.py +4665 -0
- sage/manifolds/differentiable/tensorfield_module.py +963 -0
- sage/manifolds/differentiable/tensorfield_paral.py +2450 -0
- sage/manifolds/differentiable/tensorfield_paral_test.py +16 -0
- sage/manifolds/differentiable/vector_bundle.py +1725 -0
- sage/manifolds/differentiable/vectorfield.py +1717 -0
- sage/manifolds/differentiable/vectorfield_module.py +2445 -0
- sage/manifolds/differentiable/vectorframe.py +1832 -0
- sage/manifolds/family.py +270 -0
- sage/manifolds/local_frame.py +1490 -0
- sage/manifolds/manifold.py +3090 -0
- sage/manifolds/manifold_homset.py +452 -0
- sage/manifolds/operators.py +359 -0
- sage/manifolds/point.py +994 -0
- sage/manifolds/scalarfield.py +3718 -0
- sage/manifolds/scalarfield_algebra.py +629 -0
- sage/manifolds/section.py +3111 -0
- sage/manifolds/section_module.py +831 -0
- sage/manifolds/structure.py +229 -0
- sage/manifolds/subset.py +2721 -0
- sage/manifolds/subsets/all.py +1 -0
- sage/manifolds/subsets/closure.py +131 -0
- sage/manifolds/subsets/pullback.py +883 -0
- sage/manifolds/topological_submanifold.py +891 -0
- sage/manifolds/trivialization.py +733 -0
- sage/manifolds/utilities.py +1348 -0
- sage/manifolds/vector_bundle.py +1347 -0
- sage/manifolds/vector_bundle_fiber.py +332 -0
- sage/manifolds/vector_bundle_fiber_element.py +111 -0
- sage/matrix/all__sagemath_symbolics.py +1 -0
- sage/matrix/matrix_symbolic_dense.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/matrix/matrix_symbolic_dense.pxd +6 -0
- sage/matrix/matrix_symbolic_dense.pyx +1030 -0
- sage/matrix/matrix_symbolic_sparse.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/matrix/matrix_symbolic_sparse.pxd +6 -0
- sage/matrix/matrix_symbolic_sparse.pyx +1038 -0
- sage/modules/all__sagemath_symbolics.py +1 -0
- sage/modules/vector_callable_symbolic_dense.py +105 -0
- sage/modules/vector_symbolic_dense.py +116 -0
- sage/modules/vector_symbolic_sparse.py +118 -0
- sage/rings/all__sagemath_symbolics.py +4 -0
- sage/rings/asymptotic/all.py +6 -0
- sage/rings/asymptotic/asymptotic_expansion_generators.py +1485 -0
- sage/rings/asymptotic/asymptotic_ring.py +4858 -0
- sage/rings/asymptotic/asymptotics_multivariate_generating_functions.py +4106 -0
- sage/rings/asymptotic/growth_group.py +5373 -0
- sage/rings/asymptotic/growth_group_cartesian.py +1400 -0
- sage/rings/asymptotic/term_monoid.py +5205 -0
- sage/rings/function_field/all__sagemath_symbolics.py +2 -0
- sage/rings/polynomial/all__sagemath_symbolics.py +1 -0
- sage/symbolic/all.py +15 -0
- sage/symbolic/assumptions.py +987 -0
- sage/symbolic/benchmark.py +93 -0
- sage/symbolic/callable.py +456 -0
- sage/symbolic/callable.pyi +66 -0
- sage/symbolic/comparison_impl.pyi +38 -0
- sage/symbolic/complexity_measures.py +35 -0
- sage/symbolic/constants.py +1286 -0
- sage/symbolic/constants_c_impl.pyi +10 -0
- sage/symbolic/expression_conversion_algebraic.py +310 -0
- sage/symbolic/expression_conversion_sympy.py +317 -0
- sage/symbolic/expression_conversions.py +1727 -0
- sage/symbolic/function_factory.py +355 -0
- sage/symbolic/function_factory.pyi +41 -0
- sage/symbolic/getitem_impl.pyi +24 -0
- sage/symbolic/integration/all.py +1 -0
- sage/symbolic/integration/external.py +271 -0
- sage/symbolic/integration/integral.py +1075 -0
- sage/symbolic/maxima_wrapper.py +162 -0
- sage/symbolic/operators.py +267 -0
- sage/symbolic/operators.pyi +61 -0
- sage/symbolic/pynac_constant_impl.pyi +13 -0
- sage/symbolic/pynac_function_impl.pyi +8 -0
- sage/symbolic/random_tests.py +461 -0
- sage/symbolic/relation.py +2062 -0
- sage/symbolic/ring.cpython-314t-aarch64-linux-musl.so +0 -0
- sage/symbolic/ring.pxd +5 -0
- sage/symbolic/ring.pyi +110 -0
- sage/symbolic/ring.pyx +1393 -0
- sage/symbolic/series_impl.pyi +10 -0
- sage/symbolic/subring.py +1025 -0
- sage/symbolic/symengine.py +19 -0
- sage/symbolic/tests.py +40 -0
- sage/symbolic/units.py +1468 -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)
|