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)
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)