Rev 2127 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed
### Define Methods that can be inherited for all subclasses### Idea: Coercion between *VIRTUAL* classes -- as() chooses "closest" classes### ---- should also work e.g. for dense-triangular --> sparse-triangular !## setAs("denseMatrix", "sparseMatrix",## function(from) {## as(as(from, "dgeMatrix")## })## setAs("dMatrix", "lMatrix",## function(from) {## })## "graph" coercions -- this needs the graph package which is currently## ----- *not* required on purpose## Note: 'undirected' graph <==> 'symmetric' matrixsetAs("graphNEL", "sparseMatrix",function(from) {.Call("graphNEL_as_dgTMatrix",from,symmetric = (from@edgemode == "undirected"),PACKAGE = "Matrix")})setAs("graph", "sparseMatrix",function(from) as(as(from,"graphNEL"), "sparseMatrix"))##! if(FALSE) {##--- not yetsetAs("sparseMatrix", "graph", function(from) as(from, "graphNEL"))setAs("sparseMatrix", "graphNEL",function(from) as(as(from, "dgTMatrix"), "graphNEL"))setAs("dgTMatrix", "graphNEL",function(from) {d <- dim(from)if(d[1] != d[2])stop("only square matrices can be used as incidence matrices for grphs")n <- d[1]if(n == 0) return(new("graphNEL"))if(is.null(rn <- dimnames(from)[[1]]))rn <- as.character(1:n)if(isSymmetric(from)) { # because it's "dsTMatrix" or otherwise## Need to 'uniquify' the triplets!upper <- from@i <= from@jgraph::ftM2graphNEL(cbind(from@i + 1:1, from@j + 1:1),W = from@x, V=rn, edgemode="undirected")} else { ## not symmetricgraph::ftM2graphNEL(cbind(from@i + 1:1, from@j + 1:1),W = from@x, V=rn, edgemode="directed")}stop("'dgTMatrix -> 'graphNEL' method is not yet implemented")## new("graphNEL", nodes = paste(1:n) , edgeL = ...)})##! }#--not_yet### Subsetting -- basic things (drop = "missing") are done in ./Matrix.R### FIXME : we defer to the "*gT" -- conveniently, but not efficient for gC !## [dl]sparse -> [dl]gT -- treat both in one via superclass## -- more useful when have "z" (complex) and even moresetMethod("[", signature(x = "sparseMatrix", i = "index", j = "missing",drop = "logical"),function (x, i, j, drop) {cl <- class(x)viaCl <- if(is(x,"dMatrix")) "dgTMatrix" else "lgTMatrix"x <- callGeneric(x = as(x, viaCl), i=i, drop=drop)## try_as(x, c(cl, sub("T","C", viaCl)))if(is(x, "Matrix") && extends(cl, "CsparseMatrix"))as(x, sub("T","C", viaCl)) else x})setMethod("[", signature(x = "sparseMatrix", i = "missing", j = "index",drop = "logical"),function (x, i, j, drop) {cl <- class(x)viaCl <- if(is(x,"dMatrix")) "dgTMatrix" else "lgTMatrix"x <- callGeneric(x = as(x, viaCl), j=j, drop=drop)## try_as(x, c(cl, sub("T","C", viaCl)))if(is(x, "Matrix") && extends(cl, "CsparseMatrix"))as(x, sub("T","C", viaCl)) else x})setMethod("[", signature(x = "sparseMatrix",i = "index", j = "index", drop = "logical"),function (x, i, j, drop) {cl <- class(x)viaCl <- if(is(x,"dMatrix")) "dgTMatrix" else "lgTMatrix"x <- callGeneric(x = as(x, viaCl), i=i, j=j, drop=drop)## try_as(x, c(cl, sub("T","C", viaCl)))if(is(x, "Matrix") && extends(cl, "CsparseMatrix"))as(x, sub("T","C", viaCl)) else x})setMethod("-", signature(e1 = "sparseMatrix", e2 = "missing"),function(e1) { e1@x <- -e1@x ; e1 })## with the following exceptions:setMethod("-", signature(e1 = "lsparseMatrix", e2 = "missing"),function(e1) callGeneric(as(e1, "dgCMatrix")))setMethod("-", signature(e1 = "pMatrix", e2 = "missing"),function(e1) callGeneric(as(e1, "lgTMatrix")))### --- show() method ---prSpMatrix <- function(object, zero.print = "."){stopifnot(is(object, "sparseMatrix"))m <- as(object, "matrix")x <- apply(m, 2, format)if(is.null(dim(x))) {# e.g. in 1 x 1 casedim(x) <- dim(m)dimnames(x) <- dimnames(m)}x <- emptyColnames(x)if(is.logical(zero.print))zero.print <- if(zero.print) "0" else " "## FIXME: show only "structural" zeros as 'zero.print', not all of them..x[m == 0.] <- zero.printif(is(object,"lsparseMatrix"))x[m] <- "|"print(noquote(x))invisible(object)}setMethod("show", signature(object = "sparseMatrix"),function(object) {d <- dim(object)cl <- class(object)cat(sprintf('%d x %d sparse Matrix of class "%s"\n', d[1], d[2], cl))maxp <- getOption("max.print")if(prod(d) <= maxp)prSpMatrix(object)else { ## d[1] > maxp / d[2] >= nr : -- this needs [,] working:nr <- maxp %/% d[2]n2 <- ceiling(nr / 2)nR <- d[1] # nrowprSpMatrix(object[seq(length = min(nR, max(1, n2))), drop = FALSE])cat("\n ..........\n\n")prSpMatrix(object[seq(to = nR, length = min(max(1, nr-n2), nR)),drop = FALSE])invisible(object)}})## not exported:setMethod("isSymmetric", signature(object = "sparseMatrix"),function(object, tol = 100*.Machine$double.eps) {## pretest: is it square?d <- dim(object)if(d[1] != d[2]) return(FALSE)## else slower testif (is(object, "dMatrix"))## use gC; "T" (triplet) is *not* unique!isTRUE(all.equal(as(object, "dgCMatrix"),as(t(object), "dgCMatrix"), tol = tol))else if (is(object, "lMatrix"))## test for exact equality; FIXME(?): identical() too strict?identical(as(object, "lgCMatrix"),as(t(object), "lgCMatrix"))else stop("not yet implemented")})