{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# 14. Differential $k$-forms\n",
"\n",
"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)."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'SageMath version 9.6, Release Date: 2022-05-15'"
]
},
"execution_count": 1,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"version()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Warning:** in this notebook there are many repetitions with respect to [notebook 10](https://nbviewer.org/github/sagemanifolds/IntroToManifolds/blob/main/10Manifold_AlternatingForms_onModules.ipynb).\n",
"Although mathematically alternating forms on modules from [notebook 10](https://nbviewer.org/github/sagemanifolds/IntroToManifolds/blob/main/10Manifold_AlternatingForms_onModules.ipynb) are generalizations of differential forms, the SageMath code in the present notebook differs significantly from that in [notebook 10](https://nbviewer.org/github/sagemanifolds/IntroToManifolds/blob/main/10Manifold_AlternatingForms_onModules.ipynb)."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Let $M$ be a smooth manifold. \n",
"\n",
"A **differential $k$-form or simply $k$-form on a manifold $M$**\n",
"is a smooth map $ω$ that, to each point\n",
"$p ∈ M$, assigns $k$-linear antisymmetric form $ω(p)=ω_p$ on the tangent space $T_pM$.\n",
"\n",
"**Reminder**. $k$-linear antisymmetric forms on arbitrary modules were presented in [notebook 10](https://nbviewer.org/github/sagemanifolds/IntroToManifolds/blob/main/10Manifold_AlternatingForms_onModules.ipynb), and smoothness of covariant tensor fields in [notebook 13](https://nbviewer.org/github/sagemanifolds/IntroToManifolds/blob/main/13Manifold_TensorFields.ipynb).\n",
"\n",
"
\n",
"\n",
"One can use an equivalent definition:\n",
"\n",
"A differential form of degree $k$,\n",
"or differential $k$-form, $ω$ on a manifold $M$ is \n",
"a smooth tensor field of type\n",
"$(0,k)$ on $M$, with the antisymmetry property:\n",
"\n",
"\\begin{equation}\n",
"ω(X_1 , . . . , X_i , . . . , X_j , . . . , X_k ) = \n",
"−ω(X_1, . . . , X_j , . . . , X_i , . . . , X_k ),\n",
"\\label{}\\tag{14.1}\n",
"\\end{equation}\n",
"\n",
"for\n",
"$1\\leq i < j \\leq k$, $ X_1 , . . . , X_k ∈ \\mathfrak{X}(M)$.
\n",
"\n",
"Note that from (14.1) it follows that if $X_i=X_j$ then $ω(X_1 , . . . , X_i , . . . , X_j , . . . , X_k ) = 0$.\n",
"
\n",
"The relation (14.1) can be reformulated as\n",
"\n",
"$$\n",
"\\omega(X_{\\sigma(1)},\\ldots,X_{\\sigma(k)})=\\mathrm{sign}(\\sigma)\n",
"\\omega(X_1,\\ldots,X_k),$$ \n",
"\n",
"for $\\sigma\\in S_k$ (permutations and their signs were defined in [notebook 10](https://nbviewer.org/github/sagemanifolds/IntroToManifolds/blob/main/10Manifold_AlternatingForms_onModules.ipynb)).\n",
"\n",
"A 0-form is a smooth real-valued\n",
"function on $M$.
\n",
"The set of the k-forms on a manifold $M$, is **denoted** by $\\Omega^k(M)$. It is a submodule of the module of covariant tensor fields\n",
" $T^{(0,k)} M$ on the manifold $M$.\n",
"\n",
"
\n",
"\n",
"**Example 14.1**\n",
"\n",
"Let us define a differential 2-form on a 3-dimensional manifold."
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"2-form a on the 3-dimensional differentiable manifold M\n"
]
}
],
"source": [
"M = Manifold(3, 'M') # manifold M\n",
"X. = M.chart()\n",
"a = M.diff_form(2, name='a') ; # define 2-form\n",
"print(a) # show information on a"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"# parent?"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\\(\\displaystyle \\Omega^{2}\\left(M\\right)\\)"
],
"text/latex": [
"$\\displaystyle \\Omega^{2}\\left(M\\right)$"
],
"text/plain": [
"Free module Omega^2(M) of 2-forms on the 3-dimensional differentiable manifold M"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# mathematical object of which \"a\" is an element\n",
"show(a.parent())"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The obtained module can be defined independently:"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\\(\\displaystyle \\Omega^{2}\\left(M\\right)\\)"
],
"text/latex": [
"$\\displaystyle \\Omega^{2}\\left(M\\right)$"
],
"text/plain": [
"Free module Omega^2(M) of 2-forms on the 3-dimensional differentiable manifold M"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"Om2 = M.diff_form_module(2) # define module of 2-forms\n",
"show(Om2)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"
\n",
"\n",
"### Antisymmetrization operation Alt\n",
"\n",
"
\n",
"\n",
"If $t$ is a covariant tensor field from $T^{(0,k)}M$, then we can define a differential $k$-form called Alt($t$) in the following way\n",
"\n",
"\\begin{equation}\n",
"\\mathrm{Alt}(t)(X_1,\\ldots,X_k)=\\frac{1}{k!}\\sum_{\\sigma\\in S_k}\\mathrm{sign}(\\sigma)\\;t(X_{\\sigma(1)},\\ldots,X_{\\sigma(k)}),\n",
"\\label{}\\tag{14.2}\n",
"\\end{equation}\n",
"for $X_i\\in\\mathfrak{X}(M)$.\n",
"\n",
"
\n",
"\n",
"Alt is a linear map on the module $T^{(0,k)}M$ (over $C^\\infty(M)$) into $\\Omega^k(M)$.\n",
"\n",
"To prove that for $t\\in T^{(0,k)}M$ we have $\\text{Alt}(t)\\in \\Omega^k(M)$ note that for arbitrary permutation $\\tau\\in S_k$\n",
"\n",
"$$\\text{Alt}(t)(v_{\\tau(1)},\\ldots,v_{\\tau(k)})\n",
"=\\frac{1}{k!}\\sum_{\\sigma\\in S_k}\\text{sign}\\sigma\\, \n",
"t(v_{\\sigma(\\tau(1))},\\ldots,v_{\\sigma(\\tau(k))})\\\\\n",
"=\\frac{1}{k!}\\sum_{\\sigma\\in S_k}\\text{sign}\\sigma\\, \\text{sign}\\sigma\\,t(v_{\\tau(1)},\\ldots,v_{\\tau(k)})=\\text{sign}\\tau\\,t(v_{1},\\ldots,v_{k}).\n",
"$$\n",
"\n",
"\n",
"We can check also that if $t\\in \\Omega^k(M)$, then Alt($t$)=$t$.
\n",
"In fact, assume that $t(v_{\\sigma(1)},\\ldots,v_{\\sigma(k)})=\\text{sign}\\sigma\\, t(v_1,\\ldots,v_k)$.\n",
"Then \n",
"$$\\text{Alt}(t)(v_1,\\ldots,v_k)=\n",
"\\frac{1}{k!}\\sum_{\\sigma\\in S_k}(\\text{sign} \\sigma)t(v_{\\sigma(1)},\\ldots,v_{\\sigma(k)})\\\\\n",
"=\\frac{1}{k!}\\sum_{\\sigma\\in S_k}(\\text{sign} \\sigma)(\\text{sign} \\sigma)\\,\n",
"t(v_{1},\\ldots,v_{k})=t(v_{1},\\ldots,v_{k}).\n",
"$$\n",
"\n",
"The last two observations lead to the relation \n",
"$$\\text{Alt}(\\text{Alt}(t))=\\text{Alt}(t),\n",
"\\quad \\text{or equivalently}\\quad \\text{Alt}^2=\\text{Alt}.$$\n",
"\n",
"\n",
"### Wedge product\n",
"\n",
"
\n",
"\n",
"If $ω$ is a $k$-differential form and $η$ is an $l$-differential form on $M$, the **exterior, or wedge**,\n",
"product $ω ∧ η\\in\\Omega^{(k+l)}(M)$, is defined by\n",
"\\begin{equation}\n",
"\\omega\\wedge\\eta=\\frac{(k+l)!}{k!l!}\\mathrm{Alt}(\\omega\\otimes\\eta).\n",
"\\label{}\\tag{14.3}\n",
"\\end{equation}\n",
"\n",
"**Remark.** Some authors use different coefficients in this formula. Our version is in accordance with that in SageMath Manifolds. "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"
\n",
"\n",
"**Example 14.2**\n",
"\n",
"If $α$ and $β$ are 1-forms, applying (14.3), (14.2) and using the fact that there are only two permutations of two elements with opposite signs we have\n",
"$$(α ∧ β)(X_1 , X_2 ) = \\frac{(1+1)!}{1!1!}\\mathrm{Alt} (α ⊗ β)(X_1 , X_2 )\\\\\n",
"= \\frac{2!}{1!1!}\\frac{1}{2!} [ (α ⊗ β)(X_1 , X_2 ) − (α ⊗ β)(X_2 , X_1 )]\\\\\n",
"= α(X_1 )β(X_2 ) − α(X_2 )β(X_1 )\n",
"= (α ⊗ β − β ⊗ α)(X_1 , X_2 ),$$\n",
"\n",
" for $X_1 , X_2 ∈ \\mathfrak{X}(M).$\n",
" Consequently\n",
" $$α ∧ β = (α ⊗ β − β ⊗ α) = −β ∧ α,\\quad\n",
"\\mbox{for }\\quad α, β ∈ \\Omega^1 (M).$$"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"
\n",
"\n",
"### Basic algebraic properties of wedge product\n",
"\n",
"
\n",
"\n",
"From the multilinearity of the tensor product and linearity of antisymmetrization it follows.\n",
"\n",
"For $\\alpha,\\alpha_1,\\alpha_2\\in \\Omega^k(M),\\beta,\\beta_1,\\beta_2\\in \\Omega^m(M)$ and $a\\in C^\\infty(M)$\n",
"\n",
"\\begin{equation}\n",
"\\begin{matrix}\n",
"(\\alpha_1+\\alpha_2)\\wedge\\beta=\\alpha_1\\wedge\\beta+\\alpha_2\\wedge\\beta,\\\\\n",
"\\alpha\\wedge(\\beta_1+\\beta_2)=\\alpha\\wedge\\beta_1+\\alpha\\wedge\\beta_2,\\\\\n",
"(a\\alpha)\\wedge\\beta=a(\\alpha\\wedge\\beta)=\\alpha\\wedge(a\\beta).\n",
"\\end{matrix}\n",
"\\tag{14.4}\n",
"\\end{equation}\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"
\n",
"\n",
"### Associativity of the wedge product\n",
"\n",
"
\n",
"\n",
"To check the associativity of the wedge product we need some properties of the antisymmetrization operation.\n",
"\n",
"First observe that if $t\\in T^{(0,k)}M$ and $s\\in T^{(0,m)}M$, then\n",
"\n",
"\\begin{equation}\n",
"\\text{Alt}(t)=0\\quad \\Longrightarrow\\quad\n",
"\\text{Alt}(t\\otimes s)=\\text{Alt}(s\\otimes t)=0.\n",
"\\tag{Alt1}\n",
"\\end{equation}\n",
"\n",
"To prove this, let us note that\n",
"\n",
"$$(k + m)!\\, \\text{Alt}(t ⊗ s)(v_1 , . . . , v_{k+m} ) =\n",
"\\sum_{\\sigma\\in S_{k+m}}\n",
"(\\text{sign}\\, σ) t (v_{σ(1)} , . . . , v_{σ(k)} )s(v_{σ(k+1)} , . . . , v_{σ(k+m)} ).\n",
"$$"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"First define the subgroup of $S_{k+m}$, \n",
"\n",
"$$G=\\{\\sigma\\in S_{k+m}:\n",
"(\\sigma(k+1),\\ldots,\\sigma(k+m))=(k+1,\\ldots,k+m)\\},$$\n",
"\n",
"and compute the sum from the right hand side of the previous equality restricted to this subgroup.\n",
"\n",
"$$\\sum_{\\sigma\\in G}(\\text{sign}\\, σ)\\,t (v_{σ(1)} , . . . , v_{σ(k)} )s(v_{σ(k+1)} , . . . , v_{σ(k+m)} )\\\\\n",
"=\\Big[\\sum_{\\sigma\\in G}(\\text{sign}\\, σ)\\,t (v_{σ(1)} , . . . , v_{σ(k)} )\\Big]\n",
"s(v_{k+1} , . . . , v_{k+m} )\\\\=\n",
"k!(\\text{Alt}(t))(v_{1} , . . . , v_{k} )\n",
"s(v_{k+1} , . . . , v_{k+m} )=\n",
"k!(\\text{Alt}(t)\\otimes s)(v_1,\\ldots,v_{k+m}),\n",
"$$\n",
"\n",
"so the entire sum vanishes if the sum in brackets vanishes, i.e. Alt($t$) vanishes.\n",
"\n",
"Now for fixed $\\tilde\\sigma\\in S_{k+m}$ let us sum over the coset $G\\tilde\\sigma=\\{\\sigma\\tilde\\sigma: \\sigma \\in G$\\}."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"$$\\sum_{\\sigma'\\in G\\tilde\\sigma}(\\text{sign}\\, σ')(t ⊗ s)(v_{σ'(1)} , . . . , v_{σ'(k+m)} )\\\\\n",
"=\\sum_{\\sigma\\in G}(\\text{sign}\\, σ\\tilde\\sigma)(t ⊗ s)(v_{\\sigma(\\tilde\\sigma(1))} , . . . , v_{\\sigma(\\tilde \\sigma(k+m))} )\\\\\n",
"=\\text{sign}\\tilde\\sigma\n",
"\\Big[\\sum_{\\sigma\\in G}\\text{sign}\\sigma \\,\n",
"t(v_{\\sigma(\\tilde\\sigma(1))} , . . . , v_{\\sigma(\\tilde \\sigma(k))} )\\Big]\n",
"s(v_{\\sigma(\\tilde\\sigma(k+1))} , . . . , v_{\\sigma(\\tilde \\sigma(k+m))} )\\\\\n",
"=\\text{sign}\\tilde\\sigma\\, k!\\,(\\text{Alt}(t))\n",
"(v_{\\tilde\\sigma(1)} , . . . , v_{\\tilde \\sigma(k)} )\n",
"s(v_{\\tilde\\sigma(k+1)} , . . . , v_{\\tilde \\sigma(k+m)} )\\\\\n",
"\\text{sign}\\tilde\\sigma\\, k!\\,\\big[\\text{Alt}(t)\\otimes s\\big]\n",
"(v_{\\tilde\\sigma(1)} , . . . , v_{\\tilde \\sigma(k+m)} )\n",
".$$\n",
"\n",
"Thus if $\\text{Alt}(t)$ vanishes then the sums over all cosets $G\\tilde\\sigma$ vanish. Since the group\n",
" $S_{k+m}$ is a sum of cosets $G\\tilde\\sigma$, the implication (Alt1) holds true. \n",
" "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
" The second ingredient of our associativity proof is the following\n",
" \n",
" \\begin{equation}\n",
" \\text{Alt}(\\text{Alt}(t ⊗ s) ⊗ r) = \\text{Alt}(t ⊗ s ⊗ r) = \\text{Alt}(t ⊗ \\text{Alt}(s ⊗ r)).\n",
" \\tag{Alt2}\n",
" \\end{equation}\n",
"
\n",
" \n",
" In fact, the linearity of Alt and the relation $ \\text{Alt}^2=\\text{Alt}$ implies \n",
" \n",
" $$\\text{Alt}(\\text{Alt}(s ⊗ r) − s ⊗ r)=\\text{Alt}(\\text{Alt}(s ⊗ r))-\\text{Alt}(s\\otimes r)=0.\n",
" $$\n",
" \n",
" Applying the implication (Alt1) to $\\ \\text{Alt}(s ⊗ r) − s ⊗ r\\ $\n",
" we obtain\n",
" \n",
" $$\\text{Alt}(t\\otimes\\text{Alt}(s\\otimes r))-\\text{Alt}(t\\otimes s\\otimes r)=\n",
" \\text{Alt}(t\\otimes[\\text{Alt}(s\\otimes r)-s\\otimes r]).\n",
" $$\n",
" \n",
" Since we have \n",
" checked that the value of Alt on the expression in brackets vanishes, then the implication (Alt1) gives us\n",
" \n",
" $$\\text{Alt}(t\\otimes\\text{Alt}(s\\otimes r)-\\text{Alt}(t\\otimes s\\otimes r))\n",
" =\\text{Alt}(t\\otimes[\\text{Alt}(s\\otimes r)-s\\otimes r])=0,\n",
" $$\n",
" \n",
" i.e., the second equality from (Alt2) holds true\n",
" \n",
" $$\\text{Alt}(t ⊗ \\text{Alt}(s ⊗ r)) = \\text{Alt}(t ⊗ s ⊗ r).$$\n",
" \n",
" The first equality in (Alt2) can be proved analogously.\n",
" "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"From (Alt2) it follows for $\\alpha\\in\\Omega^k(M),\\ \n",
"\\beta\\in \\Omega^l(M), \\ \\gamma\\in \\Omega^m(M)$\n",
"\n",
"$$(\\alpha\\wedge \\beta)\\wedge \\gamma=\n",
"\\frac{(k+m+l)!}{(k+m)!l!}\\text{Alt}((\\alpha\\wedge\\beta)\\otimes\\gamma)\\\\\n",
"=\\frac{(k+m+l)!}{(k+m)!l!}\\text{Alt}(\\frac{(k+m)!}{k!m!}(\\text{Alt}(\\alpha\\otimes\\beta)\\otimes\\gamma)\\\\=\n",
"\\frac{(k+m+l)!}{k!m!l!}\\text{Alt}(\\alpha\\otimes\\beta\\otimes\\gamma). \n",
"$$\n",
"\n",
"Analogously for $α ∧ (β ∧ γ )$. We have proved **associativity of the wedge product:**"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"$$(α ∧ β) ∧ γ=α ∧ (β ∧ γ ) = \\frac{(k+l+m)!}{k!l!m!} \\mathrm{Alt} (α ⊗ β ⊗ γ ),$$ \n",
"\n",
"for $\\alpha\\in\\Omega^k(M),\\ \n",
"\\beta\\in \\Omega^l(M), \\ \\gamma\\in \\Omega^m(M)$,\n",
"and more generally\n",
"\n",
"\\begin{equation}\n",
"α_1 ∧ \\ldots ∧ \\alpha_r = \\frac{(k_1+\\ldots k_r)!}{k_1!\\dots k_r!}\\mathrm{Alt}(α_1\\otimes \\ldots\\otimes \\alpha_r ),\n",
"\\label{}\\tag{14.6}\n",
"\\end{equation}\n",
"\n",
"for $\\alpha_i\\in\\Omega^{k_i}(M).$\n",
"\n",
"For example if $x^1,\\ldots,x^n$ are local coordinates on $M$, then since $dx^i$ are 1-forms, then $dx^{i_1}\\wedge\\ldots\\wedge dx^{i_k}$ are $k$-forms on $M$."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"
\n",
"\n",
"### Differential forms in local coordinates\n",
"\n",
"
\n",
"\n",
"Let $(x^1 , . . . , x^n )$ be a local coordinate system on $M$. According to (13.7) a $k$-differential form possesses the local representation\n",
"\n",
"\\begin{equation}\n",
"ω = ω_{i_1 ...i_k} dx^{i_1} ⊗ · · · ⊗ dx^{i_k},\n",
"\\label{}\\tag{14.7}\n",
"\\end{equation}\n",
"\n",
"where\n",
"\n",
"\\begin{equation}\n",
"ω_{i_1 ...i_k} = ω\\Big(\\frac{\\partial}{\\partial x^{i_1}},\\ldots,\\frac{\\partial}{\\partial x^{i_k}}\\Big).\n",
"\\label{}\\tag{14.8}\n",
"\\end{equation}\n",
"\n",
"Since $\\omega$ is antisymmetric, $ω_{i_1 ...i_k}$ is also antisymmetric.
\n",
"Since Alt is linear and Alt($\\omega$)=$\\omega\\ $ we have\n",
"\n",
"$$\n",
"\\begin{matrix}\n",
"\\omega=\\mathrm{Alt}(\\omega)=\\sum_{i_1,\\ldots,i_k=1}^n ω_{i_1 ...i_k}\\mathrm{Alt}(dx^{i_1}\\otimes\\ldots\\otimes dx^{i_k}).\\\\\n",
"\\end{matrix}\n",
"$$\n",
"\n",
"From (14.6) it follows that (note that $dx^{i_j}$ are 1-forms) $$\\mathrm{Alt}(dx^{i_1}\\otimes\\ldots\\otimes dx^{i_k})=\\frac{1}{k!}dx^{i_1}\\wedge\\ldots\\wedge dx^{i_k}.$$\n",
"Thus we have\n",
"\\begin{equation}\n",
"\\begin{matrix}\n",
"\\omega=\\frac{1}{k!}\\sum_{i_1,\\ldots,i_k=1}^n ω_{i_1 ...i_k}dx^{i_1}\\wedge\\ldots\\wedge dx^{i_k}\\\\\n",
"=\\sum_{1\\leq i_1<\\ldots\n",
"\n",
"\n",
"Elements of the set \n",
"\n",
"$$\\{dx^{i_1}\\wedge\\dots\\wedge dx^{i_k}: 1\\leq i_1<\\ldots\n",
"\n",
"### Anticommutativity\n",
"\n",
"
\n",
"\n",
"If $\\omega ∈ \\Omega^k(M)$ and $\\eta ∈ \\Omega^l(M)$, then\n",
"\n",
"$$\n",
"\\omega ∧ \\eta = (−1)^{kl} \\eta ∧ \\omega.\n",
"$$\n",
"\n",
"This is consequence of (we use the unordered version of (14.9))\n",
"\n",
"$$\n",
"(k+l)!ω ∧ η = ω_{i_1 ...i_k} η_{ j_1 ... j_l} dx^{i_1} ∧ · · · ∧ dx^{i_k} ∧ dx^{j_1} ∧ · · · ∧ dx^{j_l}\\\\\n",
"= (−1)^{kl} ω_{i_1 ...i_k} η_{j_1 ... j_l} dx^{j_1} ∧ · · · ∧ dx^{j_l} ∧ dx^{i_1} ∧ · · · ∧ dx^{i_k}\n",
"= (k+l)!(−1)^{kl} η ∧ ω.\n",
"$$"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"
\n",
"\n",
"### Abbreviated notations for $k$-forms\n",
"\n",
"
\n",
"\n",
"For arbitrary differential forms in $\\Omega^k(M)$\n",
"sometimes we would not want to actually write out all of the elements\n",
"of the local frames of $\\Omega^k(M)$, so\n",
"instead we write\n",
"\\begin{equation}\n",
" α =\\sum_I a_I dx^I .\n",
"\\label{}\\tag{14.10}\n",
"\\end{equation}\n",
"Here the $I$ stands for the sequence of $k$ increasing indices $i_1 i_2 \\ldots i_k$: $1 ≤ i_1 < i_2 < \\ldots < i_k ≤ n$. That is, we sum over\n",
"$I ∈ J_{k,n} = \\{(i_1 i_2 \\ldots i_k ) : 1 ≤ i_1 < i_2 < \\ldots < i_k ≤ n\\}.$
\n",
"\n",
"For example, for $k = 3$ and $n = 4$ we have $I\\in\\{123,124,134,234\\}.$
\n",
"\n",
"If $I$ and $J$ are disjoint, then we have $dx^I ∧ dx^J = ±dx^K$ where $K = I ∪ J$, but is reordered to be in increasing order. \n",
"Elements with repeated indices are dropped. Using this notation we can compute the wedge product as follows\n",
"\\begin{equation}\n",
"\\Big(\\sum_I a_Idx^I\\Big)\\wedge\\Big(\\sum_J b_Jdx^J\\Big)=\n",
"\\sum_K\\Big(\\sum_{\\substack{I\\cup J=K\\\\I\\cap J=\\emptyset}}\\pm a_Ib_J\\Big)dx^K.\n",
"\\label{}\\tag{14.11}\n",
"\\end{equation}\n",
"\n",
"
\n",
"\n",
"**Example 14.3**\n",
"\n",
"Let us define a differential 2-form on a 3-dimensional manifold.\n"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\\(\\displaystyle a = a_{01}\\left({x^{0}}, {x^{1}}, {x^{2}}\\right) \\mathrm{d} {x^{0}}\\wedge \\mathrm{d} {x^{1}} + a_{02}\\left({x^{0}}, {x^{1}}, {x^{2}}\\right) \\mathrm{d} {x^{0}}\\wedge \\mathrm{d} {x^{2}} + a_{12}\\left({x^{0}}, {x^{1}}, {x^{2}}\\right) \\mathrm{d} {x^{1}}\\wedge \\mathrm{d} {x^{2}}\\)"
],
"text/latex": [
"$\\displaystyle a = a_{01}\\left({x^{0}}, {x^{1}}, {x^{2}}\\right) \\mathrm{d} {x^{0}}\\wedge \\mathrm{d} {x^{1}} + a_{02}\\left({x^{0}}, {x^{1}}, {x^{2}}\\right) \\mathrm{d} {x^{0}}\\wedge \\mathrm{d} {x^{2}} + a_{12}\\left({x^{0}}, {x^{1}}, {x^{2}}\\right) \\mathrm{d} {x^{1}}\\wedge \\mathrm{d} {x^{2}}$"
],
"text/plain": [
"a = a01(x0, x1, x2) dx0∧dx1 + a02(x0, x1, x2) dx0∧dx2 + a12(x0, x1, x2) dx1∧dx2"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"%display latex\n",
"N = 3 # dimension of manifold M \n",
"M = Manifold(N, 'M') # manifold M\n",
"X = M.chart(' '.join(['x'+str(i)+':x^{'+str(i)+'}' for i in range(N)])) # chart on M\n",
"x0, x1, x2 = X[:] # coordinates x^0, x^1, x^2 of chart X as the Python variables x0, x1, x2\n",
"a = M.diff_form(2, name='a') # differential 2-form on M\n",
"a01 = M.scalar_field(function('a01')(x0,x1,x2), name='a01') # component a_{01}\n",
"a02 = M.scalar_field(function('a02')(x0,x1,x2), name='a02') # component a_{02}\n",
"a12 = M.scalar_field(function('a12')(x0,x1,x2), name='a12') # component a_{12}\n",
"a[0,1] = a01; a[0,2] = a02 # by antisymmetry, 6 nonzero components defined\n",
"a[1,2] = a12 \n",
"a.disp()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The arguments of components can be omitted"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\\(\\displaystyle a = a_{01} \\mathrm{d} {x^{0}}\\wedge \\mathrm{d} {x^{1}} + a_{02} \\mathrm{d} {x^{0}}\\wedge \\mathrm{d} {x^{2}} + a_{12} \\mathrm{d} {x^{1}}\\wedge \\mathrm{d} {x^{2}}\\)"
],
"text/latex": [
"$\\displaystyle a = a_{01} \\mathrm{d} {x^{0}}\\wedge \\mathrm{d} {x^{1}} + a_{02} \\mathrm{d} {x^{0}}\\wedge \\mathrm{d} {x^{2}} + a_{12} \\mathrm{d} {x^{1}}\\wedge \\mathrm{d} {x^{2}}$"
],
"text/plain": [
"a = a01 dx0∧dx1 + a02 dx0∧dx2 + a12 dx1∧dx2"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"Manifold.options.omit_function_arguments=True\n",
"a.disp()"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\\(\\displaystyle \\Omega^{2}\\left(M\\right)\\)"
],
"text/latex": [
"$\\displaystyle \\Omega^{2}\\left(M\\right)$"
],
"text/plain": [
"Free module Omega^2(M) of 2-forms on the 3-dimensional differentiable manifold M"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# mathematical object of which \"a\" is an element\n",
"a.parent()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The matrix of 2-form must be antisymmetric."
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\\(\\displaystyle \\left(\\begin{array}{rrr}\n",
"0 & a_{01} & a_{02} \\\\\n",
"-a_{01} & 0 & a_{12} \\\\\n",
"-a_{02} & -a_{12} & 0\n",
"\\end{array}\\right)\\)"
],
"text/latex": [
"$\\displaystyle \\left(\\begin{array}{rrr}\n",
"0 & a_{01} & a_{02} \\\\\n",
"-a_{01} & 0 & a_{12} \\\\\n",
"-a_{02} & -a_{12} & 0\n",
"\\end{array}\\right)$"
],
"text/plain": [
"[ 0 a01 a02]\n",
"[-a01 0 a12]\n",
"[-a02 -a12 0]"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"a[:]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We can check the formula $\\ a_{ij}=a(\\frac{\\partial}{\\partial x^0},\\frac{\\partial}{\\partial x^1})$."
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\\(\\displaystyle \\left(\\begin{array}{rrr}\n",
"0 & a_{01}\\left({x^{0}}, {x^{1}}, {x^{2}}\\right) & a_{02}\\left({x^{0}}, {x^{1}}, {x^{2}}\\right) \\\\\n",
"-a_{01}\\left({x^{0}}, {x^{1}}, {x^{2}}\\right) & 0 & a_{12}\\left({x^{0}}, {x^{1}}, {x^{2}}\\right) \\\\\n",
"-a_{02}\\left({x^{0}}, {x^{1}}, {x^{2}}\\right) & -a_{12}\\left({x^{0}}, {x^{1}}, {x^{2}}\\right) & 0\n",
"\\end{array}\\right)\\)"
],
"text/latex": [
"$\\displaystyle \\left(\\begin{array}{rrr}\n",
"0 & a_{01}\\left({x^{0}}, {x^{1}}, {x^{2}}\\right) & a_{02}\\left({x^{0}}, {x^{1}}, {x^{2}}\\right) \\\\\n",
"-a_{01}\\left({x^{0}}, {x^{1}}, {x^{2}}\\right) & 0 & a_{12}\\left({x^{0}}, {x^{1}}, {x^{2}}\\right) \\\\\n",
"-a_{02}\\left({x^{0}}, {x^{1}}, {x^{2}}\\right) & -a_{12}\\left({x^{0}}, {x^{1}}, {x^{2}}\\right) & 0\n",
"\\end{array}\\right)$"
],
"text/plain": [
"[ 0 a01(x0, x1, x2) a02(x0, x1, x2)]\n",
"[-a01(x0, x1, x2) 0 a12(x0, x1, x2)]\n",
"[-a02(x0, x1, x2) -a12(x0, x1, x2) 0]"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# check the matrix a(d/dxi,d/dxj)\n",
"fr = X.frame();\n",
"matrix([[a(fr[i0],fr[i1]).expr() for i1 in range(3)] for i0 in range(3)]) "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"
\n",
"\n",
"**Example 14.4**\n",
"\n",
"Let us show how the antisymmetrization operation works for tensor fields $t\\in T^{(0,2)}M$."
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [],
"source": [
"N = 3 # dimension of manifold M \n",
"M = Manifold(N, 'M') # manifold M\n",
"X = M.chart(' '.join(['x'+str(i)+':x^{'+str(i)+'}' for i in range(N)])) # chart on M\n",
"x0, x1, x2 = X[:] # coordinates x^0, x^1, x^2 of chart X as the Python variables x0, x1, x2\n",
"t = M.tensor_field(0,2, name='t') # tensor field of type (0,2)\n",
"f2 = [['f'+str(i)+str(j) for j in range(N)] for i in range(N)] # table of comp. names\n",
"f = [[M.scalar_field(function(f2[j][k])(x0,x1,x2), name=f2[j][k]) # table of comp. funcs\n",
" for k in range(N)] for j in range(N)]\n",
"t[:] = f # define all components"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\\(\\displaystyle t = f_{00} \\mathrm{d} {x^{0}}\\otimes \\mathrm{d} {x^{0}} + f_{01} \\mathrm{d} {x^{0}}\\otimes \\mathrm{d} {x^{1}} + f_{02} \\mathrm{d} {x^{0}}\\otimes \\mathrm{d} {x^{2}} + f_{10} \\mathrm{d} {x^{1}}\\otimes \\mathrm{d} {x^{0}} + f_{11} \\mathrm{d} {x^{1}}\\otimes \\mathrm{d} {x^{1}} + f_{12} \\mathrm{d} {x^{1}}\\otimes \\mathrm{d} {x^{2}} + f_{20} \\mathrm{d} {x^{2}}\\otimes \\mathrm{d} {x^{0}} + f_{21} \\mathrm{d} {x^{2}}\\otimes \\mathrm{d} {x^{1}} + f_{22} \\mathrm{d} {x^{2}}\\otimes \\mathrm{d} {x^{2}}\\)"
],
"text/latex": [
"$\\displaystyle t = f_{00} \\mathrm{d} {x^{0}}\\otimes \\mathrm{d} {x^{0}} + f_{01} \\mathrm{d} {x^{0}}\\otimes \\mathrm{d} {x^{1}} + f_{02} \\mathrm{d} {x^{0}}\\otimes \\mathrm{d} {x^{2}} + f_{10} \\mathrm{d} {x^{1}}\\otimes \\mathrm{d} {x^{0}} + f_{11} \\mathrm{d} {x^{1}}\\otimes \\mathrm{d} {x^{1}} + f_{12} \\mathrm{d} {x^{1}}\\otimes \\mathrm{d} {x^{2}} + f_{20} \\mathrm{d} {x^{2}}\\otimes \\mathrm{d} {x^{0}} + f_{21} \\mathrm{d} {x^{2}}\\otimes \\mathrm{d} {x^{1}} + f_{22} \\mathrm{d} {x^{2}}\\otimes \\mathrm{d} {x^{2}}$"
],
"text/plain": [
"t = f00 dx0⊗dx0 + f01 dx0⊗dx1 + f02 dx0⊗dx2 + f10 dx1⊗dx0 + f11 dx1⊗dx1 + f12 dx1⊗dx2 + f20 dx2⊗dx0 + f21 dx2⊗dx1 + f22 dx2⊗dx2"
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"t.disp() # show tensor t"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now we apply the antisymmetrization operation, the result is 2-form at."
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"2-form on the 3-dimensional differentiable manifold M\n"
]
}
],
"source": [
"at = t.antisymmetrize() # antisymmetrization of t\n",
"print(at) # show info on at"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\\(\\displaystyle \\left( \\frac{1}{2} \\, f_{01} - \\frac{1}{2} \\, f_{10} \\right) \\mathrm{d} {x^{0}}\\wedge \\mathrm{d} {x^{1}} + \\left( \\frac{1}{2} \\, f_{02} - \\frac{1}{2} \\, f_{20} \\right) \\mathrm{d} {x^{0}}\\wedge \\mathrm{d} {x^{2}} + \\left( \\frac{1}{2} \\, f_{12} - \\frac{1}{2} \\, f_{21} \\right) \\mathrm{d} {x^{1}}\\wedge \\mathrm{d} {x^{2}}\\)"
],
"text/latex": [
"$\\displaystyle \\left( \\frac{1}{2} \\, f_{01} - \\frac{1}{2} \\, f_{10} \\right) \\mathrm{d} {x^{0}}\\wedge \\mathrm{d} {x^{1}} + \\left( \\frac{1}{2} \\, f_{02} - \\frac{1}{2} \\, f_{20} \\right) \\mathrm{d} {x^{0}}\\wedge \\mathrm{d} {x^{2}} + \\left( \\frac{1}{2} \\, f_{12} - \\frac{1}{2} \\, f_{21} \\right) \\mathrm{d} {x^{1}}\\wedge \\mathrm{d} {x^{2}}$"
],
"text/plain": [
"(1/2*f01 - 1/2*f10) dx0∧dx1 + (1/2*f02 - 1/2*f20) dx0∧dx2 + (1/2*f12 - 1/2*f21) dx1∧dx2"
]
},
"execution_count": 14,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"Manifold.options.omit_function_arguments=True\n",
"at.disp() # show at"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The matrix of components of $t$ is a full 3-3 matrix:"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\\(\\displaystyle \\left(\\begin{array}{rrr}\n",
"f_{00} & f_{01} & f_{02} \\\\\n",
"f_{10} & f_{11} & f_{12} \\\\\n",
"f_{20} & f_{21} & f_{22}\n",
"\\end{array}\\right)\\)"
],
"text/latex": [
"$\\displaystyle \\left(\\begin{array}{rrr}\n",
"f_{00} & f_{01} & f_{02} \\\\\n",
"f_{10} & f_{11} & f_{12} \\\\\n",
"f_{20} & f_{21} & f_{22}\n",
"\\end{array}\\right)$"
],
"text/plain": [
"[f00 f01 f02]\n",
"[f10 f11 f12]\n",
"[f20 f21 f22]"
]
},
"execution_count": 15,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"t[:] # components of t"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"and the antisymmetrized tensor has the antisymmetric matrix of components:"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\\(\\displaystyle \\left(\\begin{array}{rrr}\n",
"0 & \\frac{1}{2} \\, f_{01} - \\frac{1}{2} \\, f_{10} & \\frac{1}{2} \\, f_{02} - \\frac{1}{2} \\, f_{20} \\\\\n",
"-\\frac{1}{2} \\, f_{01} + \\frac{1}{2} \\, f_{10} & 0 & \\frac{1}{2} \\, f_{12} - \\frac{1}{2} \\, f_{21} \\\\\n",
"-\\frac{1}{2} \\, f_{02} + \\frac{1}{2} \\, f_{20} & -\\frac{1}{2} \\, f_{12} + \\frac{1}{2} \\, f_{21} & 0\n",
"\\end{array}\\right)\\)"
],
"text/latex": [
"$\\displaystyle \\left(\\begin{array}{rrr}\n",
"0 & \\frac{1}{2} \\, f_{01} - \\frac{1}{2} \\, f_{10} & \\frac{1}{2} \\, f_{02} - \\frac{1}{2} \\, f_{20} \\\\\n",
"-\\frac{1}{2} \\, f_{01} + \\frac{1}{2} \\, f_{10} & 0 & \\frac{1}{2} \\, f_{12} - \\frac{1}{2} \\, f_{21} \\\\\n",
"-\\frac{1}{2} \\, f_{02} + \\frac{1}{2} \\, f_{20} & -\\frac{1}{2} \\, f_{12} + \\frac{1}{2} \\, f_{21} & 0\n",
"\\end{array}\\right)$"
],
"text/plain": [
"[ 0 1/2*f01 - 1/2*f10 1/2*f02 - 1/2*f20]\n",
"[-1/2*f01 + 1/2*f10 0 1/2*f12 - 1/2*f21]\n",
"[-1/2*f02 + 1/2*f20 -1/2*f12 + 1/2*f21 0]"
]
},
"execution_count": 16,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"at[:] # components of antisymmetrization"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"
\n",
"\n",
"**Example 14.5**\n",
"\n",
"Consider a tensor field of type $(0,3)$ on a 4-dimensional manifold and its antisymmetrization."
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Tensor field t3 of type (0,3) on the 4-dimensional differentiable manifold M\n"
]
}
],
"source": [
"%display latex\n",
"N = 4 # dimension of the manifold M\n",
"M = Manifold(N, 'M') # manifold M\n",
"X = M.chart(' '.join(['x'+str(i)+':x^{'+str(i)+'}' for i in range(N)])) # chart on M\n",
"t3 = M.tensor_field(0,3, name='t3') # tensor field of type (0,3)\n",
"print(t3) # show info on t3\n",
" # table of component names:\n",
"f3 = [[['a'+str(i)+str(j)+str(k) for k in range(N)] \n",
" for j in range(N)] for i in range(N)]\n",
" # table of component functions:\n",
"f = [[[M.scalar_field(function(f3[i][j][k])(*X), name=f3[i][j][k]) \n",
" for k in range(N)] for j in range(N)] for i in range(N)]\n",
"t3[:] = f # define all components"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Let $e$ be the frame: "
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\\(\\displaystyle \\left(M, \\left(\\frac{\\partial}{\\partial {x^{0}} },\\frac{\\partial}{\\partial {x^{1}} },\\frac{\\partial}{\\partial {x^{2}} },\\frac{\\partial}{\\partial {x^{3}} }\\right)\\right)\\)"
],
"text/latex": [
"$\\displaystyle \\left(M, \\left(\\frac{\\partial}{\\partial {x^{0}} },\\frac{\\partial}{\\partial {x^{1}} },\\frac{\\partial}{\\partial {x^{2}} },\\frac{\\partial}{\\partial {x^{3}} }\\right)\\right)$"
],
"text/plain": [
"Coordinate frame (M, (∂/∂x0,∂/∂x1,∂/∂x2,∂/∂x3))"
]
},
"execution_count": 18,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"e = X.frame(); e # frame of M"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"and let's show how the definition of the antisymmetrization works if we take $(v_1,v_2,v_3)=(\\frac{\\partial}{\\partial x^0},\n",
"\\frac{\\partial}{\\partial x^1},\\frac{\\partial}{\\partial x^2})$ in (14.2):"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {},
"outputs": [],
"source": [
"S3 = Permutations(3).list() # S_3 group\n",
"s = 1/factorial(3)*sum([sign(p)*t3(e[p[0]-1],e[p[1]-1],e[p[2]-1])\n",
" for p in S3]) # special case of (14.2)"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\\(\\displaystyle \\begin{array}{llcl} & M & \\longrightarrow & \\mathbb{R} \\\\ & \\left({x^{0}}, {x^{1}}, {x^{2}}, {x^{3}}\\right) & \\longmapsto & \\frac{1}{6} \\, a_{012} - \\frac{1}{6} \\, a_{021} - \\frac{1}{6} \\, a_{102} + \\frac{1}{6} \\, a_{120} + \\frac{1}{6} \\, a_{201} - \\frac{1}{6} \\, a_{210} \\end{array}\\)"
],
"text/latex": [
"$\\displaystyle \\begin{array}{llcl} & M & \\longrightarrow & \\mathbb{R} \\\\ & \\left({x^{0}}, {x^{1}}, {x^{2}}, {x^{3}}\\right) & \\longmapsto & \\frac{1}{6} \\, a_{012} - \\frac{1}{6} \\, a_{021} - \\frac{1}{6} \\, a_{102} + \\frac{1}{6} \\, a_{120} + \\frac{1}{6} \\, a_{201} - \\frac{1}{6} \\, a_{210} \\end{array}$"
],
"text/plain": [
"M → ℝ\n",
"(x0, x1, x2, x3) ↦ 1/6*a012 - 1/6*a021 - 1/6*a102 + 1/6*a120 + 1/6*a201 - 1/6*a210"
]
},
"execution_count": 20,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"Manifold.options.omit_function_arguments=True\n",
"s.disp() # show the result\n",
"#s.expr()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"As we can see the sum contains 3!=6 elements with signs equal to permutations signs.\n",
"\n",
"For comparison one can use the `antisymmetrize` method:"
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {},
"outputs": [],
"source": [
" # built in\n",
"t3a = t3.antisymmetrize() # antisymmetrization"
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\\(\\displaystyle \\begin{array}{llcl} & M & \\longrightarrow & \\mathbb{R} \\\\ & \\left({x^{0}}, {x^{1}}, {x^{2}}, {x^{3}}\\right) & \\longmapsto & \\frac{1}{6} \\, a_{012} - \\frac{1}{6} \\, a_{021} - \\frac{1}{6} \\, a_{102} + \\frac{1}{6} \\, a_{120} + \\frac{1}{6} \\, a_{201} - \\frac{1}{6} \\, a_{210} \\end{array}\\)"
],
"text/latex": [
"$\\displaystyle \\begin{array}{llcl} & M & \\longrightarrow & \\mathbb{R} \\\\ & \\left({x^{0}}, {x^{1}}, {x^{2}}, {x^{3}}\\right) & \\longmapsto & \\frac{1}{6} \\, a_{012} - \\frac{1}{6} \\, a_{021} - \\frac{1}{6} \\, a_{102} + \\frac{1}{6} \\, a_{120} + \\frac{1}{6} \\, a_{201} - \\frac{1}{6} \\, a_{210} \\end{array}$"
],
"text/plain": [
"M → ℝ\n",
"(x0, x1, x2, x3) ↦ 1/6*a012 - 1/6*a021 - 1/6*a102 + 1/6*a120 + 1/6*a201 - 1/6*a210"
]
},
"execution_count": 22,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"t3a(e[0],e[1],e[2]).disp()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"
\n",
"\n",
"**Example 14.6**\n",
"\n",
"Define two 1-forms with symbolic components and compute their wedge product."
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {},
"outputs": [],
"source": [
"N = 3 # dimension of manifold M\n",
"M = Manifold(N, 'M') # manifold M\n",
"X = M.chart(' '.join(['x'+str(i)+':x^{'+str(i)+'}' for i in range(N)])) # chart on M\n",
"a = M.diff_form(1,name='a') # 1-form a\n",
"b = M.diff_form(1,name='b') # 1-form b\n",
"ast = ['a'+str(j) for j in range(N)] # list of component names \n",
"bst = ['b'+str(j) for j in range(N)] # list of component names\n",
"af = [M.scalar_field(function(ast[j])(*X),name=ast[j]) \n",
" for j in range(N)] # list of component functions\n",
"bf = [M.scalar_field(function(bst[j])(*X),name=bst[j]) \n",
" for j in range(N)] # list of component functions\n",
"a[:] = af # define all components of a\n",
"b[:] = bf # define all components of b"
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\\(\\displaystyle a = a_{0} \\mathrm{d} {x^{0}} + a_{1} \\mathrm{d} {x^{1}} + a_{2} \\mathrm{d} {x^{2}}\\)"
],
"text/latex": [
"$\\displaystyle a = a_{0} \\mathrm{d} {x^{0}} + a_{1} \\mathrm{d} {x^{1}} + a_{2} \\mathrm{d} {x^{2}}$"
],
"text/plain": [
"a = a0 dx0 + a1 dx1 + a2 dx2"
]
},
"execution_count": 24,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"Manifold.options.omit_function_arguments=True\n",
"%display latex\n",
"a.disp() # show a"
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\\(\\displaystyle b = b_{0} \\mathrm{d} {x^{0}} + b_{1} \\mathrm{d} {x^{1}} + b_{2} \\mathrm{d} {x^{2}}\\)"
],
"text/latex": [
"$\\displaystyle b = b_{0} \\mathrm{d} {x^{0}} + b_{1} \\mathrm{d} {x^{1}} + b_{2} \\mathrm{d} {x^{2}}$"
],
"text/plain": [
"b = b0 dx0 + b1 dx1 + b2 dx2"
]
},
"execution_count": 25,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"b.disp() # show b"
]
},
{
"cell_type": "code",
"execution_count": 26,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\\(\\displaystyle \\Omega^{1}\\left(M\\right)\\)"
],
"text/latex": [
"$\\displaystyle \\Omega^{1}\\left(M\\right)$"
],
"text/plain": [
"Free module Omega^1(M) of 1-forms on the 3-dimensional differentiable manifold M"
]
},
"execution_count": 26,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# mathematical object of which \"b\" is an element.\n",
"b.parent()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Wedge product $a\\wedge b$:"
]
},
{
"cell_type": "code",
"execution_count": 27,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\\(\\displaystyle a\\wedge b = \\left( -a_{1} b_{0} + a_{0} b_{1} \\right) \\mathrm{d} {x^{0}}\\wedge \\mathrm{d} {x^{1}} + \\left( -a_{2} b_{0} + a_{0} b_{2} \\right) \\mathrm{d} {x^{0}}\\wedge \\mathrm{d} {x^{2}} + \\left( -a_{2} b_{1} + a_{1} b_{2} \\right) \\mathrm{d} {x^{1}}\\wedge \\mathrm{d} {x^{2}}\\)"
],
"text/latex": [
"$\\displaystyle a\\wedge b = \\left( -a_{1} b_{0} + a_{0} b_{1} \\right) \\mathrm{d} {x^{0}}\\wedge \\mathrm{d} {x^{1}} + \\left( -a_{2} b_{0} + a_{0} b_{2} \\right) \\mathrm{d} {x^{0}}\\wedge \\mathrm{d} {x^{2}} + \\left( -a_{2} b_{1} + a_{1} b_{2} \\right) \\mathrm{d} {x^{1}}\\wedge \\mathrm{d} {x^{2}}$"
],
"text/plain": [
"a∧b = (-a1*b0 + a0*b1) dx0∧dx1 + (-a2*b0 + a0*b2) dx0∧dx2 + (-a2*b1 + a1*b2) dx1∧dx2"
]
},
"execution_count": 27,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"ab = a.wedge(b) # wedge product\n",
"ab.disp() # in SageMath"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Compare with the result obtained from definition (14.3):"
]
},
{
"cell_type": "code",
"execution_count": 28,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\\(\\displaystyle \\left( -a_{1} b_{0} + a_{0} b_{1} \\right) \\mathrm{d} {x^{0}}\\wedge \\mathrm{d} {x^{1}} + \\left( -a_{2} b_{0} + a_{0} b_{2} \\right) \\mathrm{d} {x^{0}}\\wedge \\mathrm{d} {x^{2}} + \\left( -a_{2} b_{1} + a_{1} b_{2} \\right) \\mathrm{d} {x^{1}}\\wedge \\mathrm{d} {x^{2}}\\)"
],
"text/latex": [
"$\\displaystyle \\left( -a_{1} b_{0} + a_{0} b_{1} \\right) \\mathrm{d} {x^{0}}\\wedge \\mathrm{d} {x^{1}} + \\left( -a_{2} b_{0} + a_{0} b_{2} \\right) \\mathrm{d} {x^{0}}\\wedge \\mathrm{d} {x^{2}} + \\left( -a_{2} b_{1} + a_{1} b_{2} \\right) \\mathrm{d} {x^{1}}\\wedge \\mathrm{d} {x^{2}}$"
],
"text/plain": [
"(-a1*b0 + a0*b1) dx0∧dx1 + (-a2*b0 + a0*b2) dx0∧dx2 + (-a2*b1 + a1*b2) dx1∧dx2"
]
},
"execution_count": 28,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"ab1 = factorial(1+1)/factorial(1)/factorial(1)*(a*b).antisymmetrize()\n",
"ab1.disp() # use formula (14.3)"
]
},
{
"cell_type": "code",
"execution_count": 29,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\\(\\displaystyle \\mathrm{True}\\)"
],
"text/latex": [
"$\\displaystyle \\mathrm{True}$"
],
"text/plain": [
"True"
]
},
"execution_count": 29,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"ab1 == ab # check if both methods agree"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Define the matrix containing the components of 1-forms in rows:"
]
},
{
"cell_type": "code",
"execution_count": 30,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\\(\\displaystyle \\left(\\begin{array}{rrr}\n",
"a_{0} & a_{1} & a_{2} \\\\\n",
"b_{0} & b_{1} & b_{2}\n",
"\\end{array}\\right)\\)"
],
"text/latex": [
"$\\displaystyle \\left(\\begin{array}{rrr}\n",
"a_{0} & a_{1} & a_{2} \\\\\n",
"b_{0} & b_{1} & b_{2}\n",
"\\end{array}\\right)$"
],
"text/plain": [
"[a0 a1 a2]\n",
"[b0 b1 b2]"
]
},
"execution_count": 30,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"ma = matrix([a[:],b[:]])\n",
"ma"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The components of the wedge product of 1-forms are minors of the matrix of components of these 1-forms."
]
},
{
"cell_type": "code",
"execution_count": 31,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\\(\\displaystyle \\left[-a_{1} b_{0} + a_{0} b_{1}, -a_{2} b_{0} + a_{0} b_{2}, -a_{2} b_{1} + a_{1} b_{2}\\right]\\)"
],
"text/latex": [
"$\\displaystyle \\left[-a_{1} b_{0} + a_{0} b_{1}, -a_{2} b_{0} + a_{0} b_{2}, -a_{2} b_{1} + a_{1} b_{2}\\right]$"
],
"text/plain": [
"[-a1*b0 + a0*b1, -a2*b0 + a0*b2, -a2*b1 + a1*b2]"
]
},
"execution_count": 31,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"ma.minors(2)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"
\n",
"\n",
"**Example 14.7**\n",
"\n",
"Consider the wedge product of three 1-forms (in 3-dimensional manifold)."
]
},
{
"cell_type": "code",
"execution_count": 32,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\\(\\displaystyle a\\wedge b\\wedge c = \\left( -{\\left(a_{2} b_{1} - a_{1} b_{2}\\right)} c_{0} + {\\left(a_{2} b_{0} - a_{0} b_{2}\\right)} c_{1} - {\\left(a_{1} b_{0} - a_{0} b_{1}\\right)} c_{2} \\right) \\mathrm{d} {x^{0}}\\wedge \\mathrm{d} {x^{1}}\\wedge \\mathrm{d} {x^{2}}\\)"
],
"text/latex": [
"$\\displaystyle a\\wedge b\\wedge c = \\left( -{\\left(a_{2} b_{1} - a_{1} b_{2}\\right)} c_{0} + {\\left(a_{2} b_{0} - a_{0} b_{2}\\right)} c_{1} - {\\left(a_{1} b_{0} - a_{0} b_{1}\\right)} c_{2} \\right) \\mathrm{d} {x^{0}}\\wedge \\mathrm{d} {x^{1}}\\wedge \\mathrm{d} {x^{2}}$"
],
"text/plain": [
"a∧b∧c = (-(a2*b1 - a1*b2)*c0 + (a2*b0 - a0*b2)*c1 - (a1*b0 - a0*b1)*c2) dx0∧dx1∧dx2"
]
},
"execution_count": 32,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# continuation\n",
"Manifold.options.omit_function_arguments=True\n",
"cst = ['c'+str(j) for j in range(N)] # list of component names\n",
"cf = [M.scalar_field(function(cst[j])(*X),name=cst[j]) \n",
" for j in range(N)] # list of component functions\n",
"c = M.diff_form(1,name='c') # 1-form c\n",
"c[:] = cf # define all coefficients\n",
"abc = (a.wedge(b)).wedge(c) # wedge prod. a /\\ b /\\ c\n",
"abc.disp()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We can recognize in the result the Laplace expansion of the determinant $\\ $ det $\\left(\\begin{matrix}\n",
"a_0,a_1,a_2\\\\\n",
"b_0,b_1,b_2\\\\\n",
"c_0,c_1,c2\n",
"\\end{matrix}\\right),\\ \\ \n",
"$\n",
"so we have\n",
"
\n",
"$\\quad a\\wedge b\\wedge c=$\n",
"det $\\left(\\begin{matrix}\n",
"a_0,a_1,a_2\\\\\n",
"b_0,b_1,b_2\\\\\n",
"c_0,c_1,c2\n",
"\\end{matrix}\\right)\n",
"dx^0\\wedge dx^1\\wedge dx^2.\n",
"$\n",
"\n",
"We can check the observation using SageMath: "
]
},
{
"cell_type": "code",
"execution_count": 33,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\\(\\displaystyle \\left(M, \\left(\\mathrm{d} {x^{0}},\\mathrm{d} {x^{1}},\\mathrm{d} {x^{2}}\\right)\\right)\\)"
],
"text/latex": [
"$\\displaystyle \\left(M, \\left(\\mathrm{d} {x^{0}},\\mathrm{d} {x^{1}},\\mathrm{d} {x^{2}}\\right)\\right)$"
],
"text/plain": [
"Coordinate coframe (M, (dx0,dx1,dx2))"
]
},
"execution_count": 33,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"d = X.coframe()\n",
"d"
]
},
{
"cell_type": "code",
"execution_count": 34,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\\(\\displaystyle \\mathrm{True}\\)"
],
"text/latex": [
"$\\displaystyle \\mathrm{True}$"
],
"text/plain": [
"True"
]
},
"execution_count": 34,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# compare abc with the 3-form with the determinant as coefficient\n",
"abc == det(matrix([a[:],b[:],c[:]]))*(d[0].wedge(d[1])).wedge(d[2])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The unique component of the wedge product $abc=a\\wedge b\\wedge c$ must be equal to $\\ \\ abc(\\frac{\\partial}{\\partial x^0},\\frac{\\partial}{\\partial x^1},\\frac{\\partial}{\\partial x^2})$.\n",
"\n",
"Let us check it with SageMath Manifolds."
]
},
{
"cell_type": "code",
"execution_count": 35,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\\(\\displaystyle \\left(M, \\left(\\frac{\\partial}{\\partial {x^{0}} },\\frac{\\partial}{\\partial {x^{1}} },\\frac{\\partial}{\\partial {x^{2}} }\\right)\\right)\\)"
],
"text/latex": [
"$\\displaystyle \\left(M, \\left(\\frac{\\partial}{\\partial {x^{0}} },\\frac{\\partial}{\\partial {x^{1}} },\\frac{\\partial}{\\partial {x^{2}} }\\right)\\right)$"
],
"text/plain": [
"Coordinate frame (M, (∂/∂x0,∂/∂x1,∂/∂x2))"
]
},
"execution_count": 35,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"X.frame() # default frame"
]
},
{
"cell_type": "code",
"execution_count": 36,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\\(\\displaystyle \\mathrm{True}\\)"
],
"text/latex": [
"$\\displaystyle \\mathrm{True}$"
],
"text/plain": [
"True"
]
},
"execution_count": 36,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# check if the value of abc on the frame \n",
"# is equal to det([a[:],b[:],c[:]])\n",
"abc(*X.frame()) == det(matrix([a[:],b[:],c[:]]))"
]
},
{
"cell_type": "code",
"execution_count": 37,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\\(\\displaystyle \\mathrm{True}\\)"
],
"text/latex": [
"$\\displaystyle \\mathrm{True}$"
],
"text/plain": [
"True"
]
},
"execution_count": 37,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# the same in an other way\n",
"abc[0,1,2] == det(matrix([a[:],b[:],c[:]]))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"
\n",
"\n",
"**Example 14.8**\n",
"\n",
"Consider two 2-forms on a 4-dimensional manifold."
]
},
{
"cell_type": "code",
"execution_count": 38,
"metadata": {},
"outputs": [],
"source": [
"N = 4 # dimension of manifold M\n",
"M = Manifold(N, 'M') # manifold M\n",
"X = M.chart(' '.join(['x'+str(i)+':x^{'+str(i)+'}' for i in range(N)])) # chart on M\n",
"a=M.diff_form(2,name='a') # 2-form a\n",
"b=M.diff_form(2,name='b') # 2-form b"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We define first the names of functions,"
]
},
{
"cell_type": "code",
"execution_count": 39,
"metadata": {},
"outputs": [],
"source": [
"def ast(i,j): return 'a'+str(i)+str(j) # names of comp. for a\n",
" \n",
"def bst(i,j): return 'b'+str(i)+str(j) # names of comp. for b "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"and the upper triangles of component matrices."
]
},
{
"cell_type": "code",
"execution_count": 40,
"metadata": {},
"outputs": [],
"source": [
"for i0 in range(N): # component functions for a\n",
" for i1 in range(N): \n",
" if i1>i0:\n",
" a[i0,i1] = M.scalar_field(function(ast(i0,i1))(*X),\n",
" name=ast(i0,i1))\n",
"for i0 in range(N): # component functions for b\n",
" for i1 in range(N): \n",
" if i1>i0:\n",
" b[i0,i1] = M.scalar_field(function(bst(i0,i1))(*X),\n",
" name=bst(i0,i1))"
]
},
{
"cell_type": "code",
"execution_count": 41,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\\(\\displaystyle \\left(\\begin{array}{rrrr}\n",
"0 & a_{01} & a_{02} & a_{03} \\\\\n",
"-a_{01} & 0 & a_{12} & a_{13} \\\\\n",
"-a_{02} & -a_{12} & 0 & a_{23} \\\\\n",
"-a_{03} & -a_{13} & -a_{23} & 0\n",
"\\end{array}\\right)\\)"
],
"text/latex": [
"$\\displaystyle \\left(\\begin{array}{rrrr}\n",
"0 & a_{01} & a_{02} & a_{03} \\\\\n",
"-a_{01} & 0 & a_{12} & a_{13} \\\\\n",
"-a_{02} & -a_{12} & 0 & a_{23} \\\\\n",
"-a_{03} & -a_{13} & -a_{23} & 0\n",
"\\end{array}\\right)$"
],
"text/plain": [
"[ 0 a01 a02 a03]\n",
"[-a01 0 a12 a13]\n",
"[-a02 -a12 0 a23]\n",
"[-a03 -a13 -a23 0]"
]
},
"execution_count": 41,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"Manifold.options.omit_function_arguments=True\n",
"%display latex\n",
"a[:] # show components of a"
]
},
{
"cell_type": "code",
"execution_count": 42,
"metadata": {
"scrolled": true,
"tags": []
},
"outputs": [
{
"data": {
"text/html": [
"\\(\\displaystyle \\left(\\begin{array}{rrrr}\n",
"0 & b_{01} & b_{02} & b_{03} \\\\\n",
"-b_{01} & 0 & b_{12} & b_{13} \\\\\n",
"-b_{02} & -b_{12} & 0 & b_{23} \\\\\n",
"-b_{03} & -b_{13} & -b_{23} & 0\n",
"\\end{array}\\right)\\)"
],
"text/latex": [
"$\\displaystyle \\left(\\begin{array}{rrrr}\n",
"0 & b_{01} & b_{02} & b_{03} \\\\\n",
"-b_{01} & 0 & b_{12} & b_{13} \\\\\n",
"-b_{02} & -b_{12} & 0 & b_{23} \\\\\n",
"-b_{03} & -b_{13} & -b_{23} & 0\n",
"\\end{array}\\right)$"
],
"text/plain": [
"[ 0 b01 b02 b03]\n",
"[-b01 0 b12 b13]\n",
"[-b02 -b12 0 b23]\n",
"[-b03 -b13 -b23 0]"
]
},
"execution_count": 42,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"b[:] # show components of b"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"
\n",
"\n",
"Recall that according to the general rule, to obtain the wedge product we use all possible strictly increasing and disjoint sequences $I=(i_1,i_2),\\ J=(j_1,j_2)$ and define $dx^K=e^1\\wedge e^2\\wedge e^3\\wedge e^4,$ \n",
"where $K=(1,2,3,4)$ is reordered disjoint union $I\\cup J$. We have\n",
"\n",
"$$\\Big(\\sum_I a_Idx^I\\Big)\\wedge\\Big(\\sum_J b_Jdx^J\\Big)=\n",
"\\sum_K\\Big(\\sum_{\\substack{I\\cup J=K\\\\I\\cap J=\\emptyset}}\\pm a_Ib_J\\Big)dx^K.$$\n",
"\n",
"To be less formal, to compute the wedge product we\n",
"\n",
"a) take all possible components of the first 2-form with increasing permutations $I$ of two indices from (0,1,2,3);\n",
"\n",
"b) multiply them by components of the second 2-form with increasing permutations $J$ of the remaining 2 indices;\n",
"\n",
"c) the products are taken with + or - depending on the sign of the joined permutation $(I,J)$ of (0,1,2,3). "
]
},
{
"cell_type": "code",
"execution_count": 43,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\\(\\displaystyle a\\wedge b = \\left( a_{23} b_{01} - a_{13} b_{02} + a_{12} b_{03} + a_{03} b_{12} - a_{02} b_{13} + a_{01} b_{23} \\right) \\mathrm{d} {x^{0}}\\wedge \\mathrm{d} {x^{1}}\\wedge \\mathrm{d} {x^{2}}\\wedge \\mathrm{d} {x^{3}}\\)"
],
"text/latex": [
"$\\displaystyle a\\wedge b = \\left( a_{23} b_{01} - a_{13} b_{02} + a_{12} b_{03} + a_{03} b_{12} - a_{02} b_{13} + a_{01} b_{23} \\right) \\mathrm{d} {x^{0}}\\wedge \\mathrm{d} {x^{1}}\\wedge \\mathrm{d} {x^{2}}\\wedge \\mathrm{d} {x^{3}}$"
],
"text/plain": [
"a∧b = (a23*b01 - a13*b02 + a12*b03 + a03*b12 - a02*b13 + a01*b23) dx0∧dx1∧dx2∧dx3"
]
},
"execution_count": 43,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"w = a.wedge(b) # w=a/\\b\n",
"w.display() # show w"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## What's next?\n",
"\n",
"Take a look at the notebook [Pullback of tensor fields](https://nbviewer.org/github/sagemanifolds/IntroToManifolds/blob/main/15Manifold_Pullback.ipynb)."
]
}
],
"metadata": {
"kernelspec": {
"display_name": "SageMath 9.6",
"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.8.10"
}
},
"nbformat": 4,
"nbformat_minor": 4
}