#!/usr/bin/env python
# coding: utf-8
# # 15. Pulback of tensor fields
#
# This notebook is part of the [Introduction to manifolds in SageMath](https://sagemanifolds.obspm.fr/intro_to_manifolds.html) by Andrzej Chrzeszczyk (Jan Kochanowski University of Kielce, Poland).
# In[1]:
version()
# Recall from [notebook 7](https://nbviewer.org/github/sagemanifolds/IntroToManifolds/blob/main/07Manifold_FunPullb_Curves.ipynb), 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.$
# In[2]:
get_ipython().run_line_magic('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.=U.chart(r'r:(0,oo) phi:(0,2*pi):\phi')
N = Manifold(2, 'R^2c') # second copy of R^2
c_xy. = 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
#
#
# ### Pullback of covariant tensor fields
#
#
#
# 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
#
# $$d f_{ ψ( p)} (dψ_p v_p ) = dψ_p v_p ( f ) = v_p (ψ^∗ f ) = d(ψ^*f )_p (v_p ).$$
#
# 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):
# In[3]:
# 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):
# In[4]:
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)).
# $$
#
# In[5]:
get_ipython().run_line_magic('display', 'latex')
M = Manifold(2, r'R^2_{uv}') # manifold M
c_uv.=M.chart() # coordinates u,v
N = Manifold(2, r'R^2_{xy}') # manifold N
c_xy. = 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
# In[6]:
fplb.differential().disp() # d(psi^*f)
# In[7]:
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.
# In[8]:
get_ipython().run_line_magic('display', 'latex')
M = Manifold(2, r'R^2_{uv}') # manifold M
c_uv.=M.chart() # coordinates u,v
N = Manifold(2, r'R^2_{xy}') # manifold N
c_xy. = 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
# In[9]:
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.
# In[10]:
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.
# In[11]:
# 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
# In[12]:
Manifold.options.omit_function_arguments=True
tplb=psi.pullback(t) # pullback psi^*t
tplb.display_comp() # show pullback components
#
#
# ### Basic properties of pullback
#
#
# 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} ).
# $$
#
#
#
# ### Pullback of covariant tensor fields in components
#
#
#
# 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).$$
# In[13]:
get_ipython().run_line_magic('display', 'latex')
S2=manifolds.Sphere(2) # manifolds.Sphere module contains the def.
Phi=S2.embedding() # of the embedding S^2 -> E^3
sph.=S2.spherical_coordinates() # spherical coordinates
E=S2.ambient() # 3-dim Euclidean space
c_cart. = 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$
# In[14]:
g=E.metric() # g is predefined tensor field of type (0,2)
g.disp() # show g
# The pullback of g:
# In[15]:
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.$
# In[16]:
get_ipython().run_line_magic('display', 'latex')
S3=manifolds.Sphere(3) # manifolds.Sphere module contains the def.
Phi=S3.embedding() # of the embedding S^3 -> E^4
sph.=S3.spherical_coordinates() # and spherical coordinates
E=S3.ambient() # Euclidean space E^4
c_cart. = 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.$
# In[17]:
g=E.metric() # g is a predefined (0,2) type tensor field
g.disp() # show g
# Pullback of g:
# In[18]:
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).$
# In[19]:
get_ipython().run_line_magic('display', 'latex')
M = Manifold(3, 'R^3') # manifold M=R^3
c_xyz. = M.chart() # Cartesian coordinates
N = Manifold(2, 'N') # manifold N=S^2
c_sph.=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()
# In[20]:
plb=psi.pullback(omega2) # pullback psi^*omega2
plb.disp()
# In[21]:
plb=psi.pullback(omega3) # pullback psi^*omega3
plb.disp()
# More examples of pullbacks of k-forms can be found in the [next notebook](https://nbviewer.org/github/sagemanifolds/IntroToManifolds/blob/main/16Manifold_Ext_Der.ipynb).
# ## What's next?
#
# Take a look at the notebook [Exterior derivative](https://nbviewer.org/github/sagemanifolds/IntroToManifolds/blob/main/16Manifold_Ext_Der.ipynb).
|