Beispiel #1
0
    def __init__(self,
                 vector_field_module,
                 degree,
                 name=None,
                 latex_name=None):
        r"""
        Construct a differential form.

        TESTS:

        Construction via ``parent.element_class``, and not via a direct call
        to ``DiffForm`, to fit with the category framework::

            sage: M = Manifold(2, 'M')
            sage: U = M.open_subset('U') ; V = M.open_subset('V')
            sage: M.declare_union(U,V)   # M is the union of U and V
            sage: c_xy.<x,y> = U.chart() ; c_uv.<u,v> = V.chart()
            sage: xy_to_uv = c_xy.transition_map(c_uv, (x+y, x-y),
            ....:                    intersection_name='W', restrictions1= x>0,
            ....:                    restrictions2= u+v>0)
            sage: uv_to_xy = xy_to_uv.inverse()
            sage: W = U.intersection(V)
            sage: e_xy = c_xy.frame() ; e_uv = c_uv.frame()
            sage: A = M.diff_form_module(2)
            sage: XM = M.vector_field_module()
            sage: a = A.element_class(XM, 2, name='a'); a
            2-form a on the 2-dimensional differentiable manifold M
            sage: a[e_xy,0,1] = x+y
            sage: a.add_comp_by_continuation(e_uv, W, c_uv)
            sage: TestSuite(a).run(skip='_test_pickling')

        Construction with ``DifferentiableManifold.diff_form``::

            sage: a1 = M.diff_form(2, name='a'); a1
            2-form a on the 2-dimensional differentiable manifold M
            sage: type(a1) == type(a)
            True
            sage: a1.parent() is a.parent()
            True

        .. TODO::

            Fix ``_test_pickling`` (in the superclass :class:`TensorField`).

        """
        TensorField.__init__(
            self,
            vector_field_module, (0, degree),
            name=name,
            latex_name=latex_name,
            antisym=range(degree),
            parent=vector_field_module.dual_exterior_power(degree))
        self._init_derived()  # initialization of derived quantities
Beispiel #2
0
    def __init__(self, tensor, embedding, screen=None):
        r"""

        TESTS::

            sage: M = Manifold(4, 'M', structure="Lorentzian")
            sage: X.<t,x,y,z> = M.chart()
            sage: S = Manifold(3, 'S', ambient=M, structure='degenerate_metric')
            sage: X_S.<u,v,w> = S.chart()
            sage: Phi = S.diff_map(M, {(X_S, X): [u, u, v, w]},
            ....:                  name='Phi', latex_name=r'\Phi');
            sage: Phi_inv = M.diff_map(S, {(X, X_S): [x,y, z]}, name='Phi_inv',
            ....:                      latex_name=r'\Phi^{-1}');
            sage: S.set_immersion(Phi, inverse=Phi_inv); S.declare_embedding()
            sage: g = M.metric()
            sage: g[0,0], g[1,1], g[2,2], g[3,3] = -1,1,1,1
            sage: v = M.vector_field(); v[1] = 1
            sage: S.set_transverse(rigging=v)
            sage: xi = M.vector_field(); xi[0] = 1; xi[1] = 1
            sage: U = M.vector_field(); U[2] = 1; V = M.vector_field(); V[3] = 1
            sage: Sc = S.screen('Sc', (U,V), xi);
            sage: T1 = M.tensor_field(1,1).along(Phi); T1[0,0] = 1
            sage: from sage.manifolds.differentiable.degenerate_submanifold import TangentTensor
            sage: T2 = TangentTensor(T1, Phi); T2
            Tensor field of type (1,1) along the degenerate hypersurface S embedded in
            4-dimensional differentiable manifold M with values on the 4-dimensional
            Lorentzian manifold M

        """
        if not isinstance(tensor, TensorField):
            raise TypeError("the second argument must be a tensor field")
        self._tensor = tensor
        self._tensor.set_name(tensor._name, latex_name=tensor._latex_name)
        self._embedding = embedding
        try:
            tensor = tensor.along(embedding)
        except ValueError:
            pass
        if isinstance(tensor, TensorFieldParal):
            TensorFieldParal.__init__(self, tensor._vmodule, tensor._tensor_type, name=tensor._name,
                   latex_name=tensor._latex_name, sym=tensor._sym, antisym=tensor._antisym)
        else:
            TensorField.__init__(self, tensor._vmodule, tensor._tensor_type, name=tensor._name,
                   latex_name=tensor._latex_name, sym=tensor._sym, antisym=tensor._antisym)
        f = tensor._domain._ambient.default_frame().along(embedding)
        self[f, :] = tensor[f, :]
        frame = self._domain.adapted_frame(screen)
        self.display(frame)
        for i in self._domain._ambient.index_generator(tensor.tensor_rank()):
            for j in range(len(i)):
                if i[j]==self._domain._ambient._dim-self._domain._sindex-1:
                    self[frame, i] = 0
Beispiel #3
0
    def _init_derived(self):
        r"""
        Initialize the derived quantities.

        TESTS::

            sage: M = Manifold(2, 'M')
            sage: a = M.automorphism_field(name='a')
            sage: a._init_derived()

        """
        TensorField._init_derived(self)
        self._inverse = None  # inverse not set yet
    def _init_derived(self):
        r"""
        Initialize the derived quantities.

        TESTS::

            sage: M = Manifold(2, 'M')
            sage: a = M.automorphism_field(name='a')
            sage: a._init_derived()

        """
        TensorField._init_derived(self)
        self._inverse = None  # inverse not set yet
Beispiel #5
0
    def _del_derived(self):
        r"""
        Delete the derived quantities.

        TESTS::

            sage: M = Manifold(3, 'M')
            sage: a = M.diff_form(2, name='a')
            sage: a._del_derived()

        """
        TensorField._del_derived(self)
        self.exterior_derivative.clear_cache()
