https://github.com/cran/Matrix
Raw File
Tip revision: 891e875c01bd4f2885bed8274b0bec3e2926f839 authored by Martin Maechler on 26 March 2014, 00:00:00 UTC
version 1.1-3
Tip revision: 891e875
indexing.Rout.save

R Under development (unstable) (2014-01-26 r64897) -- "Unsuffered Consequences"
Copyright (C) 2014 The R Foundation for Statistical Computing
Platform: x86_64-unknown-linux-gnu (64-bit)

R is free software and comes with ABSOLUTELY NO WARRANTY.
You are welcome to redistribute it under certain conditions.
Type 'license()' or 'licence()' for distribution details.

R is a collaborative project with many contributors.
Type 'contributors()' for more information and
'citation()' on how to cite R or R packages in publications.

Type 'demo()' for some demos, 'help()' for on-line help, or
'help.start()' for an HTML browser interface to help.
Type 'q()' to quit R.

> #### For both 'Extract' ("[") and 'Replace' ("[<-") Method testing
> ####    aka    subsetting     and  subassignment
> 
> #### suppressPackageStartupMessages(...)  as we have an *.Rout.save to Rdiff against
> stopifnot(suppressPackageStartupMessages(require(Matrix)))
> 
> source(system.file("test-tools.R", package = "Matrix"), keep.source = FALSE)
> ##-> identical3() etc
> cat("doExtras:",doExtras,"\n")
doExtras: FALSE 
> 
> if(interactive()) {
+     options(error = recover, warn = 1)
+ } else if(FALSE) { ## MM @ testing *manually* only
+     options(error = recover, Matrix.verbose = TRUE, warn = 1)
+ } else {
+     options(Matrix.verbose = TRUE, warn = 1)
+ }
> 
> 
> ### Dense Matrices
> 
> m <- Matrix(1:28 +0, nrow = 7)
> validObject(m)
[1] TRUE
> stopifnot(identical(m, m[]),
+ 	  identical(m[2, 3],  16), # simple number
+ 	  identical(m[2, 3:4], c(16,23)), # simple numeric of length 2
+ 	  identical(m[NA,NA], as(Matrix(NA, 7,4), "dMatrix")))
> 
> m[2, 3:4, drop=FALSE] # sub matrix of class 'dgeMatrix'
1 x 2 Matrix of class "dgeMatrix"
     [,1] [,2]
[1,]   16   23
> m[-(4:7), 3:4]        # ditto; the upper right corner of 'm'
3 x 2 Matrix of class "dgeMatrix"
     [,1] [,2]
[1,]   15   22
[2,]   16   23
[3,]   17   24
> 
> ## rows or columns only:
> m[1,]     # first row, as simple numeric vector
[1]  1  8 15 22
> m[,2]     # 2nd column
[1]  8  9 10 11 12 13 14
> m[,1:2]   # sub matrix of first two columns
7 x 2 Matrix of class "dgeMatrix"
     [,1] [,2]
[1,]    1    8
[2,]    2    9
[3,]    3   10
[4,]    4   11
[5,]    5   12
[6,]    6   13
[7,]    7   14
> m[-(1:6),, drop=FALSE] # not the first 6 rows, i.e. only the 7th
1 x 4 Matrix of class "dgeMatrix"
     [,1] [,2] [,3] [,4]
[1,]    7   14   21   28
> m[integer(0),] #-> 0 x 4 Matrix
0 x 4 Matrix of class "dgeMatrix"
     [,1] [,2] [,3] [,4]
> m[2:4, numeric(0)] #-> 3 x 0 Matrix
3 x 0 Matrix of class "dgeMatrix"

[1,]
[2,]
[3,]
> 
> ## logical indexing
> stopifnot(identical(m[2,3], m[(1:nrow(m)) == 2, (1:ncol(m)) == 3]),
+           identical(m[2,], m[(1:nrow(m)) == 2, ]),
+           identical(m[,3:4], m[, (1:4) >= 3]))
> 
> ## dimnames indexing:
> mn <- m
> dimnames(mn) <- list(paste("r",letters[1:nrow(mn)],sep=""),
+                      LETTERS[1:ncol(mn)])
> checkMatrix(mn)
 norm(m [7 x 4]) : 1  I  F  M  ok
 Summary:  ok
2*m =?= m+m: identical
m >= m for all: ok
m < m for none: ok
> mn["rd", "D"]
[1] 25
> msr <- ms <- as(mn,"sparseMatrix")
> mnr <- mn
> v <- rev(as(ms, "vector"))
> mnr[] <- v
> msr[] <- v # [<- "sparse" -- not very sensical; did fail w/o a message
diagnosing replTmat(x,i,j,v): nargs()= 3; missing (i,j) = (0,1)
> z <- msr; z[] <- 0
> zz <- as(array(0, dim(z)), "sparseMatrix")
> a.m <- as(mnr,"matrix")
> stopifnot(identical(mn["rc", "D"], mn[3,4]), mn[3,4] == 24,
+ 	  identical(mn[, "A"], mn[,1]), mn[,1] == 1:7,
+ 	  identical(mn[c("re", "rb"), "B"], mn[c(5,2), 2]),
+ 	  identical(ms["rc", "D"], ms[3,4]), ms[3,4] == 24,
+ 	  identical(ms[, "A"], ms[,1]), ms[,1] == 1:7,
+ 	  identical(ms[ci <- c("re", "rb"), "B"], ms[c(5,2), 2]),
+ 	  identical(rownames(mn[ci, ]), ci),
+ 	  identical(rownames(ms[ci, ]), ci),
+ 	  identical(colnames(mn[,cj <- c("B","D")]), cj),
+ 	  identical(colnames(ms[,cj]), cj),
+ 	  identical(a.m, as(msr,"matrix")),
+ 	  identical(unname(z), zz),
+ 	  identical(a.m, array(v, dim=dim(mn), dimnames=dimnames(mn)))
+ 	  )
> showProc.time()
Time elapsed:  0.232 0.002 0.237 
> 
> ## Printing sparse colnames:
> ms[sample(28, 20)] <- 0
diagnosing replTmat(x,i,j,v): nargs()= 3; missing (i,j) = (0,1)
> ms <- t(rbind2(ms, 3*ms))
> cnam1 <- capture.output(show(ms))[2] ; op <- options("sparse.colnames" = "abb3")
   [[ suppressing 14 column names 'ra', 'rb', 'rc' ... ]]
> cnam2 <- capture.output(show(ms))[2] ; options(op) # revert
> stopifnot(## sparse printing
+ 	  grep("^ +$", cnam1) == 1, # cnam1 is empty
+ 	  identical(cnam2,
+ 		    paste(" ", paste(rep(rownames(mn), 2), collapse=" "))))
> 
> mo <- m
> m[2,3] <- 100
> m[1:2, 4] <- 200
> m[, 1] <- -1
> m[1:3,]
3 x 4 Matrix of class "dgeMatrix"
     [,1] [,2] [,3] [,4]
[1,]   -1    8   15  200
[2,]   -1    9  100  200
[3,]   -1   10   17   24
> 
> m. <- as.matrix(m)
> 
> ## m[ cbind(i,j) ] indexing:
> iN <- ij <- cbind(1:6, 2:3)
> iN[2:3,] <- iN[5,2] <- NA
> stopifnot(identical(m[ij], m.[ij]),
+ 	  identical(m[iN], m.[iN]))
> 
> ## testing operations on logical Matrices rather more than indexing:
> g10 <- m [ m > 10 ]
> stopifnot(18 == length(g10))
> stopifnot(10 == length(m[ m <= 10 ]))
> sel <- (20 <  m) & (m <  150)
> sel.<- (20 <  m.)& (m.<  150)
> nsel <-(20 >= m) | (m >= 150)
> (ssel <- as(sel, "sparseMatrix"))
7 x 4 sparse Matrix of class "lgCMatrix"
            
[1,] . . . .
[2,] . . | .
[3,] . . . |
[4,] . . . |
[5,] . . . |
[6,] . . . |
[7,] . . | |
> stopifnot(is(sel, "lMatrix"), is(ssel, "lsparseMatrix"),
+ 	  identical3(as.mat(sel.), as.mat(sel), as.mat(ssel)),
+ 	  identical3(!sel, !ssel, nsel), # !<sparse> is typically dense
+ 	  identical3(m[ sel],  m[ ssel], as.matrix(m)[as.matrix( ssel)]),
+ 	  identical3(m[!sel],  m[!ssel], as.matrix(m)[as.matrix(!ssel)])
+ 	  )
> showProc.time()
Time elapsed:  0.122 0.001 0.123 
> 
> ## more sparse Matrices --------------------------------------
> 
> ##' @title Check sparseMatrix sub-assignment   m[i,j] <- v
> ##' @param ms sparse Matrix
> ##' @param mm its [traditional matrix]-equivalent
> ##' @param k (approximate) length of index vectors (i,j)
> ##' @param n.uniq (approximate) number of unique values in  i,j
> ##' @param vRNG function(n) for random 'v' generation
> ##' @param show logical; if TRUE, it will not stop on error
> ##' @return
> ##' @author Martin Maechler
> chkAssign <- function(ms, mm = as(ms, "matrix"),
+                       k = min(20,dim(mm)), n.uniq = k %/% 3,
+                       vRNG = { if(is.numeric(mm) || is.complex(mm))
+                                    function(n) rpois(n,lambda= 0.75)# <- about 47% zeros
+                       else ## logical
+                           function(n) runif(n) > 0.8 }, ## 80% zeros
+                       showOnly=FALSE)
+ {
+     stopifnot(is(ms,"sparseMatrix"))
+     d <- dim(ms)
+     s1 <- function(n) sample(n, pmin(n, pmax(1, rpois(1, n.uniq))))
+     i <- sample(s1(d[1]), k/2+ rpois(1, k/2), replace = TRUE)
+     j <- sample(s1(d[2]), k/2+ rpois(1, k/2), replace = TRUE)
+     assert.EQ.mat(ms[i,j], mm[i,j])
+     ms2 <- ms. <- ms; mm. <- mm # save
+     ## now sub*assign* to these repeated indices, and then compare -----
+     v <- vRNG(length(i) * length(j))
+     mm[i,j] <- v
+     ms[i,j] <- v
+     ## useful to see (ii,ij), but confusing R/ESS when additionally debugging:
+     ## if(!showOnly && interactive()) { op <- options(error = recover); on.exit(options(op)) }
+     assert.EQ.mat(ms, mm, show=showOnly)
+     ## vector indexing m[cbind(i,j)] == m[i + N(j-1)] ,  N = nrow(.)
+     ii <- seq_len(min(length(i), length(j)))
+     i <- i[ii]
+     j <- j[ii]
+     ij <- cbind(i, j)
+     ii <- i + nrow(ms)*(j - 1)
+     ord.i <- order(ii)
+     iio <- ii[ord.i]
+     ui <- unique(iio) # compare these with :
+     neg.ii <- - setdiff(seq_len(prod(d)), ii)
+     stopifnot(identical(mm[ii], mm[ij]),
+               identical(ms.[ui], ms.[neg.ii]),
+ 	      ms.[ij] == mm.[ii], ## M[ cbind(i,j) ] was partly broken; now checking
+               ms.[ii] == mm.[ii])
+     v <- v[seq_len(length(i))]
+     if(is(ms,"nMatrix")) v <- as.logical(v)  # !
+     mm.[ij] <- v
+     ms.[ii] <- v
+     nodup <- (length(ui) == length(ii)) ## <==>  ! anyDuplicated(iio)
+     if(nodup) { cat("[-]") # rare, unfortunately
+ 	ms2[neg.ii] <- v[ord.i]
+ 	stopifnot(identical(ms2, ms.))
+     }
+     assert.EQ.mat(ms., mm., show=showOnly)
+ } ##{chkAssign}
> 
> ## Get duplicated index {because these are "hard" (and rare)
> getDuplIndex <- function(n, k) {
+     repeat {
+         i <- sample(n, k, replace=TRUE) # 3 4 6 9 2 9 :  9 is twice
+         if(anyDuplicated(i)) break
+     }
+     i
+ }
> 
> ## From package 'sfsmisc':
> repChar <- function (char, no) paste(rep.int(char, no), collapse = "")
> 
> m <- 1:800
> set.seed(101) ; m[sample(800, 600)] <- 0
> m0 <- Matrix(m, nrow = 40)
> m1 <- add.simpleDimnames(m0)
> for(kind in c("n", "l", "d")) {
+  for(m in list(m0,m1)) { ## -- with and without dimnames -------------------------
+     kClass <-paste0(kind, "Matrix"  )
+     Ckind <- paste0(kind, "gCMatrix")
+     Tkind <- paste0(kind, "gTMatrix")
+     str(mC <- as(m, Ckind))
+     str(mT <- as(as(as(m, kClass), "TsparseMatrix"), Tkind))
+     mm <- as(mC, "matrix") # also logical or double
+     IDENT <- if(kind == "n") function(x,y) Q.eq2(x,y, tol=0) else identical
+     stopifnot(identical(mT, as(as(mC, "TsparseMatrix"), Tkind)),
+               identical(mC, as(mT, Ckind)),
+               Qidentical(mC[0,0], new(Ckind)),
+               Qidentical(mT[0,0], new(Tkind)),
+               identical(unname(mT[0,]), new(Tkind, Dim = c(0L,ncol(m)))),
+               identical(unname(mT[,0]), new(Tkind, Dim = c(nrow(m),0L))),
+               IDENT(mC[0,], as(mT[FALSE,], Ckind)),
+               IDENT(mC[,0], as(mT[,FALSE], Ckind)),
+               sapply(pmin(min(dim(mC)), c(0:2, 5:10)),
+                      function(k) {i <- seq_len(k); all(mC[i,i] == mT[i,i])}),
+               TRUE)
+     cat("ok\n")
+     show(mC[,1])
+     show(mC[1:2,])
+     show(mC[7,  drop = FALSE])
+     assert.EQ.mat(mC[1:2,], mm[1:2,])
+     assert.EQ.mat(mC[0,], mm[0,])
+     assert.EQ.mat(mC[,FALSE], mm[,FALSE])
+     ##
+     ## *repeated* (aka 'duplicated') indices - did not work at all ...
+     i <- pmin(nrow(mC), rep(8:10,2))
+     j <- c(2:4, 4:3)
+     assert.EQ.mat(mC[i,], mm[i,])
+     assert.EQ.mat(mC[,j], mm[,j])
+     ## FIXME? assert.EQ.mat(mC[,NA], mm[,NA]) -- mC[,NA] is all 0 "instead" of all NA
+     ## MM currently thinks we should  NOT  allow  <sparse>[ <NA> ]
+     assert.EQ.mat(mC[i, 2:1], mm[i, 2:1])
+     assert.EQ.mat(mC[c(4,1,2:1), j], mm[c(4,1,2:1), j])
+     assert.EQ.mat(mC[i,j], mm[i,j])
+     ##
+     ## set.seed(7)
+     op <- options(Matrix.verbose = FALSE)
+     cat(" for(): ")
+     for(n in 1:(if(doExtras) 50 else 5)) {
+ 	chkAssign(mC, mm)
+ 	chkAssign(mC[-3,-2], mm[-3,-2])
+         cat(".")
+     }
+     options(op)
+     cat(sprintf("\n[Ok]%s\n\n", repChar("-", 64)))
+  }
+  cat(sprintf("\nok( %s )\n== ###%s\n\n", kind, repChar("=", 70)))
+ }## end{for}---------------------------------------------------------------
Formal class 'ngCMatrix' [package "Matrix"] with 5 slots
  ..@ i       : int [1:200] 2 6 11 21 24 29 37 38 1 4 ...
  ..@ p       : int [1:21] 0 8 22 28 37 41 50 63 71 81 ...
  ..@ Dim     : int [1:2] 40 20
  ..@ Dimnames:List of 2
  .. ..$ : NULL
  .. ..$ : NULL
  ..@ factors : list()
