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,963 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-symbolics
|
|
2
|
+
r"""
|
|
3
|
+
Tensor Field Modules
|
|
4
|
+
|
|
5
|
+
The set of tensor fields along a differentiable manifold `U` with values on
|
|
6
|
+
a differentiable manifold `M` via a differentiable map `\Phi: U \rightarrow M`
|
|
7
|
+
(possibly `U = M` and `\Phi = \mathrm{Id}_M`) is a module over the algebra
|
|
8
|
+
`C^k(U)` of differentiable scalar fields on `U`. It is a free module if
|
|
9
|
+
and only if `M` is parallelizable. Accordingly, two classes are devoted
|
|
10
|
+
to tensor field modules:
|
|
11
|
+
|
|
12
|
+
- :class:`TensorFieldModule` for tensor fields with values on a generic (in
|
|
13
|
+
practice, not parallelizable) differentiable manifold `M`,
|
|
14
|
+
- :class:`TensorFieldFreeModule` for tensor fields with values on a
|
|
15
|
+
parallelizable manifold `M`.
|
|
16
|
+
|
|
17
|
+
AUTHORS:
|
|
18
|
+
|
|
19
|
+
- Eric Gourgoulhon, Michal Bejger (2014-2015): initial version
|
|
20
|
+
- Travis Scrimshaw (2016): review tweaks
|
|
21
|
+
|
|
22
|
+
REFERENCES:
|
|
23
|
+
|
|
24
|
+
- [KN1963]_
|
|
25
|
+
- [Lee2013]_
|
|
26
|
+
- [ONe1983]_
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
# *****************************************************************************
|
|
30
|
+
# Copyright (C) 2015-2018 Eric Gourgoulhon <eric.gourgoulhon@obspm.fr>
|
|
31
|
+
# 2015 Michal Bejger <bejger@camk.edu.pl>
|
|
32
|
+
# 2016 Travis Scrimshaw <tscrimsh@umn.edu>
|
|
33
|
+
# 2020 Michael Jung
|
|
34
|
+
# 2022 Matthias Koeppe
|
|
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.categories.modules import Modules
|
|
43
|
+
from sage.manifolds.differentiable.automorphismfield import (
|
|
44
|
+
AutomorphismField,
|
|
45
|
+
AutomorphismFieldParal,
|
|
46
|
+
)
|
|
47
|
+
from sage.manifolds.differentiable.diff_form import DiffForm, DiffFormParal
|
|
48
|
+
from sage.manifolds.differentiable.multivectorfield import (
|
|
49
|
+
MultivectorField,
|
|
50
|
+
MultivectorFieldParal,
|
|
51
|
+
)
|
|
52
|
+
from sage.manifolds.differentiable.tensorfield import TensorField
|
|
53
|
+
from sage.manifolds.differentiable.tensorfield_paral import TensorFieldParal
|
|
54
|
+
from sage.misc.cachefunc import cached_method
|
|
55
|
+
from sage.structure.parent import Parent
|
|
56
|
+
from sage.structure.unique_representation import UniqueRepresentation
|
|
57
|
+
from sage.tensor.modules.reflexive_module import ReflexiveModule_tensor
|
|
58
|
+
from sage.tensor.modules.tensor_free_module import TensorFreeModule
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
class TensorFieldModule(UniqueRepresentation, ReflexiveModule_tensor):
|
|
62
|
+
r"""
|
|
63
|
+
Module of tensor fields of a given type `(k,l)` along a differentiable
|
|
64
|
+
manifold `U` with values on a differentiable manifold `M`, via a
|
|
65
|
+
differentiable map `U \rightarrow M`.
|
|
66
|
+
|
|
67
|
+
Given two nonnegative integers `k` and `l` and a differentiable map
|
|
68
|
+
|
|
69
|
+
.. MATH::
|
|
70
|
+
|
|
71
|
+
\Phi:\ U \longrightarrow M,
|
|
72
|
+
|
|
73
|
+
the *tensor field module* `T^{(k,l)}(U,\Phi)` is the set of all tensor
|
|
74
|
+
fields of the type
|
|
75
|
+
|
|
76
|
+
.. MATH::
|
|
77
|
+
|
|
78
|
+
t:\ U \longrightarrow T^{(k,l)} M
|
|
79
|
+
|
|
80
|
+
(where `T^{(k,l)} M` is the tensor bundle of type `(k,l)` over `M`) such
|
|
81
|
+
that
|
|
82
|
+
|
|
83
|
+
.. MATH::
|
|
84
|
+
|
|
85
|
+
t(p) \in T^{(k,l)}(T_{\Phi(p)}M)
|
|
86
|
+
|
|
87
|
+
for all `p \in U`, i.e. `t(p)` is a tensor of type `(k,l)` on the
|
|
88
|
+
tangent vector space `T_{\Phi(p)} M`. The set `T^{(k,l)}(U,\Phi)`
|
|
89
|
+
is a module over `C^k(U)`, the ring (algebra) of differentiable
|
|
90
|
+
scalar fields on `U` (see
|
|
91
|
+
:class:`~sage.manifolds.differentiable.scalarfield_algebra.DiffScalarFieldAlgebra`).
|
|
92
|
+
|
|
93
|
+
The standard case of tensor fields *on* a differentiable manifold
|
|
94
|
+
corresponds to `U = M` and `\Phi = \mathrm{Id}_M`; we then denote
|
|
95
|
+
`T^{(k,l)}(M,\mathrm{Id}_M)` by merely `T^{(k,l)}(M)`. Other common
|
|
96
|
+
cases are `\Phi` being an immersion and `\Phi` being a curve in `M`
|
|
97
|
+
(`U` is then an open interval of `\RR`).
|
|
98
|
+
|
|
99
|
+
.. NOTE::
|
|
100
|
+
|
|
101
|
+
If `M` is parallelizable, the class :class:`TensorFieldFreeModule`
|
|
102
|
+
should be used instead.
|
|
103
|
+
|
|
104
|
+
INPUT:
|
|
105
|
+
|
|
106
|
+
- ``vector_field_module`` -- module `\mathfrak{X}(U,\Phi)` of vector
|
|
107
|
+
fields along `U` associated with the map `\Phi: U \rightarrow M`
|
|
108
|
+
- ``tensor_type`` -- pair `(k,l)` with `k` being the contravariant
|
|
109
|
+
rank and `l` the covariant rank
|
|
110
|
+
|
|
111
|
+
EXAMPLES:
|
|
112
|
+
|
|
113
|
+
Module of type-`(2,0)` tensor fields on the 2-sphere::
|
|
114
|
+
|
|
115
|
+
sage: M = Manifold(2, 'M') # the 2-dimensional sphere S^2
|
|
116
|
+
sage: U = M.open_subset('U') # complement of the North pole
|
|
117
|
+
sage: c_xy.<x,y> = U.chart() # stereographic coordinates from the North pole
|
|
118
|
+
sage: V = M.open_subset('V') # complement of the South pole
|
|
119
|
+
sage: c_uv.<u,v> = V.chart() # stereographic coordinates from the South pole
|
|
120
|
+
sage: M.declare_union(U,V) # S^2 is the union of U and V
|
|
121
|
+
sage: xy_to_uv = c_xy.transition_map(c_uv, (x/(x^2+y^2), y/(x^2+y^2)),
|
|
122
|
+
....: intersection_name='W', restrictions1= x^2+y^2!=0,
|
|
123
|
+
....: restrictions2= u^2+v^2!=0)
|
|
124
|
+
sage: uv_to_xy = xy_to_uv.inverse()
|
|
125
|
+
sage: W = U.intersection(V)
|
|
126
|
+
sage: T20 = M.tensor_field_module((2,0)); T20
|
|
127
|
+
Module T^(2,0)(M) of type-(2,0) tensors fields on the 2-dimensional
|
|
128
|
+
differentiable manifold M
|
|
129
|
+
|
|
130
|
+
`T^{(2,0)}(M)` is a module over the algebra `C^k(M)`::
|
|
131
|
+
|
|
132
|
+
sage: T20.category()
|
|
133
|
+
Category of tensor products of modules over Algebra of differentiable scalar fields
|
|
134
|
+
on the 2-dimensional differentiable manifold M
|
|
135
|
+
sage: T20.base_ring() is M.scalar_field_algebra()
|
|
136
|
+
True
|
|
137
|
+
|
|
138
|
+
`T^{(2,0)}(M)` is not a free module::
|
|
139
|
+
|
|
140
|
+
sage: from sage.tensor.modules.finite_rank_free_module import FiniteRankFreeModule_abstract
|
|
141
|
+
sage: isinstance(T20, FiniteRankFreeModule_abstract)
|
|
142
|
+
False
|
|
143
|
+
|
|
144
|
+
because `M = S^2` is not parallelizable::
|
|
145
|
+
|
|
146
|
+
sage: M.is_manifestly_parallelizable()
|
|
147
|
+
False
|
|
148
|
+
|
|
149
|
+
On the contrary, the module of type-`(2,0)` tensor fields on `U` is a
|
|
150
|
+
free module, since `U` is parallelizable (being a coordinate domain)::
|
|
151
|
+
|
|
152
|
+
sage: T20U = U.tensor_field_module((2,0))
|
|
153
|
+
sage: isinstance(T20U, FiniteRankFreeModule_abstract)
|
|
154
|
+
True
|
|
155
|
+
sage: U.is_manifestly_parallelizable()
|
|
156
|
+
True
|
|
157
|
+
|
|
158
|
+
The zero element::
|
|
159
|
+
|
|
160
|
+
sage: z = T20.zero() ; z
|
|
161
|
+
Tensor field zero of type (2,0) on the 2-dimensional differentiable
|
|
162
|
+
manifold M
|
|
163
|
+
sage: z is T20(0)
|
|
164
|
+
True
|
|
165
|
+
sage: z[c_xy.frame(),:]
|
|
166
|
+
[0 0]
|
|
167
|
+
[0 0]
|
|
168
|
+
sage: z[c_uv.frame(),:]
|
|
169
|
+
[0 0]
|
|
170
|
+
[0 0]
|
|
171
|
+
|
|
172
|
+
The module `T^{(2,0)}(M)` coerces to any module of type-`(2,0)` tensor
|
|
173
|
+
fields defined on some subdomain of `M`, for instance `T^{(2,0)}(U)`::
|
|
174
|
+
|
|
175
|
+
sage: T20U.has_coerce_map_from(T20)
|
|
176
|
+
True
|
|
177
|
+
|
|
178
|
+
The reverse is not true::
|
|
179
|
+
|
|
180
|
+
sage: T20.has_coerce_map_from(T20U)
|
|
181
|
+
False
|
|
182
|
+
|
|
183
|
+
The coercion::
|
|
184
|
+
|
|
185
|
+
sage: T20U.coerce_map_from(T20)
|
|
186
|
+
Coercion map:
|
|
187
|
+
From: Module T^(2,0)(M) of type-(2,0) tensors fields on the 2-dimensional differentiable manifold M
|
|
188
|
+
To: Free module T^(2,0)(U) of type-(2,0) tensors fields on the Open subset U of the 2-dimensional differentiable manifold M
|
|
189
|
+
|
|
190
|
+
The coercion map is actually the *restriction* of tensor fields defined
|
|
191
|
+
on `M` to `U`::
|
|
192
|
+
|
|
193
|
+
sage: t = M.tensor_field(2,0, name='t')
|
|
194
|
+
sage: eU = c_xy.frame() ; eV = c_uv.frame()
|
|
195
|
+
sage: t[eU,:] = [[2,0], [0,-3]]
|
|
196
|
+
sage: t.add_comp_by_continuation(eV, W, chart=c_uv)
|
|
197
|
+
sage: T20U(t) # the conversion map in action
|
|
198
|
+
Tensor field t of type (2,0) on the Open subset U of the 2-dimensional
|
|
199
|
+
differentiable manifold M
|
|
200
|
+
sage: T20U(t) is t.restrict(U)
|
|
201
|
+
True
|
|
202
|
+
|
|
203
|
+
There is also a coercion map from fields of tangent-space automorphisms to
|
|
204
|
+
tensor fields of type-`(1,1)`::
|
|
205
|
+
|
|
206
|
+
sage: T11 = M.tensor_field_module((1,1)) ; T11
|
|
207
|
+
Module T^(1,1)(M) of type-(1,1) tensors fields on the 2-dimensional
|
|
208
|
+
differentiable manifold M
|
|
209
|
+
sage: GL = M.automorphism_field_group() ; GL
|
|
210
|
+
General linear group of the Module X(M) of vector fields on the
|
|
211
|
+
2-dimensional differentiable manifold M
|
|
212
|
+
sage: T11.has_coerce_map_from(GL)
|
|
213
|
+
True
|
|
214
|
+
|
|
215
|
+
Explicit call to the coercion map::
|
|
216
|
+
|
|
217
|
+
sage: a = GL.one() ; a
|
|
218
|
+
Field of tangent-space identity maps on the 2-dimensional
|
|
219
|
+
differentiable manifold M
|
|
220
|
+
sage: a.parent()
|
|
221
|
+
General linear group of the Module X(M) of vector fields on the
|
|
222
|
+
2-dimensional differentiable manifold M
|
|
223
|
+
sage: ta = T11.coerce(a) ; ta
|
|
224
|
+
Tensor field Id of type (1,1) on the 2-dimensional differentiable
|
|
225
|
+
manifold M
|
|
226
|
+
sage: ta.parent()
|
|
227
|
+
Module T^(1,1)(M) of type-(1,1) tensors fields on the 2-dimensional
|
|
228
|
+
differentiable manifold M
|
|
229
|
+
sage: ta[eU,:] # ta on U
|
|
230
|
+
[1 0]
|
|
231
|
+
[0 1]
|
|
232
|
+
sage: ta[eV,:] # ta on V
|
|
233
|
+
[1 0]
|
|
234
|
+
[0 1]
|
|
235
|
+
|
|
236
|
+
TESTS::
|
|
237
|
+
|
|
238
|
+
sage: T11.tensor_factors()
|
|
239
|
+
[Module X(M) of vector fields on the 2-dimensional differentiable manifold M,
|
|
240
|
+
Module Omega^1(M) of 1-forms on the 2-dimensional differentiable manifold M]
|
|
241
|
+
"""
|
|
242
|
+
Element = TensorField
|
|
243
|
+
|
|
244
|
+
def __init__(self, vector_field_module, tensor_type, category=None):
|
|
245
|
+
r"""
|
|
246
|
+
Construct a module of tensor fields taking values on a (a priori) not
|
|
247
|
+
parallelizable differentiable manifold.
|
|
248
|
+
|
|
249
|
+
TESTS::
|
|
250
|
+
|
|
251
|
+
sage: M = Manifold(2, 'M') # the 2-dimensional sphere S^2
|
|
252
|
+
sage: U = M.open_subset('U') # complement of the North pole
|
|
253
|
+
sage: c_xy.<x,y> = U.chart() # stereographic coordinates from the North pole
|
|
254
|
+
sage: V = M.open_subset('V') # complement of the South pole
|
|
255
|
+
sage: c_uv.<u,v> = V.chart() # stereographic coordinates from the South pole
|
|
256
|
+
sage: M.declare_union(U,V) # S^2 is the union of U and V
|
|
257
|
+
sage: xy_to_uv = c_xy.transition_map(c_uv, (x/(x^2+y^2), y/(x^2+y^2)),
|
|
258
|
+
....: intersection_name='W', restrictions1= x^2+y^2!=0,
|
|
259
|
+
....: restrictions2= u^2+v^2!=0)
|
|
260
|
+
sage: XM = M.vector_field_module()
|
|
261
|
+
sage: from sage.manifolds.differentiable.tensorfield_module import TensorFieldModule
|
|
262
|
+
sage: T21 = TensorFieldModule(XM, (2,1)); T21
|
|
263
|
+
Module T^(2,1)(M) of type-(2,1) tensors fields on the 2-dimensional
|
|
264
|
+
differentiable manifold M
|
|
265
|
+
sage: T21 is M.tensor_field_module((2,1))
|
|
266
|
+
True
|
|
267
|
+
sage: TestSuite(T21).run(skip='_test_elements')
|
|
268
|
+
|
|
269
|
+
In the above test suite, ``_test_elements`` is skipped because of the
|
|
270
|
+
``_test_pickling`` error of the elements (to be fixed in
|
|
271
|
+
:class:`~sage.manifolds.differentiable.tensorfield.TensorField`)
|
|
272
|
+
"""
|
|
273
|
+
domain = vector_field_module._domain
|
|
274
|
+
dest_map = vector_field_module._dest_map
|
|
275
|
+
kcon = tensor_type[0]
|
|
276
|
+
lcov = tensor_type[1]
|
|
277
|
+
name = "T^({},{})({}".format(kcon, lcov, domain._name)
|
|
278
|
+
latex_name = r"\mathcal{{T}}^{{({},{})}}\left({}".format(kcon, lcov, domain._latex_name)
|
|
279
|
+
if dest_map is not domain.identity_map():
|
|
280
|
+
dm_name = dest_map._name
|
|
281
|
+
dm_latex_name = dest_map._latex_name
|
|
282
|
+
if dm_name is None:
|
|
283
|
+
dm_name = "unnamed map"
|
|
284
|
+
if dm_latex_name is None:
|
|
285
|
+
dm_latex_name = r"\mathrm{unnamed\; map}"
|
|
286
|
+
name += "," + dm_name
|
|
287
|
+
latex_name += "," + dm_latex_name
|
|
288
|
+
self._name = name + ")"
|
|
289
|
+
self._latex_name = latex_name + r"\right)"
|
|
290
|
+
self._vmodule = vector_field_module
|
|
291
|
+
self._tensor_type = tensor_type
|
|
292
|
+
# the member self._ring is created for efficiency (to avoid calls to
|
|
293
|
+
# self.base_ring()):
|
|
294
|
+
self._ring = domain.scalar_field_algebra()
|
|
295
|
+
category = Modules(self._ring).TensorProducts().or_subcategory(category)
|
|
296
|
+
Parent.__init__(self, base=self._ring, category=category)
|
|
297
|
+
self._domain = domain
|
|
298
|
+
self._dest_map = dest_map
|
|
299
|
+
self._ambient_domain = vector_field_module._ambient_domain
|
|
300
|
+
|
|
301
|
+
#### Parent methods
|
|
302
|
+
|
|
303
|
+
def _element_constructor_(self, comp=[], frame=None, name=None,
|
|
304
|
+
latex_name=None, sym=None, antisym=None):
|
|
305
|
+
r"""
|
|
306
|
+
Construct a tensor field.
|
|
307
|
+
|
|
308
|
+
TESTS::
|
|
309
|
+
|
|
310
|
+
sage: M = Manifold(2, 'M')
|
|
311
|
+
sage: U = M.open_subset('U'); V = M.open_subset('V')
|
|
312
|
+
sage: c_xy.<x,y> = U.chart(); c_uv.<u,v> = V.chart()
|
|
313
|
+
sage: M.declare_union(U,V)
|
|
314
|
+
sage: T20 = M.tensor_field_module((2,0))
|
|
315
|
+
sage: t = T20([[1+x, 2], [x*y, 3-y]], name='t'); t
|
|
316
|
+
Tensor field t of type (2,0) on the 2-dimensional differentiable
|
|
317
|
+
manifold M
|
|
318
|
+
sage: t.display(c_xy.frame())
|
|
319
|
+
t = (x + 1) ∂/∂x⊗∂/∂x + 2 ∂/∂x⊗∂/∂y + x*y ∂/∂y⊗∂/∂x
|
|
320
|
+
+ (-y + 3) ∂/∂y⊗∂/∂y
|
|
321
|
+
sage: T20(0) is T20.zero()
|
|
322
|
+
True
|
|
323
|
+
"""
|
|
324
|
+
try:
|
|
325
|
+
if comp.is_trivial_zero():
|
|
326
|
+
return self.zero()
|
|
327
|
+
except AttributeError:
|
|
328
|
+
if comp == 0:
|
|
329
|
+
return self.zero()
|
|
330
|
+
if isinstance(comp, DiffForm):
|
|
331
|
+
# coercion of a p-form to a type-(0,p) tensor field:
|
|
332
|
+
form = comp # for readability
|
|
333
|
+
p = form.degree()
|
|
334
|
+
if (self._tensor_type != (0,p) or
|
|
335
|
+
self._vmodule != form.base_module()):
|
|
336
|
+
raise TypeError("cannot convert the {}".format(form) +
|
|
337
|
+
" to an element of {}".format(self))
|
|
338
|
+
if p == 1:
|
|
339
|
+
asym = None
|
|
340
|
+
else:
|
|
341
|
+
asym = range(p)
|
|
342
|
+
resu = self.element_class(self._vmodule, (0,p),
|
|
343
|
+
name=form._name,
|
|
344
|
+
latex_name=form._latex_name,
|
|
345
|
+
antisym=asym)
|
|
346
|
+
for dom, rst in form._restrictions.items():
|
|
347
|
+
resu._restrictions[dom] = dom.tensor_field_module((0,p))(rst)
|
|
348
|
+
return resu
|
|
349
|
+
if isinstance(comp, MultivectorField):
|
|
350
|
+
# coercion of a p-vector field to a type-(p,0) tensor:
|
|
351
|
+
pvect = comp # for readability
|
|
352
|
+
p = pvect.degree()
|
|
353
|
+
if (self._tensor_type != (p,0) or
|
|
354
|
+
self._vmodule != pvect.base_module()):
|
|
355
|
+
raise TypeError("cannot convert the {}".format(pvect) +
|
|
356
|
+
" to an element of {}".format(self))
|
|
357
|
+
if p == 1:
|
|
358
|
+
asym = None
|
|
359
|
+
else:
|
|
360
|
+
asym = range(p)
|
|
361
|
+
resu = self.element_class(self._vmodule, (p,0),
|
|
362
|
+
name=pvect._name,
|
|
363
|
+
latex_name=pvect._latex_name,
|
|
364
|
+
antisym=asym)
|
|
365
|
+
for dom, rst in pvect._restrictions.items():
|
|
366
|
+
resu._restrictions[dom] = dom.tensor_field_module((p,0))(rst)
|
|
367
|
+
return resu
|
|
368
|
+
if isinstance(comp, AutomorphismField):
|
|
369
|
+
# coercion of an automorphism to a type-(1,1) tensor:
|
|
370
|
+
autom = comp # for readability
|
|
371
|
+
if (self._tensor_type != (1,1) or
|
|
372
|
+
self._vmodule != autom.base_module()):
|
|
373
|
+
raise TypeError("cannot convert the {}".format(autom) +
|
|
374
|
+
" to an element of {}".format(self))
|
|
375
|
+
resu = self.element_class(self._vmodule, (1,1),
|
|
376
|
+
name=autom._name,
|
|
377
|
+
latex_name=autom._latex_name)
|
|
378
|
+
for dom, rest in autom._restrictions.items():
|
|
379
|
+
resu._restrictions[dom] = dom.tensor_field_module((1,1))(rest)
|
|
380
|
+
return resu
|
|
381
|
+
if isinstance(comp, TensorField):
|
|
382
|
+
# coercion by domain restriction
|
|
383
|
+
if (self._tensor_type == comp._tensor_type
|
|
384
|
+
and self._domain.is_subset(comp._domain)
|
|
385
|
+
and self._ambient_domain.is_subset(comp._ambient_domain)):
|
|
386
|
+
return comp.restrict(self._domain)
|
|
387
|
+
else:
|
|
388
|
+
raise TypeError("cannot convert the {}".format(comp) +
|
|
389
|
+
" to an element of {}".format(self))
|
|
390
|
+
if not isinstance(comp, (list, tuple)):
|
|
391
|
+
raise TypeError("cannot convert the {} ".format(comp) +
|
|
392
|
+
"to an element of {}".format(self))
|
|
393
|
+
# standard construction
|
|
394
|
+
resu = self.element_class(self._vmodule, self._tensor_type,
|
|
395
|
+
name=name, latex_name=latex_name,
|
|
396
|
+
sym=sym, antisym=antisym)
|
|
397
|
+
if comp:
|
|
398
|
+
resu.set_comp(frame)[:] = comp
|
|
399
|
+
return resu
|
|
400
|
+
|
|
401
|
+
def _an_element_(self):
|
|
402
|
+
r"""
|
|
403
|
+
Construct some (unnamed) tensor field.
|
|
404
|
+
|
|
405
|
+
TESTS::
|
|
406
|
+
|
|
407
|
+
sage: M = Manifold(2, 'M')
|
|
408
|
+
sage: U = M.open_subset('U'); V = M.open_subset('V')
|
|
409
|
+
sage: c_xy.<x,y> = U.chart(); c_uv.<u,v> = V.chart()
|
|
410
|
+
sage: M.declare_union(U,V)
|
|
411
|
+
sage: T31 = M.tensor_field_module((3,1))
|
|
412
|
+
sage: T31._an_element_()
|
|
413
|
+
Tensor field of type (3,1) on the 2-dimensional differentiable
|
|
414
|
+
manifold M
|
|
415
|
+
"""
|
|
416
|
+
resu = self.element_class(self._vmodule, self._tensor_type)
|
|
417
|
+
for oc in self._domain.open_covers(trivial=False):
|
|
418
|
+
# the first non-trivial open cover is selected
|
|
419
|
+
for dom in oc:
|
|
420
|
+
vmodule_dom = dom.vector_field_module(dest_map=self._dest_map.restrict(dom))
|
|
421
|
+
tmodule_dom = vmodule_dom.tensor_module(*(self._tensor_type))
|
|
422
|
+
resu.set_restriction(tmodule_dom._an_element_())
|
|
423
|
+
return resu
|
|
424
|
+
return resu
|
|
425
|
+
|
|
426
|
+
def _coerce_map_from_(self, other):
|
|
427
|
+
r"""
|
|
428
|
+
Determine whether coercion to ``self`` exists from other parent.
|
|
429
|
+
|
|
430
|
+
TESTS::
|
|
431
|
+
|
|
432
|
+
sage: M = Manifold(2, 'M')
|
|
433
|
+
sage: U = M.open_subset('U')
|
|
434
|
+
sage: T02 = M.tensor_field_module((0,2))
|
|
435
|
+
sage: T02U = U.tensor_field_module((0,2))
|
|
436
|
+
sage: T02U._coerce_map_from_(T02)
|
|
437
|
+
True
|
|
438
|
+
sage: T02._coerce_map_from_(T02U)
|
|
439
|
+
False
|
|
440
|
+
sage: T02._coerce_map_from_(M.diff_form_module(2))
|
|
441
|
+
True
|
|
442
|
+
sage: T20 = M.tensor_field_module((2,0))
|
|
443
|
+
sage: T20._coerce_map_from_(M.multivector_module(2))
|
|
444
|
+
True
|
|
445
|
+
sage: T11 = M.tensor_field_module((1,1))
|
|
446
|
+
sage: T11._coerce_map_from_(M.automorphism_field_group())
|
|
447
|
+
True
|
|
448
|
+
"""
|
|
449
|
+
from sage.manifolds.differentiable.automorphismfield_group import (
|
|
450
|
+
AutomorphismFieldGroup,
|
|
451
|
+
)
|
|
452
|
+
from sage.manifolds.differentiable.diff_form_module import DiffFormModule
|
|
453
|
+
from sage.manifolds.differentiable.multivector_module import MultivectorModule
|
|
454
|
+
if isinstance(other, (TensorFieldModule, TensorFieldFreeModule)):
|
|
455
|
+
# coercion by domain restriction
|
|
456
|
+
return (self._tensor_type == other._tensor_type
|
|
457
|
+
and self._domain.is_subset(other._domain)
|
|
458
|
+
and self._ambient_domain.is_subset(other._ambient_domain))
|
|
459
|
+
if isinstance(other, DiffFormModule):
|
|
460
|
+
# coercion of p-forms to type-(0,p) tensor fields
|
|
461
|
+
return (self._vmodule is other.base_module()
|
|
462
|
+
and self._tensor_type == (0, other.degree()))
|
|
463
|
+
if isinstance(other, MultivectorModule):
|
|
464
|
+
# coercion of p-vector fields to type-(p,0) tensor fields
|
|
465
|
+
return (self._vmodule is other.base_module()
|
|
466
|
+
and self._tensor_type == (other.degree(),0))
|
|
467
|
+
if isinstance(other, AutomorphismFieldGroup):
|
|
468
|
+
# coercion of automorphism fields to type-(1,1) tensor fields
|
|
469
|
+
return (self._vmodule is other.base_module()
|
|
470
|
+
and self._tensor_type == (1,1))
|
|
471
|
+
return False
|
|
472
|
+
|
|
473
|
+
#### End of parent methods
|
|
474
|
+
|
|
475
|
+
def _repr_(self):
|
|
476
|
+
r"""
|
|
477
|
+
Return a string representation of ``self``.
|
|
478
|
+
|
|
479
|
+
TESTS::
|
|
480
|
+
|
|
481
|
+
sage: M = Manifold(2, 'M')
|
|
482
|
+
sage: T13 = M.tensor_field_module((1,3))
|
|
483
|
+
sage: T13._repr_()
|
|
484
|
+
'Module T^(1,3)(M) of type-(1,3) tensors fields on the 2-dimensional differentiable manifold M'
|
|
485
|
+
sage: repr(T13) # indirect doctest
|
|
486
|
+
'Module T^(1,3)(M) of type-(1,3) tensors fields on the 2-dimensional differentiable manifold M'
|
|
487
|
+
sage: T13 # indirect doctest
|
|
488
|
+
Module T^(1,3)(M) of type-(1,3) tensors fields on the 2-dimensional
|
|
489
|
+
differentiable manifold M
|
|
490
|
+
"""
|
|
491
|
+
description = "Module "
|
|
492
|
+
if self._name is not None:
|
|
493
|
+
description += self._name + " "
|
|
494
|
+
description += "of type-({},{})".format(self._tensor_type[0],
|
|
495
|
+
self._tensor_type[1])
|
|
496
|
+
description += " tensors fields "
|
|
497
|
+
if self._dest_map is self._domain.identity_map():
|
|
498
|
+
description += "on the {}".format(self._domain)
|
|
499
|
+
else:
|
|
500
|
+
description += "along the {}".format(self._domain) + \
|
|
501
|
+
" mapped into the {}".format(self._ambient_domain)
|
|
502
|
+
return description
|
|
503
|
+
|
|
504
|
+
def _latex_(self):
|
|
505
|
+
r"""
|
|
506
|
+
Return a LaTeX representation of ``self``.
|
|
507
|
+
|
|
508
|
+
TESTS::
|
|
509
|
+
|
|
510
|
+
sage: M = Manifold(2, 'M')
|
|
511
|
+
sage: T13 = M.tensor_field_module((1,3))
|
|
512
|
+
sage: T13._latex_()
|
|
513
|
+
'\\mathcal{T}^{(1,3)}\\left(M\\right)'
|
|
514
|
+
sage: latex(T13) # indirect doctest
|
|
515
|
+
\mathcal{T}^{(1,3)}\left(M\right)
|
|
516
|
+
"""
|
|
517
|
+
if self._latex_name is None:
|
|
518
|
+
return r'\text{' + str(self) + r'}'
|
|
519
|
+
else:
|
|
520
|
+
return self._latex_name
|
|
521
|
+
|
|
522
|
+
def base_module(self):
|
|
523
|
+
r"""
|
|
524
|
+
Return the vector field module on which ``self`` is constructed.
|
|
525
|
+
|
|
526
|
+
OUTPUT:
|
|
527
|
+
|
|
528
|
+
- a
|
|
529
|
+
:class:`~sage.manifolds.differentiable.vectorfield_module.VectorFieldModule`
|
|
530
|
+
representing the module on which ``self`` is defined
|
|
531
|
+
|
|
532
|
+
EXAMPLES::
|
|
533
|
+
|
|
534
|
+
sage: M = Manifold(2, 'M')
|
|
535
|
+
sage: T13 = M.tensor_field_module((1,3))
|
|
536
|
+
sage: T13.base_module()
|
|
537
|
+
Module X(M) of vector fields on the 2-dimensional differentiable
|
|
538
|
+
manifold M
|
|
539
|
+
sage: T13.base_module() is M.vector_field_module()
|
|
540
|
+
True
|
|
541
|
+
sage: T13.base_module().base_ring()
|
|
542
|
+
Algebra of differentiable scalar fields on the 2-dimensional
|
|
543
|
+
differentiable manifold M
|
|
544
|
+
"""
|
|
545
|
+
return self._vmodule
|
|
546
|
+
|
|
547
|
+
def tensor_type(self):
|
|
548
|
+
r"""
|
|
549
|
+
Return the tensor type of ``self``.
|
|
550
|
+
|
|
551
|
+
OUTPUT: pair `(k,l)` of nonnegative integers such that the tensor
|
|
552
|
+
fields belonging to this module are of type `(k,l)`
|
|
553
|
+
|
|
554
|
+
EXAMPLES::
|
|
555
|
+
|
|
556
|
+
sage: M = Manifold(2, 'M')
|
|
557
|
+
sage: T13 = M.tensor_field_module((1,3))
|
|
558
|
+
sage: T13.tensor_type()
|
|
559
|
+
(1, 3)
|
|
560
|
+
sage: T20 = M.tensor_field_module((2,0))
|
|
561
|
+
sage: T20.tensor_type()
|
|
562
|
+
(2, 0)
|
|
563
|
+
"""
|
|
564
|
+
return self._tensor_type
|
|
565
|
+
|
|
566
|
+
@cached_method
|
|
567
|
+
def zero(self):
|
|
568
|
+
"""
|
|
569
|
+
Return the zero of ``self``.
|
|
570
|
+
|
|
571
|
+
TESTS::
|
|
572
|
+
|
|
573
|
+
sage: M = Manifold(2, 'M')
|
|
574
|
+
sage: U = M.open_subset('U'); V = M.open_subset('V')
|
|
575
|
+
sage: c_xy.<x,y> = U.chart(); c_uv.<u,v> = V.chart()
|
|
576
|
+
sage: M.declare_union(U,V)
|
|
577
|
+
sage: T20 = M.tensor_field_module((2,0))
|
|
578
|
+
sage: T20.zero()
|
|
579
|
+
Tensor field zero of type (2,0) on the
|
|
580
|
+
2-dimensional differentiable manifold M
|
|
581
|
+
"""
|
|
582
|
+
resu = self._element_constructor_(name='zero', latex_name='0')
|
|
583
|
+
for frame in self._domain._frames:
|
|
584
|
+
if self._dest_map.restrict(frame._domain) == frame._dest_map:
|
|
585
|
+
resu.add_comp(frame)
|
|
586
|
+
# (since new components are initialized to zero)
|
|
587
|
+
resu._is_zero = True # This element is certainly zero
|
|
588
|
+
resu.set_immutable()
|
|
589
|
+
return resu
|
|
590
|
+
|
|
591
|
+
#***********************************************************************
|
|
592
|
+
|
|
593
|
+
|
|
594
|
+
class TensorFieldFreeModule(TensorFreeModule):
|
|
595
|
+
r"""
|
|
596
|
+
Free module of tensor fields of a given type `(k,l)` along a
|
|
597
|
+
differentiable manifold `U` with values on a parallelizable manifold `M`,
|
|
598
|
+
via a differentiable map `U \rightarrow M`.
|
|
599
|
+
|
|
600
|
+
Given two nonnegative integers `k` and `l` and a differentiable map
|
|
601
|
+
|
|
602
|
+
.. MATH::
|
|
603
|
+
|
|
604
|
+
\Phi:\ U \longrightarrow M,
|
|
605
|
+
|
|
606
|
+
the *tensor field module* `T^{(k,l)}(U, \Phi)` is the set of all tensor
|
|
607
|
+
fields of the type
|
|
608
|
+
|
|
609
|
+
.. MATH::
|
|
610
|
+
|
|
611
|
+
t:\ U \longrightarrow T^{(k,l)} M
|
|
612
|
+
|
|
613
|
+
(where `T^{(k,l)}M` is the tensor bundle of type `(k,l)` over `M`)
|
|
614
|
+
such that
|
|
615
|
+
|
|
616
|
+
.. MATH::
|
|
617
|
+
|
|
618
|
+
t(p) \in T^{(k,l)}(T_{\Phi(p)}M)
|
|
619
|
+
|
|
620
|
+
for all `p \in U`, i.e. `t(p)` is a tensor of type `(k,l)` on the
|
|
621
|
+
tangent vector space `T_{\Phi(p)}M`. Since `M` is parallelizable,
|
|
622
|
+
the set `T^{(k,l)}(U,\Phi)` is a free module over `C^k(U)`, the
|
|
623
|
+
ring (algebra) of differentiable scalar fields on `U` (see
|
|
624
|
+
:class:`~sage.manifolds.differentiable.scalarfield_algebra.DiffScalarFieldAlgebra`).
|
|
625
|
+
|
|
626
|
+
The standard case of tensor fields *on* a differentiable manifold
|
|
627
|
+
corresponds to `U = M` and `\Phi = \mathrm{Id}_M`; we then denote
|
|
628
|
+
`T^{(k,l)}(M,\mathrm{Id}_M)` by merely `T^{(k,l)}(M)`. Other common cases
|
|
629
|
+
are `\Phi` being an immersion and `\Phi` being a curve in `M` (`U` is then
|
|
630
|
+
an open interval of `\RR`).
|
|
631
|
+
|
|
632
|
+
.. NOTE::
|
|
633
|
+
|
|
634
|
+
If `M` is not parallelizable, the class :class:`TensorFieldModule`
|
|
635
|
+
should be used instead, for `T^{(k,l)}(U,\Phi)` is no longer a
|
|
636
|
+
free module.
|
|
637
|
+
|
|
638
|
+
INPUT:
|
|
639
|
+
|
|
640
|
+
- ``vector_field_module`` -- free module `\mathfrak{X}(U,\Phi)` of vector
|
|
641
|
+
fields along `U` associated with the map `\Phi: U \rightarrow M`
|
|
642
|
+
- ``tensor_type`` -- pair `(k,l)` with `k` being the contravariant rank
|
|
643
|
+
and `l` the covariant rank
|
|
644
|
+
|
|
645
|
+
EXAMPLES:
|
|
646
|
+
|
|
647
|
+
Module of type-`(2,0)` tensor fields on `\RR^3`::
|
|
648
|
+
|
|
649
|
+
sage: M = Manifold(3, 'R^3')
|
|
650
|
+
sage: c_xyz.<x,y,z> = M.chart() # Cartesian coordinates
|
|
651
|
+
sage: T20 = M.tensor_field_module((2,0)) ; T20
|
|
652
|
+
Free module T^(2,0)(R^3) of type-(2,0) tensors fields on the
|
|
653
|
+
3-dimensional differentiable manifold R^3
|
|
654
|
+
|
|
655
|
+
`T^{(2,0)}(\RR^3)` is a module over the algebra `C^k(\RR^3)`::
|
|
656
|
+
|
|
657
|
+
sage: T20.category()
|
|
658
|
+
Category of tensor products of finite dimensional modules over
|
|
659
|
+
Algebra of differentiable scalar fields on the 3-dimensional differentiable manifold R^3
|
|
660
|
+
sage: T20.base_ring() is M.scalar_field_algebra()
|
|
661
|
+
True
|
|
662
|
+
|
|
663
|
+
`T^{(2,0)}(\RR^3)` is a free module::
|
|
664
|
+
|
|
665
|
+
sage: from sage.tensor.modules.finite_rank_free_module import FiniteRankFreeModule_abstract
|
|
666
|
+
sage: isinstance(T20, FiniteRankFreeModule_abstract)
|
|
667
|
+
True
|
|
668
|
+
|
|
669
|
+
because `M = \RR^3` is parallelizable::
|
|
670
|
+
|
|
671
|
+
sage: M.is_manifestly_parallelizable()
|
|
672
|
+
True
|
|
673
|
+
|
|
674
|
+
The zero element::
|
|
675
|
+
|
|
676
|
+
sage: z = T20.zero() ; z
|
|
677
|
+
Tensor field zero of type (2,0) on the 3-dimensional differentiable
|
|
678
|
+
manifold R^3
|
|
679
|
+
sage: z[:]
|
|
680
|
+
[0 0 0]
|
|
681
|
+
[0 0 0]
|
|
682
|
+
[0 0 0]
|
|
683
|
+
|
|
684
|
+
A random element::
|
|
685
|
+
|
|
686
|
+
sage: t = T20.an_element() ; t
|
|
687
|
+
Tensor field of type (2,0) on the 3-dimensional differentiable
|
|
688
|
+
manifold R^3
|
|
689
|
+
sage: t[:]
|
|
690
|
+
[2 0 0]
|
|
691
|
+
[0 0 0]
|
|
692
|
+
[0 0 0]
|
|
693
|
+
|
|
694
|
+
The module `T^{(2,0)}(\RR^3)` coerces to any module of type-`(2,0)`
|
|
695
|
+
tensor fields defined on some subdomain of `\RR^3`::
|
|
696
|
+
|
|
697
|
+
sage: U = M.open_subset('U', coord_def={c_xyz: x>0})
|
|
698
|
+
sage: T20U = U.tensor_field_module((2,0))
|
|
699
|
+
sage: T20U.has_coerce_map_from(T20)
|
|
700
|
+
True
|
|
701
|
+
sage: T20.has_coerce_map_from(T20U) # the reverse is not true
|
|
702
|
+
False
|
|
703
|
+
sage: T20U.coerce_map_from(T20)
|
|
704
|
+
Coercion map:
|
|
705
|
+
From: Free module T^(2,0)(R^3) of type-(2,0) tensors fields on the 3-dimensional differentiable manifold R^3
|
|
706
|
+
To: Free module T^(2,0)(U) of type-(2,0) tensors fields on the Open subset U of the 3-dimensional differentiable manifold R^3
|
|
707
|
+
|
|
708
|
+
The coercion map is actually the *restriction* of tensor fields defined
|
|
709
|
+
on `\RR^3` to `U`.
|
|
710
|
+
|
|
711
|
+
There is also a coercion map from fields of tangent-space automorphisms to
|
|
712
|
+
tensor fields of type `(1,1)`::
|
|
713
|
+
|
|
714
|
+
sage: T11 = M.tensor_field_module((1,1)) ; T11
|
|
715
|
+
Free module T^(1,1)(R^3) of type-(1,1) tensors fields on the
|
|
716
|
+
3-dimensional differentiable manifold R^3
|
|
717
|
+
sage: GL = M.automorphism_field_group() ; GL
|
|
718
|
+
General linear group of the Free module X(R^3) of vector fields on the
|
|
719
|
+
3-dimensional differentiable manifold R^3
|
|
720
|
+
sage: T11.has_coerce_map_from(GL)
|
|
721
|
+
True
|
|
722
|
+
|
|
723
|
+
An explicit call to this coercion map is::
|
|
724
|
+
|
|
725
|
+
sage: id = GL.one() ; id
|
|
726
|
+
Field of tangent-space identity maps on the 3-dimensional
|
|
727
|
+
differentiable manifold R^3
|
|
728
|
+
sage: tid = T11(id) ; tid
|
|
729
|
+
Tensor field Id of type (1,1) on the 3-dimensional differentiable
|
|
730
|
+
manifold R^3
|
|
731
|
+
sage: tid[:]
|
|
732
|
+
[1 0 0]
|
|
733
|
+
[0 1 0]
|
|
734
|
+
[0 0 1]
|
|
735
|
+
"""
|
|
736
|
+
Element = TensorFieldParal
|
|
737
|
+
|
|
738
|
+
def __init__(self, vector_field_module, tensor_type):
|
|
739
|
+
r"""
|
|
740
|
+
Construct a module of tensor fields taking values on a
|
|
741
|
+
parallelizable differentiable manifold.
|
|
742
|
+
|
|
743
|
+
TESTS::
|
|
744
|
+
|
|
745
|
+
sage: M = Manifold(2, 'M')
|
|
746
|
+
sage: X.<x,y> = M.chart() # makes M parallelizable
|
|
747
|
+
sage: XM = M.vector_field_module()
|
|
748
|
+
sage: from sage.manifolds.differentiable.tensorfield_module import TensorFieldFreeModule
|
|
749
|
+
sage: T12 = TensorFieldFreeModule(XM, (1,2)); T12
|
|
750
|
+
Free module T^(1,2)(M) of type-(1,2) tensors fields on the
|
|
751
|
+
2-dimensional differentiable manifold M
|
|
752
|
+
sage: T12 is M.tensor_field_module((1,2))
|
|
753
|
+
True
|
|
754
|
+
sage: TestSuite(T12).run()
|
|
755
|
+
"""
|
|
756
|
+
domain = vector_field_module._domain
|
|
757
|
+
dest_map = vector_field_module._dest_map
|
|
758
|
+
kcon = tensor_type[0]
|
|
759
|
+
lcov = tensor_type[1]
|
|
760
|
+
name = "T^({},{})({}".format(kcon, lcov, domain._name)
|
|
761
|
+
latex_name = r"\mathcal{{T}}^{{({}, {})}}\left({}".format(kcon,
|
|
762
|
+
lcov, domain._latex_name)
|
|
763
|
+
if dest_map is not domain.identity_map():
|
|
764
|
+
dm_name = dest_map._name
|
|
765
|
+
dm_latex_name = dest_map._latex_name
|
|
766
|
+
if dm_name is None:
|
|
767
|
+
dm_name = "unnamed map"
|
|
768
|
+
if dm_latex_name is None:
|
|
769
|
+
dm_latex_name = r"\mathrm{unnamed\; map}"
|
|
770
|
+
name += "," + dm_name
|
|
771
|
+
latex_name += "," + dm_latex_name
|
|
772
|
+
name += ")"
|
|
773
|
+
latex_name += r"\right)"
|
|
774
|
+
TensorFreeModule.__init__(self, vector_field_module, tensor_type,
|
|
775
|
+
name=name, latex_name=latex_name)
|
|
776
|
+
self._domain = domain
|
|
777
|
+
self._dest_map = dest_map
|
|
778
|
+
self._ambient_domain = vector_field_module._ambient_domain
|
|
779
|
+
|
|
780
|
+
#### Parent methods
|
|
781
|
+
|
|
782
|
+
def _element_constructor_(self, comp=[], frame=None, name=None,
|
|
783
|
+
latex_name=None, sym=None, antisym=None):
|
|
784
|
+
r"""
|
|
785
|
+
Construct a tensor field.
|
|
786
|
+
|
|
787
|
+
TESTS::
|
|
788
|
+
|
|
789
|
+
sage: M = Manifold(2, 'M')
|
|
790
|
+
sage: X.<x,y> = M.chart() # makes M parallelizable
|
|
791
|
+
sage: T12 = M.tensor_field_module((1,2))
|
|
792
|
+
sage: t = T12([[[x,-y], [2,y]], [[1+x,y^2], [x^2,3]],
|
|
793
|
+
....: [[x*y, 1-x], [y^2, x]]], name='t'); t
|
|
794
|
+
Tensor field t of type (1,2) on the 2-dimensional
|
|
795
|
+
differentiable manifold M
|
|
796
|
+
sage: t.display()
|
|
797
|
+
t = x ∂/∂x⊗dx⊗dx - y ∂/∂x⊗dx⊗dy + 2 ∂/∂x⊗dy⊗dx + y ∂/∂x⊗dy⊗dy
|
|
798
|
+
+ (x + 1) ∂/∂y⊗dx⊗dx + y^2 ∂/∂y⊗dx⊗dy + x^2 ∂/∂y⊗dy⊗dx
|
|
799
|
+
+ 3 ∂/∂y⊗dy⊗dy
|
|
800
|
+
sage: T12(0) is T12.zero()
|
|
801
|
+
True
|
|
802
|
+
"""
|
|
803
|
+
try:
|
|
804
|
+
if comp.is_trivial_zero():
|
|
805
|
+
return self.zero()
|
|
806
|
+
except AttributeError:
|
|
807
|
+
if comp == 0:
|
|
808
|
+
return self.zero()
|
|
809
|
+
if isinstance(comp, DiffFormParal):
|
|
810
|
+
# coercion of a p-form to a type-(0,p) tensor field:
|
|
811
|
+
form = comp # for readability
|
|
812
|
+
p = form.degree()
|
|
813
|
+
if (self._tensor_type != (0,p) or
|
|
814
|
+
self._fmodule != form.base_module()):
|
|
815
|
+
raise TypeError("cannot convert the {}".format(form) +
|
|
816
|
+
" to an element of {}".format(self))
|
|
817
|
+
if p == 1:
|
|
818
|
+
asym = None
|
|
819
|
+
else:
|
|
820
|
+
asym = range(p)
|
|
821
|
+
resu = self.element_class(self._fmodule, (0,p),
|
|
822
|
+
name=form._name,
|
|
823
|
+
latex_name=form._latex_name,
|
|
824
|
+
antisym=asym)
|
|
825
|
+
for frame, cp in form._components.items():
|
|
826
|
+
resu._components[frame] = cp.copy()
|
|
827
|
+
return resu
|
|
828
|
+
if isinstance(comp, MultivectorFieldParal):
|
|
829
|
+
# coercion of a p-vector field to a type-(p,0) tensor field:
|
|
830
|
+
pvect = comp # for readability
|
|
831
|
+
p = pvect.degree()
|
|
832
|
+
if (self._tensor_type != (p,0) or
|
|
833
|
+
self._fmodule != pvect.base_module()):
|
|
834
|
+
raise TypeError("cannot convert the {}".format(pvect) +
|
|
835
|
+
" to an element of {}".format(self))
|
|
836
|
+
if p == 1:
|
|
837
|
+
asym = None
|
|
838
|
+
else:
|
|
839
|
+
asym = range(p)
|
|
840
|
+
resu = self.element_class(self._fmodule, (p,0),
|
|
841
|
+
name=pvect._name,
|
|
842
|
+
latex_name=pvect._latex_name,
|
|
843
|
+
antisym=asym)
|
|
844
|
+
for frame, cp in pvect._components.items():
|
|
845
|
+
resu._components[frame] = cp.copy()
|
|
846
|
+
return resu
|
|
847
|
+
if isinstance(comp, AutomorphismFieldParal):
|
|
848
|
+
# coercion of an automorphism to a type-(1,1) tensor:
|
|
849
|
+
autom = comp # for readability
|
|
850
|
+
if (self._tensor_type != (1,1) or
|
|
851
|
+
self._fmodule != autom.base_module()):
|
|
852
|
+
raise TypeError("cannot convert the {}".format(autom) +
|
|
853
|
+
" to an element of {}".format(self))
|
|
854
|
+
resu = self.element_class(self._fmodule, (1,1),
|
|
855
|
+
name=autom._name,
|
|
856
|
+
latex_name=autom._latex_name)
|
|
857
|
+
for basis, comp in autom._components.items():
|
|
858
|
+
resu._components[basis] = comp.copy()
|
|
859
|
+
return resu
|
|
860
|
+
if isinstance(comp, TensorField):
|
|
861
|
+
# coercion by domain restriction
|
|
862
|
+
if (self._tensor_type == comp._tensor_type
|
|
863
|
+
and self._domain.is_subset(comp._domain)
|
|
864
|
+
and self._ambient_domain.is_subset(
|
|
865
|
+
comp._ambient_domain)):
|
|
866
|
+
return comp.restrict(self._domain)
|
|
867
|
+
else:
|
|
868
|
+
raise TypeError("cannot convert the {}".format(comp) +
|
|
869
|
+
" to an element of {}".format(self))
|
|
870
|
+
if not isinstance(comp, (list, tuple)):
|
|
871
|
+
raise TypeError("cannot convert the {} ".format(comp) +
|
|
872
|
+
"to an element of {}".format(self))
|
|
873
|
+
# Standard construction
|
|
874
|
+
resu = self.element_class(self._fmodule, self._tensor_type,
|
|
875
|
+
name=name, latex_name=latex_name,
|
|
876
|
+
sym=sym, antisym=antisym)
|
|
877
|
+
if comp:
|
|
878
|
+
resu.set_comp(frame)[:] = comp
|
|
879
|
+
return resu
|
|
880
|
+
|
|
881
|
+
# Rem: _an_element_ is declared in the superclass TensorFreeModule
|
|
882
|
+
|
|
883
|
+
def _coerce_map_from_(self, other):
|
|
884
|
+
r"""
|
|
885
|
+
Determine whether coercion to ``self`` exists from other parent.
|
|
886
|
+
|
|
887
|
+
TESTS::
|
|
888
|
+
|
|
889
|
+
sage: M = Manifold(2, 'M')
|
|
890
|
+
sage: X.<x,y> = M.chart() # makes M parallelizable
|
|
891
|
+
sage: U = M.open_subset('U', coord_def={X: x>0})
|
|
892
|
+
sage: T02 = M.tensor_field_module((0,2))
|
|
893
|
+
sage: T02U = U.tensor_field_module((0,2))
|
|
894
|
+
sage: T02U._coerce_map_from_(T02)
|
|
895
|
+
True
|
|
896
|
+
sage: T02._coerce_map_from_(T02U)
|
|
897
|
+
False
|
|
898
|
+
sage: T02._coerce_map_from_(M.diff_form_module(2))
|
|
899
|
+
True
|
|
900
|
+
sage: T20 = M.tensor_field_module((2,0))
|
|
901
|
+
sage: T20._coerce_map_from_(M.multivector_module(2))
|
|
902
|
+
True
|
|
903
|
+
sage: T11 = M.tensor_field_module((1,1))
|
|
904
|
+
sage: T11._coerce_map_from_(M.automorphism_field_group())
|
|
905
|
+
True
|
|
906
|
+
"""
|
|
907
|
+
from sage.manifolds.differentiable.automorphismfield_group import (
|
|
908
|
+
AutomorphismFieldParalGroup,
|
|
909
|
+
)
|
|
910
|
+
from sage.manifolds.differentiable.diff_form_module import DiffFormFreeModule
|
|
911
|
+
from sage.manifolds.differentiable.multivector_module import (
|
|
912
|
+
MultivectorFreeModule,
|
|
913
|
+
)
|
|
914
|
+
if isinstance(other, (TensorFieldModule, TensorFieldFreeModule)):
|
|
915
|
+
# coercion by domain restriction
|
|
916
|
+
return (self._tensor_type == other._tensor_type
|
|
917
|
+
and self._domain.is_subset(other._domain)
|
|
918
|
+
and self._ambient_domain.is_subset(other._ambient_domain))
|
|
919
|
+
if isinstance(other, DiffFormFreeModule):
|
|
920
|
+
# coercion of p-forms to type-(0,p) tensor fields
|
|
921
|
+
return (self._fmodule is other.base_module()
|
|
922
|
+
and self._tensor_type == (0, other.degree()))
|
|
923
|
+
if isinstance(other, MultivectorFreeModule):
|
|
924
|
+
# coercion of p-vector fields to type-(p,0) tensor fields
|
|
925
|
+
return (self._fmodule is other.base_module()
|
|
926
|
+
and self._tensor_type == (other.degree(),0))
|
|
927
|
+
if isinstance(other, AutomorphismFieldParalGroup):
|
|
928
|
+
# coercion of automorphism fields to type-(1,1) tensor fields
|
|
929
|
+
return (self._fmodule is other.base_module()
|
|
930
|
+
and self._tensor_type == (1,1))
|
|
931
|
+
return False
|
|
932
|
+
|
|
933
|
+
#### End of parent methods
|
|
934
|
+
|
|
935
|
+
def _repr_(self):
|
|
936
|
+
r"""
|
|
937
|
+
Return a string representation of ``self``.
|
|
938
|
+
|
|
939
|
+
TESTS::
|
|
940
|
+
|
|
941
|
+
sage: M = Manifold(2, 'M')
|
|
942
|
+
sage: X.<x,y> = M.chart() # makes M parallelizable
|
|
943
|
+
sage: T12 = M.tensor_field_module((1,2))
|
|
944
|
+
sage: T12._repr_()
|
|
945
|
+
'Free module T^(1,2)(M) of type-(1,2) tensors fields on the 2-dimensional differentiable manifold M'
|
|
946
|
+
sage: repr(T12) # indirect doctest
|
|
947
|
+
'Free module T^(1,2)(M) of type-(1,2) tensors fields on the 2-dimensional differentiable manifold M'
|
|
948
|
+
sage: T12 # indirect doctest
|
|
949
|
+
Free module T^(1,2)(M) of type-(1,2) tensors fields on the
|
|
950
|
+
2-dimensional differentiable manifold M
|
|
951
|
+
"""
|
|
952
|
+
description = "Free module "
|
|
953
|
+
if self._name is not None:
|
|
954
|
+
description += self._name + " "
|
|
955
|
+
description += "of type-({},{})".format(self._tensor_type[0],
|
|
956
|
+
self._tensor_type[1])
|
|
957
|
+
description += " tensors fields "
|
|
958
|
+
if self._dest_map is self._domain.identity_map():
|
|
959
|
+
description += "on the {}".format(self._domain)
|
|
960
|
+
else:
|
|
961
|
+
description += "along the {}".format(self._domain) + \
|
|
962
|
+
" mapped into the {}".format(self._ambient_domain)
|
|
963
|
+
return description
|