Beispiel #6
0
    def _del_derived(self):
        r"""
        Delete the derived quantities.

        TESTS::

            sage: M = Manifold(3, 'M')
            sage: a = M.diff_form(2, name='a')
            sage: a._del_derived()

        """
        TensorField._del_derived(self)
        self.exterior_derivative.clear_cache()
    def _del_derived(self):
        r"""
        Delete the derived quantities.

        TESTS::

            sage: M = Manifold(2, 'M')
            sage: a = M.automorphism_field(name='a')
            sage: a._del_derived()

        """
        # First delete the derived quantities pertaining to the mother class:
        TensorField._del_derived(self)
        # then deletes the inverse automorphism:
        self._inverse = None
Beispiel #8
0
    def _del_derived(self):
        r"""
        Delete the derived quantities.

        TESTS::

            sage: M = Manifold(2, 'M')
            sage: a = M.automorphism_field(name='a')
            sage: a._del_derived()

        """
        # First delete the derived quantities pertaining to the mother class:
        TensorField._del_derived(self)
        # then deletes the inverse automorphism:
        self._inverse = None
Beispiel #9
0
    def __init__(self, vector_field_module, degree, name=None, latex_name=None):
        r"""
        Construct a differential form.

        TESTS:

        Construction via ``parent.element_class``, and not via a direct call
        to ``DiffForm`, to fit with the category framework::

            sage: M = Manifold(2, 'M')
            sage: U = M.open_subset('U') ; V = M.open_subset('V')
            sage: M.declare_union(U,V)   # M is the union of U and V
            sage: c_xy.<x,y> = U.chart() ; c_uv.<u,v> = V.chart()
            sage: xy_to_uv = c_xy.transition_map(c_uv, (x+y, x-y),
            ....:                    intersection_name='W', restrictions1= x>0,
            ....:                    restrictions2= u+v>0)
            sage: uv_to_xy = xy_to_uv.inverse()
            sage: W = U.intersection(V)
            sage: e_xy = c_xy.frame() ; e_uv = c_uv.frame()
            sage: A = M.diff_form_module(2)
            sage: XM = M.vector_field_module()
            sage: a = A.element_class(XM, 2, name='a'); a
            2-form a on the 2-dimensional differentiable manifold M
            sage: a[e_xy,0,1] = x+y
            sage: a.add_comp_by_continuation(e_uv, W, c_uv)
            sage: TestSuite(a).run(skip='_test_pickling')

        Construction with ``DifferentiableManifold.diff_form``::

            sage: a1 = M.diff_form(2, name='a'); a1
            2-form a on the 2-dimensional differentiable manifold M
            sage: type(a1) == type(a)
            True
            sage: a1.parent() is a.parent()
            True

        .. TODO::

            Fix ``_test_pickling`` (in the superclass :class:`TensorField`).

        """
        TensorField.__init__(self, vector_field_module, (0,degree), name=name,
                             latex_name=latex_name, antisym=range(degree),
                             parent=vector_field_module.dual_exterior_power(degree))
        self._init_derived() # initialization of derived quantities
Beispiel #10
0
    def __call__(self, *args):
        r"""

        TESTS::

            sage: M = Manifold(4, 'M', structure="Lorentzian")
            sage: X.<t,x,y,z> = M.chart()
            sage: S = Manifold(3, 'S', ambient=M, structure='degenerate_metric')
            sage: X_S.<u,v,w> = S.chart()
            sage: Phi = S.diff_map(M, {(X_S, X): [u, u, v, w]},
            ....:         name='Phi', latex_name=r'\Phi');
            sage: Phi_inv = M.diff_map(S, {(X, X_S): [x,y, z]}, name='Phi_inv',
            ....:           latex_name=r'\Phi^{-1}');
            sage: S.set_immersion(Phi, inverse=Phi_inv); S.declare_embedding()
            sage: g = M.metric()
            sage: g[0,0], g[1,1], g[2,2], g[3,3] = -1,1,1,1
            sage: v = M.vector_field(); v[1] = 1
            sage: S.set_transverse(rigging=v)
            sage: xi = M.vector_field(); xi[0] = 1; xi[1] = 1
            sage: U = M.vector_field(); U[2] = 1; V = M.vector_field(); V[3] = 1
            sage: Sc = S.screen('Sc', (U,V), xi);
            sage: T1 = M.tensor_field(1,1).along(Phi); T1[0,0] = 1
            sage: from sage.manifolds.differentiable.degenerate_submanifold import TangentTensor
            sage: T2 = TangentTensor(T1, Phi); T2(xi.along(Phi))
            Vector field along the degenerate hypersurface S embedded in
            4-dimensional differentiable manifold M with values on the 4-dimensional
            Lorentzian manifold M

        """
        for vector in args:
            try:
                vector = vector.along(self._embedding)
            except ValueError:
                pass
            if not self._domain.is_tangent(vector):
                raise ValueError("The provided vector field is not " +
                                 "tangent to {}".format(self._domain._name))
        try:
            return TensorField.__call__(self._tensor.along(self._embedding),
                                        *args)
        except ValueError:
            return TensorField.__call__(self._tensor, *args)
