passagemath-symbolics 10.6.43__cp314-cp314t-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.
Potentially problematic release.
This version of passagemath-symbolics might be problematic. Click here for more details.
- passagemath_symbolics/__init__.py +3 -0
- passagemath_symbolics-10.6.43.dist-info/METADATA +187 -0
- passagemath_symbolics-10.6.43.dist-info/RECORD +171 -0
- passagemath_symbolics-10.6.43.dist-info/WHEEL +5 -0
- passagemath_symbolics-10.6.43.dist-info/top_level.txt +3 -0
- sage/all__sagemath_symbolics.py +17 -0
- sage/calculus/all.py +14 -0
- sage/calculus/calculus.py +2826 -0
- sage/calculus/desolvers.py +1866 -0
- sage/calculus/predefined.py +51 -0
- sage/calculus/tests.py +225 -0
- sage/calculus/var.cpython-314t-x86_64-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-x86_64-linux-musl.so +0 -0
- sage/dynamics/complex_dynamics/mandel_julia_helper.pyx +1035 -0
- sage/ext/all__sagemath_symbolics.py +1 -0
- sage/ext_data/kenzo/CP2.txt +45 -0
- sage/ext_data/kenzo/CP3.txt +349 -0
- sage/ext_data/kenzo/CP4.txt +4774 -0
- sage/ext_data/kenzo/README.txt +49 -0
- sage/ext_data/kenzo/S4.txt +20 -0
- sage/ext_data/magma/latex/latex.m +1021 -0
- sage/ext_data/magma/latex/latex.spec +1 -0
- sage/ext_data/magma/sage/basic.m +356 -0
- sage/ext_data/magma/sage/sage.spec +1 -0
- sage/ext_data/magma/spec +9 -0
- sage/geometry/all__sagemath_symbolics.py +8 -0
- sage/geometry/hyperbolic_space/all.py +5 -0
- sage/geometry/hyperbolic_space/hyperbolic_coercion.py +743 -0
- sage/geometry/hyperbolic_space/hyperbolic_constants.py +5 -0
- sage/geometry/hyperbolic_space/hyperbolic_geodesic.py +2409 -0
- sage/geometry/hyperbolic_space/hyperbolic_interface.py +206 -0
- sage/geometry/hyperbolic_space/hyperbolic_isometry.py +1082 -0
- sage/geometry/hyperbolic_space/hyperbolic_model.py +1502 -0
- sage/geometry/hyperbolic_space/hyperbolic_point.py +621 -0
- sage/geometry/riemannian_manifolds/all.py +7 -0
- sage/geometry/riemannian_manifolds/parametrized_surface3d.py +1632 -0
- sage/geometry/riemannian_manifolds/surface3d_generators.py +461 -0
- sage/interfaces/all__sagemath_symbolics.py +1 -0
- sage/interfaces/magma.py +3017 -0
- sage/interfaces/magma_free.py +92 -0
- sage/interfaces/maple.py +1397 -0
- sage/interfaces/mathematica.py +1345 -0
- sage/interfaces/mathics.py +1312 -0
- sage/interfaces/sympy.py +1398 -0
- sage/interfaces/sympy_wrapper.py +197 -0
- sage/interfaces/tides.py +938 -0
- sage/libs/all__sagemath_symbolics.py +6 -0
- sage/manifolds/all.py +7 -0
- sage/manifolds/calculus_method.py +555 -0
- sage/manifolds/catalog.py +437 -0
- sage/manifolds/chart.py +4019 -0
- sage/manifolds/chart_func.py +3419 -0
- sage/manifolds/continuous_map.py +2183 -0
- sage/manifolds/continuous_map_image.py +155 -0
- sage/manifolds/differentiable/affine_connection.py +2475 -0
- sage/manifolds/differentiable/all.py +1 -0
- sage/manifolds/differentiable/automorphismfield.py +1383 -0
- sage/manifolds/differentiable/automorphismfield_group.py +604 -0
- sage/manifolds/differentiable/bundle_connection.py +1445 -0
- sage/manifolds/differentiable/characteristic_cohomology_class.py +1840 -0
- sage/manifolds/differentiable/chart.py +1241 -0
- sage/manifolds/differentiable/curve.py +1028 -0
- sage/manifolds/differentiable/de_rham_cohomology.py +541 -0
- sage/manifolds/differentiable/degenerate.py +559 -0
- sage/manifolds/differentiable/degenerate_submanifold.py +1671 -0
- sage/manifolds/differentiable/diff_form.py +1658 -0
- sage/manifolds/differentiable/diff_form_module.py +1062 -0
- sage/manifolds/differentiable/diff_map.py +1315 -0
- sage/manifolds/differentiable/differentiable_submanifold.py +291 -0
- sage/manifolds/differentiable/examples/all.py +1 -0
- sage/manifolds/differentiable/examples/euclidean.py +2517 -0
- sage/manifolds/differentiable/examples/real_line.py +897 -0
- sage/manifolds/differentiable/examples/sphere.py +1186 -0
- sage/manifolds/differentiable/examples/symplectic_space.py +187 -0
- sage/manifolds/differentiable/examples/symplectic_space_test.py +40 -0
- sage/manifolds/differentiable/integrated_curve.py +4035 -0
- sage/manifolds/differentiable/levi_civita_connection.py +841 -0
- sage/manifolds/differentiable/manifold.py +4254 -0
- sage/manifolds/differentiable/manifold_homset.py +1826 -0
- sage/manifolds/differentiable/metric.py +3032 -0
- sage/manifolds/differentiable/mixed_form.py +1507 -0
- sage/manifolds/differentiable/mixed_form_algebra.py +559 -0
- sage/manifolds/differentiable/multivector_module.py +800 -0
- sage/manifolds/differentiable/multivectorfield.py +1520 -0
- sage/manifolds/differentiable/poisson_tensor.py +268 -0
- sage/manifolds/differentiable/pseudo_riemannian.py +755 -0
- sage/manifolds/differentiable/pseudo_riemannian_submanifold.py +1839 -0
- sage/manifolds/differentiable/scalarfield.py +1343 -0
- sage/manifolds/differentiable/scalarfield_algebra.py +472 -0
- sage/manifolds/differentiable/symplectic_form.py +910 -0
- sage/manifolds/differentiable/symplectic_form_test.py +220 -0
- sage/manifolds/differentiable/tangent_space.py +412 -0
- sage/manifolds/differentiable/tangent_vector.py +616 -0
- sage/manifolds/differentiable/tensorfield.py +4665 -0
- sage/manifolds/differentiable/tensorfield_module.py +963 -0
- sage/manifolds/differentiable/tensorfield_paral.py +2450 -0
- sage/manifolds/differentiable/tensorfield_paral_test.py +16 -0
- sage/manifolds/differentiable/vector_bundle.py +1728 -0
- sage/manifolds/differentiable/vectorfield.py +1717 -0
- sage/manifolds/differentiable/vectorfield_module.py +2445 -0
- sage/manifolds/differentiable/vectorframe.py +1832 -0
- sage/manifolds/family.py +270 -0
- sage/manifolds/local_frame.py +1490 -0
- sage/manifolds/manifold.py +3090 -0
- sage/manifolds/manifold_homset.py +452 -0
- sage/manifolds/operators.py +359 -0
- sage/manifolds/point.py +994 -0
- sage/manifolds/scalarfield.py +3718 -0
- sage/manifolds/scalarfield_algebra.py +629 -0
- sage/manifolds/section.py +3111 -0
- sage/manifolds/section_module.py +831 -0
- sage/manifolds/structure.py +229 -0
- sage/manifolds/subset.py +2764 -0
- sage/manifolds/subsets/all.py +1 -0
- sage/manifolds/subsets/closure.py +131 -0
- sage/manifolds/subsets/pullback.py +885 -0
- sage/manifolds/topological_submanifold.py +891 -0
- sage/manifolds/trivialization.py +733 -0
- sage/manifolds/utilities.py +1348 -0
- sage/manifolds/vector_bundle.py +1342 -0
- sage/manifolds/vector_bundle_fiber.py +332 -0
- sage/manifolds/vector_bundle_fiber_element.py +111 -0
- sage/matrix/all__sagemath_symbolics.py +1 -0
- sage/matrix/matrix_symbolic_dense.cpython-314t-x86_64-linux-musl.so +0 -0
- sage/matrix/matrix_symbolic_dense.pxd +6 -0
- sage/matrix/matrix_symbolic_dense.pyx +1022 -0
- sage/matrix/matrix_symbolic_sparse.cpython-314t-x86_64-linux-musl.so +0 -0
- sage/matrix/matrix_symbolic_sparse.pxd +6 -0
- sage/matrix/matrix_symbolic_sparse.pyx +1029 -0
- sage/modules/all__sagemath_symbolics.py +1 -0
- sage/modules/vector_callable_symbolic_dense.py +105 -0
- sage/modules/vector_symbolic_dense.py +116 -0
- sage/modules/vector_symbolic_sparse.py +118 -0
- sage/rings/all__sagemath_symbolics.py +4 -0
- sage/rings/asymptotic/all.py +6 -0
- sage/rings/asymptotic/asymptotic_expansion_generators.py +1485 -0
- sage/rings/asymptotic/asymptotic_ring.py +4858 -0
- sage/rings/asymptotic/asymptotics_multivariate_generating_functions.py +4153 -0
- sage/rings/asymptotic/growth_group.py +5373 -0
- sage/rings/asymptotic/growth_group_cartesian.py +1400 -0
- sage/rings/asymptotic/term_monoid.py +5237 -0
- sage/rings/function_field/all__sagemath_symbolics.py +2 -0
- sage/rings/polynomial/all__sagemath_symbolics.py +1 -0
- sage/symbolic/all.py +15 -0
- sage/symbolic/assumptions.py +985 -0
- sage/symbolic/benchmark.py +93 -0
- sage/symbolic/callable.py +459 -0
- sage/symbolic/complexity_measures.py +35 -0
- sage/symbolic/constants.py +1287 -0
- sage/symbolic/expression_conversion_algebraic.py +310 -0
- sage/symbolic/expression_conversion_sympy.py +317 -0
- sage/symbolic/expression_conversions.py +1713 -0
- sage/symbolic/function_factory.py +355 -0
- sage/symbolic/integration/all.py +1 -0
- sage/symbolic/integration/external.py +270 -0
- sage/symbolic/integration/integral.py +1115 -0
- sage/symbolic/maxima_wrapper.py +162 -0
- sage/symbolic/operators.py +267 -0
- sage/symbolic/random_tests.py +462 -0
- sage/symbolic/relation.py +1907 -0
- sage/symbolic/ring.cpython-314t-x86_64-linux-musl.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,885 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-symbolics
|
|
2
|
+
r"""
|
|
3
|
+
Manifold Subsets Defined as Pullbacks of Subsets under Continuous Maps
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
# ****************************************************************************
|
|
8
|
+
# Copyright (C) 2021 Matthias Koeppe <mkoeppe@math.ucdavis.edu>
|
|
9
|
+
#
|
|
10
|
+
# This program is free software: you can redistribute it and/or modify
|
|
11
|
+
# it under the terms of the GNU General Public License as published by
|
|
12
|
+
# the Free Software Foundation, either version 2 of the License, or
|
|
13
|
+
# (at your option) any later version.
|
|
14
|
+
# https://www.gnu.org/licenses/
|
|
15
|
+
# ****************************************************************************
|
|
16
|
+
|
|
17
|
+
import sage.geometry.abc
|
|
18
|
+
from sage.categories.metric_spaces import MetricSpaces
|
|
19
|
+
from sage.categories.sets_cat import EmptySetError, Sets
|
|
20
|
+
from sage.manifolds.chart import Chart
|
|
21
|
+
from sage.manifolds.scalarfield import ScalarField
|
|
22
|
+
from sage.manifolds.subset import ManifoldSubset
|
|
23
|
+
from sage.misc.lazy_import import lazy_import
|
|
24
|
+
from sage.modules.free_module import FreeModule_generic
|
|
25
|
+
from sage.modules.free_module_element import vector
|
|
26
|
+
from sage.rings.complex_double import CDF
|
|
27
|
+
from sage.rings.infinity import infinity, minus_infinity
|
|
28
|
+
from sage.rings.integer_ring import ZZ
|
|
29
|
+
from sage.rings.rational_field import QQ
|
|
30
|
+
from sage.rings.real_double import RDF
|
|
31
|
+
from sage.rings.real_lazy import CLF, RLF
|
|
32
|
+
from sage.sets.real_set import RealSet
|
|
33
|
+
from sage.symbolic.ring import SR
|
|
34
|
+
|
|
35
|
+
lazy_import('sage.geometry.relative_interior', 'RelativeInterior')
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class ManifoldSubsetPullback(ManifoldSubset):
|
|
39
|
+
"""
|
|
40
|
+
Manifold subset defined as a pullback of a subset under a continuous map.
|
|
41
|
+
|
|
42
|
+
INPUT:
|
|
43
|
+
|
|
44
|
+
- ``map`` -- an instance of :class:`~sage.manifolds.continuous_map.ContinuousMap`,
|
|
45
|
+
:class:`ScalarField`, or :class:`Chart`
|
|
46
|
+
|
|
47
|
+
- ``codomain_subset`` -- an instance of :class:`~sage.manifolds.subset.ManifoldSubset`,
|
|
48
|
+
:class:`RealSet`, or :class:`~sage.geometry.convex_set.ConvexSet_base`
|
|
49
|
+
|
|
50
|
+
EXAMPLES::
|
|
51
|
+
|
|
52
|
+
sage: from sage.manifolds.subsets.pullback import ManifoldSubsetPullback
|
|
53
|
+
sage: M = Manifold(2, 'R^2', structure='topological')
|
|
54
|
+
sage: c_cart.<x,y> = M.chart() # Cartesian coordinates on R^2
|
|
55
|
+
|
|
56
|
+
Pulling back a real interval under a scalar field::
|
|
57
|
+
|
|
58
|
+
sage: r_squared = M.scalar_field(x^2+y^2)
|
|
59
|
+
sage: r_squared.set_immutable()
|
|
60
|
+
sage: cl_I = RealSet([1, 4]); cl_I
|
|
61
|
+
[1, 4]
|
|
62
|
+
sage: cl_O = ManifoldSubsetPullback(r_squared, cl_I); cl_O
|
|
63
|
+
Subset f_inv_[1, 4] of the 2-dimensional topological manifold R^2
|
|
64
|
+
sage: M.point((0, 0)) in cl_O
|
|
65
|
+
False
|
|
66
|
+
sage: M.point((0, 1)) in cl_O
|
|
67
|
+
True
|
|
68
|
+
|
|
69
|
+
Pulling back an open real interval gives an open subset::
|
|
70
|
+
|
|
71
|
+
sage: I = RealSet((1, 4)); I
|
|
72
|
+
(1, 4)
|
|
73
|
+
sage: O = ManifoldSubsetPullback(r_squared, I); O
|
|
74
|
+
Open subset f_inv_(1, 4) of the 2-dimensional topological manifold R^2
|
|
75
|
+
sage: M.point((1, 0)) in O
|
|
76
|
+
False
|
|
77
|
+
sage: M.point((1, 1)) in O
|
|
78
|
+
True
|
|
79
|
+
|
|
80
|
+
Pulling back a polytope under a chart::
|
|
81
|
+
|
|
82
|
+
sage: # needs sage.geometry.polyhedron
|
|
83
|
+
sage: P = Polyhedron(vertices=[[0, 0], [1, 2], [2, 1]]); P
|
|
84
|
+
A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 3 vertices
|
|
85
|
+
sage: S = ManifoldSubsetPullback(c_cart, P); S
|
|
86
|
+
Subset x_y_inv_P of the 2-dimensional topological manifold R^2
|
|
87
|
+
sage: M((1, 2)) in S
|
|
88
|
+
True
|
|
89
|
+
sage: M((2, 0)) in S
|
|
90
|
+
False
|
|
91
|
+
|
|
92
|
+
Pulling back the interior of a polytope under a chart::
|
|
93
|
+
|
|
94
|
+
sage: # needs sage.geometry.polyhedron
|
|
95
|
+
sage: int_P = P.interior(); int_P
|
|
96
|
+
Relative interior of a
|
|
97
|
+
2-dimensional polyhedron in ZZ^2 defined as the convex hull of 3 vertices
|
|
98
|
+
sage: int_S = ManifoldSubsetPullback(c_cart, int_P, name='int_S'); int_S
|
|
99
|
+
Open subset int_S of the 2-dimensional topological manifold R^2
|
|
100
|
+
sage: M((0, 0)) in int_S
|
|
101
|
+
False
|
|
102
|
+
sage: M((1, 1)) in int_S
|
|
103
|
+
True
|
|
104
|
+
|
|
105
|
+
Using the embedding map of a submanifold::
|
|
106
|
+
|
|
107
|
+
sage: M = Manifold(3, 'M', structure='topological')
|
|
108
|
+
sage: N = Manifold(2, 'N', ambient=M, structure='topological'); N
|
|
109
|
+
2-dimensional topological submanifold N
|
|
110
|
+
immersed in the 3-dimensional topological manifold M
|
|
111
|
+
sage: CM.<x,y,z> = M.chart()
|
|
112
|
+
sage: CN.<u,v> = N.chart()
|
|
113
|
+
sage: t = var('t')
|
|
114
|
+
sage: phi = N.continuous_map(M, {(CN,CM): [u,v,t+u^2+v^2]})
|
|
115
|
+
sage: phi_inv = M.continuous_map(N, {(CM,CN): [x,y]})
|
|
116
|
+
sage: phi_inv_t = M.scalar_field({CM: z-x^2-y^2})
|
|
117
|
+
sage: N.set_immersion(phi, inverse=phi_inv, var=t,
|
|
118
|
+
....: t_inverse={t: phi_inv_t})
|
|
119
|
+
sage: N.declare_embedding()
|
|
120
|
+
|
|
121
|
+
sage: from sage.manifolds.subsets.pullback import ManifoldSubsetPullback
|
|
122
|
+
sage: S = M.open_subset('S', coord_def={CM: z<1})
|
|
123
|
+
sage: phi_without_t = N.continuous_map(M, {(CN, CM): [expr.subs(t=0)
|
|
124
|
+
....: for expr in phi.expr()]})
|
|
125
|
+
sage: phi_without_t
|
|
126
|
+
Continuous map
|
|
127
|
+
from the 2-dimensional topological submanifold N
|
|
128
|
+
embedded in the 3-dimensional topological manifold M
|
|
129
|
+
to the 3-dimensional topological manifold M
|
|
130
|
+
sage: phi_without_t.expr()
|
|
131
|
+
(u, v, u^2 + v^2)
|
|
132
|
+
sage: D = ManifoldSubsetPullback(phi_without_t, S); D
|
|
133
|
+
Subset f_inv_S of the 2-dimensional topological submanifold N
|
|
134
|
+
embedded in the 3-dimensional topological manifold M
|
|
135
|
+
sage: N.point((2,0)) in D
|
|
136
|
+
False
|
|
137
|
+
"""
|
|
138
|
+
@staticmethod
|
|
139
|
+
def __classcall_private__(cls, map, codomain_subset, inverse=None,
|
|
140
|
+
name=None, latex_name=None):
|
|
141
|
+
"""
|
|
142
|
+
Normalize arguments and delegate to other constructors.
|
|
143
|
+
|
|
144
|
+
TESTS::
|
|
145
|
+
|
|
146
|
+
sage: # needs sage.geometry.polyhedron
|
|
147
|
+
sage: from sage.manifolds.subsets.pullback import ManifoldSubsetPullback
|
|
148
|
+
sage: M = Manifold(2, 'R^2', structure='topological')
|
|
149
|
+
sage: c_cart.<x,y> = M.chart() # Cartesian coordinates on R^2
|
|
150
|
+
sage: P = Polyhedron(vertices=[[0, 0], [1, 2], [3, 4]]); P
|
|
151
|
+
A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 3 vertices
|
|
152
|
+
sage: S = ManifoldSubsetPullback(c_cart, P); S
|
|
153
|
+
Subset x_y_inv_P of the 2-dimensional topological manifold R^2
|
|
154
|
+
sage: S is ManifoldSubsetPullback(c_cart, P)
|
|
155
|
+
True
|
|
156
|
+
"""
|
|
157
|
+
|
|
158
|
+
try:
|
|
159
|
+
is_mutable = map.is_mutable()
|
|
160
|
+
except AttributeError:
|
|
161
|
+
pass
|
|
162
|
+
else:
|
|
163
|
+
if is_mutable:
|
|
164
|
+
map = map.copy()
|
|
165
|
+
map.set_immutable()
|
|
166
|
+
try:
|
|
167
|
+
is_mutable = inverse.is_mutable()
|
|
168
|
+
except AttributeError:
|
|
169
|
+
pass
|
|
170
|
+
else:
|
|
171
|
+
if is_mutable:
|
|
172
|
+
inverse = inverse.copy()
|
|
173
|
+
inverse.set_immutable()
|
|
174
|
+
|
|
175
|
+
if inverse is None:
|
|
176
|
+
if isinstance(map, Chart):
|
|
177
|
+
from sage.misc.latex import latex
|
|
178
|
+
inverse_latex_name = '(' + ','.join(str(latex(x)) + '^{-1}' for x in map) + ')'
|
|
179
|
+
inverse_name = '_'.join(repr(x) for x in map) + '_inv'
|
|
180
|
+
else:
|
|
181
|
+
map_name = map._name or 'f'
|
|
182
|
+
map_latex_name = map._latex_name or map_name
|
|
183
|
+
inverse_name = map_name + '_inv'
|
|
184
|
+
inverse_latex_name = map_latex_name + r'^{-1}'
|
|
185
|
+
else:
|
|
186
|
+
inverse_name = inverse._name
|
|
187
|
+
inverse_latex_name = inverse._latex_name
|
|
188
|
+
try:
|
|
189
|
+
codomain_subset_latex_name = codomain_subset._latex_name
|
|
190
|
+
codomain_subset_name = codomain_subset._name
|
|
191
|
+
except AttributeError:
|
|
192
|
+
from sage.misc.latex import latex
|
|
193
|
+
codomain_subset_latex_name = str(latex(codomain_subset))
|
|
194
|
+
s = repr(codomain_subset)
|
|
195
|
+
if len(s) > 10:
|
|
196
|
+
codomain_subset_name = 'P'
|
|
197
|
+
else:
|
|
198
|
+
codomain_subset_name = s
|
|
199
|
+
if latex_name is None:
|
|
200
|
+
if name is None:
|
|
201
|
+
latex_name = inverse_latex_name + '(' + codomain_subset_latex_name + ')'
|
|
202
|
+
else:
|
|
203
|
+
latex_name = name
|
|
204
|
+
if name is None:
|
|
205
|
+
name = inverse_name + '_' + codomain_subset_name
|
|
206
|
+
|
|
207
|
+
if cls._is_open(codomain_subset):
|
|
208
|
+
|
|
209
|
+
try:
|
|
210
|
+
coord_def = cls._coord_def(map, codomain_subset)
|
|
211
|
+
except NotImplementedError:
|
|
212
|
+
pass
|
|
213
|
+
else:
|
|
214
|
+
return map.domain().open_subset(name=name, latex_name=latex_name,
|
|
215
|
+
coord_def=coord_def)
|
|
216
|
+
|
|
217
|
+
self = super().__classcall__(cls, map, codomain_subset, inverse, name, latex_name)
|
|
218
|
+
|
|
219
|
+
return self
|
|
220
|
+
|
|
221
|
+
@staticmethod
|
|
222
|
+
def _is_open(codomain_subset):
|
|
223
|
+
"""
|
|
224
|
+
Return whether ``codomain_subset`` is (known to be) an open subset of its ambient space.
|
|
225
|
+
|
|
226
|
+
EXAMPLES:
|
|
227
|
+
|
|
228
|
+
Manifolds and subsets::
|
|
229
|
+
|
|
230
|
+
sage: from sage.manifolds.subsets.pullback import ManifoldSubsetPullback
|
|
231
|
+
sage: R2 = Manifold(2, 'R^2', structure='topological'); R2
|
|
232
|
+
2-dimensional topological manifold R^2
|
|
233
|
+
sage: ManifoldSubsetPullback._is_open(R2)
|
|
234
|
+
True
|
|
235
|
+
sage: A = R2.subset('A'); A
|
|
236
|
+
Subset A of the 2-dimensional topological manifold R^2
|
|
237
|
+
sage: ManifoldSubsetPullback._is_open(A)
|
|
238
|
+
False
|
|
239
|
+
|
|
240
|
+
:class:`RealSet` instances::
|
|
241
|
+
|
|
242
|
+
sage: I = RealSet.open(1, 2); I
|
|
243
|
+
(1, 2)
|
|
244
|
+
sage: ManifoldSubsetPullback._is_open(I)
|
|
245
|
+
True
|
|
246
|
+
sage: cl_I = RealSet.closed(1, 2); cl_I
|
|
247
|
+
[1, 2]
|
|
248
|
+
sage: ManifoldSubsetPullback._is_open(cl_I)
|
|
249
|
+
False
|
|
250
|
+
|
|
251
|
+
Polyhedra::
|
|
252
|
+
|
|
253
|
+
sage: # needs sage.geometry.polyhedron
|
|
254
|
+
sage: Empty = Polyhedron(ambient_dim=2); Empty
|
|
255
|
+
The empty polyhedron in ZZ^2
|
|
256
|
+
sage: ManifoldSubsetPullback._is_open(Empty)
|
|
257
|
+
True
|
|
258
|
+
sage: C = polytopes.cube(); C
|
|
259
|
+
A 3-dimensional polyhedron in ZZ^3 defined as the convex hull of 8 vertices
|
|
260
|
+
sage: ManifoldSubsetPullback._is_open(C)
|
|
261
|
+
False
|
|
262
|
+
|
|
263
|
+
Interiors of polyhedra::
|
|
264
|
+
|
|
265
|
+
sage: int_C = C.interior(); int_C # needs sage.geometry.polyhedron
|
|
266
|
+
Relative interior of a
|
|
267
|
+
3-dimensional polyhedron in ZZ^3 defined as the convex hull of 8 vertices
|
|
268
|
+
sage: ManifoldSubsetPullback._is_open(int_C) # needs sage.geometry.polyhedron
|
|
269
|
+
True
|
|
270
|
+
|
|
271
|
+
PPL polyhedra and not-necessarily-closed polyhedra::
|
|
272
|
+
|
|
273
|
+
sage: # needs pplpy
|
|
274
|
+
sage: from ppl import Variable, C_Polyhedron, NNC_Polyhedron, Constraint_System
|
|
275
|
+
sage: u = Variable(0)
|
|
276
|
+
sage: v = Variable(1)
|
|
277
|
+
sage: CS = Constraint_System()
|
|
278
|
+
sage: CS.insert(0 < u)
|
|
279
|
+
sage: CS.insert(u < 1)
|
|
280
|
+
sage: CS.insert(0 < v)
|
|
281
|
+
sage: CS.insert(v < 1)
|
|
282
|
+
sage: CS.insert(u + v <= 3) # redundant inequality
|
|
283
|
+
sage: P = NNC_Polyhedron(CS); P
|
|
284
|
+
A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 1 point, 4 closure_points
|
|
285
|
+
sage: ManifoldSubsetPullback._is_open(P)
|
|
286
|
+
True
|
|
287
|
+
sage: CS.insert(u + v <= 1)
|
|
288
|
+
sage: T = NNC_Polyhedron(CS); T
|
|
289
|
+
A 2-dimensional polyhedron in QQ^2 defined as the convex hull of 1 point, 3 closure_points
|
|
290
|
+
sage: ManifoldSubsetPullback._is_open(T)
|
|
291
|
+
False
|
|
292
|
+
"""
|
|
293
|
+
|
|
294
|
+
if isinstance(codomain_subset, ManifoldSubset):
|
|
295
|
+
return codomain_subset.is_open()
|
|
296
|
+
|
|
297
|
+
if isinstance(codomain_subset, RealSet):
|
|
298
|
+
return codomain_subset.is_open()
|
|
299
|
+
|
|
300
|
+
if isinstance(codomain_subset, sage.geometry.abc.Polyhedron):
|
|
301
|
+
return codomain_subset.is_empty() or codomain_subset.is_universe()
|
|
302
|
+
|
|
303
|
+
if isinstance(codomain_subset, RelativeInterior):
|
|
304
|
+
return codomain_subset.closure().is_full_dimensional()
|
|
305
|
+
|
|
306
|
+
if codomain_subset in Sets().Finite():
|
|
307
|
+
return codomain_subset.cardinality() == 0
|
|
308
|
+
|
|
309
|
+
if hasattr(codomain_subset, 'minimized_constraints'):
|
|
310
|
+
try:
|
|
311
|
+
from ppl import C_Polyhedron, NNC_Polyhedron
|
|
312
|
+
except ImportError:
|
|
313
|
+
pass
|
|
314
|
+
else:
|
|
315
|
+
if isinstance(codomain_subset, (NNC_Polyhedron, C_Polyhedron)):
|
|
316
|
+
cs = codomain_subset.minimized_constraints()
|
|
317
|
+
if cs.has_equalities():
|
|
318
|
+
return False
|
|
319
|
+
if any(constraint.is_nonstrict_inequality()
|
|
320
|
+
for constraint in cs):
|
|
321
|
+
return False
|
|
322
|
+
return True
|
|
323
|
+
|
|
324
|
+
return False
|
|
325
|
+
|
|
326
|
+
@staticmethod
|
|
327
|
+
def _interval_restriction(expr, interval):
|
|
328
|
+
"""
|
|
329
|
+
Return a restriction expressing that ``expr`` lies in ``interval``.
|
|
330
|
+
|
|
331
|
+
INPUT:
|
|
332
|
+
|
|
333
|
+
- ``expr`` -- a symbolic expression
|
|
334
|
+
- ``interval`` -- an instance of :class:`~sage.sets.real_set.InternalRealInterval`
|
|
335
|
+
|
|
336
|
+
OUTPUT:
|
|
337
|
+
|
|
338
|
+
- A restriction suitable as input to :meth:`~sage.manifolds.chart.restrict`:
|
|
339
|
+
lists are conjunctions, tuples are disjunctions
|
|
340
|
+
|
|
341
|
+
EXAMPLES::
|
|
342
|
+
|
|
343
|
+
sage: from sage.manifolds.subsets.pullback import ManifoldSubsetPullback
|
|
344
|
+
sage: _interval_restriction = ManifoldSubsetPullback._interval_restriction
|
|
345
|
+
sage: var('t')
|
|
346
|
+
t
|
|
347
|
+
sage: assume(t >= -2)
|
|
348
|
+
sage: assume(t <= 5)
|
|
349
|
+
sage: _interval_restriction(t, RealSet(3, 4)[0])
|
|
350
|
+
[t > 3, t < 4]
|
|
351
|
+
sage: _interval_restriction(t, RealSet.unbounded_below_closed(2)[0])
|
|
352
|
+
t <= 2
|
|
353
|
+
sage: _interval_restriction(t, RealSet.closed(-5, 5)[0])
|
|
354
|
+
[]
|
|
355
|
+
sage: _interval_restriction(t, RealSet.unbounded_below_closed(-5)[0])
|
|
356
|
+
()
|
|
357
|
+
sage: _interval_restriction(t, RealSet.unbounded_above_closed(6)[0])
|
|
358
|
+
()
|
|
359
|
+
sage: _interval_restriction(t^2, RealSet.unbounded_above_closed(0)[0])
|
|
360
|
+
[]
|
|
361
|
+
"""
|
|
362
|
+
|
|
363
|
+
conjunction = []
|
|
364
|
+
if interval.lower() != minus_infinity:
|
|
365
|
+
if interval.lower_closed():
|
|
366
|
+
condition = (expr >= interval.lower())
|
|
367
|
+
negation = (expr < interval.lower())
|
|
368
|
+
else:
|
|
369
|
+
condition = (expr > interval.lower())
|
|
370
|
+
negation = (expr <= interval.lower())
|
|
371
|
+
if negation:
|
|
372
|
+
# known to be false
|
|
373
|
+
return ()
|
|
374
|
+
if not condition:
|
|
375
|
+
# not known to be true
|
|
376
|
+
conjunction.append(condition)
|
|
377
|
+
|
|
378
|
+
if interval.upper() != infinity:
|
|
379
|
+
if interval.upper_closed():
|
|
380
|
+
condition = (expr <= interval.upper())
|
|
381
|
+
negation = (expr > interval.upper())
|
|
382
|
+
else:
|
|
383
|
+
condition = (expr < interval.upper())
|
|
384
|
+
negation = (expr >= interval.upper())
|
|
385
|
+
if negation:
|
|
386
|
+
# known to be false
|
|
387
|
+
return ()
|
|
388
|
+
if not condition:
|
|
389
|
+
# not known to be true
|
|
390
|
+
conjunction.append(condition)
|
|
391
|
+
|
|
392
|
+
if len(conjunction) == 1:
|
|
393
|
+
return conjunction[0]
|
|
394
|
+
else:
|
|
395
|
+
# lists express 'and'
|
|
396
|
+
return conjunction
|
|
397
|
+
|
|
398
|
+
@staticmethod
|
|
399
|
+
def _realset_restriction(expr, realset):
|
|
400
|
+
"""
|
|
401
|
+
Return a restriction expressing that ``expr`` lies in ``realset``.
|
|
402
|
+
|
|
403
|
+
INPUT:
|
|
404
|
+
|
|
405
|
+
- ``expr`` -- a symbolic expression
|
|
406
|
+
- ``interval`` -- an instance of :class:`~sage.sets.real_set.RealSet`
|
|
407
|
+
|
|
408
|
+
OUTPUT:
|
|
409
|
+
|
|
410
|
+
- A restriction suitable as input to :meth:`~sage.manifolds.chart.restrict`:
|
|
411
|
+
lists are conjunctions, tuples are disjunctions
|
|
412
|
+
|
|
413
|
+
EXAMPLES::
|
|
414
|
+
|
|
415
|
+
sage: from sage.manifolds.subsets.pullback import ManifoldSubsetPullback
|
|
416
|
+
sage: _realset_restriction = ManifoldSubsetPullback._realset_restriction
|
|
417
|
+
sage: var('t')
|
|
418
|
+
t
|
|
419
|
+
sage: assume(t >= -2)
|
|
420
|
+
sage: assume(t <= 5)
|
|
421
|
+
sage: _realset_restriction(t, RealSet(-oo, oo))
|
|
422
|
+
[]
|
|
423
|
+
sage: _realset_restriction(t, RealSet())
|
|
424
|
+
()
|
|
425
|
+
sage: _realset_restriction(t, RealSet([-5, -4], (-1, 1), [3, 4], [6, 7]))
|
|
426
|
+
([t > -1, t < 1], [t >= 3, t <= 4])
|
|
427
|
+
"""
|
|
428
|
+
disjunction = []
|
|
429
|
+
for interval in realset:
|
|
430
|
+
condition = ManifoldSubsetPullback._interval_restriction(expr, interval)
|
|
431
|
+
if condition == []:
|
|
432
|
+
return []
|
|
433
|
+
if condition != ():
|
|
434
|
+
disjunction.append(condition)
|
|
435
|
+
|
|
436
|
+
if len(disjunction) == 1:
|
|
437
|
+
return disjunction[0]
|
|
438
|
+
else:
|
|
439
|
+
# tuples express 'or'
|
|
440
|
+
return tuple(disjunction)
|
|
441
|
+
|
|
442
|
+
@staticmethod
|
|
443
|
+
def _polyhedron_restriction(expr, polyhedron, relint=False):
|
|
444
|
+
"""
|
|
445
|
+
Return a restriction expressing that ``expr`` lies in ``polyhedron`` or its relative interior.
|
|
446
|
+
|
|
447
|
+
INPUT:
|
|
448
|
+
|
|
449
|
+
- ``expr`` -- a symbolic expression
|
|
450
|
+
- ``polyhedron`` -- an instance of :class:`~sage.geometry.polyhedron.base.Polyhedron_base`
|
|
451
|
+
- ``relint`` -- whether the restriction should use the relative interior
|
|
452
|
+
|
|
453
|
+
OUTPUT:
|
|
454
|
+
|
|
455
|
+
- A restriction suitable as input to :meth:`~sage.manifolds.chart.restrict`:
|
|
456
|
+
lists are conjunctions, tuples are disjunctions
|
|
457
|
+
|
|
458
|
+
EXAMPLES::
|
|
459
|
+
|
|
460
|
+
sage: from sage.manifolds.subsets.pullback import ManifoldSubsetPullback
|
|
461
|
+
sage: _polyhedron_restriction = ManifoldSubsetPullback._polyhedron_restriction
|
|
462
|
+
sage: var('x y z')
|
|
463
|
+
(x, y, z)
|
|
464
|
+
sage: c = polytopes.cube() # needs sage.geometry.polyhedron
|
|
465
|
+
sage: _polyhedron_restriction((x, y, z), c) # needs sage.geometry.polyhedron
|
|
466
|
+
[-x + 1 >= 0, -y + 1 >= 0, -z + 1 >= 0, x + 1 >= 0, z + 1 >= 0, y + 1 >= 0]
|
|
467
|
+
sage: _polyhedron_restriction((x, y, z), c, relint=True) # needs sage.geometry.polyhedron
|
|
468
|
+
[-x + 1 > 0, -y + 1 > 0, -z + 1 > 0, x + 1 > 0, z + 1 > 0, y + 1 > 0]
|
|
469
|
+
"""
|
|
470
|
+
conjunction = []
|
|
471
|
+
|
|
472
|
+
expr = vector(SR, expr)
|
|
473
|
+
for constraint in polyhedron.Hrepresentation():
|
|
474
|
+
|
|
475
|
+
if constraint.is_inequality():
|
|
476
|
+
if relint:
|
|
477
|
+
condition = (constraint.eval(expr) > 0)
|
|
478
|
+
else:
|
|
479
|
+
condition = (constraint.eval(expr) >= 0)
|
|
480
|
+
else:
|
|
481
|
+
condition = (constraint.eval(expr) == 0)
|
|
482
|
+
if not condition:
|
|
483
|
+
# not known to be true
|
|
484
|
+
conjunction.append(condition)
|
|
485
|
+
|
|
486
|
+
if len(conjunction) == 1:
|
|
487
|
+
return conjunction[0]
|
|
488
|
+
else:
|
|
489
|
+
# lists express 'and'
|
|
490
|
+
return conjunction
|
|
491
|
+
|
|
492
|
+
@staticmethod
|
|
493
|
+
def _coord_def(map, codomain_subset):
|
|
494
|
+
r"""
|
|
495
|
+
Return a coordinate definition of the open subset that is the pullback of ``codomain_subset``.
|
|
496
|
+
|
|
497
|
+
INPUT:
|
|
498
|
+
|
|
499
|
+
- ``map`` -- an instance of :class:`ScalarField` or :class:`Chart`
|
|
500
|
+
|
|
501
|
+
- ``codomain_subset`` -- if ``map`` is a :class:`ScalarField`, an
|
|
502
|
+
instance of :class:`RealSet`; if ``map`` is a :class:`Chart`, the
|
|
503
|
+
relative interior of a polyhedron
|
|
504
|
+
|
|
505
|
+
For other inputs, a :exc:`NotImplementedError` will be raised.
|
|
506
|
+
|
|
507
|
+
OUTPUT:
|
|
508
|
+
|
|
509
|
+
- an object suitable for the parameter ``coord_def`` of
|
|
510
|
+
:meth:`sage.manifolds.manifold.TopologicalManifold.open_subset`.
|
|
511
|
+
|
|
512
|
+
EXAMPLES::
|
|
513
|
+
|
|
514
|
+
sage: from sage.manifolds.subsets.pullback import ManifoldSubsetPullback
|
|
515
|
+
sage: _coord_def = ManifoldSubsetPullback._coord_def
|
|
516
|
+
sage: M = Manifold(2, 'R^2', structure='topological')
|
|
517
|
+
|
|
518
|
+
Coordinate definition of an open chart polyhedron::
|
|
519
|
+
|
|
520
|
+
sage: c_cart.<x,y> = M.chart() # Cartesian coordinates on R^2
|
|
521
|
+
sage: P = Polyhedron(vertices=[[0, 0], [1, 2], [3, 4]]); P # needs sage.geometry.polyhedron
|
|
522
|
+
A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 3 vertices
|
|
523
|
+
sage: ri_P = P.relative_interior(); ri_P # needs sage.geometry.polyhedron
|
|
524
|
+
Relative interior of a 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 3 vertices
|
|
525
|
+
sage: _coord_def(c_cart, ri_P) # needs sage.geometry.polyhedron
|
|
526
|
+
{Chart (R^2, (x, y)): [2*x - y > 0, -4*x + 3*y > 0, x - y + 1 > 0]}
|
|
527
|
+
|
|
528
|
+
Coordinate definition of the pullback of an open interval under a scalar field::
|
|
529
|
+
|
|
530
|
+
sage: r_squared = M.scalar_field(x^2 + y^2)
|
|
531
|
+
sage: I = RealSet((1, 4)); I
|
|
532
|
+
(1, 4)
|
|
533
|
+
sage: _coord_def(r_squared, I)
|
|
534
|
+
{Chart (R^2, (x, y)): [x^2 + y^2 > 1, x^2 + y^2 < 4]}
|
|
535
|
+
"""
|
|
536
|
+
if isinstance(map, ScalarField) and isinstance(codomain_subset, RealSet):
|
|
537
|
+
|
|
538
|
+
return {chart: ManifoldSubsetPullback._realset_restriction(func.expr(),
|
|
539
|
+
codomain_subset)
|
|
540
|
+
for chart, func in map._express.items()}
|
|
541
|
+
|
|
542
|
+
if isinstance(map, Chart):
|
|
543
|
+
|
|
544
|
+
chart = map
|
|
545
|
+
|
|
546
|
+
if isinstance(codomain_subset, RealSet):
|
|
547
|
+
return {chart: ManifoldSubsetPullback._realset_restriction(chart[0],
|
|
548
|
+
codomain_subset)}
|
|
549
|
+
|
|
550
|
+
if isinstance(codomain_subset, RelativeInterior) and isinstance(codomain_subset.closure(), sage.geometry.abc.Polyhedron):
|
|
551
|
+
return {chart: ManifoldSubsetPullback._polyhedron_restriction(
|
|
552
|
+
chart, codomain_subset.closure(), relint=True)}
|
|
553
|
+
|
|
554
|
+
raise NotImplementedError
|
|
555
|
+
|
|
556
|
+
def __init__(self, map, codomain_subset, inverse, name, latex_name):
|
|
557
|
+
r"""
|
|
558
|
+
Construct a manifold subset that is a pullback.
|
|
559
|
+
|
|
560
|
+
TESTS::
|
|
561
|
+
|
|
562
|
+
sage: from sage.manifolds.subsets.pullback import ManifoldSubsetPullback
|
|
563
|
+
sage: M = Manifold(2, 'R^2', structure='topological')
|
|
564
|
+
sage: c_cart.<x,y> = M.chart() # Cartesian coordinates on R^2
|
|
565
|
+
sage: r_squared = M.scalar_field(x^2+y^2)
|
|
566
|
+
sage: r_squared.set_immutable()
|
|
567
|
+
sage: cl_I = RealSet([1, 4]); cl_I
|
|
568
|
+
[1, 4]
|
|
569
|
+
sage: cl_O = ManifoldSubsetPullback(r_squared, cl_I); cl_O
|
|
570
|
+
Subset f_inv_[1, 4] of the 2-dimensional topological manifold R^2
|
|
571
|
+
sage: TestSuite(cl_O).run(skip='_test_elements')
|
|
572
|
+
"""
|
|
573
|
+
if inverse is None and isinstance(map, Chart):
|
|
574
|
+
chart = map
|
|
575
|
+
scalar_codomain = (isinstance(codomain_subset, RealSet)
|
|
576
|
+
or any(field.has_coerce_map_from(codomain_subset)
|
|
577
|
+
for field in (CDF, RDF, CLF, RLF)))
|
|
578
|
+
if scalar_codomain:
|
|
579
|
+
if chart.domain().dimension() != 1:
|
|
580
|
+
raise ValueError('to pull back a set of scalars by a chart, the manifold must be 1-dimensional')
|
|
581
|
+
map = chart.domain().scalar_field({chart: chart[0]})
|
|
582
|
+
|
|
583
|
+
def _inverse(coord):
|
|
584
|
+
return self.point((coord,), chart=chart)
|
|
585
|
+
else:
|
|
586
|
+
def _inverse(coords):
|
|
587
|
+
return self.point(coords, chart=map)
|
|
588
|
+
inverse = _inverse
|
|
589
|
+
|
|
590
|
+
self._map = map
|
|
591
|
+
self._inverse = inverse
|
|
592
|
+
|
|
593
|
+
self._codomain_subset = codomain_subset
|
|
594
|
+
base_manifold = map.domain()
|
|
595
|
+
ManifoldSubset.__init__(self, base_manifold, name, latex_name=latex_name)
|
|
596
|
+
|
|
597
|
+
def _an_element_(self):
|
|
598
|
+
r"""
|
|
599
|
+
Construct some point in ``self``.
|
|
600
|
+
|
|
601
|
+
EXAMPLES::
|
|
602
|
+
|
|
603
|
+
sage: # needs sage.geometry.polyhedron
|
|
604
|
+
sage: from sage.manifolds.subsets.pullback import ManifoldSubsetPullback
|
|
605
|
+
sage: M = Manifold(3, 'R^3', structure='topological')
|
|
606
|
+
sage: c_cart.<x,y,z> = M.chart() # Cartesian coordinates on R^3
|
|
607
|
+
sage: Cube = polytopes.cube(); Cube
|
|
608
|
+
A 3-dimensional polyhedron in ZZ^3 defined as the convex hull of 8 vertices
|
|
609
|
+
sage: McCube = ManifoldSubsetPullback(c_cart, Cube, name='McCube'); McCube
|
|
610
|
+
Subset McCube of the 3-dimensional topological manifold R^3
|
|
611
|
+
sage: p = McCube.an_element(); p
|
|
612
|
+
Point on the 3-dimensional topological manifold R^3
|
|
613
|
+
sage: p.coordinates(c_cart)
|
|
614
|
+
(0, 0, 0)
|
|
615
|
+
|
|
616
|
+
sage: # needs sage.geometry.polyhedron
|
|
617
|
+
sage: Empty = Polyhedron(ambient_dim=3)
|
|
618
|
+
sage: McEmpty = ManifoldSubsetPullback(c_cart, Empty, name='McEmpty')
|
|
619
|
+
sage: McEmpty
|
|
620
|
+
Subset McEmpty of the 3-dimensional topological manifold R^3
|
|
621
|
+
sage: McEmpty.an_element()
|
|
622
|
+
Traceback (most recent call last):
|
|
623
|
+
...
|
|
624
|
+
sage.categories.sets_cat.EmptySetError
|
|
625
|
+
"""
|
|
626
|
+
try:
|
|
627
|
+
return next(iter(self.some_elements()))
|
|
628
|
+
except StopIteration:
|
|
629
|
+
raise EmptySetError
|
|
630
|
+
|
|
631
|
+
def some_elements(self):
|
|
632
|
+
r"""
|
|
633
|
+
Generate some elements of ``self``.
|
|
634
|
+
|
|
635
|
+
EXAMPLES::
|
|
636
|
+
|
|
637
|
+
sage: # needs sage.geometry.polyhedron
|
|
638
|
+
sage: from sage.manifolds.subsets.pullback import ManifoldSubsetPullback
|
|
639
|
+
sage: M = Manifold(3, 'R^3', structure='topological')
|
|
640
|
+
sage: c_cart.<x,y,z> = M.chart() # Cartesian coordinates on R^3
|
|
641
|
+
sage: Cube = polytopes.cube(); Cube
|
|
642
|
+
A 3-dimensional polyhedron in ZZ^3 defined as the convex hull of 8 vertices
|
|
643
|
+
sage: McCube = ManifoldSubsetPullback(c_cart, Cube, name='McCube'); McCube
|
|
644
|
+
Subset McCube of the 3-dimensional topological manifold R^3
|
|
645
|
+
sage: L = list(McCube.some_elements()); L
|
|
646
|
+
[Point on the 3-dimensional topological manifold R^3,
|
|
647
|
+
Point on the 3-dimensional topological manifold R^3,
|
|
648
|
+
Point on the 3-dimensional topological manifold R^3,
|
|
649
|
+
Point on the 3-dimensional topological manifold R^3,
|
|
650
|
+
Point on the 3-dimensional topological manifold R^3,
|
|
651
|
+
Point on the 3-dimensional topological manifold R^3]
|
|
652
|
+
sage: list(p.coordinates(c_cart) for p in L)
|
|
653
|
+
[(0, 0, 0),
|
|
654
|
+
(1, -1, -1),
|
|
655
|
+
(1, 0, -1),
|
|
656
|
+
(1, 1/2, 0),
|
|
657
|
+
(1, -1/4, 1/2),
|
|
658
|
+
(0, -5/8, 3/4)]
|
|
659
|
+
|
|
660
|
+
sage: # needs sage.geometry.polyhedron
|
|
661
|
+
sage: Empty = Polyhedron(ambient_dim=3)
|
|
662
|
+
sage: McEmpty = ManifoldSubsetPullback(c_cart, Empty, name='McEmpty')
|
|
663
|
+
sage: McEmpty
|
|
664
|
+
Subset McEmpty of the 3-dimensional topological manifold R^3
|
|
665
|
+
sage: list(McEmpty.some_elements())
|
|
666
|
+
[]
|
|
667
|
+
"""
|
|
668
|
+
if self._inverse is not None:
|
|
669
|
+
for y in self._codomain_subset.some_elements():
|
|
670
|
+
yield self._inverse(y)
|
|
671
|
+
elif self.is_empty():
|
|
672
|
+
return
|
|
673
|
+
else:
|
|
674
|
+
# Fallback
|
|
675
|
+
p = super()._an_element_()
|
|
676
|
+
if p in self:
|
|
677
|
+
yield p
|
|
678
|
+
|
|
679
|
+
def __contains__(self, point):
|
|
680
|
+
r"""
|
|
681
|
+
Check whether ``point`` is contained in ``self``.
|
|
682
|
+
|
|
683
|
+
EXAMPLES::
|
|
684
|
+
|
|
685
|
+
sage: # needs sage.geometry.polyhedron
|
|
686
|
+
sage: from sage.manifolds.subsets.pullback import ManifoldSubsetPullback
|
|
687
|
+
sage: M = Manifold(3, 'R^3', structure='topological')
|
|
688
|
+
sage: c_cart.<x,y,z> = M.chart() # Cartesian coordinates on R^3
|
|
689
|
+
sage: Cube = polytopes.cube(); Cube
|
|
690
|
+
A 3-dimensional polyhedron in ZZ^3 defined as the convex hull of 8 vertices
|
|
691
|
+
sage: Cube.vertices_list()
|
|
692
|
+
[[1, -1, -1],
|
|
693
|
+
[1, 1, -1],
|
|
694
|
+
[1, 1, 1],
|
|
695
|
+
[1, -1, 1],
|
|
696
|
+
[-1, -1, 1],
|
|
697
|
+
[-1, -1, -1],
|
|
698
|
+
[-1, 1, -1],
|
|
699
|
+
[-1, 1, 1]]
|
|
700
|
+
sage: McCube = ManifoldSubsetPullback(c_cart, Cube, name='McCube'); McCube
|
|
701
|
+
Subset McCube of the 3-dimensional topological manifold R^3
|
|
702
|
+
sage: p = M.point((0, 0, 0)); p
|
|
703
|
+
Point on the 3-dimensional topological manifold R^3
|
|
704
|
+
sage: p in McCube
|
|
705
|
+
True
|
|
706
|
+
sage: q = M.point((2, 3, 4)); q
|
|
707
|
+
Point on the 3-dimensional topological manifold R^3
|
|
708
|
+
sage: q in McCube
|
|
709
|
+
False
|
|
710
|
+
"""
|
|
711
|
+
if super().__contains__(point):
|
|
712
|
+
return True
|
|
713
|
+
coords = self._map(point)
|
|
714
|
+
if isinstance(coords, (tuple, list)):
|
|
715
|
+
coords = vector(coords)
|
|
716
|
+
return coords in self._codomain_subset
|
|
717
|
+
|
|
718
|
+
def is_open(self):
|
|
719
|
+
"""
|
|
720
|
+
Return if ``self`` is (known to be) an open set.
|
|
721
|
+
|
|
722
|
+
This version of the method always returns ``False``.
|
|
723
|
+
|
|
724
|
+
Because the map is continuous, the pullback is open if the
|
|
725
|
+
``codomain_subset`` is open.
|
|
726
|
+
|
|
727
|
+
However, the design of :class:`~sage.manifolds.subset.ManifoldSubset` requires that open subsets
|
|
728
|
+
are instances of the subclass :class:`sage.manifolds.manifold.TopologicalManifold`.
|
|
729
|
+
The constructor of :class:`ManifoldSubsetPullback` delegates to a subclass
|
|
730
|
+
of :class:`sage.manifolds.manifold.TopologicalManifold` for some open subsets.
|
|
731
|
+
|
|
732
|
+
EXAMPLES::
|
|
733
|
+
|
|
734
|
+
sage: from sage.manifolds.subsets.pullback import ManifoldSubsetPullback
|
|
735
|
+
sage: M = Manifold(2, 'R^2', structure='topological')
|
|
736
|
+
sage: c_cart.<x,y> = M.chart() # Cartesian coordinates on R^2
|
|
737
|
+
|
|
738
|
+
sage: # needs sage.geometry.polyhedron
|
|
739
|
+
sage: P = Polyhedron(vertices=[[0, 0], [1, 2], [3, 4]]); P
|
|
740
|
+
A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 3 vertices
|
|
741
|
+
sage: P.is_open()
|
|
742
|
+
False
|
|
743
|
+
sage: McP = ManifoldSubsetPullback(c_cart, P, name='McP'); McP
|
|
744
|
+
Subset McP of the 2-dimensional topological manifold R^2
|
|
745
|
+
sage: McP.is_open()
|
|
746
|
+
False
|
|
747
|
+
"""
|
|
748
|
+
return super().is_open()
|
|
749
|
+
|
|
750
|
+
def is_closed(self):
|
|
751
|
+
"""
|
|
752
|
+
Return if ``self`` is (known to be) a closed subset of the manifold.
|
|
753
|
+
|
|
754
|
+
EXAMPLES::
|
|
755
|
+
|
|
756
|
+
sage: from sage.manifolds.subsets.pullback import ManifoldSubsetPullback
|
|
757
|
+
sage: M = Manifold(2, 'R^2', structure='topological')
|
|
758
|
+
sage: c_cart.<x,y> = M.chart() # Cartesian coordinates on R^2
|
|
759
|
+
|
|
760
|
+
The pullback of a closed real interval under a scalar field is closed::
|
|
761
|
+
|
|
762
|
+
sage: r_squared = M.scalar_field(x^2+y^2)
|
|
763
|
+
sage: r_squared.set_immutable()
|
|
764
|
+
sage: cl_I = RealSet([1, 2]); cl_I
|
|
765
|
+
[1, 2]
|
|
766
|
+
sage: cl_O = ManifoldSubsetPullback(r_squared, cl_I); cl_O
|
|
767
|
+
Subset f_inv_[1, 2] of the 2-dimensional topological manifold R^2
|
|
768
|
+
sage: cl_O.is_closed()
|
|
769
|
+
True
|
|
770
|
+
|
|
771
|
+
The pullback of a (closed convex) polyhedron under a chart is closed::
|
|
772
|
+
|
|
773
|
+
sage: # needs sage.geometry.polyhedron
|
|
774
|
+
sage: P = Polyhedron(vertices=[[0, 0], [1, 2], [3, 4]]); P
|
|
775
|
+
A 2-dimensional polyhedron in ZZ^2 defined as the convex hull of 3 vertices
|
|
776
|
+
sage: McP = ManifoldSubsetPullback(c_cart, P, name='McP'); McP
|
|
777
|
+
Subset McP of the 2-dimensional topological manifold R^2
|
|
778
|
+
sage: McP.is_closed()
|
|
779
|
+
True
|
|
780
|
+
|
|
781
|
+
The pullback of real vector subspaces under a chart is closed::
|
|
782
|
+
|
|
783
|
+
sage: V = span([[1, 2]], RR); V
|
|
784
|
+
Vector space of degree 2 and dimension 1 over Real Field with 53 bits of precision
|
|
785
|
+
Basis matrix:
|
|
786
|
+
[1.00000000000000 2.00000000000000]
|
|
787
|
+
sage: McV = ManifoldSubsetPullback(c_cart, V, name='McV'); McV
|
|
788
|
+
Subset McV of the 2-dimensional topological manifold R^2
|
|
789
|
+
sage: McV.is_closed()
|
|
790
|
+
True
|
|
791
|
+
|
|
792
|
+
The pullback of point lattices under a chart is closed::
|
|
793
|
+
|
|
794
|
+
sage: W = span([[1, 0], [3, 5]], ZZ); W
|
|
795
|
+
Free module of degree 2 and rank 2 over Integer Ring
|
|
796
|
+
Echelon basis matrix:
|
|
797
|
+
[1 0]
|
|
798
|
+
[0 5]
|
|
799
|
+
sage: McW = ManifoldSubsetPullback(c_cart, W, name='McW'); McW
|
|
800
|
+
Subset McW of the 2-dimensional topological manifold R^2
|
|
801
|
+
sage: McW.is_closed()
|
|
802
|
+
True
|
|
803
|
+
|
|
804
|
+
The pullback of finite sets is closed::
|
|
805
|
+
|
|
806
|
+
sage: F = Family([vector(QQ, [1, 2], immutable=True), vector(QQ, [2, 3], immutable=True)])
|
|
807
|
+
sage: McF = ManifoldSubsetPullback(c_cart, F, name='McF'); McF
|
|
808
|
+
Subset McF of the 2-dimensional topological manifold R^2
|
|
809
|
+
sage: McF.is_closed()
|
|
810
|
+
True
|
|
811
|
+
"""
|
|
812
|
+
if self.manifold().dimension() == 0:
|
|
813
|
+
return True
|
|
814
|
+
if isinstance(self._codomain_subset, ManifoldSubset):
|
|
815
|
+
if self._codomain_subset.is_closed():
|
|
816
|
+
# known closed
|
|
817
|
+
return True
|
|
818
|
+
elif isinstance(self._codomain_subset, RealSet):
|
|
819
|
+
# RealSet can decide closedness authoritatively
|
|
820
|
+
return self._codomain_subset.is_closed()
|
|
821
|
+
elif isinstance(self._codomain_subset, sage.geometry.abc.Polyhedron):
|
|
822
|
+
# Regardless of their base_ring, we treat polyhedra as closed
|
|
823
|
+
# convex subsets of R^n
|
|
824
|
+
return True
|
|
825
|
+
elif isinstance(self._codomain_subset, FreeModule_generic) and self._codomain_subset.rank() != infinity:
|
|
826
|
+
if self._codomain_subset.base_ring() in MetricSpaces().Complete():
|
|
827
|
+
# Closed topological vector subspace
|
|
828
|
+
return True
|
|
829
|
+
if self._codomain_subset.base_ring() == ZZ:
|
|
830
|
+
if self._codomain_subset.coordinate_ring().is_subring(QQ):
|
|
831
|
+
# Discrete subgroup of R^n
|
|
832
|
+
return True
|
|
833
|
+
if self._codomain_subset.rank() == self._codomain_subset.base_extend(RR).dimension():
|
|
834
|
+
# Discrete subgroup of R^n
|
|
835
|
+
return True
|
|
836
|
+
elif self._codomain_subset in Sets().Finite():
|
|
837
|
+
return True
|
|
838
|
+
else:
|
|
839
|
+
if hasattr(self._codomain_subset, 'is_topologically_closed'):
|
|
840
|
+
try:
|
|
841
|
+
from ppl import C_Polyhedron, NNC_Polyhedron
|
|
842
|
+
except ImportError:
|
|
843
|
+
pass
|
|
844
|
+
else:
|
|
845
|
+
if isinstance(self._codomain_subset, (NNC_Polyhedron, C_Polyhedron)):
|
|
846
|
+
# ppl polyhedra can decide closedness authoritatively
|
|
847
|
+
return self._codomain_subset.is_topologically_closed()
|
|
848
|
+
return super().is_closed()
|
|
849
|
+
|
|
850
|
+
def closure(self, name=None, latex_name=None):
|
|
851
|
+
"""
|
|
852
|
+
Return the topological closure of ``self`` in the manifold.
|
|
853
|
+
|
|
854
|
+
Because ``self`` is a pullback of some subset under a continuous map,
|
|
855
|
+
the closure of ``self`` is the pullback of the closure.
|
|
856
|
+
|
|
857
|
+
EXAMPLES::
|
|
858
|
+
|
|
859
|
+
sage: from sage.manifolds.subsets.pullback import ManifoldSubsetPullback
|
|
860
|
+
sage: M = Manifold(2, 'R^2', structure='topological')
|
|
861
|
+
sage: c_cart.<x,y> = M.chart() # Cartesian coordinates on R^2
|
|
862
|
+
sage: r_squared = M.scalar_field(x^2+y^2)
|
|
863
|
+
sage: r_squared.set_immutable()
|
|
864
|
+
sage: I = RealSet.open_closed(1, 2); I
|
|
865
|
+
(1, 2]
|
|
866
|
+
sage: O = ManifoldSubsetPullback(r_squared, I); O
|
|
867
|
+
Subset f_inv_(1, 2] of the 2-dimensional topological manifold R^2
|
|
868
|
+
sage: latex(O)
|
|
869
|
+
f^{-1}((1, 2])
|
|
870
|
+
sage: cl_O = O.closure(); cl_O
|
|
871
|
+
Subset f_inv_[1, 2] of the 2-dimensional topological manifold R^2
|
|
872
|
+
sage: cl_O.is_closed()
|
|
873
|
+
True
|
|
874
|
+
"""
|
|
875
|
+
if self.is_closed():
|
|
876
|
+
return self
|
|
877
|
+
try:
|
|
878
|
+
codomain_subset_closure = self._codomain_subset.closure()
|
|
879
|
+
except AttributeError:
|
|
880
|
+
return super().closure()
|
|
881
|
+
closure = ManifoldSubsetPullback(self._map, codomain_subset_closure,
|
|
882
|
+
inverse=self._inverse,
|
|
883
|
+
name=name, latex_name=latex_name)
|
|
884
|
+
closure.declare_superset(self)
|
|
885
|
+
return closure
|