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.

Files changed (171) hide show
  1. passagemath_symbolics/__init__.py +3 -0
  2. passagemath_symbolics-10.6.43.dist-info/METADATA +187 -0
  3. passagemath_symbolics-10.6.43.dist-info/RECORD +171 -0
  4. passagemath_symbolics-10.6.43.dist-info/WHEEL +5 -0
  5. passagemath_symbolics-10.6.43.dist-info/top_level.txt +3 -0
  6. sage/all__sagemath_symbolics.py +17 -0
  7. sage/calculus/all.py +14 -0
  8. sage/calculus/calculus.py +2826 -0
  9. sage/calculus/desolvers.py +1866 -0
  10. sage/calculus/predefined.py +51 -0
  11. sage/calculus/tests.py +225 -0
  12. sage/calculus/var.cpython-314t-x86_64-linux-musl.so +0 -0
  13. sage/calculus/var.pyx +401 -0
  14. sage/dynamics/all__sagemath_symbolics.py +6 -0
  15. sage/dynamics/complex_dynamics/all.py +5 -0
  16. sage/dynamics/complex_dynamics/mandel_julia.py +765 -0
  17. sage/dynamics/complex_dynamics/mandel_julia_helper.cpython-314t-x86_64-linux-musl.so +0 -0
  18. sage/dynamics/complex_dynamics/mandel_julia_helper.pyx +1035 -0
  19. sage/ext/all__sagemath_symbolics.py +1 -0
  20. sage/ext_data/kenzo/CP2.txt +45 -0
  21. sage/ext_data/kenzo/CP3.txt +349 -0
  22. sage/ext_data/kenzo/CP4.txt +4774 -0
  23. sage/ext_data/kenzo/README.txt +49 -0
  24. sage/ext_data/kenzo/S4.txt +20 -0
  25. sage/ext_data/magma/latex/latex.m +1021 -0
  26. sage/ext_data/magma/latex/latex.spec +1 -0
  27. sage/ext_data/magma/sage/basic.m +356 -0
  28. sage/ext_data/magma/sage/sage.spec +1 -0
  29. sage/ext_data/magma/spec +9 -0
  30. sage/geometry/all__sagemath_symbolics.py +8 -0
  31. sage/geometry/hyperbolic_space/all.py +5 -0
  32. sage/geometry/hyperbolic_space/hyperbolic_coercion.py +743 -0
  33. sage/geometry/hyperbolic_space/hyperbolic_constants.py +5 -0
  34. sage/geometry/hyperbolic_space/hyperbolic_geodesic.py +2409 -0
  35. sage/geometry/hyperbolic_space/hyperbolic_interface.py +206 -0
  36. sage/geometry/hyperbolic_space/hyperbolic_isometry.py +1082 -0
  37. sage/geometry/hyperbolic_space/hyperbolic_model.py +1502 -0
  38. sage/geometry/hyperbolic_space/hyperbolic_point.py +621 -0
  39. sage/geometry/riemannian_manifolds/all.py +7 -0
  40. sage/geometry/riemannian_manifolds/parametrized_surface3d.py +1632 -0
  41. sage/geometry/riemannian_manifolds/surface3d_generators.py +461 -0
  42. sage/interfaces/all__sagemath_symbolics.py +1 -0
  43. sage/interfaces/magma.py +3017 -0
  44. sage/interfaces/magma_free.py +92 -0
  45. sage/interfaces/maple.py +1397 -0
  46. sage/interfaces/mathematica.py +1345 -0
  47. sage/interfaces/mathics.py +1312 -0
  48. sage/interfaces/sympy.py +1398 -0
  49. sage/interfaces/sympy_wrapper.py +197 -0
  50. sage/interfaces/tides.py +938 -0
  51. sage/libs/all__sagemath_symbolics.py +6 -0
  52. sage/manifolds/all.py +7 -0
  53. sage/manifolds/calculus_method.py +555 -0
  54. sage/manifolds/catalog.py +437 -0
  55. sage/manifolds/chart.py +4019 -0
  56. sage/manifolds/chart_func.py +3419 -0
  57. sage/manifolds/continuous_map.py +2183 -0
  58. sage/manifolds/continuous_map_image.py +155 -0
  59. sage/manifolds/differentiable/affine_connection.py +2475 -0
  60. sage/manifolds/differentiable/all.py +1 -0
  61. sage/manifolds/differentiable/automorphismfield.py +1383 -0
  62. sage/manifolds/differentiable/automorphismfield_group.py +604 -0
  63. sage/manifolds/differentiable/bundle_connection.py +1445 -0
  64. sage/manifolds/differentiable/characteristic_cohomology_class.py +1840 -0
  65. sage/manifolds/differentiable/chart.py +1241 -0
  66. sage/manifolds/differentiable/curve.py +1028 -0
  67. sage/manifolds/differentiable/de_rham_cohomology.py +541 -0
  68. sage/manifolds/differentiable/degenerate.py +559 -0
  69. sage/manifolds/differentiable/degenerate_submanifold.py +1671 -0
  70. sage/manifolds/differentiable/diff_form.py +1658 -0
  71. sage/manifolds/differentiable/diff_form_module.py +1062 -0
  72. sage/manifolds/differentiable/diff_map.py +1315 -0
  73. sage/manifolds/differentiable/differentiable_submanifold.py +291 -0
  74. sage/manifolds/differentiable/examples/all.py +1 -0
  75. sage/manifolds/differentiable/examples/euclidean.py +2517 -0
  76. sage/manifolds/differentiable/examples/real_line.py +897 -0
  77. sage/manifolds/differentiable/examples/sphere.py +1186 -0
  78. sage/manifolds/differentiable/examples/symplectic_space.py +187 -0
  79. sage/manifolds/differentiable/examples/symplectic_space_test.py +40 -0
  80. sage/manifolds/differentiable/integrated_curve.py +4035 -0
  81. sage/manifolds/differentiable/levi_civita_connection.py +841 -0
  82. sage/manifolds/differentiable/manifold.py +4254 -0
  83. sage/manifolds/differentiable/manifold_homset.py +1826 -0
  84. sage/manifolds/differentiable/metric.py +3032 -0
  85. sage/manifolds/differentiable/mixed_form.py +1507 -0
  86. sage/manifolds/differentiable/mixed_form_algebra.py +559 -0
  87. sage/manifolds/differentiable/multivector_module.py +800 -0
  88. sage/manifolds/differentiable/multivectorfield.py +1520 -0
  89. sage/manifolds/differentiable/poisson_tensor.py +268 -0
  90. sage/manifolds/differentiable/pseudo_riemannian.py +755 -0
  91. sage/manifolds/differentiable/pseudo_riemannian_submanifold.py +1839 -0
  92. sage/manifolds/differentiable/scalarfield.py +1343 -0
  93. sage/manifolds/differentiable/scalarfield_algebra.py +472 -0
  94. sage/manifolds/differentiable/symplectic_form.py +910 -0
  95. sage/manifolds/differentiable/symplectic_form_test.py +220 -0
  96. sage/manifolds/differentiable/tangent_space.py +412 -0
  97. sage/manifolds/differentiable/tangent_vector.py +616 -0
  98. sage/manifolds/differentiable/tensorfield.py +4665 -0
  99. sage/manifolds/differentiable/tensorfield_module.py +963 -0
  100. sage/manifolds/differentiable/tensorfield_paral.py +2450 -0
  101. sage/manifolds/differentiable/tensorfield_paral_test.py +16 -0
  102. sage/manifolds/differentiable/vector_bundle.py +1728 -0
  103. sage/manifolds/differentiable/vectorfield.py +1717 -0
  104. sage/manifolds/differentiable/vectorfield_module.py +2445 -0
  105. sage/manifolds/differentiable/vectorframe.py +1832 -0
  106. sage/manifolds/family.py +270 -0
  107. sage/manifolds/local_frame.py +1490 -0
  108. sage/manifolds/manifold.py +3090 -0
  109. sage/manifolds/manifold_homset.py +452 -0
  110. sage/manifolds/operators.py +359 -0
  111. sage/manifolds/point.py +994 -0
  112. sage/manifolds/scalarfield.py +3718 -0
  113. sage/manifolds/scalarfield_algebra.py +629 -0
  114. sage/manifolds/section.py +3111 -0
  115. sage/manifolds/section_module.py +831 -0
  116. sage/manifolds/structure.py +229 -0
  117. sage/manifolds/subset.py +2764 -0
  118. sage/manifolds/subsets/all.py +1 -0
  119. sage/manifolds/subsets/closure.py +131 -0
  120. sage/manifolds/subsets/pullback.py +885 -0
  121. sage/manifolds/topological_submanifold.py +891 -0
  122. sage/manifolds/trivialization.py +733 -0
  123. sage/manifolds/utilities.py +1348 -0
  124. sage/manifolds/vector_bundle.py +1342 -0
  125. sage/manifolds/vector_bundle_fiber.py +332 -0
  126. sage/manifolds/vector_bundle_fiber_element.py +111 -0
  127. sage/matrix/all__sagemath_symbolics.py +1 -0
  128. sage/matrix/matrix_symbolic_dense.cpython-314t-x86_64-linux-musl.so +0 -0
  129. sage/matrix/matrix_symbolic_dense.pxd +6 -0
  130. sage/matrix/matrix_symbolic_dense.pyx +1022 -0
  131. sage/matrix/matrix_symbolic_sparse.cpython-314t-x86_64-linux-musl.so +0 -0
  132. sage/matrix/matrix_symbolic_sparse.pxd +6 -0
  133. sage/matrix/matrix_symbolic_sparse.pyx +1029 -0
  134. sage/modules/all__sagemath_symbolics.py +1 -0
  135. sage/modules/vector_callable_symbolic_dense.py +105 -0
  136. sage/modules/vector_symbolic_dense.py +116 -0
  137. sage/modules/vector_symbolic_sparse.py +118 -0
  138. sage/rings/all__sagemath_symbolics.py +4 -0
  139. sage/rings/asymptotic/all.py +6 -0
  140. sage/rings/asymptotic/asymptotic_expansion_generators.py +1485 -0
  141. sage/rings/asymptotic/asymptotic_ring.py +4858 -0
  142. sage/rings/asymptotic/asymptotics_multivariate_generating_functions.py +4153 -0
  143. sage/rings/asymptotic/growth_group.py +5373 -0
  144. sage/rings/asymptotic/growth_group_cartesian.py +1400 -0
  145. sage/rings/asymptotic/term_monoid.py +5237 -0
  146. sage/rings/function_field/all__sagemath_symbolics.py +2 -0
  147. sage/rings/polynomial/all__sagemath_symbolics.py +1 -0
  148. sage/symbolic/all.py +15 -0
  149. sage/symbolic/assumptions.py +985 -0
  150. sage/symbolic/benchmark.py +93 -0
  151. sage/symbolic/callable.py +459 -0
  152. sage/symbolic/complexity_measures.py +35 -0
  153. sage/symbolic/constants.py +1287 -0
  154. sage/symbolic/expression_conversion_algebraic.py +310 -0
  155. sage/symbolic/expression_conversion_sympy.py +317 -0
  156. sage/symbolic/expression_conversions.py +1713 -0
  157. sage/symbolic/function_factory.py +355 -0
  158. sage/symbolic/integration/all.py +1 -0
  159. sage/symbolic/integration/external.py +270 -0
  160. sage/symbolic/integration/integral.py +1115 -0
  161. sage/symbolic/maxima_wrapper.py +162 -0
  162. sage/symbolic/operators.py +267 -0
  163. sage/symbolic/random_tests.py +462 -0
  164. sage/symbolic/relation.py +1907 -0
  165. sage/symbolic/ring.cpython-314t-x86_64-linux-musl.so +0 -0
  166. sage/symbolic/ring.pxd +5 -0
  167. sage/symbolic/ring.pyx +1396 -0
  168. sage/symbolic/subring.py +1025 -0
  169. sage/symbolic/symengine.py +19 -0
  170. sage/symbolic/tests.py +40 -0
  171. sage/symbolic/units.py +1470 -0
