---
title: "Quaternions are a special case of Clifford algebra"
output: html_document
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
library("clifford")
library("onion")
```

<p style="text-align: right;">
![](`r system.file("help/figures/clifford.png", package = "clifford")`){width=10%}
</p>

The Broome Bridge insight:

\[
\mathbf{i}^2=
\mathbf{j}^2=
\mathbf{k}^2=
\mathbf{i}\mathbf{j}\mathbf{k}=-1
\]

The BBI and associativity together imply

\[
\mathbf{j}\mathbf{k}=-\mathbf{k}\mathbf{j}=\mathbf{i}\qquad
\mathbf{k}\mathbf{i}=-\mathbf{i}\mathbf{k}=\mathbf{j}\qquad
\mathbf{i}\mathbf{j}=-\mathbf{j}\mathbf{i}=\mathbf{k}\qquad
\]

and if we require a distributive algebra we get the quaternions.  A
general quaternion is of the form
$a+\mathbf{i}b+\mathbf{j}c+\mathbf{k}d$; addition is componentwise and
multiplication follows from the above.

To express quaternionic multiplication using Clifford algebra we
identify $\mathbb{H}$ with $Cl(3,0)$ [technically we do not need to
call `signature()` but it is probably defensive programming to call it
anyway]

```{r}
signature(3,0)
```

\[
\mathbf{i}\leftrightarrow -e_{12}\\
\mathbf{j}\leftrightarrow -e_{13}\\
\mathbf{k}\leftrightarrow -e_{23}\\
\]

Thus, for example,
$\mathbf{ii}=(-e_{12})(-e_{12})=+e_{1212}=-e_{1122}=-1$ and
$\mathbf{ij}=(-e_{12})(-e_{13})=+e_{1213}=-e_{1123}=-e_{23}=\mathbf{k}$.

Conversion functions would be

```{r definecoercion}
`clifford_to_quaternion` <- function(C){
    C <- as.clifford(C)
    tC <- disordR::elements(terms(C))
    stopifnot(all(c(tC,recursive=TRUE) <= 3))
    jj <- unlist(lapply(tC,length))
    stopifnot(all(jj <= 2))
    stopifnot(all(jj%%2 == 0))
    out <- matrix(c(const(C), -getcoeffs(C,list(c(1,2),c(1,3),c(2,3)) )))
    as.quaternion(out)
}

`quaternion_to_clifford` <- function(Q){
  Q <- as.numeric(Q)
  stopifnot(length(Q)==4)
  clifford(list(numeric(0),c(1,2),c(1,3),c(2,3)),c(Q[1],-Q[2:4]))
}
```

We might wish to multiply $q_1=1+2\mathbf{i}+3\mathbf{j}+4\mathbf{k}$
by $q_2=-2+\mathbf{i}-2\mathbf{j}+\mathbf{k}$:
  

```{r}
q1 <- +1 + 2* -e(c(1,2)) + 3*-e(c(1,3)) + 4*-e(c(2,3))
q1
q2 <- -2 + 1* -e(c(1,2)) - 2*-e(c(1,3)) + 1*-e(c(2,3))
q2
q1*q2
```

The product would correspond to $-2+8\mathbf{i} -6\mathbf{j}
-14\mathbf{k}$.  However, it is possible to coerce a Clifford object
to a quaternion, and then use the `onion` package to carry out
quaternion multiplication directly (but don't actually do it, you
crazy fool):

```{r}
library(onion)
q1*q2 == quaternion_to_clifford(clifford_to_quaternion(q1)*clifford_to_quaternion(q2))
```

Note that in package idiom the asterisk, "`*`" represents Clifford
geometric product on the left hand side, and Hamilton's quaternionic
multiplication on the right hand side.


## Alternative mapping

Alternatively we might consider the even subalgebra of $Cl(0,3)$ with
general element $q_0 + q_1e_{23} -q_2e_{13} + q_3e_{12}$ (note change
of sign for $q_2$).  Thus

\[
\mathbf{i}\leftrightarrow e_{23}\\
\mathbf{j}\leftrightarrow -e_{13}\\
\mathbf{k}\leftrightarrow e_{12}\\
\]


A quick-and-dirty R function might be


```{r}
signature(0,3)
cliff2quat <- function(C){
  out <- getcoeffs(C,list(numeric(0),c(2,3),c(1,3),c(1,2)))
  out[2] <- -out[2]
  as.quaternion(out,single=TRUE)
}

quat2cliff <- function(H){
  jj <- c(as.matrix(H))
  jj[2] <- -jj[2]
  clifford(list(numeric(0),c(2,3),c(1,3),c(1,2)),jj)
}
```

Then:

```{r}
cliff2quat(q1*q2) == cliff2quat(q1) * cliff2quat(q2)
```

(note that the multiplication `*` is Clifford product on the left but
quaternionic product on the right).  We should go the other way too:

```{r}
Ha <- as.quaternion(c(7,-3,2,44),single=TRUE)
Hb <- as.quaternion(c(-3,13,0,4),single=TRUE)
quat2cliff(Ha*Hb) == quat2cliff(Ha)*quat2cliff(Hb)
```