Beispiel #11
0
    def __init__(self, vector_field_module, name=None, latex_name=None):
        r"""
        Construct a vector field with values on a non-parallelizable manifold.

        TESTS:

        Construction via ``parent.element_class``, and not via a direct call
        to ``VectorField``, to fit with the category framework::

            sage: M = Manifold(2, 'M') # the 2-dimensional sphere S^2
            sage: U = M.open_subset('U') # complement of the North pole
            sage: c_xy.<x,y> = U.chart() # stereographic coordinates from the North pole
            sage: V = M.open_subset('V') # complement of the South pole
            sage: c_uv.<u,v> = V.chart() # stereographic coordinates from the South pole
            sage: M.declare_union(U,V)   # S^2 is the union of U and V
            sage: XM = M.vector_field_module()
            sage: a = XM.element_class(XM, name='a'); a
            Vector field a on the 2-dimensional differentiable manifold M
            sage: a[c_xy.frame(),:] = [x, y]
            sage: a[c_uv.frame(),:] = [-u, -v]
            sage: TestSuite(a).run(skip='_test_pickling')

        Construction with ``DifferentiableManifold.vector_field``::

            sage: a1 = M.vector_field(name='a'); a1
            Vector field a on the 2-dimensional differentiable manifold M
            sage: type(a1) == type(a)
            True

        .. TODO::

            Fix ``_test_pickling`` (in the superclass :class:`TensorField`).

        """
        TensorField.__init__(self,
                             vector_field_module, (1, 0),
                             name=name,
                             latex_name=latex_name)
        # Initialization of derived quantities:
        TensorField._init_derived(self)
        # Initialization of list of quantities depending on self:
        self._init_dependencies()
Beispiel #12
0
    def __init__(self, vector_field_module, name=None, latex_name=None):
        r"""
        Construct a vector field with values on a non-parallelizable manifold.

        TESTS:

        Construction via ``parent.element_class``, and not via a direct call
        to ``VectorField``, to fit with the category framework::

            sage: M = Manifold(2, 'M') # the 2-dimensional sphere S^2
            sage: U = M.open_subset('U') # complement of the North pole
            sage: c_xy.<x,y> = U.chart() # stereographic coordinates from the North pole
            sage: V = M.open_subset('V') # complement of the South pole
            sage: c_uv.<u,v> = V.chart() # stereographic coordinates from the South pole
            sage: M.declare_union(U,V)   # S^2 is the union of U and V
            sage: XM = M.vector_field_module()
            sage: a = XM.element_class(XM, name='a'); a
            Vector field a on the 2-dimensional differentiable manifold M
            sage: a[c_xy.frame(),:] = [x, y]
            sage: a[c_uv.frame(),:] = [-u, -v]
            sage: TestSuite(a).run(skip='_test_pickling')

        Construction with ``DifferentiableManifold.vector_field``::

            sage: a1 = M.vector_field(name='a'); a1
            Vector field a on the 2-dimensional differentiable manifold M
            sage: type(a1) == type(a)
            True

        .. TODO::

            Fix ``_test_pickling`` (in the superclass :class:`TensorField`).

        """
        TensorField.__init__(self, vector_field_module, (1,0), name=name,
                             latex_name=latex_name)
        # Initialization of derived quantities:
        TensorField._init_derived(self)
        # Initialization of list of quantities depending on self:
        self._init_dependencies()
Beispiel #13
0
    def __mul__(self, other):
        r"""
        Redefinition of
        :meth:`~sage.manifolds.differentiable.tensorfield.TensorField.__mul__`
        so that ``*`` dispatches either to automorphism composition or
        to the tensor product.

        TESTS::

            sage: M = Manifold(2, 'M') # the 2-dimensional sphere S^2
            sage: U = M.open_subset('U') # complement of the North pole
            sage: c_xy.<x,y> = U.chart() # stereographic coordinates from the North pole
            sage: V = M.open_subset('V') # complement of the South pole
            sage: c_uv.<u,v> = V.chart() # stereographic coordinates from the South pole
            sage: M.declare_union(U,V)   # S^2 is the union of U and V
            sage: xy_to_uv = c_xy.transition_map(c_uv, (x/(x^2+y^2), y/(x^2+y^2)),
            ....:                                intersection_name='W', restrictions1= x^2+y^2!=0,
            ....:                                restrictions2= u^2+v^2!=0)
            sage: uv_to_xy = xy_to_uv.inverse()
            sage: e_xy = c_xy.frame(); e_uv = c_uv.frame()
            sage: a = M.automorphism_field(name='a')
            sage: a[e_xy, :] = [[-1, 0], [0, 1]]
            sage: a.add_comp_by_continuation(e_uv, U.intersection(V), c_uv)
            sage: b = M.automorphism_field(name='b')
            sage: b[e_uv, :] = [[1, 0], [0, -2]]
            sage: b.add_comp_by_continuation(e_xy, U.intersection(V), c_xy)
            sage: w = M.vector_field(name='w')
            sage: w[e_xy, :] = [3, 1]
            sage: w.add_comp_by_continuation(e_uv, U.intersection(V), c_uv)
            sage: s = a.__mul__(b); s  # automorphism composition
            Field of tangent-space automorphisms on the 2-dimensional differentiable manifold M
            sage: s(w) == a(b(w))  # long time
            True
            sage: s = a.__mul__(w); s  # tensor product
            Tensor field of type (2,1) on the 2-dimensional differentiable manifold M

        """
        if isinstance(other, AutomorphismField):
            return self._mul_(other)  # general linear group law
        else:
            return TensorField.__mul__(self, other)  # tensor product
    def __mul__(self, other):
        r"""
        Redefinition of
        :meth:`~sage.manifolds.differentiable.tensorfield.TensorField.__mul__`
        so that ``*`` dispatches either to automorphism composition or
        to the tensor product.

        TESTS::

            sage: M = Manifold(2, 'M') # the 2-dimensional sphere S^2
            sage: U = M.open_subset('U') # complement of the North pole
            sage: c_xy.<x,y> = U.chart() # stereographic coordinates from the North pole
            sage: V = M.open_subset('V') # complement of the South pole
            sage: c_uv.<u,v> = V.chart() # stereographic coordinates from the South pole
            sage: M.declare_union(U,V)   # S^2 is the union of U and V
            sage: xy_to_uv = c_xy.transition_map(c_uv, (x/(x^2+y^2), y/(x^2+y^2)),
            ....:                                intersection_name='W', restrictions1= x^2+y^2!=0,
            ....:                                restrictions2= u^2+v^2!=0)
            sage: uv_to_xy = xy_to_uv.inverse()
            sage: e_xy = c_xy.frame(); e_uv = c_uv.frame()
            sage: a = M.automorphism_field(name='a')
            sage: a[e_xy, :] = [[-1, 0], [0, 1]]
            sage: a.add_comp_by_continuation(e_uv, U.intersection(V), c_uv)
            sage: b = M.automorphism_field(name='b')
            sage: b[e_uv, :] = [[1, 0], [0, -2]]
            sage: b.add_comp_by_continuation(e_xy, U.intersection(V), c_xy)
            sage: w = M.vector_field(name='w')
            sage: w[e_xy, :] = [3, 1]
            sage: w.add_comp_by_continuation(e_uv, U.intersection(V), c_uv)
            sage: s = a.__mul__(b); s  # automorphism composition
            Field of tangent-space automorphisms on the 2-dimensional differentiable manifold M
            sage: s(w) == a(b(w))  # long time
            True
            sage: s = a.__mul__(w); s  # tensor product
            Tensor field of type (2,1) on the 2-dimensional differentiable manifold M

        """
        if isinstance(other, AutomorphismField):
            return self._mul_(other)  # general linear group law
        else:
            return TensorField.__mul__(self, other)  # tensor product