Formal class 'ngTMatrix' [package "Matrix"] with 5 slots
  ..@ i       : int [1:200] 2 6 11 21 24 29 37 38 1 4 ...
  ..@ j       : int [1:200] 0 0 0 0 0 0 0 0 1 1 ...
  ..@ Dim     : int [1:2] 40 20
  ..@ Dimnames:List of 2
  .. ..$ : NULL
  .. ..$ : NULL
  ..@ factors : list()
Note: method with signature 'nsparseMatrix#sparseMatrix' chosen for function '==',
 target signature 'ngCMatrix#ngTMatrix'.
 "nMatrix#nMatrix", "sparseMatrix#nsparseMatrix" would also be valid
ok
 [1] FALSE FALSE  TRUE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE  TRUE
[13] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE
[25]  TRUE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE
[37] FALSE  TRUE  TRUE FALSE
2 x 20 sparse Matrix of class "ngCMatrix"
                                            
[1,] . . . | . . | . . . . | . . | . | . . .
[2,] . | . . . | . . . . . . | | . . . . | .
[1] TRUE
 for(): .....
[Ok]----------------------------------------------------------------

Formal class 'ngCMatrix' [package "Matrix"] with 5 slots
  ..@ i       : int [1:200] 2 6 11 21 24 29 37 38 1 4 ...
  ..@ p       : int [1:21] 0 8 22 28 37 41 50 63 71 81 ...
  ..@ Dim     : int [1:2] 40 20
  ..@ Dimnames:List of 2
  .. ..$ : chr [1:40] "r1" "r2" "r3" "r4" ...
  .. ..$ : chr [1:20] "c1" "c2" "c3" "c4" ...
  ..@ factors : list()
Formal class 'ngTMatrix' [package "Matrix"] with 5 slots
  ..@ i       : int [1:200] 2 6 11 21 24 29 37 38 1 4 ...
  ..@ j       : int [1:200] 0 0 0 0 0 0 0 0 1 1 ...
  ..@ Dim     : int [1:2] 40 20
  ..@ Dimnames:List of 2
  .. ..$ : chr [1:40] "r1" "r2" "r3" "r4" ...
  .. ..$ : chr [1:20] "c1" "c2" "c3" "c4" ...
  ..@ factors : list()
ok
   r1    r2    r3    r4    r5    r6    r7    r8    r9   r10   r11   r12   r13 
FALSE FALSE  TRUE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE  TRUE FALSE 
  r14   r15   r16   r17   r18   r19   r20   r21   r22   r23   r24   r25   r26 
FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE  TRUE FALSE 
  r27   r28   r29   r30   r31   r32   r33   r34   r35   r36   r37   r38   r39 
FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE  TRUE 
  r40 
FALSE 
2 x 20 sparse Matrix of class "ngCMatrix"
   [[ suppressing 20 column names 'c1', 'c2', 'c3' ... ]]
                                          
r1 . . . | . . | . . . . | . . | . | . . .
r2 . | . . . | . . . . . . | | . . . . | .
[1] TRUE
 for(): .....
[Ok]----------------------------------------------------------------


ok( n )
== ###======================================================================

Formal class 'lgCMatrix' [package "Matrix"] with 6 slots
  ..@ i       : int [1:200] 2 6 11 21 24 29 37 38 1 4 ...
  ..@ p       : int [1:21] 0 8 22 28 37 41 50 63 71 81 ...
  ..@ Dim     : int [1:2] 40 20
  ..@ Dimnames:List of 2
  .. ..$ : NULL
  .. ..$ : NULL
  ..@ x       : logi [1:200] TRUE TRUE TRUE TRUE TRUE TRUE ...
  ..@ factors : list()
Formal class 'lgTMatrix' [package "Matrix"] with 6 slots
  ..@ i       : int [1:200] 2 6 11 21 24 29 37 38 1 4 ...
  ..@ j       : int [1:200] 0 0 0 0 0 0 0 0 1 1 ...
  ..@ Dim     : int [1:2] 40 20
  ..@ Dimnames:List of 2
  .. ..$ : NULL
  .. ..$ : NULL
  ..@ x       : logi [1:200] TRUE TRUE TRUE TRUE TRUE TRUE ...
  ..@ factors : list()
ok
 [1] FALSE FALSE  TRUE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE  TRUE
[13] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE
[25]  TRUE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE
[37] FALSE  TRUE  TRUE FALSE
2 x 20 sparse Matrix of class "lgCMatrix"
                                            
[1,] . . . | . . | . . . . | . . | . | . . .
[2,] . | . . . | . . . . . . | | . . . . | .
[1] TRUE
 for(): .....
[Ok]----------------------------------------------------------------

Formal class 'lgCMatrix' [package "Matrix"] with 6 slots
  ..@ i       : int [1:200] 2 6 11 21 24 29 37 38 1 4 ...
  ..@ p       : int [1:21] 0 8 22 28 37 41 50 63 71 81 ...
  ..@ Dim     : int [1:2] 40 20
  ..@ Dimnames:List of 2
  .. ..$ : chr [1:40] "r1" "r2" "r3" "r4" ...
  .. ..$ : chr [1:20] "c1" "c2" "c3" "c4" ...
  ..@ x       : logi [1:200] TRUE TRUE TRUE TRUE TRUE TRUE ...
  ..@ factors : list()
Formal class 'lgTMatrix' [package "Matrix"] with 6 slots
  ..@ i       : int [1:200] 2 6 11 21 24 29 37 38 1 4 ...
  ..@ j       : int [1:200] 0 0 0 0 0 0 0 0 1 1 ...
  ..@ Dim     : int [1:2] 40 20
  ..@ Dimnames:List of 2
  .. ..$ : chr [1:40] "r1" "r2" "r3" "r4" ...
  .. ..$ : chr [1:20] "c1" "c2" "c3" "c4" ...
  ..@ x       : logi [1:200] TRUE TRUE TRUE TRUE TRUE TRUE ...
  ..@ factors : list()
ok
   r1    r2    r3    r4    r5    r6    r7    r8    r9   r10   r11   r12   r13 
FALSE FALSE  TRUE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE  TRUE FALSE 
  r14   r15   r16   r17   r18   r19   r20   r21   r22   r23   r24   r25   r26 
FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE  TRUE FALSE 
  r27   r28   r29   r30   r31   r32   r33   r34   r35   r36   r37   r38   r39 
FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE  TRUE 
  r40 
FALSE 
2 x 20 sparse Matrix of class "lgCMatrix"
   [[ suppressing 20 column names 'c1', 'c2', 'c3' ... ]]
                                          
r1 . . . | . . | . . . . | . . | . | . . .
r2 . | . . . | . . . . . . | | . . . . | .
[1] TRUE
 for(): .....
[Ok]----------------------------------------------------------------


ok( l )
== ###======================================================================

Formal class 'dgCMatrix' [package "Matrix"] with 6 slots
  ..@ i       : int [1:200] 2 6 11 21 24 29 37 38 1 4 ...
  ..@ p       : int [1:21] 0 8 22 28 37 41 50 63 71 81 ...
  ..@ Dim     : int [1:2] 40 20
  ..@ Dimnames:List of 2
  .. ..$ : NULL
  .. ..$ : NULL
  ..@ x       : num [1:200] 3 7 12 22 25 30 38 39 42 45 ...
  ..@ factors : list()
Formal class 'dgTMatrix' [package "Matrix"] with 6 slots
  ..@ i       : int [1:200] 2 6 11 21 24 29 37 38 1 4 ...
  ..@ j       : int [1:200] 0 0 0 0 0 0 0 0 1 1 ...
  ..@ Dim     : int [1:2] 40 20
  ..@ Dimnames:List of 2
  .. ..$ : NULL
  .. ..$ : NULL
  ..@ x       : num [1:200] 3 7 12 22 25 30 38 39 42 45 ...
  ..@ factors : list()
ok
 [1]  0  0  3  0  0  0  7  0  0  0  0 12  0  0  0  0  0  0  0  0  0 22  0  0 25
[26]  0  0  0  0 30  0  0  0  0  0  0  0 38 39  0
2 x 20 sparse Matrix of class "dgCMatrix"
                                                               
[1,] .  . . 121 .   . 241 . . . . 441   .   . 561 . 641 .   . .
[2,] . 42 .   . . 202   . . . . .   . 482 522   . .   . . 722 .
[1] 7
 for(): .....
[Ok]----------------------------------------------------------------

