passagemath-symbolics 10.6.37__cp314-cp314t-macosx_13_0_arm64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- passagemath_symbolics/.dylibs/libgmp.10.dylib +0 -0
- passagemath_symbolics/__init__.py +3 -0
- passagemath_symbolics-10.6.37.dist-info/METADATA +187 -0
- passagemath_symbolics-10.6.37.dist-info/RECORD +172 -0
- passagemath_symbolics-10.6.37.dist-info/WHEEL +6 -0
- passagemath_symbolics-10.6.37.dist-info/top_level.txt +3 -0
- sage/all__sagemath_symbolics.py +17 -0
- sage/calculus/all.py +14 -0
- sage/calculus/calculus.py +2826 -0
- sage/calculus/desolvers.py +1866 -0
- sage/calculus/predefined.py +51 -0
- sage/calculus/tests.py +225 -0
- sage/calculus/var.cpython-314t-darwin.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-darwin.so +0 -0
- sage/dynamics/complex_dynamics/mandel_julia_helper.pyx +1035 -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 +743 -0
- sage/geometry/hyperbolic_space/hyperbolic_constants.py +5 -0
- sage/geometry/hyperbolic_space/hyperbolic_geodesic.py +2409 -0
- sage/geometry/hyperbolic_space/hyperbolic_interface.py +206 -0
- sage/geometry/hyperbolic_space/hyperbolic_isometry.py +1082 -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 +3017 -0
- sage/interfaces/magma_free.py +92 -0
- sage/interfaces/maple.py +1397 -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 +555 -0
- sage/manifolds/catalog.py +437 -0
- sage/manifolds/chart.py +4019 -0
- sage/manifolds/chart_func.py +3419 -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 +1671 -0
- sage/manifolds/differentiable/diff_form.py +1658 -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 +1520 -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 +910 -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 +1728 -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 +2764 -0
- sage/manifolds/subsets/all.py +1 -0
- sage/manifolds/subsets/closure.py +131 -0
- sage/manifolds/subsets/pullback.py +885 -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 +1342 -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-darwin.so +0 -0
- sage/matrix/matrix_symbolic_dense.pxd +6 -0
- sage/matrix/matrix_symbolic_dense.pyx +1022 -0
- sage/matrix/matrix_symbolic_sparse.cpython-314t-darwin.so +0 -0
- sage/matrix/matrix_symbolic_sparse.pxd +6 -0
- sage/matrix/matrix_symbolic_sparse.pyx +1029 -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 +4153 -0
- sage/rings/asymptotic/growth_group.py +5373 -0
- sage/rings/asymptotic/growth_group_cartesian.py +1400 -0
- sage/rings/asymptotic/term_monoid.py +5237 -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 +985 -0
- sage/symbolic/benchmark.py +93 -0
- sage/symbolic/callable.py +459 -0
- sage/symbolic/complexity_measures.py +35 -0
- sage/symbolic/constants.py +1287 -0
- sage/symbolic/expression_conversion_algebraic.py +310 -0
- sage/symbolic/expression_conversion_sympy.py +317 -0
- sage/symbolic/expression_conversions.py +1713 -0
- sage/symbolic/function_factory.py +355 -0
- sage/symbolic/integration/all.py +1 -0
- sage/symbolic/integration/external.py +270 -0
- sage/symbolic/integration/integral.py +1115 -0
- sage/symbolic/maxima_wrapper.py +162 -0
- sage/symbolic/operators.py +267 -0
- sage/symbolic/random_tests.py +462 -0
- sage/symbolic/relation.py +1907 -0
- sage/symbolic/ring.cpython-314t-darwin.so +0 -0
- sage/symbolic/ring.pxd +5 -0
- sage/symbolic/ring.pyx +1396 -0
- sage/symbolic/subring.py +1025 -0
- sage/symbolic/symengine.py +19 -0
- sage/symbolic/tests.py +40 -0
- sage/symbolic/units.py +1470 -0
|
@@ -0,0 +1,1342 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-symbolics
|
|
2
|
+
r"""
|
|
3
|
+
Topological Vector Bundle
|
|
4
|
+
|
|
5
|
+
Let `K` be a topological field. A *vector bundle* of rank `n` over the field
|
|
6
|
+
`K` and over a topological manifold `B` (base space) is a topological manifold
|
|
7
|
+
`E` (total space) together with a continuous and surjective map `\pi: E \to B`
|
|
8
|
+
such that for every point `p \in B`, we have:
|
|
9
|
+
|
|
10
|
+
- the set `E_p=\pi^{-1}(p)` has the vector space structure of `K^n`,
|
|
11
|
+
- there is a neighborhood `U \subset B` of `p` and a homeomorphism
|
|
12
|
+
(trivialization) `\varphi: \pi^{-1}(p) \to U \times K^n` such that `\varphi`
|
|
13
|
+
is compatible with the fibers, namely `\pi \circ \varphi^{-1} = \mathrm{pr}_1`,
|
|
14
|
+
and `v \mapsto \varphi^{-1}(q,v)` is a linear isomorphism between `K^n` and
|
|
15
|
+
`E_q` for any `q \in U`.
|
|
16
|
+
|
|
17
|
+
AUTHORS:
|
|
18
|
+
|
|
19
|
+
- Michael Jung (2019) : initial version
|
|
20
|
+
|
|
21
|
+
REFERENCES:
|
|
22
|
+
|
|
23
|
+
- [Lee2013]_
|
|
24
|
+
- [Mil1974]_
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
#******************************************************************************
|
|
28
|
+
# Copyright (C) 2019 Michael Jung <micjung@uni-potsdam.de>
|
|
29
|
+
#
|
|
30
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
|
31
|
+
# as published by the Free Software Foundation; either version 2 of
|
|
32
|
+
# the License, or (at your option) any later version.
|
|
33
|
+
# https://www.gnu.org/licenses/
|
|
34
|
+
#******************************************************************************
|
|
35
|
+
|
|
36
|
+
import sage.rings.abc
|
|
37
|
+
from sage.categories.vector_bundles import VectorBundles
|
|
38
|
+
from sage.manifolds.vector_bundle_fiber import VectorBundleFiber
|
|
39
|
+
from sage.rings.cc import CC
|
|
40
|
+
from sage.rings.integer import Integer
|
|
41
|
+
from sage.rings.real_mpfr import RR
|
|
42
|
+
from sage.structure.category_object import CategoryObject
|
|
43
|
+
from sage.structure.unique_representation import UniqueRepresentation
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class TopologicalVectorBundle(CategoryObject, UniqueRepresentation):
|
|
47
|
+
r"""
|
|
48
|
+
An instance of this class is a topological vector bundle `E \to B` over a
|
|
49
|
+
topological field `K`.
|
|
50
|
+
|
|
51
|
+
INPUT:
|
|
52
|
+
|
|
53
|
+
- ``rank`` -- positive integer; rank of the vector bundle
|
|
54
|
+
- ``name`` -- string representation given to the total space
|
|
55
|
+
- ``base_space`` -- the base space (topological manifold) over which the
|
|
56
|
+
vector bundle is defined
|
|
57
|
+
- ``field`` -- field `K` which gives the fibers the structure of a
|
|
58
|
+
vector space over `K`; allowed values are
|
|
59
|
+
|
|
60
|
+
- ``'real'`` or an object of type ``RealField`` (e.g., ``RR``) for
|
|
61
|
+
a vector bundle over `\RR`
|
|
62
|
+
- ``'complex'`` or an object of type ``ComplexField`` (e.g., ``CC``)
|
|
63
|
+
for a vector bundle over `\CC`
|
|
64
|
+
- an object in the category of topological fields (see
|
|
65
|
+
:class:`~sage.categories.fields.Fields` and
|
|
66
|
+
:class:`~sage.categories.topological_spaces.TopologicalSpaces`)
|
|
67
|
+
for other types of topological fields
|
|
68
|
+
|
|
69
|
+
- ``latex_name`` -- (default: ``None``) LaTeX representation given to the
|
|
70
|
+
total space
|
|
71
|
+
- ``category`` -- (default: ``None``) to specify the category; if
|
|
72
|
+
``None``, ``VectorBundles(base_space, c_field)`` is assumed (see the
|
|
73
|
+
category :class:`~sage.categories.vector_bundles.VectorBundles`)
|
|
74
|
+
- ``unique_tag`` -- (default: ``None``) tag used to force the construction
|
|
75
|
+
of a new object when all the other arguments have been used previously
|
|
76
|
+
(without ``unique_tag``, the
|
|
77
|
+
:class:`~sage.structure.unique_representation.UniqueRepresentation`
|
|
78
|
+
behavior would return the previously constructed object corresponding to
|
|
79
|
+
these arguments)
|
|
80
|
+
|
|
81
|
+
EXAMPLES:
|
|
82
|
+
|
|
83
|
+
A real line bundle over some 4-dimensional topological manifold::
|
|
84
|
+
|
|
85
|
+
sage: M = Manifold(4, 'M', structure='top')
|
|
86
|
+
sage: E = M.vector_bundle(1, 'E'); E
|
|
87
|
+
Topological real vector bundle E -> M of rank 1 over the base space
|
|
88
|
+
4-dimensional topological manifold M
|
|
89
|
+
sage: E.base_space()
|
|
90
|
+
4-dimensional topological manifold M
|
|
91
|
+
sage: E.base_ring()
|
|
92
|
+
Real Field with 53 bits of precision
|
|
93
|
+
sage: E.rank()
|
|
94
|
+
1
|
|
95
|
+
|
|
96
|
+
For a more sophisticated example, let us define a non-trivial
|
|
97
|
+
2-manifold to work with::
|
|
98
|
+
|
|
99
|
+
sage: M = Manifold(2, 'M', structure='top')
|
|
100
|
+
sage: U = M.open_subset('U') ; V = M.open_subset('V')
|
|
101
|
+
sage: M.declare_union(U,V) # M is the union of U and V
|
|
102
|
+
sage: c_xy.<x,y> = U.chart() ; c_uv.<u,v> = V.chart()
|
|
103
|
+
sage: xy_to_uv = c_xy.transition_map(c_uv, (x+y, x-y),
|
|
104
|
+
....: intersection_name='W', restrictions1= x>0,
|
|
105
|
+
....: restrictions2= u+v>0)
|
|
106
|
+
sage: uv_to_xy = xy_to_uv.inverse()
|
|
107
|
+
sage: W = U.intersection(V)
|
|
108
|
+
sage: E = M.vector_bundle(2, 'E'); E
|
|
109
|
+
Topological real vector bundle E -> M of rank 2 over the base space
|
|
110
|
+
2-dimensional topological manifold M
|
|
111
|
+
|
|
112
|
+
Now, there a two ways to go. Most effortlessly, we define
|
|
113
|
+
trivializations similar to charts (see
|
|
114
|
+
:class:`~sage.manifolds.trivialization.Trivialization`)::
|
|
115
|
+
|
|
116
|
+
sage: phi_U = E.trivialization('phi_U', domain=U); phi_U
|
|
117
|
+
Trivialization (phi_U, E|_U)
|
|
118
|
+
sage: phi_V = E.trivialization('phi_V', domain=V); phi_V
|
|
119
|
+
Trivialization (phi_V, E|_V)
|
|
120
|
+
sage: transf = phi_U.transition_map(phi_V, [[0,x],[x,0]]) # transition map between trivializations
|
|
121
|
+
sage: fU = phi_U.frame(); fU
|
|
122
|
+
Trivialization frame (E|_U, ((phi_U^*e_1),(phi_U^*e_2)))
|
|
123
|
+
sage: fV = phi_V.frame(); fV
|
|
124
|
+
Trivialization frame (E|_V, ((phi_V^*e_1),(phi_V^*e_2)))
|
|
125
|
+
sage: E.changes_of_frame() # random
|
|
126
|
+
{(Local frame (E|_W, ((phi_U^*e_1),(phi_U^*e_2))),
|
|
127
|
+
Local frame (E|_W, ((phi_V^*e_1),(phi_V^*e_2)))): Automorphism
|
|
128
|
+
phi_U^(-1)*phi_V^(-1) of the Free module C^0(W;E) of sections on
|
|
129
|
+
the Open subset W of the 2-dimensional topological manifold M with
|
|
130
|
+
values in the real vector bundle E of rank 2,
|
|
131
|
+
(Local frame (E|_W, ((phi_V^*e_1),(phi_V^*e_2))),
|
|
132
|
+
Local frame (E|_W, ((phi_U^*e_1),(phi_U^*e_2)))): Automorphism
|
|
133
|
+
phi_U^(-1)*phi_V of the Free module C^0(W;E) of sections on the
|
|
134
|
+
Open subset W of the 2-dimensional topological manifold M with
|
|
135
|
+
values in the real vector bundle E of rank 2}
|
|
136
|
+
|
|
137
|
+
Then, the atlas of `E` consists of all known trivializations defined
|
|
138
|
+
on E::
|
|
139
|
+
|
|
140
|
+
sage: E.atlas() # a shallow copy of the atlas
|
|
141
|
+
[Trivialization (phi_U, E|_U), Trivialization (phi_V, E|_V)]
|
|
142
|
+
|
|
143
|
+
Or we just define frames, an automorphism on the free
|
|
144
|
+
section module over the intersection domain `W` and declare the change
|
|
145
|
+
of frame manually (for more details consult
|
|
146
|
+
:class:`~sage.manifolds.local_frame.LocalFrame`)::
|
|
147
|
+
|
|
148
|
+
sage: eU = E.local_frame('eU', domain=U); eU
|
|
149
|
+
Local frame (E|_U, (eU_0,eU_1))
|
|
150
|
+
sage: eUW = eU.restrict(W) # to trivialize E|_W
|
|
151
|
+
sage: eV = E.local_frame('eV', domain=V); eV
|
|
152
|
+
Local frame (E|_V, (eV_0,eV_1))
|
|
153
|
+
sage: eVW = eV.restrict(W)
|
|
154
|
+
sage: a = E.section_module(domain=W).automorphism(); a
|
|
155
|
+
Automorphism of the Free module C^0(W;E) of sections on the Open
|
|
156
|
+
subset W of the 2-dimensional topological manifold M with values in
|
|
157
|
+
the real vector bundle E of rank 2
|
|
158
|
+
sage: a[eUW,:] = [[0,x],[x,0]]
|
|
159
|
+
sage: E.set_change_of_frame(eUW, eVW, a)
|
|
160
|
+
sage: E.change_of_frame(eUW, eVW)
|
|
161
|
+
Automorphism of the Free module C^0(W;E) of sections on the Open
|
|
162
|
+
subset W of the 2-dimensional topological manifold M with values in
|
|
163
|
+
the real vector bundle E of rank 2
|
|
164
|
+
|
|
165
|
+
Now, the list of all known frames defined on `E` can be displayed via
|
|
166
|
+
:meth:`frames`::
|
|
167
|
+
|
|
168
|
+
sage: E.frames() # a shallow copy of all known frames on E
|
|
169
|
+
[Trivialization frame (E|_U, ((phi_U^*e_1),(phi_U^*e_2))),
|
|
170
|
+
Trivialization frame (E|_V, ((phi_V^*e_1),(phi_V^*e_2))),
|
|
171
|
+
Local frame (E|_W, ((phi_U^*e_1),(phi_U^*e_2))),
|
|
172
|
+
Local frame (E|_W, ((phi_V^*e_1),(phi_V^*e_2))),
|
|
173
|
+
Local frame (E|_U, (eU_0,eU_1)),
|
|
174
|
+
Local frame (E|_W, (eU_0,eU_1)),
|
|
175
|
+
Local frame (E|_V, (eV_0,eV_1)),
|
|
176
|
+
Local frame (E|_W, (eV_0,eV_1))]
|
|
177
|
+
|
|
178
|
+
By definition `E` is a manifold, in this case of dimension 4 (notice
|
|
179
|
+
that the induced charts are not implemented, yet)::
|
|
180
|
+
|
|
181
|
+
sage: E.total_space()
|
|
182
|
+
4-dimensional topological manifold E
|
|
183
|
+
|
|
184
|
+
The method :meth:`section` returns a section while the method
|
|
185
|
+
:meth:`section_module` returns the section module on the corresponding
|
|
186
|
+
domain::
|
|
187
|
+
|
|
188
|
+
sage: s = E.section(name='s'); s
|
|
189
|
+
Section s on the 2-dimensional topological manifold M with values in
|
|
190
|
+
the real vector bundle E of rank 2
|
|
191
|
+
sage: s in E.section_module()
|
|
192
|
+
True
|
|
193
|
+
"""
|
|
194
|
+
def __init__(self, rank, name, base_space, field='real',
|
|
195
|
+
latex_name=None, category=None, unique_tag=None):
|
|
196
|
+
r"""
|
|
197
|
+
Construct a topological vector bundle.
|
|
198
|
+
|
|
199
|
+
TESTS::
|
|
200
|
+
|
|
201
|
+
sage: M = Manifold(2, 'M', structure='top')
|
|
202
|
+
sage: from sage.manifolds.vector_bundle import TopologicalVectorBundle
|
|
203
|
+
sage: TopologicalVectorBundle(2, 'E', M)
|
|
204
|
+
Topological real vector bundle E -> M of rank 2 over the base space
|
|
205
|
+
2-dimensional topological manifold M
|
|
206
|
+
"""
|
|
207
|
+
if base_space is None:
|
|
208
|
+
raise ValueError("a base space must be provided")
|
|
209
|
+
###
|
|
210
|
+
# Handle the field:
|
|
211
|
+
if field == 'real':
|
|
212
|
+
self._field = RR
|
|
213
|
+
self._field_type = field
|
|
214
|
+
elif field == 'complex':
|
|
215
|
+
self._field = CC
|
|
216
|
+
self._field_type = field
|
|
217
|
+
else:
|
|
218
|
+
self._field = field
|
|
219
|
+
if isinstance(field, sage.rings.abc.RealField):
|
|
220
|
+
self._field_type = 'real'
|
|
221
|
+
elif isinstance(field, sage.rings.abc.ComplexField):
|
|
222
|
+
self._field_type = 'complex'
|
|
223
|
+
else:
|
|
224
|
+
self._field_type = 'neither_real_nor_complex'
|
|
225
|
+
bs_field = base_space.base_field()
|
|
226
|
+
if not bs_field.is_subring(self._field):
|
|
227
|
+
raise ValueError("for concrete implementation, manifold's base "
|
|
228
|
+
"field must be a subfield of the vector bundle's "
|
|
229
|
+
"base field")
|
|
230
|
+
###
|
|
231
|
+
# Get the category:
|
|
232
|
+
if category is None:
|
|
233
|
+
category = VectorBundles(base_space, self._field)
|
|
234
|
+
CategoryObject.__init__(self, base=self._field,
|
|
235
|
+
category=category)
|
|
236
|
+
# Check rank:
|
|
237
|
+
if not isinstance(rank, (int, Integer)):
|
|
238
|
+
raise TypeError("the rank must be an integer")
|
|
239
|
+
if rank < 1:
|
|
240
|
+
raise ValueError("the rank must be strictly positive")
|
|
241
|
+
###
|
|
242
|
+
# Define remaining attributes:
|
|
243
|
+
self._rank = rank
|
|
244
|
+
self._diff_degree = 0
|
|
245
|
+
self._base_space = base_space
|
|
246
|
+
self._total_space = None
|
|
247
|
+
self._orientation = [] # set no orientation a priori
|
|
248
|
+
###
|
|
249
|
+
# Set names:
|
|
250
|
+
self._name = name
|
|
251
|
+
if latex_name is None:
|
|
252
|
+
self._latex_name = self._name
|
|
253
|
+
else:
|
|
254
|
+
self._latex_name = latex_name
|
|
255
|
+
###
|
|
256
|
+
# Initialize quantities like frames and trivializations:
|
|
257
|
+
self._init_attributes()
|
|
258
|
+
|
|
259
|
+
def _init_attributes(self):
|
|
260
|
+
r"""
|
|
261
|
+
Initialize the derived quantities.
|
|
262
|
+
|
|
263
|
+
TESTS::
|
|
264
|
+
|
|
265
|
+
sage: M = Manifold(2, 'M', structure='topological')
|
|
266
|
+
sage: E = M.vector_bundle(2, 'E')
|
|
267
|
+
sage: E._init_attributes()
|
|
268
|
+
"""
|
|
269
|
+
self._section_modules = {} # dict of section modules with domains as
|
|
270
|
+
# keys
|
|
271
|
+
self._atlas = [] # list of trivializations defined on self
|
|
272
|
+
self._transitions = {} # dictionary of transition maps (key: pair of
|
|
273
|
+
# of trivializations)
|
|
274
|
+
self._frames = [] # list of local frames for self
|
|
275
|
+
self._frame_changes = {} # dictionary of changes of frames
|
|
276
|
+
self._coframes = [] # list of local coframes for self
|
|
277
|
+
self._trivial_parts = set() # subsets of base space on which self is
|
|
278
|
+
# trivial
|
|
279
|
+
self._def_frame = None
|
|
280
|
+
|
|
281
|
+
def base_space(self):
|
|
282
|
+
r"""
|
|
283
|
+
Return the base space of the vector bundle.
|
|
284
|
+
|
|
285
|
+
EXAMPLES::
|
|
286
|
+
|
|
287
|
+
sage: M = Manifold(2, 'M', structure='top')
|
|
288
|
+
sage: E = M.vector_bundle(2, 'E')
|
|
289
|
+
sage: E.base_space()
|
|
290
|
+
2-dimensional topological manifold M
|
|
291
|
+
"""
|
|
292
|
+
return self._base_space
|
|
293
|
+
|
|
294
|
+
def base_field_type(self):
|
|
295
|
+
r"""
|
|
296
|
+
Return the type of topological field on which the fibers are defined.
|
|
297
|
+
|
|
298
|
+
OUTPUT:
|
|
299
|
+
|
|
300
|
+
A string describing the field, with three possible values:
|
|
301
|
+
|
|
302
|
+
- ``'real'`` for the real field `\RR`
|
|
303
|
+
- ``'complex'`` for the complex field `\CC`
|
|
304
|
+
- ``'neither_real_nor_complex'`` for a field different from `\RR` and `\CC`
|
|
305
|
+
|
|
306
|
+
EXAMPLES::
|
|
307
|
+
|
|
308
|
+
sage: M = Manifold(2, 'M', structure='top')
|
|
309
|
+
sage: E = M.vector_bundle(2, 'E', field=CC)
|
|
310
|
+
sage: E.base_field_type()
|
|
311
|
+
'complex'
|
|
312
|
+
"""
|
|
313
|
+
return self._field_type
|
|
314
|
+
|
|
315
|
+
def base_field(self):
|
|
316
|
+
r"""
|
|
317
|
+
Return the field on which the fibers are defined.
|
|
318
|
+
|
|
319
|
+
OUTPUT: a topological field
|
|
320
|
+
|
|
321
|
+
EXAMPLES::
|
|
322
|
+
|
|
323
|
+
sage: M = Manifold(3, 'M', structure='topological')
|
|
324
|
+
sage: E = M.vector_bundle(2, 'E', field=CC)
|
|
325
|
+
sage: E.base_field()
|
|
326
|
+
Complex Field with 53 bits of precision
|
|
327
|
+
"""
|
|
328
|
+
return self._field
|
|
329
|
+
|
|
330
|
+
def rank(self):
|
|
331
|
+
r"""
|
|
332
|
+
Return the rank of the vector bundle.
|
|
333
|
+
|
|
334
|
+
EXAMPLES::
|
|
335
|
+
|
|
336
|
+
sage: M = Manifold(2, 'M', structure='top')
|
|
337
|
+
sage: E = M.vector_bundle(3, 'E')
|
|
338
|
+
sage: E.rank()
|
|
339
|
+
3
|
|
340
|
+
"""
|
|
341
|
+
return self._rank
|
|
342
|
+
|
|
343
|
+
def _repr_object_name(self):
|
|
344
|
+
r"""
|
|
345
|
+
String name of the object without structure.
|
|
346
|
+
|
|
347
|
+
TESTS::
|
|
348
|
+
|
|
349
|
+
sage: M = Manifold(2, 'M', structure='top')
|
|
350
|
+
sage: E = M.vector_bundle(1, 'E')
|
|
351
|
+
sage: E._repr_object_name()
|
|
352
|
+
'real vector bundle E -> M of rank 1 over the base space
|
|
353
|
+
2-dimensional topological manifold M'
|
|
354
|
+
"""
|
|
355
|
+
desc = self.base_field_type() + " "
|
|
356
|
+
desc += "vector bundle "
|
|
357
|
+
desc += self._name + " -> " + self.base_space()._name + " "
|
|
358
|
+
desc += "of rank {} ".format(self._rank)
|
|
359
|
+
desc += "over the base space {}".format(self.base_space())
|
|
360
|
+
return desc
|
|
361
|
+
|
|
362
|
+
def _repr_(self):
|
|
363
|
+
r"""
|
|
364
|
+
String representation of ``self``.
|
|
365
|
+
|
|
366
|
+
TESTS::
|
|
367
|
+
|
|
368
|
+
sage: M = Manifold(2, 'M', structure='top')
|
|
369
|
+
sage: E = M.vector_bundle(1, 'E')
|
|
370
|
+
sage: E._repr_()
|
|
371
|
+
'Topological real vector bundle E -> M of rank 1 over the base space
|
|
372
|
+
2-dimensional topological manifold M'
|
|
373
|
+
"""
|
|
374
|
+
desc = "Topological "
|
|
375
|
+
desc += self._repr_object_name()
|
|
376
|
+
return desc
|
|
377
|
+
|
|
378
|
+
def _latex_(self):
|
|
379
|
+
r"""
|
|
380
|
+
Return the LaTeX representation of the object.
|
|
381
|
+
|
|
382
|
+
TESTS::
|
|
383
|
+
|
|
384
|
+
sage: M = Manifold(2, 'M', structure='top')
|
|
385
|
+
sage: E = M.vector_bundle(1, 'E')
|
|
386
|
+
sage: E._latex_()
|
|
387
|
+
'E\\to M'
|
|
388
|
+
"""
|
|
389
|
+
latex = self._latex_name
|
|
390
|
+
latex += r'\to '
|
|
391
|
+
latex += self.base_space()._latex_name
|
|
392
|
+
return latex
|
|
393
|
+
|
|
394
|
+
def _add_local_frame(self, frame):
|
|
395
|
+
r"""
|
|
396
|
+
Helper method to add local frames to the vector bundle.
|
|
397
|
+
|
|
398
|
+
INPUT:
|
|
399
|
+
|
|
400
|
+
- ``frame`` -- the local frame that shall be added
|
|
401
|
+
|
|
402
|
+
TESTS::
|
|
403
|
+
|
|
404
|
+
sage: M = Manifold(3, 'M', structure='top')
|
|
405
|
+
sage: E = M.vector_bundle(2, 'E')
|
|
406
|
+
sage: e = E.local_frame('e')
|
|
407
|
+
sage: E._add_local_frame(e)
|
|
408
|
+
sage: E._frames
|
|
409
|
+
[Local frame (E|_M, (e_0,e_1)), Local frame (E|_M, (e_0,e_1))]
|
|
410
|
+
"""
|
|
411
|
+
self._trivial_parts.add(frame.domain())
|
|
412
|
+
self._frames.append(frame)
|
|
413
|
+
|
|
414
|
+
def trivialization(self, name, domain=None, latex_name=None):
|
|
415
|
+
r"""
|
|
416
|
+
Return a trivialization of ``self`` over the domain ``domain``.
|
|
417
|
+
|
|
418
|
+
INPUT:
|
|
419
|
+
|
|
420
|
+
- ``domain`` -- (default: ``None``) domain on which the trivialization
|
|
421
|
+
is defined; if ``None`` the base space is assumed
|
|
422
|
+
- ``name`` -- (default: ``None``) name given to the trivialization
|
|
423
|
+
- ``latex_name`` -- (default: ``None``) LaTeX name given to the
|
|
424
|
+
trivialization
|
|
425
|
+
|
|
426
|
+
OUTPUT:
|
|
427
|
+
|
|
428
|
+
- a :class:`~sage.manifolds.trivialization.Trivialization` representing
|
|
429
|
+
a trivialization of `E`
|
|
430
|
+
|
|
431
|
+
EXAMPLES::
|
|
432
|
+
|
|
433
|
+
sage: M = Manifold(3, 'M')
|
|
434
|
+
sage: U = M.open_subset('U')
|
|
435
|
+
sage: E = M.vector_bundle(2, 'E')
|
|
436
|
+
sage: phi = E.trivialization('phi', domain=U); phi
|
|
437
|
+
Trivialization (phi, E|_U)
|
|
438
|
+
"""
|
|
439
|
+
if domain is None:
|
|
440
|
+
domain = self._base_space
|
|
441
|
+
from sage.manifolds.trivialization import Trivialization
|
|
442
|
+
return Trivialization(self, name, domain=domain, latex_name=latex_name)
|
|
443
|
+
|
|
444
|
+
def transitions(self):
|
|
445
|
+
r"""
|
|
446
|
+
Return the transition maps defined over subsets of the base space.
|
|
447
|
+
|
|
448
|
+
OUTPUT: dictionary of transition maps, with pairs of trivializations as keys
|
|
449
|
+
|
|
450
|
+
EXAMPLES::
|
|
451
|
+
|
|
452
|
+
sage: M = Manifold(3, 'M')
|
|
453
|
+
sage: X.<x,y,z> = M.chart()
|
|
454
|
+
sage: U = M.open_subset('U')
|
|
455
|
+
sage: V = M.open_subset('V')
|
|
456
|
+
sage: X_UV = X.restrict(U.intersection(V))
|
|
457
|
+
sage: E = M.vector_bundle(2, 'E')
|
|
458
|
+
sage: phi_U = E.trivialization('phi_U', domain=U)
|
|
459
|
+
sage: phi_V = E.trivialization('phi_U', domain=V)
|
|
460
|
+
sage: phi_U_to_phi_V = phi_U.transition_map(phi_V, 1)
|
|
461
|
+
sage: E.transitions() # random
|
|
462
|
+
{(Trivialization (phi_U, E|_U),
|
|
463
|
+
Trivialization (phi_U, E|_V)): Transition map from Trivialization
|
|
464
|
+
(phi_U, E|_U) to Trivialization (phi_U, E|_V),
|
|
465
|
+
(Trivialization (phi_U, E|_V),
|
|
466
|
+
Trivialization (phi_U, E|_U)): Transition map from Trivialization
|
|
467
|
+
(phi_U, E|_V) to Trivialization (phi_U, E|_U)}
|
|
468
|
+
"""
|
|
469
|
+
return self._transitions.copy()
|
|
470
|
+
|
|
471
|
+
def transition(self, triv1, triv2):
|
|
472
|
+
r"""
|
|
473
|
+
Return the transition map between two trivializations defined over the
|
|
474
|
+
manifold.
|
|
475
|
+
|
|
476
|
+
The transition map must have been defined previously, for instance by
|
|
477
|
+
the method
|
|
478
|
+
:meth:`~sage.manifolds.trivialization.Trivialization.transition_map`.
|
|
479
|
+
|
|
480
|
+
INPUT:
|
|
481
|
+
|
|
482
|
+
- ``triv1`` -- trivialization 1
|
|
483
|
+
- ``triv2`` -- trivialization 2
|
|
484
|
+
|
|
485
|
+
OUTPUT:
|
|
486
|
+
|
|
487
|
+
- instance of :class:`~sage.manifolds.trivialization.TransitionMap`
|
|
488
|
+
representing the transition map from trivialization 1 to
|
|
489
|
+
trivialization 2
|
|
490
|
+
|
|
491
|
+
EXAMPLES::
|
|
492
|
+
|
|
493
|
+
sage: M = Manifold(3, 'M')
|
|
494
|
+
sage: X.<x,y,z> = M.chart()
|
|
495
|
+
sage: U = M.open_subset('U')
|
|
496
|
+
sage: V = M.open_subset('V')
|
|
497
|
+
sage: X_UV = X.restrict(U.intersection(V))
|
|
498
|
+
sage: E = M.vector_bundle(2, 'E')
|
|
499
|
+
sage: phi_U = E.trivialization('phi_U', domain=U)
|
|
500
|
+
sage: phi_V = E.trivialization('phi_V', domain=V)
|
|
501
|
+
sage: phi_U_to_phi_V = phi_U.transition_map(phi_V, 1)
|
|
502
|
+
sage: E.transition(phi_V, phi_U)
|
|
503
|
+
Transition map from Trivialization (phi_V, E|_V) to Trivialization
|
|
504
|
+
(phi_U, E|_U)
|
|
505
|
+
"""
|
|
506
|
+
if (triv1, triv2) not in self._transitions:
|
|
507
|
+
raise TypeError("the transition map from " +
|
|
508
|
+
"{} to {}".format(triv1, triv2) + " has not " +
|
|
509
|
+
"been defined on the {}".format(self))
|
|
510
|
+
return self._transitions[(triv1, triv2)]
|
|
511
|
+
|
|
512
|
+
def atlas(self):
|
|
513
|
+
r"""
|
|
514
|
+
Return the list of trivializations that have been defined for ``self``.
|
|
515
|
+
|
|
516
|
+
EXAMPLES::
|
|
517
|
+
|
|
518
|
+
sage: M = Manifold(3, 'M')
|
|
519
|
+
sage: U = M.open_subset('U')
|
|
520
|
+
sage: V = M.open_subset('V')
|
|
521
|
+
sage: E = M.vector_bundle(2, 'E')
|
|
522
|
+
sage: phi_U = E.trivialization('phi_U', domain=U)
|
|
523
|
+
sage: phi_V = E.trivialization('phi_V', domain=V)
|
|
524
|
+
sage: phi_M = E.trivialization('phi_M')
|
|
525
|
+
sage: E.atlas()
|
|
526
|
+
[Trivialization (phi_U, E|_U),
|
|
527
|
+
Trivialization (phi_V, E|_V),
|
|
528
|
+
Trivialization (phi_M, E|_M)]
|
|
529
|
+
"""
|
|
530
|
+
return list(self._atlas) # Make a (shallow) copy
|
|
531
|
+
|
|
532
|
+
def is_manifestly_trivial(self):
|
|
533
|
+
r"""
|
|
534
|
+
Return ``True`` if ``self`` is manifestly a trivial bundle, i.e. there
|
|
535
|
+
exists a frame or a trivialization defined on the whole base space.
|
|
536
|
+
|
|
537
|
+
EXAMPLES::
|
|
538
|
+
|
|
539
|
+
sage: M = Manifold(2, 'M', structure='top')
|
|
540
|
+
sage: E = M.vector_bundle(1, 'E')
|
|
541
|
+
sage: U = M.open_subset('U')
|
|
542
|
+
sage: V = M.open_subset('V')
|
|
543
|
+
sage: M.declare_union(U, V)
|
|
544
|
+
sage: phi_U = E.trivialization('phi_U', domain=U); phi_U
|
|
545
|
+
Trivialization (phi_U, E|_U)
|
|
546
|
+
sage: phi_V = E.trivialization('phi_V', domain=V); phi_V
|
|
547
|
+
Trivialization (phi_V, E|_V)
|
|
548
|
+
sage: E.is_manifestly_trivial()
|
|
549
|
+
False
|
|
550
|
+
sage: E.trivialization('phi_M', M)
|
|
551
|
+
Trivialization (phi_M, E|_M)
|
|
552
|
+
sage: E.is_manifestly_trivial()
|
|
553
|
+
True
|
|
554
|
+
"""
|
|
555
|
+
return self.base_space() in self._trivial_parts
|
|
556
|
+
|
|
557
|
+
def section_module(self, domain=None, force_free=False):
|
|
558
|
+
r"""
|
|
559
|
+
Return the section module of continuous sections on ``self``.
|
|
560
|
+
|
|
561
|
+
See :class:`~sage.manifolds.section_module.SectionModule` for a complete
|
|
562
|
+
documentation.
|
|
563
|
+
|
|
564
|
+
INPUT:
|
|
565
|
+
|
|
566
|
+
- ``domain`` -- (default: ``None``) the domain on which the module is
|
|
567
|
+
defined; if ``None`` the base space is assumed
|
|
568
|
+
- ``force_free`` -- boolean (default: ``False``); if set to ``True``, force
|
|
569
|
+
the construction of a *free* module (this implies that `E` is trivial)
|
|
570
|
+
|
|
571
|
+
OUTPUT:
|
|
572
|
+
|
|
573
|
+
- a
|
|
574
|
+
:class:`~sage.manifolds.section_module.SectionModule`
|
|
575
|
+
(or if `E` is trivial, a
|
|
576
|
+
:class:`~sage.manifolds.section_module.SectionFreeModule`)
|
|
577
|
+
representing the module of continuous sections on
|
|
578
|
+
`U` taking values in `E`
|
|
579
|
+
|
|
580
|
+
EXAMPLES:
|
|
581
|
+
|
|
582
|
+
Module of sections on the Möbius bundle over the real-projective space
|
|
583
|
+
`M=\RR P^1`::
|
|
584
|
+
|
|
585
|
+
sage: M = Manifold(1, 'RP^1', structure='top', start_index=1)
|
|
586
|
+
sage: U = M.open_subset('U') # the complement of one point
|
|
587
|
+
sage: c_u.<u> = U.chart() # [1:u] in homogeneous coord.
|
|
588
|
+
sage: V = M.open_subset('V') # the complement of the point u=0
|
|
589
|
+
sage: M.declare_union(U,V) # [v:1] in homogeneous coord.
|
|
590
|
+
sage: c_v.<v> = V.chart()
|
|
591
|
+
sage: u_to_v = c_u.transition_map(c_v, (1/u),
|
|
592
|
+
....: intersection_name='W',
|
|
593
|
+
....: restrictions1 = u!=0,
|
|
594
|
+
....: restrictions2 = v!=0)
|
|
595
|
+
sage: v_to_u = u_to_v.inverse()
|
|
596
|
+
sage: W = U.intersection(V)
|
|
597
|
+
sage: E = M.vector_bundle(1, 'E')
|
|
598
|
+
sage: phi_U = E.trivialization('phi_U', latex_name=r'\varphi_U',
|
|
599
|
+
....: domain=U)
|
|
600
|
+
sage: phi_V = E.trivialization('phi_V', latex_name=r'\varphi_V',
|
|
601
|
+
....: domain=V)
|
|
602
|
+
sage: transf = phi_U.transition_map(phi_V, [[u]])
|
|
603
|
+
sage: C0 = E.section_module(); C0
|
|
604
|
+
Module C^0(RP^1;E) of sections on the 1-dimensional topological
|
|
605
|
+
manifold RP^1 with values in the real vector bundle E of rank 1
|
|
606
|
+
|
|
607
|
+
`C^0(\RR P^1;E)` is a module over the algebra `C^0(\RR P^1)`::
|
|
608
|
+
|
|
609
|
+
sage: C0.category()
|
|
610
|
+
Category of modules over Algebra of scalar fields on the
|
|
611
|
+
1-dimensional topological manifold RP^1
|
|
612
|
+
sage: C0.base_ring() is M.scalar_field_algebra()
|
|
613
|
+
True
|
|
614
|
+
|
|
615
|
+
However, `C^0(\RR P^1;E)` is not a free module::
|
|
616
|
+
|
|
617
|
+
sage: isinstance(C0, FiniteRankFreeModule)
|
|
618
|
+
False
|
|
619
|
+
|
|
620
|
+
since the Möbius bundle is not trivial::
|
|
621
|
+
|
|
622
|
+
sage: E.is_manifestly_trivial()
|
|
623
|
+
False
|
|
624
|
+
|
|
625
|
+
The section module over `U`, on the other hand, is a free module since
|
|
626
|
+
`E|_U` admits a trivialization and therefore has a local frame::
|
|
627
|
+
|
|
628
|
+
sage: C0_U = E.section_module(domain=U)
|
|
629
|
+
sage: isinstance(C0_U, FiniteRankFreeModule)
|
|
630
|
+
True
|
|
631
|
+
|
|
632
|
+
The elements of `C^0(U)` are sections on `U`::
|
|
633
|
+
|
|
634
|
+
sage: C0_U.an_element()
|
|
635
|
+
Section on the Open subset U of the 1-dimensional topological
|
|
636
|
+
manifold RP^1 with values in the real vector bundle E of rank 1
|
|
637
|
+
sage: C0_U.an_element().display(phi_U.frame())
|
|
638
|
+
2 (phi_U^*e_1)
|
|
639
|
+
"""
|
|
640
|
+
if domain is None:
|
|
641
|
+
domain = self._base_space
|
|
642
|
+
from sage.manifolds.section_module import SectionFreeModule, SectionModule
|
|
643
|
+
if domain not in self._section_modules:
|
|
644
|
+
if force_free or domain in self._trivial_parts:
|
|
645
|
+
self._section_modules[domain] = SectionFreeModule(self, domain)
|
|
646
|
+
else:
|
|
647
|
+
self._section_modules[domain] = SectionModule(self, domain)
|
|
648
|
+
|
|
649
|
+
return self._section_modules[domain]
|
|
650
|
+
|
|
651
|
+
def fiber(self, point):
|
|
652
|
+
r"""
|
|
653
|
+
Return the vector bundle fiber over a point.
|
|
654
|
+
|
|
655
|
+
INPUT:
|
|
656
|
+
|
|
657
|
+
- ``point`` -- :class:`~sage.manifolds.point.ManifoldPoint`;
|
|
658
|
+
point `p` of the base space of ``self``
|
|
659
|
+
|
|
660
|
+
OUTPUT:
|
|
661
|
+
|
|
662
|
+
- instance of :class:`~sage.manifolds.vector_bundle_fiber.VectorBundleFiber`
|
|
663
|
+
representing the fiber over `p`
|
|
664
|
+
|
|
665
|
+
EXAMPLES::
|
|
666
|
+
|
|
667
|
+
sage: M = Manifold(3, 'M', structure='top')
|
|
668
|
+
sage: X.<x,y,z> = M.chart()
|
|
669
|
+
sage: p = M((0,2,1), name='p'); p
|
|
670
|
+
Point p on the 3-dimensional topological manifold M
|
|
671
|
+
sage: E = M.vector_bundle(2, 'E'); E
|
|
672
|
+
Topological real vector bundle E -> M of rank 2 over the base space
|
|
673
|
+
3-dimensional topological manifold M
|
|
674
|
+
sage: E.fiber(p)
|
|
675
|
+
Fiber of E at Point p on the 3-dimensional topological manifold M
|
|
676
|
+
"""
|
|
677
|
+
return VectorBundleFiber(self, point)
|
|
678
|
+
|
|
679
|
+
def local_frame(self, *args, **kwargs):
|
|
680
|
+
r"""
|
|
681
|
+
Define a local frame on ``self``.
|
|
682
|
+
|
|
683
|
+
A *local frame* is a section on a subset `U \subset M` in `E` that
|
|
684
|
+
provides, at each point `p` of the base space, a vector basis of the
|
|
685
|
+
fiber `E_p` at `p`.
|
|
686
|
+
|
|
687
|
+
.. SEEALSO::
|
|
688
|
+
|
|
689
|
+
:class:`~sage.manifolds.local_frame.LocalFrame` for complete
|
|
690
|
+
documentation.
|
|
691
|
+
|
|
692
|
+
INPUT:
|
|
693
|
+
|
|
694
|
+
- ``symbol`` -- either a string, to be used as a common base for the
|
|
695
|
+
symbols of the sections constituting the local frame, or a list/tuple
|
|
696
|
+
of strings, representing the individual symbols of the sections
|
|
697
|
+
- ``sections`` -- tuple or list of `n` linearly independent sections on
|
|
698
|
+
``self`` (`n` being the rank of ``self``) defining the local
|
|
699
|
+
frame; can be omitted if the local frame is created from scratch
|
|
700
|
+
- ``latex_symbol`` -- (default: ``None``) either a string, to be used
|
|
701
|
+
as a common base for the LaTeX symbols of the sections
|
|
702
|
+
constituting the local frame, or a list/tuple of strings,
|
|
703
|
+
representing the individual LaTeX symbols of the sections;
|
|
704
|
+
if ``None``, ``symbol`` is used in place of ``latex_symbol``
|
|
705
|
+
- ``indices`` -- (default: ``None``; used only if ``symbol`` is a
|
|
706
|
+
single string) tuple of strings representing the indices labelling
|
|
707
|
+
the sections of the frame; if ``None``, the indices will be
|
|
708
|
+
generated as integers within the range declared on ``self``
|
|
709
|
+
- ``latex_indices`` -- (default: ``None``) tuple of strings
|
|
710
|
+
representing the indices for the LaTeX symbols of the sections;
|
|
711
|
+
if ``None``, ``indices`` is used instead
|
|
712
|
+
- ``symbol_dual`` -- (default: ``None``) same as ``symbol`` but for the
|
|
713
|
+
dual coframe; if ``None``, ``symbol`` must be a string and is used
|
|
714
|
+
for the common base of the symbols of the elements of the dual
|
|
715
|
+
coframe
|
|
716
|
+
- ``latex_symbol_dual`` -- (default: ``None``) same as ``latex_symbol``
|
|
717
|
+
but for the dual coframe
|
|
718
|
+
- ``domain`` -- (default: ``None``) domain on which the local frame
|
|
719
|
+
is defined; if ``None``, the whole base space is assumed
|
|
720
|
+
|
|
721
|
+
OUTPUT:
|
|
722
|
+
|
|
723
|
+
- a :class:`~sage.manifolds.local_frame.LocalFrame` representing the
|
|
724
|
+
defined local frame
|
|
725
|
+
|
|
726
|
+
EXAMPLES:
|
|
727
|
+
|
|
728
|
+
|
|
729
|
+
Defining a local frame from two linearly independent sections on a
|
|
730
|
+
real rank-2 vector bundle::
|
|
731
|
+
|
|
732
|
+
sage: M = Manifold(3, 'M', structure='top')
|
|
733
|
+
sage: U = M.open_subset('U')
|
|
734
|
+
sage: X.<x,y,z> = U.chart()
|
|
735
|
+
sage: E = M.vector_bundle(2, 'E')
|
|
736
|
+
sage: phi = E.trivialization('phi', domain=U)
|
|
737
|
+
sage: s0 = E.section(name='s_0', domain=U)
|
|
738
|
+
sage: s0[:] = 1+z^2, -2
|
|
739
|
+
sage: s1 = E.section(name='s_1', domain=U)
|
|
740
|
+
sage: s1[:] = 1, 1+x^2
|
|
741
|
+
sage: e = E.local_frame('e', (s0, s1), domain=U); e
|
|
742
|
+
Local frame (E|_U, (e_0,e_1))
|
|
743
|
+
sage: (e[0], e[1]) == (s0, s1)
|
|
744
|
+
True
|
|
745
|
+
|
|
746
|
+
If the sections are not linearly independent, an error is raised::
|
|
747
|
+
|
|
748
|
+
sage: e = E.local_frame('z', (s0, -s0), domain=U)
|
|
749
|
+
Traceback (most recent call last):
|
|
750
|
+
...
|
|
751
|
+
ValueError: the provided sections are not linearly independent
|
|
752
|
+
|
|
753
|
+
It is also possible to create a local frame from scratch, without
|
|
754
|
+
connecting it to previously defined local frames or sections
|
|
755
|
+
(this can still be performed later via the method
|
|
756
|
+
:meth:`set_change_of_frame`)::
|
|
757
|
+
|
|
758
|
+
sage: f = E.local_frame('f', domain=U); f
|
|
759
|
+
Local frame (E|_U, (f_0,f_1))
|
|
760
|
+
|
|
761
|
+
For a global frame, the argument ``domain`` is omitted::
|
|
762
|
+
|
|
763
|
+
sage: g = E.local_frame('g'); g
|
|
764
|
+
Local frame (E|_M, (g_0,g_1))
|
|
765
|
+
|
|
766
|
+
.. SEEALSO::
|
|
767
|
+
|
|
768
|
+
For more options, in particular for the choice of symbols and
|
|
769
|
+
indices, see :class:`~sage.manifolds.local_frame.LocalFrame`.
|
|
770
|
+
"""
|
|
771
|
+
from sage.manifolds.local_frame import LocalFrame
|
|
772
|
+
# Input processing
|
|
773
|
+
n_args = len(args)
|
|
774
|
+
if n_args < 1 or n_args > 2:
|
|
775
|
+
raise TypeError("local_frame() takes one or two positional "
|
|
776
|
+
"arguments, not {}".format(n_args))
|
|
777
|
+
symbol = args[0]
|
|
778
|
+
sections = None
|
|
779
|
+
if n_args == 2:
|
|
780
|
+
sections = args[1]
|
|
781
|
+
latex_symbol = kwargs.pop('latex_symbol', None)
|
|
782
|
+
indices = kwargs.pop('indices', None)
|
|
783
|
+
latex_indices = kwargs.pop('latex_indices', None)
|
|
784
|
+
symbol_dual = kwargs.pop('symbol_dual', None)
|
|
785
|
+
latex_symbol_dual = kwargs.pop('latex_symbol_dual', None)
|
|
786
|
+
domain = kwargs.pop('domain', None)
|
|
787
|
+
|
|
788
|
+
sec_module = self.section_module(domain=domain, force_free=True)
|
|
789
|
+
resu = LocalFrame(sec_module, symbol=symbol, latex_symbol=latex_symbol,
|
|
790
|
+
indices=indices, latex_indices=latex_indices,
|
|
791
|
+
symbol_dual=symbol_dual,
|
|
792
|
+
latex_symbol_dual=latex_symbol_dual)
|
|
793
|
+
if sections:
|
|
794
|
+
linked = False
|
|
795
|
+
try:
|
|
796
|
+
resu._init_from_family(sections)
|
|
797
|
+
except ArithmeticError as err:
|
|
798
|
+
linked = str(err) in ["non-invertible matrix",
|
|
799
|
+
"input matrix must be nonsingular"]
|
|
800
|
+
if linked:
|
|
801
|
+
raise ValueError("the provided sections are not linearly "
|
|
802
|
+
"independent")
|
|
803
|
+
return resu
|
|
804
|
+
|
|
805
|
+
def section(self, *comp, **kwargs):
|
|
806
|
+
r"""
|
|
807
|
+
Return a continuous section of ``self``.
|
|
808
|
+
|
|
809
|
+
INPUT:
|
|
810
|
+
|
|
811
|
+
- ``domain`` -- (default: ``None``) domain on which the section shall be
|
|
812
|
+
defined; if ``None``, the base space is assumed
|
|
813
|
+
- ``name`` -- (default: ``None``) name of the local section
|
|
814
|
+
- ``latex_name`` -- (default``None``) latex representation of the local
|
|
815
|
+
section
|
|
816
|
+
|
|
817
|
+
OUTPUT:
|
|
818
|
+
|
|
819
|
+
- an instance of :class:`~sage.manifolds.section.Section` representing
|
|
820
|
+
a continuous section of `M` with values on `E`
|
|
821
|
+
|
|
822
|
+
EXAMPLES:
|
|
823
|
+
|
|
824
|
+
A section on a non-trivial rank 2 vector bundle over a non-trivial
|
|
825
|
+
2-manifold::
|
|
826
|
+
|
|
827
|
+
sage: M = Manifold(2, 'M', structure='top')
|
|
828
|
+
sage: U = M.open_subset('U') ; V = M.open_subset('V')
|
|
829
|
+
sage: M.declare_union(U,V) # M is the union of U and V
|
|
830
|
+
sage: c_xy.<x,y> = U.chart() ; c_uv.<u,v> = V.chart()
|
|
831
|
+
sage: xy_to_uv = c_xy.transition_map(c_uv, (x+y, x-y),
|
|
832
|
+
....: intersection_name='W', restrictions1= x>0,
|
|
833
|
+
....: restrictions2= u+v>0)
|
|
834
|
+
sage: uv_to_xy = xy_to_uv.inverse()
|
|
835
|
+
sage: W = U.intersection(V)
|
|
836
|
+
sage: E = M.vector_bundle(2, 'E') # define the vector bundle
|
|
837
|
+
sage: phi_U = E.trivialization('phi_U', domain=U) # define trivializations
|
|
838
|
+
sage: phi_V = E.trivialization('phi_V', domain=V)
|
|
839
|
+
sage: transf = phi_U.transition_map(phi_V, [[0,x],[x,0]]) # transition map between trivializations
|
|
840
|
+
sage: fU = phi_U.frame(); fV = phi_V.frame() # define induced frames
|
|
841
|
+
sage: s = E.section(name='s'); s
|
|
842
|
+
Section s on the 2-dimensional topological manifold M with values in the
|
|
843
|
+
real vector bundle E of rank 2
|
|
844
|
+
"""
|
|
845
|
+
domain = kwargs.pop('domain', self._base_space)
|
|
846
|
+
name = kwargs.pop('name', None)
|
|
847
|
+
latex_name = kwargs.pop('latex_name', None)
|
|
848
|
+
smodule = self.section_module(domain=domain) # the parent
|
|
849
|
+
resu = smodule.element_class(smodule, name=name, latex_name=latex_name)
|
|
850
|
+
if comp:
|
|
851
|
+
# Some components are to be initialized
|
|
852
|
+
resu._init_components(*comp, **kwargs)
|
|
853
|
+
return resu
|
|
854
|
+
|
|
855
|
+
def total_space(self):
|
|
856
|
+
r"""
|
|
857
|
+
Return the total space of ``self``.
|
|
858
|
+
|
|
859
|
+
.. NOTE::
|
|
860
|
+
|
|
861
|
+
At this stage, the total space does not come with induced charts.
|
|
862
|
+
|
|
863
|
+
OUTPUT:
|
|
864
|
+
|
|
865
|
+
- the total space of ``self`` as an instance of
|
|
866
|
+
:class:`~sage.manifolds.manifold.TopologicalManifold`
|
|
867
|
+
|
|
868
|
+
EXAMPLES::
|
|
869
|
+
|
|
870
|
+
sage: M = Manifold(3, 'M', structure='top')
|
|
871
|
+
sage: E = M.vector_bundle(2, 'E')
|
|
872
|
+
sage: E.total_space()
|
|
873
|
+
6-dimensional topological manifold E
|
|
874
|
+
"""
|
|
875
|
+
if self._total_space is None:
|
|
876
|
+
from sage.manifolds.manifold import Manifold
|
|
877
|
+
base_space = self._base_space
|
|
878
|
+
dim = base_space._dim * self._rank
|
|
879
|
+
sindex = base_space.start_index()
|
|
880
|
+
self._total_space = Manifold(dim, self._name,
|
|
881
|
+
latex_name=self._latex_name,
|
|
882
|
+
field=self._field, structure='topological',
|
|
883
|
+
start_index=sindex)
|
|
884
|
+
|
|
885
|
+
# TODO: if update_atlas: introduce charts via self._atlas
|
|
886
|
+
|
|
887
|
+
return self._total_space
|
|
888
|
+
|
|
889
|
+
def set_change_of_frame(self, frame1, frame2, change_of_frame,
|
|
890
|
+
compute_inverse=True):
|
|
891
|
+
r"""
|
|
892
|
+
Relate two vector frames by an automorphism.
|
|
893
|
+
|
|
894
|
+
This updates the internal dictionary ``self._frame_changes``.
|
|
895
|
+
|
|
896
|
+
INPUT:
|
|
897
|
+
|
|
898
|
+
- ``frame1`` -- frame 1, denoted `(e_i)` below
|
|
899
|
+
- ``frame2`` -- frame 2, denoted `(f_i)` below
|
|
900
|
+
- ``change_of_frame`` -- instance of class
|
|
901
|
+
:class:`~sage.tensor.modules.free_module_automorphism.FreeModuleAutomorphism`
|
|
902
|
+
describing the automorphism `P` that relates the basis `(e_i)` to
|
|
903
|
+
the basis `(f_i)` according to `f_i = P(e_i)`
|
|
904
|
+
- ``compute_inverse`` -- boolean (default: ``True``); if set to True,
|
|
905
|
+
the inverse automorphism is computed and the change from basis
|
|
906
|
+
`(f_i)` to `(e_i)` is set to it in the internal dictionary
|
|
907
|
+
``self._frame_changes``
|
|
908
|
+
|
|
909
|
+
EXAMPLES::
|
|
910
|
+
|
|
911
|
+
sage: M = Manifold(3, 'M')
|
|
912
|
+
sage: c_xyz.<x,y,z> = M.chart()
|
|
913
|
+
sage: E = M.vector_bundle(2, 'E')
|
|
914
|
+
sage: e = E.local_frame('e')
|
|
915
|
+
sage: f = E.local_frame('f')
|
|
916
|
+
sage: a = E.section_module().automorphism()
|
|
917
|
+
sage: a[e,:] = [[1,2],[0,3]]
|
|
918
|
+
sage: E.set_change_of_frame(e, f, a)
|
|
919
|
+
sage: f[0].display(e)
|
|
920
|
+
f_0 = e_0
|
|
921
|
+
sage: f[1].display(e)
|
|
922
|
+
f_1 = 2 e_0 + 3 e_1
|
|
923
|
+
sage: e[0].display(f)
|
|
924
|
+
e_0 = f_0
|
|
925
|
+
sage: e[1].display(f)
|
|
926
|
+
e_1 = -2/3 f_0 + 1/3 f_1
|
|
927
|
+
sage: E.change_of_frame(e,f)[e,:]
|
|
928
|
+
[1 2]
|
|
929
|
+
[0 3]
|
|
930
|
+
"""
|
|
931
|
+
from sage.tensor.modules.free_module_automorphism import FreeModuleAutomorphism
|
|
932
|
+
sec_module = frame1._fmodule
|
|
933
|
+
if frame2._fmodule != sec_module:
|
|
934
|
+
raise ValueError("the two frames are not defined on the same " +
|
|
935
|
+
"section module")
|
|
936
|
+
if isinstance(change_of_frame, FreeModuleAutomorphism):
|
|
937
|
+
auto = change_of_frame
|
|
938
|
+
else: # Otherwise try to coerce the input
|
|
939
|
+
auto_group = sec_module.general_linear_group()
|
|
940
|
+
auto = auto_group(change_of_frame, basis=frame1)
|
|
941
|
+
sec_module.set_change_of_basis(frame1, frame2, auto,
|
|
942
|
+
compute_inverse=compute_inverse)
|
|
943
|
+
self._frame_changes[(frame1, frame2)] = auto
|
|
944
|
+
if compute_inverse:
|
|
945
|
+
self._frame_changes[(frame2, frame1)] = ~auto
|
|
946
|
+
|
|
947
|
+
def change_of_frame(self, frame1, frame2):
|
|
948
|
+
r"""
|
|
949
|
+
Return a change of local frames defined on ``self``.
|
|
950
|
+
|
|
951
|
+
INPUT:
|
|
952
|
+
|
|
953
|
+
- ``frame1`` -- local frame 1
|
|
954
|
+
- ``frame2`` -- local frame 2
|
|
955
|
+
|
|
956
|
+
OUTPUT:
|
|
957
|
+
|
|
958
|
+
- a :class:`~sage.tensor.modules.free_module_automorphism.FreeModuleAutomorphism`
|
|
959
|
+
representing, at each point, the vector space automorphism `P` that
|
|
960
|
+
relates frame 1, `(e_i)` say, to frame 2, `(f_i)` say, according to
|
|
961
|
+
`f_i = P(e_i)`
|
|
962
|
+
|
|
963
|
+
EXAMPLES::
|
|
964
|
+
|
|
965
|
+
sage: M = Manifold(3, 'M', structure='top')
|
|
966
|
+
sage: X.<x,y,z> = M.chart()
|
|
967
|
+
sage: E = M.vector_bundle(2, 'E')
|
|
968
|
+
sage: e = E.local_frame('e')
|
|
969
|
+
sage: a = E.section_module().automorphism() # Now, the section module is free
|
|
970
|
+
sage: a[:] = [[sqrt(3)/2, -1/2], [1/2, sqrt(3)/2]]
|
|
971
|
+
sage: f = e.new_frame(a, 'f')
|
|
972
|
+
sage: E.change_of_frame(e, f)
|
|
973
|
+
Automorphism of the Free module C^0(M;E) of sections on the
|
|
974
|
+
3-dimensional topological manifold M with values in the real vector
|
|
975
|
+
bundle E of rank 2
|
|
976
|
+
sage: a == E.change_of_frame(e, f)
|
|
977
|
+
True
|
|
978
|
+
sage: a.inverse() == E.change_of_frame(f, e)
|
|
979
|
+
True
|
|
980
|
+
"""
|
|
981
|
+
if (frame1, frame2) not in self._frame_changes:
|
|
982
|
+
raise ValueError("the change of frame from {} to {}".format(frame1, frame2) +
|
|
983
|
+
" has not been defined on the {}".format(self))
|
|
984
|
+
return self._frame_changes[(frame1, frame2)]
|
|
985
|
+
|
|
986
|
+
def changes_of_frame(self):
|
|
987
|
+
r"""
|
|
988
|
+
Return all the changes of local frames defined on ``self``.
|
|
989
|
+
|
|
990
|
+
OUTPUT:
|
|
991
|
+
|
|
992
|
+
- dictionary of vector bundle automorphisms representing
|
|
993
|
+
the changes of frames, the keys being the pair of frames
|
|
994
|
+
|
|
995
|
+
EXAMPLES::
|
|
996
|
+
|
|
997
|
+
sage: M = Manifold(3, 'M', structure='top')
|
|
998
|
+
sage: c_xyz.<x,y,z> = M.chart()
|
|
999
|
+
sage: E = M.vector_bundle(2, 'E')
|
|
1000
|
+
sage: e = E.local_frame('e'); e
|
|
1001
|
+
Local frame (E|_M, (e_0,e_1))
|
|
1002
|
+
sage: auto_group = E.section_module().general_linear_group()
|
|
1003
|
+
sage: e_to_f = auto_group([[0,1],[1,0]]); e_to_f
|
|
1004
|
+
Automorphism of the Free module C^0(M;E) of sections on the
|
|
1005
|
+
3-dimensional topological manifold M with values in the real vector
|
|
1006
|
+
bundle E of rank 2
|
|
1007
|
+
sage: f_in_e = auto_group([[0,1],[1,0]])
|
|
1008
|
+
sage: f = e.new_frame(f_in_e, 'f'); f
|
|
1009
|
+
Local frame (E|_M, (f_0,f_1))
|
|
1010
|
+
sage: E.changes_of_frame() # random
|
|
1011
|
+
{(Local frame (E|_M, (f_0,f_1)),
|
|
1012
|
+
Local frame (E|_M, (e_0,e_1))): Automorphism of the Free module
|
|
1013
|
+
C^0(M;E) of sections on the 3-dimensional topological manifold M
|
|
1014
|
+
with values in the real vector bundle E of rank 2,
|
|
1015
|
+
(Local frame (E|_M, (e_0,e_1)),
|
|
1016
|
+
Local frame (E|_M, (f_0,f_1))): Automorphism of the Free module
|
|
1017
|
+
C^0(M;E) of sections on the 3-dimensional topological manifold M
|
|
1018
|
+
with values in the real vector bundle E of rank 2}
|
|
1019
|
+
"""
|
|
1020
|
+
return self._frame_changes.copy()
|
|
1021
|
+
|
|
1022
|
+
def frames(self):
|
|
1023
|
+
r"""
|
|
1024
|
+
Return the list of local frames defined on ``self``.
|
|
1025
|
+
|
|
1026
|
+
OUTPUT: list of local frames defined on ``self``
|
|
1027
|
+
|
|
1028
|
+
EXAMPLES::
|
|
1029
|
+
|
|
1030
|
+
sage: M = Manifold(3, 'M', structure='top')
|
|
1031
|
+
sage: E = M.vector_bundle(2, 'E')
|
|
1032
|
+
sage: U = M.open_subset('U'); V = M.open_subset('V')
|
|
1033
|
+
sage: phi_U = E.trivialization('phi_U', domain=U)
|
|
1034
|
+
sage: e = E.local_frame('e', domain=V)
|
|
1035
|
+
sage: E.frames()
|
|
1036
|
+
[Trivialization frame (E|_U, ((phi_U^*e_1),(phi_U^*e_2))),
|
|
1037
|
+
Local frame (E|_V, (e_0,e_1))]
|
|
1038
|
+
"""
|
|
1039
|
+
return list(self._frames)
|
|
1040
|
+
|
|
1041
|
+
def coframes(self):
|
|
1042
|
+
r"""
|
|
1043
|
+
Return the list of coframes defined on ``self``.
|
|
1044
|
+
|
|
1045
|
+
OUTPUT: list of coframes defined on ``self``
|
|
1046
|
+
|
|
1047
|
+
EXAMPLES::
|
|
1048
|
+
|
|
1049
|
+
sage: M = Manifold(3, 'M', structure='top')
|
|
1050
|
+
sage: E = M.vector_bundle(2, 'E')
|
|
1051
|
+
sage: U = M.open_subset('U'); V = M.open_subset('V')
|
|
1052
|
+
sage: phi_U = E.trivialization('phi_U', domain=U)
|
|
1053
|
+
sage: e = E.local_frame('e', domain=V)
|
|
1054
|
+
sage: E.coframes()
|
|
1055
|
+
[Trivialization coframe (E|_U, ((phi_U^*e^1),(phi_U^*e^2))),
|
|
1056
|
+
Local coframe (E|_V, (e^0,e^1))]
|
|
1057
|
+
"""
|
|
1058
|
+
return list(self._coframes)
|
|
1059
|
+
|
|
1060
|
+
def default_frame(self):
|
|
1061
|
+
r"""
|
|
1062
|
+
Return the default frame of on ``self``.
|
|
1063
|
+
|
|
1064
|
+
OUTPUT:
|
|
1065
|
+
|
|
1066
|
+
- a local frame as an instance of
|
|
1067
|
+
:class:`~sage.manifolds.local_frame.LocalFrame`
|
|
1068
|
+
|
|
1069
|
+
EXAMPLES::
|
|
1070
|
+
|
|
1071
|
+
sage: M = Manifold(3, 'M', structure='top')
|
|
1072
|
+
sage: E = M.vector_bundle(2, 'E')
|
|
1073
|
+
sage: e = E.local_frame('e')
|
|
1074
|
+
sage: E.default_frame()
|
|
1075
|
+
Local frame (E|_M, (e_0,e_1))
|
|
1076
|
+
"""
|
|
1077
|
+
return self._def_frame
|
|
1078
|
+
|
|
1079
|
+
def set_default_frame(self, frame):
|
|
1080
|
+
r"""
|
|
1081
|
+
Set the default frame of ``self``.
|
|
1082
|
+
|
|
1083
|
+
INPUT:
|
|
1084
|
+
|
|
1085
|
+
- ``frame`` -- a local frame defined on ``self`` as an instance of
|
|
1086
|
+
:class:`~sage.manifolds.local_frame.LocalFrame`
|
|
1087
|
+
|
|
1088
|
+
EXAMPLES::
|
|
1089
|
+
|
|
1090
|
+
sage: M = Manifold(3, 'M', structure='top')
|
|
1091
|
+
sage: E = M.vector_bundle(2, 'E')
|
|
1092
|
+
sage: e = E.local_frame('e')
|
|
1093
|
+
sage: E.default_frame()
|
|
1094
|
+
Local frame (E|_M, (e_0,e_1))
|
|
1095
|
+
sage: f = E.local_frame('f')
|
|
1096
|
+
sage: E.set_default_frame(f)
|
|
1097
|
+
sage: E.default_frame()
|
|
1098
|
+
Local frame (E|_M, (f_0,f_1))
|
|
1099
|
+
"""
|
|
1100
|
+
from sage.manifolds.local_frame import LocalFrame
|
|
1101
|
+
if not isinstance(frame, LocalFrame):
|
|
1102
|
+
raise TypeError("{} is not a local frame".format(frame))
|
|
1103
|
+
if not frame._domain.is_subset(self._base_space):
|
|
1104
|
+
raise ValueError("the frame must be defined on " +
|
|
1105
|
+
"the {}".format(self))
|
|
1106
|
+
frame._fmodule.set_default_basis(frame)
|
|
1107
|
+
self._def_frame = frame
|
|
1108
|
+
|
|
1109
|
+
def set_orientation(self, orientation):
|
|
1110
|
+
r"""
|
|
1111
|
+
Set the preferred orientation of ``self``.
|
|
1112
|
+
|
|
1113
|
+
INPUT:
|
|
1114
|
+
|
|
1115
|
+
- ``orientation`` -- a local frame or a list of local frames whose
|
|
1116
|
+
domains cover the base space
|
|
1117
|
+
|
|
1118
|
+
.. WARNING::
|
|
1119
|
+
|
|
1120
|
+
It is the user's responsibility that the orientation set here
|
|
1121
|
+
is indeed an orientation. There is no check going on in the
|
|
1122
|
+
background. See :meth:`orientation` for the definition of an
|
|
1123
|
+
orientation.
|
|
1124
|
+
|
|
1125
|
+
EXAMPLES:
|
|
1126
|
+
|
|
1127
|
+
Set an orientation on a vector bundle::
|
|
1128
|
+
|
|
1129
|
+
sage: M = Manifold(3, 'M', structure='top')
|
|
1130
|
+
sage: E = M.vector_bundle(2, 'E')
|
|
1131
|
+
sage: e = E.local_frame('e'); e
|
|
1132
|
+
Local frame (E|_M, (e_0,e_1))
|
|
1133
|
+
sage: f = E.local_frame('f'); f
|
|
1134
|
+
Local frame (E|_M, (f_0,f_1))
|
|
1135
|
+
sage: E.set_orientation(f)
|
|
1136
|
+
sage: E.orientation()
|
|
1137
|
+
[Local frame (E|_M, (f_0,f_1))]
|
|
1138
|
+
|
|
1139
|
+
Set an orientation in the non-trivial case::
|
|
1140
|
+
|
|
1141
|
+
sage: M = Manifold(3, 'M', structure='top')
|
|
1142
|
+
sage: U = M.open_subset('U'); V = M.open_subset('V')
|
|
1143
|
+
sage: M.declare_union(U, V)
|
|
1144
|
+
sage: E = M.vector_bundle(2, 'E')
|
|
1145
|
+
sage: e = E.local_frame('e', domain=U); e
|
|
1146
|
+
Local frame (E|_U, (e_0,e_1))
|
|
1147
|
+
sage: f = E.local_frame('f', domain=V); f
|
|
1148
|
+
Local frame (E|_V, (f_0,f_1))
|
|
1149
|
+
sage: E.orientation()
|
|
1150
|
+
[]
|
|
1151
|
+
sage: E.set_orientation([e, f])
|
|
1152
|
+
sage: E.orientation()
|
|
1153
|
+
[Local frame (E|_U, (e_0,e_1)),
|
|
1154
|
+
Local frame (E|_V, (f_0,f_1))]
|
|
1155
|
+
"""
|
|
1156
|
+
from sage.manifolds.local_frame import LocalFrame
|
|
1157
|
+
if isinstance(orientation, LocalFrame):
|
|
1158
|
+
orientation = [orientation]
|
|
1159
|
+
elif isinstance(orientation, (tuple, list)):
|
|
1160
|
+
orientation = list(orientation)
|
|
1161
|
+
else:
|
|
1162
|
+
raise TypeError("orientation must be a frame or a list/tuple of "
|
|
1163
|
+
"frames")
|
|
1164
|
+
dom_union = None
|
|
1165
|
+
for frame in orientation:
|
|
1166
|
+
if frame not in self.frames():
|
|
1167
|
+
raise ValueError("{} must be a frame ".format(frame) +
|
|
1168
|
+
"defined on {}".format(self))
|
|
1169
|
+
dom = frame.domain()
|
|
1170
|
+
if dom_union is not None:
|
|
1171
|
+
dom_union = dom.union(dom_union)
|
|
1172
|
+
else:
|
|
1173
|
+
dom_union = dom
|
|
1174
|
+
base_space = self._base_space
|
|
1175
|
+
if dom_union != base_space:
|
|
1176
|
+
raise ValueError("the frames's domains must "
|
|
1177
|
+
"cover {}".format(base_space))
|
|
1178
|
+
self._orientation = orientation
|
|
1179
|
+
|
|
1180
|
+
def orientation(self):
|
|
1181
|
+
r"""
|
|
1182
|
+
Get the orientation of ``self`` if available.
|
|
1183
|
+
|
|
1184
|
+
An *orientation* on a vector bundle is a choice of local frames whose
|
|
1185
|
+
|
|
1186
|
+
1. union of domains cover the base space,
|
|
1187
|
+
2. changes of frames are pairwise orientation preserving, i.e. have
|
|
1188
|
+
positive determinant.
|
|
1189
|
+
|
|
1190
|
+
A vector bundle endowed with an orientation is called *orientable*.
|
|
1191
|
+
|
|
1192
|
+
The trivial case corresponds to ``self`` being trivial, i.e. ``self``
|
|
1193
|
+
can be covered by one frame. In that case, if no preferred
|
|
1194
|
+
orientation has been set before, one of those frames (usually the
|
|
1195
|
+
default frame) is set automatically to the preferred orientation and
|
|
1196
|
+
returned here.
|
|
1197
|
+
|
|
1198
|
+
EXAMPLES:
|
|
1199
|
+
|
|
1200
|
+
The trivial case is covered automatically::
|
|
1201
|
+
|
|
1202
|
+
sage: M = Manifold(3, 'M', structure='top')
|
|
1203
|
+
sage: E = M.vector_bundle(2, 'E')
|
|
1204
|
+
sage: e = E.local_frame('e'); e
|
|
1205
|
+
Local frame (E|_M, (e_0,e_1))
|
|
1206
|
+
sage: E.orientation() # trivial case
|
|
1207
|
+
[Local frame (E|_M, (e_0,e_1))]
|
|
1208
|
+
|
|
1209
|
+
The orientation can also be set by the user::
|
|
1210
|
+
|
|
1211
|
+
sage: f = E.local_frame('f'); f
|
|
1212
|
+
Local frame (E|_M, (f_0,f_1))
|
|
1213
|
+
sage: E.set_orientation(f)
|
|
1214
|
+
sage: E.orientation()
|
|
1215
|
+
[Local frame (E|_M, (f_0,f_1))]
|
|
1216
|
+
|
|
1217
|
+
In case of the non-trivial case, the orientation must be set manually,
|
|
1218
|
+
otherwise no orientation is returned::
|
|
1219
|
+
|
|
1220
|
+
sage: M = Manifold(3, 'M', structure='top')
|
|
1221
|
+
sage: U = M.open_subset('U'); V = M.open_subset('V')
|
|
1222
|
+
sage: M.declare_union(U, V)
|
|
1223
|
+
sage: E = M.vector_bundle(2, 'E')
|
|
1224
|
+
sage: e = E.local_frame('e', domain=U); e
|
|
1225
|
+
Local frame (E|_U, (e_0,e_1))
|
|
1226
|
+
sage: f = E.local_frame('f', domain=V); f
|
|
1227
|
+
Local frame (E|_V, (f_0,f_1))
|
|
1228
|
+
sage: E.orientation()
|
|
1229
|
+
[]
|
|
1230
|
+
sage: E.set_orientation([e, f])
|
|
1231
|
+
sage: E.orientation()
|
|
1232
|
+
[Local frame (E|_U, (e_0,e_1)),
|
|
1233
|
+
Local frame (E|_V, (f_0,f_1))]
|
|
1234
|
+
"""
|
|
1235
|
+
if not self._orientation:
|
|
1236
|
+
# Trivial case:
|
|
1237
|
+
if self.is_manifestly_trivial():
|
|
1238
|
+
# Try the default frame:
|
|
1239
|
+
def_frame = self._def_frame
|
|
1240
|
+
if def_frame is not None:
|
|
1241
|
+
if def_frame._domain is self._base_space:
|
|
1242
|
+
self._orientation = [def_frame]
|
|
1243
|
+
# Still no orientation? Choose arbitrary frame:
|
|
1244
|
+
if not self._orientation:
|
|
1245
|
+
for frame in self.frames():
|
|
1246
|
+
if frame._domain is self._base_space:
|
|
1247
|
+
self._orientation = [frame]
|
|
1248
|
+
break
|
|
1249
|
+
return list(self._orientation)
|
|
1250
|
+
|
|
1251
|
+
def has_orientation(self) -> bool:
|
|
1252
|
+
r"""
|
|
1253
|
+
Check whether ``self`` admits an obvious or by user set orientation.
|
|
1254
|
+
|
|
1255
|
+
.. SEEALSO::
|
|
1256
|
+
|
|
1257
|
+
Consult :meth:`orientation` for details about orientations.
|
|
1258
|
+
|
|
1259
|
+
.. NOTE::
|
|
1260
|
+
|
|
1261
|
+
Notice that if :meth:`has_orientation` returns ``False`` this does
|
|
1262
|
+
not necessarily mean that the vector bundle admits no orientation.
|
|
1263
|
+
It just means that the user has to set an orientation manually
|
|
1264
|
+
in that case, see :meth:`set_orientation`.
|
|
1265
|
+
|
|
1266
|
+
EXAMPLES:
|
|
1267
|
+
|
|
1268
|
+
The trivial case::
|
|
1269
|
+
|
|
1270
|
+
sage: M = Manifold(3, 'M', structure='top')
|
|
1271
|
+
sage: E = M.vector_bundle(2, 'E')
|
|
1272
|
+
sage: e = E.local_frame('e')
|
|
1273
|
+
sage: E.has_orientation() # trivial case
|
|
1274
|
+
True
|
|
1275
|
+
|
|
1276
|
+
Non-trivial case::
|
|
1277
|
+
|
|
1278
|
+
sage: M = Manifold(3, 'M', structure='top')
|
|
1279
|
+
sage: U = M.open_subset('U'); V = M.open_subset('V')
|
|
1280
|
+
sage: M.declare_union(U, V)
|
|
1281
|
+
sage: E = M.vector_bundle(2, 'E')
|
|
1282
|
+
sage: e = E.local_frame('e', domain=U)
|
|
1283
|
+
sage: f = E.local_frame('f', domain=V)
|
|
1284
|
+
sage: E.has_orientation()
|
|
1285
|
+
False
|
|
1286
|
+
sage: E.set_orientation([e, f])
|
|
1287
|
+
sage: E.has_orientation()
|
|
1288
|
+
True
|
|
1289
|
+
"""
|
|
1290
|
+
return bool(self.orientation())
|
|
1291
|
+
|
|
1292
|
+
def irange(self, start=None):
|
|
1293
|
+
r"""
|
|
1294
|
+
Single index generator.
|
|
1295
|
+
|
|
1296
|
+
INPUT:
|
|
1297
|
+
|
|
1298
|
+
- ``start`` -- (default: ``None``) initial value `i_0` of the index;
|
|
1299
|
+
if none are provided, the value returned by
|
|
1300
|
+
:meth:`sage.manifolds.manifold.Manifold.start_index()` is assumed
|
|
1301
|
+
|
|
1302
|
+
OUTPUT:
|
|
1303
|
+
|
|
1304
|
+
- an iterable index, starting from `i_0` and ending at
|
|
1305
|
+
`i_0 + n - 1`, where `n` is the vector bundle's dimension
|
|
1306
|
+
|
|
1307
|
+
EXAMPLES:
|
|
1308
|
+
|
|
1309
|
+
Index range on a 4-dimensional vector bundle over a 5-dimensional
|
|
1310
|
+
manifold::
|
|
1311
|
+
|
|
1312
|
+
sage: M = Manifold(5, 'M', structure='topological')
|
|
1313
|
+
sage: E = M.vector_bundle(4, 'E')
|
|
1314
|
+
sage: list(E.irange())
|
|
1315
|
+
[0, 1, 2, 3]
|
|
1316
|
+
sage: list(E.irange(2))
|
|
1317
|
+
[2, 3]
|
|
1318
|
+
|
|
1319
|
+
Index range on a 4-dimensional vector bundle over a 5-dimensional
|
|
1320
|
+
manifold with starting index=1::
|
|
1321
|
+
|
|
1322
|
+
sage: M = Manifold(5, 'M', structure='topological', start_index=1)
|
|
1323
|
+
sage: E = M.vector_bundle(4, 'E')
|
|
1324
|
+
sage: list(E.irange())
|
|
1325
|
+
[1, 2, 3, 4]
|
|
1326
|
+
sage: list(E.irange(2))
|
|
1327
|
+
[2, 3, 4]
|
|
1328
|
+
|
|
1329
|
+
In general, one has always::
|
|
1330
|
+
|
|
1331
|
+
sage: next(E.irange()) == M.start_index()
|
|
1332
|
+
True
|
|
1333
|
+
"""
|
|
1334
|
+
si = self._base_space._sindex
|
|
1335
|
+
imax = self._rank + si
|
|
1336
|
+
if start is None:
|
|
1337
|
+
i = si
|
|
1338
|
+
else:
|
|
1339
|
+
i = start
|
|
1340
|
+
while i < imax:
|
|
1341
|
+
yield i
|
|
1342
|
+
i += 1
|