{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Simple Vector Bundles" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This Jupyter notebook illustrates some basic features and functionalities regarding vector bundles within SageMath. The involved tools have been developed through the [SageManifolds](https://sagemanifolds.obspm.fr) project.\n", "\n", "**Author:** _Michael Jung_" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A version of SageMath at least equal to 9.0 is required to run this notebook:" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'SageMath version 9.1.beta6, Release Date: 2020-03-01'" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "version()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "First we set up the notebook to display math formulas using LaTeX formatting:" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "%display latex" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## The Möbius Bundle" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In this section we want to introduce a non-trivial line bundle and explain how it can be applied within `Sage` making use of our implementation." ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "M = Manifold(1, 'RP1',\n", " latex_name=r'\\mathbb{RP}^1',\n", " start_index=1,\n", " structure='topological')\n", "U = M.open_subset('U'); hu. = U.chart()\n", "V = M.open_subset('V'); hv. = V.chart()\n", "M.declare_union(U, V)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The change of coordinates is given by:" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "v = 1/u" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "u_to_v = hu.transition_map(hv, 1/u,\n", " intersection_name='W',\n", " restrictions1= u!=0,\n", " restrictions2= v!=0)\n", "u_to_v.display()" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "u = 1/v" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "W = U.intersection(V)\n", "v_to_u = u_to_v.inverse()\n", "v_to_u.display()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We define the Möbius bundle in `Sage`:" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Topological real vector bundle E -> RP1 of rank 1 over the base space 1-dimensional topological manifold RP1\n" ] } ], "source": [ "E = M.vector_bundle(1, 'E'); print(E)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let us state the two trivializations:" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "Trivialization (psiU, E|_U)" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "psiU = E.trivialization('psiU', latex_name=r'\\psi_U', domain=U)\n", "psiU" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "Trivialization (psiV, E|_V)" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "psiV = E.trivialization('psiV', latex_name=r'\\psi_V', domain=V)\n", "psiV" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Next we declare the transition map between $\\psi_U$ and $\\psi_V$:" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "Transition map from Trivialization (psiU, E|_U) to Trivialization (psiV, E|_V)" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "transf = psiU.transition_map(psiV, [[u]]); transf" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Of course each trivialization induces a local frame which we can get by the following command:" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "Trivialization frame (E|_U, ((psiU^*e_1)))" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "eU = psiU.frame(); eU" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The notation $\\left(\\psi_U^* e_{ 1 }\\right)$ stands for the local section on $U$ given by $p \\mapsto \\psi^{-1}_U(p,e_1)$, where $e_1$ is the standard basis of $\\mathbb{R}$. Similarly, we have for $\\psi_V$:" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "Trivialization frame (E|_V, ((psiV^*e_1)))" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "eV = psiV.frame(); eV" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The corresponding bundle automorphism $\\psi_U^{-1} \\circ \\psi_V:\\left. E \\right|_{W} \\to \\left. E \\right|_{W}$ translating $\\left(\\psi_V^* e_{ 1 }\\right)$ into $\\left(\\psi_U^* e_{ 1 }\\right)$ can be easily returned:" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "Automorphism psiU^(-1)*psiV of the Free module C^0(W;E) of sections on the Open subset W of the 1-dimensional topological manifold RP1 with values in the real vector bundle E of rank 1" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "transf.automorphism()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This is an instance of `FreeModuleAutomorphism`:" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "True" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from sage.tensor.modules.free_module_automorphism import FreeModuleAutomorphism\n", "isinstance(transf.automorphism(), FreeModuleAutomorphism)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can even get its determinant which is a scalar field on the intersection $W = U \\cap V$:" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "det(psiU^(-1)*psiV): W --> R\n", " u |--> u\n", " v |--> 1/v" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "transf.det().display()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can see that the determinant is negative if $u<0$. It is therefore reasonable to suspect that the vector bundle $E$ is not orientable. This is indeed true. As a consequence, $E$ is not trivial and each global section must vanish somewhere. To exemplify this, we define the corresponding section module over $\\mathbb{RP}^1$:" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "Module C^0(RP1;E) of sections on the 1-dimensional topological manifold RP1 with values in the real vector bundle E of rank 1" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "C0 = E.section_module(); C0" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can see that `Sage` rejects $C^{0}(\\mathbb{RP}^1;E)$ as a free module:" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "False" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from sage.tensor.modules.finite_rank_free_module import FiniteRankFreeModule\n", "isinstance(C0, FiniteRankFreeModule)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This is because there is no global frame that `Sage` knows about:" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "False" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "E.is_manifestly_trivial()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "On the contrary, the section module over $U$ must be free:" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "Free module C^0(U;E) of sections on the Open subset U of the 1-dimensional topological manifold RP1 with values in the real vector bundle E of rank 1" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "C0U = E.section_module(domain=U); C0U" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "And indeed, it is:" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "True" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from sage.tensor.modules.finite_rank_free_module import FiniteRankFreeModule\n", "isinstance(C0U, FiniteRankFreeModule)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We start with some concrete computations and therefore define a section on $U$:" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "sigma = -(u - 1)/(u^2 + 1) (psiU^*e_1)" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sU = E.section(name='sigma', latex_name=r'\\sigma', domain=U)\n", "sU[eU,1] = (1-u)/(1+u^2)\n", "sU.display()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This local section lives in the free module $C^0(U;E)$:" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "True" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sU in C0U" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can perform a change of frame on the subset $W$:" ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "sigma = (v - 1)/(v^2 + 1) (psiV^*e_1)" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sU.display(eV.restrict(W), hv.restrict(W))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This expression is obviously well-defined on the whole subset $V$. Hence, we can continue this section onto $\\mathbb{RP}^1$:" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "sigma = (v - 1)/(v^2 + 1) (psiV^*e_1)" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s = E.section(name='sigma', latex_name=r'\\sigma')\n", "s.set_restriction(sU)\n", "s.add_comp_by_continuation(eV, W)\n", "s.display(eV)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The corresponding continuation is indeed an element of $C^{0}(\\mathbb{RP}^1;E)$:" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "True" ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s in C0" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let us define another global section in $E$:" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "tau = (3*u^3 - u)/(u^4 + 1) (psiU^*e_1)" ] }, "execution_count": 25, "metadata": {}, "output_type": "execute_result" } ], "source": [ "t = E.section(name='tau', latex_name=r'\\tau')\n", "t[eV,1] = (3-v^2)/(1+v^4)\n", "t.add_comp_by_continuation(eU, W)\n", "t.display(eU)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now, $\\sigma$ and $\\tau$ can be added pointwise:" ] }, { "cell_type": "code", "execution_count": 26, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "sigma+tau = (2*u^5 + u^4 + 2*u^3 - 2*u + 1)/(u^6 + u^4 + u^2 + 1) (psiU^*e_1)" ] }, "execution_count": 26, "metadata": {}, "output_type": "execute_result" } ], "source": [ "r = (s + t); r.display(eU)" ] }, { "cell_type": "code", "execution_count": 27, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "sigma+tau = (v^5 - 2*v^4 + 2*v^2 + v + 2)/(v^6 + v^4 + v^2 + 1) (psiV^*e_1)" ] }, "execution_count": 27, "metadata": {}, "output_type": "execute_result" } ], "source": [ "r.display(eV)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Since $\\sigma + \\tau$ is again a well-defined continuous section on $E$, it must vanish at some point. We want to check this by solving an equation:" ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "[{u: -1}]" ] }, "execution_count": 28, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sol = solve(r[eU,1,hu].expr() == 0, u, solution_dict=True)\n", "sol" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let us investigate what happens at this particular point $p\\in \\mathbb{RP}^1$ determined by $u=-1$:" ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Point p on the 1-dimensional topological manifold RP1\n" ] } ], "source": [ "p = M.point([sol[0][u]], name='p', chart=hu); print(p)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The corresponding section $\\sigma$ evaluated at $p$ is an element of the fiber $E_p$:" ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Vector sigma in the fiber of E at Point p on the 1-dimensional topological manifold RP1\n" ] } ], "source": [ "print(s.at(p))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Concretely we have:" ] }, { "cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "sigma = (psiU^*e_1)" ] }, "execution_count": 31, "metadata": {}, "output_type": "execute_result" } ], "source": [ "s.at(p).display(basis=eU.at(p))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For $\\tau$ we similarly obtain:" ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "tau = -(psiU^*e_1)" ] }, "execution_count": 32, "metadata": {}, "output_type": "execute_result" } ], "source": [ "t.at(p).display(basis=eU.at(p))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "As expected, the sum vanishes at $p$:" ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "sigma+tau = 0" ] }, "execution_count": 33, "metadata": {}, "output_type": "execute_result" } ], "source": [ "r.at(p).display(basis=eU.at(p))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Tensor Bundles over $\\mathbb{S}^2$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We define $U \\subset \\mathbb{S}^2$ to be the complement of the meridian lying in the upper $x$-$z$-plane for $x\\geq 0$. Similarly $V \\subset \\mathbb{S}^2$ defines the complement of the meridian going through the $x$-$y$-plane for $x \\leq 0$. In the language of `Sage` we write:" ] }, { "cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [], "source": [ "M = Manifold(2, name='S^2', latex_name=r'\\mathbb{S}^2')\n", "U = M.open_subset('U'); V = M.open_subset('V')\n", "M.declare_union(U,V) # M is the union of U and V" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The corresponding tangent bundle can be returned by the following command:" ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "Tangent bundle TS^2 over the 2-dimensional differentiable manifold S^2" ] }, "execution_count": 35, "metadata": {}, "output_type": "execute_result" } ], "source": [ "TM = M.tangent_bundle(); TM" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "However for now, we are interested in the parallelizable subset $U \\subset \\mathbb{S}^2$:" ] }, { "cell_type": "code", "execution_count": 36, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Tangent bundle TU over the Open subset U of the 2-dimensional differentiable manifold S^2\n" ] } ], "source": [ "TU = U.tangent_bundle(); print(TU)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Trivializations entirely fall back on the class `DiffChart` at this stage. To demonstrate how it is done, we introduce spherical coordinates on the subset $U$:" ] }, { "cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [], "source": [ "c_spher. = TU.trivialization(r'th:(0,pi):\\theta ph:(0,2*pi):\\phi')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To demonstrate the pullback of tensor bundles, we define the Euclidean space $\\mathbb{R}^3$ and introduce a differential map $\\varphi: \\mathbb{S}^2 \\to \\mathbb{R}^3$ given by the embedding of $\\mathbb{S}^2$ into $\\mathbb{R}^3$:" ] }, { "cell_type": "code", "execution_count": 38, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Differentiable map phi from the Open subset U of the 2-dimensional differentiable manifold S^2 to the 3-dimensional differentiable manifold R^3\n" ] } ], "source": [ "R = Manifold(3, 'R^3', r'\\mathbb{R}^3')\n", "c_cart. = R.chart() # Cartesian coord. on R^3\n", "phi = U.diff_map(R, (sin(th)*cos(ph), sin(th)*sin(ph), cos(th)),\n", " name='phi', latex_name=r'\\varphi'); print(phi)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let us fix the point $p$ in $U \\subset \\mathbb{S}^2$ determined by $(\\frac{\\pi}{2},\\pi)$ in spherical coordinates:" ] }, { "cell_type": "code", "execution_count": 39, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Point p on the 2-dimensional differentiable manifold S^2\n" ] } ], "source": [ "p = U.point((pi/2, pi), name='p'); print(p)\t" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can evaluate $\\varphi$ at this point $p$: " ] }, { "cell_type": "code", "execution_count": 40, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "(-1, 0, 0)" ] }, "execution_count": 40, "metadata": {}, "output_type": "execute_result" } ], "source": [ "phi(p).coord(c_cart)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We get the corresponding pullback tensor bundles by stating $\\varphi$ as the destination map:" ] }, { "cell_type": "code", "execution_count": 41, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "Tensor bundle phi^*T^(1,1)R^3 over the Open subset U of the 2-dimensional differentiable manifold S^2 along the Differentiable map phi from the Open subset U of the 2-dimensional differentiable manifold S^2 to the 3-dimensional differentiable manifold R^3" ] }, "execution_count": 41, "metadata": {}, "output_type": "execute_result" } ], "source": [ "phiT11U = U.tensor_bundle(1,1, dest_map=phi); phiT11U" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "More precisely:" ] }, { "cell_type": "code", "execution_count": 42, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Tensor bundle phi^*T^(1,1)R^3 over the Open subset U of the 2-dimensional differentiable manifold S^2 along the Differentiable map phi from the Open subset U of the 2-dimensional differentiable manifold S^2 to the 3-dimensional differentiable manifold R^3\n" ] } ], "source": [ "print(phiT11U)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We see that sections completely fall back on the preexisting implementation of tensor fields:" ] }, { "cell_type": "code", "execution_count": 43, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "True" ] }, "execution_count": 43, "metadata": {}, "output_type": "execute_result" } ], "source": [ "phiT11U.section_module() is U.tensor_field_module((1,1), dest_map=phi)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The fiber at $p$ is given by the space of $(1,1)$-tensors of the tangent space over $\\mathbb{R}^3$ at $\\varphi(p)$:" ] }, { "cell_type": "code", "execution_count": 44, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "Free module of type-(1,1) tensors on the Tangent space at Point phi(p) on the 3-dimensional differentiable manifold R^3" ] }, "execution_count": 44, "metadata": {}, "output_type": "execute_result" } ], "source": [ "phiT11U.fiber(p)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Since $\\mathbb{R}^3$ is parallelizable, the pullback tensor bundle $\\varphi^* T^{(1,1)}\\mathbb{R}^3\\to U$ must be trivial:" ] }, { "cell_type": "code", "execution_count": 45, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "True" ] }, "execution_count": 45, "metadata": {}, "output_type": "execute_result" } ], "source": [ "phiT11U.is_manifestly_trivial()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Hence it comes with a frame naturally induced by the pullback:" ] }, { "cell_type": "code", "execution_count": 46, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "[Vector frame (U, (d/dx,d/dy,d/dz)) with values on the 3-dimensional differentiable manifold R^3]" ] }, "execution_count": 46, "metadata": {}, "output_type": "execute_result" } ], "source": [ "phiT11U.frames()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Strictly speaking, this is a frame of $\\varphi^* T\\mathbb{R}^3$ rather than $\\varphi^* T^{(1,1)}\\mathbb{R}^3$. But remember that all frames in the tensor bundle can be retrieved from frames in the tangent bundle. Thus, there is no loss of generality here. We can extract our frame by applying index operations on the returned list:" ] }, { "cell_type": "code", "execution_count": 47, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Vector frame (U, (d/dx,d/dy,d/dz)) with values on the 3-dimensional differentiable manifold R^3\n" ] } ], "source": [ "print(phiT11U.frames()[0])" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "SageMath 9.1.beta6", "language": "sage", "name": "sagemath" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.3" } }, "nbformat": 4, "nbformat_minor": 2 }