Formal class 'dgCMatrix' [package "Matrix"] with 6 slots
  ..@ i       : int [1:200] 2 6 11 21 24 29 37 38 1 4 ...
  ..@ p       : int [1:21] 0 8 22 28 37 41 50 63 71 81 ...
  ..@ Dim     : int [1:2] 40 20
  ..@ Dimnames:List of 2
  .. ..$ : chr [1:40] "r1" "r2" "r3" "r4" ...
  .. ..$ : chr [1:20] "c1" "c2" "c3" "c4" ...
  ..@ x       : num [1:200] 3 7 12 22 25 30 38 39 42 45 ...
  ..@ factors : list()
Formal class 'dgTMatrix' [package "Matrix"] with 6 slots
  ..@ i       : int [1:200] 2 6 11 21 24 29 37 38 1 4 ...
  ..@ j       : int [1:200] 0 0 0 0 0 0 0 0 1 1 ...
  ..@ Dim     : int [1:2] 40 20
  ..@ Dimnames:List of 2
  .. ..$ : chr [1:40] "r1" "r2" "r3" "r4" ...
  .. ..$ : chr [1:20] "c1" "c2" "c3" "c4" ...
  ..@ x       : num [1:200] 3 7 12 22 25 30 38 39 42 45 ...
  ..@ factors : list()
ok
 r1  r2  r3  r4  r5  r6  r7  r8  r9 r10 r11 r12 r13 r14 r15 r16 r17 r18 r19 r20 
  0   0   3   0   0   0   7   0   0   0   0  12   0   0   0   0   0   0   0   0 
r21 r22 r23 r24 r25 r26 r27 r28 r29 r30 r31 r32 r33 r34 r35 r36 r37 r38 r39 r40 
  0  22   0   0  25   0   0   0   0  30   0   0   0   0   0   0   0  38  39   0 
2 x 20 sparse Matrix of class "dgCMatrix"
   [[ suppressing 20 column names 'c1', 'c2', 'c3' ... ]]
                                                             
r1 .  . . 121 .   . 241 . . . . 441   .   . 561 . 641 .   . .
r2 . 42 .   . . 202   . . . . .   . 482 522   . .   . . 722 .
[1] 7
 for(): .....
[Ok]----------------------------------------------------------------


ok( d )
== ###======================================================================

> showProc.time()
Time elapsed:  0.842 0.001 0.846 
> 
> if(doExtras) {### {was ./AAA_index.R, MM-only}
+     ## an nsparse-example
+     A <- Matrix(c(rep(c(1,0,0),2), rep(c(2,0),7), c(0,0,2), rep(0,4)), 3,9)
+     i <- c(3,1:2)
+     j <- c(3, 5, 9, 5, 9)
+     vv <- logical(length(i)*length(j)); vv[6:9] <- TRUE
+ 
+     print(An <- as(A,"nMatrix")); an <- as(An, "matrix")
+     assert.EQ.mat(An, an)
+     An[i, j] <- vv
+     an[i, j] <- vv
+     assert.EQ.mat(An, an)## error
+     if(!all(An == an)) show(drop0(An - an))
+     ## all are +1
+ 
+     options("Matrix.subassign.verbose" = TRUE)# output from C
+     An <- as(A,"nMatrix"); An[i, j] <- vv
+     ## and compare with this:
+     Al <- as(A,"lMatrix"); Al[i, j] <- vv
+     options("Matrix.subassign.verbose" = FALSE)
+ 
+     ##--- An interesting not small not large example  for  M[i,j] <- v ------------
+     ##
+     M <- Matrix(c(1, rep(0,7), 1:4), 3,4)
+     N0 <- kronecker(M,M)
+     mkN1 <- function(M) {
+         stopifnot(length(d <- dim(M)) == 2)
+         isC <- is(M,"CsparseMatrix")
+         M[,d[2]] <- c(0,2,0)
+         N <- kronecker(diag(x=1:2), M)## remains sparse if 'M' is
+         if(isC) N <- as(N, "CsparseMatrix")
+         diag(N[-1,]) <- -2
+         N[9,]  <- 1:4   # is recycled
+         N[,12] <- -7:-9 # ditto
+         N
+     }
+ 
+     show(N1 <- t(N <- mkN1(N0)))    # transpose {for display reasons}
+     C1 <- t(C <- mkN1(as(N0,"CsparseMatrix")))
+     stopifnot(all(C == N))
+     assert.EQ.mat(C, mkN1(as.matrix(N0)))
+ 
+     C. <- C1
+     show(N <- N1) ; n <- as.matrix(N); str(N)
+     sort(i <- c(6,8,19,11,21,20,10,7,12,9,5,18,17,22,13))## == c(5:13, 17:22))
+     sort(j <- c(3,8,6,15,10,4,14,13,16,2,11,17,7,5))## == c(2:8, 10:11, 13:17)
+     val <- v.l <- 5*c(0,6,0,7,0,0,8:9, 0,0)
+     show(spv <- as(val, "sparseVector")); str(spv)
+ 
+     n [i,j] <- v.l
+     N [i,j] <- val# is recycled, too
+     C.[i,j] <- val
+     assert.EQ.mat(N,n) ; stopifnot(all(C. == N))
+     ## and the same *again*:
+     n [i,j] <- v.l
+     N [i,j] <- val
+     C.[i,j] <- val
+     assert.EQ.mat(N,n)
+     stopifnot(all(C. == N))
+ 
+     print(load(system.file("external", "symA.rda", package="Matrix"))) # "As"
+     stopifnot(isValid(As, "dsCMatrix"), identical(As@factors, list()))
+     R. <- drop0(chol(As))
+     stopifnot(1:32 == sort(diag(R.)), ## !
+               R.@x == as.integer(R.@x),## so it is an integer-valued chol-decomp !
+               ## shows that (1) As is *not* singular  (2) the matrix is not random
+               all.equal(crossprod(R.), As, tolerance =1e-15))
+     print(summary(evA <- eigen(As, only.values=TRUE)$val))
+     print(tail(evA)) ## largest three ~= 10^7,  smallest two *negative*
+     print(rcond(As)) # 1.722 e-21 == very bad !
+     ##-> this *is* a border line case, i.e. very close to singular !
+     ## and also determinant(.) is rather random here!
+     cc0 <- Cholesky(As)# no problem
+     try({
+         cc <- Cholesky(As, super=TRUE)
+         ## gives --on 32-bit only--
+         ## Cholmod error 'matrix not positive definite' at file:../Supernodal/t_cholmod_super_numeric.c, line 613
+         ecc <- expand(cc)
+         L.P <- with(ecc, crossprod(L,P))  ## == L'P
+         ## crossprod(L.P) == (L'P)' L'P == P'LL'P
+         stopifnot( all.equal(crossprod(L.P), As) )
+     })
+     ##---- end{ eigen( As ) -----------
+ 
+ } ## only if(doExtras)
> 
> 
> ##---- Symmetric indexing of symmetric Matrix ----------
> m. <- mC
> m.[, c(2, 7:12)] <- 0
> isValid(S <- crossprod(add.simpleDimnames(m.) %% 100), "dsCMatrix")
[1] TRUE
> ss <- as(S, "matrix")
> ds <- as(S, "denseMatrix")
> ## NA-indexing of *dense* Matrices: should work as traditionally
> assert.EQ.mat(ds[NA,NA], ss[NA,NA])
> assert.EQ.mat(ds[NA,  ], ss[NA,])
> assert.EQ.mat(ds[  ,NA], ss[,NA])
> T <- as(S, "TsparseMatrix")
> stopifnot(identical(ds[2 ,NA], ss[2,NA]),
+ 	  identical(ds[NA, 1], ss[NA, 1]),
+ 	  identical(S, as(T, "CsparseMatrix")) )
> 
> ## non-repeated indices:
> i <- c(7:5, 2:4);assert.EQ.mat(T[i,i], ss[i,i])
> ## NA in indices  -- check that we get a helpful error message:
> i[2] <- NA
> er <- tryCatch(T[i,i], error = function(e)e)
> stopifnot(as.logical(grep("indices.*sparse Matrices", er$message)))
> 
> N <- nrow(T)
> set.seed(11)
> for(n in 1:(if(doExtras) 50 else 3)) {
+     i <- sample(N, max(2, sample(N,1)), replace = FALSE)
+     validObject(Tii <- T[i,i]) ; tTi <- t(T)[i,i]
+     stopifnot(is(Tii, "dsTMatrix"), # remained symmetric Tsparse
+ 	      is(tTi, "dsTMatrix"), # may not be identical when *sorted* differently
+ 	      identical(as(t(Tii),"CsparseMatrix"), as(tTi,"CsparseMatrix")))
+     assert.EQ.mat(Tii, ss[i,i])
+ }
> 
> b <- diag(1:2)[,c(1,1,2,2)]
> cb <- crossprod(b)
> cB <- crossprod(Matrix(b, sparse=TRUE))
> a <- matrix(0, 6, 6)
> a[1:4, 1:4] <- cb
> A1 <- A2 <- Matrix(0, 6, 6)#-> sparse
> A1[1:4, 1:4] <- cb
> A2[1:4, 1:4] <- cB
> assert.EQ.mat(A1, a)# indeed
> stopifnot(identical(A1, A2), is(A1, "dsCMatrix"))
> 
> ## repeated ones ``the challenge'' (to do smartly):
> j <- c(4, 4, 9, 12, 9, 4, 17, 3, 18, 4, 12, 18, 4, 9)
> assert.EQ.mat(T[j,j], ss[j,j])
> ## and another two sets  (a, A) &  (a., A.) :
> a <- matrix(0, 6,6)
> a[upper.tri(a)] <- (utr <- c(2, 0,-1, 0,0,5, 7,0,0,0, 0,0,-2,0,8))
> ta <- t(a); ta[upper.tri(a)] <- utr; a <- t(ta)
> diag(a) <- c(0,3,0,4,6,0)
> A <- as(Matrix(a), "TsparseMatrix")
> A. <- A
> diag(A.) <- 10 * (1:6)
> a. <- as(A., "matrix")
> ## More testing {this was not working for a long time..}
> set.seed(1)
> for(n in 1:(if(doExtras) 100 else 6)) {
+     i <- sample(1:nrow(A), 3+2*rpois(1, lam=3), replace=TRUE)
+     Aii  <- A[i,i]
+     A.ii <- A.[i,i]
+     stopifnot(class(Aii) == class(A),
+               class(A.ii) == class(A.))
+     assert.EQ.mat(Aii , a [i,i])
+     assert.EQ.mat(A.ii, a.[i,i])
+     assert.EQ.mat(T[i,i], ss[i,i])
+ }
> showProc.time()
Time elapsed:  0.265 0 0.265 
> 
> stopifnot(all.equal(mC[,3], mm[,3]),
+ 	  identical(mC[ij], mC[ij + 0.4]),
+ 	  identical(mC[ij], mm[ij]),
+ 	  identical(mC[iN], mm[iN]))
> ## out of bound indexing must be detected:
> assertError(mC[cbind(ij[,1] - 5, ij[,2])])
> assertError(mC[cbind(ij[,1],     ij[,2] + ncol(mC))])
> 
> assert.EQ.mat(mC[7, , drop=FALSE], mm[7, , drop=FALSE])
> identical    (mC[7,   drop=FALSE], mm[7,   drop=FALSE]) # *vector* indexing
[1] TRUE
> 
> stopifnot(dim(mC[numeric(0), ]) == c(0,20), # used to give warnings
+           dim(mC[, integer(0)]) == c(40,0),
+           identical(mC[, integer(0)], mC[, FALSE]))
> validObject(print(mT[,c(2,4)]))
40 x 2 sparse Matrix of class "dgTMatrix"
    c2  c4
