
Thespray package provides functionality for sparsearrays.
In a sparse arrays, nonzero elements are stored along with an indexvector describing their coordinates. Thespray packageprovides functionality for sparse arrays and interprets them asmultivariate polynomials.
You can install the released version ofspray fromCRAN with:
# install.packages("spray") # uncomment this to install the packagelibrary("spray")spray package inuseBase R has extensive support for multidimensional arrays.Consider
a<-array(0,dim=4:12)a[2,2,2,2,2,2,2,2,2]<-17a[3,4,2,2,7,2,3,2,3]<-18Handlinga requires storage ofspray package, one specifies a matrix of indices with eachrow corresponding to the position of a nonzero element, and a numericvector of values:
library("spray")M<-rbind(c(2,2,2,2,2,2,2,2,2),c(3,4,2,2,7,2,3,2,3))S1<-spray(M,7:8)S1#> val#> 3 4 2 2 7 2 3 2 3 = 8#> 2 2 2 2 2 2 2 2 2 = 7Note that objectS1 is rather compact by comparison withplain arraya, as it needs to record only a 18-elementindex array of integers and two double-precision entries. The order inwhich the elements are stored is implementation-specific (see thevignette for details and an extended discussion).
Basic arithmetic is implemented where appropriate. If we define
S2<-spray(rbind(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#> 3 4 2 2 7 2 3 2 3 = -8#> 1 2 3 1 3 3 1 4 1 = 100then
S1+S2#> val#> 2 2 2 2 2 2 2 2 2 = 7#> 1 2 3 1 3 3 1 4 1 = 100(the entry with value8 has cancelled out).
One natural application forspray objects ismultivariate polynomials. Defining
S1<-spray(matrix(c(0,0,0,1,0,0,1,1,1,2,0,3),ncol=3),1:4)S2<-spray(matrix(c(6,-7,8,0,0,2,1,1,3),byrow=TRUE,ncol=3),c(17,11,-4))S1#> val#> 1 1 3 = 4#> 0 0 2 = 2#> 0 1 0 = 3#> 0 0 1 = 1S2#> val#> 1 1 3 = -4#> 0 0 2 = 11#> 6 -7 8 = 17it is natural to interpret the rows of the index matrix as powers ofdifferent variables of a multivariate polynomial, and the values asbeing the coefficients. This is realised in the package using thepolyform print option, which if set toTRUE,modifies the print method:
options(polyform =TRUE)S1#> +4*x*y*z^3 +2*z^2 +3*y +zS2#> -4*x*y*z^3 +11*z^2 +17*x^6*y^-7*z^8(only the print method has changed; the objects themselves areunaltered). The print method interprets, by default, the three columnsas variables although this behaviour is user-definable. With thisinterpretation, multiplication and addition have natural definitions asmultivariate polynomial multiplication and addition:
S1+S2#> +13*z^2 +3*y +z +17*x^6*y^-7*z^8S1*S2#> +17*x^6*y^-7*z^9 +11*z^3 +51*x^6*y^-6*z^8 +34*x^6*y^-7*z^10 -4*x*y*z^4#> +33*y*z^2 -12*x*y^2*z^3 +22*z^4 +36*x*y*z^5 +68*x^7*y^-6*z^11#> -16*x^2*y^2*z^6S1^2+4*S2#> +8*x*y*z^4 +9*y^2 +68*x^6*y^-7*z^8 +24*x*y^2*z^3 -16*x*y*z^3#> +16*x*y*z^5 +45*z^2 +16*x^2*y^2*z^6 +4*z^3 +12*y*z^2 +4*z^4 +6*y*zIt is possible to introduce an element of symbolic calculation,exhibiting familiar algebraic identities. Consider thelone() function, which creates a sparse array whosemultivariate polynomial interpretation is a single variable:
x<-lone(1,3)y<-lone(2,3)z<-lone(3,3)(x+ y)* (y+ z)* (x+ z)- (x+ y+ z)* (x*y+ x*z+ y*z)#> -x*y*zthus illustrating the identity
Spray objects can be coerced to functions:
S4<-spray(cbind(1:3,3:1),1:3)f<-as.function(S4)f(c(1,2))#> X#> 22Differentiation is also straightforward. Suppose we wish to calculatethe multivariate polynomial corresponding to
This would be
aderiv((xyz(3)+linear(1:3))^3,1:3)#> +216*x +108*x^2*yThe package vignette offers a detailed discussion of the packagedesign philosophy; also, themvp package provides a furtherinterpretation of the concept of “sparse” in the context of multivariatepolynomials.