Beispiel #15
0
    def __call__(self, *arg):
        r"""
        Redefinition of
        :meth:`~sage.manifolds.differentiable.tensorfield.TensorField.__call__`
        to allow for a proper treatment of the identity map and of the call
        with a single argument

        TESTS:

        Field of identity maps on the 2-sphere::

            sage: M = Manifold(2, 'M') # the 2-dimensional sphere S^2
            sage: U = M.open_subset('U') # complement of the North pole
            sage: c_xy.<x,y> = U.chart() # stereographic coordinates from the North pole
            sage: V = M.open_subset('V') # complement of the South pole
            sage: c_uv.<u,v> = V.chart() # stereographic coordinates from the South pole
            sage: M.declare_union(U,V)   # S^2 is the union of U and V
            sage: xy_to_uv = c_xy.transition_map(c_uv, (x/(x^2+y^2), y/(x^2+y^2)),
            ....:                                intersection_name='W', restrictions1= x^2+y^2!=0,
            ....:                                restrictions2= u^2+v^2!=0)
            sage: uv_to_xy = xy_to_uv.inverse()
            sage: e_xy = c_xy.frame(); e_uv = c_uv.frame()
            sage: w = M.vector_field(name='w')
            sage: w[e_xy, :] = [3, 1]
            sage: w.add_comp_by_continuation(e_uv, U.intersection(V), c_uv)
            sage: z = M.one_form(name='z')
            sage: z[e_xy, :] = [-y, x]
            sage: z.add_comp_by_continuation(e_uv, U.intersection(V), c_uv)
            sage: Id = M.tangent_identity_field()
            sage: s = Id(w); s
            Vector field w on the 2-dimensional differentiable manifold M
            sage: s == w
            True
            sage: s = Id(z, w); s
            Scalar field z(w) on the 2-dimensional differentiable manifold M
            sage: s == z(w)
            True

        Field of automorphisms on the 2-sphere::

            sage: a = M.automorphism_field(name='a')
            sage: a[e_xy, :] = [[-1, 0], [0, 1]]
            sage: a.add_comp_by_continuation(e_uv, U.intersection(V), c_uv)

        Call with a single argument::

            sage: s = a(w); s
            Vector field a(w) on the 2-dimensional differentiable manifold M
            sage: s.display(e_xy)
            a(w) = -3 d/dx + d/dy
            sage: s.display(e_uv)
            a(w) = (3*u^2 - 2*u*v - 3*v^2) d/du + (u^2 + 6*u*v - v^2) d/dv
            sage: s.restrict(U) == a.restrict(U)(w.restrict(U))
            True
            sage: s.restrict(V) == a.restrict(V)(w.restrict(V))
            True
            sage: s.restrict(U) == a(w.restrict(U))
            True
            sage: s.restrict(U) == a.restrict(U)(w)
            True

        Call with two arguments::

            sage: s = a(z, w); s
            Scalar field a(z,w) on the 2-dimensional differentiable manifold M
            sage: s.display()
            a(z,w): M --> R
            on U: (x, y) |--> x + 3*y
            on V: (u, v) |--> (u + 3*v)/(u^2 + v^2)
            sage: s.restrict(U) == a.restrict(U)(z.restrict(U), w.restrict(U))
            True
            sage: s.restrict(V) == a.restrict(V)(z.restrict(V), w.restrict(V))
            True
            sage: s.restrict(U) == a(z.restrict(U), w.restrict(U))
            True
            sage: s.restrict(U) == a(z, w.restrict(U))
            True

        """
        if self._is_identity:
            if len(arg) == 1:
                # The identity map acting as such, on a vector field:
                vector = arg[0]
                if vector._tensor_type != (1,0):
                    raise TypeError("the argument must be a vector field")
                dom = self._domain.intersection(vector._domain)
                return vector.restrict(dom)
            elif len(arg) == 2:
                # self acting as a type-(1,1) tensor on a pair
                # (1-form, vector field), returning a scalar field:
                oneform = arg[0]
                vector = arg[1]
                dom = self._domain.intersection(
                                  oneform._domain).intersection(vector._domain)
                return oneform.restrict(dom)(vector.restrict(dom))
            else:
                raise TypeError("wrong number of arguments")
        # Generic case
        if len(arg) == 1:
            # The field of automorphisms acting on a vector field:
            vector = arg[0]
            if vector._tensor_type != (1,0):
                raise TypeError("the argument must be a vector field")
            dom = self._domain.intersection(vector._domain)
            vector_dom = vector.restrict(dom)
            if dom != self._domain:
                return self.restrict(dom)(vector_dom)
            resu = dom.vector_field()
            if self._name is not None and vector._name is not None:
                resu._name = self._name + "(" + vector._name + ")"
            if self._latex_name is not None and vector._latex_name is not None:
                resu._latex_name = self._latex_name + r"\left(" + \
                                   vector._latex_name + r"\right)"
            for sdom, automorph in self._restrictions.items():
                resu._restrictions[sdom] = automorph(vector_dom.restrict(sdom))
            return resu
        # Case of 2 arguments:
        return TensorField.__call__(self, *arg)
    def __call__(self, *arg):
        r"""
        Redefinition of
        :meth:`~sage.manifolds.differentiable.tensorfield.TensorField.__call__`
        to allow for a proper treatment of the identity map and of the call
        with a single argument

        TESTS:

        Field of identity maps on the 2-sphere::

            sage: M = Manifold(2, 'M') # the 2-dimensional sphere S^2
            sage: U = M.open_subset('U') # complement of the North pole
            sage: c_xy.<x,y> = U.chart() # stereographic coordinates from the North pole
            sage: V = M.open_subset('V') # complement of the South pole
            sage: c_uv.<u,v> = V.chart() # stereographic coordinates from the South pole
            sage: M.declare_union(U,V)   # S^2 is the union of U and V
            sage: xy_to_uv = c_xy.transition_map(c_uv, (x/(x^2+y^2), y/(x^2+y^2)),
            ....:                                intersection_name='W', restrictions1= x^2+y^2!=0,
            ....:                                restrictions2= u^2+v^2!=0)
            sage: uv_to_xy = xy_to_uv.inverse()
            sage: e_xy = c_xy.frame(); e_uv = c_uv.frame()
            sage: w = M.vector_field(name='w')
            sage: w[e_xy, :] = [3, 1]
            sage: w.add_comp_by_continuation(e_uv, U.intersection(V), c_uv)
            sage: z = M.one_form(name='z')
            sage: z[e_xy, :] = [-y, x]
            sage: z.add_comp_by_continuation(e_uv, U.intersection(V), c_uv)
            sage: Id = M.tangent_identity_field()
            sage: s = Id(w); s
            Vector field w on the 2-dimensional differentiable manifold M
            sage: s == w
            True
            sage: s = Id(z, w); s
            Scalar field z(w) on the 2-dimensional differentiable manifold M
            sage: s == z(w)
            True

        Field of automorphisms on the 2-sphere::

            sage: a = M.automorphism_field(name='a')
            sage: a[e_xy, :] = [[-1, 0], [0, 1]]
            sage: a.add_comp_by_continuation(e_uv, U.intersection(V), c_uv)

        Call with a single argument::

            sage: s = a(w); s
            Vector field a(w) on the 2-dimensional differentiable manifold M
            sage: s.display(e_xy)
            a(w) = -3 d/dx + d/dy
            sage: s.display(e_uv)
            a(w) = (3*u^2 - 2*u*v - 3*v^2) d/du + (u^2 + 6*u*v - v^2) d/dv
            sage: s.restrict(U) == a.restrict(U)(w.restrict(U))
            True
            sage: s.restrict(V) == a.restrict(V)(w.restrict(V))
            True
            sage: s.restrict(U) == a(w.restrict(U))
            True
            sage: s.restrict(U) == a.restrict(U)(w)
            True

        Call with two arguments::

            sage: s = a(z, w); s
            Scalar field a(z,w) on the 2-dimensional differentiable manifold M
            sage: s.display()
            a(z,w): M --> R
            on U: (x, y) |--> x + 3*y
            on V: (u, v) |--> (u + 3*v)/(u^2 + v^2)
            sage: s.restrict(U) == a.restrict(U)(z.restrict(U), w.restrict(U))
            True
            sage: s.restrict(V) == a.restrict(V)(z.restrict(V), w.restrict(V))
            True
            sage: s.restrict(U) == a(z.restrict(U), w.restrict(U))
            True
            sage: s.restrict(U) == a(z, w.restrict(U))
            True

        """
        if self._is_identity:
            if len(arg) == 1:
                # The identity map acting as such, on a vector field:
                vector = arg[0]
                if vector._tensor_type != (1,0):
                    raise TypeError("the argument must be a vector field")
                dom = self._domain.intersection(vector._domain)
                return vector.restrict(dom)
            elif len(arg) == 2:
                # self acting as a type-(1,1) tensor on a pair
                # (1-form, vector field), returning a scalar field:
                oneform = arg[0]
                vector = arg[1]
                dom = self._domain.intersection(
                                  oneform._domain).intersection(vector._domain)
                return oneform.restrict(dom)(vector.restrict(dom))
            else:
                raise TypeError("wrong number of arguments")
        # Generic case
        if len(arg) == 1:
            # The field of automorphisms acting on a vector field:
            vector = arg[0]
            if vector._tensor_type != (1,0):
                raise TypeError("the argument must be a vector field")
            dom = self._domain.intersection(vector._domain)
            vector_dom = vector.restrict(dom)
            if dom != self._domain:
                return self.restrict(dom)(vector_dom)
            resu = dom.vector_field()
            if self._name is not None and vector._name is not None:
                resu._name = self._name + "(" + vector._name + ")"
            if self._latex_name is not None and vector._latex_name is not None:
                resu._latex_name = self._latex_name + r"\left(" + \
                                   vector._latex_name + r"\right)"
            for sdom, automorph in self._restrictions.items():
                resu._restrictions[sdom] = automorph(vector_dom.restrict(sdom))
            return resu
        # Case of 2 arguments:
        return TensorField.__call__(self, *arg)
    def __init__(self, vector_field_module, name=None, latex_name=None,
                 is_identity=False):
        r"""
        Construct a field of tangent-space automorphisms on a
        non-parallelizable manifold.

        TESTS:

        Construction via ``parent.element_class``, and not via a direct call
        to ``AutomorphismField``, to fit with the category framework::

            sage: M = Manifold(2, 'M')
            sage: U = M.open_subset('U') ; V = M.open_subset('V')
            sage: M.declare_union(U,V)   # M is the union of U and V
            sage: c_xy.<x,y> = U.chart() ; c_uv.<u,v> = V.chart()
            sage: transf = c_xy.transition_map(c_uv, (x+y, x-y), intersection_name='W',
            ....:                              restrictions1= x>0, restrictions2= u+v>0)
            sage: inv = transf.inverse()
            sage: XM = M.vector_field_module()
            sage: GL = XM.general_linear_group()
            sage: a = GL.element_class(XM, name='a'); a
            Field of tangent-space automorphisms a on the 2-dimensional
             differentiable manifold M
            sage: a[c_xy.frame(), :] = [[1+x^2, 0], [0, 1+y^2]]
            sage: a.add_comp_by_continuation(c_uv.frame(), U.intersection(V), c_uv)
            sage: TestSuite(a).run(skip='_test_pickling')

        Construction of the identity field::

            sage: b = GL.element_class(XM, is_identity=True); b
            Field of tangent-space identity maps on the 2-dimensional
             differentiable manifold M
            sage: TestSuite(b).run(skip='_test_pickling')

        Construction with ``DifferentiableManifold.automorphism_field``::

            sage: a1 = M.automorphism_field(name='a'); a1
            Field of tangent-space automorphisms a on the 2-dimensional
             differentiable manifold M
            sage: type(a1) == type(a)
            True

        .. TODO::

            Fix ``_test_pickling`` (in the superclass :class:`TensorField`).

        """
        if is_identity:
            if name is None:
                name = 'Id'
            if latex_name is None and name == 'Id':
                latex_name = r'\mathrm{Id}'
        TensorField.__init__(self, vector_field_module, (1,1), name=name,
                             latex_name=latex_name,
                             parent=vector_field_module.general_linear_group())
        self._is_identity = is_identity
        self._init_derived() # initialization of derived quantities
        # Specific initializations for the field of identity maps:
        if self._is_identity:
            self._inverse = self
            for dom in self._domain._subsets:
                if dom.is_manifestly_parallelizable():
                    fmodule = dom.vector_field_module()
                    self._restrictions[dom] = fmodule.identity_map(name=name,
                                                         latex_name=latex_name)
