Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
r""" Tangent-Space Automorphism Fields
The class :class:`AutomorphismField` implements fields of automorphisms of tangent spaces to a generic (a priori not parallelizable) differentiable manifold, while the class :class:`AutomorphismFieldParal` is devoted to fields of automorphisms of tangent spaces to a parallelizable manifold. The latter play the important role of transitions between vector frames sharing the same domain on a differentiable manifold.
AUTHORS:
- Eric Gourgoulhon (2015): initial version - Travis Scrimshaw (2016): review tweaks
"""
#****************************************************************************** # Copyright (C) 2015 Eric Gourgoulhon <eric.gourgoulhon@obspm.fr> # Copyright (C) 2016 Travis Scrimshaw <tscrimsh@umn.edu> # # Distributed under the terms of the GNU General Public License (GPL) # as published by the Free Software Foundation; either version 2 of # the License, or (at your option) any later version. # http://www.gnu.org/licenses/ #******************************************************************************
r""" Field of automorphisms of tangent spaces to a generic (a priori not parallelizable) differentiable manifold.
Given a differentiable manifold `U` and a differentiable map `\Phi: U \rightarrow M` to a differentiable manifold `M`, a *field of tangent-space automorphisms along* `U` *with values on* `M \supset\Phi(U)` is a differentiable map
.. MATH::
a:\ U \longrightarrow T^{(1,1)} M,
with `T^{(1,1)} M` being the tensor bundle of type `(1,1)` over `M`, such that
.. MATH::
\forall p \in U,\ a(p) \in \mathrm{Aut}(T_{\Phi(p)} M),
i.e. `a(p)` is an automorphism of the tangent space to `M` at the point `\Phi(p)`.
The standard case of a field of tangent-space automorphisms *on* a manifold corresponds to `U = M` and `\Phi = \mathrm{Id}_M`. Other common cases are `\Phi` being an immersion and `\Phi` being a curve in `M` (`U` is then an open interval of `\RR`).
.. NOTE::
If `M` is parallelizable, then :class:`AutomorphismFieldParal` *must* be used instead.
INPUT:
- ``vector_field_module`` -- module `\mathfrak{X}(U,\Phi)` of vector fields along `U` with values on `M` via the map `\Phi` - ``name`` -- (default: ``None``) name given to the field - ``latex_name`` -- (default: ``None``) LaTeX symbol to denote the field; if none is provided, the LaTeX symbol is set to ``name`` - ``is_identity`` -- (default: ``False``) determines whether the constructed object is a field of identity automorphisms
EXAMPLES:
Field of tangent-space automorphisms on a non-parallelizable 2-dimensional manifold::
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: a = M.automorphism_field('a') ; a Field of tangent-space automorphisms a on the 2-dimensional differentiable manifold M sage: a.parent() General linear group of the Module X(M) of vector fields on the 2-dimensional differentiable manifold M
We first define the components of `a` with respect to the coordinate frame on `U`::
sage: eU = c_xy.frame() ; eV = c_uv.frame() sage: a[eU,:] = [[1,x], [0,2]]
We then set the components with respect to the coordinate frame on `V` by extending the expressions of the components in the corresponding subframe on `W = U \cap V`::
sage: W = U.intersection(V) sage: a.add_comp_by_continuation(eV, W, c_uv)
At this stage, the automorphism field `a` is fully defined::
sage: a.display(eU) a = d/dx*dx + x d/dx*dy + 2 d/dy*dy sage: a.display(eV) a = (1/4*u + 1/4*v + 3/2) d/du*du + (-1/4*u - 1/4*v - 1/2) d/du*dv + (1/4*u + 1/4*v - 1/2) d/dv*du + (-1/4*u - 1/4*v + 3/2) d/dv*dv
In particular, we may ask for its inverse on the whole manifold `M`::
sage: ia = a.inverse() ; ia Field of tangent-space automorphisms a^(-1) on the 2-dimensional differentiable manifold M sage: ia.display(eU) a^(-1) = d/dx*dx - 1/2*x d/dx*dy + 1/2 d/dy*dy sage: ia.display(eV) a^(-1) = (-1/8*u - 1/8*v + 3/4) d/du*du + (1/8*u + 1/8*v + 1/4) d/du*dv + (-1/8*u - 1/8*v + 1/4) d/dv*du + (1/8*u + 1/8*v + 3/4) d/dv*dv
Equivalently, one can use the power minus one to get the inverse::
sage: ia is a^(-1) True
or the operator ``~``::
sage: ia is ~a True
""" 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`).
""" latex_name=latex_name, parent=vector_field_module.general_linear_group()) # Specific initializations for the field of identity maps: latex_name=latex_name)
r""" Return a string representation of ``self``.
TESTS::
sage: M = Manifold(2, 'M') sage: a = M.automorphism_field(name='a') sage: a._repr_() 'Field of tangent-space automorphisms a on the 2-dimensional differentiable manifold M' sage: repr(a) # indirect doctest 'Field of tangent-space automorphisms a on the 2-dimensional differentiable manifold M' sage: a # indirect doctest Field of tangent-space automorphisms a on the 2-dimensional differentiable manifold M
""" else:
r""" Initialize the derived quantities.
TESTS::
sage: M = Manifold(2, 'M') sage: a = M.automorphism_field(name='a') sage: a._init_derived()
"""
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: # then deletes the inverse automorphism:
r""" Create an instance of the same class as ``self`` on the same vector field module.
TESTS::
sage: M = Manifold(5, 'M') sage: a = M.automorphism_field(name='a') sage: a._new_instance() Field of tangent-space automorphisms on the 5-dimensional differentiable manifold M sage: a._new_instance().parent() is a.parent() True
"""
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
""" # The identity map acting as such, on a vector field: raise TypeError("the argument must be a vector field") # self acting as a type-(1,1) tensor on a pair # (1-form, vector field), returning a scalar field: oneform._domain).intersection(vector._domain) else: raise TypeError("wrong number of arguments") # Generic case # The field of automorphisms acting on a vector field: raise TypeError("the argument must be a vector field") vector._latex_name + r"\right)" # Case of 2 arguments:
#### MultiplicativeGroupElement methods ####
r""" Return the inverse automorphism of ``self``.
EXAMPLES:
Inverse of a field of tangent-space automorphisms on a non-parallelizable 2-dimensional manifold::
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: a = M.automorphism_field('a') sage: eU = c_xy.frame() ; eV = c_uv.frame() sage: a[eU,:] = [[1,x], [0,2]] sage: W = U.intersection(V) sage: a.add_comp_by_continuation(eV, W, c_uv) sage: ia = a.inverse() ; ia Field of tangent-space automorphisms a^(-1) on the 2-dimensional differentiable manifold M sage: a[eU,:], ia[eU,:] ( [1 x] [ 1 -1/2*x] [0 2], [ 0 1/2] ) sage: a[eV,:], ia[eV,:] ( [ 1/4*u + 1/4*v + 3/2 -1/4*u - 1/4*v - 1/2] [ 1/4*u + 1/4*v - 1/2 -1/4*u - 1/4*v + 3/2], [-1/8*u - 1/8*v + 3/4 1/8*u + 1/8*v + 1/4] [-1/8*u - 1/8*v + 1/4 1/8*u + 1/8*v + 3/4] )
Let us check that ia is indeed the inverse of a::
sage: s = a.contract(ia) sage: s[eU,:], s[eV,:] ( [1 0] [1 0] [0 1], [0 1] ) sage: s = ia.contract(a) sage: s[eU,:], s[eV,:] ( [1 0] [1 0] [0 1], [0 1] )
The result is cached::
sage: a.inverse() is ia True
Instead of ``inverse()``, one can use the power minus one to get the inverse::
sage: ia is a^(-1) True
or the operator ``~``::
sage: ia is ~a True
""" return self else: else: latex_name=inv_latex_name)
r""" Automorphism composition.
This implements the group law of `GL(X(U,\Phi))`, with `X(U,\Phi)` being the module of ``self``.
INPUT:
- ``other`` -- an automorphism of the same module as ``self``
OUTPUT:
- the automorphism resulting from the composition of ``other`` and ``self``
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: s = a._mul_(b); s Field of tangent-space automorphisms on the 2-dimensional differentiable manifold M sage: s.display(e_xy) -(x^4 - 10*x^2*y^2 + y^4)/(x^4 + 2*x^2*y^2 + y^4) d/dx*dx - 6*(x^3*y - x*y^3)/(x^4 + 2*x^2*y^2 + y^4) d/dx*dy + 6*(x^3*y - x*y^3)/(x^4 + 2*x^2*y^2 + y^4) d/dy*dx - 2*(x^4 - 4*x^2*y^2 + y^4)/(x^4 + 2*x^2*y^2 + y^4) d/dy*dy sage: s.display(e_uv) -(u^4 - 6*u^2*v^2 + v^4)/(u^4 + 2*u^2*v^2 + v^4) d/du*du + 8*(u^3*v - u*v^3)/(u^4 + 2*u^2*v^2 + v^4) d/du*dv - 4*(u^3*v - u*v^3)/(u^4 + 2*u^2*v^2 + v^4) d/dv*du - 2*(u^4 - 6*u^2*v^2 + v^4)/(u^4 + 2*u^2*v^2 + v^4) d/dv*dv 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(w) == a(b(w)) # long time True
""" # No need for consistency check since self and other are guaranteed # to have the same parent. In particular, they are defined on the same # module. # # Special cases: # General case: * other._restrictions[dom])
#### End of MultiplicativeGroupElement methods ####
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
""" else:
r""" Redefinition of :meth:`~sage.manifolds.differentiable.tensorfield.TensorField.__imul__`
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: a.__imul__(b) Field of tangent-space automorphisms on the 2-dimensional differentiable manifold M sage: s = a*b sage: a *= b sage: a == s True
"""
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]
""" # 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()
#******************************************************************************
r""" Field of tangent-space automorphisms with values on a parallelizable manifold.
Given a differentiable manifold `U` and a differentiable map `\Phi: U \rightarrow M` to a parallelizable manifold `M`, a *field of tangent-space automorphisms along* `U` *with values on* `M\supset\Phi(U)` is a differentiable map
.. MATH::
a:\ U \longrightarrow T^{(1,1)}M
(`T^{(1,1)}M` being the tensor bundle of type `(1,1)` over `M`) such that
.. MATH::
\forall p \in U,\ a(p) \in \mathrm{Aut}(T_{\Phi(p)} M)
i.e. `a(p)` is an automorphism of the tangent space to `M` at the point `\Phi(p)`.
The standard case of a field of tangent-space automorphisms *on* a manifold corresponds to `U=M` and `\Phi = \mathrm{Id}_M`. Other common cases are `\Phi` being an immersion and `\Phi` being a curve in `M` (`U` is then an open interval of `\RR`).
.. NOTE::
If `M` is not parallelizable, the class :class:`AutomorphismField` *must* be used instead.
INPUT:
- ``vector_field_module`` -- free module `\mathfrak{X}(U,\Phi)` of vector fields along `U` with values on `M` via the map `\Phi` - ``name`` -- (default: ``None``) name given to the field - ``latex_name`` -- (default: ``None``) LaTeX symbol to denote the field; if none is provided, the LaTeX symbol is set to ``name`` - ``is_identity`` -- (default: ``False``) determines whether the constructed object is a field of identity automorphisms
EXAMPLES:
A `\pi/3`-rotation in the Euclidean 2-plane::
sage: M = Manifold(2,'R^2') sage: c_xy.<x,y> = M.chart() sage: rot = M.automorphism_field('R') ; rot Field of tangent-space automorphisms R on the 2-dimensional differentiable manifold R^2 sage: rot[:] = [[sqrt(3)/2, -1/2], [1/2, sqrt(3)/2]] sage: rot.parent() General linear group of the Free module X(R^2) of vector fields on the 2-dimensional differentiable manifold R^2
The inverse automorphism is obtained via the method :meth:`inverse`::
sage: inv = rot.inverse() ; inv Field of tangent-space automorphisms R^(-1) on the 2-dimensional differentiable manifold R^2 sage: latex(inv) R^{-1} sage: inv[:] [1/2*sqrt(3) 1/2] [ -1/2 1/2*sqrt(3)] sage: rot[:] [1/2*sqrt(3) -1/2] [ 1/2 1/2*sqrt(3)] sage: inv[:] * rot[:] # check [1 0] [0 1]
Equivalently, one can use the power minus one to get the inverse::
sage: inv is rot^(-1) True
or the operator ``~``::
sage: inv is ~rot True
""" is_identity=False): r""" Construct a field of tangent-space automorphisms.
TESTS:
Construction via ``parent.element_class``, and not via a direct call to ``AutomorphismFieldParal``, to fit with the category framework::
sage: M = Manifold(2, 'M') sage: X.<x,y> = M.chart() # makes M parallelizable 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[:] = [[1+x^2, x*y], [0, 1+y^2]] sage: a.parent() General linear group of the Free module X(M) of vector fields on the 2-dimensional differentiable manifold M sage: a.parent() is M.automorphism_field_group() True sage: TestSuite(a).run()
Construction of the field of identity maps::
sage: b = GL.element_class(XM, is_identity=True); b Field of tangent-space identity maps on the 2-dimensional differentiable manifold M sage: b[:] [1 0] [0 1] sage: TestSuite(b).run()
""" name=name, latex_name=latex_name, is_identity=is_identity) # TensorFieldParal attributes: # Initialization of derived quantities:
r""" Return a string representation of ``self``.
TESTS::
sage: M = Manifold(2, 'M') sage: X.<x,y> = M.chart() sage: a = M.automorphism_field(name='a') sage: a._repr_() 'Field of tangent-space automorphisms a on the 2-dimensional differentiable manifold M' sage: repr(a) # indirect doctest 'Field of tangent-space automorphisms a on the 2-dimensional differentiable manifold M' sage: a # indirect doctest Field of tangent-space automorphisms a on the 2-dimensional differentiable manifold M
""" else:
r""" Delete the derived quantities.
INPUT:
- ``del_restrictions`` -- (default: ``True``) determines whether the restrictions of ``self`` to subdomains are deleted.
TESTS::
sage: M = Manifold(2, 'M') sage: X.<x,y> = M.chart() sage: a = M.automorphism_field(name='a') sage: a._del_derived()
""" # Delete the derived quantities pertaining to the mother classes:
# Method _new_instance() is defined in mother class FreeModuleAutomorphism
r""" Redefinition of :meth:`~sage.tensor.modules.free_module_automorphism.FreeModuleAutomorphism.__call__` to allow for domain treatment.
TESTS::
sage: M = Manifold(2, 'M') sage: X.<x,y> = M.chart() sage: a = M.automorphism_field(name='a') sage: a[:] = [[0, 1], [-1, 0]] sage: v = M.vector_field(name='v') sage: v[:] = [-y, x] sage: z = M.one_form(name='z') sage: z[:] = [1+y^2, x*y] sage: s = a.__call__(v); s Vector field a(v) on the 2-dimensional differentiable manifold M sage: s.display() a(v) = x d/dx + y d/dy sage: s = a.__call__(z, v); s Scalar field a(z,v) on the 2-dimensional differentiable manifold M sage: s.display() a(z,v): M --> R (x, y) |--> 2*x*y^2 + x sage: U = M.open_subset('U', coord_def={X: x>0}) sage: s = a.__call__(v.restrict(U)); s Vector field a(v) on the Open subset U of the 2-dimensional differentiable manifold M sage: s = a.__call__(z.restrict(U), v); s Scalar field a(z,v) on the Open subset U of the 2-dimensional differentiable manifold M sage: s.display() a(z,v): U --> R (x, y) |--> 2*x*y^2 + x
""" # the automorphism acting as such (map of a vector field to a # vector field) vector.restrict(dom)) # the automorphism acting as a type (1,1) tensor on a pair # (1-form, vector field), returning a scalar field: vector._domain) oneform.restrict(dom), vector.restrict(dom)) else: raise TypeError("wrong number of arguments")
r""" Return the inverse automorphism of ``self``.
EXAMPLES::
sage: M = Manifold(2, 'M') sage: X.<x,y> = M.chart() sage: a = M.automorphism_field(name='a') sage: a[:] = [[0, 2], [-1, 0]] sage: b = a.inverse(); b Field of tangent-space automorphisms a^(-1) on the 2-dimensional differentiable manifold M sage: b[:] [ 0 -1] [1/2 0] sage: a[:] [ 0 2] [-1 0]
The result is cached::
sage: a.inverse() is b True
Instead of ``inverse()``, one can use the power minus one to get the inverse::
sage: b is a^(-1) True
or the operator ``~``::
sage: b is ~a True
""" else: else: latex_name=inv_latex_name) else: # TODO: do the computation without the 'SR' enforcement [[self.comp(frame)[i, j, chart].expr(method='SR') for j in range(si, nsi)] for i in range(si, nsi)]) output_formatter=fmodule._output_formatter)
r""" Return the restriction of ``self`` to some subset of its domain.
If such restriction has not been defined yet, it is constructed here.
This is a redefinition of :meth:`sage.manifolds.differentiable.tensorfield_paral.TensorFieldParal.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 subset of ``self._codomain``; if ``None``, the restriction of ``self.base_module().destination_map()`` to `V` is used
OUTPUT:
- a :class:`AutomorphismFieldParal` representing the restriction
EXAMPLES:
Restriction of an automorphism field defined on `\RR^2` to a disk::
sage: M = Manifold(2, 'R^2') sage: c_cart.<x,y> = M.chart() # Cartesian coordinates on R^2 sage: D = M.open_subset('D') # the unit open disc sage: c_cart_D = c_cart.restrict(D, x^2+y^2<1) sage: a = M.automorphism_field(name='a') ; a Field of tangent-space automorphisms a on the 2-dimensional differentiable manifold R^2 sage: a[:] = [[1, x*y], [0, 3]] sage: a.restrict(D) Field of tangent-space automorphisms a on the Open subset D of the 2-dimensional differentiable manifold R^2 sage: a.restrict(D)[:] [ 1 x*y] [ 0 3]
Restriction to the disk 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 R^2 sage: id.restrict(D) Field of tangent-space identity maps on the Open subset D of the 2-dimensional differentiable manifold R^2 sage: id.restrict(D)[:] [1 0] [0 1] sage: id.restrict(D) == D.tangent_identity_field() True
""" dest_map=dest_map) # Special case of the identity map: raise ValueError("the provided domain is not a subset of " + "the field's domain.") 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))
r""" Value of ``self`` at a given point.
If the current field of tangent-space automorphisms is
.. MATH::
a:\ U \longrightarrow T^{(1,1)} M
associated with the differentiable map
.. MATH::
\Phi:\ U \longrightarrow M,
where `U` and `M` are two manifolds (possibly `U = M` and `\Phi = \mathrm{Id}_M`), then for any point `p \in U`, `a(p)` is an automorphism of the tangent space `T_{\Phi(p)}M`.
INPUT:
- ``point`` -- :class:`~sage.manifolds.point.ManifoldPoint`; point `p` in the domain of the field of automorphisms `a`
OUTPUT:
- the automorphism `a(p)` of the tangent vector space `T_{\Phi(p)}M`
EXAMPLES:
Automorphism at some point of a tangent space of a 2-dimensional manifold::
sage: M = Manifold(2, 'M') sage: c_xy.<x,y> = M.chart() sage: a = M.automorphism_field(name='a') sage: a[:] = [[1+exp(y), x*y], [0, 1+x^2]] sage: a.display() a = (e^y + 1) d/dx*dx + x*y d/dx*dy + (x^2 + 1) d/dy*dy sage: p = M.point((-2,3), name='p') ; p Point p on the 2-dimensional differentiable manifold M sage: ap = a.at(p) ; ap Automorphism a of the Tangent space at Point p on the 2-dimensional differentiable manifold M sage: ap.display() a = (e^3 + 1) d/dx*dx - 6 d/dx*dy + 5 d/dy*dy sage: ap.parent() General linear group of the Tangent space at Point p on the 2-dimensional differentiable manifold M
The identity map of the tangent space at point ``p``::
sage: id = M.tangent_identity_field() ; id Field of tangent-space identity maps on the 2-dimensional differentiable manifold M sage: idp = id.at(p) ; idp Identity map of the Tangent space at Point p on the 2-dimensional differentiable manifold M sage: idp is M.tangent_space(p).identity_map() True sage: idp.display() Id = d/dx*dx + d/dy*dy sage: idp.parent() General linear group of the Tangent space at Point p on the 2-dimensional differentiable manifold M sage: idp * ap == ap True
""" raise TypeError("the {} is not in the domain of the {}".format( point, self)) else: amb_point = dest_map(point) # "ambient" point |