The `hodge()` function in the `stokes` package

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")
)
knitr::include_graphics(system.file("help/figures/stokes.png", package = "stokes"))
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().

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$. f $V=\mathbb{R}^9$, what is $\star\omega_2\wedge\omega_6\wedge\omega_7$?

(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 permution has negative (permutational) sign. We can verify this using the permutations package:

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

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$:

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.

(o <- rform())
hodge(o)

We verify that the fundamental relation holds by direct inspection:

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

diff <- function(a,b){a^hodge(b) ==  kinner(a,b)*volume(dovs(a))}

and call it with random $k$-forms:

diff(rform(),rform())

Or even

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:

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:

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:

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:

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:

options(kform_symbolic_print = "txyz")
o

Specifying the Minkowski metric

Function hodge() takes a g argument to specify the metric:

hodge(o)
hodge(o,g=c(-1,1,1,1))
hodge(o)-hodge(o,g=c(-1,1,1,1))
options(kform_symbolic_print = NULL)

References



Try the stokes package in your browser

Any scripts or data that you put into this service are public.

stokes documentation built on June 22, 2024, 11:56 a.m.