6 |
setAs("Matrix", "sparseMatrix", function(from) as_Csparse(from)) |
setAs("Matrix", "sparseMatrix", function(from) as_Csparse(from)) |
7 |
setAs("Matrix", "denseMatrix", function(from) as_dense(from)) |
setAs("Matrix", "denseMatrix", function(from) as_dense(from)) |
8 |
|
|
9 |
|
## Most of these work; this is a last resort: |
10 |
|
setAs(from = "Matrix", to = "matrix", # do *not* call base::as.matrix() here: |
11 |
|
function(from) .bail.out.2("coerce", class(from), class(to))) |
12 |
|
setAs(from = "matrix", to = "Matrix", function(from) Matrix(from)) |
13 |
|
|
14 |
## ## probably not needed eventually: |
## ## probably not needed eventually: |
15 |
## setAs(from = "ddenseMatrix", to = "matrix", |
## setAs(from = "ddenseMatrix", to = "matrix", |
16 |
## function(from) { |
## function(from) { |
24 |
setMethod("as.array", signature(x = "Matrix"), function(x) as(x, "matrix")) |
setMethod("as.array", signature(x = "Matrix"), function(x) as(x, "matrix")) |
25 |
|
|
26 |
## head and tail apply to all Matrix objects for which subscripting is allowed: |
## head and tail apply to all Matrix objects for which subscripting is allowed: |
27 |
## if(paste(R.version$major, R.version$minor, sep=".") < "2.4") { |
setMethod("head", signature(x = "Matrix"), utils::head.matrix) |
28 |
setMethod("head", signature(x = "Matrix"), utils:::head.matrix) |
setMethod("tail", signature(x = "Matrix"), utils::tail.matrix) |
|
setMethod("tail", signature(x = "Matrix"), utils:::tail.matrix) |
|
|
## } else { # R 2.4.0 and newer |
|
|
## setMethod("head", signature(x = "Matrix"), utils::head.matrix) |
|
|
## setMethod("tail", signature(x = "Matrix"), utils::tail.matrix) |
|
|
## } |
|
29 |
|
|
30 |
## slow "fall back" method {subclasses should have faster ones}: |
## slow "fall back" method {subclasses should have faster ones}: |
31 |
setMethod("as.vector", signature(x = "Matrix", mode = "missing"), |
setMethod("as.vector", signature(x = "Matrix", mode = "missing"), |
38 |
function(x, ...) as.logical(as.vector(x))) |
function(x, ...) as.logical(as.vector(x))) |
39 |
|
|
40 |
|
|
41 |
## Note that isSymmetric is *not* exported |
## "base" has an isSymmetric() S3-generic since R 2.3.0 |
|
## but that "base" has an isSymmetric() S3-generic since R 2.3.0 |
|
42 |
setMethod("isSymmetric", signature(object = "symmetricMatrix"), |
setMethod("isSymmetric", signature(object = "symmetricMatrix"), |
43 |
function(object,tol) TRUE) |
function(object,tol) TRUE) |
44 |
setMethod("isSymmetric", signature(object = "triangularMatrix"), |
setMethod("isSymmetric", signature(object = "triangularMatrix"), |
45 |
## TRUE iff diagonal: |
## TRUE iff diagonal: |
46 |
function(object,tol) isDiagonal(object)) |
function(object,tol) isDiagonal(object)) |
47 |
|
|
|
if(paste(R.version$major, R.version$minor, sep=".") < "2.3") |
|
|
## need a "matrix" method as in R 2.3 and later |
|
|
setMethod("isSymmetric", signature(object = "matrix"), |
|
|
function(object, tol = 100*.Machine$double.eps, ...) |
|
|
{ |
|
|
## pretest: is it square? |
|
|
d <- dim(object) |
|
|
if(d[1] != d[2]) return(FALSE) |
|
|
## for `broken' all.equal in R <= 2.2.x: |
|
|
dn <- dimnames(object) |
|
|
if(!identical(dn[1], dn[2])) return(FALSE) |
|
|
test <- |
|
|
if(is.complex(object)) |
|
|
all.equal.numeric(object, Conj(t(object)), tol = tol, ...) |
|
|
else # numeric, character, .. |
|
|
all.equal(object, t(object), tol = tol, ...) |
|
|
isTRUE(test) |
|
|
}) |
|
|
|
|
|
|
|
48 |
setMethod("isTriangular", signature(object = "triangularMatrix"), |
setMethod("isTriangular", signature(object = "triangularMatrix"), |
49 |
function(object, ...) TRUE) |
function(object, ...) TRUE) |
50 |
|
|
80 |
sparse = NULL, forceCheck = FALSE) |
sparse = NULL, forceCheck = FALSE) |
81 |
{ |
{ |
82 |
sparseDefault <- function(m) |
sparseDefault <- function(m) |
83 |
prod(dim(m)) > 2*sum(as(m, "matrix") != 0) |
prod(dim(m)) > 2*sum(is.na(m <- as(m, "matrix")) | m != 0) |
84 |
|
|
85 |
i.M <- is(data, "Matrix") |
i.M <- is(data, "Matrix") |
86 |
if(is.null(sparse) && (i.M || is(data, "matrix"))) |
|
87 |
|
if(is.null(sparse1 <- sparse) && (i.M || is(data, "matrix"))) |
88 |
sparse <- sparseDefault(data) |
sparse <- sparseDefault(data) |
89 |
|
|
90 |
doDN <- TRUE |
doDN <- TRUE |
91 |
if (i.M && !forceCheck) { |
if (i.M) { |
92 |
sM <- is(data,"sparseMatrix") |
sM <- is(data,"sparseMatrix") |
93 |
if((sparse && sM) || (!sparse && !sM)) |
if(!forceCheck && ((sparse && sM) || (!sparse && !sM))) |
94 |
return(data) |
return(data) |
95 |
## else : convert dense <-> sparse -> at end |
## else : convert dense <-> sparse -> at end |
96 |
} |
} |
99 |
nrow <- ceiling(length(data)/ncol) |
nrow <- ceiling(length(data)/ncol) |
100 |
else if (missing(ncol)) |
else if (missing(ncol)) |
101 |
ncol <- ceiling(length(data)/nrow) |
ncol <- ceiling(length(data)/nrow) |
102 |
if(length(data) == 1 && data == 0 && !identical(sparse,FALSE)) { |
if(length(data) == 1 && is0(data) && !identical(sparse, FALSE)) { |
103 |
if(is.null(sparse)) sparse <- TRUE |
## Matrix(0, ...) : always sparse unless "sparse = FALSE": |
104 |
|
if(is.null(sparse)) sparse1 <- sparse <- TRUE |
105 |
## will be sparse: do NOT construct full matrix! |
## will be sparse: do NOT construct full matrix! |
106 |
data <- new(if(is.numeric(data)) "dgTMatrix" else |
data <- new(if(is.numeric(data)) "dgTMatrix" else |
107 |
if(is.logical(data)) "lgTMatrix" else |
if(is.logical(data)) "lgTMatrix" else |
129 |
if(isDiag) |
if(isDiag) |
130 |
isDiag <- isDiagonal(data) |
isDiag <- isDiagonal(data) |
131 |
|
|
|
### TODO: Compare with as.Matrix() and its tests in ./dgeMatrix.R |
|
|
|
|
132 |
## Find proper matrix class 'cl' |
## Find proper matrix class 'cl' |
133 |
cl <- |
cl <- |
134 |
if(isDiag) |
if(isDiag && !isTRUE(sparse1)) |
135 |
"diagonalMatrix" # -> will automatically check for type |
"diagonalMatrix" # -> will automatically check for type |
136 |
else { |
else { |
137 |
## consider it's type |
## consider it's type |
221 |
Y <- as(Y, "matrix") ; Matrix(callGeneric()) }) |
Y <- as(Y, "matrix") ; Matrix(callGeneric()) }) |
222 |
|
|
223 |
|
|
224 |
|
## FIXME: All of these should never be called |
225 |
|
setMethod("chol", signature(x = "Matrix"), |
226 |
|
function(x, pivot = FALSE) .bail.out.1(.Generic, class(x))) |
227 |
|
setMethod("determinant", signature(x = "Matrix"), |
228 |
|
function(x, logarithm = TRUE) .bail.out.1(.Generic, class(x))) |
229 |
|
|
230 |
setMethod("diag", signature(x = "Matrix"), |
setMethod("diag", signature(x = "Matrix"), |
231 |
function(x, nrow, ncol) .bail.out.1(.Generic, class(x))) |
function(x, nrow, ncol) .bail.out.1(.Generic, class(x))) |
232 |
setMethod("t", signature(x = "Matrix"), |
setMethod("t", signature(x = "Matrix"), |
241 |
0-e1 |
0-e1 |
242 |
}) |
}) |
243 |
|
|
244 |
## bail-outs: |
## old-style matrices are made into new ones |
245 |
setMethod("Compare", signature(e1 = "Matrix", e2 = "Matrix"), |
setMethod("Ops", signature(e1 = "Matrix", e2 = "matrix"), |
246 |
|
function(e1, e2) callGeneric(e1, Matrix(e2))) |
247 |
|
## callGeneric(e1, Matrix(e2, sparse=is(e1,"sparseMatrix")))) |
248 |
|
setMethod("Ops", signature(e1 = "matrix", e2 = "Matrix"), |
249 |
|
function(e1, e2) callGeneric(Matrix(e1), e2)) |
250 |
|
|
251 |
|
## bail-outs -- on highest possible level, hence "Ops", not "Compare"/"Arith" : |
252 |
|
setMethod("Ops", signature(e1 = "Matrix", e2 = "Matrix"), |
253 |
function(e1, e2) { |
function(e1, e2) { |
254 |
d <- dimCheck(e1,e2) |
d <- dimCheck(e1,e2) |
255 |
.bail.out.2(.Generic, class(e1), class(e2)) |
.bail.out.2(.Generic, class(e1), class(e2)) |
256 |
}) |
}) |
257 |
setMethod("Compare", signature(e1 = "Matrix", e2 = "ANY"), |
setMethod("Ops", signature(e1 = "Matrix", e2 = "ANY"), |
258 |
function(e1, e2) .bail.out.2(.Generic, class(e1), class(e2))) |
function(e1, e2) .bail.out.2(.Generic, class(e1), class(e2))) |
259 |
setMethod("Compare", signature(e1 = "ANY", e2 = "Matrix"), |
setMethod("Ops", signature(e1 = "ANY", e2 = "Matrix"), |
260 |
function(e1, e2) .bail.out.2(.Generic, class(e1), class(e2))) |
function(e1, e2) .bail.out.2(.Generic, class(e1), class(e2))) |
261 |
|
|
262 |
|
|
293 |
function(x,i,j, drop) |
function(x,i,j, drop) |
294 |
stop("invalid or not-yet-implemented 'Matrix' subsetting")) |
stop("invalid or not-yet-implemented 'Matrix' subsetting")) |
295 |
|
|
296 |
## "logical *vector* indexing, such as M [ M >= 10 ] : |
## logical indexing, such as M[ M >= 7 ] *BUT* also M[ M[,1] >= 3,], |
297 |
setMethod("[", signature(x = "Matrix", i = "lMatrix", j = "missing", |
## The following is *both* for M [ <logical> ] |
298 |
drop = "ANY"), |
## and also for M [ <logical> , ] |
299 |
function (x, i, j, drop) { |
.M.sub.i.logical <- function (x, i, j, drop) |
300 |
|
{ |
301 |
|
nA <- nargs() |
302 |
|
if(nA == 2) { ## M [ M >= 7 ] |
303 |
as(x, geClass(x))@x[as.vector(i)] |
as(x, geClass(x))@x[as.vector(i)] |
304 |
## -> error when lengths don't match |
## -> error when lengths don't match |
305 |
}) |
} else if(nA == 3) { ## M [ M[,1, drop=FALSE] >= 7, ] |
306 |
|
stop("not-yet-implemented 'Matrix' subsetting") ## FIXME |
307 |
|
|
308 |
## FIXME: The following is good for M [ <logical> ] |
} else stop("nargs() = ", nA, |
309 |
## *BUT* it also triggers for M [ <logical> , ] where it is *WRONG* |
" should never happen; please report.") |
310 |
## using nargs() does not help: it gives '3' for both cases |
} |
311 |
if(FALSE) |
setMethod("[", signature(x = "Matrix", i = "lMatrix", j = "missing", |
312 |
|
drop = "ANY"), |
313 |
|
.M.sub.i.logical) |
314 |
setMethod("[", signature(x = "Matrix", i = "logical", j = "missing", |
setMethod("[", signature(x = "Matrix", i = "logical", j = "missing", |
315 |
drop = "ANY"), |
drop = "ANY"), |
316 |
function (x, i, j, drop) { |
.M.sub.i.logical) |
|
## DEBUG |
|
|
cat("[(Matrix,i,..): nargs=", nargs(),"\n") |
|
|
as(x, geClass(x))@x[i] }) |
|
317 |
|
|
318 |
|
|
319 |
## "FIXME:" |
## "FIXME:" |
320 |
## How can we get at A[ ij ] where ij is (i,j) 2-column matrix? |
## ------ get at A[ ij ] where ij is (i,j) 2-column matrix? |
321 |
## and A[ LL ] where LL is a logical *vector* |
|
|
## -> [.data.frame uses nargs() - can we do this in the *generic* ? |
|
322 |
|
|
323 |
|
|
324 |
### "[<-" : ----------------- |
### "[<-" : ----------------- |
327 |
setReplaceMethod("[", signature(x = "Matrix", i = "missing", j = "missing", |
setReplaceMethod("[", signature(x = "Matrix", i = "missing", j = "missing", |
328 |
value = "ANY"),## double/logical/... |
value = "ANY"),## double/logical/... |
329 |
function (x, value) { |
function (x, value) { |
330 |
|
## Fails for 'nMatrix' ... FIXME : make sure have method there |
331 |
x@x <- value |
x@x <- value |
332 |
validObject(x)# check if type and lengths above match |
validObject(x)# check if type and lengths above match |
333 |
x |
x |
334 |
}) |
}) |
335 |
|
|
336 |
## Method for all 'Matrix' kinds (rather than incomprehensible error messages); |
setReplaceMethod("[", signature(x = "Matrix", i = "ANY", j = "ANY", |
337 |
|
value = "Matrix"), |
338 |
|
function (x, i, j, value) |
339 |
|
callGeneric(x=x, i=i, j=j, value = as.vector(value))) |
340 |
|
setReplaceMethod("[", signature(x = "Matrix", i = "ANY", j = "ANY", |
341 |
|
value = "matrix"), |
342 |
|
function (x, i, j, value) |
343 |
|
callGeneric(x=x, i=i, j=j, value = c(value))) |
344 |
|
|
345 |
## (ANY,ANY,ANY) is used when no `real method' is implemented : |
## (ANY,ANY,ANY) is used when no `real method' is implemented : |
346 |
setReplaceMethod("[", signature(x = "Matrix", i = "ANY", j = "ANY", |
setReplaceMethod("[", signature(x = "Matrix", i = "ANY", j = "ANY", |
347 |
value = "ANY"), |
value = "ANY"), |
348 |
function (x, i, j, value) { |
function (x, i, j, value) { |
349 |
if(!is.atomic(value)) |
if(!is.atomic(value)) |
350 |
stop("RHS 'value' must match matrix class ", class(x)) |
stop(sprintf("RHS 'value' (class %s) matches 'ANY', but must match matrix class %s", |
351 |
|
class(value),class(x))) |
352 |
else stop("not-yet-implemented 'Matrix[<-' method") |
else stop("not-yet-implemented 'Matrix[<-' method") |
353 |
}) |
}) |
354 |
|
|