Beispiel #18
0
    def __init__(self, vector_field_module, name=None, latex_name=None,
                 is_identity=False):
        r"""
        Construct a field of tangent-space automorphisms on a
        non-parallelizable manifold.

        TESTS:

        Construction via ``parent.element_class``, and not via a direct call
        to ``AutomorphismField``, to fit with the category framework::

            sage: M = Manifold(2, 'M')
            sage: U = M.open_subset('U') ; V = M.open_subset('V')
            sage: M.declare_union(U,V)   # M is the union of U and V
            sage: c_xy.<x,y> = U.chart() ; c_uv.<u,v> = V.chart()
            sage: transf = c_xy.transition_map(c_uv, (x+y, x-y), intersection_name='W',
            ....:                              restrictions1= x>0, restrictions2= u+v>0)
            sage: inv = transf.inverse()
            sage: XM = M.vector_field_module()
            sage: GL = XM.general_linear_group()
            sage: a = GL.element_class(XM, name='a'); a
            Field of tangent-space automorphisms a on the 2-dimensional
             differentiable manifold M
            sage: a[c_xy.frame(), :] = [[1+x^2, 0], [0, 1+y^2]]
            sage: a.add_comp_by_continuation(c_uv.frame(), U.intersection(V), c_uv)
            sage: TestSuite(a).run(skip='_test_pickling')

        Construction of the identity field::

            sage: b = GL.element_class(XM, is_identity=True); b
            Field of tangent-space identity maps on the 2-dimensional
             differentiable manifold M
            sage: TestSuite(b).run(skip='_test_pickling')

        Construction with ``DifferentiableManifold.automorphism_field``::

            sage: a1 = M.automorphism_field(name='a'); a1
            Field of tangent-space automorphisms a on the 2-dimensional
             differentiable manifold M
            sage: type(a1) == type(a)
            True

        .. TODO::

            Fix ``_test_pickling`` (in the superclass :class:`TensorField`).

        """
        if is_identity:
            if name is None:
                name = 'Id'
            if latex_name is None and name == 'Id':
                latex_name = r'\mathrm{Id}'
        TensorField.__init__(self, vector_field_module, (1,1), name=name,
                             latex_name=latex_name,
                             parent=vector_field_module.general_linear_group())
        self._is_identity = is_identity
        self._init_derived() # initialization of derived quantities
        # Specific initializations for the field of identity maps:
        if self._is_identity:
            self._inverse = self
            for dom in self._domain._subsets:
                if dom.is_manifestly_parallelizable():
                    fmodule = dom.vector_field_module()
                    self._restrictions[dom] = fmodule.identity_map(name=name,
                                                         latex_name=latex_name)
