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