Skip to content

Commit

Permalink
Trac #30284: Immutability of Bundle Connections
Browse files Browse the repository at this point in the history
Immutability of bundle connections. Furthermore, a `copy` method is
added.

See #30261.

URL: https://trac.sagemath.org/30284
Reported by: gh-mjungmath
Ticket author(s): Michael Jung
Reviewer(s): Eric Gourgoulhon
  • Loading branch information
Release Manager committed Mar 20, 2021
2 parents db46bf9 + 70a1d9a commit badd79c
Show file tree
Hide file tree
Showing 2 changed files with 133 additions and 2 deletions.
120 changes: 118 additions & 2 deletions src/sage/manifolds/differentiable/bundle_connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,13 @@
# ******************************************************************************

from sage.structure.sage_object import SageObject
from sage.structure.mutability import Mutability
from sage.rings.integer import Integer
from sage.manifolds.differentiable.vector_bundle import \
DifferentiableVectorBundle


class BundleConnection(SageObject):
class BundleConnection(SageObject, Mutability):
r"""
An instance of this class represents a bundle connection `\nabla` on a
smooth vector bundle `E \to M`.
Expand Down Expand Up @@ -128,6 +129,10 @@ class BundleConnection(SageObject):
sage: nab[1, 2] is omega
False
Hence, this is therefore equivalent to::
sage: nab[2, 2].copy_from(omega)
Preferably, we use :meth:`set_connection_form` to specify the connection
1-forms::
Expand All @@ -147,6 +152,15 @@ class BundleConnection(SageObject):
the connection 1-forms w.r.t. other frames for consistency reasons. To
avoid this behavior, :meth:`add_connection_form` must be used instead.
In conclusion, the connection 1-forms of a bundle connection are mutable
until the connection itself is set immutable::
sage: nab.set_immutable()
sage: nab[1, 2] = omega
Traceback (most recent call last):
...
ValueError: object is immutable; please change a copy instead
By definition, a bundle connection acts on vector fields and sections::
sage: v = M.vector_field((x^2,y^2,z^2), name='v'); v.display()
Expand Down Expand Up @@ -250,6 +264,7 @@ def __init__(self, vbundle, name, latex_name=None):
if not isinstance(vbundle, DifferentiableVectorBundle):
raise TypeError("the first argument must be a differentiable " +
"vector bundle")
Mutability.__init__(self)
self._vbundle = vbundle
self._base_space = vbundle.base_space()
self._name = name
Expand Down Expand Up @@ -815,6 +830,7 @@ def add_connection_form(self, i, j, frame=None):
To delete them, use the method :meth:`set_connection_form` instead.
"""
self._require_mutable()
if frame is None:
smodule = self._vbundle.section_module(domain=self._base_space)
frame = smodule.default_frame()
Expand Down Expand Up @@ -898,6 +914,7 @@ def set_connection_form(self, i, j, frame=None):
To keep them, use the method :meth:`add_connection_form` instead.
"""
self._require_mutable()
omega = self.add_connection_form(i, j, frame=frame)
self.del_other_forms(frame)
return omega
Expand Down Expand Up @@ -1035,6 +1052,11 @@ def __hash__(self):
sage: X.<x,y> = M.chart()
sage: E = M.vector_bundle(2, 'E')
sage: nab = E.bundle_connection('nabla', latex_name=r'\nabla')
sage: hash(nab)
Traceback (most recent call last):
...
ValueError: object is mutable; please make it immutable first
sage: nab.set_immutable()
sage: hash(nab) == nab.__hash__()
True
Expand All @@ -1044,8 +1066,9 @@ def __hash__(self):
1
"""
self._require_immutable()
if self._hash == -1:
self._hash = hash(repr(self))
self._hash = hash((type(self).__name__, self._vbundle))
return self._hash

