--- title: "Function `dovs()` function in the `stokes` package" author: "Robin K. S. Hankin" output: html_vignette bibliography: stokes.bib link-citations: true vignette: > %\VignetteEngine{knitr::rmarkdown} %\VignetteIndexEntry{dovs} %\usepackage[utf8]{inputenc} --- ```{r setup, include=FALSE} set.seed(0) library("stokes") options(rmarkdown.html_vignette.check_title = 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=showAlt,comment=""} dovs ``` To cite the `stokes` package in publications, please use @hankin2022_stokes. Function `dovs()` returns the dimensionality of the underlying vector space of a $k$-form. Recall that a $k$-form is an alternating linear map from $V^k$ to $\mathbb{R}$, where $V=\mathbb{R}^n$ [@spivak1965]. Function `dovs()` returns $n$ [compare `arity()`, which returns $k$]. As seen above, the function is very simple, essentially being `max(index(K))`, but its use is not entirely straightforward in the context of `stokes` idiom. Consider the following: ```{r showrform} set.seed(0) a <- rform(n=4,k=2) a ``` Now object `a` is notionally a map from $\left(\mathbb{R}^4\right)^2$ to $\mathbb{R}$: ```{r coerceatofunction} f <- as.function(a) (M <- matrix(1:8,4,2)) f(M) ``` However, `a` can equally be considered to be a map from $\left(\mathbb{R}^5\right)^2$ to $\mathbb{R}$: ```{r evaluatef} f <- as.function(a) (M <- matrix(c(1,2,3,4,1454,5,6,7,8,-9564),ncol=2)) # row 5 large numbers f(M) ``` If we view $a$ [or indeed `f()`] in this way, that is $a\colon\left(\mathbb{R}^5\right)^2\longrightarrow\mathbb{R}$, we observe that row 5 is ignored: $e_5=\left(0,0,0,0,1\right)^T$ maps to zero in the sense that $f(e_5,\mathbf{v})=f(\mathbf{v},e_5)=0$, for any $\mathbf{v}\in\mathbb{R}^5$. ```{r fonM} (M <- cbind(c(0,0,0,0,1),runif(5))) f(M) ``` (above we see that rows 1-4 of `M` are ignored because of the zero in column 1; row 5 is ignored because the index of `a` does not include the number 5). Because `a` is alternating, we could have put $e_5$ in the second column with the same result. Alternatively we see that the $k$-form `a`, evaluated with $e_5$ as one of its arguments, returns zero because the index matrix of `a` does not include the number 5. Most of the time, this kind of consideration does not matter. However, consider this: ```{r dxalone} dx ``` Now, _we_ know that `dx` is supposed to be a map from $\left(\mathbb{R}^3\right)^1$ to $\mathbb{R}$; but: ```{r dovsdx} dovs(dx) ``` So according to `stokes`, $\operatorname{dx}\colon\left(\mathbb{R}^1\right)^1\longrightarrow\mathbb{R}$. This does not really matter numerically, until we consider the Hodge star operator. We know that $\star\operatorname{dx}=\operatorname{dy}\wedge\operatorname{dz}$, but ```{r hodgedx} hodge(dx) ``` Above we see the package giving, correctly, that the Hodge star of $\operatorname{dx}$ is the zero-dimensional volume element (otherwise known as "1"). To get the answer appropriate if $\operatorname{dx}$ is considered as a map from $\left(\mathbb{R}^3\right)^1$ to $\mathbb{R}$ [that is, $\operatorname{dx}\colon\left(\mathbb{R}^3\right)^1\longrightarrow\mathbb{R}$], we need to specify `dovs` explicitly: ```{r hodgedx3} hodge(dx,3) ``` Actually this looks a lot better with a more appropriate print method: ```{r hodgeoptions} options(kform_symbolic_print="dx") hodge(dx,3) ``` ```{r reset_default_print_method, include=FALSE} options(kform_symbolic_print = NULL) ``` # References