Cramer's rule in civilised form with Clifford algebra
Robin K. S. Hankin
Source:vignettes/cramer_clifford.Rmd
cramer_clifford.Rmd
To cite the clifford
package in publications please use
Hankin (2022). This short document
shows a nice application of Clifford algebras to linear algebra. Suppose
we have vectors
where
Using Clifford algebra
Considering
which is Cramer’s rule expressed directly in vector form (rather than components). Observe that the numerator and denominator of each bracketed term is a pseudoscalar; the ratio of two pseudoscalars is an ordinary scalar. Package idiom is straightforward:
a <- as.1vector(runif(3))
b <- as.1vector(runif(3))
c <- as.1vector(runif(3))
(x <- as.1vector(1:3))
## Element of a Clifford algebra, equal to
## + 1e_1 + 2e_2 + 3e_3
options(maxdim = 3) # needed to drop() pseudoscalars
abc <- drop(a ^ b ^ c)
alpha <- drop(x ^ b ^ c)/abc
beta <- drop(a ^ x ^ c)/abc
gamma <- drop(a ^ b ^ x)/abc
c(alpha,beta,gamma)
## [1] -3.805997 -5.328439 8.309581
alpha*a + beta*b + gamma*c
## Element of a Clifford algebra, equal to
## + 1e_1 + 2e_2 + 3e_3
Mod(alpha*a + beta*b + gamma*c-x)
## [1] 0
Thus we have expressed
## [1] 1 2 3
Higher dimensional space
To accomplish this in arbitrary-dimensional space is straightforward.
Here we consider
n <- 5 # dimensionality of space
options(maxdim=5) # safety precaution
x <- as.1vector(seq_len(n)) # target vector
x
## Element of a Clifford algebra, equal to
## + 1e_1 + 2e_2 + 3e_3 + 4e_4 + 5e_5
L <- replicate(n,as.1vector(rnorm(n)),simplify=FALSE) # spanning vectors
subst <- function(L,n,x){L[[n]] <- x; return(L)} # list substitution
coeff <- function(n,L,x){
drop(Reduce(`^`,subst(L,n,x))/Reduce(`^`,L))
}
Then the coefficients are given by:
## [1] 21.610237 27.030973 11.866383 -22.222116 3.199427
and we can reconstitute vector
out <- as.clifford(0)
f <- function(i){alpha[i]*L[[i]]}
for(i in seq_len(n)){
out <- out + f(i)
}
Mod(out-x) # zero to numerical precision
## [1] 2.340649e-14
Or, somewhat slicker:
## Element of a Clifford algebra, equal to
## + 1e_1 + 2e_2 + 3e_3 + 4e_4 + 5e_5
Conversely, if we know the coefficients are, say, 15:11
,
then we would have
coeffs <- 15:11
x <- 0
for(i in seq_len(5)){x <- x + coeffs[i]*L[[i]]}
x
## Element of a Clifford algebra, equal to
## + 29.23618e_1 + 18.68409e_2 + 20.23065e_3 - 0.6361232e_4 - 40.82507e_5
And then to find the coefficients:
## [1] 15 14 13 12 11
Above we see that the original coefficients are recovered, up to numerical accuracy.