r1   . 121
r2  42   .
r3   .   .
r4   .   .
r5  45   .
r6   .   .
r7   .   .
r8   . 128
r9   . 129
r10 50   .
r11  .   .
r12 52 132
r13  . 133
r14  .   .
r15 55   .
r16  .   .
r17  .   .
r18  . 138
r19  .   .
r20  .   .
r21  . 141
r22  . 142
r23 63   .
r24  .   .
r25 65   .
r26  .   .
r27 67   .
r28 68   .
r29  .   .
r30  .   .
r31 71   .
r32 72   .
r33  .   .
r34 74   .
r35  .   .
r36 76   .
r37  .   .
r38  .   .
r39  . 159
r40 80   .
[1] TRUE
> stopifnot(all.equal(mT[2,], mm[2,]),
+ 	  ## row or column indexing in combination with t() :
+ 	  Q.C.identical(mT[2,], t(mT)[,2]),
+ 	  Q.C.identical(mT[-2,], t(t(mT)[,-2])),
+ 	  Q.C.identical(mT[c(2,5),], t(t(mT)[,c(2,5)])) )
> assert.EQ.mat(mT[4,, drop = FALSE], mm[4,, drop = FALSE])
> stopifnot(identical3(mm[,1], mC[,1], mT[,1]),
+ 	  identical3(mm[3,], mC[3,], mT[3,]),
+ 	  identical3(mT[2,3], mC[2,3], 0),
+ 	  identical(mT[], mT),
+           identical4(       mm[c(3,7), 2:4],  as.mat( m[c(3,7), 2:4]),
+                      as.mat(mT[c(3,7), 2:4]), as.mat(mC[c(3,7), 2:4]))
+           )
> 
> x.x <- crossprod(mC)
> stopifnot(class(x.x) == "dsCMatrix",
+           class(x.x. <- round(x.x / 10000)) == "dsCMatrix",
+           identical(x.x[cbind(2:6, 2:6)],
+                     diag(x.x [2:6, 2:6])))
> head(x.x.) # Note the *non*-structural 0's printed as "0"
6 x 20 sparse Matrix of class "dgCMatrix"
   [[ suppressing 20 column names 'c1', 'c2', 'c3' ... ]]
                                                           
c1 1 0 .  1  .  1  1  3  .  3  2  1  6  1  .  2  4  6  5  1
c2 0 6 2  1  3  5  7  5 12 14 14  9 11 16 12 13 17 19 19 10
c3 . 2 6  .  4  2  5  3  8 12  5 16  9 11 23  .  .  6  7  7
c4 1 1 . 17  .  8 10 13  8  6 18 18 29 35 14  8 25 10 19 21
c5 . 3 4  . 14  4 10  .  . 29  8  9 19 11 11  .  . 26 26 16
c6 1 5 2  8  4 42  5 19 14  9  8 10 42 56 50 27 29 32 64 16
> tail(x.x., -3) # all but the first three lines
17 x 20 sparse Matrix of class "dgCMatrix"
   [[ suppressing 20 column names 'c1', 'c2', 'c3' ... ]]
                                                                           
c4  1  1  . 17  .  8  10 13   8   6  18  18  29  35  14   8  25  10  19  21
c5  .  3  4  . 14  4  10  .   .  29   8   9  19  11  11   .   .  26  26  16
c6  1  5  2  8  4 42   5 19  14   9   8  10  42  56  50  27  29  32  64  16
c7  1  7  5 10 10  5  87 14   9  31  77  47  79  43  28  17  67 110  36 121
c8  3  5  3 13  . 19  14 70  10  24  37  13  59  62  34  19  58  21  64  44
c9  . 12  8  8  . 14   9 10 116  41  58  33  33  72  78  43  69  72  75  25
c10 3 14 12  6 29  9  31 24  41 167  69  56  99  44  70  24 105  82  85  32
c11 2 14  5 18  8  8  77 37  58  69 267  80  86 139  49 105 194 119 122 129
c12 1  9 16 18  9 10  47 13  33  56  80 194  70  77  81   .  90  32   . 106
c13 6 11  9 29 19 42  79 59  33  99  86  70 324 157  55   .  69 142 144 155
c14 1 16 11 35 11 56  43 62  72  44 139  77 157 375 123 102 145  39 196  81
c15 . 12 23 14 11 50  28 34  78  70  49  81  55 123 368  71 112  41  41  86
c16 2 13  .  8  . 27  17 19  43  24 105   .   . 102  71 233 124  44 139   .
c17 4 17  . 25  . 29  67 58  69 105 194  90  69 145 112 124 523 141 245 100
c18 6 19  6 10 26 32 110 21  72  82 119  32 142  39  41  44 141 497 104 111
c19 5 19  7 19 26 64  36 64  75  85 122   . 144 196  41 139 245 104 542  55
c20 1 10  7 21 16 16 121 44  25  32 129 106 155  81  86   . 100 111  55 541
> 
> lx.x <- as(x.x, "lsCMatrix") # FALSE only for "structural" 0
> (l10 <- lx.x[1:10, 1:10])# "lsC"
10 x 10 sparse Matrix of class "lsCMatrix"
   [[ suppressing 10 column names 'c1', 'c2', 'c3' ... ]]
                       
c1  | | . | . | | | . |
c2  | | | | | | | | | |
c3  . | | . | | | | | |
c4  | | . | . | | | | |
c5  . | | . | | | . . |
c6  | | | | | | | | | |
c7  | | | | | | | | | |
c8  | | | | . | | | | |
c9  . | | | . | | | | |
c10 | | | | | | | | | |
> (l3 <-  lx.x[1:3, ])
3 x 20 sparse Matrix of class "lgCMatrix"
   [[ suppressing 20 column names 'c1', 'c2', 'c3' ... ]]
                                          
c1 | | . | . | | | . | | | | | . | | | | |
c2 | | | | | | | | | | | | | | | | | | | |
c3 . | | . | | | | | | | | | | | . . | | |
> m.x <- as.mat(x.x) # as.mat() *drops* (NULL,NULL) dimnames
> stopifnot(class(l10) == "lsCMatrix", # symmetric indexing -> symmetric !
+           identical(as.mat(lx.x), m.x != 0),
+           identical(as.logical(lx.x), as.logical(m.x)),
+           identical(as.mat(l10), m.x[1:10, 1:10] != 0),
+           identical(as.mat(l3 ), m.x[1:3, ] != 0)
+           )
> 
> ##-- Sub*assignment* with repeated / duplicated index:
> A <- Matrix(0,4,3) ; A[c(1,2,1), 2] <- 1 ; A
4 x 3 sparse Matrix of class "dgCMatrix"
          
[1,] . 1 .
[2,] . 1 .
[3,] . . .
[4,] . . .
> B <- A;              B[c(1,2,1), 2] <- 1:3; B; B. <- B
4 x 3 sparse Matrix of class "dgCMatrix"
          
[1,] . 3 .
[2,] . 2 .
[3,] . . .
[4,] . . .
> B.[3,] <- rbind(4:2)
> ## change the diagonal and the upper and lower subdiagonal :
> diag(B.) <- 10 * diag(B.)
> diag(B.[,-1]) <- 5* diag(B.[,-1])
> diag(B.[-1,]) <- 4* diag(B.[-1,]) ; B.
4 x 3 sparse Matrix of class "dgCMatrix"
            
[1,] . 15  .
[2,] . 20  .
[3,] 4 12 20
[4,] .  .  .
> C <- B.; C[,2] <- C[,2];  C[1,] <- C[1,]; C[2:3,2:1] <- C[2:3,2:1]
> stopifnot(identical(unname(as.matrix(A)),
+ 		    local({a <- matrix(0,4,3); a[c(1,2,1), 2] <-  1 ; a})),
+ 	  identical(unname(as.matrix(B)),
+ 		    local({a <- matrix(0,4,3); a[c(1,2,1), 2] <- 1:3; a})),
+ 	  identical(C, drop0(B.)))
> ## <sparse>[<logicalSparse>] <- v  failed in the past
> T <- as(C,"TsparseMatrix"); C. <- C
> T[T>0] <- 21
Note: method with signature 'TsparseMatrix#Matrix#missing#replValue' chosen for function '[<-',
 target signature 'dgTMatrix#lgTMatrix#missing#numeric'.
 "Matrix#lsparseMatrix#missing#replValue" would also be valid
diagnosing replTmat(x,i,j,v): nargs()= 3; missing (i,j) = (0,1)
> C[C>0] <- 21
Note: method with signature 'CsparseMatrix#Matrix#missing#replValue' chosen for function '[<-',
 target signature 'dgCMatrix#lgCMatrix#missing#numeric'.
 "Matrix#lsparseMatrix#missing#replValue" would also be valid
diagnosing replTmat(x,i,j,v): nargs()= 3; missing (i,j) = (0,1)
> a. <- local({a <- as.matrix(C.); a[a>0] <- 21; a})
> assert.EQ.mat(C, a.)
> stopifnot(identical(C, as(T, "CsparseMatrix")))
> 
> ## used to fail
> n <- 5 ## or much larger
> sm <- new("dsTMatrix", i=1L, j=1L, Dim=as.integer(c(n,n)), x = 1)
> (cm <- as(sm, "CsparseMatrix"))
5 x 5 sparse Matrix of class "dsCMatrix"
              
[1,] . . . . .
[2,] . 1 . . .
[3,] . . . . .
[4,] . . . . .
[5,] . . . . .
> sm[2,]
[1] 0 1 0 0 0
> stopifnot(sm[2,] == c(0:1, rep.int(0,ncol(sm)-2)),
+ 	  sm[2,] == cm[2,],
+ 	  sm[,3] == sm[3,],
+ 	  all(sm[,-(1:3)] == t(sm[-(1:3),])), # all(<lge.>)
+ 	  all(sm[,-(1:3)] == 0)
+ 	  )
> showProc.time()
Time elapsed:  0.149 0.001 0.151 
> 
> ##---  "nsparse*" sub-assignment :----------
> M <- Matrix(c(1, rep(0,7), 1:4), 3,4)
> N0 <- kronecker(M,M)
> Nn <- as(N0, "nMatrix"); nn <- as(Nn,"matrix")
> (Nn00 <- Nn0 <- Nn); nn00 <- nn0 <- nn
9 x 16 sparse Matrix of class "ngTMatrix"
                                     
 [1,] | . . | . . . . . . . . | . . |
 [2,] . . . | . . . . . . . . . . . |
 [3,] . . | | . . . . . . . . . . | |
 [4,] . . . . . . . . . . . . | . . |
 [5,] . . . . . . . . . . . . . . . |
 [6,] . . . . . . . . . . . . . . | |
 [7,] . . . . . . . . | . . | | . . |
 [8,] . . . . . . . . . . . | . . . |
 [9,] . . . . . . . . . . | | . . | |
> 
> set.seed(1)
> Nn0 <- Nn00; nn0 <- nn00
> for(i in 1:(if(doExtras) 200 else 25)) {
+     Nn <- Nn0
+     nn <- nn0
+     i. <- getDuplIndex(nrow(N0), 6)
+     j. <- getDuplIndex(ncol(N0), 4)
+     vv <- sample(c(FALSE,TRUE),
+                  length(i.)*length(j.), replace=TRUE)
+     cat(",")
+     Nn[i., j.] <- vv
+     nn[i., j.] <- vv
+     assert.EQ.mat(Nn, nn)
+     if(!all(Nn == nn)) {
+         cat("i=",i,":\n i. <- "); dput(i.)
+         cat("j. <- "); dput(j.)
+         cat("which(vv): "); dput(which(vv))
+         cat("Difference matrix:\n")
+         show(drop0(Nn - nn))
+     }
+     cat("k")
+     ## sub-assign double precision to logical sparseMatrices: now *with* warning:
+     ##  {earlier: gave *no* warning}:
+     assertWarning(Nn[1:2,] <- -pi)
+     assertWarning(Nn[, 5] <- -pi)
+     assertWarning(Nn[2:4, 5:8] <- -pi)
+     stopifnot(isValid(Nn,"nsparseMatrix"))
+     ##
+     cat(".")
+     if(i %% 10 == 0) cat("\n")
+     if(i == 100) {
+         Nn0 <- as(Nn0, "CsparseMatrix")
+         cat("Now: class", class(Nn0)," :\n~~~~~~~~~~~~~~~~~\n")
+     }
+ }
,k.,k.,k.,k.,k.,k.,k.,k.,k.,k.
,k.,k.,k.,k.,k.,k.,k.,k.,k.,k.
,k.,k.,k.,k.,k.> showProc.time()
Time elapsed:  0.198 0 0.199 
> Nn <- Nn0
> ## Check that  NA is interpreted as TRUE (with a warning), for "nsparseMatrix":
> assertWarning(Nn[ii <-     3  ] <- NA); stopifnot(isValid(Nn,"nsparseMatrix"), Nn[ii])
diagnosing replTmat(x,i,j,v): nargs()= 3; missing (i,j) = (0,1)
> assertWarning(Nn[ii <-   22:24] <- NA); stopifnot(isValid(Nn,"nsparseMatrix"), Nn[ii])
diagnosing replTmat(x,i,j,v): nargs()= 3; missing (i,j) = (0,1)
> assertWarning(Nn[ii <- -(1:99)] <- NA); stopifnot(isValid(Nn,"nsparseMatrix"), Nn[ii])
diagnosing replTmat(x,i,j,v): nargs()= 3; missing (i,j) = (0,1)
> assertWarning(Nn[ii <- 3:4  ] <- c(0,NA))
diagnosing replTmat(x,i,j,v): nargs()= 3; missing (i,j) = (0,1)
> stopifnot(isValid(Nn,"nsparseMatrix"), Nn[ii] == 0:1)
> assertWarning(Nn[ii <- 25:27] <- c(0,1,NA))
diagnosing replTmat(x,i,j,v): nargs()= 3; missing (i,j) = (0,1)
> stopifnot(isValid(Nn,"nsparseMatrix"), Nn[ii] == c(FALSE,TRUE,TRUE))
> 
> m0 <- Diagonal(5)
> stopifnot(identical(m0[2,], m0[,2]),
+ 	  identical(m0[,1], c(1,0,0,0,0)))
> ### Diagonal -- Sparse:
> (m1 <- as(m0, "TsparseMatrix")) # dtTMatrix unitriangular
5 x 5 sparse Matrix of class "dtTMatrix" (unitriangular)
              
