The `spray`

package provides functionality for sparse
arrays.

In a sparse arrays, nonzero elements are stored along with an index
vector describing their coordinates. The `spray`

package
provides functionality for sparse arrays and interprets them as
multivariate polynomials.

You can install the released version of `spray`

from CRAN with:

```
# install.packages("spray") # uncomment this to install the package
library("spray")
```

`spray`

package in
useBase R has extensive support for multidimensional arrays. Consider

```
<- array(0,dim=4:12)
a 2,2,2,2,2,2,2,2,2] <- 17
a[3,4,2,2,7,2,3,2,3] <- 18 a[
```

Handling `a`

requires storage of

```
library("spray")
<- rbind(
M c(2,2,2,2,2,2,2,2,2),
c(3,4,2,2,7,2,3,2,3))
<- spray(M,7:8)
S1
S1#> val
#> 2 2 2 2 2 2 2 2 2 = 7
#> 3 4 2 2 7 2 3 2 3 = 8
```

Note that object `S1`

is rather compact by comparison with
plain array `a`

, as it needs to record only a 18-element
index array of integers and two double-precision entries. The order in
which the elements are stored is implementation-specific (see the
vignette for details and an extended discussion).

Basic arithmetic is implemented where appropriate. If we define

```
<-spray(rbind(
S2 c(1,2,3,1,3,3,1,4,1),
c(3,4,2,2,7,2,3,2,3)), c(100,-8))
S2#> val
#> 1 2 3 1 3 3 1 4 1 = 100
#> 3 4 2 2 7 2 3 2 3 = -8
```

then

```
+S2
S1#> val
#> 2 2 2 2 2 2 2 2 2 = 7
#> 1 2 3 1 3 3 1 4 1 = 100
```

(the entry with value `8`

has cancelled out).

One natural application for `spray`

objects is
multivariate polynomials. Defining

```
<- spray(matrix(c(0,0,0,1,0,0,1,1,1,2,0,3),ncol=3),1:4)
S1 <- spray(matrix(c(6,-7,8,0,0,2,1,1,3),byrow=TRUE,ncol=3),c(17,11,-4))
S2
S1#> val
#> 0 0 1 = 1
#> 0 1 0 = 3
#> 0 0 2 = 2
#> 1 1 3 = 4
S2#> val
#> 6 -7 8 = 17
#> 0 0 2 = 11
#> 1 1 3 = -4
```

it is natural to interpret the rows of the index matrix as powers of
different variables of a multivariate polynomial, and the values as
being the coefficients. This is realised in the package using the
`polyform`

print option, which if set to `TRUE`

,
modifies the print method:

```
options(polyform = TRUE)
S1#> +z +3*y +2*z^2 +4*x*y*z^3
S2#> +17*x^6*y^-7*z^8 +11*z^2 -4*x*y*z^3
```

(only the print method has changed; the objects themselves are unaltered). The print method interprets, by default, the three columns as variables

```
+S2
S1#> +z +3*y +13*z^2 +17*x^6*y^-7*z^8
*S2
S1#> -16*x^2*y^2*z^6 -12*x*y^2*z^3 +17*x^6*y^-7*z^9 +68*x^7*y^-6*z^11
#> +34*x^6*y^-7*z^10 +22*z^4 +36*x*y*z^5 +33*y*z^2 +51*x^6*y^-6*z^8
#> -4*x*y*z^4 +11*z^3
^2+4*S2
S1#> +4*z^3 -16*x*y*z^3 +45*z^2 +6*y*z +12*y*z^2 +24*x*y^2*z^3 +9*y^2
#> +16*x^2*y^2*z^6 +4*z^4 +8*x*y*z^4 +16*x*y*z^5 +68*x^6*y^-7*z^8
```

It is possible to introduce an element of symbolic calculation,
exhibiting familiar algebraic identities. Consider the
`lone()`

function, which creates a sparse array whose
multivariate polynomial interpretation is a single variable:

```
<- lone(1, 3)
x <- lone(2, 3)
y <- lone(3, 3)
z + y) * (y + z) * (x + z) - (x + y + z) * (x*y + x*z + y*z)
(x #> -x*y*z
```

thus illustrating the identity

Spray objects can be coerced to functions:

```
<- spray(cbind(1:3, 3:1), 1:3)
S4 <- as.function(S4)
f f(c(1, 2))
#> X
#> 22
```

Differentiation is also straightforward. Suppose we wish to calculate the multivariate polynomial corresponding to

[ \frac{\partial^6}{\partial x\,\partial^{2y\,\partial}3z}
\left(xyz +
x+2y+3z\right)^3.](https://latex.codecogs.com/png.latex?%0A%5Cfrac%7B%5Cpartial%5E6%7D%7B%5Cpartial%20x%5C%2C%5Cpartial%5E2y%5C%2C%5Cpartial%5E3z%7D%0A%5Cleft%28xyz%20%2B%20x%2B2y%2B3z%5Cright%29%5E3.%0A
” (xyz + x+2y+3z)^3. “)

This would be

```
aderiv((xyz(3) + linear(1:3))^3, 1:3)
#> +216*x +108*x^2*y
```

The package vignette offers a detailed discussion of the package
design philosophy; also, the `mvp`

package provides a further
interpretation of the concept of “sparse” in the context of multivariate
polynomials.