@@ -0,0 +1,994 @@
1
+ # sage_setup: distribution = sagemath-symbolics
2
+ r"""
3
+ Points of Topological Manifolds
4
+
5
+ The class :class:`ManifoldPoint` implements points of a
6
+ topological manifold.
7
+
8
+ A :class:`ManifoldPoint` object can have coordinates in
9
+ various charts defined on the manifold. Two points are declared
10
+ equal if they have the same coordinates in the same chart.
11
+
12
+ AUTHORS:
13
+
14
+ - Eric Gourgoulhon, Michal Bejger (2013-2015) : initial version
15
+
16
+ REFERENCES:
17
+
18
+ - [Lee2011]_
19
+ - [Lee2013]_
20
+
21
+ EXAMPLES:
22
+
23
+ Defining a point in `\RR^3` by its spherical coordinates::
24
+
25
+ sage: M = Manifold(3, 'R^3', structure='topological')
26
+ sage: U = M.open_subset('U') # the domain of spherical coordinates
27
+ sage: c_spher.<r,th,ph> = U.chart(r'r:(0,+oo) th:(0,pi):\theta ph:(0,2*pi):periodic:\phi')
28
+
29
+ We construct the point in the coordinates in the default chart of ``U``
30
+ (``c_spher``)::
31
+
32
+ sage: p = U((1, pi/2, pi), name='P')
33
+ sage: p
34
+ Point P on the 3-dimensional topological manifold R^3
35
+ sage: latex(p)
36
+ P
37
+ sage: p in U
38
+ True
39
+ sage: p.parent()
40
+ Open subset U of the 3-dimensional topological manifold R^3
41
+ sage: c_spher(p)
42
+ (1, 1/2*pi, pi)
43
+ sage: p.coordinates(c_spher) # equivalent to above
44
+ (1, 1/2*pi, pi)
45
+
46
+ Computing the coordinates of ``p`` in a new chart::
47
+
48
+ sage: c_cart.<x,y,z> = U.chart() # Cartesian coordinates on U
49
+ sage: spher_to_cart = c_spher.transition_map(c_cart,
50
+ ....: [r*sin(th)*cos(ph), r*sin(th)*sin(ph), r*cos(th)])
51
+ sage: c_cart(p) # evaluate P's Cartesian coordinates
52
+ (-1, 0, 0)
53
+
54
+ Points can be compared::
55
+
56
+ sage: p1 = U((1, pi/2, pi))
57
+ sage: p1 == p
58
+ True
59
+ sage: q = U((2, pi/2, pi))
60
+ sage: q == p
61
+ False
62
+
63
+ even if they were initially not defined within the same coordinate chart::
64
+
65
+ sage: p2 = U((-1,0,0), chart=c_cart)
66
+ sage: p2 == p
67
+ True
68
+
69
+ The `2\pi`-periodicity of the `\phi` coordinate is also taken into account
70
+ for the comparison::
71
+
72
+ sage: p3 = U((1, pi/2, 5*pi))
73
+ sage: p3 == p
74
+ True
75
+ sage: p4 = U((1, pi/2, -pi))
76
+ sage: p4 == p
77
+ True
78
+ """
79
+
80
+ #*****************************************************************************
81
+ # Copyright (C) 2015 Eric Gourgoulhon <eric.gourgoulhon@obspm.fr>
82
+ # Copyright (C) 2015 Michal Bejger <bejger@camk.edu.pl>
83
+ #
84
+ # This program is free software: you can redistribute it and/or modify
85
+ # it under the terms of the GNU General Public License as published by
86
+ # the Free Software Foundation, either version 2 of the License, or
87
+ # (at your option) any later version.
88
+ # https://www.gnu.org/licenses/
89
+ #*****************************************************************************
90
+
91
+ from sage.misc.decorators import options
92
+ from sage.rings.integer_ring import ZZ
93
+ from sage.structure.element import Element
94
+ from sage.symbolic.expression import Expression
95
+
96
+
97
+ class ManifoldPoint(Element):
98
+ r"""
99
+ Point of a topological manifold.
100
+
101
+ This is a Sage *element* class, the corresponding *parent* class
102
+ being :class:`~sage.manifolds.manifold.TopologicalManifold`
103
+ or :class:`~sage.manifolds.subset.ManifoldSubset`.
104
+
105
+ INPUT:
106
+
107
+ - ``parent`` -- the manifold subset to which the point belongs
108
+ - ``coords`` -- (default: ``None``) the point coordinates (as a tuple
109
+ or a list) in the chart ``chart``
110
+ - ``chart`` -- (default: ``None``) chart in which the coordinates are
111
+ given; if ``None``, the coordinates are assumed to refer to the
112
+ default chart of ``parent``
113
+ - ``name`` -- (default: ``None``) name given to the point
114
+ - ``latex_name`` -- (default: ``None``) LaTeX symbol to denote the point;
115
+ if ``None``, the LaTeX symbol is set to ``name``
116
+ - ``check_coords`` -- boolean (default: ``True``); determines whether ``coords``
117
+ are valid coordinates for the chart ``chart``. For symbolic
118
+ coordinates, it is recommended to set ``check_coords`` to ``False``.
119
+
120
+ EXAMPLES:
121
+
122
+ A point on a 2-dimensional manifold::
123
+
124
+ sage: M = Manifold(2, 'M', structure='topological')
125
+ sage: c_xy.<x,y> = M.chart()
126
+ sage: (a, b) = var('a b') # generic coordinates for the point
127
+ sage: p = M.point((a, b), name='P'); p
128
+ Point P on the 2-dimensional topological manifold M
129
+ sage: p.coordinates() # coordinates of P in the subset's default chart
130
+ (a, b)
131
+
132
+ Since points are Sage *elements*, the *parent* of which being the
133
+ subset on which they are defined, it is equivalent to write::
134
+
135
+ sage: p = M((a, b), name='P'); p
136
+ Point P on the 2-dimensional topological manifold M
137
+
138
+ A point is an element of the manifold subset in which it has
139
+ been defined::
140
+
141
+ sage: p in M
142
+ True
143
+ sage: p.parent()
144
+ 2-dimensional topological manifold M
145
+ sage: U = M.open_subset('U', coord_def={c_xy: x>0})
146
+ sage: q = U.point((2,1), name='q')
147
+ sage: q.parent()
148
+ Open subset U of the 2-dimensional topological manifold M
149
+ sage: q in U
150
+ True
151
+ sage: q in M
152
+ True
153
+
154
+ By default, the LaTeX symbol of the point is deduced from its name::
155
+
156
+ sage: latex(p)
157
+ P
158
+
159
+ But it can be set to any value::
160
+
161
+ sage: p = M.point((a, b), name='P', latex_name=r'\mathcal{P}')
162
+ sage: latex(p)
163
+ \mathcal{P}
164
+
165
+ Points can be drawn in 2D or 3D graphics thanks to the
166
+ method :meth:`plot`.
167
+ """
168
+ def __init__(self, parent, coords=None, chart=None, name=None,
169
+ latex_name=None, check_coords=True):
170
+ r"""
171
+ Construct a manifold point.
172
+
173
+ TESTS::
174
+
175
+ sage: M = Manifold(2, 'M', structure='topological')
176
+ sage: X.<x,y> = M.chart()
177
+ sage: p = M((2,3), name='p'); p
178
+ Point p on the 2-dimensional topological manifold M
179
+ sage: TestSuite(p).run()
180
+ sage: U = M.open_subset('U', coord_def={X: x<0})
181
+ sage: q = U((-1,2), name='q'); q
182
+ Point q on the 2-dimensional topological manifold M
183
+ sage: TestSuite(q).run()
184
+ """
185
+ if parent.is_empty():
186
+ raise TypeError(f'cannot define a point on the {parent} because it has been declared empty')
187
+ Element.__init__(self, parent)
188
+ parent._has_defined_points = True
189
+ self._manifold = parent.manifold() # a useful shortcut
190
+ self._coordinates = {} # dictionary of the point coordinates in various
191
+ # charts, with the charts as keys
192
+ if coords is not None:
193
+ if len(coords) != parent.manifold().dimension():
194
+ raise ValueError("the number of coordinates must be equal " +
195
+ "to the manifold's dimension")
196
+ from sage.manifolds.manifold import TopologicalManifold
197
+ if chart is None:
198
+ chart = parent._def_chart
199
+ elif isinstance(parent, TopologicalManifold):
200
+ if chart not in parent._atlas:
201
+ raise ValueError("the {} has not been".format(chart) +
202
+ "defined on the {}".format(parent))
203
+ if check_coords:
204
+ if not chart.valid_coordinates(*coords):
205
+ raise ValueError("the coordinates {}".format(coords) +
206
+ " are not valid on the {}".format(chart))
207
+ for schart in chart._supercharts:
208
+ self._coordinates[schart] = tuple(coords)
209
+ for schart in chart._subcharts:
210
+ if schart != chart:
211
+ if schart.valid_coordinates(*coords):
212
+ self._coordinates[schart] = tuple(coords)
213
+ self._name = name
214
+ if latex_name is None:
215
+ self._latex_name = self._name
216
+ else:
217
+ self._latex_name = latex_name
218
+
219
+ def _repr_(self):
220
+ r"""
221
+ Return a string representation of the point.
222
+
223
+ TESTS::
224
+
225
+ sage: M = Manifold(2, 'M', structure='topological')
226
+ sage: X.<x,y> = M.chart()
227
+ sage: p = M((2,-3))
228
+ sage: p._repr_()
229
+ 'Point on the 2-dimensional topological manifold M'
230
+ sage: p = M((2,-3), name='p')
231
+ sage: p._repr_()
232
+ 'Point p on the 2-dimensional topological manifold M'
233
+ sage: repr(p) # indirect doctest
234
+ 'Point p on the 2-dimensional topological manifold M'
235
+ """
236
+ description = "Point"
237
+ if self._name is not None:
238
+ description += " " + self._name
239
+ description += " on the {}".format(self._manifold)
240
+ return description
241
+
242
+ def _latex_(self):
243
+ r"""
244
+ Return a LaTeX representation of the point.
245
+
246
+ TESTS::
247
+
248
+ sage: M = Manifold(2, 'M', structure='topological')
249
+ sage: X.<x,y> = M.chart()
250
+ sage: p = M((2,-3))
251
+ sage: p._latex_()
252
+ '\\text{Point on the 2-dimensional topological manifold M}'
253
+ sage: p = M((2,-3), name='p')
254
+ sage: p._latex_()
255
+ 'p'
256
+ sage: p = M((2,-3), name='p', latex_name=r'\mathcal{P}')
257
+ sage: p._latex_()
258
+ '\\mathcal{P}'
259
+ sage: latex(p) # indirect doctest
260
+ \mathcal{P}
261
+ """
262
+ if self._latex_name is None:
263
+ return r'\text{' + str(self) + r'}'
264
+ return self._latex_name
265
+
266
+ def coordinates(self, chart=None, old_chart=None):
267
+ r"""
268
+ Return the point coordinates in the specified chart.
269
+
270
+ If these coordinates are not already known, they are computed from
271
+ known ones by means of change-of-chart formulas.
272
+
273
+ An equivalent way to get the coordinates of a point is to let the
274
+ chart acting on the point, i.e. if ``X`` is a chart and ``p`` a
275
+ point, one has ``p.coordinates(chart=X) == X(p)``.
276
+
277
+ INPUT:
278
+
279
+ - ``chart`` -- (default: ``None``) chart in which the coordinates
280
+ are given; if none are provided, the coordinates are assumed to
281
+ refer to the subset's default chart
282
+ - ``old_chart`` -- (default: ``None``) chart from which the
283
+ coordinates in ``chart`` are to be computed; if ``None``, a chart
284
+ in which the point's coordinates are already known will be picked,
285
+ privileging the subset's default chart
286
+
287
+ EXAMPLES:
288
+
289
+ Spherical coordinates of a point on `\RR^3`::
290
+
291
+ sage: M = Manifold(3, 'M', structure='topological')
292
+ sage: c_spher.<r,th,ph> = M.chart(r'r:(0,+oo) th:(0,pi):\theta ph:(0,2*pi):\phi') # spherical coordinates
293
+ sage: p = M.point((1, pi/2, pi))
294
+ sage: p.coordinates() # coordinates in the manifold's default chart
295
+ (1, 1/2*pi, pi)
296
+
297
+ Since the default chart of ``M`` is ``c_spher``, it is equivalent to
298
+ write::
299
+
300
+ sage: p.coordinates(c_spher)
301
+ (1, 1/2*pi, pi)
302
+
303
+ An alternative way to get the coordinates is to let the chart act
304
+ on the point (from the very definition of a chart)::
305
+
306
+ sage: c_spher(p)
307
+ (1, 1/2*pi, pi)
308
+
309
+ A shortcut for ``coordinates`` is ``coord``::
310
+
311
+ sage: p.coord()
312
+ (1, 1/2*pi, pi)
313
+
314
+ Computing the Cartesian coordinates from the spherical ones::
315
+
316
+ sage: c_cart.<x,y,z> = M.chart() # Cartesian coordinates
317
+ sage: c_spher.transition_map(c_cart, [r*sin(th)*cos(ph),
318
+ ....: r*sin(th)*sin(ph), r*cos(th)])
319
+ Change of coordinates from Chart (M, (r, th, ph)) to Chart (M, (x, y, z))
320
+
321
+ The computation is performed by means of the above change
322
+ of coordinates::
323
+
324
+ sage: p.coord(c_cart)
325
+ (-1, 0, 0)
326
+ sage: p.coord(c_cart) == c_cart(p)
327
+ True
328
+
329
+ Coordinates of a point on a 2-dimensional manifold::
330
+
331
+ sage: M = Manifold(2, 'M', structure='topological')
332
+ sage: c_xy.<x,y> = M.chart()
333
+ sage: (a, b) = var('a b') # generic coordinates for the point
334
+ sage: P = M.point((a, b), name='P')
335
+
336
+ Coordinates of ``P`` in the manifold's default chart::
337
+
338
+ sage: P.coord()
339
+ (a, b)
340
+
341
+ Coordinates of ``P`` in a new chart::
342
+
343
+ sage: c_uv.<u,v> = M.chart()
344
+ sage: ch_xy_uv = c_xy.transition_map(c_uv, [x-y, x+y])
345
+ sage: P.coord(c_uv)
346
+ (a - b, a + b)
347
+
348
+ Coordinates of ``P`` in a third chart::
349
+
350
+ sage: c_wz.<w,z> = M.chart()
351
+ sage: ch_uv_wz = c_uv.transition_map(c_wz, [u^3, v^3])
352
+ sage: P.coord(c_wz, old_chart=c_uv)
353
+ (a^3 - 3*a^2*b + 3*a*b^2 - b^3, a^3 + 3*a^2*b + 3*a*b^2 + b^3)
354
+
355
+ Actually, in the present case, it is not necessary to specify
356
+ ``old_chart='uv'``. Note that the first command erases all
357
+ the coordinates except those in the chart ``c_uv``::
358
+
359
+ sage: P.set_coord((a-b, a+b), c_uv)
360
+ sage: P._coordinates
361
+ {Chart (M, (u, v)): (a - b, a + b)}
362
+ sage: P.coord(c_wz)
363
+ (a^3 - 3*a^2*b + 3*a*b^2 - b^3, a^3 + 3*a^2*b + 3*a*b^2 + b^3)
364
+ sage: P._coordinates # random (dictionary output)
365
+ {Chart (M, (u, v)): (a - b, a + b),
366
+ Chart (M, (w, z)): (a^3 - 3*a^2*b + 3*a*b^2 - b^3,
367
+ a^3 + 3*a^2*b + 3*a*b^2 + b^3)}
368
+ """
369
+ if chart is None:
370
+ dom = self.parent()
371
+ chart = dom._def_chart
372
+ def_chart = chart
373
+ else:
374
+ dom = chart.domain()
375
+ def_chart = dom._def_chart
376
+ if self not in dom:
377
+ raise ValueError("the point does not belong to the domain " +
378
+ "of {}".format(chart))
379
+ if chart not in self._coordinates:
380
+ # Check whether chart corresponds to a superchart of a chart
381
+ # in which the coordinates are known:
382
+ for ochart in self._coordinates:
383
+ if chart in ochart._supercharts or chart in ochart._subcharts:
384
+ self._coordinates[chart] = self._coordinates[ochart]
385
+ return self._coordinates[chart]
386
+ # If this point is reached, some change of coordinates must be
387
+ # performed
388
+ if old_chart is not None:
389
+ s_old_chart = old_chart
390
+ s_chart = chart
391
+ else:
392
+ # A chart must be found as a starting point of the computation
393
+ # The domain's default chart is privileged:
394
+ if (def_chart in self._coordinates
395
+ and (def_chart, chart) in dom._coord_changes):
396
+ old_chart = def_chart
397
+ s_old_chart = def_chart
398
+ s_chart = chart
399
+ else:
400
+ for ochart in self._coordinates:
401
+ for subchart in ochart._subcharts:
402
+ if (subchart, chart) in dom._coord_changes:
403
+ old_chart = ochart
404
+ s_old_chart = subchart
405
+ s_chart = chart
406
+ break
407
+ if old_chart is not None:
408
+ break
409
+ if old_chart is None:
410
+ # Some search involving the subcharts of chart is
411
+ # performed:
412
+ for schart in chart._subcharts:
413
+ for ochart in self._coordinates:
414
+ for subchart in ochart._subcharts:
415
+ if (subchart, schart) in dom._coord_changes:
416
+ old_chart = ochart
417
+ s_old_chart = subchart
418
+ s_chart = schart
419
+ break
420
+ if old_chart is not None:
421
+ break
422
+ if old_chart is not None:
423
+ break
424
+ if old_chart is None:
425
+ raise ValueError("the coordinates of {}".format(self) +
426
+ " in the {}".format(chart) + " cannot be computed " +
427
+ "by means of known changes of charts.")
428
+ else:
429
+ chcoord = dom._coord_changes[(s_old_chart, s_chart)]
430
+ self._coordinates[chart] = chcoord(*self._coordinates[old_chart])
431
+ return self._coordinates[chart]
432
+
433
+ coord = coordinates
434
+
435
+ def set_coordinates(self, coords, chart=None):
436
+ r"""
437
+ Set the point coordinates in the specified chart.
438
+
439
+ Coordinates with respect to other charts are deleted, in order to
440
+ avoid any inconsistency. To keep them, use the method :meth:`add_coord`
441
+ instead.
442
+
443
+ INPUT:
444
+
445
+ - ``coords`` -- the point coordinates (as a tuple or a list)
446
+ - ``chart`` -- (default: ``None``) chart in which the coordinates
447
+ are given; if none are provided, the coordinates are assumed to
448
+ refer to the subset's default chart
449
+
450
+ EXAMPLES:
451
+
452
+ Setting coordinates to a point on a 2-dimensional manifold::
453
+
454
+ sage: M = Manifold(2, 'M', structure='topological')
455
+ sage: X.<x,y> = M.chart()
456
+ sage: p = M.point()
457
+
458
+ We set the coordinates in the manifold's default chart::
459
+
460
+ sage: p.set_coordinates((2,-3))
461
+ sage: p.coordinates()
462
+ (2, -3)
463
+ sage: X(p)
464
+ (2, -3)
465
+
466
+ A shortcut for ``set_coordinates`` is ``set_coord``::
467
+
468
+ sage: p.set_coord((2,-3))
469
+ sage: p.coord()
470
+ (2, -3)
471
+
472
+ Let us introduce a second chart on the manifold::
473
+
474
+ sage: Y.<u,v> = M.chart()
475
+ sage: X_to_Y = X.transition_map(Y, [x+y, x-y])
476
+
477
+ If we set the coordinates of ``p`` in chart ``Y``, those in chart ``X``
478
+ are lost::
479
+
480
+ sage: Y(p)
481
+ (-1, 5)
482
+ sage: p.set_coord(Y(p), chart=Y)
483
+ sage: p._coordinates
484
+ {Chart (M, (u, v)): (-1, 5)}
485
+ """
486
+ self._coordinates.clear()
487
+ self.add_coord(coords, chart)
488
+
489
+ set_coord = set_coordinates
490
+
491
+ def add_coordinates(self, coords, chart=None):
492
+ r"""
493
+ Add some coordinates in the specified chart.
494
+
495
+ The previous coordinates with respect to other charts are kept. To
496
+ clear them, use :meth:`set_coord` instead.
497
+
498
+ INPUT:
499
+
500
+ - ``coords`` -- the point coordinates (as a tuple or a list)
501
+ - ``chart`` -- (default: ``None``) chart in which the coordinates
502
+ are given; if none are provided, the coordinates are assumed to
503
+ refer to the subset's default chart
504
+
505
+ .. WARNING::
506
+
507
+ If the point has already coordinates in other charts, it
508
+ is the user's responsibility to make sure that the coordinates
509
+ to be added are consistent with them.
510
+
511
+ EXAMPLES:
512
+
513
+ Setting coordinates to a point on a 2-dimensional manifold::
514
+
515
+ sage: M = Manifold(2, 'M', structure='topological')
516
+ sage: X.<x,y> = M.chart()
517
+ sage: p = M.point()
518
+
519
+ We give the point some coordinates in the manifold's default chart::
520
+
521
+ sage: p.add_coordinates((2,-3))
522
+ sage: p.coordinates()
523
+ (2, -3)
524
+ sage: X(p)
525
+ (2, -3)
526
+
527
+ A shortcut for ``add_coordinates`` is ``add_coord``::
528
+
529
+ sage: p.add_coord((2,-3))
530
+ sage: p.coord()
531
+ (2, -3)
532
+
533
+ Let us introduce a second chart on the manifold::
534
+
535
+ sage: Y.<u,v> = M.chart()
536
+ sage: X_to_Y = X.transition_map(Y, [x+y, x-y])
537
+
538
+ If we add coordinates for ``p`` in chart ``Y``, those in chart ``X``
539
+ are kept::
540
+
541
+ sage: p.add_coordinates((-1,5), chart=Y)
542
+ sage: p._coordinates # random (dictionary output)
543
+ {Chart (M, (u, v)): (-1, 5), Chart (M, (x, y)): (2, -3)}
544
+
545
+ On the contrary, with the method :meth:`set_coordinates`, the
546
+ coordinates in charts different from ``Y`` would be lost::
547
+
548
+ sage: p.set_coordinates((-1,5), chart=Y)
549
+ sage: p._coordinates
550
+ {Chart (M, (u, v)): (-1, 5)}
551
+ """
552
+ if len(coords) != self.parent().manifold()._dim:
553
+ raise ValueError("the number of coordinates must be equal to " +
554
+ "the manifold's dimension.")
555
+ if chart is None:
556
+ chart = self.parent()._def_chart
557
+ else:
558
+ if chart not in self.parent()._atlas:
559
+ raise ValueError("the {}".format(chart) + " has not been " +
560
+ "defined on the {}".format(self.parent()))
561
+ self._coordinates[chart] = coords
562
+
563
+ add_coord = add_coordinates
564
+
565
+ def __eq__(self, other):
566
+ r"""
567
+ Compare the current point with another one.
568
+
569
+ EXAMPLES:
570
+
571
+ Comparison with coordinates in the same chart::
572
+
573
+ sage: M = Manifold(2, 'M', structure='topological')
574
+ sage: X.<x,y> = M.chart()
575
+ sage: p = M((2,-3), chart=X)
576
+ sage: q = M((2,-3), chart=X)
577
+ sage: p == q
578
+ True
579
+ sage: q = M((-2,-3), chart=X)
580
+ sage: p == q
581
+ False
582
+
583
+ Comparison with coordinates of other in a subchart::
584
+
585
+ sage: U = M.open_subset('U', coord_def={X: x>0})
586
+ sage: XU = X.restrict(U)
587
+ sage: q = U((2,-3), chart=XU)
588
+ sage: p == q and q == p
589
+ True
590
+ sage: q = U((1,-3), chart=XU)
591
+ sage: p == q or q == p
592
+ False
593
+
594
+ Comparison requiring a change of chart::
595
+
596
+ sage: Y.<u,v> = U.chart()
597
+ sage: XU_to_Y = XU.transition_map(Y, (ln(x), x+y))
598
+ sage: XU_to_Y.inverse()(u,v)
599
+ (e^u, v - e^u)
600
+ sage: q = U((ln(2),-1), chart=Y)
601
+ sage: p == q and q == p
602
+ True
603
+ sage: q = U((ln(3),1), chart=Y)
604
+ sage: p == q or q == p
605
+ False
606
+
607
+ Comparison with periodic coordinates::
608
+
609
+ sage: M = Manifold(2, 'M', structure='topological')
610
+ sage: X.<x,y> = M.chart('x y:period=2')
611
+ sage: p = M((0,1))
612
+ sage: q = M((0,3))
613
+ sage: p == q and q == p
614
+ True
615
+ sage: q = M((0,2))
616
+ sage: p == q or q == p
617
+ False
618
+ sage: Y.<u,v> = M.chart('u:(0,2*pi):periodic v')
619
+ sage: p = M((0,1), chart=Y)
620
+ sage: q = M((-4*pi,1), chart=Y)
621
+ sage: p == q and q == p
622
+ True
623
+ sage: q = M((3*pi,1), chart=Y)
624
+ sage: p == q or q == p
625
+ False
626
+ """
627
+ if other is self:
628
+ return True
629
+ if not isinstance(other, ManifoldPoint):
630
+ return False
631
+ if other.parent().manifold() != self.parent().manifold():
632
+ return False
633
+ # Search for a common chart to compare the coordinates
634
+ common_chart = None
635
+ # the subset's default chart is privileged:
636
+ # FIXME: Make this a better test
637
+ if hasattr(self.parent(), '_def_chart'): # self.parent() is open
638
+ def_chart = self.parent()._def_chart
639
+ else:
640
+ def_chart = self.parent().manifold()._def_chart
641
+ if def_chart in self._coordinates and def_chart in other._coordinates:
642
+ common_chart = def_chart
643
+ else:
644
+ for chart in self._coordinates:
645
+ if chart in other._coordinates:
646
+ common_chart = chart
647
+ break
648
+ if common_chart is None:
649
+ # A common chart is searched via a coordinate transformation,
650
+ # privileging the default chart
651
+ if def_chart in self._coordinates:
652
+ try:
653
+ other.coordinates(def_chart)
654
+ common_chart = def_chart
655
+ except ValueError:
656
+ pass
657
+ if common_chart is None:
658
+ if def_chart in other._coordinates:
659
+ try:
660
+ self.coordinates(def_chart)
661
+ common_chart = def_chart
662
+ except ValueError:
663
+ pass
664
+ if common_chart is None:
665
+ # At this stage, a common chart is searched via a coordinate
666
+ # transformation from any chart
667
+ for chart in self._coordinates:
668
+ try:
669
+ other.coordinates(chart)
670
+ common_chart = chart
671
+ break
672
+ except ValueError:
673
+ pass
674
+ else:
675
+ # Attempt a coordinate transformation in the reverse way:
676
+ for chart in other._coordinates:
677
+ try:
678
+ self.coordinates(chart)
679
+ common_chart = chart
680
+ break
681
+ except ValueError:
682
+ pass
683
+ if common_chart is None:
684
+ return False
685
+ #!# Another option would be:
686
+ # raise ValueError("no common chart has been found to compare " +
687
+ # "{} and {}".format(self, other))
688
+ periods = common_chart.periods()
689
+ for ind, (xs, xo) in enumerate(zip(self._coordinates[common_chart],
690
+ other._coordinates[common_chart])):
691
+ diff = xs - xo
692
+ period = periods[ind]
693
+ if period is not None:
694
+ if diff/period not in ZZ:
695
+ return False
696
+ else:
697
+ if isinstance(diff, Expression) and not diff.is_trivial_zero():
698
+ return False
699
+ elif not (diff == 0):
700
+ return False
701
+ return True
702
+
703
+ def __ne__(self, other):
704
+ r"""
705
+ Non-equality operator.
706
+
707
+ TESTS::
708
+
709
+ sage: M = Manifold(2, 'M', structure='topological')
710
+ sage: X.<x,y> = M.chart()
711
+ sage: p = M((2,-3), chart=X)
712
+ sage: q = M((0,1), chart=X)
713
+ sage: p != q
714
+ True
715
+ sage: p != M((2,-3), chart=X)
716
+ False
717
+ """
718
+ return not (self == other)
719
+
720
+ def __hash__(self):
721
+ r"""
722
+ Return the hash of ``self``.
723
+
724
+ This hash function is set to constant on a given manifold, to fulfill
725
+ Python's credo::
726
+
727
+ p == q ==> hash(p) == hash(q)
728
+
729
+ This is necessary since ``p`` and ``q`` may be created in
730
+ different coordinate systems and nevertheless be equal.
731
+
732
+ .. TODO::
733
+
734
+ Find a better hash function.
735
+
736
+ TESTS::
737
+
738
+ sage: M = Manifold(2, 'M', structure='topological')
739
+ sage: X.<x,y> = M.chart()
740
+ sage: p = M((2,-3), chart=X)
741
+ sage: hash(p) == hash(M)
742
+ True
743
+ """
744
+ return hash(self.parent().manifold())
745
+
746
+ @options(size=10, color='black', label_color=None, fontsize=10, label_offset=0.1)
747
+ def plot(self, chart=None, ambient_coords=None, mapping=None,
748
+ label=None, parameters=None, **kwds):
749
+ r"""
750
+ For real manifolds, plot ``self`` in a Cartesian graph based
751
+ on the coordinates of some ambient chart.
752
+
753
+ The point is drawn in terms of two (2D graphics) or three (3D graphics)
754
+ coordinates of a given chart, called hereafter the *ambient chart*.
755
+ The domain of the ambient chart must contain the point, or its image
756
+ by a continuous manifold map `\Phi`.
757
+
758
+ INPUT:
759
+
760
+ - ``chart`` -- (default: ``None``) the ambient chart (see above); if
761
+ ``None``, the ambient chart is set the default chart of
762
+ ``self.parent()``
763
+ - ``ambient_coords`` -- (default: ``None``) tuple containing the 2
764
+ or 3 coordinates of the ambient chart in terms of which the plot
765
+ is performed; if ``None``, all the coordinates of the ambient
766
+ chart are considered
767
+ - ``mapping`` -- (default: ``None``)
768
+ :class:`~sage.manifolds.continuous_map.ContinuousMap`; continuous
769
+ manifold map `\Phi` providing the link between the current point
770
+ `p` and the ambient chart ``chart``: the domain of ``chart`` must
771
+ contain `\Phi(p)`; if ``None``, the identity map is assumed
772
+ - ``label`` -- (default: ``None``) label printed next to the point;
773
+ if ``None``, the point's name is used
774
+ - ``parameters`` -- (default: ``None``) dictionary giving the numerical
775
+ values of the parameters that may appear in the point coordinates
776
+ - ``size`` -- (default: 10) size of the point once drawn as a small
777
+ disk or sphere
778
+ - ``color`` -- (default: ``'black'``) color of the point
779
+ - ``label_color`` -- (default: ``None``) color to print the label;
780
+ if ``None``, the value of ``color`` is used
781
+ - ``fontsize`` -- (default: 10) size of the font used to print the
782
+ label
783
+ - ``label_offset`` -- (default: 0.1) determines the separation between
784
+ the point and its label
785
+
786
+ OUTPUT:
787
+
788
+ - a graphic object, either an instance of
789
+ :class:`~sage.plot.graphics.Graphics` for a 2D plot (i.e. based on
790
+ 2 coordinates of the ambient chart) or an instance of
791
+ :class:`~sage.plot.plot3d.base.Graphics3d` for a 3D plot (i.e.
792
+ based on 3 coordinates of the ambient chart)
793
+
794
+ EXAMPLES:
795
+
796
+ Drawing a point on a 2-dimensional manifold::
797
+
798
+ sage: # needs sage.plot
799
+ sage: M = Manifold(2, 'M', structure='topological')
800
+ sage: X.<x,y> = M.chart()
801
+ sage: p = M.point((1,3), name='p')
802
+ sage: g = p.plot(X)
803
+ sage: print(g)
804
+ Graphics object consisting of 2 graphics primitives
805
+ sage: gX = X.plot(max_range=4) # plot of the coordinate grid
806
+ sage: g + gX # display of the point atop the coordinate grid
807
+ Graphics object consisting of 20 graphics primitives
808
+
809
+ .. PLOT::
810
+
811
+ M = Manifold(2, 'M', structure='topological')
812
+ X = M.chart('x y'); x,y = X[:]
813
+ p = M.point((1,3), name='p')
814
+ g = p.plot(X)
815
+ gX = X.plot(max_range=4)
816
+ sphinx_plot(g+gX)
817
+
818
+ Actually, since ``X`` is the default chart of the open set in which
819
+ ``p`` has been defined, it can be skipped in the arguments of
820
+ ``plot``::
821
+
822
+ sage: # needs sage.plot
823
+ sage: g = p.plot()
824
+ sage: g + gX
825
+ Graphics object consisting of 20 graphics primitives
826
+
827
+ Call with some options::
828
+
829
+ sage: # needs sage.plot
830
+ sage: g = p.plot(chart=X, size=40, color='green', label='$P$',
831
+ ....: label_color='blue', fontsize=20, label_offset=0.3)
832
+ sage: g + gX
833
+ Graphics object consisting of 20 graphics primitives
834
+
835
+ .. PLOT::
836
+
837
+ M = Manifold(2, 'M', structure='topological')
838
+ X = M.chart('x y'); x,y = X[:]
839
+ p = M.point((1,3), name='p')
840
+ g = p.plot(chart=X, size=40, color='green', label='$P$', \
841
+ label_color='blue', fontsize=20, label_offset=0.3)
842
+ gX = X.plot(max_range=4)
843
+ sphinx_plot(g+gX)
844
+
845
+ Use of the ``parameters`` option to set a numerical value of some
846
+ symbolic variable::
847
+
848
+ sage: a = var('a')
849
+ sage: q = M.point((a,2*a), name='q') # needs sage.plot
850
+ sage: gq = q.plot(parameters={a:-2}, label_offset=0.2) # needs sage.plot
851
+ sage: g + gX + gq # needs sage.plot
852
+ Graphics object consisting of 22 graphics primitives
853
+
854
+ .. PLOT::
855
+
856
+ M = Manifold(2, 'M', structure='topological')
857
+ X = M.chart('x y'); x,y = X[:]
858
+ p = M.point((1,3), name='p')
859
+ g = p.plot(chart=X, size=40, color='green', label='$P$', \
860
+ label_color='blue', fontsize=20, label_offset=0.3)
861
+ var('a')
862
+ q = M.point((a,2*a), name='q')
863
+ gq = q.plot(parameters={a:-2}, label_offset=0.2)
864
+ gX = X.plot(max_range=4)
865
+ sphinx_plot(g+gX+gq)
866
+
867
+ The numerical value is used only for the plot::
868
+
869
+ sage: q.coord() # needs sage.plot
870
+ (a, 2*a)
871
+
872
+ Drawing a point on a 3-dimensional manifold::
873
+
874
+ sage: # needs sage.plot
875
+ sage: M = Manifold(3, 'M', structure='topological')
876
+ sage: X.<x,y,z> = M.chart()
877
+ sage: p = M.point((2,1,3), name='p')
878
+ sage: g = p.plot()
879
+ sage: print(g)
880
+ Graphics3d Object
881
+ sage: gX = X.plot(number_values=5) # coordinate mesh cube
882
+ sage: g + gX # display of the point atop the coordinate mesh
883
+ Graphics3d Object
884
+
885
+ Call with some options::
886
+
887
+ sage: g = p.plot(chart=X, size=40, color='green', label='P_1', # needs sage.plot
888
+ ....: label_color='blue', fontsize=20, label_offset=0.3)
889
+ sage: g + gX # needs sage.plot
890
+ Graphics3d Object
891
+
892
+ An example of plot via a mapping: plot of a point on a 2-sphere viewed
893
+ in the 3-dimensional space ``M``::
894
+
895
+ sage: # needs sage.plot
896
+ sage: S2 = Manifold(2, 'S^2', structure='topological')
897
+ sage: U = S2.open_subset('U') # the open set covered by spherical coord.
898
+ sage: XS.<th,ph> = U.chart(r'th:(0,pi):\theta ph:(0,2*pi):\phi')
899
+ sage: p = U.point((pi/4, pi/8), name='p')
900
+ sage: F = S2.continuous_map(M, {(XS, X): [sin(th)*cos(ph),
901
+ ....: sin(th)*sin(ph), cos(th)]}, name='F')
902
+ sage: F.display()
903
+ F: S^2 → M
904
+ on U: (th, ph) ↦ (x, y, z) = (cos(ph)*sin(th), sin(ph)*sin(th), cos(th))
905
+ sage: g = p.plot(chart=X, mapping=F)
906
+ sage: gS2 = XS.plot(chart=X, mapping=F, number_values=9)
907
+ sage: g + gS2
908
+ Graphics3d Object
909
+
910
+ Use of the option ``ambient_coords`` for plots on a 4-dimensional
911
+ manifold::
912
+
913
+ sage: # needs sage.plot
914
+ sage: M = Manifold(4, 'M', structure='topological')
915
+ sage: X.<t,x,y,z> = M.chart()
916
+ sage: p = M.point((1,2,3,4), name='p')
917
+ sage: g = p.plot(X, ambient_coords=(t,x,y), label_offset=0.4) # the coordinate z is skipped
918
+ sage: gX = X.plot(X, ambient_coords=(t,x,y), number_values=5) # long time
919
+ sage: g + gX # 3D plot # long time
920
+ Graphics3d Object
921
+ sage: g = p.plot(X, ambient_coords=(t,y,z), label_offset=0.4) # the coordinate x is skipped
922
+ sage: gX = X.plot(X, ambient_coords=(t,y,z), number_values=5) # long time
923
+ sage: g + gX # 3D plot # long time
924
+ Graphics3d Object
925
+ sage: g = p.plot(X, ambient_coords=(y,z), label_offset=0.4) # the coordinates t and x are skipped
926
+ sage: gX = X.plot(X, ambient_coords=(y,z))
927
+ sage: g + gX # 2D plot
928
+ Graphics object consisting of 20 graphics primitives
929
+
930
+ .. PLOT::
931
+
932
+ M = Manifold(4, 'M', structure='topological')
933
+ X = M.chart('t x y z'); t,x,y,z = X[:]
934
+ p = M.point((1,2,3,4), name='p')
935
+ g = p.plot(X, ambient_coords=(y,z), label_offset=0.4)
936
+ gX = X.plot(X, ambient_coords=(y,z))
937
+ sphinx_plot(g+gX)
938
+ """
939
+ from sage.manifolds.chart import Chart
940
+ from sage.plot.graphics import Graphics
941
+ from sage.plot.plot3d.shapes2 import point3d, text3d
942
+ from sage.plot.point import point2d
943
+ from sage.plot.text import text
944
+ if self._manifold.base_field_type() != 'real':
945
+ raise NotImplementedError('plot of points on manifolds over fields different'
946
+ ' from the real field is not implemented')
947
+ # The ambient chart:
948
+ if chart is None:
949
+ chart = self.parent().default_chart()
950
+ elif not isinstance(chart, Chart):
951
+ raise TypeError("the argument 'chart' must be a coordinate chart")
952
+ # The effective point to be plotted:
953
+ if mapping is None:
954
+ eff_point = self
955
+ else:
956
+ eff_point = mapping(self)
957
+ # The coordinates of the ambient chart used for the plot:
958
+ if ambient_coords is None:
959
+ ambient_coords = chart[:]
960
+ elif not isinstance(ambient_coords, tuple):
961
+ ambient_coords = tuple(ambient_coords)
962
+ nca = len(ambient_coords)
963
+ if nca != 2 and nca != 3:
964
+ raise TypeError("invalid number of ambient coordinates: {}".format(nca))
965
+
966
+ # Extract the kwds options
967
+ size = kwds['size']
968
+ color = kwds['color']
969
+ label_color = kwds['label_color']
970
+ fontsize = kwds['fontsize']
971
+ label_offset = kwds['label_offset']
972
+
973
+ # The point coordinates:
974
+ coords = eff_point.coord(chart)
975
+ xx = chart[:]
976
+ xp = [coords[xx.index(c)] for c in ambient_coords]
977
+ if parameters is not None:
978
+ xps = [coord.substitute(parameters) for coord in xp]
979
+ xp = xps
980
+ xlab = [coord + label_offset for coord in xp]
981
+ if label_color is None:
982
+ label_color = color
983
+ resu = Graphics()
984
+ if nca == 2:
985
+ if label is None:
986
+ label = r'$' + self._latex_name + r'$'
987
+ resu += (point2d(xp, color=color, size=size) +
988
+ text(label, xlab, fontsize=fontsize, color=label_color))
989
+ else:
990
+ if label is None:
991
+ label = self._name
992
+ resu += (point3d(xp, color=color, size=size) +
993
+ text3d(label, xlab, fontsize=fontsize, color=label_color))
994
+ return resu