Ticket #26355: degenerate.py

File degenerate.py, 14.8 KB (added by Dicolevrai, 3 years ago)

To create the class Degenerate Manifold

Line 
1from sage.rings.infinity import infinity
2from sage.manifolds.structure import DegenerateStructure
3from sage.manifolds.differentiable.manifold import DifferentiableManifold
4
5###############################################################################
6
7class DegenerateManifold(DifferentiableManifold):
8    r"""
9    Degenerate Manifolds
10
11    A *degenerate manifold* (or a *null manifold*) is a pair`(M,g)
12    where `M` is a real differentiable manifold  (see
13    :class:`~sage.manifolds.differentiable.manifold.DifferentiableManifold`)
14    and `g` is a field of degenerate symmetric bilinear forms on `M (see
15    :class:`~sage.manifolds.differentiable.metric.DegenerateMetric`).
16
17    INPUT:
18
19    - ``n`` -- positive integer; dimension of the manifold
20    - ``name`` -- string; name (symbol) given to the manifold
21    - ``metric_name`` -- (default: ``'g'``) string; name (symbol) given to the
22      metric
23    - ``signature`` -- (default: ``None``) signature `S` of the metric as a
24      tuple: `S = (n_+, n_-, n_0)`, where `n_+` (resp. `n_-`, resp. `n_0`) is the
25      number of positive terms (resp. negative terms, resp. zero tems) in any
26      diagonal writing of the metric components; if ``signature`` is not
27      provided, `S` is set to `(ndim-1, 0, 1)`, being `ndim` the manifold's dimension
28    - ``ambient`` -- (default: ``None``) if not ``None``, must be a
29      differentiable manifold; the created object is then an open subset of
30      ``ambient``
31    - ``diff_degree`` -- (default: ``infinity``) degree `k` of
32      differentiability
33    - ``latex_name`` -- (default: ``None``) string; LaTeX symbol to
34      denote the manifold; if none is provided, it is set to ``name``
35    - ``metric_latex_name`` -- (default: ``None``) string; LaTeX symbol to
36      denote the metric; if none is provided, it is set to ``metric_name``
37    - ``start_index`` -- (default: 0) integer; lower value of the range of
38      indices used for "indexed objects" on the manifold, e.g. coordinates
39      in a chart
40    - ``category`` -- (default: ``None``) to specify the category; if ``None``,
41      ``Manifolds(RR).Differentiable()`` (or ``Manifolds(RR).Smooth()``
42      if ``diff_degree`` = ``infinity``) is assumed (see the category
43      :class:`~sage.categories.manifolds.Manifolds`)
44    - ``unique_tag`` -- (default: ``None``) tag used to force the construction
45      of a new object when all the other arguments have been used previously
46      (without ``unique_tag``, the
47      :class:`~sage.structure.unique_representation.UniqueRepresentation`
48      behavior inherited from
49      :class:`~sage.manifolds.subset.ManifoldSubset`, via
50      :class:`~sage.manifolds.differentiable.manifold.DifferentiableManifold`
51      and :class:`~sage.manifolds.manifold.TopologicalManifold`,
52      would return the previously constructed object corresponding to these
53      arguments).
54
55    EXAMPLES:
56
57    A degenerate manifold is constructed via the generic function
58    :func:`~sage.manifolds.manifold.Manifold`, using the keyword
59    ``structure``::
60
61        sage: M = Manifold(3, 'M', structure='degenerate_metric')
62        sage: M
63        3-dimensional degenerate manifold M
64        sage: M.parent()
65        <class 'sage.manifolds.differentiable.degenerate.DegenerateManifold_with_category'>
66
67    The metric associated with ``M`` is::
68
69        sage: g = M.metric()
70        sage: g
71        degenerate metric g on the 3-dimensional degenerate manifold M
72        sage: g.signature()
73        (0, 2, 1)
74
75    Its value has to be initialized either by setting its components in various
76    vector frames (see the above examples regarding the 2-sphere and Minkowski
77    spacetime) or by making it equal to a given field of symmetric bilinear
78    forms (see the method
79    :meth:`~sage.manifolds.differentiable.metric.PseudoRiemannianMetric.set`
80    of the metric class). Both methods are also covered in the
81    documentation of method :meth:`metric` below.
82
83
84    """
85    def __init__(self, n, name, metric_name='g', signature=None, base_manifold=None,
86                 diff_degree=infinity, latex_name=None,
87                 metric_latex_name=None, start_index=0, category=None,
88                 unique_tag=None):
89        r"""
90        Construct a pseudo-Riemannian manifold.
91
92        TESTS::
93
94            sage: M = Manifold(3, 'M', structure='degenerate_metric')
95            sage: M
96            3-dimensional degenerate manifold M
97            sage: type(M)
98            <class 'sage.manifolds.differentiable.degenerate.DegenerateManifold_with_category'>
99            sage: X.<x,y,z> = M.chart()
100            sage: M.metric()
101            degenerate metric g on the 3-dimensional degenerate manifold M
102            sage: TestSuite(M).run()
103
104        """
105        if base_manifold and not isinstance(base_manifold, DegenerateManifold):
106            raise TypeError("the argument 'base_manifold' must be a " +
107                            "Degenerate manifold")
108        structure = DegenerateStructure()
109        DifferentiableManifold.__init__(self, n, name, 'real', structure,
110                                        base_manifold=base_manifold,
111                                        diff_degree=diff_degree,
112                                        latex_name=latex_name,
113                                        start_index=start_index,
114                                        category=category)
115        self._metric = None # to be initialized by metric()
116        self._metric_signature = signature
117        if not isinstance(metric_name, str):
118            raise TypeError("{} is not a string".format(metric_name))
119        self._metric_name = metric_name
120        if metric_latex_name is None:
121            self._metric_latex_name = self._metric_name
122        else:
123            if not isinstance(metric_latex_name, str):
124                raise TypeError("{} is not a string".format(metric_latex_name))
125            self._metric_latex_name = metric_latex_name
126
127    def metric(self, name=None, signature=None, latex_name=None,
128               dest_map=None):
129        r"""
130        Return the metric giving the null manifold structure to the
131        manifold, or define a new metric tensor on the manifold.
132
133        INPUT:
134
135        - ``name`` -- (default: ``None``) name given to the metric; if
136          ``name`` is ``None`` or matches the name of the metric defining the
137          null manifold structure of ``self``, the latter metric is
138          returned
139        - ``signature`` -- (default: ``None``; ignored if ``name`` is ``None``)
140          signature `S` of the metric as a tuple: `S = (n_+, n_-, n_0)`,
141          where `n_+` (resp. `n_-`, resp. `n_0`) is the number of positive
142          terms (resp. negative terms, resp. zero tems) in any diagonal writing
143          of the metric components; if ``signature`` is not provided, `S` is set
144          to `(ndim-1, 0, 1)`, being `ndim` the manifold's dimension
145        - ``latex_name`` -- (default: ``None``; ignored if ``name`` is ``None``)
146          LaTeX symbol to denote the metric; if ``None``, it is formed from
147          ``name``
148        - ``dest_map`` -- (default: ``None``; ignored if ``name`` is ``None``)
149          instance of
150          class :class:`~sage.manifolds.differentiable.diff_map.DiffMap`
151          representing the destination map `\Phi:\ U \rightarrow M`, where `U`
152          is the current manifold; if ``None``, the identity map is assumed
153          (case of a metric tensor field *on* `U`)
154
155        OUTPUT:
156
157        - instance of
158          :class:`~sage.manifolds.differentiable.metric.DegenerateMetric`
159
160        EXAMPLES:
161
162        Metric of a 3-dimensional degenerate manifold::
163
164            sage: M = Manifold(3, 'M', structure='degenerate_metric', start_index=1)
165            sage: X.<x,y,z> = M.chart()
166            sage: g = M.metric(); g
167            degenerate metric g on the 3-dimensional degenerate manifold M
168
169        The metric remains to be initialized, for instance by setting its
170        components in the coordinate frame associated to the chart ``X``::
171
172            sage: g[1,1], g[2,2] = -1, 1
173            sage: g.display()
174            g = -dx*dx + dy*dy
175            sage: g[:]
176            [-1  0  0]
177            [ 0  1  0]
178            [ 0  0  0]
179
180        Alternatively, the metric can be initialized from a given field of
181        degenerate symmetric bilinear forms; we may create the former
182        object by::
183
184            sage: X.coframe()
185            Coordinate coframe (M, (dx,dy,dz))
186            sage: dx, dy = X.coframe()[1], X.coframe()[2]
187            sage: b = dx*dx + dy*dy
188            sage: b
189            Field of symmetric bilinear forms dx*dx+dy*dy on the
190            3-dimensional degenerate manifold M
191
192        We then use the metric method
193        :meth:`~sage.manifolds.differentiable.metric.DegenerateMetric.set`
194        to make ``g`` being equal to ``b`` as a symmetric tensor field of
195        type ``(0,2)``::
196
197            sage: g.set(b)
198            sage: g.display()
199            g = dx*dx + dy*dy
200
201        Another metric can be defined on ``M`` by specifying a metric name
202        distinct from that chosen at the creation of the manifold (which
203        is ``g`` by default, but can be changed thanks to the keyword
204        ``metric_name`` in :func:`~sage.manifolds.manifold.Manifold`)::
205
206            sage: h = M.metric('h'); h
207            degenerate metric h on the 3-dimensional degenerate manifold M
208            sage: h[1,1], h[2,2], h[3,3] = 1+y^2, 1+z^2, 1+x^2
209            sage: h.display()
210            h = (y^2 + 1) dx*dx + (z^2 + 1) dy*dy + (x^2 + 1) dz*dz
211
212        The metric tensor ``h`` is distinct from the metric entering in the
213        definition of the degenerate manifold ``M``::
214
215            sage: h is M.metric()
216            False
217
218        while we have of course::
219
220            sage: g is M.metric()
221            True
222
223        Providing the same name as the manifold's default metric returns the
224        latter::
225
226            sage: M.metric('g') is M.metric()
227            True
228
229        """
230        if signature is None:
231            signature = self._metric_signature
232        if name is None or name == self._metric_name:
233            # Default metric associated with the manifold
234            if self._metric is None:
235                if self._manifold is not self and self._manifold._metric is not None:
236                    # case of an open subset with a metric already defined on
237                    # the ambient manifold:
238                    self._metric = self._manifold._metric.restrict(self)
239                else:
240                    # creation from scratch:
241                    self._metric = DifferentiableManifold.metric(self,
242                                           self._metric_name,
243                                           signature=self._metric_signature,
244                                           latex_name=self._metric_latex_name)
245            return self._metric
246        # Metric distinct from the default one: it is created by the method
247        # metric of the superclass for generic differentiable manifolds:
248        return DifferentiableManifold.metric(self, name, signature=signature,
249                                             latex_name=latex_name,
250                                             dest_map=dest_map)
251
252    def open_subset(self, name, latex_name=None, coord_def={}):
253        r"""
254        Create an open subset of ``self``.
255
256        An open subset is a set that is (i) included in the manifold and (ii)
257        open with respect to the manifold's topology. It is a differentiable
258        manifold by itself. Moreover, equipped with the restriction of the
259        manifold metric to itself, it is a null manifold. Hence
260        the returned object is an instance of
261        :class:`DegenerateManifold`.
262
263        INPUT:
264
265        - ``name`` -- name given to the open subset
266        - ``latex_name`` --  (default: ``None``) LaTeX symbol to denote the
267          subset; if none is provided, it is set to ``name``
268        - ``coord_def`` -- (default: {}) definition of the subset in
269          terms of coordinates; ``coord_def`` must a be dictionary with keys
270          charts in the manifold's atlas and values the symbolic expressions
271          formed by the coordinates to define the subset.
272
273        OUTPUT:
274
275        - instance of :class:`DegenerateManifold` representing the
276          created open subset
277
278        EXAMPLES:
279
280        Open subset of a 3-dimensional degenerate manifold::
281
282            sage: M = Manifold(3, 'M', structure='degenerate_metric', start_index=1)
283            sage: X.<x,y,z> = M.chart()
284            sage: U = M.open_subset('U', coord_def={X: [x>0, y>0]}); U
285            Open subset U of the 3-dimensional degenerate manifold M
286            sage: type(U)
287            <class 'sage.manifolds.differentiable.degenerate.DegenerateManifold_with_category'>
288
289        We initialize the metric of ``M``::
290
291            sage: g = M.metric()
292            sage: g[1,1], g[2,2] = -1, 1
293
294        Then the metric on ``U`` is determined as the restriction of ``g`` to
295        ``U``::
296
297            sage: gU = U.metric(); gU
298            degenerate metric g on the Open subset U of the 3-dimensional degenerate manifold M
299            sage: gU.display()
300            g = -dx*dx + dy*dy
301            sage: gU is g.restrict(U)
302            True
303
304        TESTS:
305
306        Open subset created after the initialization of the metric::
307
308            sage: V = M.open_subset('V', coord_def={X: x<0}); V
309            Open subset V of the 3-dimensional degenerate manifold M
310            sage: gV = V.metric()
311            sage: gV.display()
312            g = -dx*dx + dy*dy
313            sage: gV is g.restrict(V)
314            True
315
316        """
317        resu = DegenerateManifold(self._dim, name,
318                                        metric_name=self._metric_name,
319                                        signature=self._metric_signature,
320                                        base_manifold=self._manifold,
321                                        diff_degree=self._diff_degree,
322                                        latex_name=latex_name,
323                                        metric_latex_name=self._metric_latex_name,
324                                        start_index=self._sindex)
325        resu._calculus_method = self._calculus_method
326        resu._supersets.update(self._supersets)
327        for sd in self._supersets:
328            sd._subsets.add(resu)
329        self._top_subsets.add(resu)
330        # Charts on the result from the coordinate definition:
331        for chart, restrictions in coord_def.items():
332            if chart not in self._atlas:
333                raise ValueError("the {} does not belong to ".format(chart) +
334                                 "the atlas of {}".format(self))
335            chart.restrict(resu, restrictions)
336        # Transition maps on the result inferred from those of self:
337        for chart1 in coord_def:
338            for chart2 in coord_def:
339                if chart2 != chart1 and (chart1, chart2) in self._coord_changes:
340                    self._coord_changes[(chart1, chart2)].restrict(resu)
341        #!# update non-coordinate vector frames and change of frames
342        #
343        return resu