Create, coerce, and test for sparse array objects

```
spray(M, x, addrepeats=FALSE)
spraymaker(L, addrepeats=FALSE, arity=ncol(L[[1]]))
is.spray(S)
as.spray(arg1, arg2, addrepeats=FALSE, offbyone=FALSE)
index(S)
value(S)
value(S) <- value
is_valid_spray(L)
```

M

Integer matrix with rows corresponding to index positions

x

Numeric value with elements corresponding to spray entries

S

Object to be tested for being a spray

L

A list, nominally of two elements (index matrix and value) which is to be tested for acceptability to be coerce to class spray

arg1,arg2

Various arguments to be coerced to a spray

addrepeats

Boolean, with default `FALSE`

meaning to check
for repeated index rows and, if any are found, return an error

value

In the assignment operator ``value<-()``

, a scalar so
that `value(S) <- x`

works as expected

offbyone

In function `as.spray()`

, when converting from an
array. Argument `offbyone`

is Boolean with default
`FALSE`

meaning to insert array elements in positions
corresponding to index elements, and `TRUE`

meaning to add
one

arity

In function `spraymaker()`

, integer specifying the
arity (number of columns of the index matrix `L[[1]]`

); ignored
if `L`

is non-empty. See details

The user should use `spray()`

, if a matrix of indices and vector
of values is available, or `as.spray()`

which tries hard to
do the Right Thing (tm).

Function `spraymaker()`

is the formal creator function, and it is
written to take the output of the C++ routines and return a spray
object. The reason this needs an `arity`

argument is that C++
sometimes returns `NULL`

(in lieu of a zero-row matrix, which it
cannot deal with). In this case, we need some way to tell R the arity
of the corresponding spray object.

Functions `index()`

and `value()`

are accessor methods.

# NOT RUN { S <- spray(diag(5)) # missing second argument interpreted as '1'. as.array(S,offbyone=TRUE) # zero indices interpreted as ones. M <- matrix(1:5,6,5) # note first row matches the sixth row # } # NOT RUN { spray(M,1:6) # } # NOT RUN { # will not work because addrepeats is not TRUE spray(M,1:6,addrepeats=TRUE) # 7=1:6 S <- spray(matrix(1:7,5,7)) a <- as.array(S) # will not work if any(M<1) S1 <- as.spray(a) stopifnot(S==S1) # }