[1,] 1 . . . .
[2,] . 1 . . .
[3,] . . 1 . .
[4,] . . . 1 .
[5,] . . . . 1
> (m2 <- as(m0, "CsparseMatrix")) # dtCMatrix unitriangular
5 x 5 sparse Matrix of class "dtCMatrix" (unitriangular)
              
[1,] 1 . . . .
[2,] . 1 . . .
[3,] . . 1 . .
[4,] . . . 1 .
[5,] . . . . 1
> m1g <- as(m1, "generalMatrix")
> stopifnot(is(m1g, "dgTMatrix"))
> assert.EQ.mat(m2[1:3,],    diag(5)[1:3,])
> assert.EQ.mat(m2[,c(4,1)], diag(5)[,c(4,1)])
> stopifnot(identical(m2[1:3,], as(m1[1:3,], "CsparseMatrix")),
+           identical(Matrix:::uniqTsparse(m1[, c(4,2)]),
+                     Matrix:::uniqTsparse(as(m2[, c(4,2)], "TsparseMatrix")))
+           )## failed in 0.9975-11
> 
> (uTr <- new("dtTMatrix", Dim = c(3L,3L), diag="U"))
3 x 3 sparse Matrix of class "dtTMatrix" (unitriangular)
          
[1,] 1 . .
[2,] . 1 .
[3,] . . 1
> uTr[1,] <- 0
> assert.EQ.mat(uTr, cbind(0, rbind(0,diag(2))))
> 
> M <- m0; M[1,] <- 0
> Z <- m0; Z[] <- 0; z <- array(0, dim(M))
> stopifnot(identical(M, Diagonal(x=c(0, rep(1,4)))),
+           all(Z == 0), Qidentical(as(Z, "matrix"), z))
> M <- m0; M[,3] <- 3 ; M ; stopifnot(is(M, "sparseMatrix"), M[,3] == 3)
5 x 5 sparse Matrix of class "dgCMatrix"
              
[1,] 1 . 3 . .
[2,] . 1 3 . .
[3,] . . 3 . .
[4,] . . 3 1 .
[5,] . . 3 . 1
> checkMatrix(M)
Note: method with signature 'sparseMatrix#ldiMatrix' chosen for function '==',
 target signature 'nsCMatrix#ldiMatrix'.
 "nsparseMatrix#sparseMatrix", "nMatrix#lMatrix" would also be valid
 norm(m [5 x 5]) : 1  I  F  M  ok
 Summary:  ok
as(., "nMatrix") giving full nonzero-pattern: ok
2*m =?= m+m: identical
m >= m for all: ok
m < m for none: ok
symmpart(m) + skewpart(m) == m: ok;  determinant(): ok
> M <- m0; M[1:3, 3] <- 0 ;M
5 x 5 diagonal matrix of class "ddiMatrix"
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    .    .    .    .
[2,]    .    1    .    .    .
[3,]    .    .    0    .    .
[4,]    .    .    .    1    .
[5,]    .    .    .    .    1
> T <- m0; T[1:3, 3] <- 10
> stopifnot(identical(M, Diagonal(x=c(1,1, 0, 1,1))),
+           isValid(T, "triangularMatrix"), identical(T[,3], c(10,10,10,0,0)))
> 
> M <- m1; M[1,] <- 0 ; M ; assert.EQ.mat(M, diag(c(0,rep(1,4))), tol=0)
5 x 5 sparse Matrix of class "dtTMatrix"
              
[1,] . . . . .
[2,] . 1 . . .
[3,] . . 1 . .
[4,] . . . 1 .
[5,] . . . . 1
> M <- m1; M[,3] <- 3 ; stopifnot(is(M,"sparseMatrix"), M[,3] == 3)
M[i,j] <- v :  coercing symmetric M[] into non-symmetric
> Z <- m1; Z[] <- 0
> checkMatrix(M)
 norm(m [5 x 5]) : 1  I  F  M  ok
 Summary:  ok
as(., "nMatrix") giving full nonzero-pattern: ok
2*m =?= m+m: Note: method with signature 'sparseMatrix#ldiMatrix' chosen for function '&',
 target signature 'nsCMatrix#ldiMatrix'.
 "nsparseMatrix#sparseMatrix", "nMatrix#lMatrix" would also be valid
ok
m >= m for all: ok
m < m for none: ok
symmpart(m) + skewpart(m) == m: ok;  determinant(): ok
> M <- m1; M[1:3, 3] <- 0 ;M
5 x 5 sparse Matrix of class "dtTMatrix"
              
[1,] 1 . . . .
[2,] . 1 . . .
[3,] . . . . .
[4,] . . . 1 .
[5,] . . . . 1
> assert.EQ.mat(M, diag(c(1,1, 0, 1,1)), tol=0)
> T <- m1; T[1:3, 3] <- 10; checkMatrix(T)
 norm(m [5 x 5]) : 1  I  F  M  ok
 Summary:  ok
as(., "nMatrix") giving full nonzero-pattern: ok
2*m =?= m+m: identical
m >= m for all: ok
m < m for none: ok
symmpart(m) + skewpart(m) == m: ok;  determinant(): ok
diagnosing replTmat(x,i,j,v): nargs()= 3; missing (i,j) = (0,1)
'sub-optimal sparse 'x[i] <- v' assignment: Coercing class dtTMatrix to dgTMatrix
as(<triangular (ge)matrix>, dtTMatrix): valid: TRUE 
> stopifnot(is(T, "triangularMatrix"), identical(T[,3], c(10,10,10,0,0)),
+ 	  Qidentical(as(Z, "matrix"), z))
> 
> M <- m2; M[1,] <- 0 ; M ; assert.EQ.mat(M, diag(c(0,rep(1,4))), tol=0)
5 x 5 sparse Matrix of class "dtCMatrix"
              
[1,] . . . . .
[2,] . 1 . . .
[3,] . . 1 . .
[4,] . . . 1 .
[5,] . . . . 1
> M <- m2; M[,3] <- 3 ; stopifnot(is(M,"sparseMatrix"), M[,3] == 3)
> checkMatrix(M)
 norm(m [5 x 5]) : 1  I  F  M  ok
 Summary:  ok
as(., "nMatrix") giving full nonzero-pattern: ok
2*m =?= m+m: identical
m >= m for all: ok
m < m for none: ok
symmpart(m) + skewpart(m) == m: ok;  determinant(): ok
> Z <- m2; Z[] <- 0
> M <- m2; M[1:3, 3] <- 0 ;M
5 x 5 sparse Matrix of class "dtCMatrix"
              
[1,] 1 . . . .
[2,] . 1 . . .
[3,] . . . . .
[4,] . . . 1 .
[5,] . . . . 1
> assert.EQ.mat(M, diag(c(1,1, 0, 1,1)), tol=0)
> T <- m2; T[1:3, 3] <- 10; checkMatrix(T)
 norm(m [5 x 5]) : 1  I  F  M  ok
 Summary:  ok
as(., "nMatrix") giving full nonzero-pattern: ok
2*m =?= m+m: identical
m >= m for all: ok
m < m for none: ok
symmpart(m) + skewpart(m) == m: ok;  determinant(): ok
diagnosing replTmat(x,i,j,v): nargs()= 3; missing (i,j) = (0,1)
'sub-optimal sparse 'x[i] <- v' assignment: Coercing class dtTMatrix to dgTMatrix
as(<triangular (ge)matrix>, dtCMatrix): valid: TRUE 
> stopifnot(is(T, "dtCMatrix"), identical(T[,3], c(10,10,10,0,0)),
+ 	  Qidentical(as(Z, "matrix"), z))
> showProc.time()
Time elapsed:  0.75 0.002 0.756 
> 
> 
> ## "Vector indices" -------------------
> asLogical <- function(x) {
+     stopifnot(is.atomic(x))
+     storage.mode(x) <- "logical"
+     x
+ }
> .iniDiag.example <- expression({
+     D <- Diagonal(6)
+     M <- as(D,"dgeMatrix")
+     m <- as(D,"matrix")
+     s <- as(D,"TsparseMatrix"); N <- as(s,"nMatrix")
+     S <- as(s,"CsparseMatrix"); C <- as(S,"nMatrix")
+ })
> eval(.iniDiag.example)
> i <- c(3,1,6); v <- c(10,15,20)
> ## (logical,value) which both are recycled:
> L <- c(TRUE, rep(FALSE,8)) ; z <- c(50,99)
> 
> ## vector subassignment, both with integer & logical
> ## these now work correctly {though not very efficiently; hence warnings}
> m[i] <- v # the role model: only first column is affected
> M[i] <- v; assert.EQ.mat(M,m) # dge
> D[i] <- v; assert.EQ.mat(D,m) # ddi -> dtT -> dgT
diagnosing replTmat(x,i,j,v): nargs()= 3; missing (i,j) = (0,1)
'sub-optimal sparse 'x[i] <- v' assignment: Coercing class dtTMatrix to dgTMatrix
> s[i] <- v; assert.EQ.mat(s,m) # dtT -> dgT
diagnosing replTmat(x,i,j,v): nargs()= 3; missing (i,j) = (0,1)
'sub-optimal sparse 'x[i] <- v' assignment: Coercing class dtTMatrix to dgTMatrix
> S[i] <- v; assert.EQ.mat(S,m); S # dtC -> dtT -> dgT -> dgC
diagnosing replTmat(x,i,j,v): nargs()= 3; missing (i,j) = (0,1)
'sub-optimal sparse 'x[i] <- v' assignment: Coercing class dtTMatrix to dgTMatrix
6 x 6 sparse Matrix of class "dgCMatrix"
                 
[1,] 15 . . . . .
[2,]  . 1 . . . .
[3,] 10 . 1 . . .
[4,]  . . . 1 . .
[5,]  . . . . 1 .
[6,] 20 . . . . 1
> m.L <- asLogical(m)
> C[i] <- v; assert.EQ.mat(C,m.L); validObject(C)
diagnosing replTmat(x,i,j,v): nargs()= 3; missing (i,j) = (0,1)
'sub-optimal sparse 'x[i] <- v' assignment: Coercing class ntTMatrix to ngTMatrix
Warning in `[<-`(`*tmp*`, i, value = c(10, 15, 20)) :
  x[.] <- val: x is "ngTMatrix", val not in {TRUE, FALSE} is coerced.
