Skip to content
This repository was archived by the owner on Jan 30, 2023. It is now read-only.

Commit dc15aff

Browse files
committed
Implement PseudoRiemannianSubmanifold.metric() and various related improvements (Trac #31781)
1 parent 7282b2b commit dc15aff

File tree

6 files changed

+145
-66
lines changed

6 files changed

+145
-66
lines changed

src/sage/manifolds/differentiable/degenerate.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ class DegenerateManifold(DifferentiableManifold):
3131
3232
- ``n`` -- positive integer; dimension of the manifold
3333
- ``name`` -- string; name (symbol) given to the manifold
34-
- ``metric_name`` -- (default: ``'g'``) string; name (symbol) given to the
35-
metric
34+
- ``metric_name`` -- (default: ``None``) string; name (symbol) given to the
35+
metric; if ``None``, ``'g'`` is used
3636
- ``signature`` -- (default: ``None``) signature `S` of the metric as a
3737
tuple: `S = (n_+, n_-, n_0)`, where `n_+` (resp. `n_-`, resp. `n_0`) is the
3838
number of positive terms (resp. negative terms, resp. zero tems) in any
@@ -98,12 +98,12 @@ class DegenerateManifold(DifferentiableManifold):
9898
- [DB1996]_
9999
- [DS2010]_
100100
"""
101-
def __init__(self, n, name, metric_name='g', signature=None, base_manifold=None,
102-
diff_degree=infinity, latex_name=None,
101+
def __init__(self, n, name, metric_name=None, signature=None,
102+
base_manifold=None, diff_degree=infinity, latex_name=None,
103103
metric_latex_name=None, start_index=0, category=None,
104104
unique_tag=None):
105105
r"""
106-
Construct a pseudo-Riemannian manifold.
106+
Construct a degenerate manifold.
107107
108108
TESTS::
109109
@@ -130,7 +130,9 @@ def __init__(self, n, name, metric_name='g', signature=None, base_manifold=None,
130130
category=category)
131131
self._metric = None # to be initialized by metric()
132132
self._metric_signature = signature
133-
if not isinstance(metric_name, str):
133+
if metric_name is None:
134+
metric_name = 'g'
135+
elif not isinstance(metric_name, str):
134136
raise TypeError("{} is not a string".format(metric_name))
135137
self._metric_name = metric_name
136138
if metric_latex_name is None:

src/sage/manifolds/differentiable/degenerate_submanifold.py

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -182,30 +182,24 @@ class DegenerateSubmanifold(DegenerateManifold, DifferentiableSubmanifold):
182182
183183
- ``n`` -- positive integer; dimension of the manifold
184184
- ``name`` -- string; name (symbol) given to the manifold
185-
- ``field`` -- field `K` on which the manifold is
186-
defined; allowed values are
187-
188-
- ``'real'`` or an object of type ``RealField`` (e.g., ``RR``) for
189-
a manifold over `\RR`
190-
- ``'complex'`` or an object of type ``ComplexField`` (e.g., ``CC``)
191-
for a manifold over `\CC`
192-
- an object in the category of topological fields (see
193-
:class:`~sage.categories.fields.Fields` and
194-
:class:`~sage.categories.topological_spaces.TopologicalSpaces`)
195-
for other types of manifolds
196-
185+
- ``ambient`` -- (default: ``None``) pseudo-Riemannian manifold `M` in
186+
which the submanifold is embedded (or immersed). If ``None``, it is set
187+
to ``self``
188+
- ``metric_name`` -- (default: ``None``) string; name (symbol) given to the
189+
metric; if ``None``, ``'g'`` is used
197190
- ``signature`` -- (default: ``None``) signature `S` of the metric as a
198191
tuple: `S = (n_+, n_-, n_0)`, where `n_+` (resp. `n_-`, resp. `n_0`) is the
199192
number of positive terms (resp. negative terms, resp. zero tems) in any
200193
diagonal writing of the metric components; if ``signature`` is not
201194
provided, `S` is set to `(ndim-1, 0, 1)`, being `ndim` the manifold's dimension
202-
- ``ambient`` -- (default: ``None``) manifold of destination
203-
of the immersion. If ``None``, set to ``self``
204195
- ``base_manifold`` -- (default: ``None``) if not ``None``, must be a
205196
topological manifold; the created object is then an open subset of
206197
``base_manifold``
198+
- ``diff_degree`` -- (default: ``infinity``) degree of differentiability
207199
- ``latex_name`` -- (default: ``None``) string; LaTeX symbol to
208200
denote the manifold; if none are provided, it is set to ``name``
201+
- ``metric_latex_name`` -- (default: ``None``) string; LaTeX symbol to
202+
denote the metric; if none is provided, it is set to ``metric_name``
209203
- ``start_index`` -- (default: 0) integer; lower value of the range of
210204
indices used for "indexed objects" on the manifold, e.g., coordinates
211205
in a chart
@@ -227,12 +221,12 @@ class DegenerateSubmanifold(DegenerateManifold, DifferentiableSubmanifold):
227221
:mod:`~sage.manifolds.differentiable.differentiable_submanifold`
228222
229223
"""
230-
def __init__(self, n, name, ambient=None, metric_name='g', signature=None,
224+
def __init__(self, n, name, ambient=None, metric_name=None, signature=None,
231225
base_manifold=None, diff_degree=infinity, latex_name=None,
232226
metric_latex_name=None, start_index=0, category=None,
233227
unique_tag=None):
234228
r"""
235-
Construct a pseudo-Riemannian submanifold.
229+
Construct a degenerate submanifold.
236230
237231
EXAMPLES:
238232
@@ -245,7 +239,6 @@ def __init__(self, n, name, ambient=None, metric_name='g', signature=None,
245239
differentiable manifold M
246240
247241
"""
248-
249242
DegenerateManifold.__init__(self, n, name=name,
250243
metric_name=metric_name,
251244
signature=signature,

src/sage/manifolds/differentiable/examples/sphere.py

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -52,14 +52,14 @@
5252
As a submanifold of a Riemannian manifold, namely the Euclidean space,
5353
the 2-sphere admits an induced metric::
5454
55-
sage: h = S2_r.induced_metric()
56-
sage: h.display()
57-
gamma = r^2 dtheta⊗dtheta + r^2*sin(theta)^2 dphi⊗dphi
55+
sage: g = S2_r.induced_metric()
56+
sage: g.display()
57+
g = r^2 dtheta⊗dtheta + r^2*sin(theta)^2 dphi⊗dphi
5858
5959
The induced metric is also known as the *first fundamental form* (see
6060
:meth:`~sage.manifolds.differentiable.pseudo_riemannian_submanifold.PseudoRiemannianSubmanifold.first_fundamental_form`)::
6161
62-
sage: h is S2_r.first_fundamental_form()
62+
sage: g is S2_r.first_fundamental_form()
6363
True
6464
6565
The *second fundamental form* encodes the extrinsic curvature of the
@@ -157,12 +157,12 @@
157157
vector field pointing outwards. Henceforth, the manifold admits
158158
a volume form::
159159
160-
sage: h = S1c.induced_metric()
161-
sage: h.display()
162-
gamma = dchi⊗dchi
163-
sage: eps = h.volume_form()
160+
sage: g = S1c.induced_metric()
161+
sage: g.display()
162+
g = dchi⊗dchi
163+
sage: eps = g.volume_form()
164164
sage: eps.display()
165-
eps_gamma = -dchi
165+
eps_g = -dchi
166166
167167
"""
168168

@@ -380,7 +380,8 @@ def __init__(self, n, radius=1, ambient_space=None, center=None, name=None,
380380
PseudoRiemannianSubmanifold.__init__(self, n, name,
381381
ambient=ambient_space,
382382
signature=n, latex_name=latex_name,
383-
start_index=1, category=category)
383+
metric_name='g', start_index=1,
384+
category=category)
384385
# set attributes
385386
self._radius = radius
386387
self._center = center

src/sage/manifolds/differentiable/pseudo_riemannian.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -297,8 +297,8 @@ class PseudoRiemannianManifold(DifferentiableManifold):
297297
298298
- ``n`` -- positive integer; dimension of the manifold
299299
- ``name`` -- string; name (symbol) given to the manifold
300-
- ``metric_name`` -- (default: ``'g'``) string; name (symbol) given to the
301-
metric
300+
- ``metric_name`` -- (default: ``None``) string; name (symbol) given to the
301+
metric; if ``None``, ``'g'`` is used
302302
- ``signature`` -- (default: ``None``) signature `S` of the metric as a
303303
single integer: `S = n_+ - n_-`, where `n_+` (resp. `n_-`) is the
304304
number of positive terms (resp. number of negative terms) in any
@@ -412,8 +412,8 @@ class PseudoRiemannianManifold(DifferentiableManifold):
412412
-2
413413
414414
"""
415-
def __init__(self, n, name, metric_name='g', signature=None, base_manifold=None,
416-
diff_degree=infinity, latex_name=None,
415+
def __init__(self, n, name, metric_name=None, signature=None,
416+
base_manifold=None, diff_degree=infinity, latex_name=None,
417417
metric_latex_name=None, start_index=0, category=None,
418418
unique_tag=None):
419419
r"""
@@ -450,7 +450,9 @@ def __init__(self, n, name, metric_name='g', signature=None, base_manifold=None,
450450
category=category)
451451
self._metric = None # to be initialized by metric()
452452
self._metric_signature = signature
453-
if not isinstance(metric_name, str):
453+
if metric_name is None:
454+
metric_name = 'g'
455+
elif not isinstance(metric_name, str):
454456
raise TypeError("{} is not a string".format(metric_name))
455457
self._metric_name = metric_name
456458
if metric_latex_name is None:

src/sage/manifolds/differentiable/pseudo_riemannian_submanifold.py

Lines changed: 104 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -221,8 +221,8 @@ class PseudoRiemannianSubmanifold(PseudoRiemannianManifold,
221221
- ``ambient`` -- (default: ``None``) pseudo-Riemannian manifold `M` in
222222
which the submanifold is embedded (or immersed). If ``None``, it is set
223223
to ``self``
224-
- ``metric_name`` -- (default: ``'g'``) string; name (symbol) given to the
225-
submanifold's metric
224+
- ``metric_name`` -- (default: ``None``) string; name (symbol) given to the
225+
metric; if ``None``, ``'gamma'`` is used
226226
- ``signature`` -- (default: ``None``) signature `S` of the metric as a
227227
single integer: `S = n_+ - n_-`, where `n_+` (resp. `n_-`) is the
228228
number of positive terms (resp. number of negative terms) in any
@@ -236,7 +236,8 @@ class PseudoRiemannianSubmanifold(PseudoRiemannianManifold,
236236
- ``latex_name`` -- (default: ``None``) string; LaTeX symbol to
237237
denote the submanifold; if none is provided, it is set to ``name``
238238
- ``metric_latex_name`` -- (default: ``None``) string; LaTeX symbol to
239-
denote the metric; if none is provided, it is set to ``metric_name``
239+
denote the metric; if none is provided, it is set to ``metric_name`` if
240+
the latter is not ``None`` and to ``r'\gamma'`` otherwise
240241
- ``start_index`` -- (default: 0) integer; lower value of the range of
241242
indices used for "indexed objects" on the submanifold, e.g. coordinates
242243
in a chart
@@ -300,10 +301,10 @@ class PseudoRiemannianSubmanifold(PseudoRiemannianManifold,
300301
:mod:`~sage.manifolds.differentiable.differentiable_submanifold`
301302
302303
"""
303-
def __init__(self, n, name, ambient=None, metric_name='g', signature=None,
304-
base_manifold=None, diff_degree=infinity, latex_name=None,
305-
metric_latex_name=None, start_index=0, category=None,
306-
unique_tag=None):
304+
def __init__(self, n, name, ambient=None, metric_name=None,
305+
signature=None, base_manifold=None, diff_degree=infinity,
306+
latex_name=None, metric_latex_name=None, start_index=0,
307+
category=None, unique_tag=None):
307308
r"""
308309
Construct a pseudo-Riemannian submanifold.
309310
@@ -337,6 +338,9 @@ def __init__(self, n, name, ambient=None, metric_name='g', signature=None,
337338
5-dimensional pseudo-Riemannian manifold M
338339
339340
"""
341+
if metric_name is None:
342+
metric_name = 'gamma'
343+
metric_latex_name = r'\gamma'
340344
PseudoRiemannianManifold.__init__(self, n, name=name,
341345
metric_name=metric_name,
342346
signature=signature,
@@ -513,7 +517,7 @@ def first_fundamental_form(self):
513517
A sphere embedded in Euclidean space::
514518
515519
sage: M.<x,y,z> = EuclideanSpace()
516-
sage: N = Manifold(2, 'N', ambient=M, structure="Riemannian")
520+
sage: N = Manifold(2, 'N', ambient=M, structure='Riemannian')
517521
sage: C.<th,ph> = N.chart(r'th:(0,pi):\theta ph:(-pi,pi):\phi')
518522
sage: r = var('r', domain='real')
519523
sage: assume(r>0)
@@ -535,16 +539,105 @@ def first_fundamental_form(self):
535539
[ r^2 0]
536540
[ 0 r^2*sin(th)^2]
537541
542+
By default, the first fundamental form is named ``gamma``, but this
543+
can be customized by means of the argument ``metric_name`` when
544+
declaring the submanifold::
545+
546+
sage: P = Manifold(1, 'P', ambient=M, structure='Riemannian',
547+
....: metric_name='g')
548+
sage: CP.<t> = P.chart()
549+
sage: F = P.diff_map(M, [t, 2*t, 3*t])
550+
sage: P.set_embedding(F)
551+
sage: P.induced_metric()
552+
Riemannian metric g on the 1-dimensional Riemannian submanifold P
553+
embedded in the Euclidean space E^3
554+
sage: P.induced_metric().display()
555+
g = 14 dt⊗dt
556+
538557
"""
539558
if self._first_fundamental_form is None:
540-
self._first_fundamental_form = self.metric()
559+
self._first_fundamental_form = super().metric()
541560
self._first_fundamental_form.set(
542561
self._immersion.pullback(self.ambient_metric()))
543-
self._first_fundamental_form.set_name("gamma", r"\gamma")
544562
return self._first_fundamental_form
545563

546564
induced_metric = first_fundamental_form
547565

566+
def metric(self, name=None, signature=None, latex_name=None,
567+
dest_map=None):
568+
r"""
569+
Return the induced metric (first fundamental form) or define a new
570+
metric tensor on the submanifold.
571+
572+
A new (uninitialzed) metric is returned only if the argument ``name``
573+
is provided and differs from the metric name declared at the
574+
construction of the submanifold; otherwise, the first fundamental
575+
form is returned.
576+
577+
INPUT:
578+
579+
- ``name`` -- (default: ``None``) name given to the metric; if ``name``
580+
is ``None`` or equals the metric name declared when constructing
581+
the submanifold, the first fundamental form is returned (see
582+
:meth:`first_fundamental_form`)
583+
- ``signature`` -- (default: ``None``; ignored if ``name`` is ``None``)
584+
signature `S` of the metric as a single integer: `S = n_+ - n_-`,
585+
where `n_+` (resp. `n_-`) is the number of positive terms (resp.
586+
number of negative terms) in any diagonal writing of the metric
587+
components; if ``signature`` is not provided, `S` is set to the
588+
submanifold's dimension (Riemannian signature)
589+
- ``latex_name`` -- (default: ``None``; ignored if ``name`` is ``None``)
590+
LaTeX symbol to denote the metric; if ``None``, it is formed from
591+
``name``
592+
- ``dest_map`` -- (default: ``None``; ignored if ``name`` is ``None``)
593+
instance of
594+
class :class:`~sage.manifolds.differentiable.diff_map.DiffMap`
595+
representing the destination map `\Phi:\ U \rightarrow M`, where `U`
596+
is the current submanifold; if ``None``, the identity map is assumed
597+
(case of a metric tensor field *on* `U`)
598+
599+
OUTPUT:
600+
601+
- instance of
602+
:class:`~sage.manifolds.differentiable.metric.PseudoRiemannianMetric`
603+
604+
EXAMPLES:
605+
606+
Induced metric on a straight line of the Euclidean plane::
607+
608+
sage: M.<x,y> = EuclideanSpace()
609+
sage: N = Manifold(1, 'N', ambient=M, structure='Riemannian')
610+
sage: CN.<t> = N.chart()
611+
sage: F = N.diff_map(M, [t, 2*t])
612+
sage: N.set_embedding(F)
613+
sage: N.metric()
614+
Riemannian metric gamma on the 1-dimensional Riemannian
615+
submanifold N embedded in the Euclidean plane E^2
616+
sage: N.metric().display()
617+
gamma = 5 dt⊗dt
618+
619+
Setting the argument ``name`` to that declared while constructing
620+
the submanifold (default = ``'gamma'``) yields the same result::
621+
622+
sage: N.metric(name='gamma') is N.metric()
623+
True
624+
625+
while using a different name allows one to define a new metric on the
626+
submanifold::
627+
628+
sage: h = N.metric(name='h'); h
629+
Riemannian metric h on the 1-dimensional Riemannian submanifold N
630+
embedded in the Euclidean plane E^2
631+
sage: h[0, 0] = 1 # initialization
632+
sage: h.display()
633+
h = dt⊗dt
634+
635+
"""
636+
if name is None or name == self._metric_name:
637+
return self.first_fundamental_form()
638+
return super().metric(name=name, signature=signature,
639+
latex_name=latex_name, dest_map=dest_map)
640+
548641
@cached_method
549642
def difft(self):
550643
r"""
@@ -1162,7 +1255,7 @@ def second_fundamental_form(self):
11621255
+ " hypersurfaces")
11631256
if self._second_fundamental_form is None:
11641257
resu = self.vector_field_module().tensor((0, 2), name='K',
1165-
sym=[(0, 1)])
1258+
sym=[(0, 1)])
11661259
if self._dim_foliation != 0:
11671260
inverse_subs = {v: k for k, v in self._subs[0].items()}
11681261
asff = self.ambient_second_fundamental_form()

src/sage/manifolds/manifold.py

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3008,27 +3008,15 @@ def Manifold(dim, name, latex_name=None, field='real', structure='smooth',
30083008
start_index=start_index,
30093009
unique_tag=unique_tag())
30103010
elif structure in ['pseudo-Riemannian', 'Riemannian', 'Lorentzian','degenerate_metric']:
3011-
if 'diff_degree' in extra_kwds:
3012-
diff_degree = extra_kwds['diff_degree']
3013-
else:
3014-
diff_degree = infinity
3015-
if 'metric_name' in extra_kwds:
3016-
metric_name = extra_kwds['metric_name']
3017-
else:
3018-
metric_name = 'g'
3019-
if 'metric_latex_name' in extra_kwds:
3020-
metric_latex_name = extra_kwds['metric_latex_name']
3021-
else:
3022-
metric_latex_name = None
3011+
diff_degree = extra_kwds.get('diff_degree', infinity)
3012+
metric_name = extra_kwds.get('metric_name', None)
3013+
metric_latex_name = extra_kwds.get('metric_latex_name', None)
30233014
if structure == 'pseudo-Riemannian':
3024-
if 'signature' in extra_kwds:
3025-
signature = extra_kwds['signature']
3026-
else:
3027-
signature = None
3015+
signature = extra_kwds.get('signature', None)
30283016
elif structure == 'Riemannian':
30293017
signature = dim
30303018
elif structure == 'degenerate_metric':
3031-
signature = (0,dim-1,1)
3019+
signature = (0, dim-1, 1)
30323020
elif structure == 'Lorentzian':
30333021
if 'signature' in extra_kwds:
30343022
signat = extra_kwds['signature']

0 commit comments

Comments
 (0)