def __getitem__(self, args):
Expand Down Expand Up @@ -1358,3 +1381,96 @@ def display(self, frame=None, vector_frame=None, chart=None,
rtxt = rtxt[:-1] # remove the last new line
rlatex = rlatex[:-2] + r'\end{array}'
return FormattedExpansion(rtxt, rlatex)

def copy(self, name, latex_name=None):
r"""
Return an exact copy of ``self``.
INPUT:
- ``name`` -- name given to the copy
- ``latex_name`` -- (default: ``None``) LaTeX symbol to denote the
copy; if none is provided, the LaTeX symbol is set to ``name``
.. NOTE::
The name and the derived quantities are not copied.
EXAMPLES::
sage: M = Manifold(3, 'M', start_index=1)
sage: X.<x,y,z> = M.chart()
sage: E = M.vector_bundle(2, 'E')
sage: e = E.local_frame('e')
sage: nab = E.bundle_connection('nabla')
sage: nab.set_connection_form(1, 1)[:] = [x^2, x-z, y^3]
sage: nab.set_connection_form(1, 2)[:] = [1, x, z*y^3]
sage: nab.set_connection_form(2, 1)[:] = [1, 2, 3]
sage: nab.set_connection_form(2, 2)[:] = [0, 0, 0]
sage: nab.display()
connection (1,1) of bundle connection nabla w.r.t. Local frame
(E|_M, (e_1,e_2)) = x^2 dx + (x - z) dy + y^3 dz
connection (1,2) of bundle connection nabla w.r.t. Local frame
(E|_M, (e_1,e_2)) = dx + x dy + y^3*z dz
connection (2,1) of bundle connection nabla w.r.t. Local frame
(E|_M, (e_1,e_2)) = dx + 2 dy + 3 dz
sage: nab_copy = nab.copy('nablo'); nab_copy
Bundle connection nablo on the Differentiable real vector bundle
E -> M of rank 2 over the base space 3-dimensional differentiable
manifold M
sage: nab is nab_copy
False
sage: nab == nab_copy
True
sage: nab_copy.display()
connection (1,1) of bundle connection nablo w.r.t. Local frame
(E|_M, (e_1,e_2)) = x^2 dx + (x - z) dy + y^3 dz
connection (1,2) of bundle connection nablo w.r.t. Local frame
(E|_M, (e_1,e_2)) = dx + x dy + y^3*z dz
connection (2,1) of bundle connection nablo w.r.t. Local frame
(E|_M, (e_1,e_2)) = dx + 2 dy + 3 dz
"""
copy = type(self)(self._vbundle, name, latex_name=latex_name)
for frame, form_dict in self._connection_forms.items():
copy._coefficients[frame] = copy._new_forms(frame=frame)
for ind, form in form_dict.items():
copy._coefficients[frame][ind].copy_from(form)
return copy

def set_immutable(self):
r"""
Set ``self`` and all restrictions of ``self`` immutable.
EXAMPLES:
An affine connection can be set immutable::
sage: M = Manifold(3, 'M', start_index=1)
sage: X.<x,y,z> = M.chart()
sage: E = M.vector_bundle(2, 'E')
sage: e = E.local_frame('e')
sage: nab = E.bundle_connection('nabla')
sage: nab.set_connection_form(1, 1)[:] = [x^2, x-z, y^3]
sage: nab.set_connection_form(1, 2)[:] = [1, x, z*y^3]
sage: nab.set_connection_form(2, 1)[:] = [1, 2, 3]
sage: nab.set_connection_form(2, 2)[:] = [0, 0, 0]
sage: nab.is_immutable()
False
sage: nab.set_immutable()
sage: nab.is_immutable()
True
The coefficients of immutable elements cannot be changed::
sage: f = E.local_frame('f')
sage: nab.add_connection_form(1, 1, frame=f)[:] = [x, y, z]
Traceback (most recent call last):
...
ValueError: object is immutable; please change a copy instead
"""
for form_dict in self._connection_forms.values():
for form in form_dict.values():
form.set_immutable()
Mutability.set_immutable(self)
15 changes: 15 additions & 0 deletions src/sage/manifolds/differentiable/characteristic_class.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,13 +109,18 @@
sage: nab[0, 0].display()
connection (0,0) of bundle connection nabla^E w.r.t. Local frame
(E|_M, (e_0)) = I*A(t) dx
sage: nab.set_immutable()
The Chern character is then given by::
sage: ch = E.characteristic_class('ChernChar'); ch
Characteristic class ch of additive type associated to e^x on the
Differentiable complex vector bundle E -> M of rank 1 over the base space
2-dimensional Lorentzian manifold M
The corresponding characteristic form w.r.t. the bundle connection can be
obtained via :meth:`get_form`.
sage: ch_form = ch.get_form(nab); ch_form.display_expansion()
ch(E, nabla^E) = [1] + [0] + [1/2*d(A)/dt/pi dt/\dx]
Expand Down Expand Up @@ -182,6 +187,7 @@
sage: omega = U.one_form(name='omega')
sage: omega[c_comp.frame(),1,c_comp] = zbar/(1+z*zbar)
sage: nab[e, 1, 1] = omega
sage: nab.set_immutable()
Now, the Chern class can be constructed::
Expand Down Expand Up @@ -671,10 +677,19 @@ def get_form(self, connection, cmatrices=None):
sage: omega = M.one_form(name='omega')
sage: A = function('A')
sage: nab.set_connection_form(0, 0)[1] = I*A(t)
sage: nab.set_immutable()
sage: nab[0, 0].display()
connection (0,0) of bundle connection nabla^E w.r.t. Local frame
(E|_M, (e_0)) = I*A(t) dx
.. NOTE::
The characteristic form is strongly linked to the connection
which is why we must make the connection unchangeable,
i.e. immutable, with the command
:meth:`sage.manifolds.differentiable.bundle_connection.BundleConnection.set_immutable`
before we can use :meth:`get_form`.
The Chern character is then given by::
sage: ch = E.characteristic_class('ChernChar'); ch
Expand Down

0 comments on commit badd79c

Please sign in to comment.