knitr::opts_chunk$set(echo = TRUE) options(rmarkdown.html_vignette.check_title = FALSE) library("evitaicossa") set.seed(1)
knitr::include_graphics(system.file("help/figures/evitaicossa.png", package = "evitaicossa"))
Here I introduce the evitaicossa
R package for antiassociative
algebras. An algebra is a vector space in which the vectors possess
a bilinear product. Formally, a vector space is a set $V$ of vectors
which form an Abelian group under addition and also satisfy the
following axioms:
Above, $\mathbf{u},\mathbf{v}\in V$ are vectors, $a,b$ are scalars [here the real numbers], and $1$ is the multiplicative identity. We also require a bilinear vector product, mapping pairs of vectors to vectors; vector multiplication is denoted using juxtaposition, as in $\mathbf{u}\mathbf{v}$, which satisfies the following axioms:
Note the absence of commutativity and associativity. Associative algebras seem to be the most common, and examples would include multivariate polynomials [@hankin2022_mvp,@hankin2022_spray], Clifford algebras [@hankin2022_clifford], Weyl algebras [@hankin2022_weyl_arxiv], and free algebras [@hankin2022_freealg]. Non-associative algebras would include the octonions [@hankin2006_onion] and Jordan algebras [@hankin2023_jordan]. Here I consider antiassociative algebras in which the usual associativity relation $\mathbf{u}(\mathbf{v}\mathbf{w})=(\mathbf{u}\mathbf{v})\mathbf{w}$ is replaced by the relation $\mathbf{u}(\mathbf{v}\mathbf{w})=-(\mathbf{u}\mathbf{v})\mathbf{w}$.
Algebras satisfying $\mathbf{u}(\mathbf{v}\mathbf{w})=-(\mathbf{u}\mathbf{v})\mathbf{w}$ exhibit some startling behaviour. Firstly, in the vector space there are no scalars except for $0\in\mathbb{R}$. Proof: for any $x\in\mathbb{R}$, we have $x^3=x(xx)=-(xx)x=-x^3$; thus $x^3=-x^3$, so $x=0$. Secondly, antiassociative algebras are nilpotent of order 4:
$$ (\mathbf{a}\mathbf{b})(\mathbf{c}\mathbf{d}) = -\mathbf{a}(\mathbf{b}(\mathbf{c}\mathbf{d})) = \mathbf{a}((\mathbf{b}\mathbf{c})\mathbf{d}) = -(\mathbf{a}(\mathbf{b}\mathbf{c}))\mathbf{d} = ((\mathbf{a}\mathbf{b})\mathbf{c})\mathbf{d} = -(\mathbf{a}\mathbf{b})(\mathbf{c}\mathbf{d}) $$
We see that $(\mathbf{a}\mathbf{b})(\mathbf{c}\mathbf{d})=-(\mathbf{a}\mathbf{b})(\mathbf{c}\mathbf{d})$ so $\mathbf{a}\mathbf{b}\mathbf{c}\mathbf{d}$ (however bracketed) must be zero.
We consider vector spaces generated by a finite alphabet of symbols $\mathbf{x}_1,\ldots,\mathbf{x}_n$. These will be denoted generally by a single letter, as in $\mathbf{a},\mathbf{b},\ldots,\mathbf{z}$. We now consider the algebra spanned by products of linear combinations of these symbols, subject only to the axioms of an algebra [and the antiassociative relation $\mathbf{u}(\mathbf{v}\mathbf{w})=-(\mathbf{u}\mathbf{v})\mathbf{w}$]. Given an alphabet $\mathbf{x}_1,\ldots,\mathbf{x}_n$, the general form of an element of an antiassociative algebra will be
$$ \sum_{i}\alpha_i\mathbf{x}i + \sum{i,j}\alpha_{ij}\mathbf{x}i\mathbf{x}_j+ \sum{i,j,k}\alpha_{ijk}(\mathbf{x}_i\mathbf{x}_j)\mathbf{x}_k $$
(see @remm2024antiassociative for a proof, but note that she uses $\mathbf{x}i(\mathbf{x}_j\mathbf{x}_k)$ rather than $(\mathbf{x}_i\mathbf{x}_j)\mathbf{x}_k$ for the triple products; a brief discussion is given in the appendix). In the package, the components of the first term $\sum{i}\alpha_i\mathbf{x}i$ are known as "single-symbol" terms [$\mathbf{x}_i$] and coefficients [$\alpha_i$] respectively. Similarly, the components of $\sum{i,j}\alpha_{ij}\mathbf{x}i\mathbf{x}_j$ are known as the "double-symbol" terms and coefficients; and the components of $\sum{i,j,k}\alpha_{ijk}(\mathbf{x}_i\mathbf{x}_j)\mathbf{x}_k$ are the "triple-symbol" terms and coefficients.
Addition is performed elementwise among the single-, double-, and triple- components; the result is the (formal) composition of the three results. Given
$$A= \sum_{i}\alpha_i\mathbf{x}i + \sum{i,j}\alpha_{ij}\mathbf{x}i\mathbf{x}_j+ \sum{i,j,k}\alpha_{ijk}(\mathbf{x}_i\mathbf{x}_j)\mathbf{x}_k $$
$$B= \sum_{i}\beta_i\mathbf{x}i + \sum{i,j}\beta_{ij}\mathbf{x}i\mathbf{x}_j+ \sum{i,j,k}\beta_{ijk}(\mathbf{x}_i\mathbf{x}_j)\mathbf{x}_k $$
(where the sums run from $1$ to $n$), we define the sum $A+B$ to be
$$ \sum_{i}(\alpha_i+\beta_i)\mathbf{x}i + \sum{i,j}(\alpha_{ij}+\beta_{ij})\mathbf{x}i\mathbf{x}_j+ \sum{i,j,k}(\alpha_{ijk}+\beta_{ijk})(\mathbf{x}_i\mathbf{x}_j)\mathbf{x}_k $$
Multiplication is slightly more involved. We define the product $AB$ to be
$$ \sum_{i,j}\alpha_i\beta_{ij}\mathbf{x}i\mathbf{x}_j +\sum{i,j,k}\alpha_{ij}\beta_{k}(\mathbf{x}i\mathbf{x}_j)\mathbf{x}_k -\sum{i,j,k}\alpha_i\beta_{jk}(\mathbf{x}_i\mathbf{x}_j)\mathbf{x}_k. $$
The minus sign in front of the third term embodies antiassociativity.
evitaicossa
packageThe evitaicossa
package implements these relations in the context of
an R-centric suite of software. I give some examples of the package
in use. A good place to start is function raaa()
, which returns a
simple random element of the free antiassociative algebra:
raaa()
(the default alphabet for this command is $\left\lbrace\mathbf{a},\mathbf{b},\mathbf{c},\mathbf{d}\right\rbrace$). We see the print method for the package which shows some of the structure of the object. This one has some single-symbol elements, some double-symbol and some triple-symbol elements.
It is possible to create elements using the aaa()
or as.aaa()
functions:
x <- as.aaa(c("p","q","r")) x1 <- aaa(s1 = c("p","r","x"),c(-1,5,6)) y <- aaa(d1 = letters[1:3],d2 = c("foo","bar","baz"),dc=1:3) z <- aaa( t1 = c("bar","bar","bar"), t2 = c("q","r","s"), t3 = c("foo","foo","bar"), tc = 5:7)
And then apply arithmetic operations to these objects:
x
x1
x+x1
(above, note the cancellation in x+x1
). Multiplication is also
implemented (package idiom is to use an asterisk *
):
x*(x1+y)
Check:
x*(x1+y) == x*x1 + x*y
We end with a remarkable identity:
$$ (\mathbf{a}+\mathbf{a}\mathbf{x})(\mathbf{b} + \mathbf{x}\mathbf{b})=\mathbf{a}\mathbf{b} $$
Numerically:
a <- raaa() b <- raaa() x <- raaa() (a+a*x)*(b+x*b) == a*b
Because of the tripartite nature of antiassociative algebra, the
package provides three families of extraction methods: single()
,
double()
and triple()
, which return the different components of an
object:
a single(a) double(a) triple(a)
The corresponding replacement methods are also implemented:
single(a) <- 0 a double(a) <- double(b) * 1000 a
Square bracket extraction and replacement is also implemented:
(a <- raaa(s=5)) a[s1=c("c","e"),t1="c",t2="d",t3="d"]
Above we pass named arguments (\code{s1} et seq.) and the
appropriate aaa
object is returned. Zero coeffients are discarded.
This mode also implements replacement methods:
(a <- raaa(s=5)) a[s1="a",d1=c("c","w"),d2=c("d","w")] <- 888 a
The other square bracket method is to pass an (unnamed) character vector:
(a <- raaa())
disordR
disciplineIf we try to access the symbols or coefficients of an aaa
object
[functions s1()
and sc()
respectively], we get a disord
object
[@hankin2022_disordR]. Suppose we wish to extract the single-symbol
terms and the single-symbol coefficients:
x s1(x) sc(x)
See how the hash codes of the symbols and coeffients match. However, the double-symbol terms and coefficients, while internally matching, differ from the single-symbol stuff:
list(d1(x),d2(x),dc(x))
Above, see how the double-symbol terms and double-symbol coefficients have consistent hashes, but do not match the single-symbol objects (or indeed the triple-symbol objects).
If square bracket extraction is given an index that is a matrix, it is interpreted rowwise:
l <- letters[1:3] (a <- aaa(s1=l,sc=1:3, d1=l,d2=rev(l),dc=3:1,t1=l,t2=l,t3=rev(l),tc=1:3)) a[cbind(l,l)] a[cbind(rev(l),l,l)] <- 88 a
We may generalize antiassociativity to $\mathbf{a}(\mathbf{b}\mathbf{c})=k(\mathbf{a}\mathbf{b})\mathbf{c}$. Thus associativity is recovered if $k=1$ and antiassociativity if $k=-1$. Then the nilpotence argument becomes:
$$ (\mathbf{a}\mathbf{b})(\mathbf{c}\mathbf{d}) = k^{-1}\mathbf{a}(\mathbf{b}(\mathbf{c}\mathbf{d})) = \mathbf{a}((\mathbf{b}\mathbf{c})\mathbf{d}) = k(\mathbf{a}(\mathbf{b}\mathbf{c}))\mathbf{d} = k^2((\mathbf{a}\mathbf{b})\mathbf{c})\mathbf{d} = k(\mathbf{a}\mathbf{b})(\mathbf{c}\mathbf{d}) $$
The value of $k$ may be set at compile-time by editing file
src/anti.h
. The line in question reads:
#define K -1 // a(bc) == K(ab)c
but it is possible to change the value of K
. Note that this will
cause test_aac.R
, one of the testthat
suite, to fail R CMD
check
.
As noted above, @remm2024antiassociative uses $\mathbf{x}_i(\mathbf{x}_j\mathbf{x}_k)$ rather than $(\mathbf{x}_i\mathbf{x}_j)\mathbf{x}_k$ for the triple products. I chose the latter because R idiom for multiplication is left associative:
x <- 3 class(x) <- "foo" `*.foo` <- function(x,y){x + y + x} print.foo <- function(x){print(unclass(x))} c(`(x*x)*x` = (x*x)*x, `x*(x*x)` = x*(x*x), `x*x*x` = x*x*x)
Above we see that x*x*x
is interpreted as (x*x)*x
, which is why
the sign convention in the package was adopted.
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.