[1] TRUE
> N[i] <- v; assert.EQ.mat(N,m.L); validObject(N)
diagnosing replTmat(x,i,j,v): nargs()= 3; missing (i,j) = (0,1)
'sub-optimal sparse 'x[i] <- v' assignment: Coercing class ntTMatrix to ngTMatrix
Warning in `[<-`(`*tmp*`, i, value = c(10, 15, 20)) :
  x[.] <- val: x is "ngTMatrix", val not in {TRUE, FALSE} is coerced.
[1] TRUE
> stopifnot(Q.C.identical(D,s, checkClass=FALSE))
> ## logical *vector* indexing
> eval(.iniDiag.example)
> m[L] <- z; m.L <- asLogical(m)
> M[L] <- z; assert.EQ.mat(M,m)
> D[L] <- z; assert.EQ.mat(D,m)
diagnosing replTmat(x,i,j,v): nargs()= 3; missing (i,j) = (0,1)
'sub-optimal sparse 'x[i] <- v' assignment: Coercing class dtTMatrix to dgTMatrix
> s[L] <- z; assert.EQ.mat(s,m)
diagnosing replTmat(x,i,j,v): nargs()= 3; missing (i,j) = (0,1)
'sub-optimal sparse 'x[i] <- v' assignment: Coercing class dtTMatrix to dgTMatrix
> S[L] <- z; assert.EQ.mat(S,m) ; S
diagnosing replTmat(x,i,j,v): nargs()= 3; missing (i,j) = (0,1)
'sub-optimal sparse 'x[i] <- v' assignment: Coercing class dtTMatrix to dgTMatrix
6 x 6 sparse Matrix of class "dgCMatrix"
                    
[1,] 50  . . 50  . .
[2,]  .  1 .  .  . .
[3,]  .  . 1  .  . .
[4,]  . 99 .  1 99 .
[5,]  .  . .  .  1 .
[6,]  .  . .  .  . 1
> C[L] <- z; assert.EQ.mat(C,m.L)
diagnosing replTmat(x,i,j,v): nargs()= 3; missing (i,j) = (0,1)
'sub-optimal sparse 'x[i] <- v' assignment: Coercing class ntTMatrix to ngTMatrix
Warning in `[<-`(`*tmp*`, i, value = c(50, 99)) :
  x[.] <- val: x is "ngTMatrix", val not in {TRUE, FALSE} is coerced.
> N[L] <- z; assert.EQ.mat(N,m.L)
diagnosing replTmat(x,i,j,v): nargs()= 3; missing (i,j) = (0,1)
'sub-optimal sparse 'x[i] <- v' assignment: Coercing class ntTMatrix to ngTMatrix
Warning in `[<-`(`*tmp*`, L, value = c(50, 99)) :
  x[.] <- val: x is "ngTMatrix", val not in {TRUE, FALSE} is coerced.
> 
> 
> ## indexing [i]  vs  [i,] --- now ok
> eval(.iniDiag.example)
> stopifnot(identical5(m[i], M[i], D[i], s[i], S[i]), identical3(as.logical(m[i]), C[i], N[i]),
+           identical5(m[L], M[L], D[L], s[L], S[L]), identical3(as.logical(m[L]), C[L], N[L]))
<sparse>[ <logic> ] : .M.sub.i.logical() maybe inefficient
<sparse>[ <logic> ] : .M.sub.i.logical() maybe inefficient
<sparse>[ <logic> ] : .M.sub.i.logical() maybe inefficient
<sparse>[ <logic> ] : .M.sub.i.logical() maybe inefficient
<sparse>[ <logic> ] : .M.sub.i.logical() maybe inefficient
> ## bordercase ' drop = .' *vector* indexing {failed till 2009-04-..)
> stopifnot(identical5(m[i,drop=FALSE], M[i,drop=FALSE], D[i,drop=FALSE],
+ 		     s[i,drop=FALSE], S[i,drop=FALSE]),
+ 	  identical3(as.logical(m[i,drop=FALSE]),
+ 		     C[i,drop=FALSE], N[i,drop=FALSE]))
> stopifnot(identical5(m[L,drop=FALSE], M[L,drop=FALSE], D[L,drop=FALSE],
+ 		     s[L,drop=FALSE], S[L,drop=FALSE]),
+ 	  identical3(as.logical(m[L,drop=FALSE]),
+ 		     C[L,drop=FALSE], N[L,drop=FALSE]))
> ## using L for row-indexing should give an error
> assertError(m[L,]); assertError(m[L,, drop=FALSE])
> ## these did not signal an error, upto (including) 0.999375-30:
> assertError(s[L,]); assertError(s[L,, drop=FALSE])
> assertError(S[L,]); assertError(S[L,, drop=FALSE])
> assertError(N[L,]); assertError(N[L,, drop=FALSE])
> 
> ## row indexing:
> assert.EQ.mat(D[i,], m[i,])
> assert.EQ.mat(M[i,], m[i,])
> assert.EQ.mat(s[i,], m[i,])
> assert.EQ.mat(S[i,], m[i,])
> assert.EQ.mat(C[i,], asLogical(m[i,]))
> assert.EQ.mat(N[i,], asLogical(m[i,]))
> ## column indexing:
> assert.EQ.mat(D[,i], m[,i])
> assert.EQ.mat(M[,i], m[,i])
> assert.EQ.mat(s[,i], m[,i])
> assert.EQ.mat(S[,i], m[,i])
> assert.EQ.mat(C[,i], asLogical(m[,i]))
> assert.EQ.mat(N[,i], asLogical(m[,i]))
> 
> 
> ### --- negative indices ----------
> 
> ## 1) negative *vector* indexing
> eval(.iniDiag.example)
> i <- -(2:30)
> stopifnot(identical5(m[i], M[i], D[i], s[i], S[i]),
+           identical3(as.logical(m[i]), C[i], N[i]))
> ##  negative vector subassignment :
> v <- seq_along(m[i])
> m[i] <- v; m.L <- asLogical(m)
> M[i] <- v; assert.EQ.mat(M,m) # dge
> D[i] <- v; assert.EQ.mat(D,m) # ddi -> dtT -> dgT
diagnosing replTmat(x,i,j,v): nargs()= 3; missing (i,j) = (0,1)
'sub-optimal sparse 'x[i] <- v' assignment: Coercing class dtTMatrix to dgTMatrix
> s[i] <- v; assert.EQ.mat(s,m) # dtT -> dgT
diagnosing replTmat(x,i,j,v): nargs()= 3; missing (i,j) = (0,1)
'sub-optimal sparse 'x[i] <- v' assignment: Coercing class dtTMatrix to dgTMatrix
> S[i] <- v; assert.EQ.mat(S,m); S # dtC -> dtT -> dgT -> dgC
diagnosing replTmat(x,i,j,v): nargs()= 3; missing (i,j) = (0,1)
'sub-optimal sparse 'x[i] <- v' assignment: Coercing class dtTMatrix to dgTMatrix
6 x 6 sparse Matrix of class "dgCMatrix"
                
[1,] 1 . . . . 2
[2,] . 1 . . . 3
[3,] . . 1 . . 4
[4,] . . . 1 . 5
[5,] . . . . 1 6
[6,] . . . . . 7
> N[i] <- v; assert.EQ.mat(N,m.L); N #
diagnosing replTmat(x,i,j,v): nargs()= 3; missing (i,j) = (0,1)
'sub-optimal sparse 'x[i] <- v' assignment: Coercing class ntTMatrix to ngTMatrix
Warning in `[<-`(`*tmp*`, i, value = 1:7) :
  x[.] <- val: x is "ngTMatrix", val not in {TRUE, FALSE} is coerced.
6 x 6 sparse Matrix of class "ngTMatrix"
                
[1,] | . . . . |
[2,] . | . . . |
[3,] . . | . . |
[4,] . . . | . |
[5,] . . . . | |
[6,] . . . . . |
> C[i] <- v; assert.EQ.mat(C,m.L); C #
diagnosing replTmat(x,i,j,v): nargs()= 3; missing (i,j) = (0,1)
'sub-optimal sparse 'x[i] <- v' assignment: Coercing class ntTMatrix to ngTMatrix
Warning in `[<-`(`*tmp*`, i, value = 1:7) :
  x[.] <- val: x is "ngTMatrix", val not in {TRUE, FALSE} is coerced.
6 x 6 sparse Matrix of class "ngCMatrix"
                
[1,] | . . . . |
[2,] . | . . . |
[3,] . . | . . |
[4,] . . . | . |
[5,] . . . . | |
[6,] . . . . . |
> 
> 
> ## 2) negative [i,j] indices
> mc <- mC[1:5, 1:7]
> mt <- mT[1:5, 1:7]
> ## sub matrix
> assert.EQ.mat(mC[1:2, 0:3], mm[1:2, 0:3]) # test 0-index
> stopifnot(identical(mc[-(3:5), 0:2], mC[1:2, 0:2]),
+           identical(mt[-(3:5), 0:2], mT[1:2, 0:2]),
+           identical(mC[2:3, 4],      mm[2:3, 4]))
> assert.EQ.mat(mC[1:2,], mm[1:2,])
> ## sub vector
> stopifnot(identical4(mc[-(1:4), ], mC[5, 1:7],
+                      mt[-(1:4), ], mT[5, 1:7]))
> stopifnot(identical4(mc[-(1:4), -(2:4)], mC[5, c(1,5:7)],
+                      mt[-(1:4), -(2:4)], mT[5, c(1,5:7)]))
> 
> ## mixing of negative and positive must give error
> assertError(mT[-1:1,])
> showProc.time()
Time elapsed:  0.183 0 0.184 
> 
> ## Sub *Assignment* ---- now works (partially):
> mt0 <- mt
> nt <- as(mt, "nMatrix")
> mt[1, 4] <- -99
> mt[2:3, 1:6] <- 0
> mt
5 x 7 sparse Matrix of class "dgTMatrix"
   c1 c2 c3  c4 c5 c6  c7
r1  .  .  . -99  .  . 241
r2  .  .  .   .  .  .   .
r3  .  .  .   .  .  . 243
r4  .  .  .   .  .  .   .
r5  . 45  .   .  .  .   .
> m2 <- mt+mt
> m2[1,4] <- -200
> m2[c(1,3), c(5:6,2)] <- 1:6
> stopifnot(m2[1,4] == -200,
+           as.vector(m2[c(1,3), c(5:6,2)]) == 1:6)
> mt[,3] <- 30
> mt[2:3,] <- 250
> mt[1:5 %% 2 == 1, 3] <- 0
> mt[3:1, 1:7 > 5] <- 0
> mt
5 x 7 sparse Matrix of class "dgTMatrix"
    c1  c2  c3  c4  c5 c6 c7
r1   .   .   . -99   .  .  .
r2 250 250 250 250 250  .  .
r3 250 250   . 250 250  .  .
r4   .   .  30   .   .  .  .
r5   .  45   .   .   .  .  .
> 
> tt <- as(mt,"matrix")
> ii <- c(0,2,5)
> jj <- c(2:3,5)
> tt[ii, jj] <- 1:6 # 0 is just "dropped"
> mt[ii, jj] <- 1:6
> assert.EQ.mat(mt, tt)
> 
> mt[1:5, 2:6]
5 x 5 sparse Matrix of class "dgTMatrix"
    c2 c3  c4  c5 c6
r1   .  . -99   .  .
r2   1  3 250   5  .
r3 250  . 250 250  .
r4   . 30   .   .  .
r5   2  4   .   6  .
> as((mt0 - mt)[1:5,], "dsparseMatrix")# [1,5] and lines 2:3
5 x 7 sparse Matrix of class "dgCMatrix"
     c1   c2  c3   c4   c5  c6  c7
r1    .    .   .  220    .   . 241
r2 -250   41  -3 -250   -5 202   .
r3 -247 -250   . -250 -250   . 243
r4    .    . -30    .    .   .   .
r5    .   43  -4    .   -6   .   .
> 
> mt[c(2,4), ] <- 0; stopifnot(as(mt[c(2,4), ],"matrix") == 0)
> mt[2:3, 4:7] <- 33
> checkMatrix(mt)
 norm(m [5 x 7]) : 1  I  F  M  ok
 Summary:  ok
