evitaicossa
packageHere 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 Hankin (2022e), Clifford algebras (Hankin 2022a), Weyl algebras (Hankin 2022d), and free algebras (Hankin 2022f). Non-associative algebras would include the octonions (Hankin 2006) and Jordan algebras (Hankin 2023). 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 Remm (2024) 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:
## free antiassociative algebra element:
## +1a +1c +2d +1b.c +1c.b +1c.c +2(b.a)a +1(b.b)c +1(b.c)a
(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:
## free antiassociative algebra element:
## +1p +1q +1r
## free antiassociative algebra element:
## -1p +5r +6x
## free antiassociative algebra element:
## +1q +6r +6x
(above, note the cancellation in x+x1
). Multiplication
is also implemented (package idiom is to use an asterisk
*
):
## free antiassociative algebra element:
## -1p.p +5p.r +6p.x -1q.p +5q.r +6q.x -1r.p +5r.r +6r.x -1(p.a)foo -2(p.b)bar
## -3(p.c)baz -1(q.a)foo -2(q.b)bar -3(q.c)baz -1(r.a)foo -2(r.b)bar -3(r.c)baz
Check:
## [1] TRUE
We end with a remarkable identity:
\[ (\mathbf{a}+\mathbf{a}\mathbf{x})(\mathbf{b} + \mathbf{x}\mathbf{b})=\mathbf{a}\mathbf{b} \]
Numerically:
## [1] TRUE
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:
## free antiassociative algebra element:
## +4a +1b +2a.b +2c.c +2d.d +1(c.d)a +4(d.b)c +4(d.d)b
## free antiassociative algebra element:
## +4a +1b
## free antiassociative algebra element:
## +2a.b +2c.c +2d.d
## free antiassociative algebra element:
## +1(c.d)a +4(d.b)c +4(d.d)b
The corresponding replacement methods are also implemented:
## free antiassociative algebra element:
## +2a.b +2c.c +2d.d +1(c.d)a +4(d.b)c +4(d.d)b
## free antiassociative algebra element:
## +2000b.b +1000b.d +2000c.d +1(c.d)a +4(d.b)c +4(d.d)b
Square bracket extraction and replacement is also implemented:
## free antiassociative algebra element:
## +4a +9c +3b.c +1b.d +2c.b +3d.a +2d.c +2(a.d)d +3(b.a)a +3(b.c)d +1(c.d)d
## +3(d.c)b
## free antiassociative algebra element:
## +9c +1(c.d)d
Above we pass named arguments ( et seq.) and the appropriate
aaa
object is returned. Zero coeffients are discarded. This
mode also implements replacement methods:
## free antiassociative algebra element:
## +8a +3b +1a.b +3b.c +4c.c +4c.d +2(a.c)c +4(b.c)a +4(b.c)d +4(c.a)c +1(c.d)d
## free antiassociative algebra element:
## +888a +3b +1a.b +3b.c +4c.c +888c.d +888w.w +2(a.c)c +4(b.c)a +4(b.c)d +4(c.a)c
## +1(c.d)d
The other square bracket method is to pass an (unnamed) character vector:
## free antiassociative algebra element:
## +1a +2c +2d +3b.a +3b.b +3c.c +2(a.d)d +2(b.c)a +4(c.d)b
disordR
disciplineIf we try to access the symbols or coefficients of an
aaa
object [functions s1()
and
sc()
respectively], we get a disord
object
(Hankin 2022b). Suppose we wish to extract
the single-symbol terms and the single-symbol coefficients:
## free antiassociative algebra element:
## +5c +1d +3a.c +4d.a +1d.b +1(a.a)d +2(b.d)a +3(d.d)a
## A disord object with hash 059117d244e1291a3c3e4e94c5ad5bbc0ed7c254 and elements
## [1] "c" "d"
## (in some order)
## A disord object with hash 059117d244e1291a3c3e4e94c5ad5bbc0ed7c254 and elements
## [1] 5 1
## (in some order)
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:
## [[1]]
## A disord object with hash c3d0273c48d84843b58af77622164b0c0a319848 and elements
## [1] "a" "d" "d"
## (in some order)
##
## [[2]]
## A disord object with hash c3d0273c48d84843b58af77622164b0c0a319848 and elements
## [1] "c" "a" "b"
## (in some order)
##
## [[3]]
## A disord object with hash c3d0273c48d84843b58af77622164b0c0a319848 and elements
## [1] 3 4 1
## (in some order)
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:
## free antiassociative algebra element:
## +1a +2b +3c +3a.c +2b.b +1c.a +1(a.a)c +2(b.b)b +3(c.c)a
## free antiassociative algebra element:
## +2b.b
## free antiassociative algebra element:
## +1a +2b +3c +3a.c +2b.b +1c.a +1(a.a)c +88(a.c)c +88(b.b)b +88(c.a)a +3(c.c)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, Remm (2024) 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)
## (x*x)*x x*(x*x) x*x*x
## 21 15 21
Above we see that x*x*x
is interpreted as
(x*x)*x
, which is why the sign convention in the package
was adopted.
disordR
Package.” https://arxiv.org/abs/2210.03856; arXiv. https://doi.org/10.48550/ARXIV.2210.03856.
mvp
Package.” arXiv. https://doi.org/10.48550/ARXIV.2210.15991.
spray
Package.” https://arxiv.org/abs/2210.03856; arXiv. https://doi.org/10.48550/ARXIV.2210.10848.