passagemath-symbolics 10.6.37__cp310-cp310-musllinux_1_2_x86_64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- passagemath_symbolics/__init__.py +3 -0
- passagemath_symbolics-10.6.37.dist-info/METADATA +187 -0
- passagemath_symbolics-10.6.37.dist-info/RECORD +171 -0
- passagemath_symbolics-10.6.37.dist-info/WHEEL +5 -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-310-x86_64-linux-gnu.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-310-x86_64-linux-gnu.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-310-x86_64-linux-gnu.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-310-x86_64-linux-gnu.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-310-x86_64-linux-gnu.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,1383 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-symbolics
|
|
2
|
+
r"""
|
|
3
|
+
Tangent-Space Automorphism Fields
|
|
4
|
+
|
|
5
|
+
The class :class:`AutomorphismField` implements fields of automorphisms of
|
|
6
|
+
tangent spaces to a generic (a priori not parallelizable) differentiable
|
|
7
|
+
manifold, while the class :class:`AutomorphismFieldParal`
|
|
8
|
+
is devoted to fields of automorphisms of tangent spaces to a parallelizable
|
|
9
|
+
manifold. The latter play the important role of transitions between vector
|
|
10
|
+
frames sharing the same domain on a differentiable manifold.
|
|
11
|
+
|
|
12
|
+
AUTHORS:
|
|
13
|
+
|
|
14
|
+
- Eric Gourgoulhon (2015): initial version
|
|
15
|
+
- Travis Scrimshaw (2016): review tweaks
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
# *****************************************************************************
|
|
19
|
+
# Copyright (C) 2015 Eric Gourgoulhon <eric.gourgoulhon@obspm.fr>
|
|
20
|
+
# Copyright (C) 2016 Travis Scrimshaw <tscrimsh@umn.edu>
|
|
21
|
+
#
|
|
22
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
|
23
|
+
# as published by the Free Software Foundation; either version 2 of
|
|
24
|
+
# the License, or (at your option) any later version.
|
|
25
|
+
# https://www.gnu.org/licenses/
|
|
26
|
+
# *****************************************************************************
|
|
27
|
+
|
|
28
|
+
from sage.manifolds.differentiable.tensorfield import TensorField
|
|
29
|
+
from sage.manifolds.differentiable.tensorfield_paral import TensorFieldParal
|
|
30
|
+
from sage.tensor.modules.free_module_automorphism import FreeModuleAutomorphism
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class AutomorphismField(TensorField):
|
|
34
|
+
r"""
|
|
35
|
+
Field of automorphisms of tangent spaces to a generic (a priori
|
|
36
|
+
not parallelizable) differentiable manifold.
|
|
37
|
+
|
|
38
|
+
Given a differentiable manifold `U` and a differentiable map
|
|
39
|
+
`\Phi: U \rightarrow M` to a differentiable manifold `M`,
|
|
40
|
+
a *field of tangent-space automorphisms along* `U` *with values on*
|
|
41
|
+
`M \supset\Phi(U)` is a differentiable map
|
|
42
|
+
|
|
43
|
+
.. MATH::
|
|
44
|
+
|
|
45
|
+
a:\ U \longrightarrow T^{(1,1)} M,
|
|
46
|
+
|
|
47
|
+
with `T^{(1,1)} M` being the tensor bundle of type `(1,1)` over `M`,
|
|
48
|
+
such that
|
|
49
|
+
|
|
50
|
+
.. MATH::
|
|
51
|
+
|
|
52
|
+
\forall p \in U,\ a(p) \in \mathrm{Aut}(T_{\Phi(p)} M),
|
|
53
|
+
|
|
54
|
+
i.e. `a(p)` is an automorphism of the tangent space to `M` at the
|
|
55
|
+
point `\Phi(p)`.
|
|
56
|
+
|
|
57
|
+
The standard case of a field of tangent-space automorphisms *on* a
|
|
58
|
+
manifold corresponds to `U = M` and `\Phi = \mathrm{Id}_M`. Other
|
|
59
|
+
common cases are `\Phi` being an immersion and `\Phi` being a curve
|
|
60
|
+
in `M` (`U` is then an open interval of `\RR`).
|
|
61
|
+
|
|
62
|
+
.. NOTE::
|
|
63
|
+
|
|
64
|
+
If `M` is parallelizable, then :class:`AutomorphismFieldParal`
|
|
65
|
+
*must* be used instead.
|
|
66
|
+
|
|
67
|
+
INPUT:
|
|
68
|
+
|
|
69
|
+
- ``vector_field_module`` -- module `\mathfrak{X}(U,\Phi)` of vector
|
|
70
|
+
fields along `U` with values on `M` via the map `\Phi`
|
|
71
|
+
- ``name`` -- (default: ``None``) name given to the field
|
|
72
|
+
- ``latex_name`` -- (default: ``None``) LaTeX symbol to denote the field;
|
|
73
|
+
if none is provided, the LaTeX symbol is set to ``name``
|
|
74
|
+
- ``is_identity`` -- boolean (default: ``False``); determines whether the
|
|
75
|
+
constructed object is a field of identity automorphisms
|
|
76
|
+
|
|
77
|
+
EXAMPLES:
|
|
78
|
+
|
|
79
|
+
Field of tangent-space automorphisms on a non-parallelizable
|
|
80
|
+
2-dimensional manifold::
|
|
81
|
+
|
|
82
|
+
sage: M = Manifold(2, 'M')
|
|
83
|
+
sage: U = M.open_subset('U') ; V = M.open_subset('V')
|
|
84
|
+
sage: M.declare_union(U,V) # M is the union of U and V
|
|
85
|
+
sage: c_xy.<x,y> = U.chart() ; c_uv.<u,v> = V.chart()
|
|
86
|
+
sage: transf = c_xy.transition_map(c_uv, (x+y, x-y), intersection_name='W',
|
|
87
|
+
....: restrictions1= x>0, restrictions2= u+v>0)
|
|
88
|
+
sage: inv = transf.inverse()
|
|
89
|
+
sage: a = M.automorphism_field(name='a') ; a
|
|
90
|
+
Field of tangent-space automorphisms a on the 2-dimensional
|
|
91
|
+
differentiable manifold M
|
|
92
|
+
sage: a.parent()
|
|
93
|
+
General linear group of the Module X(M) of vector fields on the
|
|
94
|
+
2-dimensional differentiable manifold M
|
|
95
|
+
|
|
96
|
+
We first define the components of `a` with respect to the
|
|
97
|
+
coordinate frame on `U`::
|
|
98
|
+
|
|
99
|
+
sage: eU = c_xy.frame() ; eV = c_uv.frame()
|
|
100
|
+
sage: a[eU,:] = [[1,x], [0,2]]
|
|
101
|
+
|
|
102
|
+
It is equivalent to pass the components while defining `a`::
|
|
103
|
+
|
|
104
|
+
sage: a = M.automorphism_field({eU: [[1,x], [0,2]]}, name='a')
|
|
105
|
+
|
|
106
|
+
We then set the components with respect to the coordinate frame
|
|
107
|
+
on `V` by extending the expressions of the components in the
|
|
108
|
+
corresponding subframe on `W = U \cap V`::
|
|
109
|
+
|
|
110
|
+
sage: W = U.intersection(V)
|
|
111
|
+
sage: a.add_comp_by_continuation(eV, W, c_uv)
|
|
112
|
+
|
|
113
|
+
At this stage, the automorphism field `a` is fully defined::
|
|
114
|
+
|
|
115
|
+
sage: a.display(eU)
|
|
116
|
+
a = ∂/∂x⊗dx + x ∂/∂x⊗dy + 2 ∂/∂y⊗dy
|
|
117
|
+
sage: a.display(eV)
|
|
118
|
+
a = (1/4*u + 1/4*v + 3/2) ∂/∂u⊗du + (-1/4*u - 1/4*v - 1/2) ∂/∂u⊗dv
|
|
119
|
+
+ (1/4*u + 1/4*v - 1/2) ∂/∂v⊗du + (-1/4*u - 1/4*v + 3/2) ∂/∂v⊗dv
|
|
120
|
+
|
|
121
|
+
In particular, we may ask for its inverse on the whole manifold `M`::
|
|
122
|
+
|
|
123
|
+
sage: ia = a.inverse() ; ia
|
|
124
|
+
Field of tangent-space automorphisms a^(-1) on the 2-dimensional
|
|
125
|
+
differentiable manifold M
|
|
126
|
+
sage: ia.display(eU)
|
|
127
|
+
a^(-1) = ∂/∂x⊗dx - 1/2*x ∂/∂x⊗dy + 1/2 ∂/∂y⊗dy
|
|
128
|
+
sage: ia.display(eV)
|
|
129
|
+
a^(-1) = (-1/8*u - 1/8*v + 3/4) ∂/∂u⊗du + (1/8*u + 1/8*v + 1/4) ∂/∂u⊗dv
|
|
130
|
+
+ (-1/8*u - 1/8*v + 1/4) ∂/∂v⊗du + (1/8*u + 1/8*v + 3/4) ∂/∂v⊗dv
|
|
131
|
+
|
|
132
|
+
Equivalently, one can use the power minus one to get the inverse::
|
|
133
|
+
|
|
134
|
+
sage: ia is a^(-1)
|
|
135
|
+
True
|
|
136
|
+
|
|
137
|
+
or the operator ``~``::
|
|
138
|
+
|
|
139
|
+
sage: ia is ~a
|
|
140
|
+
True
|
|
141
|
+
"""
|
|
142
|
+
def __init__(self, vector_field_module, name=None, latex_name=None):
|
|
143
|
+
r"""
|
|
144
|
+
Construct a field of tangent-space automorphisms on a
|
|
145
|
+
non-parallelizable manifold.
|
|
146
|
+
|
|
147
|
+
TESTS:
|
|
148
|
+
|
|
149
|
+
Construction via ``parent.element_class``, and not via a direct call
|
|
150
|
+
to ``AutomorphismField``, to fit with the category framework::
|
|
151
|
+
|
|
152
|
+
sage: M = Manifold(2, 'M')
|
|
153
|
+
sage: U = M.open_subset('U') ; V = M.open_subset('V')
|
|
154
|
+
sage: M.declare_union(U,V) # M is the union of U and V
|
|
155
|
+
sage: c_xy.<x,y> = U.chart() ; c_uv.<u,v> = V.chart()
|
|
156
|
+
sage: transf = c_xy.transition_map(c_uv, (x+y, x-y), intersection_name='W',
|
|
157
|
+
....: restrictions1= x>0, restrictions2= u+v>0)
|
|
158
|
+
sage: inv = transf.inverse()
|
|
159
|
+
sage: XM = M.vector_field_module()
|
|
160
|
+
sage: GL = XM.general_linear_group()
|
|
161
|
+
sage: a = GL.element_class(XM, name='a'); a
|
|
162
|
+
Field of tangent-space automorphisms a on the 2-dimensional
|
|
163
|
+
differentiable manifold M
|
|
164
|
+
sage: a[c_xy.frame(), :] = [[1+x^2, 0], [0, 1+y^2]]
|
|
165
|
+
sage: a.add_comp_by_continuation(c_uv.frame(), U.intersection(V), c_uv)
|
|
166
|
+
sage: TestSuite(a).run(skip='_test_pickling')
|
|
167
|
+
|
|
168
|
+
Construction of the identity field::
|
|
169
|
+
|
|
170
|
+
sage: b = GL.one(); b
|
|
171
|
+
Field of tangent-space identity maps on the 2-dimensional
|
|
172
|
+
differentiable manifold M
|
|
173
|
+
sage: TestSuite(b).run(skip='_test_pickling')
|
|
174
|
+
|
|
175
|
+
Construction with ``DifferentiableManifold.automorphism_field``::
|
|
176
|
+
|
|
177
|
+
sage: a1 = M.automorphism_field(name='a'); a1
|
|
178
|
+
Field of tangent-space automorphisms a on the 2-dimensional
|
|
179
|
+
differentiable manifold M
|
|
180
|
+
sage: type(a1) == type(a)
|
|
181
|
+
True
|
|
182
|
+
|
|
183
|
+
.. TODO::
|
|
184
|
+
|
|
185
|
+
Fix ``_test_pickling`` (in the superclass :class:`TensorField`).
|
|
186
|
+
"""
|
|
187
|
+
TensorField.__init__(self, vector_field_module, (1,1), name=name,
|
|
188
|
+
latex_name=latex_name,
|
|
189
|
+
parent=vector_field_module.general_linear_group())
|
|
190
|
+
self._is_identity = False # a priori
|
|
191
|
+
self._init_derived() # initialization of derived quantities
|
|
192
|
+
|
|
193
|
+
def _repr_(self):
|
|
194
|
+
r"""
|
|
195
|
+
Return a string representation of ``self``.
|
|
196
|
+
|
|
197
|
+
TESTS::
|
|
198
|
+
|
|
199
|
+
sage: M = Manifold(2, 'M')
|
|
200
|
+
sage: a = M.automorphism_field(name='a')
|
|
201
|
+
sage: a._repr_()
|
|
202
|
+
'Field of tangent-space automorphisms a on the 2-dimensional differentiable manifold M'
|
|
203
|
+
sage: repr(a) # indirect doctest
|
|
204
|
+
'Field of tangent-space automorphisms a on the 2-dimensional differentiable manifold M'
|
|
205
|
+
sage: a # indirect doctest
|
|
206
|
+
Field of tangent-space automorphisms a on the 2-dimensional
|
|
207
|
+
differentiable manifold M
|
|
208
|
+
"""
|
|
209
|
+
description = "Field of tangent-space "
|
|
210
|
+
if self is self.parent().one():
|
|
211
|
+
description += "identity maps "
|
|
212
|
+
else:
|
|
213
|
+
description += "automorphisms "
|
|
214
|
+
if self._name is not None:
|
|
215
|
+
description += self._name + " "
|
|
216
|
+
return self._final_repr(description)
|
|
217
|
+
|
|
218
|
+
def _init_derived(self):
|
|
219
|
+
r"""
|
|
220
|
+
Initialize the derived quantities.
|
|
221
|
+
|
|
222
|
+
TESTS::
|
|
223
|
+
|
|
224
|
+
sage: M = Manifold(2, 'M')
|
|
225
|
+
sage: a = M.automorphism_field(name='a')
|
|
226
|
+
sage: a._init_derived()
|
|
227
|
+
"""
|
|
228
|
+
TensorField._init_derived(self)
|
|
229
|
+
self._inverse = None # inverse not set yet
|
|
230
|
+
|
|
231
|
+
def _del_derived(self):
|
|
232
|
+
r"""
|
|
233
|
+
Delete the derived quantities.
|
|
234
|
+
|
|
235
|
+
TESTS::
|
|
236
|
+
|
|
237
|
+
sage: M = Manifold(2, 'M')
|
|
238
|
+
sage: a = M.automorphism_field(name='a')
|
|
239
|
+
sage: a._del_derived()
|
|
240
|
+
"""
|
|
241
|
+
# First delete the derived quantities pertaining to the mother class:
|
|
242
|
+
TensorField._del_derived(self)
|
|
243
|
+
# then deletes the inverse automorphism:
|
|
244
|
+
self._inverse = None
|
|
245
|
+
|
|
246
|
+
def set_comp(self, basis=None):
|
|
247
|
+
r"""
|
|
248
|
+
Return the components of ``self`` w.r.t. a given module basis for
|
|
249
|
+
assignment.
|
|
250
|
+
|
|
251
|
+
The components with respect to other bases are deleted, in order to
|
|
252
|
+
avoid any inconsistency. To keep them, use the method :meth:`add_comp`
|
|
253
|
+
instead.
|
|
254
|
+
|
|
255
|
+
INPUT:
|
|
256
|
+
|
|
257
|
+
- ``basis`` -- (default: ``None``) basis in which the components are
|
|
258
|
+
defined; if none is provided, the components are assumed to refer to
|
|
259
|
+
the module's default basis
|
|
260
|
+
|
|
261
|
+
OUTPUT:
|
|
262
|
+
|
|
263
|
+
- components in the given basis, as an instance of the
|
|
264
|
+
class :class:`~sage.tensor.modules.comp.Components`; if such
|
|
265
|
+
components did not exist previously, they are created.
|
|
266
|
+
|
|
267
|
+
EXAMPLES::
|
|
268
|
+
|
|
269
|
+
sage: M = Manifold(2, 'M') # the 2-dimensional sphere S^2
|
|
270
|
+
sage: U = M.open_subset('U') # complement of the North pole
|
|
271
|
+
sage: c_xy.<x,y> = U.chart() # stereographic coordinates from the North pole
|
|
272
|
+
sage: V = M.open_subset('V') # complement of the South pole
|
|
273
|
+
sage: c_uv.<u,v> = V.chart() # stereographic coordinates from the South pole
|
|
274
|
+
sage: M.declare_union(U,V) # S^2 is the union of U and V
|
|
275
|
+
sage: e_uv = c_uv.frame()
|
|
276
|
+
sage: a= M.automorphism_field(name='a')
|
|
277
|
+
sage: a.set_comp(e_uv)
|
|
278
|
+
2-indices components w.r.t. Coordinate frame (V, (∂/∂u,∂/∂v))
|
|
279
|
+
sage: a.set_comp(e_uv)[0,0] = u+v
|
|
280
|
+
sage: a.set_comp(e_uv)[1,1] = u+v
|
|
281
|
+
sage: a.display(e_uv)
|
|
282
|
+
a = (u + v) ∂/∂u⊗du + (u + v) ∂/∂v⊗dv
|
|
283
|
+
|
|
284
|
+
Setting the components in a new frame::
|
|
285
|
+
|
|
286
|
+
sage: e = V.vector_frame('e')
|
|
287
|
+
sage: a.set_comp(e)
|
|
288
|
+
2-indices components w.r.t. Vector frame (V, (e_0,e_1))
|
|
289
|
+
sage: a.set_comp(e)[0,1] = u*v
|
|
290
|
+
sage: a.set_comp(e)[1,0] = u*v
|
|
291
|
+
sage: a.display(e)
|
|
292
|
+
a = u*v e_0⊗e^1 + u*v e_1⊗e^0
|
|
293
|
+
|
|
294
|
+
Since the frames ``e`` and ``e_uv`` are defined on the same domain, the
|
|
295
|
+
components w.r.t. ``e_uv`` have been erased::
|
|
296
|
+
|
|
297
|
+
sage: a.display(c_uv.frame())
|
|
298
|
+
Traceback (most recent call last):
|
|
299
|
+
...
|
|
300
|
+
ValueError: no basis could be found for computing the components
|
|
301
|
+
in the Coordinate frame (V, (∂/∂u,∂/∂v))
|
|
302
|
+
|
|
303
|
+
Since the identity map is an immutable element, its components
|
|
304
|
+
cannot be changed::
|
|
305
|
+
|
|
306
|
+
sage: id = M.tangent_identity_field()
|
|
307
|
+
sage: id.add_comp(e)[0,1] = u*v
|
|
308
|
+
Traceback (most recent call last):
|
|
309
|
+
...
|
|
310
|
+
ValueError: the components of an immutable element cannot be
|
|
311
|
+
changed
|
|
312
|
+
"""
|
|
313
|
+
comp = super().set_comp(basis=basis)
|
|
314
|
+
self._is_identity = False # a priori
|
|
315
|
+
return comp
|
|
316
|
+
|
|
317
|
+
def add_comp(self, basis=None):
|
|
318
|
+
r"""
|
|
319
|
+
Return the components of ``self`` w.r.t. a given module basis for
|
|
320
|
+
assignment, keeping the components w.r.t. other bases.
|
|
321
|
+
|
|
322
|
+
To delete the components w.r.t. other bases, use the method
|
|
323
|
+
:meth:`set_comp` instead.
|
|
324
|
+
|
|
325
|
+
INPUT:
|
|
326
|
+
|
|
327
|
+
- ``basis`` -- (default: ``None``) basis in which the components are
|
|
328
|
+
defined; if none is provided, the components are assumed to refer to
|
|
329
|
+
the module's default basis
|
|
330
|
+
|
|
331
|
+
.. WARNING::
|
|
332
|
+
|
|
333
|
+
If the automorphism field has already components in other bases, it
|
|
334
|
+
is the user's responsibility to make sure that the components
|
|
335
|
+
to be added are consistent with them.
|
|
336
|
+
|
|
337
|
+
OUTPUT:
|
|
338
|
+
|
|
339
|
+
- components in the given basis, as an instance of the
|
|
340
|
+
class :class:`~sage.tensor.modules.comp.Components`;
|
|
341
|
+
if such components did not exist previously, they are created
|
|
342
|
+
|
|
343
|
+
EXAMPLES::
|
|
344
|
+
|
|
345
|
+
sage: M = Manifold(2, 'M') # the 2-dimensional sphere S^2
|
|
346
|
+
sage: U = M.open_subset('U') # complement of the North pole
|
|
347
|
+
sage: c_xy.<x,y> = U.chart() # stereographic coordinates from the North pole
|
|
348
|
+
sage: V = M.open_subset('V') # complement of the South pole
|
|
349
|
+
sage: c_uv.<u,v> = V.chart() # stereographic coordinates from the South pole
|
|
350
|
+
sage: M.declare_union(U,V) # S^2 is the union of U and V
|
|
351
|
+
sage: e_uv = c_uv.frame()
|
|
352
|
+
sage: a= M.automorphism_field(name='a')
|
|
353
|
+
sage: a.add_comp(e_uv)
|
|
354
|
+
2-indices components w.r.t. Coordinate frame (V, (∂/∂u,∂/∂v))
|
|
355
|
+
sage: a.add_comp(e_uv)[0,0] = u+v
|
|
356
|
+
sage: a.add_comp(e_uv)[1,1] = u+v
|
|
357
|
+
sage: a.display(e_uv)
|
|
358
|
+
a = (u + v) ∂/∂u⊗du + (u + v) ∂/∂v⊗dv
|
|
359
|
+
|
|
360
|
+
Setting the components in a new frame::
|
|
361
|
+
|
|
362
|
+
sage: e = V.vector_frame('e')
|
|
363
|
+
sage: a.add_comp(e)
|
|
364
|
+
2-indices components w.r.t. Vector frame (V, (e_0,e_1))
|
|
365
|
+
sage: a.add_comp(e)[0,1] = u*v
|
|
366
|
+
sage: a.add_comp(e)[1,0] = u*v
|
|
367
|
+
sage: a.display(e)
|
|
368
|
+
a = u*v e_0⊗e^1 + u*v e_1⊗e^0
|
|
369
|
+
|
|
370
|
+
The components with respect to ``e_uv`` are kept::
|
|
371
|
+
|
|
372
|
+
sage: a.display(e_uv)
|
|
373
|
+
a = (u + v) ∂/∂u⊗du + (u + v) ∂/∂v⊗dv
|
|
374
|
+
|
|
375
|
+
Since the identity map is a special element, its components cannot be
|
|
376
|
+
changed::
|
|
377
|
+
|
|
378
|
+
sage: id = M.tangent_identity_field()
|
|
379
|
+
sage: id.add_comp(e)[0,1] = u*v
|
|
380
|
+
Traceback (most recent call last):
|
|
381
|
+
...
|
|
382
|
+
ValueError: the components of an immutable element cannot be
|
|
383
|
+
changed
|
|
384
|
+
"""
|
|
385
|
+
comp = super().add_comp(basis=basis)
|
|
386
|
+
self._is_identity = False # a priori
|
|
387
|
+
return comp
|
|
388
|
+
|
|
389
|
+
def _new_instance(self):
|
|
390
|
+
r"""
|
|
391
|
+
Create an instance of the same class as ``self`` on the same
|
|
392
|
+
vector field module.
|
|
393
|
+
|
|
394
|
+
TESTS::
|
|
395
|
+
|
|
396
|
+
sage: M = Manifold(5, 'M')
|
|
397
|
+
sage: a = M.automorphism_field(name='a')
|
|
398
|
+
sage: a._new_instance()
|
|
399
|
+
Field of tangent-space automorphisms on the 5-dimensional
|
|
400
|
+
differentiable manifold M
|
|
401
|
+
sage: a._new_instance().parent() is a.parent()
|
|
402
|
+
True
|
|
403
|
+
"""
|
|
404
|
+
return type(self)(self._vmodule)
|
|
405
|
+
|
|
406
|
+
def __call__(self, *arg):
|
|
407
|
+
r"""
|
|
408
|
+
Redefinition of
|
|
409
|
+
:meth:`~sage.manifolds.differentiable.tensorfield.TensorField.__call__`
|
|
410
|
+
to allow for a proper treatment of the identity map and of the call
|
|
411
|
+
with a single argument
|
|
412
|
+
|
|
413
|
+
TESTS:
|
|
414
|
+
|
|
415
|
+
Field of identity maps on the 2-sphere::
|
|
416
|
+
|
|
417
|
+
sage: M = Manifold(2, 'M') # the 2-dimensional sphere S^2
|
|
418
|
+
sage: U = M.open_subset('U') # complement of the North pole
|
|
419
|
+
sage: c_xy.<x,y> = U.chart() # stereographic coordinates from the North pole
|
|
420
|
+
sage: V = M.open_subset('V') # complement of the South pole
|
|
421
|
+
sage: c_uv.<u,v> = V.chart() # stereographic coordinates from the South pole
|
|
422
|
+
sage: M.declare_union(U,V) # S^2 is the union of U and V
|
|
423
|
+
sage: xy_to_uv = c_xy.transition_map(c_uv, (x/(x^2+y^2), y/(x^2+y^2)),
|
|
424
|
+
....: intersection_name='W', restrictions1= x^2+y^2!=0,
|
|
425
|
+
....: restrictions2= u^2+v^2!=0)
|
|
426
|
+
sage: uv_to_xy = xy_to_uv.inverse()
|
|
427
|
+
sage: e_xy = c_xy.frame(); e_uv = c_uv.frame()
|
|
428
|
+
sage: w = M.vector_field({e_xy: [3, 1]}, name='w')
|
|
429
|
+
sage: w.add_comp_by_continuation(e_uv, U.intersection(V), c_uv)
|
|
430
|
+
sage: z = M.one_form({e_xy: [-y, x]}, name='z')
|
|
431
|
+
sage: z.add_comp_by_continuation(e_uv, U.intersection(V), c_uv)
|
|
432
|
+
sage: Id = M.tangent_identity_field()
|
|
433
|
+
sage: s = Id(w); s
|
|
434
|
+
Vector field w on the 2-dimensional differentiable manifold M
|
|
435
|
+
sage: s == w
|
|
436
|
+
True
|
|
437
|
+
sage: s = Id(z, w); s
|
|
438
|
+
Scalar field z(w) on the 2-dimensional differentiable manifold M
|
|
439
|
+
sage: s == z(w)
|
|
440
|
+
True
|
|
441
|
+
|
|
442
|
+
Field of automorphisms on the 2-sphere::
|
|
443
|
+
|
|
444
|
+
sage: a = M.automorphism_field({e_xy: [[-1, 0], [0, 1]]}, name='a')
|
|
445
|
+
sage: a.add_comp_by_continuation(e_uv, U.intersection(V), c_uv)
|
|
446
|
+
|
|
447
|
+
Call with a single argument::
|
|
448
|
+
|
|
449
|
+
sage: s = a(w); s
|
|
450
|
+
Vector field a(w) on the 2-dimensional differentiable manifold M
|
|
451
|
+
sage: s.display(e_xy)
|
|
452
|
+
a(w) = -3 ∂/∂x + ∂/∂y
|
|
453
|
+
sage: s.display(e_uv)
|
|
454
|
+
a(w) = (3*u^2 - 2*u*v - 3*v^2) ∂/∂u + (u^2 + 6*u*v - v^2) ∂/∂v
|
|
455
|
+
sage: s.restrict(U) == a.restrict(U)(w.restrict(U))
|
|
456
|
+
True
|
|
457
|
+
sage: s.restrict(V) == a.restrict(V)(w.restrict(V))
|
|
458
|
+
True
|
|
459
|
+
sage: s.restrict(U) == a(w.restrict(U))
|
|
460
|
+
True
|
|
461
|
+
sage: s.restrict(U) == a.restrict(U)(w)
|
|
462
|
+
True
|
|
463
|
+
|
|
464
|
+
Call with two arguments::
|
|
465
|
+
|
|
466
|
+
sage: s = a(z, w); s
|
|
467
|
+
Scalar field a(z,w) on the 2-dimensional differentiable manifold M
|
|
468
|
+
sage: s.display()
|
|
469
|
+
a(z,w): M → ℝ
|
|
470
|
+
on U: (x, y) ↦ x + 3*y
|
|
471
|
+
on V: (u, v) ↦ (u + 3*v)/(u^2 + v^2)
|
|
472
|
+
sage: s.restrict(U) == a.restrict(U)(z.restrict(U), w.restrict(U))
|
|
473
|
+
True
|
|
474
|
+
sage: s.restrict(V) == a.restrict(V)(z.restrict(V), w.restrict(V))
|
|
475
|
+
True
|
|
476
|
+
sage: s.restrict(U) == a(z.restrict(U), w.restrict(U))
|
|
477
|
+
True
|
|
478
|
+
sage: s.restrict(U) == a(z, w.restrict(U))
|
|
479
|
+
True
|
|
480
|
+
"""
|
|
481
|
+
if self._is_identity:
|
|
482
|
+
if len(arg) == 1:
|
|
483
|
+
# The identity map acting as such, on a vector field:
|
|
484
|
+
vector = arg[0]
|
|
485
|
+
if vector._tensor_type != (1,0):
|
|
486
|
+
raise TypeError("the argument must be a vector field")
|
|
487
|
+
dom = self._domain.intersection(vector._domain)
|
|
488
|
+
return vector.restrict(dom)
|
|
489
|
+
elif len(arg) == 2:
|
|
490
|
+
# self acting as a type-(1,1) tensor on a pair
|
|
491
|
+
# (1-form, vector field), returning a scalar field:
|
|
492
|
+
oneform = arg[0]
|
|
493
|
+
vector = arg[1]
|
|
494
|
+
dom = self._domain.intersection(
|
|
495
|
+
oneform._domain).intersection(vector._domain)
|
|
496
|
+
return oneform.restrict(dom)(vector.restrict(dom))
|
|
497
|
+
else:
|
|
498
|
+
raise TypeError("wrong number of arguments")
|
|
499
|
+
# Generic case
|
|
500
|
+
if len(arg) == 1:
|
|
501
|
+
# The field of automorphisms acting on a vector field:
|
|
502
|
+
vector = arg[0]
|
|
503
|
+
if vector._tensor_type != (1,0):
|
|
504
|
+
raise TypeError("the argument must be a vector field")
|
|
505
|
+
dom = self._domain.intersection(vector._domain)
|
|
506
|
+
vector_dom = vector.restrict(dom)
|
|
507
|
+
if dom != self._domain:
|
|
508
|
+
return self.restrict(dom)(vector_dom)
|
|
509
|
+
resu = dom.vector_field()
|
|
510
|
+
if self._name is not None and vector._name is not None:
|
|
511
|
+
resu._name = self._name + "(" + vector._name + ")"
|
|
512
|
+
if self._latex_name is not None and vector._latex_name is not None:
|
|
513
|
+
resu._latex_name = self._latex_name + r"\left(" + \
|
|
514
|
+
vector._latex_name + r"\right)"
|
|
515
|
+
for sdom, automorph in self._restrictions.items():
|
|
516
|
+
resu._restrictions[sdom] = automorph(vector_dom.restrict(sdom))
|
|
517
|
+
return resu
|
|
518
|
+
# Case of 2 arguments:
|
|
519
|
+
return TensorField.__call__(self, *arg)
|
|
520
|
+
|
|
521
|
+
def copy(self, name=None, latex_name=None):
|
|
522
|
+
r"""
|
|
523
|
+
Return an exact copy of the automorphism field ``self``.
|
|
524
|
+
|
|
525
|
+
INPUT:
|
|
526
|
+
|
|
527
|
+
- ``name`` -- (default: ``None``) name given to the copy
|
|
528
|
+
- ``latex_name`` -- (default: ``None``) LaTeX symbol to denote the
|
|
529
|
+
copy; if none is provided, the LaTeX symbol is set to ``name``
|
|
530
|
+
|
|
531
|
+
.. NOTE::
|
|
532
|
+
|
|
533
|
+
The name and the derived quantities are not copied.
|
|
534
|
+
|
|
535
|
+
EXAMPLES::
|
|
536
|
+
|
|
537
|
+
sage: M = Manifold(2, 'M')
|
|
538
|
+
sage: U = M.open_subset('U') ; V = M.open_subset('V')
|
|
539
|
+
sage: M.declare_union(U,V) # M is the union of U and V
|
|
540
|
+
sage: c_xy.<x,y> = U.chart() ; c_uv.<u,v> = V.chart()
|
|
541
|
+
sage: xy_to_uv = c_xy.transition_map(c_uv, (x+y, x-y),
|
|
542
|
+
....: intersection_name='W', restrictions1= x>0,
|
|
543
|
+
....: restrictions2= u+v>0)
|
|
544
|
+
sage: uv_to_xy = xy_to_uv.inverse()
|
|
545
|
+
sage: Id = M.tangent_identity_field(); Id
|
|
546
|
+
Field of tangent-space identity maps on the 2-dimensional
|
|
547
|
+
differentiable manifold M
|
|
548
|
+
sage: one = Id.copy('1'); one
|
|
549
|
+
Field of tangent-space automorphisms 1 on the 2-dimensional
|
|
550
|
+
differentiable manifold M
|
|
551
|
+
"""
|
|
552
|
+
copy = super().copy(name=name, latex_name=latex_name)
|
|
553
|
+
copy._is_identity = self._is_identity
|
|
554
|
+
return copy
|
|
555
|
+
|
|
556
|
+
#### MultiplicativeGroupElement methods ####
|
|
557
|
+
|
|
558
|
+
def __invert__(self):
|
|
559
|
+
r"""
|
|
560
|
+
Return the inverse automorphism of ``self``.
|
|
561
|
+
|
|
562
|
+
EXAMPLES:
|
|
563
|
+
|
|
564
|
+
Inverse of a field of tangent-space automorphisms on a
|
|
565
|
+
non-parallelizable 2-dimensional manifold::
|
|
566
|
+
|
|
567
|
+
sage: M = Manifold(2, 'M')
|
|
568
|
+
sage: U = M.open_subset('U') ; V = M.open_subset('V')
|
|
569
|
+
sage: M.declare_union(U,V) # M is the union of U and V
|
|
570
|
+
sage: W = U.intersection(V)
|
|
571
|
+
sage: c_xy.<x,y> = U.chart() ; c_uv.<u,v> = V.chart()
|
|
572
|
+
sage: transf = c_xy.transition_map(c_uv, (x+y, x-y),
|
|
573
|
+
....: intersection_name='W', restrictions1= x>0, restrictions2= u+v>0)
|
|
574
|
+
sage: inv = transf.inverse()
|
|
575
|
+
sage: eU = c_xy.frame() ; eV = c_uv.frame()
|
|
576
|
+
sage: a = M.automorphism_field({eU: [[1,x], [0,2]]}, name='a')
|
|
577
|
+
sage: a.add_comp_by_continuation(eV, W, c_uv)
|
|
578
|
+
sage: ia = a.inverse() ; ia
|
|
579
|
+
Field of tangent-space automorphisms a^(-1) on the 2-dimensional
|
|
580
|
+
differentiable manifold M
|
|
581
|
+
sage: a[eU,:], ia[eU,:]
|
|
582
|
+
(
|
|
583
|
+
[1 x] [ 1 -1/2*x]
|
|
584
|
+
[0 2], [ 0 1/2]
|
|
585
|
+
)
|
|
586
|
+
sage: a[eV,:], ia[eV,:]
|
|
587
|
+
(
|
|
588
|
+
[ 1/4*u + 1/4*v + 3/2 -1/4*u - 1/4*v - 1/2]
|
|
589
|
+
[ 1/4*u + 1/4*v - 1/2 -1/4*u - 1/4*v + 3/2],
|
|
590
|
+
[-1/8*u - 1/8*v + 3/4 1/8*u + 1/8*v + 1/4]
|
|
591
|
+
[-1/8*u - 1/8*v + 1/4 1/8*u + 1/8*v + 3/4]
|
|
592
|
+
)
|
|
593
|
+
|
|
594
|
+
Let us check that ia is indeed the inverse of a::
|
|
595
|
+
|
|
596
|
+
sage: s = a.contract(ia)
|
|
597
|
+
sage: s[eU,:], s[eV,:]
|
|
598
|
+
(
|
|
599
|
+
[1 0] [1 0]
|
|
600
|
+
[0 1], [0 1]
|
|
601
|
+
)
|
|
602
|
+
sage: s = ia.contract(a)
|
|
603
|
+
sage: s[eU,:], s[eV,:]
|
|
604
|
+
(
|
|
605
|
+
[1 0] [1 0]
|
|
606
|
+
[0 1], [0 1]
|
|
607
|
+
)
|
|
608
|
+
|
|
609
|
+
The result is cached::
|
|
610
|
+
|
|
611
|
+
sage: a.inverse() is ia
|
|
612
|
+
True
|
|
613
|
+
|
|
614
|
+
Instead of ``inverse()``, one can use the power minus one to get the
|
|
615
|
+
inverse::
|
|
616
|
+
|
|
617
|
+
sage: ia is a^(-1)
|
|
618
|
+
True
|
|
619
|
+
|
|
620
|
+
or the operator ``~``::
|
|
621
|
+
|
|
622
|
+
sage: ia is ~a
|
|
623
|
+
True
|
|
624
|
+
"""
|
|
625
|
+
if self._is_identity:
|
|
626
|
+
return self
|
|
627
|
+
if self._inverse is None:
|
|
628
|
+
from sage.tensor.modules.format_utilities import is_atomic
|
|
629
|
+
if self._name is None:
|
|
630
|
+
inv_name = None
|
|
631
|
+
else:
|
|
632
|
+
if is_atomic(self._name, ['*']):
|
|
633
|
+
inv_name = self._name + '^(-1)'
|
|
634
|
+
else:
|
|
635
|
+
inv_name = '(' + self._name + ')^(-1)'
|
|
636
|
+
if self._latex_name is None:
|
|
637
|
+
inv_latex_name = None
|
|
638
|
+
else:
|
|
639
|
+
if is_atomic(self._latex_name, ['\\circ', '\\otimes']):
|
|
640
|
+
inv_latex_name = self._latex_name + r'^{-1}'
|
|
641
|
+
else:
|
|
642
|
+
inv_latex_name = r'\left(' + self._latex_name + \
|
|
643
|
+
r'\right)^{-1}'
|
|
644
|
+
self._inverse = self._vmodule.automorphism(name=inv_name,
|
|
645
|
+
latex_name=inv_latex_name)
|
|
646
|
+
for dom, rst in self._restrictions.items():
|
|
647
|
+
self._inverse._restrictions[dom] = rst.inverse()
|
|
648
|
+
return self._inverse
|
|
649
|
+
|
|
650
|
+
inverse = __invert__
|
|
651
|
+
|
|
652
|
+
def _mul_(self, other):
|
|
653
|
+
r"""
|
|
654
|
+
Automorphism composition.
|
|
655
|
+
|
|
656
|
+
This implements the group law of `GL(X(U,\Phi))`, with `X(U,\Phi)`
|
|
657
|
+
being the module of ``self``.
|
|
658
|
+
|
|
659
|
+
INPUT:
|
|
660
|
+
|
|
661
|
+
- ``other`` -- an automorphism of the same module as ``self``
|
|
662
|
+
|
|
663
|
+
OUTPUT:
|
|
664
|
+
|
|
665
|
+
- the automorphism resulting from the composition of ``other`` and
|
|
666
|
+
``self``
|
|
667
|
+
|
|
668
|
+
TESTS::
|
|
669
|
+
|
|
670
|
+
sage: M = Manifold(2, 'M') # the 2-dimensional sphere S^2
|
|
671
|
+
sage: U = M.open_subset('U') # complement of the North pole
|
|
672
|
+
sage: c_xy.<x,y> = U.chart() # stereographic coordinates from the North pole
|
|
673
|
+
sage: V = M.open_subset('V') # complement of the South pole
|
|
674
|
+
sage: c_uv.<u,v> = V.chart() # stereographic coordinates from the South pole
|
|
675
|
+
sage: M.declare_union(U,V) # S^2 is the union of U and V
|
|
676
|
+
sage: xy_to_uv = c_xy.transition_map(c_uv, (x/(x^2+y^2), y/(x^2+y^2)),
|
|
677
|
+
....: intersection_name='W', restrictions1= x^2+y^2!=0,
|
|
678
|
+
....: restrictions2= u^2+v^2!=0)
|
|
679
|
+
sage: uv_to_xy = xy_to_uv.inverse()
|
|
680
|
+
sage: e_xy = c_xy.frame(); e_uv = c_uv.frame()
|
|
681
|
+
sage: a = M.automorphism_field({e_xy: [[-1, 0], [0, 1]]}, name='a')
|
|
682
|
+
sage: a.add_comp_by_continuation(e_uv, U.intersection(V), c_uv)
|
|
683
|
+
sage: b = M.automorphism_field({e_uv: [[1, 0], [0, -2]]}, name='b')
|
|
684
|
+
sage: b.add_comp_by_continuation(e_xy, U.intersection(V), c_xy)
|
|
685
|
+
sage: s = a._mul_(b); s
|
|
686
|
+
Field of tangent-space automorphisms on the 2-dimensional
|
|
687
|
+
differentiable manifold M
|
|
688
|
+
sage: s.display(e_xy)
|
|
689
|
+
-(x^4 - 10*x^2*y^2 + y^4)/(x^4 + 2*x^2*y^2 + y^4) ∂/∂x⊗dx
|
|
690
|
+
- 6*(x^3*y - x*y^3)/(x^4 + 2*x^2*y^2 + y^4) ∂/∂x⊗dy
|
|
691
|
+
+ 6*(x^3*y - x*y^3)/(x^4 + 2*x^2*y^2 + y^4) ∂/∂y⊗dx
|
|
692
|
+
- 2*(x^4 - 4*x^2*y^2 + y^4)/(x^4 + 2*x^2*y^2 + y^4) ∂/∂y⊗dy
|
|
693
|
+
sage: s.display(e_uv)
|
|
694
|
+
-(u^4 - 6*u^2*v^2 + v^4)/(u^4 + 2*u^2*v^2 + v^4) ∂/∂u⊗du
|
|
695
|
+
+ 8*(u^3*v - u*v^3)/(u^4 + 2*u^2*v^2 + v^4) ∂/∂u⊗dv
|
|
696
|
+
- 4*(u^3*v - u*v^3)/(u^4 + 2*u^2*v^2 + v^4) ∂/∂v⊗du
|
|
697
|
+
- 2*(u^4 - 6*u^2*v^2 + v^4)/(u^4 + 2*u^2*v^2 + v^4) ∂/∂v⊗dv
|
|
698
|
+
sage: w = M.vector_field(name='w')
|
|
699
|
+
sage: w[e_xy, :] = [3, 1]
|
|
700
|
+
sage: w.add_comp_by_continuation(e_uv, U.intersection(V), c_uv)
|
|
701
|
+
sage: s(w) == a(b(w)) # long time
|
|
702
|
+
True
|
|
703
|
+
"""
|
|
704
|
+
# No need for consistency check since self and other are guaranteed
|
|
705
|
+
# to have the same parent. In particular, they are defined on the same
|
|
706
|
+
# module.
|
|
707
|
+
#
|
|
708
|
+
# Special cases:
|
|
709
|
+
if self._is_identity:
|
|
710
|
+
return other
|
|
711
|
+
if other._is_identity:
|
|
712
|
+
return self
|
|
713
|
+
if other is self._inverse or self is other._inverse:
|
|
714
|
+
return self.parent().one()
|
|
715
|
+
# General case:
|
|
716
|
+
resu = type(self)(self._vmodule)
|
|
717
|
+
for dom in self._common_subdomains(other):
|
|
718
|
+
resu._restrictions[dom] = (self._restrictions[dom]
|
|
719
|
+
* other._restrictions[dom])
|
|
720
|
+
return resu
|
|
721
|
+
|
|
722
|
+
#### End of MultiplicativeGroupElement methods ####
|
|
723
|
+
|
|
724
|
+
def __mul__(self, other):
|
|
725
|
+
r"""
|
|
726
|
+
Redefinition of
|
|
727
|
+
:meth:`~sage.manifolds.differentiable.tensorfield.TensorField.__mul__`
|
|
728
|
+
so that ``*`` dispatches either to automorphism composition or
|
|
729
|
+
to the tensor product.
|
|
730
|
+
|
|
731
|
+
TESTS::
|
|
732
|
+
|
|
733
|
+
sage: M = Manifold(2, 'M') # the 2-dimensional sphere S^2
|
|
734
|
+
sage: U = M.open_subset('U') # complement of the North pole
|
|
735
|
+
sage: c_xy.<x,y> = U.chart() # stereographic coordinates from the North pole
|
|
736
|
+
sage: V = M.open_subset('V') # complement of the South pole
|
|
737
|
+
sage: c_uv.<u,v> = V.chart() # stereographic coordinates from the South pole
|
|
738
|
+
sage: M.declare_union(U,V) # S^2 is the union of U and V
|
|
739
|
+
sage: xy_to_uv = c_xy.transition_map(c_uv, (x/(x^2+y^2), y/(x^2+y^2)),
|
|
740
|
+
....: intersection_name='W', restrictions1= x^2+y^2!=0,
|
|
741
|
+
....: restrictions2= u^2+v^2!=0)
|
|
742
|
+
sage: uv_to_xy = xy_to_uv.inverse()
|
|
743
|
+
sage: e_xy = c_xy.frame(); e_uv = c_uv.frame()
|
|
744
|
+
sage: a = M.automorphism_field(name='a')
|
|
745
|
+
sage: a[e_xy, :] = [[-1, 0], [0, 1]]
|
|
746
|
+
sage: a.add_comp_by_continuation(e_uv, U.intersection(V), c_uv)
|
|
747
|
+
sage: b = M.automorphism_field(name='b')
|
|
748
|
+
sage: b[e_uv, :] = [[1, 0], [0, -2]]
|
|
749
|
+
sage: b.add_comp_by_continuation(e_xy, U.intersection(V), c_xy)
|
|
750
|
+
sage: w = M.vector_field(name='w')
|
|
751
|
+
sage: w[e_xy, :] = [3, 1]
|
|
752
|
+
sage: w.add_comp_by_continuation(e_uv, U.intersection(V), c_uv)
|
|
753
|
+
sage: s = a.__mul__(b); s # automorphism composition
|
|
754
|
+
Field of tangent-space automorphisms on the 2-dimensional differentiable manifold M
|
|
755
|
+
sage: s(w) == a(b(w)) # long time
|
|
756
|
+
True
|
|
757
|
+
sage: s = a.__mul__(w); s # tensor product
|
|
758
|
+
Tensor field of type (2,1) on the 2-dimensional differentiable manifold M
|
|
759
|
+
"""
|
|
760
|
+
if isinstance(other, AutomorphismField):
|
|
761
|
+
return self._mul_(other) # general linear group law
|
|
762
|
+
else:
|
|
763
|
+
return TensorField.__mul__(self, other) # tensor product
|
|
764
|
+
|
|
765
|
+
def __imul__(self, other):
|
|
766
|
+
r"""
|
|
767
|
+
Redefinition of
|
|
768
|
+
:meth:`~sage.manifolds.differentiable.tensorfield.TensorField.__imul__`
|
|
769
|
+
|
|
770
|
+
TESTS::
|
|
771
|
+
|
|
772
|
+
sage: M = Manifold(2, 'M') # the 2-dimensional sphere S^2
|
|
773
|
+
sage: U = M.open_subset('U') # complement of the North pole
|
|
774
|
+
sage: c_xy.<x,y> = U.chart() # stereographic coordinates from the North pole
|
|
775
|
+
sage: V = M.open_subset('V') # complement of the South pole
|
|
776
|
+
sage: c_uv.<u,v> = V.chart() # stereographic coordinates from the South pole
|
|
777
|
+
sage: M.declare_union(U,V) # S^2 is the union of U and V
|
|
778
|
+
sage: xy_to_uv = c_xy.transition_map(c_uv, (x/(x^2+y^2), y/(x^2+y^2)),
|
|
779
|
+
....: intersection_name='W', restrictions1= x^2+y^2!=0,
|
|
780
|
+
....: restrictions2= u^2+v^2!=0)
|
|
781
|
+
sage: uv_to_xy = xy_to_uv.inverse()
|
|
782
|
+
sage: e_xy = c_xy.frame(); e_uv = c_uv.frame()
|
|
783
|
+
sage: a = M.automorphism_field(name='a')
|
|
784
|
+
sage: a[e_xy, :] = [[-1, 0], [0, 1]]
|
|
785
|
+
sage: a.add_comp_by_continuation(e_uv, U.intersection(V), c_uv)
|
|
786
|
+
sage: b = M.automorphism_field(name='b')
|
|
787
|
+
sage: b[e_uv, :] = [[1, 0], [0, -2]]
|
|
788
|
+
sage: b.add_comp_by_continuation(e_xy, U.intersection(V), c_xy)
|
|
789
|
+
sage: a.__imul__(b)
|
|
790
|
+
Field of tangent-space automorphisms on the 2-dimensional differentiable manifold M
|
|
791
|
+
sage: s = a*b
|
|
792
|
+
sage: a *= b
|
|
793
|
+
sage: a == s
|
|
794
|
+
True
|
|
795
|
+
"""
|
|
796
|
+
return self.__mul__(other)
|
|
797
|
+
|
|
798
|
+
def restrict(self, subdomain, dest_map=None):
|
|
799
|
+
r"""
|
|
800
|
+
Return the restriction of ``self`` to some subdomain.
|
|
801
|
+
|
|
802
|
+
This is a redefinition of
|
|
803
|
+
:meth:`sage.manifolds.differentiable.tensorfield.TensorField.restrict`
|
|
804
|
+
to take into account the identity map.
|
|
805
|
+
|
|
806
|
+
INPUT:
|
|
807
|
+
|
|
808
|
+
- ``subdomain`` --
|
|
809
|
+
:class:`~sage.manifolds.differentiable.manifold.DifferentiableManifold`
|
|
810
|
+
open subset `V` of ``self._domain``
|
|
811
|
+
- ``dest_map`` -- (default: ``None``)
|
|
812
|
+
:class:`~sage.manifolds.differentiable.diff_map.DiffMap`;
|
|
813
|
+
destination map `\Phi:\ V \rightarrow N`, where `N` is a
|
|
814
|
+
subdomain of ``self._codomain``; if ``None``, the restriction
|
|
815
|
+
of ``self.base_module().destination_map()`` to `V` is used
|
|
816
|
+
|
|
817
|
+
OUTPUT: a :class:`AutomorphismField` representing the restriction
|
|
818
|
+
|
|
819
|
+
EXAMPLES:
|
|
820
|
+
|
|
821
|
+
Restrictions of an automorphism field on the 2-sphere::
|
|
822
|
+
|
|
823
|
+
sage: M = Manifold(2, 'S^2', start_index=1)
|
|
824
|
+
sage: U = M.open_subset('U') # the complement of the North pole
|
|
825
|
+
sage: stereoN.<x,y> = U.chart() # stereographic coordinates from the North pole
|
|
826
|
+
sage: eN = stereoN.frame() # the associated vector frame
|
|
827
|
+
sage: V = M.open_subset('V') # the complement of the South pole
|
|
828
|
+
sage: stereoS.<u,v> = V.chart() # stereographic coordinates from the South pole
|
|
829
|
+
sage: eS = stereoS.frame() # the associated vector frame
|
|
830
|
+
sage: transf = stereoN.transition_map(stereoS, (x/(x^2+y^2), y/(x^2+y^2)),
|
|
831
|
+
....: intersection_name='W',
|
|
832
|
+
....: restrictions1= x^2+y^2!=0,
|
|
833
|
+
....: restrictions2= u^2+v^2!=0)
|
|
834
|
+
sage: inv = transf.inverse() # transformation from stereoS to stereoN
|
|
835
|
+
sage: W = U.intersection(V) # the complement of the North and South poles
|
|
836
|
+
sage: stereoN_W = W.atlas()[0] # restriction of stereo. coord. from North pole to W
|
|
837
|
+
sage: stereoS_W = W.atlas()[1] # restriction of stereo. coord. from South pole to W
|
|
838
|
+
sage: eN_W = stereoN_W.frame() ; eS_W = stereoS_W.frame()
|
|
839
|
+
sage: a = M.automorphism_field({eN: [[1, atan(x^2+y^2)], [0,3]]},
|
|
840
|
+
....: name='a')
|
|
841
|
+
sage: a.add_comp_by_continuation(eS, W, chart=stereoS); a
|
|
842
|
+
Field of tangent-space automorphisms a on the 2-dimensional
|
|
843
|
+
differentiable manifold S^2
|
|
844
|
+
sage: a.restrict(U)
|
|
845
|
+
Field of tangent-space automorphisms a on the Open subset U of the
|
|
846
|
+
2-dimensional differentiable manifold S^2
|
|
847
|
+
sage: a.restrict(U)[eN,:]
|
|
848
|
+
[ 1 arctan(x^2 + y^2)]
|
|
849
|
+
[ 0 3]
|
|
850
|
+
sage: a.restrict(V)
|
|
851
|
+
Field of tangent-space automorphisms a on the Open subset V of the
|
|
852
|
+
2-dimensional differentiable manifold S^2
|
|
853
|
+
sage: a.restrict(V)[eS,:]
|
|
854
|
+
[ (u^4 + 10*u^2*v^2 + v^4 + 2*(u^3*v - u*v^3)*arctan(1/(u^2 + v^2)))/(u^4 + 2*u^2*v^2 + v^4) -(4*u^3*v - 4*u*v^3 + (u^4 - 2*u^2*v^2 + v^4)*arctan(1/(u^2 + v^2)))/(u^4 + 2*u^2*v^2 + v^4)]
|
|
855
|
+
[ 4*(u^2*v^2*arctan(1/(u^2 + v^2)) - u^3*v + u*v^3)/(u^4 + 2*u^2*v^2 + v^4) (3*u^4 - 2*u^2*v^2 + 3*v^4 - 2*(u^3*v - u*v^3)*arctan(1/(u^2 + v^2)))/(u^4 + 2*u^2*v^2 + v^4)]
|
|
856
|
+
sage: a.restrict(W)
|
|
857
|
+
Field of tangent-space automorphisms a on the Open subset W of the
|
|
858
|
+
2-dimensional differentiable manifold S^2
|
|
859
|
+
sage: a.restrict(W)[eN_W,:]
|
|
860
|
+
[ 1 arctan(x^2 + y^2)]
|
|
861
|
+
[ 0 3]
|
|
862
|
+
|
|
863
|
+
Restrictions of the field of tangent-space identity maps::
|
|
864
|
+
|
|
865
|
+
sage: id = M.tangent_identity_field() ; id
|
|
866
|
+
Field of tangent-space identity maps on the 2-dimensional
|
|
867
|
+
differentiable manifold S^2
|
|
868
|
+
sage: id.restrict(U)
|
|
869
|
+
Field of tangent-space identity maps on the Open subset U of the
|
|
870
|
+
2-dimensional differentiable manifold S^2
|
|
871
|
+
sage: id.restrict(U)[eN,:]
|
|
872
|
+
[1 0]
|
|
873
|
+
[0 1]
|
|
874
|
+
sage: id.restrict(V)
|
|
875
|
+
Field of tangent-space identity maps on the Open subset V of the
|
|
876
|
+
2-dimensional differentiable manifold S^2
|
|
877
|
+
sage: id.restrict(V)[eS,:]
|
|
878
|
+
[1 0]
|
|
879
|
+
[0 1]
|
|
880
|
+
sage: id.restrict(W)[eN_W,:]
|
|
881
|
+
[1 0]
|
|
882
|
+
[0 1]
|
|
883
|
+
sage: id.restrict(W)[eS_W,:]
|
|
884
|
+
[1 0]
|
|
885
|
+
[0 1]
|
|
886
|
+
"""
|
|
887
|
+
if subdomain == self._domain:
|
|
888
|
+
return self
|
|
889
|
+
if subdomain not in self._restrictions:
|
|
890
|
+
if self is not self.parent().one():
|
|
891
|
+
return TensorField.restrict(self, subdomain, dest_map=dest_map)
|
|
892
|
+
# Special case of the immutable identity map:
|
|
893
|
+
if not subdomain.is_subset(self._domain):
|
|
894
|
+
raise ValueError("the provided domain is not a subset of " +
|
|
895
|
+
"the field's domain")
|
|
896
|
+
if dest_map is None:
|
|
897
|
+
dest_map = self._vmodule._dest_map.restrict(subdomain)
|
|
898
|
+
elif not dest_map._codomain.is_subset(self._ambient_domain):
|
|
899
|
+
raise ValueError("the argument 'dest_map' is not compatible " +
|
|
900
|
+
"with the ambient domain of " +
|
|
901
|
+
"the {}".format(self))
|
|
902
|
+
smodule = subdomain.vector_field_module(dest_map=dest_map)
|
|
903
|
+
self._restrictions[subdomain] = smodule.identity_map()
|
|
904
|
+
return self._restrictions[subdomain]
|
|
905
|
+
|
|
906
|
+
|
|
907
|
+
#******************************************************************************
|
|
908
|
+
|
|
909
|
+
class AutomorphismFieldParal(FreeModuleAutomorphism, TensorFieldParal):
|
|
910
|
+
r"""
|
|
911
|
+
Field of tangent-space automorphisms with values on a parallelizable
|
|
912
|
+
manifold.
|
|
913
|
+
|
|
914
|
+
Given a differentiable manifold `U` and a differentiable map
|
|
915
|
+
`\Phi: U \rightarrow M` to a parallelizable manifold `M`,
|
|
916
|
+
a *field of tangent-space automorphisms along* `U` *with values on*
|
|
917
|
+
`M\supset\Phi(U)` is a differentiable map
|
|
918
|
+
|
|
919
|
+
.. MATH::
|
|
920
|
+
|
|
921
|
+
a:\ U \longrightarrow T^{(1,1)}M
|
|
922
|
+
|
|
923
|
+
(`T^{(1,1)}M` being the tensor bundle of type `(1,1)` over `M`) such
|
|
924
|
+
that
|
|
925
|
+
|
|
926
|
+
.. MATH::
|
|
927
|
+
|
|
928
|
+
\forall p \in U,\ a(p) \in \mathrm{Aut}(T_{\Phi(p)} M)
|
|
929
|
+
|
|
930
|
+
i.e. `a(p)` is an automorphism of the tangent space to `M` at the point
|
|
931
|
+
`\Phi(p)`.
|
|
932
|
+
|
|
933
|
+
The standard case of a field of tangent-space automorphisms *on* a
|
|
934
|
+
manifold corresponds to `U=M` and `\Phi = \mathrm{Id}_M`. Other
|
|
935
|
+
common cases are `\Phi` being an immersion and `\Phi` being a curve in `M`
|
|
936
|
+
(`U` is then an open interval of `\RR`).
|
|
937
|
+
|
|
938
|
+
.. NOTE::
|
|
939
|
+
|
|
940
|
+
If `M` is not parallelizable, the class :class:`AutomorphismField`
|
|
941
|
+
*must* be used instead.
|
|
942
|
+
|
|
943
|
+
INPUT:
|
|
944
|
+
|
|
945
|
+
- ``vector_field_module`` -- free module `\mathfrak{X}(U,\Phi)` of vector
|
|
946
|
+
fields along `U` with values on `M` via the map `\Phi`
|
|
947
|
+
- ``name`` -- (default: ``None``) name given to the field
|
|
948
|
+
- ``latex_name`` -- (default: ``None``) LaTeX symbol to denote the field;
|
|
949
|
+
if none is provided, the LaTeX symbol is set to ``name``
|
|
950
|
+
|
|
951
|
+
EXAMPLES:
|
|
952
|
+
|
|
953
|
+
A `\pi/3`-rotation in the Euclidean 2-plane::
|
|
954
|
+
|
|
955
|
+
sage: M = Manifold(2, 'R^2')
|
|
956
|
+
sage: c_xy.<x,y> = M.chart()
|
|
957
|
+
sage: rot = M.automorphism_field([[sqrt(3)/2, -1/2], [1/2, sqrt(3)/2]],
|
|
958
|
+
....: name='R'); rot
|
|
959
|
+
Field of tangent-space automorphisms R on the 2-dimensional
|
|
960
|
+
differentiable manifold R^2
|
|
961
|
+
sage: rot.parent()
|
|
962
|
+
General linear group of the Free module X(R^2) of vector fields on the
|
|
963
|
+
2-dimensional differentiable manifold R^2
|
|
964
|
+
|
|
965
|
+
The inverse automorphism is obtained via the method :meth:`inverse`::
|
|
966
|
+
|
|
967
|
+
sage: inv = rot.inverse() ; inv
|
|
968
|
+
Field of tangent-space automorphisms R^(-1) on the 2-dimensional
|
|
969
|
+
differentiable manifold R^2
|
|
970
|
+
sage: latex(inv)
|
|
971
|
+
R^{-1}
|
|
972
|
+
sage: inv[:]
|
|
973
|
+
[1/2*sqrt(3) 1/2]
|
|
974
|
+
[ -1/2 1/2*sqrt(3)]
|
|
975
|
+
sage: rot[:]
|
|
976
|
+
[1/2*sqrt(3) -1/2]
|
|
977
|
+
[ 1/2 1/2*sqrt(3)]
|
|
978
|
+
sage: inv[:] * rot[:] # check
|
|
979
|
+
[1 0]
|
|
980
|
+
[0 1]
|
|
981
|
+
|
|
982
|
+
Equivalently, one can use the power minus one to get the inverse::
|
|
983
|
+
|
|
984
|
+
sage: inv is rot^(-1)
|
|
985
|
+
True
|
|
986
|
+
|
|
987
|
+
or the operator ``~``::
|
|
988
|
+
|
|
989
|
+
sage: inv is ~rot
|
|
990
|
+
True
|
|
991
|
+
"""
|
|
992
|
+
def __init__(self, vector_field_module, name=None, latex_name=None):
|
|
993
|
+
r"""
|
|
994
|
+
Construct a field of tangent-space automorphisms.
|
|
995
|
+
|
|
996
|
+
TESTS:
|
|
997
|
+
|
|
998
|
+
Construction via ``parent.element_class``, and not via a direct call
|
|
999
|
+
to ``AutomorphismFieldParal``, to fit with the category framework::
|
|
1000
|
+
|
|
1001
|
+
sage: M = Manifold(2, 'M')
|
|
1002
|
+
sage: X.<x,y> = M.chart() # makes M parallelizable
|
|
1003
|
+
sage: XM = M.vector_field_module()
|
|
1004
|
+
sage: GL = XM.general_linear_group()
|
|
1005
|
+
sage: a = GL.element_class(XM, name='a'); a
|
|
1006
|
+
Field of tangent-space automorphisms a on the 2-dimensional
|
|
1007
|
+
differentiable manifold M
|
|
1008
|
+
sage: a[:] = [[1+x^2, x*y], [0, 1+y^2]]
|
|
1009
|
+
sage: a.parent()
|
|
1010
|
+
General linear group of the Free module X(M) of vector fields on
|
|
1011
|
+
the 2-dimensional differentiable manifold M
|
|
1012
|
+
sage: a.parent() is M.automorphism_field_group()
|
|
1013
|
+
True
|
|
1014
|
+
sage: TestSuite(a).run()
|
|
1015
|
+
|
|
1016
|
+
Construction of the field of identity maps::
|
|
1017
|
+
|
|
1018
|
+
sage: b = GL.one(); b
|
|
1019
|
+
Field of tangent-space identity maps on the 2-dimensional
|
|
1020
|
+
differentiable manifold M
|
|
1021
|
+
sage: b[:]
|
|
1022
|
+
[1 0]
|
|
1023
|
+
[0 1]
|
|
1024
|
+
sage: TestSuite(b).run()
|
|
1025
|
+
"""
|
|
1026
|
+
FreeModuleAutomorphism.__init__(self, vector_field_module,
|
|
1027
|
+
name=name, latex_name=latex_name)
|
|
1028
|
+
# TensorFieldParal attributes:
|
|
1029
|
+
self._vmodule = vector_field_module
|
|
1030
|
+
self._domain = vector_field_module._domain
|
|
1031
|
+
self._ambient_domain = vector_field_module._ambient_domain
|
|
1032
|
+
self._is_identity = False # a priori
|
|
1033
|
+
# Initialization of derived quantities:
|
|
1034
|
+
TensorFieldParal._init_derived(self)
|
|
1035
|
+
|
|
1036
|
+
def _repr_(self):
|
|
1037
|
+
r"""
|
|
1038
|
+
Return a string representation of ``self``.
|
|
1039
|
+
|
|
1040
|
+
TESTS::
|
|
1041
|
+
|
|
1042
|
+
sage: M = Manifold(2, 'M')
|
|
1043
|
+
sage: X.<x,y> = M.chart()
|
|
1044
|
+
sage: a = M.automorphism_field(name='a')
|
|
1045
|
+
sage: a._repr_()
|
|
1046
|
+
'Field of tangent-space automorphisms a on the 2-dimensional differentiable manifold M'
|
|
1047
|
+
sage: repr(a) # indirect doctest
|
|
1048
|
+
'Field of tangent-space automorphisms a on the 2-dimensional differentiable manifold M'
|
|
1049
|
+
sage: a # indirect doctest
|
|
1050
|
+
Field of tangent-space automorphisms a on the 2-dimensional
|
|
1051
|
+
differentiable manifold M
|
|
1052
|
+
"""
|
|
1053
|
+
description = "Field of tangent-space "
|
|
1054
|
+
if self is self.parent().one():
|
|
1055
|
+
description += "identity maps "
|
|
1056
|
+
else:
|
|
1057
|
+
description += "automorphisms "
|
|
1058
|
+
if self._name is not None:
|
|
1059
|
+
description += self._name + " "
|
|
1060
|
+
return self._final_repr(description)
|
|
1061
|
+
|
|
1062
|
+
def _del_derived(self, del_restrictions=True):
|
|
1063
|
+
r"""
|
|
1064
|
+
Delete the derived quantities.
|
|
1065
|
+
|
|
1066
|
+
INPUT:
|
|
1067
|
+
|
|
1068
|
+
- ``del_restrictions`` -- boolean (default: ``True``); determines whether the
|
|
1069
|
+
restrictions of ``self`` to subdomains are deleted
|
|
1070
|
+
|
|
1071
|
+
TESTS::
|
|
1072
|
+
|
|
1073
|
+
sage: M = Manifold(2, 'M')
|
|
1074
|
+
sage: X.<x,y> = M.chart()
|
|
1075
|
+
sage: a = M.automorphism_field(name='a')
|
|
1076
|
+
sage: a._del_derived()
|
|
1077
|
+
"""
|
|
1078
|
+
# Delete the derived quantities pertaining to the mother classes:
|
|
1079
|
+
FreeModuleAutomorphism._del_derived(self)
|
|
1080
|
+
TensorFieldParal._del_derived(self, del_restrictions=del_restrictions)
|
|
1081
|
+
|
|
1082
|
+
# Method _new_instance() is defined in mother class FreeModuleAutomorphism
|
|
1083
|
+
|
|
1084
|
+
def __call__(self, *arg):
|
|
1085
|
+
r"""
|
|
1086
|
+
Redefinition of
|
|
1087
|
+
:meth:`~sage.tensor.modules.free_module_automorphism.FreeModuleAutomorphism.__call__`
|
|
1088
|
+
to allow for domain treatment.
|
|
1089
|
+
|
|
1090
|
+
TESTS::
|
|
1091
|
+
|
|
1092
|
+
sage: M = Manifold(2, 'M')
|
|
1093
|
+
sage: X.<x,y> = M.chart()
|
|
1094
|
+
sage: a = M.automorphism_field([[0, 1], [-1, 0]], name='a')
|
|
1095
|
+
sage: v = M.vector_field(-y, x, name='v')
|
|
1096
|
+
sage: z = M.one_form(1+y^2, x*y, name='z')
|
|
1097
|
+
sage: s = a.__call__(v); s
|
|
1098
|
+
Vector field a(v) on the 2-dimensional differentiable manifold M
|
|
1099
|
+
sage: s.display()
|
|
1100
|
+
a(v) = x ∂/∂x + y ∂/∂y
|
|
1101
|
+
sage: s = a.__call__(z, v); s
|
|
1102
|
+
Scalar field a(z,v) on the 2-dimensional differentiable manifold M
|
|
1103
|
+
sage: s.display()
|
|
1104
|
+
a(z,v): M → ℝ
|
|
1105
|
+
(x, y) ↦ 2*x*y^2 + x
|
|
1106
|
+
sage: U = M.open_subset('U', coord_def={X: x>0})
|
|
1107
|
+
sage: s = a.__call__(v.restrict(U)); s
|
|
1108
|
+
Vector field a(v) on the Open subset U of the 2-dimensional
|
|
1109
|
+
differentiable manifold M
|
|
1110
|
+
sage: s = a.__call__(z.restrict(U), v); s
|
|
1111
|
+
Scalar field a(z,v) on the Open subset U of the 2-dimensional
|
|
1112
|
+
differentiable manifold M
|
|
1113
|
+
sage: s.display()
|
|
1114
|
+
a(z,v): U → ℝ
|
|
1115
|
+
(x, y) ↦ 2*x*y^2 + x
|
|
1116
|
+
"""
|
|
1117
|
+
if len(arg) == 1:
|
|
1118
|
+
# the automorphism acting as such (map of a vector field to a
|
|
1119
|
+
# vector field)
|
|
1120
|
+
vector = arg[0]
|
|
1121
|
+
dom = self._domain.intersection(vector._domain)
|
|
1122
|
+
return FreeModuleAutomorphism.__call__(self.restrict(dom),
|
|
1123
|
+
vector.restrict(dom))
|
|
1124
|
+
elif len(arg) == 2:
|
|
1125
|
+
# the automorphism acting as a type (1,1) tensor on a pair
|
|
1126
|
+
# (1-form, vector field), returning a scalar field:
|
|
1127
|
+
oneform = arg[0]
|
|
1128
|
+
vector = arg[1]
|
|
1129
|
+
dom = self._domain.intersection(oneform._domain).intersection(
|
|
1130
|
+
vector._domain)
|
|
1131
|
+
return FreeModuleAutomorphism.__call__(self.restrict(dom),
|
|
1132
|
+
oneform.restrict(dom),
|
|
1133
|
+
vector.restrict(dom))
|
|
1134
|
+
else:
|
|
1135
|
+
raise TypeError("wrong number of arguments")
|
|
1136
|
+
|
|
1137
|
+
def __invert__(self):
|
|
1138
|
+
r"""
|
|
1139
|
+
Return the inverse automorphism of ``self``.
|
|
1140
|
+
|
|
1141
|
+
EXAMPLES::
|
|
1142
|
+
|
|
1143
|
+
sage: M = Manifold(2, 'M')
|
|
1144
|
+
sage: X.<x,y> = M.chart()
|
|
1145
|
+
sage: a = M.automorphism_field([[0, 2], [-1, 0]], name='a')
|
|
1146
|
+
sage: b = a.inverse(); b
|
|
1147
|
+
Field of tangent-space automorphisms a^(-1) on the 2-dimensional
|
|
1148
|
+
differentiable manifold M
|
|
1149
|
+
sage: b[:]
|
|
1150
|
+
[ 0 -1]
|
|
1151
|
+
[1/2 0]
|
|
1152
|
+
sage: a[:]
|
|
1153
|
+
[ 0 2]
|
|
1154
|
+
[-1 0]
|
|
1155
|
+
|
|
1156
|
+
The result is cached::
|
|
1157
|
+
|
|
1158
|
+
sage: a.inverse() is b
|
|
1159
|
+
True
|
|
1160
|
+
|
|
1161
|
+
Instead of ``inverse()``, one can use the power minus one to get the
|
|
1162
|
+
inverse::
|
|
1163
|
+
|
|
1164
|
+
sage: b is a^(-1)
|
|
1165
|
+
True
|
|
1166
|
+
|
|
1167
|
+
or the operator ``~``::
|
|
1168
|
+
|
|
1169
|
+
sage: b is ~a
|
|
1170
|
+
True
|
|
1171
|
+
"""
|
|
1172
|
+
from sage.manifolds.differentiable.vectorframe import CoordFrame
|
|
1173
|
+
from sage.matrix.constructor import matrix
|
|
1174
|
+
from sage.tensor.modules.comp import Components
|
|
1175
|
+
if self._is_identity:
|
|
1176
|
+
return self
|
|
1177
|
+
if self._inverse is None:
|
|
1178
|
+
from sage.tensor.modules.format_utilities import is_atomic
|
|
1179
|
+
if self._name is None:
|
|
1180
|
+
inv_name = None
|
|
1181
|
+
else:
|
|
1182
|
+
if is_atomic(self._name, ['*']):
|
|
1183
|
+
inv_name = self._name + '^(-1)'
|
|
1184
|
+
else:
|
|
1185
|
+
inv_name = '(' + self._name + ')^(-1)'
|
|
1186
|
+
if self._latex_name is None:
|
|
1187
|
+
inv_latex_name = None
|
|
1188
|
+
else:
|
|
1189
|
+
if is_atomic(self._latex_name, ['\\circ', '\\otimes']):
|
|
1190
|
+
inv_latex_name = self._latex_name + r'^{-1}'
|
|
1191
|
+
else:
|
|
1192
|
+
inv_latex_name = r'\left(' + self._latex_name + \
|
|
1193
|
+
r'\right)^{-1}'
|
|
1194
|
+
fmodule = self._fmodule
|
|
1195
|
+
si = fmodule._sindex
|
|
1196
|
+
nsi = fmodule._rank + si
|
|
1197
|
+
self._inverse = fmodule.automorphism(name=inv_name,
|
|
1198
|
+
latex_name=inv_latex_name)
|
|
1199
|
+
for frame in self._components:
|
|
1200
|
+
if isinstance(frame, CoordFrame):
|
|
1201
|
+
chart = frame._chart
|
|
1202
|
+
else:
|
|
1203
|
+
chart = self._domain._def_chart # ! # to be improved
|
|
1204
|
+
try:
|
|
1205
|
+
# TODO: do the computation without the 'SR' enforcement
|
|
1206
|
+
mat_self = matrix(
|
|
1207
|
+
[[self.comp(frame)[i, j, chart].expr(method='SR')
|
|
1208
|
+
for j in range(si, nsi)] for i in range(si, nsi)])
|
|
1209
|
+
except (KeyError, ValueError):
|
|
1210
|
+
continue
|
|
1211
|
+
mat_inv = mat_self.inverse()
|
|
1212
|
+
cinv = Components(fmodule._ring, frame, 2, start_index=si,
|
|
1213
|
+
output_formatter=fmodule._output_formatter)
|
|
1214
|
+
for i in range(si, nsi):
|
|
1215
|
+
for j in range(si, nsi):
|
|
1216
|
+
val = chart.simplify(mat_inv[i-si,j-si], method='SR')
|
|
1217
|
+
cinv[i, j] = {chart: val}
|
|
1218
|
+
self._inverse._components[frame] = cinv
|
|
1219
|
+
return self._inverse
|
|
1220
|
+
|
|
1221
|
+
inverse = __invert__
|
|
1222
|
+
|
|
1223
|
+
def restrict(self, subdomain, dest_map=None):
|
|
1224
|
+
r"""
|
|
1225
|
+
Return the restriction of ``self`` to some subset of its domain.
|
|
1226
|
+
|
|
1227
|
+
If such restriction has not been defined yet, it is constructed here.
|
|
1228
|
+
|
|
1229
|
+
This is a redefinition of
|
|
1230
|
+
:meth:`sage.manifolds.differentiable.tensorfield_paral.TensorFieldParal.restrict`
|
|
1231
|
+
to take into account the identity map.
|
|
1232
|
+
|
|
1233
|
+
INPUT:
|
|
1234
|
+
|
|
1235
|
+
- ``subdomain`` --
|
|
1236
|
+
:class:`~sage.manifolds.differentiable.manifold.DifferentiableManifold`;
|
|
1237
|
+
open subset `V` of ``self._domain``
|
|
1238
|
+
- ``dest_map`` -- (default: ``None``)
|
|
1239
|
+
:class:`~sage.manifolds.differentiable.diff_map.DiffMap`
|
|
1240
|
+
destination map `\Phi:\ V \rightarrow N`, where `N` is a subset of
|
|
1241
|
+
``self._codomain``; if ``None``, the restriction of
|
|
1242
|
+
``self.base_module().destination_map()`` to `V` is used
|
|
1243
|
+
|
|
1244
|
+
OUTPUT: a :class:`AutomorphismFieldParal` representing the restriction
|
|
1245
|
+
|
|
1246
|
+
EXAMPLES:
|
|
1247
|
+
|
|
1248
|
+
Restriction of an automorphism field defined on `\RR^2` to a disk::
|
|
1249
|
+
|
|
1250
|
+
sage: M = Manifold(2, 'R^2')
|
|
1251
|
+
sage: c_cart.<x,y> = M.chart() # Cartesian coordinates on R^2
|
|
1252
|
+
sage: D = M.open_subset('D') # the unit open disc
|
|
1253
|
+
sage: c_cart_D = c_cart.restrict(D, x^2+y^2<1)
|
|
1254
|
+
sage: a = M.automorphism_field([[1, x*y], [0, 3]], name='a'); a
|
|
1255
|
+
Field of tangent-space automorphisms a on the 2-dimensional
|
|
1256
|
+
differentiable manifold R^2
|
|
1257
|
+
sage: a.restrict(D)
|
|
1258
|
+
Field of tangent-space automorphisms a on the Open subset D of the
|
|
1259
|
+
2-dimensional differentiable manifold R^2
|
|
1260
|
+
sage: a.restrict(D)[:]
|
|
1261
|
+
[ 1 x*y]
|
|
1262
|
+
[ 0 3]
|
|
1263
|
+
|
|
1264
|
+
Restriction to the disk of the field of tangent-space identity maps::
|
|
1265
|
+
|
|
1266
|
+
sage: id = M.tangent_identity_field() ; id
|
|
1267
|
+
Field of tangent-space identity maps on the 2-dimensional
|
|
1268
|
+
differentiable manifold R^2
|
|
1269
|
+
sage: id.restrict(D)
|
|
1270
|
+
Field of tangent-space identity maps on the Open subset D of the
|
|
1271
|
+
2-dimensional differentiable manifold R^2
|
|
1272
|
+
sage: id.restrict(D)[:]
|
|
1273
|
+
[1 0]
|
|
1274
|
+
[0 1]
|
|
1275
|
+
sage: id.restrict(D) == D.tangent_identity_field()
|
|
1276
|
+
True
|
|
1277
|
+
"""
|
|
1278
|
+
if subdomain == self._domain:
|
|
1279
|
+
return self
|
|
1280
|
+
if subdomain not in self._restrictions:
|
|
1281
|
+
if not self._is_identity:
|
|
1282
|
+
return TensorFieldParal.restrict(self, subdomain,
|
|
1283
|
+
dest_map=dest_map)
|
|
1284
|
+
# Special case of the identity map:
|
|
1285
|
+
if not subdomain.is_subset(self._domain):
|
|
1286
|
+
raise ValueError("the provided domain is not a subset of " +
|
|
1287
|
+
"the field's domain.")
|
|
1288
|
+
if dest_map is None:
|
|
1289
|
+
dest_map = self._fmodule._dest_map.restrict(subdomain)
|
|
1290
|
+
elif not dest_map._codomain.is_subset(self._ambient_domain):
|
|
1291
|
+
raise ValueError("the argument 'dest_map' is not compatible " +
|
|
1292
|
+
"with the ambient domain of " +
|
|
1293
|
+
"the {}".format(self))
|
|
1294
|
+
smodule = subdomain.vector_field_module(dest_map=dest_map)
|
|
1295
|
+
self._restrictions[subdomain] = smodule.identity_map()
|
|
1296
|
+
return self._restrictions[subdomain]
|
|
1297
|
+
|
|
1298
|
+
def at(self, point):
|
|
1299
|
+
r"""
|
|
1300
|
+
Value of ``self`` at a given point.
|
|
1301
|
+
|
|
1302
|
+
If the current field of tangent-space automorphisms is
|
|
1303
|
+
|
|
1304
|
+
.. MATH::
|
|
1305
|
+
|
|
1306
|
+
a:\ U \longrightarrow T^{(1,1)} M
|
|
1307
|
+
|
|
1308
|
+
associated with the differentiable map
|
|
1309
|
+
|
|
1310
|
+
.. MATH::
|
|
1311
|
+
|
|
1312
|
+
\Phi:\ U \longrightarrow M,
|
|
1313
|
+
|
|
1314
|
+
where `U` and `M` are two manifolds (possibly `U = M` and
|
|
1315
|
+
`\Phi = \mathrm{Id}_M`), then for any point `p \in U`,
|
|
1316
|
+
`a(p)` is an automorphism of the tangent space `T_{\Phi(p)}M`.
|
|
1317
|
+
|
|
1318
|
+
INPUT:
|
|
1319
|
+
|
|
1320
|
+
- ``point`` -- :class:`~sage.manifolds.point.ManifoldPoint`;
|
|
1321
|
+
point `p` in the domain of the field of automorphisms `a`
|
|
1322
|
+
|
|
1323
|
+
OUTPUT:
|
|
1324
|
+
|
|
1325
|
+
- the automorphism `a(p)` of the tangent vector space `T_{\Phi(p)}M`
|
|
1326
|
+
|
|
1327
|
+
EXAMPLES:
|
|
1328
|
+
|
|
1329
|
+
Automorphism at some point of a tangent space of a 2-dimensional
|
|
1330
|
+
manifold::
|
|
1331
|
+
|
|
1332
|
+
sage: M = Manifold(2, 'M')
|
|
1333
|
+
sage: c_xy.<x,y> = M.chart()
|
|
1334
|
+
sage: a = M.automorphism_field([[1+exp(y), x*y], [0, 1+x^2]],
|
|
1335
|
+
....: name='a')
|
|
1336
|
+
sage: a.display()
|
|
1337
|
+
a = (e^y + 1) ∂/∂x⊗dx + x*y ∂/∂x⊗dy + (x^2 + 1) ∂/∂y⊗dy
|
|
1338
|
+
sage: p = M.point((-2,3), name='p') ; p
|
|
1339
|
+
Point p on the 2-dimensional differentiable manifold M
|
|
1340
|
+
sage: ap = a.at(p) ; ap
|
|
1341
|
+
Automorphism a of the Tangent space at Point p on the
|
|
1342
|
+
2-dimensional differentiable manifold M
|
|
1343
|
+
sage: ap.display()
|
|
1344
|
+
a = (e^3 + 1) ∂/∂x⊗dx - 6 ∂/∂x⊗dy + 5 ∂/∂y⊗dy
|
|
1345
|
+
sage: ap.parent()
|
|
1346
|
+
General linear group of the Tangent space at Point p on the
|
|
1347
|
+
2-dimensional differentiable manifold M
|
|
1348
|
+
|
|
1349
|
+
The identity map of the tangent space at point ``p``::
|
|
1350
|
+
|
|
1351
|
+
sage: id = M.tangent_identity_field() ; id
|
|
1352
|
+
Field of tangent-space identity maps on the 2-dimensional
|
|
1353
|
+
differentiable manifold M
|
|
1354
|
+
sage: idp = id.at(p) ; idp
|
|
1355
|
+
Identity map of the Tangent space at Point p on the 2-dimensional
|
|
1356
|
+
differentiable manifold M
|
|
1357
|
+
sage: idp is M.tangent_space(p).identity_map()
|
|
1358
|
+
True
|
|
1359
|
+
sage: idp.display()
|
|
1360
|
+
Id = ∂/∂x⊗dx + ∂/∂y⊗dy
|
|
1361
|
+
sage: idp.parent()
|
|
1362
|
+
General linear group of the Tangent space at Point p on the
|
|
1363
|
+
2-dimensional differentiable manifold M
|
|
1364
|
+
sage: idp * ap == ap
|
|
1365
|
+
True
|
|
1366
|
+
"""
|
|
1367
|
+
if point not in self._domain:
|
|
1368
|
+
raise TypeError("the {} is not in the domain of the {}".format(
|
|
1369
|
+
point, self))
|
|
1370
|
+
dest_map = self._fmodule._dest_map
|
|
1371
|
+
if dest_map.is_identity():
|
|
1372
|
+
amb_point = point
|
|
1373
|
+
else:
|
|
1374
|
+
amb_point = dest_map(point) # "ambient" point
|
|
1375
|
+
ts = amb_point._manifold.tangent_space(amb_point)
|
|
1376
|
+
if self._is_identity:
|
|
1377
|
+
return ts.identity_map()
|
|
1378
|
+
resu = ts.automorphism(name=self._name, latex_name=self._latex_name)
|
|
1379
|
+
for frame, comp in self._components.items():
|
|
1380
|
+
comp_resu = resu.add_comp(frame.at(point))
|
|
1381
|
+
for ind, val in comp._comp.items():
|
|
1382
|
+
comp_resu._comp[ind] = val(point)
|
|
1383
|
+
return resu
|