---
title: "Determinants using Clifford algebra"
author: "Robin K. S. Hankin"
output: html_vignette
bibliography: clifford.bib
link-citations: true
vignette: >
  %\VignetteIndexEntry{Determinants using Clifford algebra}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---


```{r out.width='20%', out.extra='style="float:right; padding:10px"',echo=FALSE}
knitr::include_graphics(system.file("help/figures/clifford.png", package = "clifford"))
```

To cite the `clifford` package in publications please use
@hankin2022_clifford.  This short document shows how determinants
can be calculated using Clifford algebra as implemented by the
`clifford` R package; notation follows @hestenes1987.  The methods
shown here are not computationally efficient compared with bespoke
linear algebra implementations (such as used in base R).

Given a square matrix $M$, we consider alternating forms on its column
vectors.  Requiring that the identity matrix map to $+1$ gives a
unique alternating form which we identify with the determinant of $M$.
Hestenes points out that wedge products of 1-vectors are alternating
forms and further points out [equation 4.1, p33] that any alternating
$r$-form $\alpha_r=\alpha_r\left(a_1,a_2,\ldots,a_r\right)$ can be
written in the form

$$\alpha_r\left(a_1,a_2,\ldots,a_r\right)=
A_r^\dagger\cdot\left(a_1\wedge a_2\wedge\cdots\wedge a_r\right)
$$

for some unique $r$-vector $A_r^\dagger$ .  We then define the
determinant to be the $r$-form corresponding to $A$ being the Clifford
$r$-volume element.  In the package this is easy to implement.
Considering a $3\times 3$ matrix as an example, we simply calculate
the wedge product of its columns:

```{r formalshow}
suppressMessages(library("clifford"))
set.seed(0)
(M <- matrix(rnorm(9),3,3))
o <- as.1vector(M[,1]) ^ as.1vector(M[,2]) ^ as.1vector(M[,3])
Adag <- rev(e(seq_len(3)))
c(drop(Adag %.% o), det(M))
```

Above, we see numerical agreement [as a parenthetical note, we observe
that the dagger is needed to get the correct sign if the dimension is
odd].  Alternatively, we can examine the wedge product directly:

```{r directwedge}
as.1vector(M[,1]) ^ as.1vector(M[,2]) ^ as.1vector(M[,3])
```		  

Note that the wedge product is given as a Clifford volume element.  We
can extract its coefficient (which would be the determinant of `M`)
using `coeffs()`:

```{r usecoeffs}
coeffs(as.1vector(M[,1]) ^ as.1vector(M[,2]) ^ as.1vector(M[,3]))
```

Just as a consistency check, we evaluate the wedge product of a set of
basis vectors, effectively calculating the determinant of $I_3$:

```{r detofi3}
coeffs(e(1) ^ e(2) ^ e(3))
```

We see $+1$, as expected.  It is possible to consider larger matrices:

```{r largermatrix}
cliff_det <- function(M){
  o <- as.1vector(M[,1])
  for(i in 2:nrow(M)){
    o <- o ^ as.1vector(M[,i])
  }
  return(coeffs(o))
}
```

Then

```{r usenewfunction}
M <- matrix(rnorm(100),10,10)
LHS <- det(M)
RHS <- cliff_det(M)
c(LHS,RHS,LHS-RHS)
```

above we see numerical agreement.

## References