as(., "nMatrix") giving full nonzero-pattern: ok
2*m =?= m+m: ok
m >= m for all: ok
m < m for none: ok
> mt
5 x 7 sparse Matrix of class "dgTMatrix"
    c1  c2 c3  c4 c5 c6 c7
r1   .   .  . -99  .  .  .
r2   .   .  .  33 33 33 33
r3 250 250  .  33 33 33 33
r4   .   .  .   .  .  .  .
r5   .   2  4   .  6  .  .
> 
> mc[1,4] <- -99 ; stopifnot(mc[1,4] == -99)
> mc[1,4] <-  00 ; stopifnot(mc[1,4] ==  00)
> mc[1,4] <- -99 ; stopifnot(mc[1,4] == -99)
> mc[1:2,4:3] <- 4:1; stopifnot(as.matrix(mc[1:2,4:3]) == 4:1)
> 
> mc[-1, 3] <- -2:1 # 0 should not be entered; 'value' recycled
> mt[-1, 3] <- -2:1
> stopifnot(mc@x != 0, mt@x != 0,
+ 	  mc[-1,3] == -2:1, mt[-1,3] == -2:1) ## failed earlier
> 
> mc0 <- mc
> mt0 <- as(mc0, "TsparseMatrix")
> m0  <- as(mc0, "matrix")
> set.seed(1); options(Matrix.verbose = FALSE)
> for(i in 1:(if(doExtras) 50 else 4)) {
+     mc <- mc0; mt <- mt0 ; m <- m0
+     ev <- 1:5 %% 2 == round(runif(1))# 0 or 1
+     j <- sample(ncol(mc), 1 + round(runif(1)))
+     nv <- rpois(sum(ev) * length(j), lambda = 1)
+     mc[ev, j] <- nv
+      m[ev, j] <- nv
+     mt[ev, j] <- nv
+     if(i %% 10 == 1) print(mc[ev,j, drop = FALSE])
+     stopifnot(as.vector(mc[ev, j]) == nv, ## failed earlier...
+               as.vector(mt[ev, j]) == nv)
+     validObject(mc) ; assert.EQ.mat(mc, m)
+     validObject(mt) ; assert.EQ.mat(mt, m)
+ }
2 x 1 sparse Matrix of class "dgCMatrix"
   c5
r2  2
r4  .
> showProc.time()
Time elapsed:  0.157 0.001 0.158 
> options(Matrix.verbose = TRUE)
> 
> mc # no longer has non-structural zeros
5 x 7 sparse Matrix of class "dgCMatrix"
   c1 c2 c3 c4 c5  c6  c7
r1  .  .  2  4  .   . 241
r2  . 42  .  3  . 202   .
r3  3  . -1  .  .   . 243
r4  .  .  1  .  .   .   .
r5  . 45  1  .  .   .   .
> mc[ii, jj] <- 1:6
> mc[c(2,5), c(3,5)] <- 3.2
> checkMatrix(mc)
 norm(m [5 x 7]) : 1  I  F  M  ok
 Summary:  ok
as(., "nMatrix") giving full nonzero-pattern: ok
2*m =?= m+m: identical
m >= m for all: ok
m < m for none: ok
> m. <- mc
> mc[4,] <- 0
> mc
5 x 7 sparse Matrix of class "dgCMatrix"
   c1 c2   c3 c4  c5  c6  c7
r1  .  .  2.0  4 .     . 241
r2  .  1  3.2  3 3.2 202   .
r3  3  . -1.0  . .     . 243
r4  .  .  .    . .     .   .
r5  .  2  3.2  . 3.2   .   .
> 
> S <- as(Diagonal(5),"TsparseMatrix")
> H <- Hilbert(9)
> Hc <- as(round(H, 3), "dsCMatrix")# a sparse matrix with no 0 ...
> (trH <- tril(Hc[1:5, 1:5]))
5 x 5 sparse Matrix of class "dtCMatrix"
                                  
[1,] 1.000 .     .     .     .    
[2,] 0.500 0.333 .     .     .    
[3,] 0.333 0.250 0.200 .     .    
[4,] 0.250 0.200 0.167 0.143 .    
[5,] 0.200 0.167 0.143 0.125 0.111
> stopifnot(is(trH, "triangularMatrix"), trH@uplo == "L",
+           is(S, "triangularMatrix"))
> 
> ## triangular assignment
> ## the slick (but inefficient in case of sparse!) way to assign sub-diagonals:
> ## equivalent to tmp <- `diag<-`(S[,-1], -2:1); S[,-1] <- tmp
> ## which dispatches to (x="TsparseMatrix", i="missing",j="index", value="replValue")
> diag(S[,-1]) <- -2:1 # used to give a wrong warning
M[i,j] <- v :  coercing symmetric M[] into non-symmetric
> S <- as(S,"triangularMatrix")
> assert.EQ.mat(S, local({s <- diag(5); diag(s[,-1]) <- -2:1; s}))
> 
> trH[c(1:2,4), c(2:3,5)] <- 0 # gave an *error* upto Jan.2008
> trH[ lower.tri(trH) ] <- 0   # ditto, because of callNextMethod()
diagnosing replTmat(x,i,j,v): nargs()= 3; missing (i,j) = (0,1)
'sub-optimal sparse 'x[i] <- v' assignment: Coercing class dtTMatrix to dgTMatrix
> 
> m <- Matrix(0+1:28, nrow = 4)
> m[-3,c(2,4:5,7)] <- m[ 3, 1:4] <- m[1:3, 6] <- 0
> mT <- as(m, "dgTMatrix")
> stopifnot(identical(mT[lower.tri(mT)],
+                     m [lower.tri(m) ]))
<sparse>[ <logic> ] : .M.sub.i.logical() maybe inefficient
> lM <- upper.tri(mT, diag=TRUE)
> mT[lM] <- 0
diagnosing replTmat(x,i,j,v): nargs()= 3; missing (i,j) = (0,1)
>  m[lM] <- 0
> assert.EQ.mat(mT, as(m,"matrix"))
> mT[lM] <- -1:0
diagnosing replTmat(x,i,j,v): nargs()= 3; missing (i,j) = (0,1)
>  m[lM] <- -1:0
> assert.EQ.mat(mT, as(m,"matrix"))
> (mT <- drop0(mT))
4 x 7 sparse Matrix of class "dgCMatrix"
                         
[1,] -1  .  . -1 -1 -1 -1
[2,]  2 -1 -1  .  .  .  .
[3,]  .  .  . -1 -1 -1 -1
[4,]  4  . 12  .  .  .  .
> 
> i <- c(1:2, 4, 6:7); j <- c(2:4,6)
> H[i,j] <- 0
> (H. <- round(as(H, "sparseMatrix"), 3)[ , 2:7])
9 x 6 sparse Matrix of class "dgCMatrix"
                                         
 [1,] .     .     .     0.200 .     0.143
 [2,] .     .     .     0.167 .     0.125
 [3,] 0.250 0.200 0.167 0.143 0.125 0.111
 [4,] .     .     .     0.125 .     0.100
 [5,] 0.167 0.143 0.125 0.111 0.100 0.091
 [6,] .     .     .     0.100 .     0.083
 [7,] .     .     .     0.091 .     0.077
 [8,] 0.111 0.100 0.091 0.083 0.077 0.071
 [9,] 0.100 0.091 0.083 0.077 0.071 0.067
> Hc. <- Hc
> Hc.[i,j] <- 0 ## now "works", but setting "non-structural" 0s
> stopifnot(as.matrix(Hc.[i,j]) == 0)
> Hc.[, 1:6]
9 x 6 sparse Matrix of class "dgCMatrix"
                                         
 [1,] 1.000 .     .     .     0.200 .    
 [2,] 0.500 .     .     .     0.167 .    
 [3,] 0.333 0.250 0.200 0.167 0.143 0.125
 [4,] 0.250 .     .     .     0.125 .    
 [5,] 0.200 0.167 0.143 0.125 0.111 0.100
 [6,] 0.167 .     .     .     0.100 .    
 [7,] 0.143 .     .     .     0.091 .    
 [8,] 0.125 0.111 0.100 0.091 0.083 0.077
 [9,] 0.111 0.100 0.091 0.083 0.077 0.071
> 
> ## an example that failed for a long time
> sy3 <- new("dsyMatrix", Dim = as.integer(c(2, 2)), x = c(14, -1, 2, -7))
> checkMatrix(dm <- kronecker(Diagonal(2), sy3))# now sparse with new kronecker
Note: method with signature 'sparseMatrix#ANY' chosen for function 'kronecker',
 target signature 'dtTMatrix#dsyMatrix'.
 "ANY#Matrix" would also be valid
 norm(m [4 x 4]) : 1  I  F  M  ok
 Summary:  ok
as(., "nMatrix") giving full nonzero-pattern: ok
2*m =?= m+m: ok
m >= m for all: ok
m < m for none: ok
symmpart(m) + skewpart(m) == m: ok;  determinant(): ok
> dm <- Matrix(as.matrix(dm))# -> "dsyMatrix"
> (s2 <- as(dm, "sparseMatrix"))
4 x 4 sparse Matrix of class "dsCMatrix"
                
[1,] 14  2  .  .
[2,]  2 -7  .  .
[3,]  .  . 14  2
[4,]  .  .  2 -7
> checkMatrix(st <- as(s2, "TsparseMatrix"))
 norm(m [4 x 4]) : 1  I  F  M  ok
 Summary:  ok
as(., "nMatrix") giving full nonzero-pattern: ok
2*m =?= m+m: suboptimal 'Arith' implementation of  'dsC*  o  dsC*'
identical
m >= m for all: ok
m < m for none: ok
symmpart(m) + skewpart(m) == m: suboptimal 'Arith' implementation of  'dsC*  o  dsC*'
ok;  determinant(): ok
> stopifnot(is(s2, "symmetricMatrix"),
+ 	  is(st, "symmetricMatrix"))
> checkMatrix(s.32  <- st[1:3,1:2]) ## 3 x 2 - and *not* dsTMatrix
 norm(m [3 x 2]) : 1  I  F  M  ok
 Summary:  ok
as(., "nMatrix") giving full nonzero-pattern: ok
2*m =?= m+m: ok
m >= m for all: ok
m < m for none: ok
> checkMatrix(s2.32 <- s2[1:3,1:2])
 norm(m [3 x 2]) : 1  I  F  M  ok
 Summary:  ok
as(., "nMatrix") giving full nonzero-pattern: ok
2*m =?= m+m: identical
m >= m for all: ok
m < m for none: ok
> I <- c(1,4:3)
> stopifnot(is(s2.32, "generalMatrix"),
+           is(s.32,  "generalMatrix"),
+           identical(as.mat(s.32), as.mat(s2.32)),
+           identical3(dm[1:3,-1], asD(s2[1:3,-1]), asD(st[1:3,-1])),
+           identical4(2, dm[4,3], s2[4,3], st[4,3]),
+           identical3(diag(dm), diag(s2), diag(st)),
+           is((cI <- s2[I,I]), "dsCMatrix"),
+           is((tI <- st[I,I]), "dsTMatrix"),
+           identical4(as.mat(dm)[I,I], as.mat(dm[I,I]), as.mat(tI), as.mat(cI))
+           )
> 
> ## now sub-assign  and check for consistency
> ## symmetric subassign should keep symmetry
> st[I,I] <- 0; checkMatrix(st); stopifnot(is(st,"symmetricMatrix"))
 norm(m [4 x 4]) : 1  I  F  M  ok
 Summary:  ok
as(., "nMatrix") giving full nonzero-pattern: ok
2*m =?= m+m: suboptimal 'Arith' implementation of  'dsC*  o  dsC*'
identical
m >= m for all: ok
m < m for none: ok
symmpart(m) + skewpart(m) == m: suboptimal 'Arith' implementation of  'dsC*  o  dsC*'
ok;  determinant(): ok
> s2[I,I] <- 0; checkMatrix(s2); stopifnot(is(s2,"symmetricMatrix"))
 norm(m [4 x 4]) : 1  I  F  M  ok
 Summary:  ok
