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,891 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-symbolics
|
|
2
|
+
r"""
|
|
3
|
+
Submanifolds of topological manifolds
|
|
4
|
+
|
|
5
|
+
Given a topological manifold `M` over a topological field `K`, a *topological
|
|
6
|
+
submanifold of* `M` is defined by a topological manifold `N` over the same
|
|
7
|
+
field `K` of dimension lower than the dimension of `M` and a topological
|
|
8
|
+
embedding `\phi` from `N` to `M` (i.e. `\phi` is a homeomorphism onto its
|
|
9
|
+
image).
|
|
10
|
+
|
|
11
|
+
In the case where the map `\phi` is only an embedding locally, it is called an
|
|
12
|
+
*topological immersion*, and defines an *immersed submanifold*.
|
|
13
|
+
|
|
14
|
+
The global embedding property cannot be checked in sage, so the immersed or
|
|
15
|
+
embedded aspect of the manifold must be declared by the user, by calling either
|
|
16
|
+
:meth:`~sage.manifolds.topological_submanifold.TopologicalSubmanifold.set_embedding`
|
|
17
|
+
or
|
|
18
|
+
:meth:`~sage.manifolds.topological_submanifold.TopologicalSubmanifold.set_immersion`
|
|
19
|
+
while declaring the map `\phi`.
|
|
20
|
+
|
|
21
|
+
The map `\phi: N\to M` can also depend on one or multiple parameters. As long
|
|
22
|
+
as `\phi` remains injective in these parameters, it represents a *foliation*.
|
|
23
|
+
The *dimension* of the foliation is defined as the number of parameters.
|
|
24
|
+
|
|
25
|
+
AUTHORS:
|
|
26
|
+
|
|
27
|
+
- Florentin Jaffredo (2018): initial version
|
|
28
|
+
- Eric Gourgoulhon (2018-2019): add documentation
|
|
29
|
+
- Matthias Koeppe (2021): open subsets of submanifolds
|
|
30
|
+
|
|
31
|
+
REFERENCES:
|
|
32
|
+
|
|
33
|
+
- \J. M. Lee: *Introduction to Smooth Manifolds* [Lee2013]_
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
# *****************************************************************************
|
|
38
|
+
# Copyright (C) 2018 Florentin Jaffredo <florentin.jaffredo@polytechnique.edu>
|
|
39
|
+
# Copyright (C) 2018-2019 Eric Gourgoulhon <eric.gourgoulhon@obspm.fr>
|
|
40
|
+
# Copyright (C) 2021 Matthias Koeppe <mkoeppe@math.ucdavis.edu>
|
|
41
|
+
#
|
|
42
|
+
# This program is free software: you can redistribute it and/or modify
|
|
43
|
+
# it under the terms of the GNU General Public License as published by
|
|
44
|
+
# the Free Software Foundation, either version 2 of the License, or
|
|
45
|
+
# (at your option) any later version.
|
|
46
|
+
# http://www.gnu.org/licenses/
|
|
47
|
+
# *****************************************************************************
|
|
48
|
+
|
|
49
|
+
from sage.manifolds.continuous_map import ContinuousMap
|
|
50
|
+
from sage.manifolds.manifold import TopologicalManifold
|
|
51
|
+
from sage.misc.lazy_import import lazy_import
|
|
52
|
+
from sage.symbolic.assumptions import assume, assumptions
|
|
53
|
+
from sage.symbolic.expression import Expression
|
|
54
|
+
|
|
55
|
+
lazy_import("sage.plot.plot3d.parametric_surface", "ParametricSurface")
|
|
56
|
+
|
|
57
|
+
#############################################################################
|
|
58
|
+
# Global options
|
|
59
|
+
|
|
60
|
+
#############################################################################
|
|
61
|
+
# Class
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
class TopologicalSubmanifold(TopologicalManifold):
|
|
65
|
+
r"""
|
|
66
|
+
Submanifold of a topological manifold.
|
|
67
|
+
|
|
68
|
+
Given a topological manifold `M` over a topological field `K`, a
|
|
69
|
+
*topological submanifold of* `M` is defined by a topological manifold `N`
|
|
70
|
+
over the same field `K` of dimension lower than the dimension of `M` and
|
|
71
|
+
a topological embedding `\phi` from `N` to `M` (i.e. `\phi` is an
|
|
72
|
+
homeomorphism onto its image).
|
|
73
|
+
|
|
74
|
+
In the case where `\phi` is only a topological immersion (i.e. is only
|
|
75
|
+
locally an embedding), one says that `N` is an *immersed submanifold*.
|
|
76
|
+
|
|
77
|
+
The map `\phi` can also depend on one or multiple parameters.
|
|
78
|
+
As long as `\phi` remains injective in these parameters, it represents
|
|
79
|
+
a *foliation*. The *dimension* of the foliation is defined as the number of
|
|
80
|
+
parameters.
|
|
81
|
+
|
|
82
|
+
INPUT:
|
|
83
|
+
|
|
84
|
+
- ``n`` -- positive integer; dimension of the submanifold
|
|
85
|
+
- ``name`` -- string; name (symbol) given to the submanifold
|
|
86
|
+
- ``field`` -- field `K` on which the submanifold is defined; allowed
|
|
87
|
+
values are
|
|
88
|
+
|
|
89
|
+
- ``'real'`` or an object of type ``RealField`` (e.g., ``RR``) for
|
|
90
|
+
a manifold over `\RR`
|
|
91
|
+
- ``'complex'`` or an object of type ``ComplexField`` (e.g., ``CC``)
|
|
92
|
+
for a manifold over `\CC`
|
|
93
|
+
- an object in the category of topological fields (see
|
|
94
|
+
:class:`~sage.categories.fields.Fields` and
|
|
95
|
+
:class:`~sage.categories.topological_spaces.TopologicalSpaces`)
|
|
96
|
+
for other types of manifolds
|
|
97
|
+
|
|
98
|
+
- ``structure`` -- manifold structure (see
|
|
99
|
+
:class:`~sage.manifolds.structure.TopologicalStructure` or
|
|
100
|
+
:class:`~sage.manifolds.structure.RealTopologicalStructure`)
|
|
101
|
+
- ``ambient`` -- (default: ``None``) codomain `M` of the immersion `\phi`;
|
|
102
|
+
must be a topological manifold. If ``None``, it is set to ``self``
|
|
103
|
+
- ``base_manifold`` -- (default: ``None``) if not ``None``, must be a
|
|
104
|
+
topological manifold; the created object is then an open subset of
|
|
105
|
+
``base_manifold``
|
|
106
|
+
- ``latex_name`` -- (default: ``None``) string; LaTeX symbol to
|
|
107
|
+
denote the submanifold; if none are provided, it is set to ``name``
|
|
108
|
+
- ``start_index`` -- (default: 0) integer; lower value of the range of
|
|
109
|
+
indices used for "indexed objects" on the submanifold, e.g., coordinates
|
|
110
|
+
in a chart
|
|
111
|
+
- ``category`` -- (default: ``None``) to specify the category; if
|
|
112
|
+
``None``, ``Manifolds(field)`` is assumed (see the category
|
|
113
|
+
:class:`~sage.categories.manifolds.Manifolds`)
|
|
114
|
+
- ``unique_tag`` -- (default: ``None``) tag used to force the construction
|
|
115
|
+
of a new object when all the other arguments have been used previously
|
|
116
|
+
(without ``unique_tag``, the
|
|
117
|
+
:class:`~sage.structure.unique_representation.UniqueRepresentation`
|
|
118
|
+
behavior inherited from
|
|
119
|
+
:class:`~sage.manifolds.subset.ManifoldSubset` via
|
|
120
|
+
:class:`~sage.manifolds.manifold.TopologicalManifold`
|
|
121
|
+
would return the previously constructed object corresponding to these
|
|
122
|
+
arguments)
|
|
123
|
+
|
|
124
|
+
EXAMPLES:
|
|
125
|
+
|
|
126
|
+
Let `N` be a 2-dimensional submanifold of a 3-dimensional manifold `M`::
|
|
127
|
+
|
|
128
|
+
sage: M = Manifold(3, 'M', structure='topological')
|
|
129
|
+
sage: N = Manifold(2, 'N', ambient=M, structure='topological')
|
|
130
|
+
sage: N
|
|
131
|
+
2-dimensional topological submanifold N immersed in the 3-dimensional
|
|
132
|
+
topological manifold M
|
|
133
|
+
sage: CM.<x,y,z> = M.chart()
|
|
134
|
+
sage: CN.<u,v> = N.chart()
|
|
135
|
+
|
|
136
|
+
Let us define a 1-dimensional foliation indexed by `t`::
|
|
137
|
+
|
|
138
|
+
sage: t = var('t')
|
|
139
|
+
sage: phi = N.continuous_map(M, {(CN,CM): [u, v, t+u^2+v^2]})
|
|
140
|
+
sage: phi.display()
|
|
141
|
+
N → M
|
|
142
|
+
(u, v) ↦ (x, y, z) = (u, v, u^2 + v^2 + t)
|
|
143
|
+
|
|
144
|
+
The foliation inverse maps are needed for computing the adapted chart on
|
|
145
|
+
the ambient manifold::
|
|
146
|
+
|
|
147
|
+
sage: phi_inv = M.continuous_map(N, {(CM, CN): [x, y]})
|
|
148
|
+
sage: phi_inv.display()
|
|
149
|
+
M → N
|
|
150
|
+
(x, y, z) ↦ (u, v) = (x, y)
|
|
151
|
+
sage: phi_inv_t = M.scalar_field({CM: z-x^2-y^2})
|
|
152
|
+
sage: phi_inv_t.display()
|
|
153
|
+
M → ℝ
|
|
154
|
+
(x, y, z) ↦ -x^2 - y^2 + z
|
|
155
|
+
|
|
156
|
+
`\phi` can then be declared as an embedding `N\to M`::
|
|
157
|
+
|
|
158
|
+
sage: N.set_embedding(phi, inverse=phi_inv, var=t,
|
|
159
|
+
....: t_inverse={t: phi_inv_t})
|
|
160
|
+
|
|
161
|
+
The foliation can also be used to find new charts on the ambient manifold
|
|
162
|
+
that are adapted to the foliation, i.e. in which the expression of the
|
|
163
|
+
immersion is trivial. At the same time, the appropriate coordinate changes
|
|
164
|
+
are computed::
|
|
165
|
+
|
|
166
|
+
sage: N.adapted_chart()
|
|
167
|
+
[Chart (M, (u_M, v_M, t_M))]
|
|
168
|
+
sage: M.atlas()
|
|
169
|
+
[Chart (M, (x, y, z)), Chart (M, (u_M, v_M, t_M))]
|
|
170
|
+
sage: len(M.coord_changes())
|
|
171
|
+
2
|
|
172
|
+
|
|
173
|
+
The foliation parameters are always added as the last coordinates.
|
|
174
|
+
|
|
175
|
+
.. SEEALSO::
|
|
176
|
+
|
|
177
|
+
:mod:`~sage.manifolds.manifold`
|
|
178
|
+
"""
|
|
179
|
+
def __init__(self, n, name, field, structure, ambient=None,
|
|
180
|
+
base_manifold=None, latex_name=None, start_index=0,
|
|
181
|
+
category=None, unique_tag=None):
|
|
182
|
+
r"""
|
|
183
|
+
Construct a submanifold of a topological manifold.
|
|
184
|
+
|
|
185
|
+
TESTS::
|
|
186
|
+
|
|
187
|
+
sage: M = Manifold(3, 'M', structure='topological')
|
|
188
|
+
sage: N = Manifold(2, 'N', ambient=M, structure='topological')
|
|
189
|
+
sage: N
|
|
190
|
+
2-dimensional topological submanifold N immersed in the
|
|
191
|
+
3-dimensional topological manifold M
|
|
192
|
+
"""
|
|
193
|
+
TopologicalManifold.__init__(self, n, name, field, structure,
|
|
194
|
+
base_manifold=base_manifold,
|
|
195
|
+
latex_name=latex_name,
|
|
196
|
+
start_index=start_index,
|
|
197
|
+
category=category)
|
|
198
|
+
if not (ambient is None
|
|
199
|
+
or isinstance(ambient, TopologicalManifold)):
|
|
200
|
+
raise TypeError("ambient must be a manifold")
|
|
201
|
+
self._init_immersion(ambient=ambient)
|
|
202
|
+
|
|
203
|
+
def _init_immersion(self, ambient=None):
|
|
204
|
+
r"""
|
|
205
|
+
Initialize the attributes relative to the immersion of ``self`` in
|
|
206
|
+
the ambient manifold.
|
|
207
|
+
|
|
208
|
+
INPUT:
|
|
209
|
+
|
|
210
|
+
- ``ambient`` -- (default: ``None``) codomain of the immersion;
|
|
211
|
+
must be a topological manifold. If ``None``, it is set to ``self``
|
|
212
|
+
|
|
213
|
+
TESTS::
|
|
214
|
+
|
|
215
|
+
sage: M = Manifold(2, 'M', structure='topological')
|
|
216
|
+
sage: N = Manifold(1, 'N', ambient=M, structure='topological')
|
|
217
|
+
sage: N._init_immersion(ambient=M)
|
|
218
|
+
"""
|
|
219
|
+
self._immersion = None
|
|
220
|
+
self._immersion_inv = None
|
|
221
|
+
self._var = None
|
|
222
|
+
self._dim_foliation = 0
|
|
223
|
+
self._t_inverse = {}
|
|
224
|
+
if ambient is None:
|
|
225
|
+
self._ambient = self
|
|
226
|
+
else:
|
|
227
|
+
self._ambient = ambient
|
|
228
|
+
self._codim = ambient._dim - self._dim
|
|
229
|
+
if self._codim < 0:
|
|
230
|
+
raise ValueError("the submanifold must be of smaller "
|
|
231
|
+
+ "dimension than its ambient manifold")
|
|
232
|
+
self._immersed = False
|
|
233
|
+
self._embedded = False
|
|
234
|
+
self._adapted_charts = None
|
|
235
|
+
self._subs = None
|
|
236
|
+
|
|
237
|
+
def _repr_(self):
|
|
238
|
+
r"""
|
|
239
|
+
Return a string representation of the submanifold.
|
|
240
|
+
|
|
241
|
+
If no ambient manifold is specified, the submanifold is considered as
|
|
242
|
+
a manifold.
|
|
243
|
+
|
|
244
|
+
TESTS::
|
|
245
|
+
|
|
246
|
+
sage: M = Manifold(3, 'M', structure='topological')
|
|
247
|
+
sage: N = Manifold(2, 'N', ambient=M, structure='topological')
|
|
248
|
+
sage: N
|
|
249
|
+
2-dimensional topological submanifold N immersed in the
|
|
250
|
+
3-dimensional topological manifold M
|
|
251
|
+
sage: phi = N.continuous_map(M)
|
|
252
|
+
sage: N.set_embedding(phi)
|
|
253
|
+
sage: N
|
|
254
|
+
2-dimensional topological submanifold N embedded in the
|
|
255
|
+
3-dimensional topological manifold M
|
|
256
|
+
"""
|
|
257
|
+
if self is not self._manifold:
|
|
258
|
+
return "Open subset {} of the {}".format(self._name, self._manifold)
|
|
259
|
+
if self._ambient is self:
|
|
260
|
+
return super(TopologicalManifold, self).__repr__()
|
|
261
|
+
if self._embedded:
|
|
262
|
+
return "{}-dimensional {} submanifold {} embedded in the {}".format(
|
|
263
|
+
self._dim, self._structure.name, self._name, self._ambient)
|
|
264
|
+
return "{}-dimensional {} submanifold {} immersed in the {}".format(
|
|
265
|
+
self._dim, self._structure.name, self._name, self._ambient)
|
|
266
|
+
|
|
267
|
+
def open_subset(self, name, latex_name=None, coord_def={}, supersets=None):
|
|
268
|
+
r"""
|
|
269
|
+
Create an open subset of the manifold.
|
|
270
|
+
|
|
271
|
+
An open subset is a set that is (i) included in the manifold and (ii)
|
|
272
|
+
open with respect to the manifold's topology. It is a topological
|
|
273
|
+
manifold by itself.
|
|
274
|
+
|
|
275
|
+
As ``self`` is a submanifold of its ambient manifold,
|
|
276
|
+
the new open subset is also considered a submanifold of that.
|
|
277
|
+
Hence the returned object is an instance of
|
|
278
|
+
:class:`TopologicalSubmanifold`.
|
|
279
|
+
|
|
280
|
+
INPUT:
|
|
281
|
+
|
|
282
|
+
- ``name`` -- name given to the open subset
|
|
283
|
+
- ``latex_name`` -- (default: ``None``) LaTeX symbol to denote
|
|
284
|
+
the subset; if none are provided, it is set to ``name``
|
|
285
|
+
- ``coord_def`` -- (default: {}) definition of the subset in
|
|
286
|
+
terms of coordinates; ``coord_def`` must a be dictionary with keys
|
|
287
|
+
charts on the manifold and values the symbolic expressions formed
|
|
288
|
+
by the coordinates to define the subset
|
|
289
|
+
- ``supersets`` -- (default: only ``self``) list of sets that the
|
|
290
|
+
new open subset is a subset of
|
|
291
|
+
|
|
292
|
+
OUTPUT: the open subset, as an instance of :class:`TopologicalSubmanifold`
|
|
293
|
+
|
|
294
|
+
EXAMPLES::
|
|
295
|
+
|
|
296
|
+
sage: M = Manifold(3, 'M', structure='topological')
|
|
297
|
+
sage: N = Manifold(2, 'N', ambient=M, structure='topological'); N
|
|
298
|
+
2-dimensional topological submanifold N immersed in the
|
|
299
|
+
3-dimensional topological manifold M
|
|
300
|
+
sage: S = N.subset('S'); S
|
|
301
|
+
Subset S of the
|
|
302
|
+
2-dimensional topological submanifold N immersed in the
|
|
303
|
+
3-dimensional topological manifold M
|
|
304
|
+
sage: O = N.subset('O', is_open=True); O # indirect doctest
|
|
305
|
+
Open subset O of the
|
|
306
|
+
2-dimensional topological submanifold N immersed in the
|
|
307
|
+
3-dimensional topological manifold M
|
|
308
|
+
|
|
309
|
+
sage: phi = N.continuous_map(M)
|
|
310
|
+
sage: N.set_embedding(phi)
|
|
311
|
+
sage: N
|
|
312
|
+
2-dimensional topological submanifold N embedded in the
|
|
313
|
+
3-dimensional topological manifold M
|
|
314
|
+
sage: S = N.subset('S'); S
|
|
315
|
+
Subset S of the
|
|
316
|
+
2-dimensional topological submanifold N embedded in the
|
|
317
|
+
3-dimensional topological manifold M
|
|
318
|
+
sage: O = N.subset('O', is_open=True); O # indirect doctest
|
|
319
|
+
Open subset O of the
|
|
320
|
+
2-dimensional topological submanifold N embedded in the
|
|
321
|
+
3-dimensional topological manifold M
|
|
322
|
+
"""
|
|
323
|
+
resu = TopologicalSubmanifold(self._dim, name, self._field,
|
|
324
|
+
self._structure, self._ambient,
|
|
325
|
+
base_manifold=self._manifold,
|
|
326
|
+
latex_name=latex_name,
|
|
327
|
+
start_index=self._sindex)
|
|
328
|
+
if supersets is None:
|
|
329
|
+
supersets = [self]
|
|
330
|
+
for superset in supersets:
|
|
331
|
+
superset._init_open_subset(resu, coord_def=coord_def)
|
|
332
|
+
return resu
|
|
333
|
+
|
|
334
|
+
def _init_open_subset(self, resu, coord_def):
|
|
335
|
+
r"""
|
|
336
|
+
Initialize ``resu`` as an open subset of ``self``.
|
|
337
|
+
|
|
338
|
+
INPUT:
|
|
339
|
+
|
|
340
|
+
- ``resu`` -- an instance of :class:`TopologicalManifold` or
|
|
341
|
+
a subclass
|
|
342
|
+
|
|
343
|
+
- ``coord_def`` -- (default: ``{}``) definition of the subset in
|
|
344
|
+
terms of coordinates; ``coord_def`` must a be dictionary with keys
|
|
345
|
+
charts on the manifold and values the symbolic expressions formed
|
|
346
|
+
by the coordinates to define the subset
|
|
347
|
+
|
|
348
|
+
EXAMPLES::
|
|
349
|
+
|
|
350
|
+
sage: M = Manifold(3, 'M', structure='topological')
|
|
351
|
+
sage: N = Manifold(2, 'N', ambient=M, structure='topological')
|
|
352
|
+
sage: phi = N.continuous_map(M)
|
|
353
|
+
sage: N.set_embedding(phi)
|
|
354
|
+
sage: N
|
|
355
|
+
2-dimensional topological submanifold N embedded in the
|
|
356
|
+
3-dimensional topological manifold M
|
|
357
|
+
sage: from sage.manifolds.topological_submanifold import TopologicalSubmanifold
|
|
358
|
+
sage: O = TopologicalSubmanifold(3, 'O', field=M._field, structure=M._structure,
|
|
359
|
+
....: ambient=M, base_manifold=N)
|
|
360
|
+
sage: N._init_open_subset(O, {})
|
|
361
|
+
sage: O
|
|
362
|
+
Open subset O of the
|
|
363
|
+
2-dimensional topological submanifold N embedded in the
|
|
364
|
+
3-dimensional topological manifold M
|
|
365
|
+
sage: O.embedding()
|
|
366
|
+
Continuous map
|
|
367
|
+
from the Open subset O of the 2-dimensional topological submanifold N
|
|
368
|
+
embedded in the 3-dimensional topological manifold M
|
|
369
|
+
to the 3-dimensional topological manifold M
|
|
370
|
+
"""
|
|
371
|
+
super()._init_open_subset(resu, coord_def=coord_def)
|
|
372
|
+
## Extras for Submanifold
|
|
373
|
+
if self._immersed:
|
|
374
|
+
resu.set_immersion(self._immersion.restrict(resu),
|
|
375
|
+
var=self._var, t_inverse=self._t_inverse)
|
|
376
|
+
if self._embedded:
|
|
377
|
+
resu.declare_embedding()
|
|
378
|
+
|
|
379
|
+
def set_immersion(self, phi, inverse=None, var=None,
|
|
380
|
+
t_inverse=None):
|
|
381
|
+
r"""
|
|
382
|
+
Register the immersion of the immersed submanifold.
|
|
383
|
+
|
|
384
|
+
A *topological immersion* is a continuous map that is locally a
|
|
385
|
+
topological embedding (i.e. a homeomorphism onto its image).
|
|
386
|
+
A *differentiable immersion* is a differentiable map whose differential
|
|
387
|
+
is injective at each point.
|
|
388
|
+
|
|
389
|
+
If an inverse of the immersion onto its image exists, it can be
|
|
390
|
+
registered at the same time. If the immersion depends on parameters,
|
|
391
|
+
they must also be declared here.
|
|
392
|
+
|
|
393
|
+
INPUT:
|
|
394
|
+
|
|
395
|
+
- ``phi`` -- continuous map `\phi` from ``self`` to ``self.ambient()``
|
|
396
|
+
- ``inverse`` -- (default: ``None``) continuous map from
|
|
397
|
+
``self.ambient()`` to ``self``, which once restricted to the image
|
|
398
|
+
of `\phi` is the inverse of `\phi` onto its image if the latter
|
|
399
|
+
exists (NB: no check of this is performed)
|
|
400
|
+
- ``var`` -- (default: ``None``) list of parameters involved in the
|
|
401
|
+
definition of `\phi` (case of foliation); if `\phi` depends on a
|
|
402
|
+
single parameter ``t``, one can write ``var=t`` as a shortcut for
|
|
403
|
+
``var=[t]``
|
|
404
|
+
- ``t_inverse`` -- (default: ``None``) dictionary of scalar fields on
|
|
405
|
+
``self.ambient()`` providing the values of the parameters involved
|
|
406
|
+
in the definition of `\phi` (case of foliation), the keys being
|
|
407
|
+
the parameters
|
|
408
|
+
|
|
409
|
+
EXAMPLES::
|
|
410
|
+
|
|
411
|
+
sage: M = Manifold(3, 'M', structure='topological')
|
|
412
|
+
sage: N = Manifold(2, 'N', ambient=M, structure='topological')
|
|
413
|
+
sage: N
|
|
414
|
+
2-dimensional topological submanifold N immersed in the
|
|
415
|
+
3-dimensional topological manifold M
|
|
416
|
+
sage: CM.<x,y,z> = M.chart()
|
|
417
|
+
sage: CN.<u,v> = N.chart()
|
|
418
|
+
sage: t = var('t')
|
|
419
|
+
sage: phi = N.continuous_map(M, {(CN,CM): [u,v,t+u^2+v^2]})
|
|
420
|
+
sage: phi.display()
|
|
421
|
+
N → M
|
|
422
|
+
(u, v) ↦ (x, y, z) = (u, v, u^2 + v^2 + t)
|
|
423
|
+
sage: phi_inv = M.continuous_map(N, {(CM,CN): [x,y]})
|
|
424
|
+
sage: phi_inv.display()
|
|
425
|
+
M → N
|
|
426
|
+
(x, y, z) ↦ (u, v) = (x, y)
|
|
427
|
+
sage: phi_inv_t = M.scalar_field({CM: z-x^2-y^2})
|
|
428
|
+
sage: phi_inv_t.display()
|
|
429
|
+
M → ℝ
|
|
430
|
+
(x, y, z) ↦ -x^2 - y^2 + z
|
|
431
|
+
sage: N.set_immersion(phi, inverse=phi_inv, var=t,
|
|
432
|
+
....: t_inverse={t: phi_inv_t})
|
|
433
|
+
"""
|
|
434
|
+
if not isinstance(phi, ContinuousMap):
|
|
435
|
+
raise TypeError("the argument phi must be a continuous map")
|
|
436
|
+
if phi.domain() is not self or phi.codomain() is not self._ambient:
|
|
437
|
+
raise ValueError("{} is not a map from {} to {}".format(phi, self,
|
|
438
|
+
self._ambient))
|
|
439
|
+
self._immersion = phi
|
|
440
|
+
|
|
441
|
+
if inverse is not None:
|
|
442
|
+
self._immersion._inverse = inverse
|
|
443
|
+
self._immersion_inv = inverse
|
|
444
|
+
|
|
445
|
+
if var is not None:
|
|
446
|
+
try:
|
|
447
|
+
iter(var)
|
|
448
|
+
for v in var:
|
|
449
|
+
if not isinstance(v, Expression):
|
|
450
|
+
raise TypeError()
|
|
451
|
+
except TypeError:
|
|
452
|
+
if not isinstance(var, Expression):
|
|
453
|
+
raise TypeError("var must be a variable "
|
|
454
|
+
"or list of variables")
|
|
455
|
+
|
|
456
|
+
if isinstance(var, Expression):
|
|
457
|
+
self._var = [var]
|
|
458
|
+
self._dim_foliation = 1
|
|
459
|
+
else:
|
|
460
|
+
self._var = var
|
|
461
|
+
self._dim_foliation = len(var)
|
|
462
|
+
if t_inverse is None:
|
|
463
|
+
t_inverse = {}
|
|
464
|
+
|
|
465
|
+
self._t_inverse = t_inverse
|
|
466
|
+
self._immersed = True
|
|
467
|
+
|
|
468
|
+
def declare_embedding(self):
|
|
469
|
+
r"""
|
|
470
|
+
Declare that the immersion provided by :meth:`set_immersion` is in
|
|
471
|
+
fact an embedding.
|
|
472
|
+
|
|
473
|
+
A *topological embedding* is a continuous map that is a homeomorphism
|
|
474
|
+
onto its image. A *differentiable embedding* is a topological embedding
|
|
475
|
+
that is also a differentiable immersion.
|
|
476
|
+
|
|
477
|
+
EXAMPLES::
|
|
478
|
+
|
|
479
|
+
sage: M = Manifold(3, 'M', structure='topological')
|
|
480
|
+
sage: N = Manifold(2, 'N', ambient=M, structure='topological')
|
|
481
|
+
sage: N
|
|
482
|
+
2-dimensional topological submanifold N immersed in the
|
|
483
|
+
3-dimensional topological manifold M
|
|
484
|
+
sage: CM.<x,y,z> = M.chart()
|
|
485
|
+
sage: CN.<u,v> = N.chart()
|
|
486
|
+
sage: t = var('t')
|
|
487
|
+
sage: phi = N.continuous_map(M, {(CN,CM): [u,v,t+u^2+v^2]})
|
|
488
|
+
sage: phi_inv = M.continuous_map(N, {(CM,CN): [x,y]})
|
|
489
|
+
sage: phi_inv_t = M.scalar_field({CM: z-x^2-y^2})
|
|
490
|
+
sage: N.set_immersion(phi, inverse=phi_inv, var=t,
|
|
491
|
+
....: t_inverse={t: phi_inv_t})
|
|
492
|
+
sage: N._immersed
|
|
493
|
+
True
|
|
494
|
+
sage: N._embedded
|
|
495
|
+
False
|
|
496
|
+
sage: N.declare_embedding()
|
|
497
|
+
sage: N._immersed
|
|
498
|
+
True
|
|
499
|
+
sage: N._embedded
|
|
500
|
+
True
|
|
501
|
+
"""
|
|
502
|
+
if not self._immersed:
|
|
503
|
+
raise ValueError("please declare an embedding using set_immersion "
|
|
504
|
+
"before calling declare_embedding()")
|
|
505
|
+
self._embedded = True
|
|
506
|
+
|
|
507
|
+
def set_embedding(
|
|
508
|
+
self, phi: ContinuousMap, inverse=None, var=None, t_inverse=None
|
|
509
|
+
):
|
|
510
|
+
r"""
|
|
511
|
+
Register the embedding of an embedded submanifold.
|
|
512
|
+
|
|
513
|
+
A *topological embedding* is a continuous map that is a homeomorphism
|
|
514
|
+
onto its image. A *differentiable embedding* is a topological embedding
|
|
515
|
+
that is also a differentiable immersion.
|
|
516
|
+
|
|
517
|
+
INPUT:
|
|
518
|
+
|
|
519
|
+
- ``phi`` -- continuous map `\phi` from ``self`` to ``self.ambient()``
|
|
520
|
+
- ``inverse`` -- (default: ``None``) continuous map from
|
|
521
|
+
``self.ambient()`` to ``self``, which once restricted to the image
|
|
522
|
+
of `\phi` is the inverse of `\phi` onto its image (NB: no check of
|
|
523
|
+
this is performed)
|
|
524
|
+
- ``var`` -- (default: ``None``) list of parameters involved in the
|
|
525
|
+
definition of `\phi` (case of foliation); if `\phi` depends on a
|
|
526
|
+
single parameter ``t``, one can write ``var=t`` as a shortcut for
|
|
527
|
+
``var=[t]``
|
|
528
|
+
- ``t_inverse`` -- (default: ``None``) dictionary of scalar fields on
|
|
529
|
+
``self.ambient()`` providing the values of the parameters involved
|
|
530
|
+
in the definition of `\phi` (case of foliation), the keys being
|
|
531
|
+
the parameters
|
|
532
|
+
|
|
533
|
+
EXAMPLES::
|
|
534
|
+
|
|
535
|
+
sage: M = Manifold(3, 'M', structure='topological')
|
|
536
|
+
sage: N = Manifold(2, 'N', ambient=M, structure='topological')
|
|
537
|
+
sage: N
|
|
538
|
+
2-dimensional topological submanifold N immersed in the
|
|
539
|
+
3-dimensional topological manifold M
|
|
540
|
+
sage: CM.<x,y,z> = M.chart()
|
|
541
|
+
sage: CN.<u,v> = N.chart()
|
|
542
|
+
sage: t = var('t')
|
|
543
|
+
sage: phi = N.continuous_map(M, {(CN,CM): [u,v,t+u^2+v^2]})
|
|
544
|
+
sage: phi.display()
|
|
545
|
+
N → M
|
|
546
|
+
(u, v) ↦ (x, y, z) = (u, v, u^2 + v^2 + t)
|
|
547
|
+
sage: phi_inv = M.continuous_map(N, {(CM,CN): [x,y]})
|
|
548
|
+
sage: phi_inv.display()
|
|
549
|
+
M → N
|
|
550
|
+
(x, y, z) ↦ (u, v) = (x, y)
|
|
551
|
+
sage: phi_inv_t = M.scalar_field({CM: z-x^2-y^2})
|
|
552
|
+
sage: phi_inv_t.display()
|
|
553
|
+
M → ℝ
|
|
554
|
+
(x, y, z) ↦ -x^2 - y^2 + z
|
|
555
|
+
sage: N.set_embedding(phi, inverse=phi_inv, var=t,
|
|
556
|
+
....: t_inverse={t: phi_inv_t})
|
|
557
|
+
|
|
558
|
+
Now ``N`` appears as an embedded submanifold::
|
|
559
|
+
|
|
560
|
+
sage: N
|
|
561
|
+
2-dimensional topological submanifold N embedded in the
|
|
562
|
+
3-dimensional topological manifold M
|
|
563
|
+
"""
|
|
564
|
+
self.set_immersion(phi, inverse, var, t_inverse)
|
|
565
|
+
self.declare_embedding()
|
|
566
|
+
|
|
567
|
+
def adapted_chart(self, postscript=None, latex_postscript=None):
|
|
568
|
+
r"""
|
|
569
|
+
Create charts and changes of charts in the ambient manifold adapted
|
|
570
|
+
to the foliation.
|
|
571
|
+
|
|
572
|
+
A manifold `M` of dimension `m` can be foliated by submanifolds `N` of
|
|
573
|
+
dimension `n`. The corresponding embedding needs `m-n` free parameters
|
|
574
|
+
to describe the whole manifold.
|
|
575
|
+
|
|
576
|
+
A chart adapted to the foliation is a set of coordinates
|
|
577
|
+
`(x_1,\ldots,x_n,t_1,\ldots,t_{m-n})` on `M` such that
|
|
578
|
+
`(x_1,\ldots,x_n)` are coordinates on `N` and `(t_1,\ldots,t_{m-n})`
|
|
579
|
+
are the `m-n` free parameters of the foliation.
|
|
580
|
+
|
|
581
|
+
Provided that an embedding with free variables is already defined, this
|
|
582
|
+
function constructs such charts and coordinates changes whenever
|
|
583
|
+
it is possible.
|
|
584
|
+
|
|
585
|
+
If there are restrictions of the coordinates on the starting chart,
|
|
586
|
+
these restrictions are also propagated.
|
|
587
|
+
|
|
588
|
+
INPUT:
|
|
589
|
+
|
|
590
|
+
- ``postscript`` -- (default: ``None``) string defining the name of the
|
|
591
|
+
coordinates of the adapted chart. This string will be appended to
|
|
592
|
+
the names of the coordinates `(x_1,\ldots,x_n)` and of the parameters
|
|
593
|
+
`(t_1,\ldots,t_{m-n})`. If ``None``, ``"_" + self.ambient()._name``
|
|
594
|
+
is used
|
|
595
|
+
- ``latex_postscript`` -- (default: ``None``) string defining the LaTeX
|
|
596
|
+
name of the coordinates of the adapted chart. This string will be
|
|
597
|
+
appended to the LaTeX names of the coordinates `(x_1,\ldots,x_n)` and
|
|
598
|
+
of the parameters `(t_1,\ldots,t_{m-n})`, If ``None``,
|
|
599
|
+
``"_" + self.ambient()._latex_()`` is used
|
|
600
|
+
|
|
601
|
+
OUTPUT: list of adapted charts on `M` created from the charts of ``self``
|
|
602
|
+
|
|
603
|
+
EXAMPLES::
|
|
604
|
+
|
|
605
|
+
sage: M = Manifold(3, 'M', structure='topological',
|
|
606
|
+
....: latex_name=r"\mathcal{M}")
|
|
607
|
+
sage: N = Manifold(2, 'N', ambient=M, structure='topological')
|
|
608
|
+
sage: N
|
|
609
|
+
2-dimensional topological submanifold N immersed in the
|
|
610
|
+
3-dimensional topological manifold M
|
|
611
|
+
sage: CM.<x,y,z> = M.chart()
|
|
612
|
+
sage: CN.<u,v> = N.chart()
|
|
613
|
+
sage: t = var('t')
|
|
614
|
+
sage: phi = N.continuous_map(M, {(CN,CM): [u,v,t+u^2+v^2]})
|
|
615
|
+
sage: phi_inv = M.continuous_map(N, {(CM,CN): [x,y]})
|
|
616
|
+
sage: phi_inv_t = M.scalar_field({CM: z-x^2-y^2})
|
|
617
|
+
sage: N.set_embedding(phi, inverse=phi_inv, var=t,
|
|
618
|
+
....: t_inverse={t:phi_inv_t})
|
|
619
|
+
sage: N.adapted_chart()
|
|
620
|
+
[Chart (M, (u_M, v_M, t_M))]
|
|
621
|
+
sage: latex(_)
|
|
622
|
+
\left[\left(\mathcal{M},({{u}_{\mathcal{M}}}, {{v}_{\mathcal{M}}},
|
|
623
|
+
{{t}_{\mathcal{M}}})\right)\right]
|
|
624
|
+
|
|
625
|
+
The adapted chart has been added to the atlas of ``M``::
|
|
626
|
+
|
|
627
|
+
sage: M.atlas()
|
|
628
|
+
[Chart (M, (x, y, z)), Chart (M, (u_M, v_M, t_M))]
|
|
629
|
+
sage: N.atlas()
|
|
630
|
+
[Chart (N, (u, v))]
|
|
631
|
+
|
|
632
|
+
The names of the adapted coordinates can be customized::
|
|
633
|
+
|
|
634
|
+
sage: N.adapted_chart(postscript='1', latex_postscript='_1')
|
|
635
|
+
[Chart (M, (u1, v1, t1))]
|
|
636
|
+
sage: latex(_)
|
|
637
|
+
\left[\left(\mathcal{M},({{u}_1}, {{v}_1}, {{t}_1})\right)\right]
|
|
638
|
+
"""
|
|
639
|
+
if not self._embedded:
|
|
640
|
+
raise ValueError("an embedding is required")
|
|
641
|
+
|
|
642
|
+
if self._dim_foliation + self._dim != self._ambient._dim:
|
|
643
|
+
raise ValueError("a foliation of dimension dim(M) - dim(N) is "
|
|
644
|
+
"needed to find an adapted chart")
|
|
645
|
+
res = []
|
|
646
|
+
self._subs = []
|
|
647
|
+
|
|
648
|
+
if postscript is None:
|
|
649
|
+
postscript = "_" + self._ambient._name.replace("^", "")
|
|
650
|
+
# NB: "^" is deleted from the name of ambient to get valid
|
|
651
|
+
# Python identifiers for the symbolic variables representing the
|
|
652
|
+
# coordinates
|
|
653
|
+
if latex_postscript is None:
|
|
654
|
+
latex_postscript = "_{" + self._ambient._latex_() + "}"
|
|
655
|
+
|
|
656
|
+
# All possible expressions for the immersion
|
|
657
|
+
chart_pairs = list(self._immersion._coord_expression.keys())
|
|
658
|
+
for (chart1, chart2) in chart_pairs:
|
|
659
|
+
name = " ".join(chart1[i]._repr_() + postscript + ":{"
|
|
660
|
+
+ chart1[i]._latex_() + "}" + latex_postscript
|
|
661
|
+
for i in self.irange()) + " " \
|
|
662
|
+
+ " ".join(v._repr_() + postscript + ":{" + v._latex_()
|
|
663
|
+
+ "}" + latex_postscript for v in self._var)
|
|
664
|
+
chart = chart2.domain().chart(name)
|
|
665
|
+
if chart not in res:
|
|
666
|
+
|
|
667
|
+
# Construct restrictions on coordinates:
|
|
668
|
+
subs = {chart1[:][i]: chart[:][i] for i in range(self._dim)}
|
|
669
|
+
# NB: chart1[:][i] is used instead of chart1[i] to allow for
|
|
670
|
+
# start_index != 0
|
|
671
|
+
for i in range(len(self._var)):
|
|
672
|
+
subs[self._var[i]] = chart[:][self._dim + i]
|
|
673
|
+
for rest in chart1._restrictions:
|
|
674
|
+
chart.add_restrictions(rest.subs(subs))
|
|
675
|
+
for _a in assumptions(*(chart1[:] + tuple(self._var))):
|
|
676
|
+
if isinstance(_a, Expression):
|
|
677
|
+
assume(_a.subs(subs))
|
|
678
|
+
|
|
679
|
+
self._subs.append(subs)
|
|
680
|
+
res.append(chart)
|
|
681
|
+
self._immersion.add_expr(chart1, chart,
|
|
682
|
+
list(chart1[:]) + self._var)
|
|
683
|
+
self._immersion_inv.add_expr(chart, chart1,
|
|
684
|
+
chart[:][0:self._dim])
|
|
685
|
+
for i in range(len(self._var)):
|
|
686
|
+
self._t_inverse[self._var[i]].add_expr(
|
|
687
|
+
chart[:][self._dim:][i], chart=chart)
|
|
688
|
+
|
|
689
|
+
for (chartNV, chartMV) in self._immersion._coord_expression:
|
|
690
|
+
for (chartNU, chartMU) in self._immersion._coord_expression:
|
|
691
|
+
if chartMU is not chartMV and\
|
|
692
|
+
(chartMU, chartMV) not in self._ambient._coord_changes:
|
|
693
|
+
if (chartNU, chartNV) in self._coord_changes or \
|
|
694
|
+
chartNU is chartNV:
|
|
695
|
+
_f = self._immersion.coord_functions(chartNV, chartMV)
|
|
696
|
+
_g = self._coord_changes[(chartNU, chartNV)]._transf \
|
|
697
|
+
if chartNU is not chartNV else lambda *x: x
|
|
698
|
+
_h = self._immersion_inv.coord_functions(chartMU,
|
|
699
|
+
chartNU)
|
|
700
|
+
expr = list(_f(*_g(*_h(*chartMU[:]))))
|
|
701
|
+
substitutions = {v: self._t_inverse[v].expr(chartMU)
|
|
702
|
+
for v in self._var}
|
|
703
|
+
for i in range(len(expr)):
|
|
704
|
+
expr[i] = expr[i].subs(substitutions)
|
|
705
|
+
|
|
706
|
+
chartMU.transition_map(chartMV, expr)
|
|
707
|
+
self._adapted_charts = res
|
|
708
|
+
return res
|
|
709
|
+
|
|
710
|
+
def plot(self, param, u, v, chart1=None, chart2=None, **kwargs):
|
|
711
|
+
r"""
|
|
712
|
+
Plot an embedding.
|
|
713
|
+
|
|
714
|
+
Plot the embedding defined by the foliation and a set of values for the
|
|
715
|
+
free parameters. This function can only plot 2-dimensional surfaces
|
|
716
|
+
embedded in 3-dimensional manifolds. It ultimately calls
|
|
717
|
+
:class:`~sage.plot.plot3d.parametric_surface.ParametricSurface`.
|
|
718
|
+
|
|
719
|
+
INPUT:
|
|
720
|
+
|
|
721
|
+
- ``param`` -- dictionary of values indexed by the free variables
|
|
722
|
+
appearing in the foliation
|
|
723
|
+
- ``u`` -- iterable of the values taken by the first coordinate of the
|
|
724
|
+
surface to plot
|
|
725
|
+
- ``v`` -- iterable of the values taken by the second coordinate of the
|
|
726
|
+
surface to plot
|
|
727
|
+
- ``chart1`` -- (default: ``None``) chart in which ``u`` and ``v`` are
|
|
728
|
+
considered. By default, the default chart of the submanifold is used
|
|
729
|
+
- ``chart2`` -- (default: ``None``) chart in the codomain of the
|
|
730
|
+
embedding. By default, the default chart of the codomain is used
|
|
731
|
+
- ``**kwargs`` -- other arguments as used in
|
|
732
|
+
:class:`~sage.plot.plot3d.parametric_surface.ParametricSurface`
|
|
733
|
+
|
|
734
|
+
EXAMPLES::
|
|
735
|
+
|
|
736
|
+
sage: # needs sage.plot
|
|
737
|
+
sage: M = Manifold(3, 'M', structure='topological')
|
|
738
|
+
sage: N = Manifold(2, 'N', ambient = M, structure='topological')
|
|
739
|
+
sage: CM.<x,y,z> = M.chart()
|
|
740
|
+
sage: CN.<u,v> = N.chart()
|
|
741
|
+
sage: t = var('t')
|
|
742
|
+
sage: phi = N.continuous_map(M, {(CN,CM): [u,v,t+u^2+v^2]})
|
|
743
|
+
sage: phi_inv = M.continuous_map(N, {(CM,CN): [x,y]})
|
|
744
|
+
sage: phi_inv_t = M.scalar_field({CM: z-x^2-y^2})
|
|
745
|
+
sage: N.set_embedding(phi, inverse=phi_inv, var=t,
|
|
746
|
+
....: t_inverse = {t:phi_inv_t})
|
|
747
|
+
sage: N.adapted_chart()
|
|
748
|
+
[Chart (M, (u_M, v_M, t_M))]
|
|
749
|
+
sage: P0 = N.plot({t:0}, srange(-1, 1, 0.1), srange(-1, 1, 0.1),
|
|
750
|
+
....: CN, CM, opacity=0.3, mesh=True)
|
|
751
|
+
sage: P1 = N.plot({t:1}, srange(-1, 1, 0.1), srange(-1, 1, 0.1),
|
|
752
|
+
....: CN, CM, opacity=0.3, mesh=True)
|
|
753
|
+
sage: P2 = N.plot({t:2}, srange(-1, 1, 0.1), srange(-1, 1, 0.1),
|
|
754
|
+
....: CN, CM, opacity=0.3, mesh=True)
|
|
755
|
+
sage: P3 = N.plot({t:3}, srange(-1, 1, 0.1), srange(-1, 1, 0.1),
|
|
756
|
+
....: CN, CM, opacity=0.3, mesh=True)
|
|
757
|
+
sage: P0 + P1 + P2 + P3
|
|
758
|
+
Graphics3d Object
|
|
759
|
+
|
|
760
|
+
.. PLOT::
|
|
761
|
+
|
|
762
|
+
M = Manifold(3, 'M', structure='topological')
|
|
763
|
+
N = Manifold(2, 'N', ambient = M, structure='topological')
|
|
764
|
+
CM = M.chart('x y z'); x, y, z = CM[:]
|
|
765
|
+
CN = N.chart('u v'); u, v = CN[:]
|
|
766
|
+
t = var('t')
|
|
767
|
+
phi = N.continuous_map(M, {(CN,CM): [u,v,t+u**2+v**2]})
|
|
768
|
+
phi_inv = M.continuous_map(N, {(CM,CN): [x,y]})
|
|
769
|
+
phi_inv_t = M.scalar_field({CM: z-x**2-y**2})
|
|
770
|
+
N.set_embedding(phi, inverse=phi_inv, var=t,
|
|
771
|
+
t_inverse = {t:phi_inv_t})
|
|
772
|
+
N.adapted_chart()
|
|
773
|
+
P0 = N.plot({t:0}, srange(-1, 1, 0.1), srange(-1, 1, 0.1),
|
|
774
|
+
CN, CM, opacity=0.3, mesh=True)
|
|
775
|
+
P1 = N.plot({t:1}, srange(-1, 1, 0.1), srange(-1, 1, 0.1),
|
|
776
|
+
CN, CM, opacity=0.3, mesh=True)
|
|
777
|
+
P2 = N.plot({t:2}, srange(-1, 1, 0.1), srange(-1, 1, 0.1),
|
|
778
|
+
CN, CM, opacity=0.3, mesh=True)
|
|
779
|
+
P3 = N.plot({t:3}, srange(-1, 1, 0.1), srange(-1, 1, 0.1),
|
|
780
|
+
CN, CM, opacity=0.3, mesh=True)
|
|
781
|
+
sphinx_plot(P0 + P1 + P2 + P3)
|
|
782
|
+
|
|
783
|
+
.. SEEALSO::
|
|
784
|
+
|
|
785
|
+
:class:`~sage.plot.plot3d.parametric_surface.ParametricSurface`
|
|
786
|
+
"""
|
|
787
|
+
|
|
788
|
+
if self._dim != 2 or self._ambient._dim != 3:
|
|
789
|
+
raise ValueError("plot only for 2-dimensional hypersurfaces")
|
|
790
|
+
if chart1 is None:
|
|
791
|
+
chart1 = self.default_chart()
|
|
792
|
+
if chart2 is None:
|
|
793
|
+
chart2 = self._ambient.default_chart()
|
|
794
|
+
expr = list(self._immersion.coord_functions(chart1, chart2))
|
|
795
|
+
for i in range(len(expr)):
|
|
796
|
+
expr[i] = expr[i].expr().subs(param)
|
|
797
|
+
fx = expr[0].function(*chart1[:])
|
|
798
|
+
fy = expr[1].function(*chart1[:])
|
|
799
|
+
fz = expr[2].function(*chart1[:])
|
|
800
|
+
|
|
801
|
+
return ParametricSurface((fx, fy, fz), (u, v), **kwargs)
|
|
802
|
+
|
|
803
|
+
def ambient(self) -> TopologicalManifold:
|
|
804
|
+
r"""
|
|
805
|
+
Return the manifold in which ``self`` is immersed or embedded.
|
|
806
|
+
|
|
807
|
+
EXAMPLES::
|
|
808
|
+
|
|
809
|
+
sage: M = Manifold(3, 'M', structure='topological')
|
|
810
|
+
sage: N = Manifold(2, 'N', ambient=M, structure='topological')
|
|
811
|
+
sage: N.ambient()
|
|
812
|
+
3-dimensional topological manifold M
|
|
813
|
+
"""
|
|
814
|
+
return self._ambient
|
|
815
|
+
|
|
816
|
+
def immersion(self) -> ContinuousMap:
|
|
817
|
+
r"""
|
|
818
|
+
Return the immersion of ``self`` into the ambient manifold.
|
|
819
|
+
|
|
820
|
+
EXAMPLES::
|
|
821
|
+
|
|
822
|
+
sage: M = Manifold(3, 'M', structure='topological')
|
|
823
|
+
sage: N = Manifold(2, 'N', ambient=M, structure='topological')
|
|
824
|
+
sage: CM.<x,y,z> = M.chart()
|
|
825
|
+
sage: CN.<u,v> = N.chart()
|
|
826
|
+
sage: t = var('t')
|
|
827
|
+
sage: phi = N.continuous_map(M, {(CN,CM): [u,v,t+u^2+v^2]})
|
|
828
|
+
sage: phi_inv = M.continuous_map(N, {(CM,CN): [x,y]})
|
|
829
|
+
sage: phi_inv_t = M.scalar_field({CM: z-x^2-y^2})
|
|
830
|
+
sage: N.set_immersion(phi, inverse=phi_inv, var=t,
|
|
831
|
+
....: t_inverse={t: phi_inv_t})
|
|
832
|
+
sage: N.immersion()
|
|
833
|
+
Continuous map from the 2-dimensional topological submanifold N
|
|
834
|
+
immersed in the 3-dimensional topological manifold M to the
|
|
835
|
+
3-dimensional topological manifold M
|
|
836
|
+
"""
|
|
837
|
+
if not self._immersed:
|
|
838
|
+
raise ValueError("the submanifold is not immersed")
|
|
839
|
+
assert self._immersion
|
|
840
|
+
return self._immersion
|
|
841
|
+
|
|
842
|
+
def embedding(self) -> ContinuousMap:
|
|
843
|
+
r"""
|
|
844
|
+
Return the embedding of ``self`` into the ambient manifold.
|
|
845
|
+
|
|
846
|
+
EXAMPLES::
|
|
847
|
+
|
|
848
|
+
sage: M = Manifold(3, 'M', structure='topological')
|
|
849
|
+
sage: N = Manifold(2, 'N', ambient=M, structure='topological')
|
|
850
|
+
sage: CM.<x,y,z> = M.chart()
|
|
851
|
+
sage: CN.<u,v> = N.chart()
|
|
852
|
+
sage: t = var('t')
|
|
853
|
+
sage: phi = N.continuous_map(M, {(CN,CM): [u,v,t+u^2+v^2]})
|
|
854
|
+
sage: phi_inv = M.continuous_map(N, {(CM,CN): [x,y]})
|
|
855
|
+
sage: phi_inv_t = M.scalar_field({CM: z-x^2-y^2})
|
|
856
|
+
sage: N.set_embedding(phi, inverse=phi_inv, var=t,
|
|
857
|
+
....: t_inverse={t: phi_inv_t})
|
|
858
|
+
sage: N.embedding()
|
|
859
|
+
Continuous map from the 2-dimensional topological submanifold N
|
|
860
|
+
embedded in the 3-dimensional topological manifold M to the
|
|
861
|
+
3-dimensional topological manifold M
|
|
862
|
+
"""
|
|
863
|
+
if not self._embedded:
|
|
864
|
+
raise ValueError("the submanifold is not embedded")
|
|
865
|
+
assert self._immersion
|
|
866
|
+
return self._immersion
|
|
867
|
+
|
|
868
|
+
def as_subset(self):
|
|
869
|
+
r"""
|
|
870
|
+
Return ``self`` as a subset of the ambient manifold.
|
|
871
|
+
|
|
872
|
+
``self`` must be an embedded submanifold.
|
|
873
|
+
|
|
874
|
+
EXAMPLES::
|
|
875
|
+
|
|
876
|
+
sage: M = Manifold(2, 'M', structure='topological')
|
|
877
|
+
sage: N = Manifold(1, 'N', ambient=M, structure='topological')
|
|
878
|
+
sage: CM.<x,y> = M.chart()
|
|
879
|
+
sage: CN.<u> = N.chart(coord_restrictions=lambda u: [u > -1, u < 1])
|
|
880
|
+
sage: phi = N.continuous_map(M, {(CN,CM): [u, u^2]})
|
|
881
|
+
sage: N.set_embedding(phi)
|
|
882
|
+
sage: N
|
|
883
|
+
1-dimensional topological submanifold N
|
|
884
|
+
embedded in the 2-dimensional topological manifold M
|
|
885
|
+
sage: N.as_subset()
|
|
886
|
+
Image of the Continuous map
|
|
887
|
+
from the 1-dimensional topological submanifold N
|
|
888
|
+
embedded in the 2-dimensional topological manifold M
|
|
889
|
+
to the 2-dimensional topological manifold M
|
|
890
|
+
"""
|
|
891
|
+
return self.embedding().image()
|