82 static const char *
valid[] = {
83 "dCHMsuper",
"dCHMsimpl",
"nCHMsuper",
"nCHMsimpl",
"" };
84 int ivalid = R_check_class_etc(from,
valid);
87 const char *
class =
valid[ivalid];
88 memset(L, 0,
sizeof(cholmod_factor));
91 type = PROTECT(
GET_SLOT(from, install(
"type"))),
93 colcount = PROTECT(
GET_SLOT(from, install(
"colcount")));
94 L->n = INTEGER(dim)[0];
96 L->ordering = INTEGER(type)[0];
97 if (L->ordering != CHOLMOD_NATURAL)
98 L->Perm = INTEGER(perm);
103 int n = (int) L->n, *Perm = (
int *) R_alloc(L->n,
sizeof(
int));
104 for (
int j = 0; j < n; ++j)
108 L->ColCount = INTEGER(colcount);
109 L->is_super = INTEGER(type)[2];
113 SEXP super = PROTECT(
GET_SLOT(from, install(
"super"))),
114 pi = PROTECT(
GET_SLOT(from, install(
"pi"))),
115 px = PROTECT(
GET_SLOT(from, install(
"px"))),
116 s = PROTECT(
GET_SLOT(from, install(
"s")));
117 L->super = INTEGER(super);
121 L->nsuper = LENGTH(super) - 1;
122 L->ssize = ((
int *) L->pi)[L->nsuper];
123 L->xsize = ((
int *) L->px)[L->nsuper];
124 L->maxcsize = INTEGER(type)[4];
125 L->maxesize = INTEGER(type)[5];
128 L->is_ll = INTEGER(type)[1];
129 L->is_monotonic = INTEGER(type)[3];
130 if (
class[0] !=
'n') {
133 nz = PROTECT(
GET_SLOT(from, install(
"nz"))),
134 nxt = PROTECT(
GET_SLOT(from, install(
"nxt"))),
135 prv = PROTECT(
GET_SLOT(from, install(
"prv")));
139 L->next = INTEGER(nxt);
140 L->prev = INTEGER(prv);
141 L->nzmax = ((
int *) L->p)[L->n];
145 L->itype = CHOLMOD_INT;
146 L->dtype = CHOLMOD_DOUBLE;
147 if (
class[0] !=
'n') {
152 L->xtype = CHOLMOD_COMPLEX;
156 L->xtype = CHOLMOD_REAL;
164 if (!cholmod_check_factor(L, &
c))
165 error(
_(
"'%s' failed in '%s'"),
"cholmod_check_factor", __func__);
189 Rboolean checkUnit, Rboolean sortInPlace)
195 static const char *
valid[] = {
196 "dgCMatrix",
"dsCMatrix",
"dtCMatrix",
197 "lgCMatrix",
"lsCMatrix",
"ltCMatrix",
198 "ngCMatrix",
"nsCMatrix",
"ntCMatrix",
"" };
199 int ivalid = R_check_class_etc(from,
valid);
202 const char *
class =
valid[ivalid];
203 memset(A, 0,
sizeof(cholmod_sparse));
206 int *pdim = INTEGER(dim), m = pdim[0], n = pdim[1];
210 cpi = PROTECT(
checkpi(p, i, m, n));
211 if (TYPEOF(cpi) != LGLSXP)
212 error(
_(
"'%s' failed in '%s': %s"),
213 "checkpi", __func__, CHAR(STRING_ELT(cpi, 0)));
214 int *pp = INTEGER(p), *pi = INTEGER(i), sorted = LOGICAL(cpi)[0];
215 size_t np = (size_t) XLENGTH(p), ni = (size_t) XLENGTH(i);
216 if (!sorted && !sortInPlace) {
218 tmp = (
int *) R_alloc(np,
sizeof(
int));
219 memcpy(tmp, pp, np *
sizeof(
int));
221 tmp = (
int *) R_alloc(ni,
sizeof(
int));
222 memcpy(tmp, pi, ni *
sizeof(
int));
232 A->itype = CHOLMOD_INT;
233 A->xtype = CHOLMOD_PATTERN;
234 A->dtype = CHOLMOD_DOUBLE;
235 A->sorted = LOGICAL(cpi)[0];
240 int *tmp = (
int *) R_alloc(n,
sizeof(
int));
241 for (
int j = 0; j < n; ++j)
242 tmp[j] = pp[j + 1] - pp[j];
245 if (
class[1] ==
's') {
247 char ul = *CHAR(STRING_ELT(uplo, 0));
248 A->stype = (ul ==
'U') ? 1 : -1;
250 if (
class[0] !=
'n') {
252 size_t nx = (size_t) XLENGTH(x);
257 int *px = (TYPEOF(x) == LGLSXP) ? LOGICAL(x) : INTEGER(x);
258 double *rtmp = (
double *) R_alloc(nx,
sizeof(
double));
259 for (
size_t ix = 0; ix < nx; ++ix)
260 rtmp[ix] = (px[ix] == NA_INTEGER)
261 ? NA_REAL : (double) px[ix];
263 A->xtype = CHOLMOD_REAL;
268 double *px = REAL(x);
269 if (!sorted && !sortInPlace) {
270 double *rtmp = (
double *) R_alloc(nx,
sizeof(
double));
271 memcpy(rtmp, px, nx *
sizeof(
double));
275 A->xtype = CHOLMOD_REAL;
280 Rcomplex *px = COMPLEX(x);
281 if (!sorted && !sortInPlace) {
282 Rcomplex *rtmp = (Rcomplex *) R_alloc(nx,
sizeof(Rcomplex));
283 memcpy(rtmp, px, nx *
sizeof(Rcomplex));
287 A->xtype = CHOLMOD_COMPLEX;
295 if (!sorted && !cholmod_sort(A, &
c))
296 error(
_(
"'%s' failed in '%s'"),
"cholmod_sort", __func__);
297 if (checkUnit &&
class[1] ==
't' && n > 0) {
299 char di = *CHAR(STRING_ELT(diag, 0));
301 double one[] = { 1.0, 0.0 };
303 *eye = cholmod_speye(n, n, A->xtype, &
c),
304 *A1a = cholmod_add(A, eye, one, one, 1, 1, &
c);
305 memcpy(A, A1a,
sizeof(cholmod_sparse));
306 A->p = (
int *) R_alloc(A1a->ncol + 1,
sizeof(
int));
307 memcpy(A->p, A1a->p, (A1a->ncol + 1) *
sizeof(
int));
308 A->i = (
int *) R_alloc(A1a->nzmax,
sizeof(
int));
309 memcpy(A->i, A1a->i, A1a->nzmax *
sizeof(
int));
310 if (A1a->xtype != CHOLMOD_PATTERN) {
311 size_t size = (A1a->xtype == CHOLMOD_REAL)
312 ?
sizeof(
double) :
sizeof(Rcomplex);
313 A->x = R_alloc(A1a->nzmax, size);
314 memcpy(A->x, A1a->x, A1a->nzmax * size);
316 cholmod_free_sparse(&eye, &
c);
317 cholmod_free_sparse(&A1a, &
c);
343 static const char *
valid[] = {
344 "dgTMatrix",
"dsTMatrix",
"dtTMatrix",
345 "lgTMatrix",
"lsTMatrix",
"ltTMatrix",
346 "ngTMatrix",
"nsTMatrix",
"ntTMatrix",
"" };
347 int ivalid = R_check_class_etc(from,
valid);
350 const char *
class =
valid[ivalid];
351 memset(A, 0,
sizeof(cholmod_triplet));
354 int *pdim = INTEGER(dim), m = pdim[0], n = pdim[1];
358 int *pi = INTEGER(i), *pj = INTEGER(j);
359 size_t nnz0 = (size_t) XLENGTH(i), nnz1 = nnz0;
361 if (checkUnit &&
class[1] ==
't') {
363 char di = *CHAR(STRING_ELT(diag, 0));
370 tmp = (
int *) R_alloc(nnz1,
sizeof(
int));
371 memcpy(tmp, pi, nnz1 *
sizeof(
int));
373 tmp = (
int *) R_alloc(nnz1,
sizeof(
int));
374 memcpy(tmp, pj, nnz1 *
sizeof(
int));
377 pi += nnz0; pj += nnz0;
378 for (
int d = 0; d < n; ++d)
379 *(pi++) = *(pj++) = d;
380 pi -= nnz1; pj -= nnz1;
390 A->itype = CHOLMOD_INT;
391 A->xtype = CHOLMOD_PATTERN;
392 A->dtype = CHOLMOD_DOUBLE;
394 if (
class[1] ==
's') {
396 char ul = *CHAR(STRING_ELT(uplo, 0));
397 A->stype = (ul ==
'U') ? 1 : -1;
399 if (
class[0] !=
'n') {
405 int *px = (TYPEOF(x) == LGLSXP) ? LOGICAL(x) : INTEGER(x);
406 double *rtmp = (
double *) R_alloc(nnz1,
sizeof(
double));
407 for (
size_t k = 0; k < nnz0; ++k)
408 rtmp[k] = (px[k] == NA_INTEGER)
409 ? NA_REAL : (double) px[k];
410 for (
size_t k = nnz0; k < nnz1; ++k)
413 A->xtype = CHOLMOD_REAL;
418 double *px = REAL(x);
420 double *rtmp = (
double *) R_alloc(nnz1,
sizeof(
double));
421 memcpy(rtmp, px, nnz0 *
sizeof(
double));
422 for (
size_t k = nnz0; k < nnz1; ++k)
427 A->xtype = CHOLMOD_REAL;
432 Rcomplex *px = COMPLEX(x);
434 Rcomplex *rtmp = (Rcomplex *) R_alloc(nnz1,
sizeof(Rcomplex));
435 memcpy(rtmp, px, nnz0 *
sizeof(Rcomplex));
436 for (
size_t k = nnz0; k < nnz1; ++k)
441 A->xtype = CHOLMOD_COMPLEX;
472 static const char *
valid[] = {
473 "dgeMatrix",
"lgeMatrix",
"ngeMatrix",
"" };
474 int ivalid = R_check_class_etc(from,
valid);
475 memset(A, 0,
sizeof(cholmod_dense));
479 switch (TYPEOF(from)) {
489 SEXP dim = getAttrib(from, R_DimSymbol);
490 if (TYPEOF(dim) == INTSXP && LENGTH(dim) == 2) {
506 A->nzmax = A->nrow * A->ncol;
508 A->dtype = CHOLMOD_DOUBLE;
510 size_t nx = (size_t) XLENGTH(from);
511 switch (TYPEOF(from)) {
515 int *px = (TYPEOF(from) == LGLSXP) ? LOGICAL(from) : INTEGER(from),
516 pattern = ivalid == 2;
517 double *rtmp = (
double *) R_alloc(nx + 1,
sizeof(
double));
518 for (
size_t ix = 0; ix < nx; ++ix)
519 rtmp[ix] = (px[ix] == NA_INTEGER)
520 ? ((pattern) ? 1.0 : NA_REAL) : (double) px[ix];
522 A->xtype = CHOLMOD_REAL;
527 A->xtype = CHOLMOD_REAL;
530 A->x = COMPLEX(from);
531 A->xtype = CHOLMOD_COMPLEX;
587#define FREE_THEN(_EXPR_) \
592 else if (L->itype == CHOLMOD_INT) \
593 cholmod_free_factor(&L, &c); \
595 cholmod_l_free_factor(&L, &cl); \
600 if (L->itype != CHOLMOD_INT)
602 if (L->xtype != CHOLMOD_PATTERN &&
603 L->xtype != CHOLMOD_REAL && L->xtype != CHOLMOD_COMPLEX)
605 if (L->dtype != CHOLMOD_DOUBLE)
608 FREE_THEN(error(
_(
"dimensions cannot exceed %s"),
"2^31-1"));
610 if (L->maxcsize > INT_MAX)
611 FREE_THEN(error(
_(
"'%s' would overflow type \"%s\""),
612 "maxcsize",
"integer"));
615 FREE_THEN(error(
_(
"n+1 would overflow type \"%s\""),
618 if (L->minor < L->n) {
620 FREE_THEN(error(
_(
"leading principal minor of order %d is not positive"),
621 (
int) L->minor + 1));
623 FREE_THEN(error(
_(
"leading principal minor of order %d is zero"),
624 (
int) L->minor + 1));
626 char class[] =
".CHM.....";
627 class[0] = (L->xtype == CHOLMOD_PATTERN)
628 ?
'n' : ((L->xtype == CHOLMOD_COMPLEX) ?
'z' :
'd');
629 memcpy(
class + 4, (L->is_super) ?
"super" :
"simpl", 5);
632 INTEGER(dim)[0] = INTEGER(dim)[1] = (int) L->n;
633 if (L->ordering != CHOLMOD_NATURAL) {
634 SEXP perm = PROTECT(allocVector(INTSXP, L->n));
635 memcpy(INTEGER(perm), L->Perm, L->n *
sizeof(
int));
639 SEXP type = PROTECT(allocVector(INTSXP, 6)),
640 colcount = PROTECT(allocVector(INTSXP, L->n));
641 INTEGER(type)[0] = L->ordering;
642 INTEGER(type)[1] = (L->is_super) ? 1 : L->is_ll;
643 INTEGER(type)[2] = (L->is_super) ? 1 : 0;
644 INTEGER(type)[3] = (L->is_super) ? 1 : L->is_monotonic;
645 INTEGER(type)[4] = (L->is_super) ? (
int) L->maxcsize : 0;
646 INTEGER(type)[5] = (L->is_super) ? (
int) L->maxesize : 0;
647 memcpy(INTEGER(colcount), L->ColCount, L->n *
sizeof(
int));
648 SET_SLOT(to, install(
"type"), type);
649 SET_SLOT(to, install(
"colcount"), colcount);
651 SEXP super = PROTECT(allocVector(INTSXP, L->nsuper + 1)),
652 pi = PROTECT(allocVector(INTSXP, L->nsuper + 1)),
653 px = PROTECT(allocVector(INTSXP, L->nsuper + 1)),
654 s = PROTECT(allocVector(INTSXP, L->ssize));
655 memcpy(INTEGER(super), L->super, (L->nsuper + 1) *
sizeof(
int));
656 memcpy(INTEGER(pi), L->pi, (L->nsuper + 1) *
sizeof(
int));
657 memcpy(INTEGER(px), L->px, (L->nsuper + 1) *
sizeof(
int));
658 memcpy(INTEGER(s), L->s, L->ssize *
sizeof(
int));
659 SET_SLOT(to, install(
"super"), super);
664 }
else if (L->xtype != CHOLMOD_PATTERN) {
665 SEXP p = PROTECT(allocVector(INTSXP, L->n + 1)),
666 i = PROTECT(allocVector(INTSXP, L->nzmax)),
667 nz = PROTECT(allocVector(INTSXP, L->n)),
668 nxt = PROTECT(allocVector(INTSXP, L->n + 2)),
669 prv = PROTECT(allocVector(INTSXP, L->n + 2));
670 memcpy(INTEGER(p), L->p, (L->n + 1) *
sizeof(
int));
671 memcpy(INTEGER(i), L->i, L->nzmax *
sizeof(
int));
672 memcpy(INTEGER(nz), L->nz, L->n *
sizeof(
int));
673 memcpy(INTEGER(nxt), L->next, (L->n + 2) *
sizeof(
int));
674 memcpy(INTEGER(prv), L->prev, (L->n + 2) *
sizeof(
int));
682 if (L->xtype != CHOLMOD_PATTERN) {
684 R_xlen_t nx = (R_xlen_t) ((L->is_super) ? L->xsize : L->nzmax);
685 if (L->xtype == CHOLMOD_COMPLEX) {
686 PROTECT(x = allocVector(CPLXSXP, nx));
687 memcpy(COMPLEX(x), L->x, (
size_t) nx *
sizeof(Rcomplex));
689 PROTECT(x = allocVector(REALSXP, nx));
690 memcpy(REAL(x), L->x, (
size_t) nx *
sizeof(
double));
733 int ttype,
int doLogic,
const char *diagString,
737#define FREE_THEN(_EXPR_) \
742 else if (A_->itype == CHOLMOD_INT) \
743 cholmod_free_sparse(&A_, &c); \
745 cholmod_l_free_sparse(&A_, &cl); \
750 cholmod_sparse *A_ = A;
751 if (A->itype != CHOLMOD_INT)
753 if (A->xtype != CHOLMOD_PATTERN &&
754 A->xtype != CHOLMOD_REAL && A->xtype != CHOLMOD_COMPLEX)
756 if (A->dtype != CHOLMOD_DOUBLE)
758 if (A->nrow > INT_MAX || A->ncol > INT_MAX)
759 FREE_THEN(error(
_(
"dimensions cannot exceed %s"),
"2^31-1"));
762 if (!A->packed || A->stype != 0)
763 A = cholmod_copy(A, A->stype, 1, &
c);
764 int m = (int) A->nrow, n = (
int) A->ncol, nnz = ((
int *) A->p)[A->ncol];
765 R_xlen_t n1a = (R_xlen_t) n + 1;
766 char class[] =
"..CMatrix";
767 class[0] = (A->xtype == CHOLMOD_PATTERN)
768 ?
'n' : ((A->xtype == CHOLMOD_COMPLEX) ?
'z' : ((doLogic) ?
'l' :
'd'));
769 class[1] = (ttype != 0) ?
't' : ((A->stype != 0) ?
's' :
'g');
772 p = PROTECT(allocVector(INTSXP, n1a)),
773 i = PROTECT(allocVector(INTSXP, nnz));
776 memcpy(INTEGER(p), A->p, (
size_t) n1a *
sizeof(
int));
777 memcpy(INTEGER(i), A->i, (
size_t) nnz *
sizeof(
int));
780 if (A->xtype != CHOLMOD_PATTERN) {
782 if (A->xtype == CHOLMOD_COMPLEX) {
783 PROTECT(x = allocVector(CPLXSXP, nnz));
784 memcpy(COMPLEX(x), A->x, (
size_t) nnz *
sizeof(Rcomplex));
785 }
else if (!doLogic) {
786 PROTECT(x = allocVector(REALSXP, nnz));
787 memcpy(REAL(x), A->x, (
size_t) nnz *
sizeof(
double));
789 PROTECT(x = allocVector(LGLSXP, nnz));
790 int *px = LOGICAL(x);
791 double *py = (
double *) A->x;
792 for (
int k = 0; k < nnz; ++k)
793 px[k] = (ISNAN(py[k])) ? NA_LOGICAL : (py[k] != 0.0);
798 if (ttype < 0 || A->stype < 0) {
799 SEXP uplo = PROTECT(mkString(
"L"));
803 if (ttype != 0 && diagString && diagString[0] !=
'N') {
804 SEXP diag = PROTECT(mkString(
"U"));
808 if (TYPEOF(dimnames) == VECSXP && LENGTH(dimnames) == 2)
812 cholmod_free_sparse(&A, &
c);
849 int ttype,
int doLogic,
const char *diagString,
853#define FREE_THEN(_EXPR_) \
858 else if (A->itype == CHOLMOD_INT) \
859 cholmod_free_triplet(&A, &c); \
861 cholmod_l_free_triplet(&A, &cl); \
866 if (A->itype != CHOLMOD_INT)
868 if (A->xtype != CHOLMOD_PATTERN &&
869 A->xtype != CHOLMOD_REAL && A->xtype != CHOLMOD_COMPLEX)
871 if (A->dtype != CHOLMOD_DOUBLE)
873 if (A->nrow > INT_MAX || A->ncol > INT_MAX)
874 FREE_THEN(error(
_(
"dimensions cannot exceed %s"),
"2^31-1"));
875 int m = (int) A->nrow, n = (
int) A->ncol;
876 R_xlen_t nnz = (R_xlen_t) A->nnz;
877 char class[] =
"..TMatrix";
878 class[0] = (A->xtype == CHOLMOD_PATTERN)
879 ?
'n' : ((A->xtype == CHOLMOD_COMPLEX) ?
'z' : ((doLogic) ?
'l' :
'd'));
880 class[1] = (ttype != 0) ?
't' : ((A->stype != 0) ?
's' :
'g');
883 i = PROTECT(allocVector(INTSXP, nnz)),
884 j = PROTECT(allocVector(INTSXP, nnz));
887 memcpy(INTEGER(i), A->i, (
size_t) nnz *
sizeof(
int));
888 memcpy(INTEGER(j), A->j, (
size_t) nnz *
sizeof(
int));
890 int tmp, *pi = INTEGER(i), *pj = INTEGER(j);
891 for (R_xlen_t k = 0; k < nnz; ++k) {
899 if (A->xtype != CHOLMOD_PATTERN) {
901 if (A->xtype == CHOLMOD_COMPLEX) {
902 PROTECT(x = allocVector(CPLXSXP, nnz));
903 memcpy(COMPLEX(x), A->x, (
size_t) nnz *
sizeof(Rcomplex));
904 }
else if (!doLogic) {
905 PROTECT(x = allocVector(REALSXP, nnz));
906 memcpy(REAL(x), A->x, (
size_t) nnz *
sizeof(
double));
908 PROTECT(x = allocVector(LGLSXP, nnz));
909 int *px = LOGICAL(x);
910 double *py = (
double *) A->x;
911 for (R_xlen_t k = 0; k < nnz; ++k)
912 px[k] = (ISNAN(py[k])) ? NA_LOGICAL : (py[k] != 0.0);
917 if (ttype < 0 || A->stype < 0) {
918 SEXP uplo = PROTECT(mkString(
"L"));
922 if (ttype != 0 && diagString && diagString[0] !=
'N') {
923 SEXP diag = PROTECT(mkString(
"U"));
927 if (TYPEOF(dimnames) == VECSXP && LENGTH(dimnames) == 2)