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
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
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
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(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
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
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
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 __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()
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()
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
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)
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)
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]