Rev 4500 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed
#### Currently a collection of simple tests## (since 'Matrix' takes long to load, rather have fewer source files!)library(Matrix)source(system.file("test-tools.R", package = "Matrix"))# identical3() etc### Matrix() ''smartness''(d4 <- Matrix(diag(4)))(z4 <- Matrix(0*diag(4)))(o4 <- Matrix(1+diag(4)))(tr <- Matrix(cbind(1,0:1)))(m4 <- Matrix(cbind(0,rbind(6*diag(3),0))))dm4 <- Matrix(m4, sparse = FALSE)class(mN <- Matrix(NA, 3,4)) # NA *is* logicalstopifnot(validObject(d4), validObject(z4), validObject(o4),validObject(m4), validObject(dm4), validObject(mN))assert.EQ.mat(dm4, as(m4, "matrix"))assert.EQ.mat(mN, matrix(NA, 3,4))sL <- Matrix(, 3,4, sparse=TRUE)# -> "lgC"trS <- Matrix(tr, sparse=TRUE)# failed in 0.9975-11stopifnot(is(tr, "triangularMatrix"), is(trS, "triangularMatrix"),all(is.na(sL@x)), ## not yet: all(is.na(sL)),!any(sL, na.rm=TRUE), all(!sL, na.rm=TRUE),validObject(Matrix(c(NA,0), 4, 3, byrow = TRUE)),validObject(Matrix(c(NA,0), 4, 4)),is(Matrix(c(NA,0,0,0), 4, 4), "sparseMatrix"))## large sparse ones: these now directly "go sparse":str(m0 <- Matrix(0, nrow=100, ncol = 1000))str(l0 <- Matrix(FALSE, nrow=100, ncol = 200))stopifnot(all(!l0),identical(FALSE, any(l0)))## with dimnames:m. <- matrix(c(0, 0, 2:0), 3, 5)dimnames(m.) <- list(LETTERS[1:3], letters[1:5])(m0 <- m <- Matrix(m.))m@Dimnames[[2]] <- m@Dimnames[[1]]## not valid anymore:(val <- validObject(m, test=TRUE))stopifnot(is.character(val))rm(m)###-- Sparse Triangular :(t1 <- new("dtTMatrix", x= c(3,7), i= 0:1, j=3:2,Dim= as.integer(c(4,4))))stopifnot(validObject(t1),validObject(t1c <- as(t1, "dtCMatrix")))assert.EQ.mat(t1, as(t1c, "matrix"))## from 0-diagonal to unit-diagonal {low-level step}:tu <- t1 ; tu@diag <- "U"tucu <- as(tu, "dtCMatrix")stopifnot(validObject(cu), validObject(tu. <- as(cu, "dtTMatrix")),validObject(tt <- as(cu, "TsparseMatrix")),## NOT: identical(tu, tu.), # since T* is not unique!identical(cu, as(tu., "dtCMatrix")),all(cu >= 0, na.rm = TRUE), all(cu >= 0),any(cu >= 7),validObject(tcu <- t(cu)),validObject(ttu <- t(tu)))assert.EQ.mat(cu, as(tu,"matrix"), tol=0)## <sparse> o <numeric> (of length > 1):stopifnot(is(tm <- tu * 1:8, "sparseMatrix"),identical4(tm, cu * 1:8, 1:8 * cu, 1:8 * tu))cu[1,2] <- tu[1,2] <- NAmu <- as(tu,"matrix")stopifnot(is(cu, "CsparseMatrix"), is(cu, "triangularMatrix"),is(tu, "TsparseMatrix"), is(tu, "triangularMatrix"),identical(cu * 1:8, tu * 1:8), # but are no longer triangularall(cu >= 0, na.rm=TRUE), !all(cu >= 1), is.na(all(tu >= 0)))assert.EQ.mat(cu * 1:8, mu * 1:8)## tu. is diag "U", but tu2 not:tu2 <- as(as(tu., "dgTMatrix"), "dtTMatrix")assert.EQ.mat(cu, mu, tol=0)stopifnot(identical3(cu[cu > 1], tu [tu > 1], mu [mu > 1]),identical3(cu <= 1, tu <= 1, as(mu <= 1, "lMatrix")),# all lgeMatrixidentical3(cu[cu <= 1], tu[tu <= 1], mu[mu <= 1]),identical3(cu , triu(cu ), t(t(cu))),identical3(tu , triu(tu ), t(t(tu))),identical3(tu., triu(tu.), t(t(tu.))),identical(tu2, triu(tu2)),identical(tcu , tril(tcu)),identical(ttu , tril(ttu)),identical(t(tu), tril(t(tu))))(t4 <- new("dgTMatrix", i = 3:0, j = 0:3, x = rep(1,4), Dim = as.integer(c(4,4))))c4 <- as(t4, "CsparseMatrix")## the same but "dsT" (symmetric)M <- Matrix(c(0, rep(c(0,0:1),4)), 4,4)#ok warningtt <- as(M, "TsparseMatrix")stopifnot(all.equal(triu(t4) + tril(t4), c4),all.equal(triu(tt) + tril(tt), c4))###-- Numeric Dense: Crossprod & Solveset.seed(123)mm. <- mm <- Matrix(rnorm(500 * 150), nc = 150)stopifnot(validObject(mm))xpx <- crossprod(mm)stopifnot(identical(mm, mm.),# once upon a time, mm was altered by crossprod()validObject(xpx))str(mm) # 'dge*"str(xpx)# 'dpo*"xpy <- crossprod(mm, rnorm(500))res <- solve(xpx, xpy)str(xpx)# now with Cholesky factorstopifnot(validObject(xpx),validObject(xpy),validObject(res))stopifnot(all.equal(xpx %*% res, xpy, tol= 1e-12))lp <- xpx >= 1slp <- as(lp, "sparseMatrix")ltlp <- lp[ lower.tri(lp) ]if(FALSE) # this particular indexing fails (FIXME, not urgent)sltlp <- slp[ lower.tri(slp) ]ij <- which(lower.tri(lp), arr.ind = TRUE)if(FALSE) {## FIXME!!! This "[.]" is *HORRENDOUSLY* slow (but "works"):ss <- slp[ij]stopifnot(identical(ss, lp[ij]))}stopifnot(identical3(lp[ij], ltlp, as(lp, "matrix")[ij]))stopifnot(is(lp, "lsyMatrix"), lp@uplo == "U")###-- more solve() methods {was ./solve.R }## first for "dgeMatrix" and all kinds of RHS :(m6 <- 1 + as(diag(0:5), "dgeMatrix"))rcond(m6)I6 <- as(diag(6), "dgeMatrix")stopifnot(all.equal(I6, m6 %*% solve(m6)),all.equal(I6, solve(m6) %*% m6) )(i6 <- solve(m6, Matrix(1:6)))stopifnot(identical(i6, as(cbind(c(-4, rep(1,5))), "dgeMatrix")),identical(i6, solve(m6, 1:6)),identical(i6, solve(m6, matrix(1:6))),identical(i6, solve(m6, matrix(c(1,2,3,4,5,6)))))## solve(<sparse>)(m <- t1+ t(t1) + Diagonal(4))i.m <- solve(as.mat(m))I1 <- m %*% i.mo4 <- diag(I1)im <- solve(m)(I2 <- m %*% im)(ms <- as(m, "dsCMatrix"))## solve(<sparse>, <sparse>):s.mm <- solve(m,m)s.mms <- solve(m, ms)## these now work "fully-sparse"s.ms2 <- solve(ms, ms)s.msm <- solve(ms, m)I4c <- as(Matrix(diag(4),sparse=TRUE), "dgCMatrix")stopifnot(is(im, "Matrix"), is(I2, "Matrix"),all.equal(I1, I2, tol = 1e-14),all.equal(diag(4), as.mat(I2), tol = 1e-12),all.equal(s.mm, I2, tol = 1e-14),all.equal(s.mms, I2, tol = 1e-14),all.equal(s.ms2, s.msm, tol = 4e-15),all.equal(s.ms2, I4c , tol = 4e-15),abs(o4 - 1) < 1e-14)###-- row- and column operations {was ./rowcolOps.R }set.seed(321)(m1 <- round(Matrix(rnorm(25), 5), 2))m1k <- Matrix(round(rnorm(1000), 2), 50, 20)m.m <- as(m1k, "matrix")stopifnot(all.equal(colMeans(m1k), colMeans(m.m)),all.equal(colSums (m1k), colSums (m.m)),all.equal(rowMeans(m1k), rowMeans(m.m)),all.equal(rowSums (m1k), rowSums (m.m)))###-- kronecker for nonsparse uses Matrix(.):stopifnot(is(kr <- kronecker(m1, m6), "Matrix"))assert.EQ.mat(kr,kronecker(as(m1, "matrix"),as(m6, "matrix")), tol = 0)## sparse:(kt1 <- kronecker(t1, tu))kt2 <- kronecker(t1c, cu)stopifnot(identical(Matrix:::uniq(kt1), Matrix:::uniq(kt2)))## but kt1 and kt2, both "dgT" are different since entries are not ordered!ktf <- kronecker(as.matrix(t1), as.matrix(tu))if(FALSE) # FIXME? our kronecker treats "0 * NA" as "0" for structural-0assert.EQ.mat(kt2, ktf, tol= 0)(cs1 <- colSums(kt1))NA.or.True <- function(x) is.na(x) | xeq <- (cs1 == colSums(as(kt1, "matrix")))stopifnot(NA.or.True(eq), identical(is.na(eq), is.na(cs1)))nt1 <- as(kt1, "nMatrix") # no NA's anymore(ng1 <- as(as(nt1, "generalMatrix"),"CsparseMatrix")) # ngCdg1 <- as(ng1, "dMatrix")# dgClt1 <- kt1 > 5nt1 <- as(lt1, "nMatrix")(colSums(nt1, sparseResult = TRUE))(colSums(kt1, sparseResult = TRUE)) # dsparse, with NA(colSums(lt1, sparseResult = TRUE)) # isparse, with NA(colSums(lt1, sparseResult = TRUE, na.rm = TRUE))(colSums(nt1, sparseResult = TRUE)) # isparse, no NA## check correct sparseness of both:for(M in list(kt1, nt1, ng1, dg1, lt1, nt1)) {m <- as(M, "matrix")for(na.rm in c(FALSE,TRUE)) {cs <- colSums(M, na.rm = na.rm)cs. <- colSums(M, na.rm = na.rm, sparseResult = TRUE)rs <- rowSums(M, na.rm = na.rm)rs. <- rowSums(M, na.rm = na.rm, sparseResult = TRUE)stopifnot(identical(cs, as(cs., "vector")),identical(rs, as(rs., "vector")),{eq <- cs == colSums(m, na.rm = na.rm) ; ineq <- is.na(eq)all(ineq | eq) && identical(ineq, is.na(cs)) },{eq <- rs == rowSums(m, na.rm = na.rm) ; ineq <- is.na(eq)all(ineq | eq) && identical(ineq, is.na(rs)) },is(cs., "sparseVector"),is(rs., "sparseVector"))}}## coercion from "dpo" or "dsy"xx <- as(xpx, "dsyMatrix")stopifnot(isSymmetric(xxS <- as(xx, "sparseMatrix")),isSymmetric(xpxS <- as(xpx, "sparseMatrix")))tm <- matrix(0, 8,8)tm[cbind(c(1,1,2,7,8),c(3,6,4,8,8))] <- c(2,-30,15,20,80)(tM <- Matrix(tm)) ## dtC(mM <- Matrix(m <- (tm + t(tm)))) ## dsCmT <- as(mM, "dsTMatrix")gC <- as(as(mT, "dgTMatrix"), "dgCMatrix")## Check that 'mT' and gC print properly :pr.mT <- capture.output(mT)nn <- unlist(strsplit(gsub(" +\\.", "", sub("^....", "", pr.mT[-(1:2)])), " "))stopifnot(as.numeric(nn[nn != ""]) == m[m != 0],capture.output(gC)[-1] == pr.mT[-1])assert.EQ.mat(tM, tm, tol=0)assert.EQ.mat(gC, m, tol=0)assert.EQ.mat(mT, m, tol=0)stopifnot(is(mM, "dsCMatrix"), is(tM, "dtCMatrix"), identical(mT, as(mM, "TsparseMatrix")), identical(gC, as(mM, "generalMatrix"))## coercions general <-> symmetric, identical(as(as(mM, "dgCMatrix"), "dsCMatrix"), mM), identical(as(as(mM, "dgTMatrix"), "dsTMatrix"), mT), identical(as(as(tM, "dgCMatrix"), "dtCMatrix"), tM))eM <- eigen(mM) # works thanks to base::as.matrix hack in ../R/zzz.Rstopifnot(all.equal(eM$values,{ v <- c(162.462112512353, 30.0665927567458)c(v, 15, 0, 0, 160-v[1], -15, -v[2])}, tol=1e-14))##--- symmetric -> pos.def. needs valid test:m5 <- Matrix(diag(5) - 1)if(FALSE) { # FIXME: this as(.,.) happily "works"assertError(mpo <- as(m5, "dpoMatrix"))validObject(mpo) # FIXME? it is *not* really pos.definite!}###-- dense nonzero pattern:class(m <- Matrix(TRUE,2,2)) # lsy(n <- as(m, "nMatrix")) # nsyvalidObject(n)## 1)as(n,"CsparseMatrix") # used to give CHOLMOD error: invalid xtype...ls2 <- as(m, "CsparseMatrix") # works fine## and really 'm' and 'n' are interally slot identical (!!!)as(n,"sparseMatrix")as(m,"sparseMatrix")### -- now when starting with nsparse :nT <- new("ngTMatrix",i = as.integer(c(0, 1, 0)),j = as.integer(c(0, 0, 1)), Dim = as.integer(c(2,2)),Dimnames = list(NULL, NULL))(nC <- as(nT, "ngCMatrix"))str(nC)# of course, no 'x' slotstopifnot(identical(tt <- as(nT,"denseMatrix"), # lgeas(as(nT, "lMatrix"),"denseMatrix")))ttas(nC,"denseMatrix")###-- sparse nonzero pattern : ----------(nkt <- as(as(as(kt1, "generalMatrix"), "CsparseMatrix"), "ngCMatrix"))# okdkt <- as(nkt, "denseMatrix")(clt <- crossprod(nkt))stopifnot(is(nkt, "ngCMatrix"), is(clt, "nsCMatrix"))crossprod(clt) ## a warning: crossprod() of symmetric## a Csparse with *repeated* entry is not valid!assertError(new("ngCMatrix", p = c(0L,2L), i = c(0L,0L), Dim = 2:1))### "d" <-> "l" for (symmetric) sparse :data(KNex)mm <- KNex$mmxpx <- crossprod(mm)## extract nonzero patternnxpx <- as(xpx, "nsCMatrix")if(FALSE)show(nxpx) ## gives error about "nsC" -> "ngT" coercion ..## The bug is actually from *subsetting* the large matrix:if(FALSE) ## FIXMEr <- nxpx[1:2,]lmm <- as(mm, "lgCMatrix")nmm <- as(lmm, "nMatrix")xlx <- crossprod(lmm)x.x <- crossprod(nmm)## now A = lxpx and B = xlx should be close, but not quite the same## since <x,y> = 0 is well possible when x!=0 and y!=0 .## However, A[i,j] != 0 ==> B[i,j] != 0:A <- as(as(nxpx, "lMatrix"), "TsparseMatrix")B <- as(as(xlx, "lMatrix"), "TsparseMatrix")ij <- function(a) a@i + ncol(a) * a@jstopifnot(all(ij(A) %in% ij(B)))l3 <- upper.tri(matrix(,3,3))(c3 <- as(l3, "CsparseMatrix"))stopifnot(validObject(c3), is(c3, "CsparseMatrix"), is(c3, "triangularMatrix"))(M <- Matrix(l3)) # -> "ltCMatrix"M2 <- M %x% Mstopifnot(is(M, "ltCMatrix"), validObject(M2), dim(M2) == c(9,9),identical(M2, kronecker(M,M)),is(M2, "triangularMatrix")) # is "dtT" (why not "dtC" ?)M3 <- M %x% M2 #ok(cM3 <- colSums(M3, sparse=TRUE))identical(as.vector(cM3),as(rev(rowSums(M3, sparse=TRUE)), "vector"))M. <- M2 %x% M # gave infinite recursion## diagonal, sparse & interactionsstopifnot(is(as(Diagonal(3), "TsparseMatrix"), "TsparseMatrix"),is(X <- Diagonal(7) + 1.5 * tM[1:7,1:7], "sparseMatrix"))X(XX <- X - chol(crossprod(X)))## hmm, if we use drop0() here, maybe we should export it ...XX <- as(Matrix:::drop0(XX), "dsCMatrix")stopifnot(identical(XX, Matrix(0, nrow(X), ncol(X))))M <- Matrix(m., sparse = FALSE)(sM <- Matrix(m.))class(dlM <- M >= 1)stopifnot(identical(dlM, !(M < 1)),is(sM, "sparseMatrix"),is(dlM, "denseMatrix"))(lM <- as(dlM, "sparseMatrix"))lM2 <- as(dlM, "CsparseMatrix") #-> now oklM0 <- Matrix:::as_Csparse(dlM)stopifnot(identical3(lM, lM2, lM0))selectMethod("coerce", c("lgeMatrix", "CsparseMatrix"),useInherited = c(from = TRUE, to = FALSE))ms0 <- Matrix(c(0,1,1,0), 2,2)(ms <- as(ms0, "dsTMatrix"))cs <- as(ms, "CsparseMatrix")ll <- as(ms, "lMatrix")lt <- as(ll, "lgTMatrix")nn <- as(cs, "nsparseMatrix")l2 <- as(cs, "lsparseMatrix")nt <- triu(nn)n3 <- as(nt, "lsparseMatrix")da <- nt + t(nt)dm <- nt * t(nt) + dastopifnot(as(ms0,"matrix") == as(ll, "matrix"), # coercing num |-> logas(lt, "matrix") == as(ll, "matrix"),identical(ms, as(ll, "dMatrix")),identical4(as(ll, "CsparseMatrix"), as(cs, "lMatrix"),# lsC*as(nn, "lsparseMatrix"), l2),identical3(da, dm, as(cs, "generalMatrix")), # dgC*identical(as(da, "lMatrix"), as(lt, "CsparseMatrix")) # lgC*)cat('Time elapsed: ', proc.time(),'\n') # "stats"if(!interactive()) warnings()