%&% and Methodsboolmatmult-methods.RdFor boolean or “pattern” matrices, i.e., R objects of
class nMatrix, it is natural to allow matrix
products using boolean instead of numerical arithmetic.
In package Matrix, we use the binary operator %&% (aka
“infix”) function) for this and provide methods for all our
matrices and the traditional R matrices (see matrix).
We provide methods for both the “traditional” (R base) matrices
and numeric vectors and conceptually all matrices and
sparseVectors in package Matrix.
signature(x = "ANY", y = "ANY")signature(x = "ANY", y = "Matrix")signature(x = "Matrix", y = "ANY")signature(x = "nMatrix", y = "nMatrix")signature(x = "nMatrix", y = "nsparseMatrix")signature(x = "nsparseMatrix", y = "nMatrix")signature(x = "nsparseMatrix", y = "nsparseMatrix")signature(x = "sparseVector", y = "sparseVector")These boolean arithmetic matrix products had been newly introduced for Matrix 1.2.0 (March 2015). Its implementation has still not been tested extensively.
Originally, it was left unspecified how non-structural zeros, i.e., 0's
as part of the M@x slot should be treated for numeric
("dMatrix") and logical ("lMatrix")
sparse matrices. We now specify that boolean matrix products should behave as if
applied to drop0(M), i.e., as if dropping such zeros from
the matrix before using it.
Equivalently, for all matrices M, boolean arithmetic should work as if
applied to M != 0 (or M != FALSE).
The current implementation ends up coercing both x and y to
(virtual) class nsparseMatrix which may be quite inefficient
for dense matrices. A future implementation may well return a matrix
with different class, but the “same” content, i.e., the
same matrix entries \(m_ij\).
%*%, crossprod(), or tcrossprod(),
for (regular) matrix product methods.
a pattern matrix, i.e., inheriting from "nMatrix",
or an "ldiMatrix" in case of a diagonal matrix.
set.seed(7)
L <- Matrix(rnorm(20) > 1, 4,5)
(N <- as(L, "nMatrix"))
#> 4 x 5 sparse Matrix of class "ngCMatrix"
#>
#> [1,] | . . | .
#> [2,] . . | . .
#> [3,] . . . | .
#> [4,] . . | . .
L. <- L; L.[1:2,1] <- TRUE; L.@x[1:2] <- FALSE; L. # has "zeros" to drop0()
#> 4 x 5 sparse Matrix of class "lgCMatrix"
#>
#> [1,] : . . | .
#> [2,] : . | . .
#> [3,] . . . | .
#> [4,] . . | . .
D <- Matrix(round(rnorm(30)), 5,6) # -> values in -1:1 (for this seed)
L %&% D
#> 4 x 6 sparse Matrix of class "ngCMatrix"
#>
#> [1,] | | | | | .
#> [2,] | | . | . |
#> [3,] | | . . | .
#> [4,] | | . | . |
stopifnot(identical(L %&% D, N %&% D),
all(L %&% D == as((L %*% abs(D)) > 0, "sparseMatrix")))
## cross products , possibly with boolArith = TRUE :
crossprod(N) # -> sparse patter'n' (TRUE/FALSE : boolean arithmetic)
#> 5 x 5 sparse Matrix of class "nsCMatrix"
#>
#> [1,] | . . | .
#> [2,] . . . . .
#> [3,] . . | . .
#> [4,] | . . | .
#> [5,] . . . . .
crossprod(N +0) # -> numeric Matrix (with same "pattern")
#> 5 x 5 sparse Matrix of class "dsCMatrix"
#>
#> [1,] 1 . . 1 .
#> [2,] . . . . .
#> [3,] . . 2 . .
#> [4,] 1 . . 2 .
#> [5,] . . . . .
stopifnot(all(crossprod(N) == t(N) %&% N),
identical(crossprod(N), crossprod(N +0, boolArith=TRUE)),
identical(crossprod(L), crossprod(N , boolArith=FALSE)))
crossprod(D, boolArith = TRUE) # pattern: "nsCMatrix"
#> 6 x 6 sparse Matrix of class "nsCMatrix"
#>
#> [1,] | | | | | |
#> [2,] | | | | | |
#> [3,] | | | | | |
#> [4,] | | | | | |
#> [5,] | | | | | |
#> [6,] | | | | | |
crossprod(L, boolArith = TRUE) # ditto
#> 5 x 5 sparse Matrix of class "nsCMatrix"
#>
#> [1,] | . . | .
#> [2,] . . . . .
#> [3,] . . | . .
#> [4,] | . . | .
#> [5,] . . . . .
crossprod(L, boolArith = FALSE) # numeric: "dsCMatrix"
#> 5 x 5 sparse Matrix of class "dsCMatrix"
#>
#> [1,] 1 . . 1 .
#> [2,] . . . . .
#> [3,] . . 2 . .
#> [4,] 1 . . 2 .
#> [5,] . . . . .