4 |
|
|
5 |
SEXP Csparse_validate(SEXP x) |
SEXP Csparse_validate(SEXP x) |
6 |
{ |
{ |
7 |
|
/* NB: we do *NOT* check a potential 'x' slot here, at all */ |
8 |
SEXP pslot = GET_SLOT(x, Matrix_pSym), |
SEXP pslot = GET_SLOT(x, Matrix_pSym), |
9 |
islot = GET_SLOT(x, Matrix_iSym); |
islot = GET_SLOT(x, Matrix_iSym); |
10 |
int j, ncol = length(pslot) - 1, |
int j, k, ncol, nrow, sorted, |
11 |
*dims = INTEGER(GET_SLOT(x, Matrix_DimSym)), |
*dims = INTEGER(GET_SLOT(x, Matrix_DimSym)), |
12 |
nrow, *xp = INTEGER(pslot), |
*xp = INTEGER(pslot), |
13 |
*xi = INTEGER(islot); |
*xi = INTEGER(islot); |
14 |
|
|
15 |
nrow = dims[0]; |
nrow = dims[0]; |
16 |
if (length(pslot) <= 0) |
ncol = dims[1]; |
17 |
return mkString(_("slot p must have length > 0")); |
if (length(pslot) != dims[1] + 1) |
18 |
|
return mkString(_("slot p must have length = ncol(.) + 1")); |
19 |
if (xp[0] != 0) |
if (xp[0] != 0) |
20 |
return mkString(_("first element of slot p must be zero")); |
return mkString(_("first element of slot p must be zero")); |
21 |
if (length(islot) != xp[ncol]) |
if (length(islot) != xp[ncol]) |
22 |
return mkString(_("last element of slot p must match length of slots i and x")); |
return |
23 |
|
mkString(_("last element of slot p must match length of slots i and x")); |
24 |
|
for (j = 0; j < length(islot); j++) { |
25 |
|
if (xi[j] < 0 || xi[j] >= nrow) |
26 |
|
return mkString(_("all row indices must be between 0 and nrow-1")); |
27 |
|
} |
28 |
|
sorted = TRUE; |
29 |
for (j = 0; j < ncol; j++) { |
for (j = 0; j < ncol; j++) { |
30 |
if (xp[j] > xp[j+1]) |
if (xp[j] > xp[j+1]) |
31 |
return mkString(_("slot p must be non-decreasing")); |
return mkString(_("slot p must be non-decreasing")); |
32 |
|
for (k = xp[j] + 1; k < xp[j + 1]; k++) |
33 |
|
if (xi[k] < xi[k - 1]) sorted = FALSE; |
34 |
} |
} |
35 |
for (j = 0; j < length(islot); j++) { |
if (!sorted) { |
36 |
if (xi[j] < 0 || xi[j] >= nrow) |
cholmod_sparse *chx = as_cholmod_sparse(x); |
37 |
return mkString(_("all row indices must be between 0 and nrow-1")); |
cholmod_sort(chx, &c); |
38 |
|
Free(chx); |
39 |
} |
} |
40 |
return ScalarLogical(1); |
return ScalarLogical(1); |
41 |
} |
} |
46 |
cholmod_dense *chxd = cholmod_sparse_to_dense(chxs, &c); |
cholmod_dense *chxd = cholmod_sparse_to_dense(chxs, &c); |
47 |
|
|
48 |
Free(chxs); |
Free(chxs); |
49 |
return chm_dense_to_SEXP(chxd, 1); |
return chm_dense_to_SEXP(chxd, 1, Real_kind(x)); |
50 |
} |
} |
51 |
|
|
52 |
SEXP Csparse_to_logical(SEXP x, SEXP tri) |
SEXP Csparse_to_nz_pattern(SEXP x, SEXP tri) |
53 |
{ |
{ |
54 |
cholmod_sparse *chxs = as_cholmod_sparse(x); |
cholmod_sparse *chxs = as_cholmod_sparse(x); |
55 |
cholmod_sparse |
cholmod_sparse |
62 |
-1 : 1; |
-1 : 1; |
63 |
diag = CHAR(asChar(GET_SLOT(x, Matrix_diagSym))); |
diag = CHAR(asChar(GET_SLOT(x, Matrix_diagSym))); |
64 |
} |
} |
65 |
return chm_sparse_to_SEXP(chxcp, 1, uploT, diag, |
return chm_sparse_to_SEXP(chxcp, 1, uploT, 0, diag, |
66 |
GET_SLOT(x, Matrix_DimNamesSym)); |
GET_SLOT(x, Matrix_DimNamesSym)); |
67 |
} |
} |
68 |
|
|
80 |
{ |
{ |
81 |
cholmod_sparse *chxs = as_cholmod_sparse(x); |
cholmod_sparse *chxs = as_cholmod_sparse(x); |
82 |
cholmod_triplet *chxt = cholmod_sparse_to_triplet(chxs, &c); |
cholmod_triplet *chxt = cholmod_sparse_to_triplet(chxs, &c); |
83 |
int uploT = 0; char *diag = ""; |
int uploT = 0; |
84 |
|
char *diag = ""; |
85 |
|
int Rkind = (chxs->xtype == CHOLMOD_REAL) ? Real_kind(x) : 0; |
86 |
|
|
87 |
Free(chxs); |
Free(chxs); |
88 |
if (asLogical(tri)) { /* triangular sparse matrices */ |
if (asLogical(tri)) { /* triangular sparse matrices */ |
89 |
uploT = (strcmp(CHAR(asChar(GET_SLOT(x, Matrix_uploSym))), "U")) ? |
uploT = (*uplo_P(x) == 'U') ? -1 : 1; |
90 |
-1 : 1; |
diag = diag_P(x); |
|
diag = CHAR(asChar(GET_SLOT(x, Matrix_diagSym))); |
|
91 |
} |
} |
92 |
return chm_triplet_to_SEXP(chxt, 1, uploT, diag, |
return chm_triplet_to_SEXP(chxt, 1, uploT, Rkind, diag, |
93 |
GET_SLOT(x, Matrix_DimNamesSym)); |
GET_SLOT(x, Matrix_DimNamesSym)); |
94 |
} |
} |
95 |
|
|
96 |
|
/* this used to be called sCMatrix_to_gCMatrix(..) [in ./dsCMatrix.c ]: */ |
97 |
SEXP Csparse_symmetric_to_general(SEXP x) |
SEXP Csparse_symmetric_to_general(SEXP x) |
98 |
{ |
{ |
99 |
cholmod_sparse *chx = as_cholmod_sparse(x), *chgx; |
cholmod_sparse *chx = as_cholmod_sparse(x), *chgx; |
100 |
|
int Rkind = (chx->xtype == CHOLMOD_REAL) ? Real_kind(x) : 0; |
101 |
|
|
102 |
if (!(chx->stype)) |
if (!(chx->stype)) |
103 |
error(_("Nonsymmetric matrix in Csparse_symmeteric_to_general")); |
error(_("Nonsymmetric matrix in Csparse_symmetric_to_general")); |
104 |
chgx = cholmod_copy(chx, 0, chx->xtype, &c); |
chgx = cholmod_copy(chx, /* stype: */ 0, chx->xtype, &c); |
105 |
|
/* xtype: pattern, "real", complex or .. */ |
106 |
|
Free(chx); |
107 |
|
return chm_sparse_to_SEXP(chgx, 1, 0, Rkind, "", |
108 |
|
GET_SLOT(x, Matrix_DimNamesSym)); |
109 |
|
} |
110 |
|
|
111 |
|
SEXP Csparse_general_to_symmetric(SEXP x, SEXP uplo) |
112 |
|
{ |
113 |
|
cholmod_sparse *chx = as_cholmod_sparse(x), *chgx; |
114 |
|
int uploT = (*CHAR(asChar(uplo)) == 'U') ? -1 : 1; |
115 |
|
int Rkind = (chx->xtype == CHOLMOD_REAL) ? Real_kind(x) : 0; |
116 |
|
|
117 |
|
chgx = cholmod_copy(chx, /* stype: */ uploT, chx->xtype, &c); |
118 |
|
/* xtype: pattern, "real", complex or .. */ |
119 |
Free(chx); |
Free(chx); |
120 |
return chm_sparse_to_SEXP(chgx, 1, 0, "", |
return chm_sparse_to_SEXP(chgx, 1, 0, Rkind, "", |
121 |
GET_SLOT(x, Matrix_DimNamesSym)); |
GET_SLOT(x, Matrix_DimNamesSym)); |
122 |
} |
} |
123 |
|
|
124 |
SEXP Csparse_transpose(SEXP x, SEXP tri) |
SEXP Csparse_transpose(SEXP x, SEXP tri) |
125 |
{ |
{ |
126 |
cholmod_sparse *chx = as_cholmod_sparse(x); |
cholmod_sparse *chx = as_cholmod_sparse(x); |
127 |
|
int Rkind = (chx->xtype == CHOLMOD_REAL) ? Real_kind(x) : 0; |
128 |
cholmod_sparse *chxt = cholmod_transpose(chx, (int) chx->xtype, &c); |
cholmod_sparse *chxt = cholmod_transpose(chx, (int) chx->xtype, &c); |
129 |
SEXP dn = PROTECT(duplicate(GET_SLOT(x, Matrix_DimNamesSym))), tmp; |
SEXP dn = PROTECT(duplicate(GET_SLOT(x, Matrix_DimNamesSym))), tmp; |
130 |
int uploT = 0; char *diag = ""; |
int uploT = 0; char *diag = ""; |
135 |
SET_VECTOR_ELT(dn, 1, tmp); |
SET_VECTOR_ELT(dn, 1, tmp); |
136 |
UNPROTECT(1); |
UNPROTECT(1); |
137 |
if (asLogical(tri)) { /* triangular sparse matrices */ |
if (asLogical(tri)) { /* triangular sparse matrices */ |
138 |
uploT = (strcmp(CHAR(asChar(GET_SLOT(x, Matrix_uploSym))), "U")) ? |
uploT = (*uplo_P(x) == 'U') ? -1 : 1; |
139 |
1 : -1; /* switch upper and lower for transpose */ |
diag = diag_P(x); |
|
diag = CHAR(asChar(GET_SLOT(x, Matrix_diagSym))); |
|
140 |
} |
} |
141 |
return chm_sparse_to_SEXP(chxt, 1, uploT, diag, dn); |
return chm_sparse_to_SEXP(chxt, 1, uploT, Rkind, diag, dn); |
142 |
} |
} |
143 |
|
|
144 |
SEXP Csparse_Csparse_prod(SEXP a, SEXP b) |
SEXP Csparse_Csparse_prod(SEXP a, SEXP b) |
153 |
duplicate(VECTOR_ELT(GET_SLOT(a, Matrix_DimNamesSym), 0))); |
duplicate(VECTOR_ELT(GET_SLOT(a, Matrix_DimNamesSym), 0))); |
154 |
SET_VECTOR_ELT(dn, 1, |
SET_VECTOR_ELT(dn, 1, |
155 |
duplicate(VECTOR_ELT(GET_SLOT(b, Matrix_DimNamesSym), 1))); |
duplicate(VECTOR_ELT(GET_SLOT(b, Matrix_DimNamesSym), 1))); |
156 |
return chm_sparse_to_SEXP(chc, 1, 0, "", dn); |
return chm_sparse_to_SEXP(chc, 1, 0, 0, "", dn); |
157 |
|
} |
158 |
|
|
159 |
|
SEXP Csparse_Csparse_crossprod(SEXP a, SEXP b) |
160 |
|
{ |
161 |
|
cholmod_sparse *cha = as_cholmod_sparse(a), |
162 |
|
*chb = as_cholmod_sparse(b); |
163 |
|
cholmod_sparse *chta = cholmod_transpose(cha, 1, &c); |
164 |
|
cholmod_sparse *chc = cholmod_ssmult(chta, chb, 0, cha->xtype, 1, &c); |
165 |
|
SEXP dn = allocVector(VECSXP, 2); |
166 |
|
|
167 |
|
Free(cha); Free(chb); cholmod_free_sparse(&chta, &c); |
168 |
|
SET_VECTOR_ELT(dn, 0, /* establish dimnames */ |
169 |
|
duplicate(VECTOR_ELT(GET_SLOT(a, Matrix_DimNamesSym), 1))); |
170 |
|
SET_VECTOR_ELT(dn, 1, |
171 |
|
duplicate(VECTOR_ELT(GET_SLOT(b, Matrix_DimNamesSym), 1))); |
172 |
|
return chm_sparse_to_SEXP(chc, 1, 0, 0, "", dn); |
173 |
} |
} |
174 |
|
|
175 |
SEXP Csparse_dense_prod(SEXP a, SEXP b) |
SEXP Csparse_dense_prod(SEXP a, SEXP b) |
176 |
{ |
{ |
177 |
cholmod_sparse *cha = as_cholmod_sparse(a); |
cholmod_sparse *cha = as_cholmod_sparse(a); |
178 |
cholmod_dense *chb = as_cholmod_dense(b); |
cholmod_dense *chb = as_cholmod_dense(PROTECT(mMatrix_as_dgeMatrix(b))); |
179 |
cholmod_dense *chc = cholmod_allocate_dense(cha->nrow, chb->ncol, |
cholmod_dense *chc = |
180 |
cha->nrow, chb->xtype, &c); |
cholmod_allocate_dense(cha->nrow, chb->ncol, cha->nrow, chb->xtype, &c); |
181 |
double alpha = 1, beta = 0; |
double alpha[] = {1,0}, beta[] = {0,0}; |
182 |
|
|
183 |
cholmod_sdmult(cha, 0, &alpha, &beta, chb, chc, &c); |
cholmod_sdmult(cha, 0, alpha, beta, chb, chc, &c); |
184 |
Free(cha); Free(chb); |
Free(cha); Free(chb); |
185 |
return chm_dense_to_SEXP(chc, 1); |
UNPROTECT(1); |
186 |
|
return chm_dense_to_SEXP(chc, 1, 0); |
187 |
} |
} |
188 |
|
|
189 |
SEXP Csparse_dense_crossprod(SEXP a, SEXP b) |
SEXP Csparse_dense_crossprod(SEXP a, SEXP b) |
190 |
{ |
{ |
191 |
cholmod_sparse *cha = as_cholmod_sparse(a); |
cholmod_sparse *cha = as_cholmod_sparse(a); |
192 |
cholmod_dense *chb = as_cholmod_dense(b); |
cholmod_dense *chb = as_cholmod_dense(PROTECT(mMatrix_as_dgeMatrix(b))); |
193 |
cholmod_dense *chc = cholmod_allocate_dense(cha->ncol, chb->ncol, |
cholmod_dense *chc = |
194 |
cha->ncol, chb->xtype, &c); |
cholmod_allocate_dense(cha->ncol, chb->ncol, cha->ncol, chb->xtype, &c); |
195 |
double alpha = 1, beta = 0; |
double alpha[] = {1,0}, beta[] = {0,0}; |
196 |
|
|
197 |
cholmod_sdmult(cha, 1, &alpha, &beta, chb, chc, &c); |
cholmod_sdmult(cha, 1, alpha, beta, chb, chc, &c); |
198 |
Free(cha); Free(chb); |
Free(cha); Free(chb); |
199 |
return chm_dense_to_SEXP(chc, 1); |
UNPROTECT(1); |
200 |
|
return chm_dense_to_SEXP(chc, 1, 0); |
201 |
} |
} |
202 |
|
|
203 |
SEXP Csparse_crossprod(SEXP x, SEXP trans, SEXP triplet) |
SEXP Csparse_crossprod(SEXP x, SEXP trans, SEXP triplet) |
215 |
chxt = cholmod_transpose(chx, chx->xtype, &c); |
chxt = cholmod_transpose(chx, chx->xtype, &c); |
216 |
chcp = cholmod_aat((!tr) ? chxt : chx, (int *) NULL, 0, chx->xtype, &c); |
chcp = cholmod_aat((!tr) ? chxt : chx, (int *) NULL, 0, chx->xtype, &c); |
217 |
if(!chcp) |
if(!chcp) |
218 |
error("Csparse_crossprod(): error return from cholmod_aat()"); |
error(_("Csparse_crossprod(): error return from cholmod_aat()")); |
219 |
cholmod_band_inplace(0, chcp->ncol, chcp->xtype, chcp, &c); |
cholmod_band_inplace(0, chcp->ncol, chcp->xtype, chcp, &c); |
220 |
chcp->stype = 1; |
chcp->stype = 1; |
221 |
if (trip) { |
if (trip) { |
231 |
(tr) ? 1 : 0))); |
(tr) ? 1 : 0))); |
232 |
SET_VECTOR_ELT(dn, 1, duplicate(VECTOR_ELT(dn, 0))); |
SET_VECTOR_ELT(dn, 1, duplicate(VECTOR_ELT(dn, 0))); |
233 |
UNPROTECT(1); |
UNPROTECT(1); |
234 |
return chm_sparse_to_SEXP(chcp, 1, 0, "", dn); |
return chm_sparse_to_SEXP(chcp, 1, 0, 0, "", dn); |
235 |
|
} |
236 |
|
|
237 |
|
SEXP Csparse_drop(SEXP x, SEXP tol) |
238 |
|
{ |
239 |
|
cholmod_sparse *chx = as_cholmod_sparse(x), |
240 |
|
*ans = cholmod_copy(chx, chx->stype, chx->xtype, &c); |
241 |
|
double dtol = asReal(tol); |
242 |
|
int Rkind = (chx->xtype == CHOLMOD_REAL) ? Real_kind(x) : 0; |
243 |
|
|
244 |
|
if(!cholmod_drop(dtol, ans, &c)) |
245 |
|
error(_("cholmod_drop() failed")); |
246 |
|
Free(chx); |
247 |
|
/* FIXME: currently drops dimnames */ |
248 |
|
return chm_sparse_to_SEXP(ans, 1, 0, Rkind, "", R_NilValue); |
249 |
} |
} |
250 |
|
|
251 |
|
|
252 |
SEXP Csparse_horzcat(SEXP x, SEXP y) |
SEXP Csparse_horzcat(SEXP x, SEXP y) |
253 |
{ |
{ |
254 |
cholmod_sparse *chx = as_cholmod_sparse(x), |
cholmod_sparse *chx = as_cholmod_sparse(x), |
255 |
*chy = as_cholmod_sparse(y), *ans; |
*chy = as_cholmod_sparse(y), *ans; |
256 |
|
int Rkind = 0; /* only for "d" - FIXME */ |
257 |
|
|
258 |
ans = cholmod_horzcat(chx, chy, 1, &c); |
ans = cholmod_horzcat(chx, chy, 1, &c); |
259 |
Free(chx); Free(chy); |
Free(chx); Free(chy); |
260 |
/* FIXME: currently drops dimnames */ |
/* FIXME: currently drops dimnames */ |
261 |
return chm_sparse_to_SEXP(ans, 1, 0, "", R_NilValue); |
return chm_sparse_to_SEXP(ans, 1, 0, Rkind, "", R_NilValue); |
262 |
} |
} |
263 |
|
|
264 |
SEXP Csparse_vertcat(SEXP x, SEXP y) |
SEXP Csparse_vertcat(SEXP x, SEXP y) |
265 |
{ |
{ |
266 |
cholmod_sparse *chx = as_cholmod_sparse(x), |
cholmod_sparse *chx = as_cholmod_sparse(x), |
267 |
*chy = as_cholmod_sparse(y), *ans; |
*chy = as_cholmod_sparse(y), *ans; |
268 |
|
int Rkind = 0; /* only for "d" - FIXME */ |
269 |
|
|
270 |
ans = cholmod_vertcat(chx, chy, 1, &c); |
ans = cholmod_vertcat(chx, chy, 1, &c); |
271 |
Free(chx); Free(chy); |
Free(chx); Free(chy); |
272 |
/* FIXME: currently drops dimnames */ |
/* FIXME: currently drops dimnames */ |
273 |
return chm_sparse_to_SEXP(ans, 1, 0, "", R_NilValue); |
return chm_sparse_to_SEXP(ans, 1, 0, Rkind, "", R_NilValue); |
274 |
} |
} |
275 |
|
|
276 |
SEXP Csparse_band(SEXP x, SEXP k1, SEXP k2) |
SEXP Csparse_band(SEXP x, SEXP k1, SEXP k2) |
277 |
{ |
{ |
278 |
cholmod_sparse *chx = as_cholmod_sparse(x), *ans; |
cholmod_sparse *chx = as_cholmod_sparse(x), *ans; |
279 |
|
int Rkind = (chx->xtype == CHOLMOD_REAL) ? Real_kind(x) : 0; |
280 |
|
|
281 |
ans = cholmod_band(chx, asInteger(k1), asInteger(k2), chx->xtype, &c); |
ans = cholmod_band(chx, asInteger(k1), asInteger(k2), chx->xtype, &c); |
282 |
Free(chx); |
Free(chx); |
283 |
return chm_sparse_to_SEXP(ans, 1, 0, "", R_NilValue); |
return chm_sparse_to_SEXP(ans, 1, 0, Rkind, "", R_NilValue); |
284 |
} |
} |
285 |
|
|
286 |
SEXP Csparse_diagU2N(SEXP x) |
SEXP Csparse_diagU2N(SEXP x) |
291 |
cholmod_sparse *ans = cholmod_add(chx, eye, one, one, TRUE, TRUE, &c); |
cholmod_sparse *ans = cholmod_add(chx, eye, one, one, TRUE, TRUE, &c); |
292 |
int uploT = (strcmp(CHAR(asChar(GET_SLOT(x, Matrix_uploSym))), "U")) ? |
int uploT = (strcmp(CHAR(asChar(GET_SLOT(x, Matrix_uploSym))), "U")) ? |
293 |
-1 : 1; |
-1 : 1; |
294 |
|
int Rkind = (chx->xtype == CHOLMOD_REAL) ? Real_kind(x) : 0; |
295 |
|
|
296 |
Free(chx); cholmod_free_sparse(&eye, &c); |
Free(chx); cholmod_free_sparse(&eye, &c); |
297 |
return chm_sparse_to_SEXP(ans, 1, uploT, "N", |
return chm_sparse_to_SEXP(ans, 1, uploT, Rkind, "N", |
298 |
duplicate(GET_SLOT(x, Matrix_DimNamesSym))); |
duplicate(GET_SLOT(x, Matrix_DimNamesSym))); |
299 |
} |
} |
300 |
|
|
303 |
cholmod_sparse *chx = as_cholmod_sparse(x); |
cholmod_sparse *chx = as_cholmod_sparse(x); |
304 |
int rsize = (isNull(i)) ? -1 : LENGTH(i), |
int rsize = (isNull(i)) ? -1 : LENGTH(i), |
305 |
csize = (isNull(j)) ? -1 : LENGTH(j); |
csize = (isNull(j)) ? -1 : LENGTH(j); |
306 |
|
int Rkind = (chx->xtype == CHOLMOD_REAL) ? Real_kind(x) : 0; |
307 |
|
|
308 |
if (rsize >= 0 && !isInteger(i)) |
if (rsize >= 0 && !isInteger(i)) |
309 |
error(_("Index i must be NULL or integer")); |
error(_("Index i must be NULL or integer")); |
312 |
return chm_sparse_to_SEXP(cholmod_submatrix(chx, INTEGER(i), rsize, |
return chm_sparse_to_SEXP(cholmod_submatrix(chx, INTEGER(i), rsize, |
313 |
INTEGER(j), csize, |
INTEGER(j), csize, |
314 |
TRUE, TRUE, &c), |
TRUE, TRUE, &c), |
315 |
1, 0, "", R_NilValue); |
1, 0, Rkind, "", R_NilValue); |
316 |
} |
} |