% -*- mode: noweb; noweb-default-code-mode: R-mode; -*- \documentclass[nojss]{jss} \usepackage{amsmath} \usepackage{amssymb} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% declarations for jss.cls %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% just as usual \author{Robin K. S. Hankin\\University of Stirling} \title{Clifford algebra in \proglang{R}} %\VignetteIndexEntry{The clifford package} %% for pretty printing and a nice hypersummary also set: \Plainauthor{Robin K. S. Hankin} \Plaintitle{The clifford package} \Shorttitle{The clifford package} %% an abstract and keywords \Abstract{Here I present the \pkg{clifford} package for working with Clifford algebras. The algebra is described and package idiom is given.} \Keywords{Clifford algebra} \Plainkeywords{Clifford algebra} %% publication information %% NOTE: This needs to filled out ONLY IF THE PAPER WAS ACCEPTED. %% If it was not (yet) accepted, leave them commented. %% \Volume{13} %% \Issue{9} %% \Month{September} %% \Year{2004} %% \Submitdate{2004-09-29} %% \Acceptdate{2004-09-29} %% \Repository{https://github.com/RobinHankin/lorentz} %% this line for Tragula %% The address of (at least) one author should be given %% in the following format: \Address{ Robin K. S. Hankin\\%\orcid{https://orcid.org/0000-0001-5982-0415}\\ University of Stirling\\ E-mail: \email{hankin.robin@gmail.com} } %% It is also possible to add a telephone and fax number %% before the e-mail in the following format: %% Telephone: +43/1/31336-5053 %% Fax: +43/1/31336-734 %% for those who use Sweave please include the following line (with % symbols): %% need no \usepackage{Sweave.sty} %% end of declarations %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \SweaveOpts{} \begin{document} <>= library("clifford") @ \hfill\includegraphics[width=1in]{\Sexpr{system.file("help/figures/clifford.png",package="clifford")}} \section{Introduction} This document gives an introduction to the \pkg{clifford} package from an R perspective. A more theoretical and cursive description is given by~\cite{hankin2022_clifford}. Clifford algebras are interesting and instructive mathematical objects. The class has a rich structure with varied applications to physics. Notation follows~\cite{snygg2010}. \subsection{Existing work} Computational support for working with the Clifford algebras is part of a number of algebra systems including Sage~\citep{sagemath2019} and \proglang{sympy}~\citep{sympy2017}. Here I introduce the \pkg{clifford} package, which provides R-centric functionality for Clifford algebras. \newcommand{\ei}[1]{\ensuremath{{\bf e}_{#1}}} \newcommand{\bx}{\ensuremath{{\bf x}}} \newcommand{\by}{\ensuremath{{\bf y}}} Considering a vector space of dimension 3, and given a basis $\ei{1},\ei{2},\ei{3}$, we can consider linear combinations such as \begin{eqnarray} \bx = x^1\ei{1} + x^2\ei{2} + x^3\ei{3}\nonumber\\ \by = y^1\ei{1} + y^2\ei{2} + y^3\ei{3}. \end{eqnarray} A Clifford algebra includes a formal product on such sums, defined using the relations \begin{eqnarray}\label{square} \left(\ei{1}\right)^2= \left(\ei{2}\right)^2= \left(\ei{3}\right)^2=1\\ \ei{2}\ei{3} + \ei{3}\ei{2} = \label{sumprod} \ei{1}\ei{3} + \ei{3}\ei{1} = \ei{2}\ei{1} + \ei{1}\ei{2} = 0 \end{eqnarray} This gives: \begin{eqnarray} \bx\by &=& \left(x^1\ei{1} + x^2\ei{2} + x^3\ei{3}\right) \left(y^1\ei{1} + y^2\ei{2} + y^3\ei{3}\right)\nonumber\\ &=& \left(x^1y^1+x^2y^2+x^3y^3\right) +\nonumber\\&& \left(x^2y^3-x^3y^2\right)\ei{2}\ei{3} + \left(x^3y^1-x^1y^3\right)\ei{1}\ei{3} + \left(x^1y^2-x^2y^1\right)\ei{1}\ei{2} \end{eqnarray} Multiplication is associative by design. \citeauthor{snygg2010} goes on to consider the algebra spanned by products of $\ei{1},\ei{2},\ei{3}$ and shows that this is an eight dimensional space spanned by \begin{equation} \left\{ 1,\ei{1},\ei{2},\ei{3},\ei{12},\ei{31},\ei{12},\ei{123} \right\} \end{equation} where $\ei{12}=\ei{1}\ei{2}$ and so on. Thus a general element of this space would be \begin{equation} a^0+ a^1\ei{1} + a^2\ei{2} + a^3\ei{3} + a^{12}\ei{12} + a^{31}\ei{31} + a^{23}\ei{23} + a^{123}\ei{123} \end{equation} (here the $a$'s are real). That the space is closed under multiplication follows from equations~\ref{square} and~\ref{sumprod}; thus, for example, \begin{equation} \ei{1}\ei{3}\ei{1}\ei{2}= -\ei{1}\ei{1}\ei{3}\ei{2}= -\ei{3}\ei{2}= \ei{2}\ei{3}=\ei{23}. \end{equation} (observe how associativity is assumed). \subsection{Generalization to arbitrary dimensions} Generalization to higher dimensional vector spaces is easy. Suppose we consider a $n$-dimensional vector space spanned by $\ei{1},\ldots,\ei{n}$. Then an arbitrary vector in this space will be $a^1\ei{1}+\cdots+a^n\ei{n}$. The associated Clifford algebra will be of dimension $2^n$, spanned by elements like $\ei{1}\ei{3}\ei{5}=\ei{135}$ and $\ei{1}\ei{2}\ei{3}\ei{5}=\ei{1235}$. The defining relations would be \begin{equation}\label{posdefcliff} \ei{i}\ei{j}+\ei{j}\ei{i}=2n_{ij} \end{equation} where \begin{equation}\label{posdefcliff2} n_{ij} = \begin{cases} 1, & i=j\\ 0 &i\neq j \end{cases} \end{equation} \subsection{Clifford algebra in a pseudo-Euclidean space} Equations~\ref{posdefcliff} and~\ref{posdefcliff2} defined a positive-definite inner product on the vector space spanned by~$\ei{1},\ei{2},\ei{3}$. This is readily generalized to allow a more general inner product. Conventionally we define \begin{equation}\label{gencliff1} \ei{i}\ei{j}+\ei{j}\ei{i}=2n_{ij} \end{equation} where \begin{equation}\label{gencliff2} n_{ij} = \begin{cases} 1, & i=j=1,\ldots,p\\ -1, & i=j=p+1,\ldots,n\\ 0, &i\neq j \end{cases} \end{equation} for $1\leqslant p\leqslant n$; usually we also specify $p+q=n$ and write $\mathbb{R}_{p,q}$ for the $p+q$-dimensional vector space with inner product given by equation~\ref{gencliff1}. The Clifford algebra ${\mathcal C}_{p,q}$ (other notations include $Cl(p,q)$) is then the algebra formed by $\mathbb{R}_{p,q}$ together with formal products of basis vectors. Note carefully that the diagonal matrix of the inner product specified above conventionally has the the positive elements first, followed by the negative elements. But in relativity, the metric tensor $\eta$ is usually written with the negative elements first followed by the positive elements; \begin{equation}\eta= \begin{bmatrix} -1&0&0&0\\ 0&1&0&0\\ 0&0&1&0\\ 0&0&0&1\\ \end{bmatrix} \end{equation} \subsection{Wedge product of the exterior algebra is a special case of the geometric product} If we specify that the quadratic form is identically zero then equation \ref{gencliff1} becomes \begin{equation}\label{specwedge} \ei{i}\ei{j}+\ei{j}\ei{i}=0,\qquad 1\leqslant i,j\leqslant p \end{equation} which implies that $\ei{i}\ei{i}=0$. Geometric products become wedge products (although linearity means that we may add terms of different grades, unlike conventional Grassmann algebra). \section{The package in use} Suppose we want to work with arbitrary Clifford object $1+2\ei{1}+3\ei{2}+4\ei{2}\ei{3}$. In R idiom this would be <>= (x <- clifford(list(numeric(0),1,2,2:3),1:4)) @ Function \code{clifford()} takes a list of terms and a vector of coefficients. Addition and subtraction work as expected: <>= y <- clifford(list(1),2) x-y @ In the above, see how the $\ei{1}$ term has vanished. We can multiply Clifford elements using natural R idiom: <>= x*x @ (Multiplication that Snygg denotes by juxtaposition is here indicated with a \code{*}). We can consider arbitrarily high dimensional data: <>= (z <- as.1vector(1:7)) z*x @ In the above, we coerce a vector to a Clifford 1-vector. The package includes many functions to generate Clifford objects: <>= rcliff() @ The defaults for \code{rcliff()} specify that the object is a sum of grade-4 terms but this can be altered: <>= (x <- rcliff(d=7,g=5,include.fewer=TRUE)) grades(x) @ \section{Pseudo-Euclidean spaces} The signature of the metric may be altered. Starting with the Euclidean case we have: <>= e1 <- e(1) e2 <- e(2) e1*e1 e2*e2 @ (function \code{e(i)} returns $\ei{i}$). However, if we wish to consider $n=\begin{bmatrix}1&0\\0&-1\end{bmatrix}$, the package idiom is to use the \code{signature()} function: <>= signature(1,1) # signature +- e1*e1 # as before, returns +1 e2*e2 # should return -1 @ Suppose we wish to use a signature $+++-$, corresponding to the Minkowski metric in special relativity; this would be indicated in package idiom by \code{signature(3,1)}. Note that the clifford objects themselves do not store the signature; it is used only by the product operation \code{*}. <>= x <- rcliff(d=4,g=3,include.fewer=TRUE) y <- rcliff(d=4,g=3,include.fewer=TRUE) @ Then we may multiply these two clifford objects using either the default positive-definite inner product, or the Minkowski metric: <>= x*y signature(3,1) # switch to signature +++- x*y @ In the above, see how the products are different using the two inner products. \section{Grassmann algebra} A Grassmann algebra corresponds to a Clifford algebra with identically zero inner product. Package idiom is to use a zero signature: <>= signature(0,0) # specify null inner product <>= e(5)^2 == 0 # cannot use is.zero() here because the jordan package masks clifford::is.zero() @ This is a somewhat clunky way of reproducing the functionality of the \pkg{stokes} package. If we have <>= x <- clifford(list(1:3, c(2,3,7)), coeffs=3:4) y <- clifford(list(1:3, c(1,4,5), c(4,5,6)), coeffs=1:3) x %^% y @ then the \pkg{stokes} idiom for this would be: \begin{Schunk} \begin{Sinput} > (x <- as.kform(rbind(1:3,c(2,3,7)),3:4)) \end{Sinput} \begin{Soutput} val 2 3 7 = 4 1 2 3 = 3 \end{Soutput} \begin{Sinput} > (y <- as.kform(rbind(1:3,c(1,4,5),4:6),1:3)) \end{Sinput} \begin{Soutput} val 1 2 3 = 1 1 4 5 = 2 4 5 6 = 3 \end{Soutput} \begin{Sinput} > x %^% y \end{Sinput} \begin{Soutput} val 1 2 3 4 5 6 = 9 2 3 4 5 6 7 = -12 1 2 3 4 5 7 = -8 \end{Soutput} \end{Schunk} \section{Positive-definite inner product} Function \code{signature()} takes an infinite argument to make the inner product positive-definite: <>= signature(Inf) @ (internally the package sets the signature to \code{.Machine$integer.max}, a near-infinite integer). With this, $\ei{i}\ei{i}=+1$ for any $i$: <<>>= e(53)^2 @ \section{Left and right contractions} \cite{dorst2002} defines the left contraction $A\rfloor B$ and right contraction $A\lfloor B$ (\cite{chisholm2012} calls these left and right inner products) as follows: \begin{eqnarray} \displaystyle A\rfloor B = \sum_{r,s}\left\langle\left\langle A\right\rangle_r\left\langle B\right\rangle_s\right\rangle_{s-r}\\ \displaystyle A\lfloor B = \sum_{r,s}\left\langle\left\langle A\right\rangle_r\left\langle B\right\rangle_s\right\rangle_{r-s} \end{eqnarray} Package idiom for these would be \code{A\%_|\%B} and \code{A\%|_\%B} ---or \code{lefttick(A,B)} and \code{righttick(A,B)}---respectively. Thus: <<>>= (A <- rcliff()) (B <- rcliff()) A %_|% B A %|_% B @ One thing to be wary of is the order of operations. Thus $\ei{2}\rfloor\ei{12}=-\ei{1}$ (in a positive-definite space) but <<>>= e(2) %_|% e(1)*e(2) @ because this is parsed as $(\ei{2}\rfloor\ei{1})\ei{2}=0\ei{2}=0$. To evaluate this as intended we need to include brackets: <<>>= e(2) %_|% (e(1)*e(2)) @ although in this case it might be preferable to create the terms directly: <<>>= e(2) %_|% e(1:2) @ \subsection{Numerical verification of left and right inner product identities} Chisholm gives a number of identities for these products including \begin{eqnarray} A\rfloor(B\lfloor C) &=& (A\rfloor B)\lfloor C\\ A\rfloor(B\rfloor C) &=& (A\wedge B)\rfloor C\\ A\lfloor(B\wedge C) &=& (A\lfloor B)\lfloor C \end{eqnarray} In package idiom: <<>>= A <- rcliff(); B <- rcliff(); C <- rcliff() A %_|% (B %|_% C) == (A %_|% B) %|_% C A %_|% (B %_|% C) == (A %^% B) %_|% C A %|_% (B %^% C) == (A %|_% B) %|_% C @ \section{Higher dimensional spaces} \cite{ablamowicz2012} consider high-dimensional Clifford algebras and consider the following two elements of the 1024-dimensional Clifford algebra which we may treat as ${\mathcal C}_{7,3}$ spanned by $\ei{1},\ldots,\ei{10}$ and perform a calculation which I reproduce below (although \citeauthor{ablamowicz2012} exploited Bott periodicity, a feature not considered here). Firstly we change the default print method slightly: <>= options("basissep" = ",") @ (this separates the subscripts of the basis vectors with a comma, which is useful for clarity if $n>9$). We then define clifford elements $x,y$: <>= (x <- clifford(list(1:3,c(1,5,7,8,10)),c(4,-10)) + 2) (y <- clifford(list(c(1,2,3,7),c(1,5,6,8),c(1,4,6,7)),c(4,1,-3)) - 1) @ Their geometric product is given in the package as <>= signature(7) x*y @ in agreement with \cite{ablamowicz2012}, although the terms appear in a different order. \section{Conclusions and further work} The \pkg{clifford} package furnishes a consistent and documented suite of reasonably efficient \proglang{R}-centric functionality. Further work might include closer integration with the \code{stokes} package~\citep{hankin2022_stokes}. \bibliography{clifford} \end{document}