library("testthat") library("Matrix") library("MatrixExtra") library("float") context("Matrix multiplications") set_new_matrix_behavior() options("MatrixExtra.nthreads" = 1) ### TODO: add tests about the names of objects test_that("matmult dense-CSC", { set.seed(1) A <- rsparsematrix(100, 50, .4) B <- rsparsematrix(50, 20, .4) A1 <- rsparsematrix(1, 50, .4) B1 <- rsparsematrix(50, 1, .4) expect_equal(as.matrix(A) %*% as.csc.matrix(B), as.matrix(A) %*% as.matrix(B)) expect_equal(float::dbl(float::fl(as.matrix(A)) %*% as.csc.matrix(B)), as.matrix(A) %*% as.matrix(B), tolerance=1e-5) expect_s4_class(float::fl(as.matrix(A)) %*% as.csc.matrix(B), "float32") expect_equal(as.matrix(A1) %*% as.csc.matrix(B), as.matrix(A1) %*% as.matrix(B)) expect_equal(as.matrix(A) %*% as.csc.matrix(B1), as.matrix(A) %*% as.matrix(B1)) expect_equal(as.matrix(A1) %*% as.csc.matrix(B1), as.matrix(A1) %*% as.matrix(B1)) expect_equal(as.matrix(A) %*% as.csc.matrix(B, binary=TRUE), as.matrix(A) %*% as.matrix(as.csc.matrix(B, binary=TRUE))) expect_equal(as.matrix(A) %*% as.csc.matrix(B, logical=TRUE), as.matrix(A) %*% as.matrix(as.csc.matrix(B, logical=TRUE))) sy <- sparseMatrix(i= c(2,4,3:5), j= c(4,7:5,5), x = 1:5, dims = c(7,7), symmetric=TRUE, dimnames = list(NULL, letters[1:7])) expect_s4_class(sy, "dsCMatrix") set.seed(1) sy_counterpart <- rsparsematrix(20, nrow(sy), .4) sy_counterpart <- as.matrix(sy_counterpart) expect_equal(sy_counterpart %*% sy, sy_counterpart %*% as.matrix(sy)) tri <- matrix(c(1,2,0,4, 0,0,6,7, 0,0,8,9, 0,0,0,0), byrow=TRUE, nrow=4) tri <- as(tri, "triangularMatrix") tri <- as(tri, "CsparseMatrix") expect_s4_class(tri, "dtCMatrix") set.seed(1) tri_counterpart <- rsparsematrix(20, nrow(tri), .4) tri_counterpart <- as.matrix(tri_counterpart) expect_equal(tri_counterpart %*% tri, tri_counterpart %*% as.matrix(tri)) }) test_that("tcrossprod dense-CSR", { set.seed(1) A <- rsparsematrix(100, 50, .4) B <- rsparsematrix(20, 50, .4) A1 <- rsparsematrix(1, 50, .4) B1 <- rsparsematrix(1, 50, .4) expect_equal(tcrossprod(as.matrix(A), as.csr.matrix(B)), tcrossprod(as.matrix(A), as.matrix(as.csr.matrix(B)))) expect_equal(float::dbl(tcrossprod(float::fl(as.matrix(A)), as.csr.matrix(B))), tcrossprod(as.matrix(A), as.matrix(as.csr.matrix(B))), tolerance=1e-5) expect_s4_class(tcrossprod(float::fl(as.matrix(A)), as.csr.matrix(B)), "float32") expect_equal(tcrossprod(as.matrix(A1), as.csr.matrix(B)), tcrossprod(as.matrix(A1), as.matrix(as.csr.matrix(B)))) expect_equal(tcrossprod(as.matrix(A), as.csr.matrix(B1)), tcrossprod(as.matrix(A), as.matrix(as.csr.matrix(B1)))) expect_equal(tcrossprod(as.matrix(A1), as.csr.matrix(B1)), tcrossprod(as.matrix(A1), as.matrix(as.csr.matrix(B1)))) sy <- sparseMatrix(i= c(2,4,3:5), j= c(4,7:5,5), x = 1:5, dims = c(7,7), symmetric=TRUE, dimnames = list(NULL, letters[1:7])) sy <- as(sy, "RsparseMatrix") expect_s4_class(sy, "dsRMatrix") set.seed(1) sy_counterpart <- rsparsematrix(20, nrow(sy), .4) sy_counterpart <- as.matrix(sy_counterpart) expect_equal(tcrossprod(sy_counterpart, sy), tcrossprod(sy_counterpart, as.matrix(sy))) tri <- matrix(c(1,2,0,4, 0,0,6,7, 0,0,8,9, 0,0,0,0), byrow=TRUE, nrow=4) tri <- as(tri, "triangularMatrix") tri <- as(tri, "RsparseMatrix") expect_s4_class(tri, "dtRMatrix") set.seed(1) tri_counterpart <- rsparsematrix(20, nrow(tri), .4) tri_counterpart <- as.matrix(tri_counterpart) expect_equal(tcrossprod(tri_counterpart, tri), tcrossprod(tri_counterpart, as.matrix(tri))) }) test_that("crossprod dense-CSC", { set.seed(1) A <- rsparsematrix(50, 100, .4) B <- rsparsematrix(50, 20, .4) expect_equal(crossprod(as.matrix(A), as.csc.matrix(B)), crossprod(as.matrix(A), as.matrix(B)), tolerance=1e-3) }) test_that("matmult CSR-dense", { set.seed(1) A <- rsparsematrix(100, 50, .4) B <- rsparsematrix(50, 20, .4) expect_equal(as.csr.matrix(A) %*% as.matrix(B), as.matrix(A) %*% as.matrix(B)) }) test_that("tcrossprod CSR-dense", { set.seed(1) A <- rsparsematrix(100, 50, .4) B <- rsparsematrix(20, 50, .4) expect_equal(tcrossprod(as.csr.matrix(A), as.matrix(B)), tcrossprod(as.matrix(A), as.matrix(B))) }) test_that("tcrossprod dense-CSR", { set.seed(1) A <- rsparsematrix(100, 50, .4) B <- rsparsematrix(20, 50, .4) expect_equal(tcrossprod(as.matrix(A), as.csr.matrix(B)), tcrossprod(as.matrix(A), as.matrix(B))) }) test_that("matmult CSR-vector", { set.seed(1) A <- rsparsematrix(100, 50, .4) v <- rnorm(50) dvec <- as(v, "dsparseVector") ivec <- as(dvec, "isparseVector") lvec <- as(dvec, "lsparseVector") nvec <- as(dvec, "nsparseVector") num <- as.numeric(v) int <- as.integer(num) bool <- as.logical(num) lst_inputs <- list( dvec, ivec, lvec, nvec, num, int, bool ) for (inp in lst_inputs) { expect_equal(as.csr.matrix(A) %*% inp, as.matrix(A) %*% as.numeric(inp)) expect_equal(unname(as.matrix(as.csr.matrix(A[,1,drop=FALSE]) %*% inp)), unname(as.matrix(A[,1,drop=FALSE]) %*% as.numeric(inp))) expect_equal(unname(as.matrix(as.csr.matrix(A[1:10,1,drop=FALSE]) %*% inp)), unname(as.matrix(A[1:10,1,drop=FALSE]) %*% as.numeric(inp))) } # v[4] <- NA_real_ # A <- as.csr.matrix(A) # A@x[10] <- NA_real_ # expect_equal(A %*% v, unname(as.matrix(as.matrix(A) %*% v))) }) test_that("float32 vectors", { set.seed(1) A <- rsparsematrix(100, 50, .4) v <- float::fl(rnorm(100)) v2 <- float::fl(rnorm(50)) expect_equal(float::dbl(v %*% A), float::dbl(v) %*% as.matrix(A), tolerance=1e-5) ### sparse CSC expect_equal(unname(as.matrix(v2 %*% as.csc.matrix(A[1,,drop=FALSE]))), float::dbl(v2) %*% as.matrix(A)[1,,drop=FALSE], tolerance=1e-5) ### sparse CSC expect_equal(unname(as.matrix(v2 %*% as.csc.matrix(A[1,1:10,drop=FALSE]))), float::dbl(v2) %*% as.matrix(A)[1,1:10,drop=FALSE], tolerance=1e-5) expect_equal(float::dbl(tcrossprod(v2, as.csr.matrix(A))), tcrossprod(float::dbl(v2), as.matrix(A)), tolerance=1e-5) expect_equal(float::dbl(tcrossprod(v2, as.csr.matrix(A[1:10,]))), tcrossprod(float::dbl(v2), as.matrix(A)[1:10,]), tolerance=1e-5) ### sparse CSC expect_equal(unname(as.matrix(tcrossprod(v, as.csr.matrix(A[,1,drop=FALSE])))), tcrossprod(float::dbl(v), as.matrix(A[,1,drop=FALSE])), tolerance=1e-5) ### sparse CSC expect_equal(unname(as.matrix(tcrossprod(v, as.csr.matrix(A[1:10,1,drop=FALSE])))), tcrossprod(float::dbl(v), as.matrix(A[1:10,1,drop=FALSE])), tolerance=1e-5) expect_equal(float::dbl(crossprod(v, as.csc.matrix(A))), crossprod(float::dbl(v), as.matrix(A)), tolerance=1e-5) expect_equal(float::dbl(crossprod(v, as.csc.matrix(A[,1:10,drop=FALSE]))), crossprod(float::dbl(v), as.matrix(A)[,1:10,drop=FALSE]), tolerance=1e-5) expect_equal(float::dbl(as.csr.matrix(A) %*% v2), as.matrix(A) %*% float::dbl(v2), tolerance=1e-5) # sparse CSR expect_equal(unname(as.matrix(as.csr.matrix(A[,1,drop=FALSE]) %*% v2)), as.matrix(A[,1,drop=FALSE]) %*% float::dbl(v2), tolerance=1e-5) # sparse CSR expect_equal(unname(as.matrix(as.csr.matrix(A[1:10,1,drop=FALSE]) %*% v2)), as.matrix(A[1:10,1,drop=FALSE]) %*% float::dbl(v2), tolerance=1e-5) }) set_new_matrix_behavior()