Beispiel #19
0
    def restrict(self, subdomain, dest_map=None):
        r"""
        Return the restriction of ``self`` to some subdomain.

        This is a redefinition of
        :meth:`sage.manifolds.differentiable.tensorfield.TensorField.restrict`
        to take into account the identity map.

        INPUT:

        - ``subdomain`` --
          :class:`~sage.manifolds.differentiable.manifold.DifferentiableManifold`
          open subset `V` of ``self._domain``
        - ``dest_map`` -- (default: ``None``)
          :class:`~sage.manifolds.differentiable.diff_map.DiffMap`;
          destination map `\Phi:\ V \rightarrow N`, where `N` is a
          subdomain of ``self._codomain``; if ``None``, the restriction
          of ``self.base_module().destination_map()`` to `V` is used

        OUTPUT:

        - a :class:`AutomorphismField` representing the restriction

        EXAMPLES:

        Restrictions of an automorphism field on the 2-sphere::

            sage: M = Manifold(2, 'S^2', start_index=1)
            sage: U = M.open_subset('U') # the complement of the North pole
            sage: stereoN.<x,y> = U.chart()  # stereographic coordinates from the North pole
            sage: eN = stereoN.frame() # the associated vector frame
            sage: V =  M.open_subset('V') # the complement of the South pole
            sage: stereoS.<u,v> = V.chart()  # stereographic coordinates from the South pole
            sage: eS = stereoS.frame() # the associated vector frame
            sage: transf = stereoN.transition_map(stereoS, (x/(x^2+y^2), y/(x^2+y^2)), intersection_name='W', \
                                                  restrictions1= x^2+y^2!=0, restrictions2= u^2+v^2!=0)
            sage: inv = transf.inverse() # transformation from stereoS to stereoN
            sage: W = U.intersection(V) # the complement of the North and South poles
            sage: stereoN_W = W.atlas()[0]  # restriction of stereographic coord. from North pole to W
            sage: stereoS_W = W.atlas()[1]  # restriction of stereographic coord. from South pole to W
            sage: eN_W = stereoN_W.frame() ; eS_W = stereoS_W.frame()
            sage: a = M.automorphism_field(name='a') ; a
            Field of tangent-space automorphisms a on the 2-dimensional
             differentiable manifold S^2
            sage: a[eN,:] = [[1, atan(x^2+y^2)], [0,3]]
            sage: a.add_comp_by_continuation(eS, W, chart=stereoS)
            sage: a.restrict(U)
            Field of tangent-space automorphisms a on the Open subset U of the
             2-dimensional differentiable manifold S^2
            sage: a.restrict(U)[eN,:]
            [                1 arctan(x^2 + y^2)]
            [                0                 3]
            sage: a.restrict(V)
            Field of tangent-space automorphisms a on the Open subset V of the
             2-dimensional differentiable manifold S^2
            sage: a.restrict(V)[eS,:]
            [   (u^4 + 10*u^2*v^2 + v^4 + 2*(u^3*v - u*v^3)*arctan(1/(u^2 + v^2)))/(u^4 + 2*u^2*v^2 + v^4)  -(4*u^3*v - 4*u*v^3 + (u^4 - 2*u^2*v^2 + v^4)*arctan(1/(u^2 + v^2)))/(u^4 + 2*u^2*v^2 + v^4)]
            [                    4*(u^2*v^2*arctan(1/(u^2 + v^2)) - u^3*v + u*v^3)/(u^4 + 2*u^2*v^2 + v^4) (3*u^4 - 2*u^2*v^2 + 3*v^4 - 2*(u^3*v - u*v^3)*arctan(1/(u^2 + v^2)))/(u^4 + 2*u^2*v^2 + v^4)]
            sage: a.restrict(W)
            Field of tangent-space automorphisms a on the Open subset W of the
             2-dimensional differentiable manifold S^2
            sage: a.restrict(W)[eN_W,:]
            [                1 arctan(x^2 + y^2)]
            [                0                 3]

        Restrictions of the field of tangent-space identity maps::

            sage: id = M.tangent_identity_field() ; id
            Field of tangent-space identity maps on the 2-dimensional
             differentiable manifold S^2
            sage: id.restrict(U)
            Field of tangent-space identity maps on the Open subset U of the
             2-dimensional differentiable manifold S^2
            sage: id.restrict(U)[eN,:]
            [1 0]
            [0 1]
            sage: id.restrict(V)
            Field of tangent-space identity maps on the Open subset V of the
             2-dimensional differentiable manifold S^2
            sage: id.restrict(V)[eS,:]
            [1 0]
            [0 1]
            sage: id.restrict(W)[eN_W,:]
            [1 0]
            [0 1]
            sage: id.restrict(W)[eS_W,:]
            [1 0]
            [0 1]

        """
        if subdomain == self._domain:
            return self
        if subdomain not in self._restrictions:
            if not self._is_identity:
                return TensorField.restrict(self, subdomain, dest_map=dest_map)
            # Special case of the identity map:
            if not subdomain.is_subset(self._domain):
                raise ValueError("the provided domain is not a subset of " +
                                 "the field's domain")
            if dest_map is None:
                dest_map = self._vmodule._dest_map.restrict(subdomain)
            elif not dest_map._codomain.is_subset(self._ambient_domain):
                raise ValueError("the argument 'dest_map' is not compatible " +
                                 "with the ambient domain of " +
                                 "the {}".format(self))
            smodule = subdomain.vector_field_module(dest_map=dest_map)
            self._restrictions[subdomain] = smodule.identity_map()
        return self._restrictions[subdomain]
    def restrict(self, subdomain, dest_map=None):
        r"""
        Return the restriction of ``self`` to some subdomain.

        This is a redefinition of
        :meth:`sage.manifolds.differentiable.tensorfield.TensorField.restrict`
        to take into account the identity map.

        INPUT:

        - ``subdomain`` --
          :class:`~sage.manifolds.differentiable.manifold.DifferentiableManifold`
          open subset `V` of ``self._domain``
        - ``dest_map`` -- (default: ``None``)
          :class:`~sage.manifolds.differentiable.diff_map.DiffMap`;
          destination map `\Phi:\ V \rightarrow N`, where `N` is a
          subdomain of ``self._codomain``; if ``None``, the restriction
          of ``self.base_module().destination_map()`` to `V` is used

        OUTPUT:

        - a :class:`AutomorphismField` representing the restriction

        EXAMPLES:

        Restrictions of an automorphism field on the 2-sphere::

            sage: M = Manifold(2, 'S^2', start_index=1)
            sage: U = M.open_subset('U') # the complement of the North pole
            sage: stereoN.<x,y> = U.chart()  # stereographic coordinates from the North pole
            sage: eN = stereoN.frame() # the associated vector frame
            sage: V =  M.open_subset('V') # the complement of the South pole
            sage: stereoS.<u,v> = V.chart()  # stereographic coordinates from the South pole
            sage: eS = stereoS.frame() # the associated vector frame
            sage: transf = stereoN.transition_map(stereoS, (x/(x^2+y^2), y/(x^2+y^2)), intersection_name='W', \
                                                  restrictions1= x^2+y^2!=0, restrictions2= u^2+v^2!=0)
            sage: inv = transf.inverse() # transformation from stereoS to stereoN
            sage: W = U.intersection(V) # the complement of the North and South poles
            sage: stereoN_W = W.atlas()[0]  # restriction of stereographic coord. from North pole to W
            sage: stereoS_W = W.atlas()[1]  # restriction of stereographic coord. from South pole to W
            sage: eN_W = stereoN_W.frame() ; eS_W = stereoS_W.frame()
            sage: a = M.automorphism_field(name='a') ; a
            Field of tangent-space automorphisms a on the 2-dimensional
             differentiable manifold S^2
            sage: a[eN,:] = [[1, atan(x^2+y^2)], [0,3]]
            sage: a.add_comp_by_continuation(eS, W, chart=stereoS)
            sage: a.restrict(U)
            Field of tangent-space automorphisms a on the Open subset U of the
             2-dimensional differentiable manifold S^2
            sage: a.restrict(U)[eN,:]
            [                1 arctan(x^2 + y^2)]
            [                0                 3]
            sage: a.restrict(V)
            Field of tangent-space automorphisms a on the Open subset V of the
             2-dimensional differentiable manifold S^2
            sage: a.restrict(V)[eS,:]
            [   (u^4 + 10*u^2*v^2 + v^4 + 2*(u^3*v - u*v^3)*arctan(1/(u^2 + v^2)))/(u^4 + 2*u^2*v^2 + v^4)  -(4*u^3*v - 4*u*v^3 + (u^4 - 2*u^2*v^2 + v^4)*arctan(1/(u^2 + v^2)))/(u^4 + 2*u^2*v^2 + v^4)]
            [                    4*(u^2*v^2*arctan(1/(u^2 + v^2)) - u^3*v + u*v^3)/(u^4 + 2*u^2*v^2 + v^4) (3*u^4 - 2*u^2*v^2 + 3*v^4 - 2*(u^3*v - u*v^3)*arctan(1/(u^2 + v^2)))/(u^4 + 2*u^2*v^2 + v^4)]
            sage: a.restrict(W)
            Field of tangent-space automorphisms a on the Open subset W of the
             2-dimensional differentiable manifold S^2
            sage: a.restrict(W)[eN_W,:]
            [                1 arctan(x^2 + y^2)]
            [                0                 3]

        Restrictions of the field of tangent-space identity maps::

            sage: id = M.tangent_identity_field() ; id
            Field of tangent-space identity maps on the 2-dimensional
             differentiable manifold S^2
            sage: id.restrict(U)
            Field of tangent-space identity maps on the Open subset U of the
             2-dimensional differentiable manifold S^2
            sage: id.restrict(U)[eN,:]
            [1 0]
            [0 1]
            sage: id.restrict(V)
            Field of tangent-space identity maps on the Open subset V of the
             2-dimensional differentiable manifold S^2
            sage: id.restrict(V)[eS,:]
            [1 0]
            [0 1]
            sage: id.restrict(W)[eN_W,:]
            [1 0]
            [0 1]
            sage: id.restrict(W)[eS_W,:]
            [1 0]
            [0 1]

        """
        if subdomain == self._domain:
            return self
        if subdomain not in self._restrictions:
            if not self._is_identity:
                return TensorField.restrict(self, subdomain, dest_map=dest_map)
            # Special case of the identity map:
            if not subdomain.is_subset(self._domain):
                raise ValueError("the provided domain is not a subset of " +
                                 "the field's domain")
            if dest_map is None:
                dest_map = self._vmodule._dest_map.restrict(subdomain)
            elif not dest_map._codomain.is_subset(self._ambient_domain):
                raise ValueError("the argument 'dest_map' is not compatible " +
                                 "with the ambient domain of " +
                                 "the {}".format(self))
            smodule = subdomain.vector_field_module(dest_map=dest_map)
            self._restrictions[subdomain] = smodule.identity_map()
        return self._restrictions[subdomain]