1 |
### Define Methods that can be inherited for all subclasses |
### Define Methods that can be inherited for all subclasses |
2 |
|
|
3 |
|
## This replaces many "d..Matrix" -> "dgeMatrix" ones |
4 |
|
## >> but << needs all sub(sub(sub)) classes of "ddenseMatrix" listed |
5 |
|
## ----- in ../src/Mutils.c |
6 |
|
|
7 |
|
## Should this method return 'from' without duplication when it has |
8 |
|
## class dgeMatrix? |
9 |
|
setAs("ddenseMatrix", "dgeMatrix", |
10 |
|
function(from) { |
11 |
|
if (class(from) != "dgeMatrix") |
12 |
|
from <- .Call(dup_mMatrix_as_dgeMatrix, from) |
13 |
|
from |
14 |
|
}) |
15 |
|
|
16 |
|
## d(ouble) to l(ogical): |
17 |
setAs("dgeMatrix", "lgeMatrix", d2l_Matrix) |
setAs("dgeMatrix", "lgeMatrix", d2l_Matrix) |
18 |
setAs("dtrMatrix", "ltrMatrix", d2l_Matrix) |
setAs("dtrMatrix", "ltrMatrix", d2l_Matrix) |
19 |
setAs("dtpMatrix", "ltpMatrix", d2l_Matrix) |
setAs("dtpMatrix", "ltpMatrix", d2l_Matrix) |
20 |
setAs("dsyMatrix", "lsyMatrix", d2l_Matrix) |
setAs("dsyMatrix", "lsyMatrix", d2l_Matrix) |
21 |
setAs("dspMatrix", "lspMatrix", d2l_Matrix) |
setAs("dspMatrix", "lspMatrix", d2l_Matrix) |
22 |
|
|
23 |
|
setAs("ddenseMatrix", "CsparseMatrix", |
24 |
|
function(from) { |
25 |
|
if (class(from) != "dgeMatrix") |
26 |
|
from <- .Call(dup_mMatrix_as_dgeMatrix, from) |
27 |
|
.Call(dense_to_Csparse, from) |
28 |
|
}) |
29 |
|
|
30 |
|
## special case |
31 |
|
setAs("dgeMatrix", "dgCMatrix", |
32 |
|
function(from) .Call(dense_to_Csparse, from)) |
33 |
|
|
34 |
|
setAs("matrix", "CsparseMatrix", |
35 |
|
function(from) { |
36 |
|
if(is.numeric(from)) |
37 |
|
.Call(dense_to_Csparse, .Call(dup_mMatrix_as_dgeMatrix, from)) |
38 |
|
else if(is.logical(from)) ## FIXME: this works, but maybe wastefully |
39 |
|
as(Matrix(from, sparse=TRUE), "CsparseMatrix") |
40 |
|
else stop('not-yet-implemented coercion to "CsparseMatrix"') |
41 |
|
}) |
42 |
|
|
43 |
|
|
44 |
|
## special case needed in the Matrix function |
45 |
|
setAs("matrix", "dgCMatrix", |
46 |
|
function(from) { |
47 |
|
storage.mode(from) <- "double" |
48 |
|
.Call(dense_to_Csparse, from) |
49 |
|
}) |
50 |
|
|
51 |
|
setAs("numeric", "CsparseMatrix", |
52 |
|
function(from) |
53 |
|
.Call(dense_to_Csparse, .Call(dup_mMatrix_as_dgeMatrix, from))) |
54 |
|
|
55 |
|
setMethod("as.numeric", signature(x = "ddenseMatrix"), |
56 |
|
function(x, ...) as(x, "dgeMatrix")@x) |
57 |
|
|
58 |
## -- see also ./Matrix.R e.g., for a show() method |
## -- see also ./Matrix.R e.g., for a show() method |
59 |
|
|
60 |
## These methods are the 'fallback' methods for all dense numeric |
## These methods are the 'fallback' methods for all dense numeric |
77 |
## setMethod("t", signature(x = "ddenseMatrix"), |
## setMethod("t", signature(x = "ddenseMatrix"), |
78 |
## function(x) callGeneric(as(x, "dgeMatrix"))) |
## function(x) callGeneric(as(x, "dgeMatrix"))) |
79 |
|
|
80 |
setMethod("tcrossprod", signature(x = "ddenseMatrix"), |
setMethod("tcrossprod", signature(x = "ddenseMatrix", y = "missing"), |
81 |
function(x) callGeneric(as(x, "dgeMatrix"))) |
function(x, y = NULL) callGeneric(as(x, "dgeMatrix"))) |
82 |
|
|
83 |
setMethod("crossprod", signature(x = "ddenseMatrix", y = "missing"), |
setMethod("crossprod", signature(x = "ddenseMatrix", y = "missing"), |
84 |
function(x, y = NULL) callGeneric(as(x, "dgeMatrix"))) |
function(x, y = NULL) callGeneric(as(x, "dgeMatrix"))) |
86 |
setMethod("diag", signature(x = "ddenseMatrix"), |
setMethod("diag", signature(x = "ddenseMatrix"), |
87 |
function(x = 1, nrow, ncol = n) callGeneric(as(x, "dgeMatrix"))) |
function(x = 1, nrow, ncol = n) callGeneric(as(x, "dgeMatrix"))) |
88 |
|
|
89 |
setMethod("solve", signature(a = "ddenseMatrix", b = "missing"), |
## These methods cause an infinite loop in pre-2.4.0 |
90 |
function(a, b, ...) callGeneric(as(a, "dgeMatrix"))) |
## setMethod("solve", signature(a = "ddenseMatrix", b = "missing"), |
91 |
|
## function(a, b, ...) callGeneric(as(a, "dgeMatrix"))) |
92 |
setMethod("solve", signature(a = "ddenseMatrix", b = "ANY"), |
|
93 |
function(a, b, ...) callGeneric(as(a, "dgeMatrix"), b)) |
## setMethod("solve", signature(a = "ddenseMatrix", b = "ANY"), |
94 |
|
## function(a, b, ...) callGeneric(as(a, "dgeMatrix"), b)) |
95 |
|
|
96 |
|
## General method for dense matrix multiplication in case specific methods |
97 |
|
## have not been defined. |
98 |
|
setMethod("%*%", signature(x = "ddenseMatrix", y = "ddenseMatrix"), |
99 |
|
function(x, y) .Call(dgeMatrix_matrix_mm, |
100 |
|
.Call(dup_mMatrix_as_dgeMatrix, x), y, FALSE), |
101 |
|
valueClass = "dgeMatrix") |
102 |
|
|
103 |
setMethod("lu", signature(x = "ddenseMatrix"), |
setMethod("lu", signature(x = "ddenseMatrix"), |
104 |
function(x, ...) callGeneric(as(x, "dgeMatrix"))) |
function(x, ...) callGeneric(as(x, "dgeMatrix"))) |
105 |
|
|
106 |
|
setMethod("chol", signature(x = "ddenseMatrix", pivot = "ANY"), cholMat) |
107 |
|
|
108 |
setMethod("determinant", signature(x = "ddenseMatrix", logarithm = "missing"), |
setMethod("determinant", signature(x = "ddenseMatrix", logarithm = "missing"), |
109 |
function(x, logarithm, ...) callGeneric(as(x, "dgeMatrix"))) |
function(x, logarithm, ...) callGeneric(as(x, "dgeMatrix"))) |
110 |
|
|
123 |
function(x, vectors, ...) callGeneric(as(x, "dgeMatrix"), vectors)) |
function(x, vectors, ...) callGeneric(as(x, "dgeMatrix"), vectors)) |
124 |
|
|
125 |
|
|
126 |
### NAMESPACE must export this -- also only for R version 2.2.x: |
## Cheap version: work via "dgeMatrix" and use the group methods there: |
127 |
if(paste(R.version$major, R.version$minor, sep=".") >= "2.2") { |
## FIXME(?): try to preserve "symmetric", "triangular", ... |
128 |
## for R 2.2.x (and later): |
setMethod("Arith", ## "+", "-", "*", "^", "%%", "%/%", "/" |
129 |
|
signature(e1 = "ddenseMatrix", e2 = "ddenseMatrix"), |
130 |
### cbind2 |
function(e1, e2) callGeneric(as(e1, "dgeMatrix"), |
131 |
setMethod("cbind2", signature(x = "ddenseMatrix", y = "numeric"), |
as(e2, "dgeMatrix"))) |
132 |
function(x, y) { |
setMethod("Arith", |
133 |
d <- dim(x); nr <- d[1]; nc <- d[2] |
signature(e1 = "ddenseMatrix", e2 = "numeric"), |
134 |
y <- rep(y, length.out = nr)# 'silent procrustes' |
function(e1, e2) callGeneric(as(e1, "dgeMatrix"), e2)) |
135 |
## beware of (packed) triangular, symmetric, ... |
setMethod("Arith", |
136 |
x <- as(x, "dgeMatrix") |
signature(e1 = "numeric", e2 = "ddenseMatrix"), |
137 |
x@x <- c(x@x, as.double(y)) |
function(e1, e2) callGeneric(e1, as(e2, "dgeMatrix"))) |
|
x@Dim[2] <- nc + 1:1 |
|
|
if(is.character(dn <- x@Dimnames[[2]])) |
|
|
x@Dimnames[[2]] <- c(dn, "") |
|
|
x |
|
|
}) |
|
|
## the same, (x,y) <-> (y,x): |
|
|
setMethod("cbind2", signature(x = "numeric", y = "ddenseMatrix"), |
|
|
function(x, y) { |
|
|
d <- dim(y); nr <- d[1]; nc <- d[2] |
|
|
x <- rep(x, length.out = nr) |
|
|
y <- as(y, "dgeMatrix") |
|
|
y@x <- c(as.double(x), y@x) |
|
|
y@Dim[2] <- nc + 1:1 |
|
|
if(is.character(dn <- y@Dimnames[[2]])) |
|
|
y@Dimnames[[2]] <- c("", dn) |
|
|
y |
|
|
}) |
|
|
|
|
|
setMethod("cbind2", signature(x = "ddenseMatrix", y = "matrix"), |
|
|
function(x, y) callGeneric(x, as(y, "dgeMatrix"))) |
|
|
setMethod("cbind2", signature(x = "matrix", y = "ddenseMatrix"), |
|
|
function(x, y) callGeneric(as(x, "dgeMatrix"), y)) |
|
|
|
|
|
setMethod("cbind2", signature(x = "ddenseMatrix", y = "ddenseMatrix"), |
|
|
function(x, y) { |
|
|
nr <- rowCheck(x,y) |
|
|
ncx <- x@Dim[2] |
|
|
ncy <- y@Dim[2] |
|
|
## beware of (packed) triangular, symmetric, ... |
|
|
hasDN <- !is.null(dnx <- dimnames(x)) | |
|
|
!is.null(dny <- dimnames(y)) |
|
|
x <- as(x, "dgeMatrix") |
|
|
y <- as(y, "dgeMatrix") |
|
|
x@x <- c(x@x, y@x) |
|
|
x@Dim[2] <- ncx + ncy |
|
|
if(hasDN) { |
|
|
## R and S+ are different in which names they take |
|
|
## if they differ -- but there's no warning in any case |
|
|
rn <- if(!is.null(dnx[[1]])) dnx[[1]] else dny[[1]] |
|
|
cx <- dnx[[2]] ; cy <- dny[[2]] |
|
|
cn <- if(is.null(cx) && is.null(cy)) NULL |
|
|
else c(if(!is.null(cx)) cx else rep.int("", ncx), |
|
|
if(!is.null(cy)) cy else rep.int("", ncy)) |
|
|
x@Dimnames <- list(rn, cn) |
|
|
} |
|
|
x |
|
|
}) |
|
|
|
|
|
### rbind2 -- analogous to cbind2 --- more to do for @x though: |
|
|
|
|
|
setMethod("rbind2", signature(x = "ddenseMatrix", y = "numeric"), |
|
|
function(x, y) { |
|
|
if(is.character(dn <- x@Dimnames[[1]])) dn <- c(dn, "") |
|
|
new("dgeMatrix", Dim = x@Dim + 1:0, |
|
|
Dimnames = list(dn, x@Dimnames[[2]]), |
|
|
x = c(rbind2(as(x,"matrix"), y))) |
|
|
}) |
|
|
## the same, (x,y) <-> (y,x): |
|
|
setMethod("rbind2", signature(x = "numeric", y = "ddenseMatrix"), |
|
|
function(x, y) { |
|
|
if(is.character(dn <- y@Dimnames[[1]])) dn <- c("", dn) |
|
|
new("dgeMatrix", Dim = y@Dim + 1:0, |
|
|
Dimnames = list(dn, y@Dimnames[[2]]), |
|
|
x = c(rbind2(x, as(y,"matrix")))) |
|
|
}) |
|
|
|
|
|
setMethod("rbind2", signature(x = "ddenseMatrix", y = "matrix"), |
|
|
function(x, y) callGeneric(x, as(y, "dgeMatrix"))) |
|
|
setMethod("rbind2", signature(x = "matrix", y = "ddenseMatrix"), |
|
|
function(x, y) callGeneric(as(x, "dgeMatrix"), y)) |
|
|
|
|
|
setMethod("rbind2", signature(x = "ddenseMatrix", y = "ddenseMatrix"), |
|
|
function(x, y) { |
|
|
nc <- colCheck(x,y) |
|
|
nrx <- x@Dim[1] |
|
|
nry <- y@Dim[1] |
|
|
dn <- |
|
|
if(!is.null(dnx <- dimnames(x)) | |
|
|
!is.null(dny <- dimnames(y))) { |
|
|
## R and S+ are different in which names they take |
|
|
## if they differ -- but there's no warning in any case |
|
|
list(if(is.null(rx <- dnx[[1]]) && is.null(ry <- dny[[1]])) |
|
|
NULL else |
|
|
c(if(!is.null(rx)) rx else rep.int("", nrx), |
|
|
if(!is.null(ry)) ry else rep.int("", nry)), |
|
|
if(!is.null(dnx[[2]])) dnx[[2]] else dny[[2]]) |
|
|
|
|
|
} else list(NULL, NULL) |
|
|
## beware of (packed) triangular, symmetric, ... |
|
|
new("dgeMatrix", Dim = c(nrx + nry, nc), Dimnames = dn, |
|
|
x = c(rbind2(as(x,"matrix"), as(y,"matrix")))) |
|
|
}) |
|
138 |
|
|
139 |
}## R-2.2.x ff |
setMethod("Math", |
140 |
|
signature(x = "ddenseMatrix"), |
141 |
|
function(x) callGeneric(as(x, "dgeMatrix"))) |
142 |
|
|
143 |
|
|
144 |
|
### FIXME: band() et al should be extended from "ddense" to "dense" ! |
145 |
|
### However, needs much work to generalize dup_mMatrix_as_dgeMatrix() |
146 |
|
|
147 |
|
## NB: have extra tril(), triu() methods for symmetric ["dsy" and "dsp"] and |
148 |
|
## for triangular ["dtr" and "dtp"] |
149 |
|
setMethod("tril", "ddenseMatrix", |
150 |
|
function(x, k = 0, ...) { |
151 |
|
k <- as.integer(k[1]) |
152 |
|
dd <- dim(x); sqr <- dd[1] == dd[2] |
153 |
|
stopifnot(-dd[1] <= k, k <= dd[1]) # had k <= 0 |
154 |
|
## returns "lower triangular" if k <= 0 && sqr |
155 |
|
.Call(ddense_band, x, -dd[1], k) |
156 |
|
}) |
157 |
|
|
158 |
|
setMethod("triu", "ddenseMatrix", |
159 |
|
function(x, k = 0, ...) { |
160 |
|
k <- as.integer(k[1]) |
161 |
|
dd <- dim(x); sqr <- dd[1] == dd[2] |
162 |
|
stopifnot(-dd[1] <= k, k <= dd[1]) # had k >= 0 |
163 |
|
## returns "upper triangular" if k >= 0 |
164 |
|
.Call(ddense_band, x, k, dd[2]) |
165 |
|
}) |
166 |
|
|
167 |
|
setMethod("band", "ddenseMatrix", |
168 |
|
function(x, k1, k2, ...) { |
169 |
|
k1 <- as.integer(k1[1]) |
170 |
|
k2 <- as.integer(k2[1]) |
171 |
|
dd <- dim(x); sqr <- dd[1] == dd[2] |
172 |
|
stopifnot(-dd[1] <= k1, k1 <= k2, k2 <= dd[1]) |
173 |
|
r <- .Call(ddense_band, x, k1, k2) |
174 |
|
if (k1 < 0 && k1 == -k2 && isSymmetric(x)) ## symmetric |
175 |
|
as(r, paste(.M.kind(x), "syMatrix", sep='')) |
176 |
|
else |
177 |
|
r |
178 |
|
}) |