This notebook is part of the Introduction to manifolds in SageMath by Andrzej Chrzeszczyk (Jan Kochanowski University of Kielce, Poland).
version()
'SageMath version 9.6, Release Date: 2022-05-15'
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.