# 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:
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