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));
30 L->ordering = INTEGER(ordering)[0];
31 L->is_super =
class[2] ==
'u';
32 L->n = (size_t) INTEGER(dim)[0];
34 if (L->ordering != CHOLMOD_NATURAL)
35 L->Perm = INTEGER(perm);
40 int n = (int) L->n, *Perm = (
int *) R_alloc(L->n,
sizeof(
int));
41 for (
int j = 0; j < n; ++j)
45 L->ColCount = INTEGER(colcount);
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);
66 if (
class[0] !=
'n') {
74 L->nzmax = (size_t) INTEGER(p)[L->n];
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;
85 L->itype = CHOLMOD_INT;
86 L->xtype = CHOLMOD_PATTERN;
87 L->dtype = CHOLMOD_DOUBLE;
88 if (
class[0] !=
'n') {
90 L->minor = (size_t) INTEGER(minor)[0];
95 L->xtype = CHOLMOD_REAL;
99 L->xtype = CHOLMOD_COMPLEX;
128 Rboolean
allocUnit, Rboolean sortInPlace)
131 SEXP
checkpi(SEXP dim, SEXP p, SEXP i);
134 memset(A, 0,
sizeof(cholmod_sparse));
135 int mg = (
class[2] ==
'C') ? 1 : 0;
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];
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;
150 if (
class[1] ==
's') {
152 A->stype = ((CHAR(STRING_ELT(uplo, 0))[0] ==
'U') == (mg == 1)) ? 1 : -1;
154 if (!A->sorted && !sortInPlace) {
157 A->p = (
void *) R_alloc(A->ncol + 1,
sizeof(
int));
158 memcpy(A->p, tmp,
sizeof(
int) * (A->ncol + 1));
160 A->i = (
void *) R_alloc(A->nzmax,
sizeof(
int));
161 memcpy(A->i, tmp,
sizeof(
int) * A->nzmax);
163 if (
class[0] !=
'n') {
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];
174 A->xtype = CHOLMOD_REAL;
179 A->xtype = CHOLMOD_REAL;
180 if (!A->sorted && !sortInPlace) {
182 A->x = (
void *) R_alloc(A->nzmax,
sizeof(
double));
183 memcpy(A->x, tmp,
sizeof(
double) * A->nzmax);
188 A->xtype = CHOLMOD_COMPLEX;
189 if (!A->sorted && !sortInPlace) {
191 A->x = (
void *) R_alloc(A->nzmax,
sizeof(Rcomplex));
192 memcpy(A->x, tmp,
sizeof(Rcomplex) * A->nzmax);
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) {
204 char nu = CHAR(STRING_ELT(diag, 0))[0];
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);
220 A->x = (
void *) R_alloc(A->nzmax,
sizeof(Rcomplex));
221 memcpy(A->x, A1->x,
sizeof(
double) * A->nzmax);
224 cholmod_free_sparse(&I1, &
c);
225 cholmod_free_sparse(&A1, &
c);
251 memset(A, 0,
sizeof(cholmod_triplet));
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);
261 A->itype = CHOLMOD_INT;
262 A->xtype = CHOLMOD_PATTERN;
263 A->dtype = CHOLMOD_DOUBLE;
264 if (
class[1] ==
's') {
266 A->stype = (CHAR(STRING_ELT(uplo, 0))[0] ==
'U') ? 1 : -1;
268 if (
class[0] !=
'n') {
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];
279 A->xtype = CHOLMOD_REAL;
284 A->xtype = CHOLMOD_REAL;
288 A->xtype = CHOLMOD_COMPLEX;
295 if (
class[1] ==
't' && A->ncol > 0 &&
allocUnit) {
297 char nu = CHAR(STRING_ELT(diag, 0))[0];
302 A->i = (
void *) R_alloc(A->nzmax,
sizeof(
int));
303 memcpy(A->i, tmp,
sizeof(
int) * A->nnz);
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) {
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);
313 A->x = (
void *) R_alloc(A->nzmax,
sizeof(Rcomplex));
314 memcpy(A->x, tmp,
sizeof(Rcomplex) * A->nnz);
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)
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)
328 Rcomplex *Ax = ((Rcomplex *) A->x) + A->nnz;
329 for (
int j = 0; j < n; ++j)
358 static const char *valid[] = {
359 "ngeMatrix",
"lgeMatrix",
"igeMatrix",
"dgeMatrix",
"zgeMatrix",
"" };
378 SEXP dim = Rf_getAttrib(from, R_DimSymbol);
379 if (
TYPEOF(dim) == INTSXP && LENGTH(dim) == 2) {
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;
393 A->dtype = CHOLMOD_DOUBLE;
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];
405 A->xtype = CHOLMOD_REAL;
410 A->xtype = CHOLMOD_REAL;
413 A->x = COMPLEX(from);
414 A->xtype = CHOLMOD_COMPLEX;
469#define errorFree(...) \
472 Rf_error(__VA_ARGS__); \
480 else if (L->itype == CHOLMOD_INT) \
481 cholmod_free_factor(&L, &c); \
483 cholmod_l_free_factor(&L, &cl); \
487 if (L->itype != CHOLMOD_INT)
489 if (L->xtype != CHOLMOD_PATTERN &&
490 L->xtype != CHOLMOD_REAL && L->xtype != CHOLMOD_COMPLEX)
492 if (L->dtype != CHOLMOD_DOUBLE)
495 errorFree(
_(
"dimensions cannot exceed %s"),
"2^31-1");
497 if (L->maxcsize > INT_MAX)
498 errorFree(
_(
"'%s' would overflow type \"%s\""),
499 "maxcsize",
"integer");
502 errorFree(
_(
"n+1 would overflow type \"%s\""),
505 if (L->minor < L->n) {
507 errorFree(
_(
"leading principal minor of order %d is not positive"),
510 errorFree(
_(
"leading principal minor of order %d is zero"),
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);
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);
528 SEXP colcount = PROTECT(Rf_allocVector(INTSXP, (R_xlen_t) L->n));
529 memcpy(INTEGER(colcount), L->ColCount,
sizeof(
int) * L->n);
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);
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))),
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;
574 if (L->xtype != CHOLMOD_PATTERN) {
576 INTEGER(minor)[0] = (int) L->minor;
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);
583 PROTECT(x = Rf_allocVector(CPLXSXP, (R_xlen_t) nnz));
584 memcpy(COMPLEX(x), L->x,
sizeof(Rcomplex) * nnz);
626 int ttype,
int doLogic,
const char *diagString,
635 else if (A_->itype == CHOLMOD_INT) \
636 cholmod_free_sparse(&A_, &c); \
638 cholmod_l_free_sparse(&A_, &cl); \
642 cholmod_sparse *A_ = A;
643 if (A->itype != CHOLMOD_INT)
645 if (A->xtype != CHOLMOD_PATTERN &&
646 A->xtype != CHOLMOD_REAL && A->xtype != CHOLMOD_COMPLEX)
648 if (A->dtype != CHOLMOD_DOUBLE)
650 if (A->nrow > INT_MAX || A->ncol > INT_MAX)
651 errorFree(
_(
"dimensions cannot exceed %s"),
"2^31-1");
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];
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);
671 if (A->xtype != CHOLMOD_PATTERN) {
673 if (A->xtype == CHOLMOD_REAL) {
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);
681 PROTECT(x = Rf_allocVector(REALSXP, nnz));
682 memcpy(REAL(x), A->x,
sizeof(
double) * (
size_t) nnz);
685 PROTECT(x = Rf_allocVector(CPLXSXP, nnz));
686 memcpy(COMPLEX(x), A->x,
sizeof(Rcomplex) * (
size_t) nnz);
691 if (ttype < 0 || A->stype < 0) {
692 SEXP uplo = PROTECT(Rf_mkString(
"L"));
696 if (ttype != 0 && diagString && diagString[0] !=
'N') {
697 SEXP diag = PROTECT(Rf_mkString(
"U"));
701 if (
TYPEOF(dimnames) == VECSXP && XLENGTH(dimnames) == 2)
704 cholmod_free_sparse(&A, &
c);
741 int ttype,
int doLogic,
const char *diagString,
750 else if (A->itype == CHOLMOD_INT) \
751 cholmod_free_triplet(&A, &c); \
753 cholmod_l_free_triplet(&A, &cl); \
757 if (A->itype != CHOLMOD_INT)
759 if (A->xtype != CHOLMOD_PATTERN &&
760 A->xtype != CHOLMOD_REAL && A->xtype != CHOLMOD_COMPLEX)
762 if (A->dtype != CHOLMOD_DOUBLE)
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');
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;
777 memcpy(INTEGER(i), A->i,
sizeof(
int) * A->nnz);
778 memcpy(INTEGER(j), A->j,
sizeof(
int) * A->nnz);
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)) {
794 if (A->xtype != CHOLMOD_PATTERN) {
796 if (A->xtype == CHOLMOD_REAL) {
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);
804 PROTECT(x = Rf_allocVector(REALSXP, (R_xlen_t) A->nnz));
805 memcpy(REAL(x), A->x,
sizeof(
double) * A->nnz);
808 PROTECT(x = Rf_allocVector(CPLXSXP, (R_xlen_t) A->nnz));
809 memcpy(COMPLEX(x), A->x,
sizeof(Rcomplex) * A->nnz);
814 if (ttype < 0 || A->stype < 0) {
815 SEXP uplo = PROTECT(Rf_mkString(
"L"));
819 if (ttype != 0 && diagString && diagString[0] !=
'N') {
820 SEXP diag = PROTECT(Rf_mkString(
"U"));
824 if (
TYPEOF(dimnames) == VECSXP && XLENGTH(dimnames) == 2)
860 cholmod_free_dense(&A, &c); \
864 if (A->xtype != CHOLMOD_REAL && A->xtype != CHOLMOD_COMPLEX)
866 if (A->dtype != CHOLMOD_DOUBLE)
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"),
875 char class[] =
".geMatrix";
876 class[0] = (A->xtype == CHOLMOD_COMPLEX) ?
'z' :
'd';
879 INTEGER(dim)[0] = (int) A->nrow;
880 INTEGER(dim)[1] = (int) A->ncol;
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));
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));
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]));
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++)
931 Rf_error(
_(
"invalid simplicial Cholesky factorization: structural zero on main diagonal in column %d"),
935 ans += log(lx[p] * ((L->is_ll) ? lx[p] : 1.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__);
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.
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.