Rev 4817 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed
#### Permutation Matrices -- Coercion and Methods## The typical 'constructor' : coerce from 'index'setAs("integer", "pMatrix",function(from) {n <- length(from)nn <- names(from)new("pMatrix", Dim = rep.int(n, 2), Dimnames = list(nn,nn),perm = from)})setAs("numeric", "pMatrix",function(from)if(all(from == (i <- as.integer(from)))) as(i, "pMatrix")else stop("coercion to 'pMatrix' only works from integer numeric"))setAs("pMatrix", "matrix",function(from) {fp <- from@permr <- idiag(n = length(fp))[fp,]if(.has.DN(from)) dimnames(r) <- from@Dimnamesr})## coerce to 0/1 sparse matrix, i.e. sparse patternsetAs("pMatrix", "ngTMatrix",function(from) {d <- from@Dimnew("ngTMatrix", i = seq_len(d[1]) - 1L, j = from@perm - 1L,Dim = d, Dimnames = from@Dimnames)})setAs("pMatrix", "TsparseMatrix", function(from) as(from, "ngTMatrix"))setAs("pMatrix", "nMatrix", function(from) as(from, "ngTMatrix"))setAs("pMatrix", "lMatrix", function(from) as(as(from, "nMatrix"), "lMatrix"))setAs("pMatrix", "dMatrix", function(from) as(as(from, "nMatrix"), "dMatrix"))setAs("pMatrix", "CsparseMatrix",function(from) as(as(from, "ngTMatrix"), "CsparseMatrix"))setAs("nMatrix", "pMatrix",function(from) {from <- as(as(from, "TsparseMatrix"), "ngTMatrix")n <- (d <- from@Dim)[1]if(n != d[2]) stop("not a square matrix")if(length(i <- from@i) != n)stop("the number of non-zero entries differs from nrow(.)")if((need.sort <- is.unsorted(i))) {ii <- sort.list(i)i <- i[ii]}if(n >= 1 && !identical(i, 0:(n - 1)))stop("must have exactly one non-zero entry per row")new("pMatrix", ## validity checking checks the 'perm' slot:perm = 1L + if(need.sort) from@j[ii] else from@j,Dim = d, Dimnames = from@Dimnames)})setAs("matrix", "pMatrix", function(from) as(as(from, "nMatrix"), "pMatrix"))setMethod("solve", signature(a = "pMatrix", b = "missing"),function(a, b) {ap <- a@permap[ap] <- seq_along(ap)a@perm <- apa@Dimnames <- a@Dimnames[2:1]a})setMethod("solve", signature(a = "Matrix", b = "pMatrix"),function(a, b) {## Or alternatively solve(a, as(b, "CsparseMatrix"))i <- b@permi[i] <- seq_along(i)solve(a)[, i]})## t(pM) is == the inverse pM^(-1):setMethod("t", signature(x = "pMatrix"), function(x) solve(x)).m.mult.pMat <- function(x, y) {mmultCheck(x,y)i <- y@permi[i] <- seq_along(i)x[, i]}setMethod("%*%", signature(x = "matrix", y = "pMatrix"),.m.mult.pMat, valueClass = "matrix")setMethod("%*%", signature(x = "Matrix", y = "pMatrix"),.m.mult.pMat)setMethod("%*%", signature(x = "pMatrix", y = "matrix"),function(x, y) { mmultCheck(x,y); y[x@perm ,]}, valueClass = "matrix")setMethod("%*%", signature(x = "pMatrix", y = "Matrix"),function(x, y) { mmultCheck(x,y); y[x@perm ,]})setMethod("%*%", signature(x = "pMatrix", y = "pMatrix"),function(x, y) {stopifnot(identical(d <- x@Dim, y@Dim))n <- d[1]## FIXME: dimnames dealing: as with S3 matrix's %*%x@perm <- x@perm[y@perm]x})### FIXME: crossprod / tcrossprod currently work### ----- via t(.) and later [ i, ] -- separate methods will be faster!setMethod("crossprod", signature(x = "pMatrix", y = "missing"),function(x, y=NULL) Diagonal(nrow(x)))setMethod("tcrossprod", signature(x = "pMatrix", y = "missing"),function(x, y=NULL) Diagonal(nrow(x))).pMat.nosense <- function (x, i, j, ..., value)stop('partially replacing "pMatrix" entries is not sensible')setReplaceMethod("[", signature(x = "pMatrix", i = "index"), .pMat.nosense)setReplaceMethod("[", signature(x = "pMatrix", i = "missing", j = "index"),.pMat.nosense) ## explicit ^^^^^^^^^^^^ for disambiguation