This notebook is part of the Introduction to manifolds in SageMath by Andrzej Chrzeszczyk (Jan Kochanowski University of Kielce, Poland).
version()
Recall from notebook 7, that every smooth map between two smooth manifolds $\psi : M → N$ defines a pullback map $\psi^* : C^∞ (N ) → C^∞ (M )$ by
$$ \psi^∗ f = f ◦ \psi\quad \mbox{ for any } f ∈ C^∞ (N ).$$Example 15.1
If we denote by $\psi$ the coordinate change defined by $x=r\cos(\phi),\; y=r\sin(\phi)$ on the open set $U=\{(r,\phi): r>0, 0<\phi <2\pi \},$ then for a scalar function $f$ of variables $x,y,$ the pullback $\psi^*f$ is the function $(r,\phi)\to f(r\cos(\phi),r\sin(\phi))$, defined on $U$.
In the special case $f(x,y)=\sqrt{x^2+y^2}$, the pullback $\psi^*f$ is the function on $U$: $(r,\phi)\to r.$
%display latex
M = Manifold(2, 'R^2p') # manifold R^2
U = M.open_subset('U') # open subset of R2,
# polar coord. on U:
c_rphi.<r,phi>=U.chart(r'r:(0,oo) phi:(0,2*pi):\phi')
N = Manifold(2, 'R^2c') # second copy of R^2
c_xy.<x,y> = N.chart() # Cartesian coordinates:
# psi: M --> N : polar to Cart.:
psi = U.diff_map(N, (r*cos(phi), r*sin(phi)),name=r'\psi')
# f -scalar function on N
f=N.scalar_field(sqrt(x^2+y^2),name='f')
fplb=psi.pullback(f) # psi^*f -scalar func. on M
fplb.disp() # show pullback psi^*f
If $\psi: M\to N$ is a smooth map between smooth manifolds, one can extend the pullback operation to a map $\psi^∗ : T^{(0,k)}N → T^{(0,k)}M $ by
\begin{equation} (ψ^∗ t)_p (u_{1p} , . . . , u_{kp} ) = t_{ψ( p)} (dψ_p u_{1p} , . . . , dψ_p u_{kp} ), \label{}\tag{15.1} \end{equation}for $u_{1p} , . . . , u_{kp} ∈ T_p M,\ \ p ∈ M.$ From the linearity of $d\psi_p$ it follows the multilinearity of $(\psi^*t)_p$.
If $f ∈ C^∞ (N )$, then the differential $d f$ of $f$ is a tensor field of type $(0,1)$, consequently from (15.1) it follows
$$(ψ^∗ d f )_p (v_p ) = d f_{ψ( p)} (dψ_p v_p ),$$for $v_p ∈ T_p M.$
From the definitions of $df$ and $d\psi$ we have
We have checked that for a smooth map $\ \psi : M → N\ $ and $\ f\in C^∞ (N )$
\begin{equation} ψ^∗ d f = d(ψ^∗ f ). \label{}\tag{15.2} \end{equation}Example 15.2
Compute the pullback of differential of the scalar function from Example 15.1.
First we compute the left hand side of (15.2):
# continuation
df=f.differential() # differential of f
dfplb=psi.pullback(df) # pullback psi^*df
dfplb.disp(basis=c_rphi) # display in polar coordinates
Here is the right hand side of (15.2):
fplb.differential().disp() # d(psi^*f)
Example 15.3
Compute pullback of a scalar function and its differential for general mapping between two-dimensional manifolds $M$ and $N$
$$\psi: M \to N,\quad \psi(u,v)= (\psi_1(u,v),\psi_2(u,v)). $$%display latex
M = Manifold(2, r'R^2_{uv}') # manifold M
c_uv.<u,v>=M.chart() # coordinates u,v
N = Manifold(2, r'R^2_{xy}') # manifold N
c_xy.<x,y> = N.chart() # coordinates x,y
# first component of psi
psi1=M.scalar_field(function('psi1')(u,v),name=r'\psi1')
# second component of psi
psi2=M.scalar_field(function('psi2')(u,v),name=r'\psi2')
# define psi
psi = M.diff_map(N,(psi1.expr(),psi2.expr()) ,name=r'\psi')
# scalar function f
f=N.scalar_field(function('f')(x,y),name='f')
fplb=psi.pullback(f) # pullback psi^*f
fplb.disp() # show pullback psi^*f
fplb.differential().disp() # d(psi^*f)
df=f.differential() # df
dfplb=psi.pullback(df) # psi^*(df)
dfplb.disp() # show pullback of df
Example 15.4
Compute the pullback of 1-form $\ \ 𝛼=𝑎_0(𝑥,𝑦)d𝑥+𝑎_1(𝑥,𝑦)d𝑦\ $ under the map $\psi$ from the previous example.
%display latex
M = Manifold(2, r'R^2_{uv}') # manifold M
c_uv.<u,v>=M.chart() # coordinates u,v
N = Manifold(2, r'R^2_{xy}') # manifold N
c_xy.<x,y> = N.chart() # coordinates x,y
# first component of psi
psi1=M.scalar_field(function('psi1')(u,v),name=r'\psi1')
# second component of psi
psi2=M.scalar_field(function('psi2')(u,v),name=r'\psi2')
# define psi
psi = M.diff_map(N,(psi1.expr(),psi2.expr()) ,name=r'\psi')
# scalar function f
f=N.scalar_field(function('f')(x,y),name='f')
al=N.diff_form(1,name=r'\alpha') # 1-form al
astr=['a'+str(i) for i in range(2)] # list of comp. names
af=[N.scalar_field(function(astr[i])(x,y),name=astr[i])
for i in range(2)] # list of components
al[:]=af # define all components
al.disp() # show al
Manifold.options.omit_function_arguments=False
alplb=psi.pullback(al) # pullback psi^*al
alplb.disp() # show pullback of al
Shorter result can be obtained omitting functions arguments.
Manifold.options.omit_function_arguments=True
alplb.disp()
Example 15.5
Compute the pullback of a tensor field of (0,2)-type
$f_{00}(𝑥,𝑦)d𝑥⊗d𝑥+𝑓_{01}(𝑥,𝑦)d𝑥⊗d𝑦+𝑓_{10}(𝑥,𝑦)d𝑦⊗d𝑥+𝑓_{11}(𝑥,𝑦)d𝑦⊗d𝑦\ \ $
on a two dimensional manifold under $\psi$ from Example 15.3.
# continuation
t = N.tensor_field(0,2, name='t') # tensor field t of type (0,2)
# list of component names:
def fn(i,j): return 'f'+str(i)+str(j)
# list of component functions:
f=[[N.scalar_field(function(fn(j,k))(x,y),name=fn(j,k))
for k in range(2)] for j in range(2)]
t[:]=f # define all components of t
t.disp() # show t
Manifold.options.omit_function_arguments=True
tplb=psi.pullback(t) # pullback psi^*t
tplb.display_comp() # show pullback components
For a smooth map $\psi: M \to N,\ $ tensor fields $t$ and $s$ on $N$ of type $( 0,k)$ and constants $a,b\in R\ $ we have
$$ (ψ^*(at + bs))_p (u_{1p} , . . . , u_{kp} ) = (at + bs)_{ψ( p)} (dψ_p u_{1p} , . . . , dψ_p u_{kp} )\\ = (at_{ψ( p)} + bs_{ψ( p)} )(dψ_p u_{1p} , . . . , dψ_p u_{kp} )\\ = at_{ψ( p)} (dψ_p u_{1p} , . . . , dψ_p u_{kp} ) + bs_{ψ( p)} (dψ_p u_{1p} , . . . , dψ_p u_{kp} )\\ = a(ψ^∗ t)_p (u_{1p} , . . . , u_{kp} ) + b(ψ^∗ s)_p (u_{1p} , . . . , u_{kp} )\\ = (aψ^∗ t + bψ^∗ s)_p (u_p , . . . , w_p ),$$for $u_{1p} , . . . , u_{kp} ∈ T_p M$. Therefore we have the following linearity result.
Let $ψ : M → N$ be a smooth map. If $t$ and $s$ are tensor fields of type $( 0,k)$ on $N$ and $a, b ∈ R$, then
\begin{equation} ψ^∗ (at + bs) = aψ^∗ t + bψ^∗ s. \label{}\tag{15.3} \end{equation}For $\psi\ $ as before, $f\in C^\infty(N)\ $ and $t\in T^{(0.k)}N$, we have
$$ (ψ^∗ ( f t)_p (u_{1p} , . . . , u_{kp} ) = ( f t)_{ψ( p)} (dψ_p u_{1p} , . . . , dψ_p u_{kp} )\\ = f( ψ( p)) t_{ψ( p)} (dψ_p u_{1p} , . . . , dψ_p u_{kp} ) = (ψ^∗ f )( p) (ψ^∗ t)_p (u_{1p} , . . . , u_{kp} ) =((ψ^∗ f )(ψ^∗ t))_p (u_{1p} , . . . , u_{kp} ). $$Thus
\begin{equation}
ψ^∗ ( f t) = (ψ^∗ f )(ψ^∗ t).
\label{}\tag{15.4}
\end{equation}
If $\psi:M\to N\ $ is smooth, $t$ and $s$ are tensor fields on $N$ of types $(0,k)$ and $(0,l)$ respectively, we have
$$ ψ^*(t ⊗ s)_p(u_{1p},...,u_{(k+l)p}) = (t ⊗ s)_{ψ( p)} (dψ_p u_{1p} , . . . , dψ_p u_{(k+l)p} )\\ = t_{ψ( p)} (dψ_p u_{1p} , . . .,dψ_p u_{kp}) s_{ψ( p)} (dψ_p u_{(k+1)p},. . . , dψ_p u_{(k+l)p} )\\ = (ψ^∗ t)_p (u_{1p} , . . .,u_{kp})(ψ^∗ s)_p (u_{(k+1)p},. . . , u_{(k+l)p} ) = ((ψ^∗ t) ⊗ (ψ^∗ s))_p (u_{1p} , . . . , u_{(k+l)p} ), $$so
\begin{equation} ψ^∗ (t ⊗ s) = (ψ^∗ t) ⊗ (ψ^∗ s). \label{}\tag{15.5} \end{equation}If $M_1, M_2, M_3$ are smooth manifolds, $ψ_1 : M_1 → M_2$ and $ψ_2 : M_2 → M_3$ are smooth maps, then
$$ (ψ_2 ◦ ψ_1 )^∗ t = (ψ_1^∗ ◦ ψ_2^∗ )\;t,\quad \mbox{for } t ∈ T^{(0,k)} M_3.$$To prove this relation let us note that $$((ψ_2 ◦ ψ_1 )^∗ t)_p (u_{1p} , . . . , u_{kp} )\\ = t_{(ψ_2 ◦ψ_1 )( p)} (d(ψ_2 ◦ ψ_1 )_p u_{1p} , . . . , d(ψ_2 ◦ ψ_1 )_p u_{kp})\\ = t_{ψ_2(ψ_1(p))} (dψ_{2ψ_1( p)} (dψ_{1p} u_{1p} ), . . . , dψ_{2ψ_1( p)} (dψ_{1p} u_{kp} ))\\ = (ψ_2^∗ t)_{ψ 1 ( p)} (dψ_{1 p} u_{1p} , . . . , dψ_{1p} u_{kp} ) = (ψ_1^∗ (ψ_2^∗ t))_p (u_{1p} , . . . , u_{kp} ). $$
If $t$ is a tensor field of type $(0,k)$ on $N$, given locally by $t = t_{i_1... i_k} dy^{i_1} ⊗ · · · ⊗dy^{i_k}$, then the pullback of $t$ under $ψ$ is given by
$$ψ^∗ t = ψ^∗ (t_{i_1... i_k} dy^{i_1} ⊗ · · · ⊗ dy^{i_k} )\\ = (ψ^∗ t_{i_1... i_k} )(ψ^∗ dy^{i_1} ) ⊗ · · · ⊗ (ψ^∗ dy^{i_k} )\\ = (ψ^∗ t_{i_1... i_k} ) d(ψ^∗ y^{i_1} ) ⊗ · · · ⊗ d(ψ^∗ y^{i_k} ).$$Since $d(ψ^∗ y^i ) = (∂(ψ^∗ y^i )/∂ x^m) dx^m$, where $(x^1 , . . . , x^n )$ are coordinates on $M$, we have
\begin{equation} ψ^∗ t = (ψ^∗ t_{i_1... i_k} )\frac{\partial(\psi^*y^{i_1})}{ \partial x^{m_1}}\ldots \frac{\partial(\psi^*y^{i_k})}{\partial x^{m_k}}dx^{m_1}⊗ · · · ⊗ dx^{m_k}. \tag{15.6} \end{equation}The same formula can be written:
$$ψ^∗ (t_{i_1... i_k} dy^{i_1} ⊗ · · · ⊗dy^{i_k} )= (t_{i_1... i_k}\circ\psi )\frac{\partial(y^{i_1}\circ\psi)}{
\partial x^{m_1}}\ldots
\frac{\partial(y^{i_k}\circ\psi)}{\partial x^{m_k}}dx^{m_1}⊗ · · · ⊗ dx^{m_k}.$$
So to obtain $\psi^*t$, just replace in $t=t_{i_1... i_k} dy^{i_1} ⊗ · · · ⊗dy^{i_k}$
$t_{i_1... i_k}\to t_{i_1... i_k}\circ \psi\quad$
and $dy^i\to \frac{\partial(y^{i}\circ\psi)}{\partial x^{m}}dx^{m}.$
Example 15.6
Consider the covariant tensor field $ \ g=dx\otimes dx+ dy\otimes dy+ dz\otimes dz$ in $R^3$ and its pullback under the embedding $\psi: S^2\to R^3$ defined by
$$ \psi(\theta,\phi)=(\sin \theta \cos \phi, \sin \theta\sin \phi,\cos\theta).$$%display latex
S2=manifolds.Sphere(2) # manifolds.Sphere module contains the def.
Phi=S2.embedding() # of the embedding S^2 -> E^3
sph.<th,ph>=S2.spherical_coordinates() # spherical coordinates
E=S2.ambient() # 3-dim Euclidean space
c_cart.<x,y,z> = E.cartesian_coordinates() # Cartesian coord. in E^3
Phi.disp() # show Phi
metric
is a predefined covariant tensor field of type (0,2) in $E^3$
g=E.metric() # g is predefined tensor field of type (0,2)
g.disp() # show g
The pullback of g:
Phi.pullback(g).disp() # pullback of g
Example 15.7
We can repeat the previous example in higher dimensions. For example we can compute the pullback of $ \ g=dx_1\otimes dx_1+ dx_2\otimes dx_2+ dx_3\otimes dx_3+dx_4\otimes dx_4$ under the embedding $S^3\to E^4.$
%display latex
S3=manifolds.Sphere(3) # manifolds.Sphere module contains the def.
Phi=S3.embedding() # of the embedding S^3 -> E^4
sph.<chi,theta,phi>=S3.spherical_coordinates() # and spherical coordinates
E=S3.ambient() # Euclidean space E^4
c_cart.<x1,x2,x3,x4> = E.cartesian_coordinates() # Cartesian coord. in E^4
fun=Phi.coord_functions()[:];fun # functions defining the emb. S^3 -> E^4
metric
is a predefined covariant tensor field of type (0,2) in $E^4.$
g=E.metric() # g is a predefined (0,2) type tensor field
g.disp() # show g
Pullback of g:
Phi.pullback(g).disp() # pullback Psi^*g
Since the differential k-forms are special cases of covariant tensor fields, the pullback operation can be applied to such forms.
Example 15.8
Consider the same embedding $\psi: S^2\to R^3$ as in Example 15.6, defined by $$ \psi(\theta,\phi)=(\sin \theta \cos \phi, \sin \theta\sin \phi,\cos\theta),$$ and compute the pullbacks $\psi^*(dx\wedge dy),\ \psi^*(dy\wedge dz),\ \psi^*(dx\wedge dz).$
%display latex
M = Manifold(3, 'R^3') # manifold M=R^3
c_xyz.<x,y,z> = M.chart() # Cartesian coordinates
N = Manifold(2, 'N') # manifold N=S^2
c_sph.<theta,phi>=N.chart() # spherical coordinates
# embedding S^2->R^3
psi = N.diff_map(M, (sin(theta)*cos(phi), sin(theta)*sin(phi),cos(theta)),
name='psi',latex_name=r'\psi')
E=c_xyz.coframe() # coframe (dx,dy,dz)
dx,dy,dz=E[:] # define dx,dy,dz
omega1=dx.wedge(dy) # wedge prod. dx/\dy
omega2=dy.wedge(dz) # wedge prod. dy/\dz
omega3=dx.wedge(dz) # wedge prod. dx/\dz
plb=psi.pullback(omega1) # pullback psi^*omega1
plb.disp()
plb=psi.pullback(omega2) # pullback psi^*omega2
plb.disp()
plb=psi.pullback(omega3) # pullback psi^*omega3
plb.disp()
More examples of pullbacks of k-forms can be found in the next notebook.
Take a look at the notebook Exterior derivative.