as(., "nMatrix") giving full nonzero-pattern: ok
2*m =?= m+m: suboptimal 'Arith' implementation of  'dsC*  o  dsC*'
identical
m >= m for all: ok
m < m for none: ok
symmpart(m) + skewpart(m) == m: suboptimal 'Arith' implementation of  'dsC*  o  dsC*'
ok;  determinant(): ok
> ##
> m <- as.mat(st)
>  m[2:1,2:1] <- 4:1
> st[2:1,2:1] <- 4:1
M[i,j] <- v :  coercing symmetric M[] into non-symmetric
> s2[2:1,2:1] <- 4:1
> stopifnot(identical(m, as.mat(st)),
+ 	  1:4 == as.vector(s2[1:2,1:2]),
+ 	  identical(m, as.mat(s2)))
> 
> ## now a slightly different situation for 's2' (had bug)
> s2 <- as(dm, "sparseMatrix")
> s2[I,I] <- 0; diag(s2)[2:3] <- -(1:2)
> stopifnot(is(s2,"symmetricMatrix"), diag(s2) == c(0:-2,0))
> t2 <- as(s2, "TsparseMatrix")
> m <- as.mat(s2)
> s2[2:1,2:1] <- 4:1
> t2[2:1,2:1] <- 4:1
M[i,j] <- v :  coercing symmetric M[] into non-symmetric
>  m[2:1,2:1] <- 4:1
> assert.EQ.mat(t2, m)
> assert.EQ.mat(s2, m)
> ## and the same (for a different s2 !)
> s2[2:1,2:1] <- 4:1
> t2[2:1,2:1] <- 4:1
> assert.EQ.mat(t2, m)# ok
> assert.EQ.mat(s2, m)# failed in 0.9975-8
> showProc.time()
Time elapsed:  0.709 0.001 0.713 
> 
> 
> ## m[cbind(i,j)] <- value: (2-column matrix subassignment):
> m.[ cbind(3:5, 1:3) ] <- 1:3
> stopifnot(m.[3,1] == 1, m.[4,2] == 2)
> nt. <- nt ; nt[rbind(2:3, 3:4, c(3,3))] <- FALSE
> s. <- m. ; m.[cbind(3,4:6)] <- 0 ## assigning 0 where there *is* 0 ..
> stopifnot(identical(nt.,nt),       ## should not have changed
+ 	  identical(s., m.))
> x.x[ cbind(2:6, 2:6)] <- 12:16
> stopifnot(isValid(x.x, "dsCMatrix"),
+ 	  12:16 == as.mat(x.x)[cbind(2:6, 2:6)])
> (ne1 <- (mc - m.) != 0)
5 x 7 sparse Matrix of class "lgCMatrix"
   c1 c2 c3 c4 c5 c6 c7
r1  .  .  :  :  .  .  :
r2  .  :  :  :  :  :  .
r3  |  .  :  .  .  .  :
r4  .  |  |  .  .  .  .
r5  .  :  |  .  :  .  .
> stopifnot(identical(ne1, 0 != abs(mc - m.)))
> (ge <- m. >= mc) # contains "=" -> result is dense
5 x 7 Matrix of class "lgeMatrix"
      c1   c2    c3   c4   c5   c6   c7
r1  TRUE TRUE  TRUE TRUE TRUE TRUE TRUE
r2  TRUE TRUE  TRUE TRUE TRUE TRUE TRUE
r3 FALSE TRUE  TRUE TRUE TRUE TRUE TRUE
r4  TRUE TRUE  TRUE TRUE TRUE TRUE TRUE
r5  TRUE TRUE FALSE TRUE TRUE TRUE TRUE
> ne. <- mc != m.  # was wrong (+ warning)
> stopifnot(identical(!(m. < mc), m. >= mc),
+ 	  identical(m. < mc, as(!ge, "sparseMatrix")),
+ 	  identical(ne., drop0(ne1)))
> 
> d6 <- Diagonal(6)
> ii <- c(1:2, 4:5)
> d6[cbind(ii,ii)] <- 7*ii
> stopifnot(is(d6, "ddiMatrix"), identical(d6, Diagonal(x=c(7*1:2,1,7*4:5,1))))
> 
> for(j in 3:6) { ## even and odd j used to behave differently
+     M <- Matrix(0, j,j); m <- matrix(0, j,j)
+     T  <- as(M, "TsparseMatrix")
+     TG <- as(T, "generalMatrix")
+     G <-  as(M, "generalMatrix")
+     id <- cbind(1:j,1:j)
+     i2 <- cbind(1:j,j:1)
+     m[id] <- 1:j
+     M[id] <- 1:j ; stopifnot(is(M,"symmetricMatrix"))
+     T[id] <- 1:j ; stopifnot(is(T,"symmetricMatrix"))
+     G[id] <- 1:j
+     TG[id]<- 1:j
+     m[i2] <- 10
+     M[i2] <- 10 ; stopifnot(is(M,"symmetricMatrix"))
+     T[i2] <- 10 ; stopifnot(is(T,"symmetricMatrix"))
+     G[i2] <- 10
+     TG[i2]<- 10
+     ##
+     assert.EQ.mat(M, m)
+     assert.EQ.mat(T, m)
+     assert.EQ.mat(G, m)
+     assert.EQ.mat(TG,m)
+ }
> 
> 
> ## drop, triangular, ...
> (M3 <- Matrix(upper.tri(matrix(, 3, 3)))) # ltC; indexing used to fail
3 x 3 sparse Matrix of class "ltCMatrix"
          
[1,] . | |
[2,] . . |
[3,] . . .
> T3 <- as(M3, "TsparseMatrix")
> stopifnot(identical(drop(M3), M3),
+ 	  identical4(drop(M3[,2, drop = FALSE]), M3[,2, drop = TRUE],
+ 		     drop(T3[,2, drop = FALSE]), T3[,2, drop = TRUE]),
+ 	  is(T3, "triangularMatrix"),
+ 	  !is(T3[,2, drop=FALSE], "triangularMatrix")
+ 	  )
> 
> (T6 <- as(as(kronecker(Matrix(c(0,0,1,0),2,2), t(T3)), "lMatrix"),
+ 	  "triangularMatrix"))
6 x 6 sparse Matrix of class "ltTMatrix"
                
[1,] . . . . . .
[2,] . . . | . .
[3,] . . . | | .
[4,] . . . . . .
[5,] . . . . . .
[6,] . . . . . .
> T6[1:4, -(1:3)] # failed (trying to coerce back to ltTMatrix)
4 x 3 sparse Matrix of class "lgTMatrix"
          
[1,] . . .
[2,] | . .
[3,] | | .
[4,] . . .
> stopifnot(identical(T6[1:4, -(1:3)][2:3, -3],
+ 		    spMatrix(2,2, i=c(1,2,2), j=c(1,1,2), x=rep(TRUE,3))))
> 
> M <- Diagonal(4); M[1,2] <- 2
> M. <- as(M, "CsparseMatrix")
> (R <- as(M., "RsparseMatrix"))
4 x 4 sparse Matrix of class "dtRMatrix" (unitriangular)
            
[1,] 1 2 . .
[2,] . 1 . .
[3,] . . 1 .
[4,] . . . 1
> (Ms <- symmpart(M.))
4 x 4 sparse Matrix of class "dsCMatrix"
            
[1,] 1 1 . .
[2,] 1 1 . .
[3,] . . 1 .
[4,] . . . 1
> Rs <- as(Ms, "RsparseMatrix")
> stopifnot(isValid(M, "triangularMatrix"),
+           isValid(M.,"triangularMatrix"),
+           isValid(Ms, "dsCMatrix"),
+           isValid(R,  "dtRMatrix"),
+           isValid(Rs, "dsRMatrix") )
> stopifnot(dim(M[2:3, FALSE]) == c(2,0),
+           dim(R[2:3, FALSE]) == c(2,0),
+           identical(M [2:3,TRUE], M [2:3,]),
+           identical(M.[2:3,TRUE], M.[2:3,]),
+           identical(R [2:3,TRUE], R [2:3,]),
+           dim(R[FALSE, FALSE]) == c(0,0))
> 
> n <- 50000L
> Lrg <- new("dgTMatrix", Dim = c(n,n))
> diag(Lrg) <- 1:n
> dLrg <- as(Lrg, "diagonalMatrix")
> stopifnot(identical(Diagonal(x = 1:n), dLrg))
> diag(dLrg) <- 1 + diag(dLrg)
> Clrg <- as(Lrg,"CsparseMatrix")
> Ctrg <- as(Clrg, "triangularMatrix")
> diag(Ctrg) <- 1 + diag(Ctrg)
> stopifnot(identical(Diagonal(x = 1+ 1:n), dLrg),
+           identical(Ctrg, as(dLrg,"CsparseMatrix")))
> 
> cc <- capture.output(show(dLrg))# show(<diag>) used to error for large n
> showProc.time()
Time elapsed:  0.687 0.003 0.692 
> 
> ## Large Matrix indexing / subassignment
> ## ------------------------------------- (from ex. by Imran Rashid)
> n <- 7000000
> m <-  100000
> nnz <- 20000
> 
> set.seed(12)
> f <- sparseMatrix(i = sample(n, size=nnz, replace=TRUE),
+                   j = sample(m, size=nnz, replace=TRUE))
> str(f)
Formal class 'ngCMatrix' [package "Matrix"] with 5 slots
  ..@ i       : int [1:20000] 6692226 4657233 4490801 3688935 344371 6380246 2797160 3584813 6553304 2327896 ...
  ..@ p       : int [1:99993] 0 1 1 1 1 1 1 1 1 1 ...
  ..@ Dim     : int [1:2] 6999863 99992
  ..@ Dimnames:List of 2
  .. ..$ : NULL
  .. ..$ : NULL
  ..@ factors : list()
> dim(f) # 6999863 x 99992
[1] 6999863   99992
> prod(dim(f)) # 699930301096 == 699'930'301'096  (~ 700'000 millions)
[1] 699930301096
> str(thisCol <-  f[,5000])# logi [~ 7 mio....]
 logi [1:6999863] FALSE FALSE FALSE FALSE FALSE FALSE ...
> sv <- as(thisCol, "sparseVector")
> str(sv) ## "empty" !
Formal class 'lsparseVector' [package "Matrix"] with 3 slots
  ..@ x     : logi(0) 
  ..@ length: int 6999863
  ..@ i     : int(0) 
> validObject(spCol <- f[,5000, drop=FALSE])
[1] TRUE
> ##
> ## *not* identical(): as(spCol, "sparseVector")@length is "double"prec:
> stopifnot(all.equal(as(spCol, "sparseVector"),
+                     as(sv,   "nsparseVector"), tolerance=0))
> if(doExtras) {#-----------------------------------------------------------------
+ f[,5762] <- thisCol # now "fine" <<<<<<<<<< FIXME uses LARGE objects -- slow --
+ ## is using  replCmat() in ../R/Csparse.R, then
+ ##           replTmat() in ../R/Tsparse.R
+ 
+ fx <- sparseMatrix(i = sample(n, size=nnz, replace=TRUE),
+                    j = sample(m, size=nnz, replace=TRUE),
+                    x = round(10*rnorm(nnz)))
+ class(fx)## dgCMatrix
+ fx[,6000] <- (tC <- rep(thisCol, length=nrow(fx)))# slow (as above)
+ thCol <- fx[,2000]
+ fx[,5762] <- thCol# slow
+ stopifnot(is(f, "ngCMatrix"), is(fx, "dgCMatrix"),
+ 	  identical(thisCol, f[,5762]),# perfect
+ 	  identical(as.logical(fx[,6000]), tC),
+ 	  identical(thCol,  fx[,5762]))
+ 
+ showProc.time()
+ ##
+ cat("checkMatrix() of all: \n---------\n")
+ Sys.setlocale("LC_COLLATE", "C")# to keep ls() reproducible
+ for(nm in ls()) if(is(.m <- get(nm), "Matrix")) {
+     cat(nm, "\n")
+     checkMatrix(.m, verbose = FALSE
+ 		, doDet = nm != "As" ## <- "As" almost singular <=> det() "ill posed"
+ 		)
+ }
+ showProc.time()
+ }#--------------end if(doExtras) -----------------------------------------------
> 
> if(!interactive()) warnings()
NULL
> 
> proc.time()
   user  system elapsed 
  6.942   0.118   7.167 
back to top