--- title: "The `hodge()` function in the `stokes` package" author: "Robin K. S. Hankin" output: html_vignette bibliography: stokes.bib link-citations: true vignette: > %\VignetteEngine{knitr::rmarkdown} %\VignetteIndexEntry{hodge} %\usepackage[utf8]{inputenc} --- ```{r setup, include=FALSE} set.seed(0) library("permutations") library("stokes") options(rmarkdown.html_vignette.check_title = FALSE) options(polyform = FALSE) knitr::opts_chunk$set(echo = TRUE) knit_print.function <- function(x, ...){dput(x)} registerS3method( "knit_print", "function", knit_print.function, envir = asNamespace("knitr") ) ``` ```{r out.width='20%', out.extra='style="float:right; padding:10px"',echo=FALSE} knitr::include_graphics(system.file("help/figures/stokes.png", package = "stokes")) ``` ```{r, label=showhodge,comment=""} hodge ``` To cite the `stokes` package in publications, please use @hankin2022_stokes. Given a $k$-form $\beta$, function `hodge()` returns its Hodge dual $\star\beta$. Formally, if $V={\mathbb R}^n$, and $\Lambda^k(V)$ is the space of alternating linear maps from $V^k$ to ${\mathbb R}$, then $\star\colon\Lambda^k(V)\longrightarrow\Lambda^{n-k}(V)$. To define the Hodge dual, we need an inner product $\left\langle\cdot,\cdot\right\rangle$ [function `kinner()` in the package] and, given this and $\beta\in\Lambda^k(V)$ we define $\star\beta$ to be the (unique) $n-k$-form satisfying the fundamental relation: $$ \alpha\wedge\left(\star\beta\right)=\left\langle\alpha,\beta\right\rangle\omega,$$ for every $\alpha\in\Lambda^k(V)$. Here $\omega=e_1\wedge e_2\wedge\cdots\wedge e_n$ is the unit $n$-vector of $\Lambda^n(V)$. Taking determinants of this relation shows the following. If we use multi-index notation so $e_I=e_{i_1}\wedge\cdots\wedge e_{i_k}$ with $I=\left\lbrace i_1,\cdots,i_k\right\rbrace$, then $$\star e_I=(-1)^{\sigma(I)}e_J$$ where $J=\left\lbrace j_i,\ldots,j_k\right\rbrace=[n]\setminus\left\lbrace i_1,\ldots,i_k\right\rbrace$ is the complement of $I$, and $(-1)^{\sigma(I)}$ is the sign of the permutation $\sigma(I)=i_1\cdots i_kj_1\cdots j_{n-k}$. We extend to the whole of $\Lambda^k(V)$ using linearity. Package idiom for calculating the Hodge dual is straightforward, being simply `hodge()`. ```{r, label=setsymbprint,include = FALSE} options(kform_symbolic_print = NULL) ``` ## The Hodge dual on basis elements of $\Lambda^k(V)$ We start by demonstrating `hodge()` on basis elements of $\Lambda^k(V)$. Recall that if $\left\lbrace e_1,\ldots,e_n\right\rbrace$ is a basis of vector space $V=\mathbb{R}^n$, then $\left\lbrace\omega_1,\ldots,\omega_k\right\rbrace$ is a basis of $\Lambda^1(V)$, where $\omega_i(e_j)=\delta_{ij}$. A basis of $\Lambda^k(V)$ is given by the set \[ \bigcup_{1\leqslant i_1 < \cdots < i_k\leqslant n} \bigwedge_{j=1}^k\omega_{i_j} = \left\lbrace \left.\omega_{i_1}\wedge\cdots\wedge\omega_{i_k} \right|1\leqslant i_1 < \cdots < i_k\leqslant n \right\rbrace. \] This means that basis elements are things like $\omega_2\wedge\omega_6\wedge\omega_7$. If $V=\mathbb{R}^9$, what is $\star\omega_2\wedge\omega_6\wedge\omega_7$? ```{r,label=simpexamp} (a <- d(2) ^ d(6) ^ d(7)) hodge(a,9) ``` See how $\star a$ has index entries 1-9 except $2,6,7$ (from $a$). The (numerical) sign is negative because the permutation has negative (permutational) sign. We can verify this using the `permutations` package: ```{r,label=useperm} p <- c(2,6,7, 1,3,4,5,8,9) (pw <- as.word(p)) print_word(pw) sgn(pw) ``` Above we see the sign of the permutation is negative. More succinct idiom would be ```{r,label=shorthodge} hodge(d(c(2,6,7)),9) ``` The second argument to `hodge()` is needed if the largest index $i_k$ of the first argument is less than $n$; the default value is indeed $n$. In the example above, this is $7$: ```{r label=defaulthodge} hodge(d(c(2,6,7))) ``` Above we see the result if $V=\mathbb{R}^7$. ## More complicated examples The hodge operator is linear and it is interesting to verify this. ```{r,defineo} (o <- rform()) hodge(o) ``` We verify that the fundamental relation holds by direct inspection: ```{r verifyhodgeo} o ^ hodge(o) kinner(o,o)*volume(dovs(o)) ``` showing agreement (above, we use function `volume()` in lieu of calculating the permutation's sign explicitly. See the `volume` vignette for more details). We may work more formally by defining a function that returns `TRUE` if the left and right hand sides match ```{r defdif} diff <- function(a,b){a^hodge(b) == kinner(a,b)*volume(dovs(a))} ``` and call it with random $k$-forms: ```{r calldefdif} diff(rform(),rform()) ``` Or even ```{r alldefdif} all(replicate(10,diff(rform(),rform()))) ``` ## Small-dimensional vector spaces We can work in three dimensions in which case we have three linearly independent $1$-forms: $dx$, $dy$, and $dz$. To work in this system it is better to use `dx` print method: ```{r} options(kform_symbolic_print = "dx") hodge(dx,3) ``` This is further discussed in the `dovs` vignette. ## Vector cross product identities The three dimensional vector cross product $\mathbf{u}\times\mathbf{v}=\det\begin{pmatrix} i & j & k \\ u_1&u_2&u_3\\ v_1&v_2&v_3 \end{pmatrix}$ is a standard part of elementary vector calculus. In the package the idiom is as follows: ```{r showvcp} vcp3 ``` revealing the formal definition of cross product as $\mathbf{u}\times\mathbf{v}=\star{\left(\mathbf{u}\wedge\mathbf{v}\right)}$. There are several elementary identities that are satisfied by the cross product: $$ \begin{aligned} \mathbf{u}\times(\mathbf{v}\times\mathbf{w}) &= \mathbf{v}(\mathbf{w}\cdot\mathbf{u})-\mathbf{w}(\mathbf{u}\cdot\mathbf{v})\\ (\mathbf{u}\times\mathbf{v})\times\mathbf{w} &= \mathbf{v}(\mathbf{w}\cdot\mathbf{u})-\mathbf{u}(\mathbf{v}\cdot\mathbf{w})\\ (\mathbf{u}\times\mathbf{v})\times(\mathbf{u}\times\mathbf{w}) &= (\mathbf{u}\cdot(\mathbf{v}\times\mathbf{w}))\mathbf{u} \\ (\mathbf{u}\times\mathbf{v})\cdot(\mathbf{w}\times\mathbf{x}) &= (\mathbf{u}\cdot\mathbf{w})(\mathbf{v}\cdot\mathbf{x}) - (\mathbf{u}\cdot\mathbf{x})(\mathbf{v}\cdot\mathbf{w}) \end{aligned} $$ We may verify all four together: ```{r} u <- c(1,4,2) v <- c(2,1,5) w <- c(1,-3,2) x <- c(-6,5,7) c( hodge(as.1form(u) ^ vcp3(v,w)) == as.1form(v*sum(w*u) - w*sum(u*v)), hodge(vcp3(u,v) ^ as.1form(w)) == as.1form(v*sum(w*u) - u*sum(v*w)), as.1form(as.function(vcp3(v,w))(u)*u) == hodge(vcp3(u,v) ^ vcp3(u,w)) , hodge(hodge(vcp3(u,v)) ^ vcp3(w,x)) == sum(u*w)*sum(v*x) - sum(u*x)*sum(v*w) ) ``` Above, note the use of the hodge operator to define triple vector cross products. For example we have $\mathbf{u}\times\left(\mathbf{v}\times\mathbf{w}\right)= \star\left(\mathbf{u}\wedge\star\left(\mathbf{v}\wedge\mathbf{w}\right)\right)$. # Non positive-definite metrics The inner product $\left\langle\alpha,\beta\right\rangle$ above may be generalized by defining it on decomposable vectors $\alpha=\alpha_1\wedge\cdots\wedge\alpha_k$ and $\beta=\beta_1\wedge\cdots\wedge\beta_k$ as $$\left\langle\alpha,\beta\right\rangle= \det\left(\left\langle\alpha_i,\beta_j\right\rangle_{i,j}\right)$$ where $\left\langle\alpha_i,\beta_j\right\rangle=\pm\delta_{ij}$ is an inner product on $\Lambda^1(V)$ [the inner product is given by `kinner()`]. The resulting Hodge star operator is implemented in the package and one can specify the metric. For example, if we consider the Minkowski metric this would be $-1,1,1,1$. ## Print methods for the Minkowski metric The standard print method is not particularly suitable for working with the Minkowski metric: ```{r} options(kform_symbolic_print = NULL) # default print method (o <- kform_general(4,2,1:6)) ``` Above we see an unhelpful representation. To work with $2$-forms in relativistic physics, it is often preferable to use bespoke print method `usetxyz`: ```{r} options(kform_symbolic_print = "txyz") o ``` ## Specifying the Minkowski metric Function `hodge()` takes a `g` argument to specify the metric: ```{r} hodge(o) hodge(o,g=c(-1,1,1,1)) hodge(o)-hodge(o,g=c(-1,1,1,1)) ``` ```{r reset_default_print_method, include=FALSE} options(kform_symbolic_print = NULL) ``` # References