161 |
return chm_dense_to_SEXP(chxd, 1, Rkind, GET_SLOT(x, Matrix_DimNamesSym)); |
return chm_dense_to_SEXP(chxd, 1, Rkind, GET_SLOT(x, Matrix_DimNamesSym)); |
162 |
} |
} |
163 |
|
|
164 |
|
// FIXME: do not go via CHM (should not be too hard, to just *drop* the x-slot, right? |
165 |
SEXP Csparse_to_nz_pattern(SEXP x, SEXP tri) |
SEXP Csparse_to_nz_pattern(SEXP x, SEXP tri) |
166 |
{ |
{ |
167 |
CHM_SP chxs = AS_CHM_SP__(x); |
CHM_SP chxs = AS_CHM_SP__(x); |
175 |
GET_SLOT(x, Matrix_DimNamesSym)); |
GET_SLOT(x, Matrix_DimNamesSym)); |
176 |
} |
} |
177 |
|
|
178 |
|
// n.CMatrix --> [dli].CMatrix (not going through CHM!) |
179 |
|
SEXP nz_pattern_to_Csparse(SEXP x, SEXP res_kind) |
180 |
|
{ |
181 |
|
return nz2Csparse(x, asInteger(res_kind)); |
182 |
|
} |
183 |
|
// n.CMatrix --> [dli].CMatrix (not going through CHM!) |
184 |
|
SEXP nz2Csparse(SEXP x, enum x_slot_kind r_kind) |
185 |
|
{ |
186 |
|
const char *cl_x = class_P(x); |
187 |
|
if(cl_x[0] != 'n') error(_("not a 'n.CMatrix'")); |
188 |
|
if(cl_x[2] != 'C') error(_("not a CsparseMatrix")); |
189 |
|
int nnz = LENGTH(GET_SLOT(x, Matrix_iSym)); |
190 |
|
SEXP ans; |
191 |
|
char *ncl = strdup(cl_x); |
192 |
|
double *dx_x; int *ix_x; |
193 |
|
ncl[0] = (r_kind == x_double ? 'd' : |
194 |
|
(r_kind == x_logical ? 'l' : |
195 |
|
/* else (for now): r_kind == x_integer : */ 'i')); |
196 |
|
PROTECT(ans = NEW_OBJECT(MAKE_CLASS(ncl))); |
197 |
|
// create a correct 'x' slot: |
198 |
|
switch(r_kind) { |
199 |
|
int i; |
200 |
|
case x_double: // 'd' |
201 |
|
dx_x = REAL(ALLOC_SLOT(ans, Matrix_xSym, REALSXP, nnz)); |
202 |
|
for (i=0; i < nnz; i++) dx_x[i] = 1.; |
203 |
|
break; |
204 |
|
case x_logical: // 'l' |
205 |
|
ix_x = LOGICAL(ALLOC_SLOT(ans, Matrix_xSym, LGLSXP, nnz)); |
206 |
|
for (i=0; i < nnz; i++) ix_x[i] = TRUE; |
207 |
|
break; |
208 |
|
case x_integer: // 'i' |
209 |
|
ix_x = INTEGER(ALLOC_SLOT(ans, Matrix_xSym, INTSXP, nnz)); |
210 |
|
for (i=0; i < nnz; i++) ix_x[i] = 1; |
211 |
|
break; |
212 |
|
|
213 |
|
default: |
214 |
|
error(_("nz2Csparse(): invalid/non-implemented r_kind = %d"), |
215 |
|
r_kind); |
216 |
|
} |
217 |
|
|
218 |
|
// now copy all other slots : |
219 |
|
slot_dup(ans, x, Matrix_iSym); |
220 |
|
slot_dup(ans, x, Matrix_pSym); |
221 |
|
slot_dup(ans, x, Matrix_DimSym); |
222 |
|
slot_dup(ans, x, Matrix_DimNamesSym); |
223 |
|
if(ncl[1] != 'g') { // symmetric or triangular ... |
224 |
|
slot_dup_if_has(ans, x, Matrix_uploSym); |
225 |
|
slot_dup_if_has(ans, x, Matrix_diagSym); |
226 |
|
} |
227 |
|
UNPROTECT(1); |
228 |
|
return ans; |
229 |
|
} |
230 |
|
|
231 |
SEXP Csparse_to_matrix(SEXP x) |
SEXP Csparse_to_matrix(SEXP x) |
232 |
{ |
{ |
233 |
return chm_dense_to_matrix(cholmod_l_sparse_to_dense(AS_CHM_SP__(x), &c), |
return chm_dense_to_matrix(cholmod_l_sparse_to_dense(AS_CHM_SP__(x), &c), |
385 |
chb->xtype, &c); |
chb->xtype, &c); |
386 |
SEXP dn = PROTECT(allocVector(VECSXP, 2)); |
SEXP dn = PROTECT(allocVector(VECSXP, 2)); |
387 |
double one[] = {1,0}, zero[] = {0,0}; |
double one[] = {1,0}, zero[] = {0,0}; |
388 |
|
int nprot = 2; |
389 |
R_CheckStack(); |
R_CheckStack(); |
390 |
|
/* Tim Davis, please FIXME: currently (2010-11) *fails* when a is a pattern matrix:*/ |
391 |
|
if(cha->xtype == CHOLMOD_PATTERN) { |
392 |
|
/* warning(_("Csparse_dense_prod(): cholmod_sdmult() not yet implemented for pattern./ ngCMatrix" */ |
393 |
|
/* " --> slightly inefficient coercion")); */ |
394 |
|
|
395 |
|
// This *fails* to produce a CHOLMOD_REAL .. |
396 |
|
// CHM_SP chd = cholmod_l_copy(cha, cha->stype, CHOLMOD_REAL, &c); |
397 |
|
// --> use our Matrix-classes |
398 |
|
SEXP da = PROTECT(nz2Csparse(a, x_double)); nprot++; |
399 |
|
cha = AS_CHM_SP(da); |
400 |
|
} |
401 |
cholmod_l_sdmult(cha, 0, one, zero, chb, chc, &c); |
cholmod_l_sdmult(cha, 0, one, zero, chb, chc, &c); |
402 |
SET_VECTOR_ELT(dn, 0, /* establish dimnames */ |
SET_VECTOR_ELT(dn, 0, /* establish dimnames */ |
403 |
duplicate(VECTOR_ELT(GET_SLOT(a, Matrix_DimNamesSym), 0))); |
duplicate(VECTOR_ELT(GET_SLOT(a, Matrix_DimNamesSym), 0))); |
404 |
SET_VECTOR_ELT(dn, 1, |
SET_VECTOR_ELT(dn, 1, |
405 |
duplicate(VECTOR_ELT(GET_SLOT(b_M, Matrix_DimNamesSym), 1))); |
duplicate(VECTOR_ELT(GET_SLOT(b_M, Matrix_DimNamesSym), 1))); |
406 |
UNPROTECT(2); |
UNPROTECT(nprot); |
407 |
return chm_dense_to_SEXP(chc, 1, 0, dn); |
return chm_dense_to_SEXP(chc, 1, 0, dn); |
408 |
} |
} |
409 |
|
|
414 |
CHM_DN chb = AS_CHM_DN(b_M); |
CHM_DN chb = AS_CHM_DN(b_M); |
415 |
CHM_DN chc = cholmod_l_allocate_dense(cha->ncol, chb->ncol, cha->ncol, |
CHM_DN chc = cholmod_l_allocate_dense(cha->ncol, chb->ncol, cha->ncol, |
416 |
chb->xtype, &c); |
chb->xtype, &c); |
417 |
SEXP dn = PROTECT(allocVector(VECSXP, 2)); |
SEXP dn = PROTECT(allocVector(VECSXP, 2)); int nprot = 2; |
418 |
double one[] = {1,0}, zero[] = {0,0}; |
double one[] = {1,0}, zero[] = {0,0}; |
419 |
R_CheckStack(); |
R_CheckStack(); |
420 |
|
// -- see Csparse_dense_prod() above : |
421 |
|
if(cha->xtype == CHOLMOD_PATTERN) { |
422 |
|
SEXP da = PROTECT(nz2Csparse(a, x_double)); nprot++; |
423 |
|
cha = AS_CHM_SP(da); |
424 |
|
} |
425 |
cholmod_l_sdmult(cha, 1, one, zero, chb, chc, &c); |
cholmod_l_sdmult(cha, 1, one, zero, chb, chc, &c); |
426 |
SET_VECTOR_ELT(dn, 0, /* establish dimnames */ |
SET_VECTOR_ELT(dn, 0, /* establish dimnames */ |
427 |
duplicate(VECTOR_ELT(GET_SLOT(a, Matrix_DimNamesSym), 1))); |
duplicate(VECTOR_ELT(GET_SLOT(a, Matrix_DimNamesSym), 1))); |
428 |
SET_VECTOR_ELT(dn, 1, |
SET_VECTOR_ELT(dn, 1, |
429 |
duplicate(VECTOR_ELT(GET_SLOT(b_M, Matrix_DimNamesSym), 1))); |
duplicate(VECTOR_ELT(GET_SLOT(b_M, Matrix_DimNamesSym), 1))); |
430 |
UNPROTECT(2); |
UNPROTECT(nprot); |
431 |
return chm_dense_to_SEXP(chc, 1, 0, dn); |
return chm_dense_to_SEXP(chc, 1, 0, dn); |
432 |
} |
} |
433 |
|
|
472 |
return chm_sparse_to_SEXP(chcp, 1, 0, 0, "", dn); |
return chm_sparse_to_SEXP(chcp, 1, 0, 0, "", dn); |
473 |
} |
} |
474 |
|
|
475 |
|
/* Csparse_drop(x, tol): drop entries with absolute value < tol, i.e, |
476 |
|
* at least all "explicit" zeros */ |
477 |
SEXP Csparse_drop(SEXP x, SEXP tol) |
SEXP Csparse_drop(SEXP x, SEXP tol) |
478 |
{ |
{ |
479 |
const char *cl = class_P(x); |
const char *cl = class_P(x); |
863 |
case 'l': |
case 'l': |
864 |
error(_("code not yet written for cls = \"lgCMatrix\"")); |
error(_("code not yet written for cls = \"lgCMatrix\"")); |
865 |
} |
} |
866 |
|
/* FIXME: dimnames are *NOT* put there yet (if non-NULL) */ |
867 |
cholmod_l_free_sparse(&A, &c); |
cholmod_l_free_sparse(&A, &c); |
868 |
UNPROTECT(1); |
UNPROTECT(1); |
869 |
return ans; |
return ans; |