Matrix r5059
Loading...
Searching...
No Matches
cholmod-api.c
Go to the documentation of this file.
1#include "Mdefines.h"
2#include "cholmod-api.h"
3
17/* NB: mostly parallel to M2CHF in ./cholmod-etc.c */
18cholmod_factor *sexp_as_cholmod_factor(cholmod_factor *L, SEXP from)
19{
20 static const char *valid[] = {
21 "nsimplicialCholesky", "nsupernodalCholesky",
22 "dsimplicialCholesky", "dsupernodalCholesky",
23 "zsimplicialCholesky", "zsupernodalCholesky", "" };
24 const char *class = Matrix_class(from, valid, -1, __func__);
25 memset(L, 0, sizeof(cholmod_factor));
26 SEXP dim = PROTECT(GET_SLOT(from, Matrix_DimSym)),
27 perm = PROTECT(GET_SLOT(from, Matrix_permSym)),
28 colcount = PROTECT(GET_SLOT(from, Matrix_colcountSym)),
29 ordering = PROTECT(GET_SLOT(from, Matrix_orderingSym));
30 L->ordering = INTEGER(ordering)[0];
31 L->is_super = class[2] == 'u';
32 L->n = (size_t) INTEGER(dim)[0];
33 L->minor = L->n;
34 if (L->ordering != CHOLMOD_NATURAL)
35 L->Perm = INTEGER(perm);
36 else {
37 /* cholmod_check_factor allows L->Perm == NULL,
38 but cholmod_copy_factor does not test, so it segfaults ...
39 */
40 int n = (int) L->n, *Perm = (int *) R_alloc(L->n, sizeof(int));
41 for (int j = 0; j < n; ++j)
42 Perm[j] = j;
43 L->Perm = Perm;
44 }
45 L->ColCount = INTEGER(colcount);
46 if (L->is_super) {
47 SEXP maxcsize = PROTECT(GET_SLOT(from, Matrix_maxcsizeSym)),
48 maxesize = PROTECT(GET_SLOT(from, Matrix_maxesizeSym)),
49 super = PROTECT(GET_SLOT(from, Matrix_superSym)),
50 pi = PROTECT(GET_SLOT(from, Matrix_piSym)),
51 px = PROTECT(GET_SLOT(from, Matrix_pxSym)),
52 s = PROTECT(GET_SLOT(from, Matrix_sSym));
53 L->nsuper = (size_t) (LENGTH(super) - 1);
54 L->ssize = (size_t) INTEGER(pi)[L->nsuper];
55 L->xsize = (size_t) INTEGER(px)[L->nsuper];
56 L->maxcsize = (size_t) INTEGER(maxcsize)[0];
57 L->maxesize = (size_t) INTEGER(maxesize)[0];
58 L->super = INTEGER(super);
59 L->pi = INTEGER(pi);
60 L->px = INTEGER(px);
61 L->s = INTEGER(s);
62 L->is_ll = 1;
63 L->is_monotonic = 1;
64 UNPROTECT(6);
65 } else {
66 if (class[0] != 'n') {
67 SEXP p = PROTECT(GET_SLOT(from, Matrix_pSym)),
68 i = PROTECT(GET_SLOT(from, Matrix_iSym)),
69 nz = PROTECT(GET_SLOT(from, Matrix_nzSym)),
70 next = PROTECT(GET_SLOT(from, Matrix_nextSym)),
71 prev = PROTECT(GET_SLOT(from, Matrix_prevSym)),
72 is_ll = PROTECT(GET_SLOT(from, Matrix_isllSym)),
73 is_monotonic = PROTECT(GET_SLOT(from, Matrix_ismtSym));
74 L->nzmax = (size_t) INTEGER(p)[L->n];
75 L->p = INTEGER(p);
76 L->i = INTEGER(i);
77 L->nz = INTEGER(nz);
78 L->next = INTEGER(next);
79 L->prev = INTEGER(prev);
80 L->is_ll = LOGICAL(is_ll)[0] != 0;
81 L->is_monotonic = LOGICAL(is_monotonic)[0] != 0;
82 UNPROTECT(7);
83 }
84 }
85 L->itype = CHOLMOD_INT;
86 L->xtype = CHOLMOD_PATTERN;
87 L->dtype = CHOLMOD_DOUBLE;
88 if (class[0] != 'n') {
89 SEXP minor = GET_SLOT(from, Matrix_minorSym);
90 L->minor = (size_t) INTEGER(minor)[0];
91 SEXP x = GET_SLOT(from, Matrix_xSym);
92 switch (class[0]) {
93 case 'd':
94 L->x = REAL(x);
95 L->xtype = CHOLMOD_REAL;
96 break;
97 case 'z':
98 L->x = COMPLEX(x);
99 L->xtype = CHOLMOD_COMPLEX;
100 break;
101 default:
102 break;
103 }
104 }
105 UNPROTECT(4);
106 return L;
107}
108
126/* NB: mostly parallel to M2CHS in ./cholmod-etc.c */
127cholmod_sparse *sexp_as_cholmod_sparse(cholmod_sparse *A, SEXP from,
128 Rboolean allocUnit, Rboolean sortInPlace)
129{
130 /* defined in ./Csparse.c : */
131 SEXP checkpi(SEXP dim, SEXP p, SEXP i);
132
133 const char *class = Matrix_class(from, valid_sparse_compressed, 6, __func__);
134 memset(A, 0, sizeof(cholmod_sparse));
135 int mg = (class[2] == 'C') ? 1 : 0;
136 SEXP dim = PROTECT(GET_SLOT(from, Matrix_DimSym)),
137 p = PROTECT(GET_SLOT(from, Matrix_pSym)),
138 i = PROTECT(GET_SLOT(from, (mg == 1) ? Matrix_iSym : Matrix_jSym));
139 A->nrow = (size_t) INTEGER(dim)[(mg == 1) ? 0 : 1];
140 A->ncol = (size_t) INTEGER(dim)[(mg == 1) ? 1 : 0];
141 A->nzmax = (size_t) INTEGER(p)[A->ncol];
142 A->p = INTEGER(p);
143 A->i = INTEGER(i);
144 A->stype = 0;
145 A->itype = CHOLMOD_INT;
146 A->xtype = CHOLMOD_PATTERN;
147 A->dtype = CHOLMOD_DOUBLE;
148 A->sorted = LOGICAL(checkpi(dim, p, i))[0] != 0;
149 A->packed = 1;
150 if (class[1] == 's') {
151 SEXP uplo = GET_SLOT(from, Matrix_uploSym);
152 A->stype = ((CHAR(STRING_ELT(uplo, 0))[0] == 'U') == (mg == 1)) ? 1 : -1;
153 }
154 if (!A->sorted && !sortInPlace) {
155 void *tmp;
156 tmp = A->p;
157 A->p = (void *) R_alloc(A->ncol + 1, sizeof(int));
158 memcpy(A->p, tmp, sizeof(int) * (A->ncol + 1));
159 tmp = A->i;
160 A->i = (void *) R_alloc(A->nzmax, sizeof(int));
161 memcpy(A->i, tmp, sizeof(int) * A->nzmax);
162 }
163 if (class[0] != 'n') {
164 SEXP x = PROTECT(GET_SLOT(from, Matrix_xSym));
165 switch (class[0]) {
166 case 'l':
167 case 'i':
168 {
169 int *px = (TYPEOF(x) == LGLSXP) ? LOGICAL(x) : INTEGER(x);
170 double *Ax = (double *) R_alloc(A->nzmax, sizeof(double));
171 for (size_t k = 0; k < A->nzmax; ++k)
172 Ax[k] = (px[k] == NA_INTEGER) ? NA_REAL : (double) px[k];
173 A->x = Ax;
174 A->xtype = CHOLMOD_REAL;
175 break;
176 }
177 case 'd':
178 A->x = REAL(x);
179 A->xtype = CHOLMOD_REAL;
180 if (!A->sorted && !sortInPlace) {
181 void *tmp = A->x;
182 A->x = (void *) R_alloc(A->nzmax, sizeof(double));
183 memcpy(A->x, tmp, sizeof(double) * A->nzmax);
184 }
185 break;
186 case 'z':
187 A->x = COMPLEX(x);
188 A->xtype = CHOLMOD_COMPLEX;
189 if (!A->sorted && !sortInPlace) {
190 void *tmp = A->x;
191 A->x = (void *) R_alloc(A->nzmax, sizeof(Rcomplex));
192 memcpy(A->x, tmp, sizeof(Rcomplex) * A->nzmax);
193 }
194 break;
195 default:
196 break;
197 }
198 UNPROTECT(1); /* x */
199 }
200 if (!A->sorted && !cholmod_sort(A, &c))
201 Rf_error(_("'%s' failed in '%s'"), "cholmod_sort", __func__);
202 if (class[1] == 't' && A->ncol > 0 && allocUnit) {
203 SEXP diag = GET_SLOT(from, Matrix_diagSym);
204 char nu = CHAR(STRING_ELT(diag, 0))[0];
205 if (nu != 'N') {
206 double one[] = { 1.0, 0.0 };
207 cholmod_sparse *I1 = cholmod_speye(A->nrow, A->ncol, A->xtype, &c);
208 I1->stype = A->stype;
209 cholmod_sparse *A1 = cholmod_add(A, I1, one, one, 1, 1, &c);
210 A->nzmax = (size_t) ((int *) A1->p)[A->ncol];
211 A->p = (void *) R_alloc(A->ncol + 1, sizeof(int));
212 memcpy(A->p, A1->p, sizeof(int) * (A->ncol + 1));
213 A->i = (void *) R_alloc(A->nzmax, sizeof(int));
214 memcpy(A->i, A1->i, sizeof(int) * A->nzmax);
215 if (A->xtype != CHOLMOD_PATTERN) {
216 if (A->xtype == CHOLMOD_REAL) {
217 A->x = (void *) R_alloc(A->nzmax, sizeof(double));
218 memcpy(A->x, A1->x, sizeof(double) * A->nzmax);
219 } else {
220 A->x = (void *) R_alloc(A->nzmax, sizeof(Rcomplex));
221 memcpy(A->x, A1->x, sizeof(double) * A->nzmax);
222 }
223 }
224 cholmod_free_sparse(&I1, &c);
225 cholmod_free_sparse(&A1, &c);
226 }
227 }
228 UNPROTECT(3); /* i, p, dim */
229 return A;
230}
231
247cholmod_triplet *sexp_as_cholmod_triplet(cholmod_triplet *A, SEXP from,
248 Rboolean allocUnit)
249{
250 const char *class = Matrix_class(from, valid_sparse_triplet, 6, __func__);
251 memset(A, 0, sizeof(cholmod_triplet));
252 SEXP dim = PROTECT(GET_SLOT(from, Matrix_DimSym)),
253 i = PROTECT(GET_SLOT(from, Matrix_pSym)),
254 j = PROTECT(GET_SLOT(from, Matrix_iSym));;
255 A->nrow = (size_t) INTEGER(dim)[0];
256 A->ncol = (size_t) INTEGER(dim)[1];
257 A->nzmax = A->nnz = (size_t) XLENGTH(i);
258 A->i = INTEGER(i);
259 A->j = INTEGER(j);
260 A->stype = 0;
261 A->itype = CHOLMOD_INT;
262 A->xtype = CHOLMOD_PATTERN;
263 A->dtype = CHOLMOD_DOUBLE;
264 if (class[1] == 's') {
265 SEXP uplo = GET_SLOT(from, Matrix_uploSym);
266 A->stype = (CHAR(STRING_ELT(uplo, 0))[0] == 'U') ? 1 : -1;
267 }
268 if (class[0] != 'n') {
269 SEXP x = PROTECT(GET_SLOT(from, Matrix_xSym));
270 switch (class[0]) {
271 case 'l':
272 case 'i':
273 {
274 int *px = (TYPEOF(x) == LGLSXP) ? LOGICAL(x) : INTEGER(x);
275 double *Ax = (double *) R_alloc(A->nzmax, sizeof(double));
276 for (size_t k = 0; k < A->nzmax; ++k)
277 Ax[k] = (px[k] == NA_INTEGER) ? NA_REAL : (double) px[k];
278 A->x = Ax;
279 A->xtype = CHOLMOD_REAL;
280 break;
281 }
282 case 'd':
283 A->x = REAL(x);
284 A->xtype = CHOLMOD_REAL;
285 break;
286 case 'z':
287 A->x = COMPLEX(x);
288 A->xtype = CHOLMOD_COMPLEX;
289 break;
290 default:
291 break;
292 }
293 UNPROTECT(1); /* x */
294 }
295 if (class[1] == 't' && A->ncol > 0 && allocUnit) {
296 SEXP diag = GET_SLOT(from, Matrix_diagSym);
297 char nu = CHAR(STRING_ELT(diag, 0))[0];
298 if (nu != 'N') {
299 A->nzmax += A->ncol;
300 void *tmp;
301 tmp = A->i;
302 A->i = (void *) R_alloc(A->nzmax, sizeof(int));
303 memcpy(A->i, tmp, sizeof(int) * A->nnz);
304 tmp = A->j;
305 A->j = (void *) R_alloc(A->nzmax, sizeof(int));
306 memcpy(A->j, tmp, sizeof(int) * A->nnz);
307 if (A->xtype != CHOLMOD_PATTERN) {
308 tmp = A->x;
309 if (A->xtype == CHOLMOD_REAL) {
310 A->x = (void *) R_alloc(A->nzmax, sizeof(double));
311 memcpy(A->x, tmp, sizeof(double) * A->nnz);
312 } else {
313 A->x = (void *) R_alloc(A->nzmax, sizeof(Rcomplex));
314 memcpy(A->x, tmp, sizeof(Rcomplex) * A->nnz);
315 }
316 }
317 int n = (int) A->ncol,
318 *Ai = ((int *) A->i) + A->nnz,
319 *Aj = ((int *) A->j) + A->nnz;
320 for (int j = 0; j < n; ++j)
321 Ai[j] = Aj[j] = j;
322 if (A->xtype != CHOLMOD_PATTERN) {
323 if (A->xtype == CHOLMOD_REAL) {
324 double *Ax = ((double *) A->x) + A->nnz;
325 for (int j = 0; j < n; ++j)
326 Ax[j] = 1.0;
327 } else {
328 Rcomplex *Ax = ((Rcomplex *) A->x) + A->nnz;
329 for (int j = 0; j < n; ++j)
330 Ax[j] = Matrix_zunit;
331 }
332 }
333 A->nnz += A->ncol;
334 }
335 }
336 UNPROTECT(3); /* j, i, dim */
337 return A;
338}
339
355/* NB: mostly parallel to M2CHD in ./cholmod-etc.c */
356cholmod_dense *sexp_as_cholmod_dense(cholmod_dense *A, SEXP from)
357{
358 static const char *valid[] = {
359 "ngeMatrix", "lgeMatrix", "igeMatrix", "dgeMatrix", "zgeMatrix", "" };
360 const char *class = Matrix_class(from, valid, 0, NULL);
361 int m, n;
362 if (class) {
363 SEXP dim = GET_SLOT(from, Matrix_DimSym);
364 m = INTEGER(dim)[0];
365 n = INTEGER(dim)[1];
366 from = GET_SLOT(from, Matrix_xSym);
367 } else {
368 switch (TYPEOF(from)) {
369 case LGLSXP:
370 case INTSXP:
371 case REALSXP:
372 case CPLXSXP:
373 break;
374 default:
375 ERROR_INVALID_TYPE(from, __func__);
376 break;
377 }
378 SEXP dim = Rf_getAttrib(from, R_DimSymbol);
379 if (TYPEOF(dim) == INTSXP && LENGTH(dim) == 2) {
380 m = INTEGER(dim)[0];
381 n = INTEGER(dim)[1];
382 } else {
383 m = LENGTH(from);
384 n = 1;
385 }
386 }
387 PROTECT(from);
388 memset(A, 0, sizeof(cholmod_dense));
389 A->nrow = (size_t) m;
390 A->ncol = (size_t) n;
391 A->nzmax = A->nrow * A->ncol;
392 A->d = A->nrow;
393 A->dtype = CHOLMOD_DOUBLE;
394 switch (TYPEOF(from)) {
395 case LGLSXP:
396 case INTSXP:
397 {
398 int pattern = class[0] == 'n';
399 int *px = (TYPEOF(from) == LGLSXP) ? LOGICAL(from) : INTEGER(from);
400 double *Ax = (double *) R_alloc(A->nzmax, sizeof(double));
401 for (size_t k = 0; k < A->nzmax; ++k)
402 Ax[k] = (px[k] == NA_INTEGER)
403 ? ((pattern) ? 1.0 : NA_REAL) : (double) px[k];
404 A->x = Ax;
405 A->xtype = CHOLMOD_REAL;
406 break;
407 }
408 case REALSXP:
409 A->x = REAL(from);
410 A->xtype = CHOLMOD_REAL;
411 break;
412 case CPLXSXP:
413 A->x = COMPLEX(from);
414 A->xtype = CHOLMOD_COMPLEX;
415 break;
416 default:
417 break;
418 }
419 UNPROTECT(1); /* from */
420 return A;
421}
422
436cholmod_dense *numeric_as_cholmod_dense(cholmod_dense *A,
437 double *data, int nrow, int ncol)
438{
439 memset(A, 0, sizeof(cholmod_dense));
440 A->nrow = (size_t) nrow;
441 A->ncol = (size_t) ncol;
442 A->nzmax = A->nrow * A->ncol;
443 A->d = A->nrow;
444 A->x = data;
445 A->xtype = CHOLMOD_REAL;
446 A->dtype = CHOLMOD_DOUBLE;
447 return A;
448}
449
465/* NB: mostly parallel to CHF2M in ./cholmod-etc.c */
466SEXP cholmod_factor_as_sexp(cholmod_factor *L, int doFree)
467{
468
469#define errorFree(...) \
470 do { \
471 MAYBE_FREE; \
472 Rf_error(__VA_ARGS__); \
473 } while (0)
474
475#define MAYBE_FREE \
476 do { \
477 if (doFree != 0) { \
478 if (doFree < 0) \
479 R_Free(L); \
480 else if (L->itype == CHOLMOD_INT) \
481 cholmod_free_factor(&L, &c); \
482 else \
483 cholmod_l_free_factor(&L, &cl); \
484 } \
485 } while (0)
486
487 if (L->itype != CHOLMOD_INT)
488 errorFree(_("wrong '%s'"), "itype");
489 if (L->xtype != CHOLMOD_PATTERN &&
490 L->xtype != CHOLMOD_REAL && L->xtype != CHOLMOD_COMPLEX)
491 errorFree(_("wrong '%s'"), "xtype");
492 if (L->dtype != CHOLMOD_DOUBLE)
493 errorFree(_("wrong '%s'"), "dtype");
494 if (L->n > INT_MAX)
495 errorFree(_("dimensions cannot exceed %s"), "2^31-1");
496 if (L->super) {
497 if (L->maxcsize > INT_MAX)
498 errorFree(_("'%s' would overflow type \"%s\""),
499 "maxcsize", "integer");
500 } else {
501 if (L->n == INT_MAX)
502 errorFree(_("n+1 would overflow type \"%s\""),
503 "integer");
504 }
505 if (L->minor < L->n) {
506 if (L->is_ll)
507 errorFree(_("leading principal minor of order %d is not positive"),
508 (int) L->minor + 1);
509 else
510 errorFree(_("leading principal minor of order %d is zero"),
511 (int) L->minor + 1);
512 }
513 char class[] = "...........Cholesky";
514 class[0] = (L->xtype == CHOLMOD_PATTERN)
515 ? 'n' : ((L->xtype == CHOLMOD_REAL) ? 'd' : 'z');
516 memcpy(class + 1, (L->is_super) ? "supernodal" : "simplicial", 10);
517 SEXP to = PROTECT(newObject(class)),
518 dim = PROTECT(GET_SLOT(to, Matrix_DimSym)),
519 ordering = PROTECT(GET_SLOT(to, Matrix_orderingSym));
520 INTEGER(ordering)[0] = L->ordering;
521 INTEGER(dim)[0] = INTEGER(dim)[1] = (int) L->n;
522 if (L->ordering != CHOLMOD_NATURAL) {
523 SEXP perm = PROTECT(Rf_allocVector(INTSXP, (R_xlen_t) L->n));
524 memcpy(INTEGER(perm), L->Perm, sizeof(int) * L->n);
525 SET_SLOT(to, Matrix_permSym, perm);
526 UNPROTECT(1);
527 }
528 SEXP colcount = PROTECT(Rf_allocVector(INTSXP, (R_xlen_t) L->n));
529 memcpy(INTEGER(colcount), L->ColCount, sizeof(int) * L->n);
530 SET_SLOT(to, Matrix_colcountSym, colcount);
531 UNPROTECT(1);
532 if (L->is_super) {
533 SEXP maxcsize = PROTECT(GET_SLOT(to, Matrix_maxcsizeSym)),
534 maxesize = PROTECT(GET_SLOT(to, Matrix_maxesizeSym)),
535 super = PROTECT(Rf_allocVector(INTSXP, (R_xlen_t) (L->nsuper + 1))),
536 pi = PROTECT(Rf_allocVector(INTSXP, (R_xlen_t) (L->nsuper + 1))),
537 px = PROTECT(Rf_allocVector(INTSXP, (R_xlen_t) (L->nsuper + 1))),
538 s = PROTECT(Rf_allocVector(INTSXP, (R_xlen_t) L->ssize));
539 INTEGER(maxcsize)[0] = (int) L->maxcsize;
540 INTEGER(maxesize)[0] = (int) L->maxesize;
541 memcpy(INTEGER(super), L->super, sizeof(int) * (L->nsuper + 1));
542 memcpy(INTEGER(pi), L->pi, sizeof(int) * (L->nsuper + 1));
543 memcpy(INTEGER(px), L->px, sizeof(int) * (L->nsuper + 1));
544 memcpy(INTEGER(s), L->s, sizeof(int) * L->ssize);
545 SET_SLOT(to, Matrix_superSym, super);
546 SET_SLOT(to, Matrix_piSym, pi);
547 SET_SLOT(to, Matrix_pxSym, px);
548 SET_SLOT(to, Matrix_sSym, s);
549 UNPROTECT(6);
550 } else {
551 if (L->xtype != CHOLMOD_PATTERN) {
552 SEXP p = PROTECT(Rf_allocVector(INTSXP, (R_xlen_t) (L->n + 1))),
553 i = PROTECT(Rf_allocVector(INTSXP, (R_xlen_t) L->nzmax)),
554 nz = PROTECT(Rf_allocVector(INTSXP, (R_xlen_t) L->n)),
555 next = PROTECT(Rf_allocVector(INTSXP, (R_xlen_t) (L->n + 2))),
556 prev = PROTECT(Rf_allocVector(INTSXP, (R_xlen_t) (L->n + 2))),
557 is_ll = PROTECT(GET_SLOT(to, Matrix_isllSym)),
558 is_monotonic = PROTECT(GET_SLOT(to, Matrix_ismtSym));
559 memcpy(INTEGER(p), L->p, sizeof(int) * (L->n + 1));
560 memcpy(INTEGER(i), L->i, sizeof(int) * L->nzmax);
561 memcpy(INTEGER(nz), L->nz, sizeof(int) * L->n);
562 memcpy(INTEGER(next), L->next, sizeof(int) * (L->n + 2));
563 memcpy(INTEGER(prev), L->prev, sizeof(int) * (L->n + 2));
564 LOGICAL(is_ll)[0] = L->is_ll != 0;
565 LOGICAL(is_monotonic)[0] = L->is_monotonic != 0;
566 SET_SLOT(to, Matrix_pSym, p);
567 SET_SLOT(to, Matrix_iSym, i);
568 SET_SLOT(to, Matrix_nzSym, nz);
569 SET_SLOT(to, Matrix_nextSym, next);
570 SET_SLOT(to, Matrix_prevSym, prev);
571 UNPROTECT(7);
572 }
573 }
574 if (L->xtype != CHOLMOD_PATTERN) {
575 SEXP minor = GET_SLOT(to, Matrix_minorSym);
576 INTEGER(minor)[0] = (int) L->minor;
577 SEXP x;
578 size_t nnz = (L->is_super) ? L->xsize : L->nzmax;
579 if (L->xtype == CHOLMOD_REAL) {
580 PROTECT(x = Rf_allocVector(REALSXP, (R_xlen_t) nnz));
581 memcpy(REAL(x), L->x, sizeof(double) * nnz);
582 } else {
583 PROTECT(x = Rf_allocVector(CPLXSXP, (R_xlen_t) nnz));
584 memcpy(COMPLEX(x), L->x, sizeof(Rcomplex) * nnz);
585 }
586 SET_SLOT(to, Matrix_xSym, x);
587 UNPROTECT(1);
588 }
590
591#undef MAYBE_FREE
592
593 UNPROTECT(3);
594 return to;
595}
596
624/* NB: mostly parallel to CHS2M in ./cholmod-etc.c */
625SEXP cholmod_sparse_as_sexp(cholmod_sparse *A, int doFree,
626 int ttype, int doLogic, const char *diagString,
627 SEXP dimnames)
628{
629
630#define MAYBE_FREE \
631 do { \
632 if (doFree != 0) { \
633 if (doFree < 0) \
634 R_Free(A_); \
635 else if (A_->itype == CHOLMOD_INT) \
636 cholmod_free_sparse(&A_, &c); \
637 else \
638 cholmod_l_free_sparse(&A_, &cl); \
639 } \
640 } while (0)
641
642 cholmod_sparse *A_ = A;
643 if (A->itype != CHOLMOD_INT)
644 errorFree(_("wrong '%s'"), "itype");
645 if (A->xtype != CHOLMOD_PATTERN &&
646 A->xtype != CHOLMOD_REAL && A->xtype != CHOLMOD_COMPLEX)
647 errorFree(_("wrong '%s'"), "xtype");
648 if (A->dtype != CHOLMOD_DOUBLE)
649 errorFree(_("wrong '%s'"), "dtype");
650 if (A->nrow > INT_MAX || A->ncol > INT_MAX)
651 errorFree(_("dimensions cannot exceed %s"), "2^31-1");
652 if (!A->sorted)
653 cholmod_sort(A, &c);
654 if (!A->packed || A->stype != 0)
655 A = cholmod_copy(A, A->stype, 2, &c);
656 char class[] = "..CMatrix";
657 class[0] = (A->xtype == CHOLMOD_PATTERN)
658 ? 'n' : ((A->xtype == CHOLMOD_REAL) ? ((doLogic) ? 'l' : 'd') : 'z');
659 class[1] = (ttype != 0) ? 't' : ((A->stype != 0) ? 's' : 'g');
660 int nnz = ((int *) A->p)[A->ncol];
661 SEXP to = PROTECT(newObject(class)),
662 dim = PROTECT(GET_SLOT(to, Matrix_DimSym)),
663 p = PROTECT(Rf_allocVector(INTSXP, (R_xlen_t) (A->ncol + 1))),
664 i = PROTECT(Rf_allocVector(INTSXP, (R_xlen_t) nnz));
665 INTEGER(dim)[0] = (int) A->nrow;
666 INTEGER(dim)[1] = (int) A->ncol;
667 memcpy(INTEGER(p), A->p, sizeof(int) * (A->ncol + 1));
668 memcpy(INTEGER(i), A->i, sizeof(int) * (size_t) nnz);
669 SET_SLOT(to, Matrix_pSym, p);
670 SET_SLOT(to, Matrix_iSym, i);
671 if (A->xtype != CHOLMOD_PATTERN) {
672 SEXP x;
673 if (A->xtype == CHOLMOD_REAL) {
674 if (doLogic) {
675 PROTECT(x = Rf_allocVector(LGLSXP, nnz));
676 int *px = LOGICAL(x);
677 double *Ax = (double *) A->x;
678 for (int k = 0; k < nnz; ++k)
679 px[k] = (ISNAN(Ax[k])) ? NA_LOGICAL : (Ax[k] != 0.0);
680 } else {
681 PROTECT(x = Rf_allocVector(REALSXP, nnz));
682 memcpy(REAL(x), A->x, sizeof(double) * (size_t) nnz);
683 }
684 } else {
685 PROTECT(x = Rf_allocVector(CPLXSXP, nnz));
686 memcpy(COMPLEX(x), A->x, sizeof(Rcomplex) * (size_t) nnz);
687 }
688 SET_SLOT(to, Matrix_xSym, x);
689 UNPROTECT(1);
690 }
691 if (ttype < 0 || A->stype < 0) {
692 SEXP uplo = PROTECT(Rf_mkString("L"));
693 SET_SLOT(to, Matrix_uploSym, uplo);
694 UNPROTECT(1);
695 }
696 if (ttype != 0 && diagString && diagString[0] != 'N') {
697 SEXP diag = PROTECT(Rf_mkString("U"));
698 SET_SLOT(to, Matrix_diagSym, diag);
699 UNPROTECT(1);
700 }
701 if (TYPEOF(dimnames) == VECSXP && XLENGTH(dimnames) == 2)
702 SET_SLOT(to, Matrix_DimNamesSym, dimnames);
703 if (A != A_)
704 cholmod_free_sparse(&A, &c);
706
707#undef MAYBE_FREE
708
709 UNPROTECT(4);
710 return to;
711}
712
740SEXP cholmod_triplet_as_sexp(cholmod_triplet *A, int doFree,
741 int ttype, int doLogic, const char *diagString,
742 SEXP dimnames)
743{
744
745#define MAYBE_FREE \
746 do { \
747 if (doFree != 0) { \
748 if (doFree < 0) \
749 R_Free(A); \
750 else if (A->itype == CHOLMOD_INT) \
751 cholmod_free_triplet(&A, &c); \
752 else \
753 cholmod_l_free_triplet(&A, &cl); \
754 } \
755 } while (0)
756
757 if (A->itype != CHOLMOD_INT)
758 errorFree(_("wrong '%s'"), "itype");
759 if (A->xtype != CHOLMOD_PATTERN &&
760 A->xtype != CHOLMOD_REAL && A->xtype != CHOLMOD_COMPLEX)
761 errorFree(_("wrong '%s'"), "xtype");
762 if (A->dtype != CHOLMOD_DOUBLE)
763 errorFree(_("wrong '%s'"), "dtype");
764 if (A->nrow > INT_MAX || A->ncol > INT_MAX)
765 errorFree(_("dimensions cannot exceed %s"), "2^31-1");
766 char class[] = "..TMatrix";
767 class[0] = (A->xtype == CHOLMOD_PATTERN)
768 ? 'n' : ((A->xtype == CHOLMOD_REAL) ? ((doLogic) ? 'l' : 'd') : 'z');
769 class[1] = (ttype != 0) ? 't' : ((A->stype != 0) ? 's' : 'g');
770 SEXP to = PROTECT(newObject(class)),
771 dim = PROTECT(GET_SLOT(to, Matrix_DimSym)),
772 i = PROTECT(Rf_allocVector(INTSXP, (R_xlen_t) A->nnz)),
773 j = PROTECT(Rf_allocVector(INTSXP, (R_xlen_t) A->nnz));
774 INTEGER(dim)[0] = (int) A->nrow;
775 INTEGER(dim)[1] = (int) A->ncol;
776 if (A->stype == 0) {
777 memcpy(INTEGER(i), A->i, sizeof(int) * A->nnz);
778 memcpy(INTEGER(j), A->j, sizeof(int) * A->nnz);
779 } else {
780 int *pi = INTEGER(i), *Ai = (int *) A->i,
781 *pj = INTEGER(j), *Aj = (int *) A->j;
782 for (size_t k = 0; k < A->nnz; ++k) {
783 if ((Ai[k] <= Aj[k]) == (A->stype > 0)) {
784 pi[k] = Ai[k];
785 pj[k] = Aj[k];
786 } else {
787 pi[k] = Aj[k];
788 pj[k] = Ai[k];
789 }
790 }
791 }
792 SET_SLOT(to, Matrix_iSym, i);
793 SET_SLOT(to, Matrix_jSym, j);
794 if (A->xtype != CHOLMOD_PATTERN) {
795 SEXP x;
796 if (A->xtype == CHOLMOD_REAL) {
797 if (doLogic) {
798 PROTECT(x = Rf_allocVector(LGLSXP, (R_xlen_t) A->nnz));
799 int *px = LOGICAL(x);
800 double *Ax = (double *) A->x;
801 for (size_t k = 0; k < A->nnz; ++k)
802 px[k] = (ISNAN(Ax[k])) ? NA_LOGICAL : (Ax[k] != 0.0);
803 } else {
804 PROTECT(x = Rf_allocVector(REALSXP, (R_xlen_t) A->nnz));
805 memcpy(REAL(x), A->x, sizeof(double) * A->nnz);
806 }
807 } else {
808 PROTECT(x = Rf_allocVector(CPLXSXP, (R_xlen_t) A->nnz));
809 memcpy(COMPLEX(x), A->x, sizeof(Rcomplex) * A->nnz);
810 }
811 SET_SLOT(to, Matrix_xSym, x);
812 UNPROTECT(1);
813 }
814 if (ttype < 0 || A->stype < 0) {
815 SEXP uplo = PROTECT(Rf_mkString("L"));
816 SET_SLOT(to, Matrix_uploSym, uplo);
817 UNPROTECT(1);
818 }
819 if (ttype != 0 && diagString && diagString[0] != 'N') {
820 SEXP diag = PROTECT(Rf_mkString("U"));
821 SET_SLOT(to, Matrix_diagSym, diag);
822 UNPROTECT(1);
823 }
824 if (TYPEOF(dimnames) == VECSXP && XLENGTH(dimnames) == 2)
825 SET_SLOT(to, Matrix_DimNamesSym, dimnames);
826
828
829#undef MAYBE_FREE
830
831 UNPROTECT(4);
832 return to;
833}
834
850/* NB: mostly parallel to CHD2M in ./cholmod-etc.c */
851SEXP cholmod_dense_as_sexp(cholmod_dense *A, int doFree)
852{
853
854#define MAYBE_FREE \
855 do { \
856 if (doFree != 0) { \
857 if (doFree < 0) \
858 R_Free(A); \
859 else \
860 cholmod_free_dense(&A, &c); \
861 } \
862 } while (0)
863
864 if (A->xtype != CHOLMOD_REAL && A->xtype != CHOLMOD_COMPLEX)
865 errorFree(_("wrong '%s'"), "xtype");
866 if (A->dtype != CHOLMOD_DOUBLE)
867 errorFree(_("wrong '%s'"), "dtype");
868 if (A->d != A->nrow) /* MJ: currently no need to support this case */
869 errorFree(_("leading dimension not equal to number of rows"));
870 if (A->nrow > INT_MAX || A->ncol > INT_MAX)
871 errorFree(_("dimensions cannot exceed %s"), "2^31-1");
872 if (A->nrow * A->ncol > R_XLEN_T_MAX)
873 errorFree(_("attempt to allocate vector of length exceeding %s"),
874 "R_XLEN_T_MAX");
875 char class[] = ".geMatrix";
876 class[0] = (A->xtype == CHOLMOD_COMPLEX) ? 'z' : 'd';
877 SEXP to = PROTECT(newObject(class)),
878 dim = PROTECT(GET_SLOT(to, Matrix_DimSym));
879 INTEGER(dim)[0] = (int) A->nrow;
880 INTEGER(dim)[1] = (int) A->ncol;
881 SEXP x;
882 if (A->xtype == CHOLMOD_REAL) {
883 PROTECT(x = Rf_allocVector(REALSXP, (R_xlen_t) (A->nrow * A->ncol)));
884 memcpy(REAL(x), A->x, sizeof(double) * (A->nrow * A->ncol));
885 } else {
886 PROTECT(x = Rf_allocVector(CPLXSXP, (R_xlen_t) (A->nrow * A->ncol)));
887 memcpy(COMPLEX(x), A->x, sizeof(Rcomplex) * (A->nrow * A->ncol));
888 }
889 SET_SLOT(to, Matrix_xSym, x);
890 UNPROTECT(1);
892
893#undef MAYBE_FREE
894
895 UNPROTECT(2);
896 return to;
897}
898
911double cholmod_factor_ldetA(cholmod_factor *L)
912{
913 int i, j, p;
914 double ans = 0;
915 if (L->is_super) {
916 int *lpi = (int *) L->pi, *lsup = (int *) L->super;
917 for (i = 0; i < L->nsuper; i++) {
918 int nrp1 = 1 + lpi[i + 1] - lpi[i],
919 nc = lsup[i + 1] - lsup[i];
920 double *x = (double *) L->x + ((int *) L->px)[i];
921 for (R_xlen_t jn = 0, j = 0; j < nc; j++, jn += nrp1)
922 ans += 2.0 * log(fabs(x[jn]));
923 }
924 } else {
925 int *li = (int *) L->i, *lp = (int *) L->p;
926 double *lx = (double *) L->x;
927 for (j = 0; j < L->n; j++) {
928 for (p = lp[j]; li[p] != j && p < lp[j + 1]; p++)
929 ;
930 if (li[p] != j) {
931 Rf_error(_("invalid simplicial Cholesky factorization: structural zero on main diagonal in column %d"),
932 j);
933 break;
934 }
935 ans += log(lx[p] * ((L->is_ll) ? lx[p] : 1.0));
936 }
937 }
938 return ans;
939}
940
958cholmod_factor *cholmod_factor_update(cholmod_factor *L, cholmod_sparse *A,
959 double beta)
960{
961 int ll = L->is_ll;
962 double z[2];
963 z[0] = beta;
964 z[1] = 0.0;
965 if (!cholmod_factorize_p(A, z, NULL, 0, L, &c))
966 Rf_error(_("'%s' failed in '%s'"), "cholmod_factorize_p", __func__);
967 if (L->is_ll != ll &&
968 !cholmod_change_factor(L->xtype, ll, L->is_super, 1, 1, L, &c))
969 Rf_error(_("'%s' failed in '%s'"), "cholmod_change_factor", __func__);
970 return L;
971}
SEXP checkpi(SEXP dim, SEXP p, SEXP i)
Definition Csparse.c:6
SEXP allocUnit(SEXPTYPE, R_xlen_t)
Definition utils.c:94
#define _(String)
Definition Mdefines.h:66
const char * Matrix_class(SEXP, const char **, int, const char *)
Definition objects.c:112
#define ERROR_INVALID_TYPE(_X_, _FUNC_)
Definition Mdefines.h:145
const char * valid_sparse_triplet[]
Definition Mdefines.h:330
#define GET_SLOT(x, name)
Definition Mdefines.h:72
SEXP newObject(const char *)
Definition objects.c:13
const char * valid_sparse_compressed[]
Definition Mdefines.h:329
#define SET_SLOT(x, name, value)
Definition Mdefines.h:73
#define TYPEOF(s)
Definition Mdefines.h:123
#define MAYBE_FREE
cholmod_dense * numeric_as_cholmod_dense(cholmod_dense *A, double *data, int nrow, int ncol)
Coerce from (double *) to (cholmod_dense *) with given dimensions.
cholmod_triplet * sexp_as_cholmod_triplet(cholmod_triplet *A, SEXP from, Rboolean allocUnit)
Coerce from TsparseMatrix to (cholmod_triplet *)
SEXP cholmod_sparse_as_sexp(cholmod_sparse *A, int doFree, int ttype, int doLogic, const char *diagString, SEXP dimnames)
Coerce from (cholmod_sparse *) to CsparseMatrix.
cholmod_factor * sexp_as_cholmod_factor(cholmod_factor *L, SEXP from)
Coerce from sparseCholesky to (cholmod_factor *)
Definition cholmod-api.c:18
SEXP cholmod_dense_as_sexp(cholmod_dense *A, int doFree)
Coerce from (cholmod_dense *) to [dz]geMatrix.
#define errorFree(...)
cholmod_dense * sexp_as_cholmod_dense(cholmod_dense *A, SEXP from)
Coerce from .geMatrix or vector to (cholmod_dense *)
SEXP cholmod_triplet_as_sexp(cholmod_triplet *A, int doFree, int ttype, int doLogic, const char *diagString, SEXP dimnames)
Coerce from (cholmod_triplet *) to TsparseMatrix.
double cholmod_factor_ldetA(cholmod_factor *L)
Log determinant from Cholesky factorization.
cholmod_sparse * sexp_as_cholmod_sparse(cholmod_sparse *A, SEXP from, Rboolean allocUnit, Rboolean sortInPlace)
Coerce from [CR]sparseMatrix to (cholmod_sparse *)
cholmod_factor * cholmod_factor_update(cholmod_factor *L, cholmod_sparse *A, double beta)
Update a Cholesky factorization.
SEXP cholmod_factor_as_sexp(cholmod_factor *L, int doFree)
Coerce from (cholmod_factor *) to sparseCholesky.
cholmod_common c
Definition cholmod-etc.c:5
SEXP Matrix_nextSym
Definition init.c:618
SEXP Matrix_nzSym
Definition init.c:619
SEXP Matrix_permSym
Definition init.c:623
SEXP Matrix_DimSym
Definition init.c:598
SEXP Matrix_pxSym
Definition init.c:626
SEXP Matrix_prevSym
Definition init.c:625
SEXP Matrix_orderingSym
Definition init.c:621
Rcomplex Matrix_zunit
Definition init.c:642
SEXP Matrix_xSym
Definition init.c:635
SEXP Matrix_iSym
Definition init.c:607
SEXP Matrix_sSym
Definition init.c:628
SEXP Matrix_jSym
Definition init.c:610
SEXP Matrix_DimNamesSym
Definition init.c:597
SEXP Matrix_maxesizeSym
Definition init.c:616
SEXP Matrix_diagSym
Definition init.c:605
SEXP Matrix_superSym
Definition init.c:630
SEXP Matrix_uploSym
Definition init.c:632
SEXP Matrix_minorSym
Definition init.c:617
SEXP Matrix_isllSym
Definition init.c:608
SEXP Matrix_colcountSym
Definition init.c:604
SEXP Matrix_ismtSym
Definition init.c:609
SEXP Matrix_pSym
Definition init.c:622
SEXP Matrix_maxcsizeSym
Definition init.c:615
SEXP Matrix_piSym
Definition init.c:624