In mathematics, the Einstein notation or Einstein summation convention is a notational convention that implies summation over a set of repeated indices. When an index variable appears twice, it implies summation over all the values of the index1. For instance the matrix product can be written in terms of Einstein notation as:
\[C_{ij} = A_{ik}{B_{kj}}\equiv\sum_k A_{ik}{B_{kj}}\]
The function einstein
provides a convenient way to compute general Einstein summations among
two or more tensors, with or without repeated indices appearing in the
same tensor. The function supports both numerical and symbolical
calculations implemented via the usage of C++
templates
that operate with generic types and allow the function to work on the
different data types without being rewritten for each one.
\[ C_{i,k} = A_{i,j} B_{j,k} \]
a <- array(letters[1:6], dim = c(i=2, j=3))
b <- array(letters[1:3], dim = c(j=3, k=1))
einstein(a, b)
#> [,1]
#> [1,] "(a) * (a) + (c) * (b) + (e) * (c)"
#> [2,] "(b) * (a) + (d) * (b) + (f) * (c)"
The indices can also be set on the fly with the function index
a <- array(letters[1:6], dim = c(2, 3))
b <- array(letters[1:3], dim = c(3, 1))
index(a) <- c("i", "j")
index(b) <- c("j", "k")
einstein(a, b)
#> [,1]
#> [1,] "(a) * (a) + (c) * (b) + (e) * (c)"
#> [2,] "(b) * (a) + (d) * (b) + (f) * (c)"
\[D_{jk}=A_{ij}B_{ki}C_{ii}\]
a <- array(1:6, dim = c(i = 2, j = 3))
b <- array(1:4, dim = c(k = 2, i = 2))
c <- array(letters[1:4], dim = c(i = 2, i = 2))
einstein(a, b, c)
#> [,1] [,2]
#> [1,] "1 * (a) + 6 * (d)" "2 * (a) + 8 * (d)"
#> [2,] "3 * (a) + 12 * (d)" "6 * (a) + 16 * (d)"
#> [3,] "5 * (a) + 18 * (d)" "10 * (a) + 24 * (d)"
Guidotti E (2022). “calculus: High-Dimensional Numerical and Symbolic Calculus in R.” Journal of Statistical Software, 104(5), 1-37. doi:10.18637/jss.v104.i05
A BibTeX entry for LaTeX users is
@Article{calculus,
title = {{calculus}: High-Dimensional Numerical and Symbolic Calculus in {R}},
author = {Emanuele Guidotti},
journal = {Journal of Statistical Software},
year = {2022},
volume = {104},
number = {5},
pages = {1--37},
doi = {10.18637/jss.v104.i05},
}