Matrix r5059
Loading...
Searching...
No Matches
cholmod-etc.c
Go to the documentation of this file.
1#include "Mdefines.h"
2#include "idz.h"
3#include "cholmod-etc.h"
4
5cholmod_common c ;
6cholmod_common cl;
7
8static
9void Matrix_cholmod_error_handler(int status, const char *file, int line,
10 const char *message)
11{
12 cholmod_defaults(&c);
13 if (status < 0)
14 Rf_error(_("CHOLMOD error '%s' at file '%s', line %d"),
15 message, file, line);
16 else
17 Rf_warning(_("CHOLMOD warning '%s' at file '%s', line %d"),
18 message, file, line);
19 return;
20}
21
22int Matrix_cholmod_start(cholmod_common *Common)
23{
24 int ans = cholmod_start(Common);
25 if (!ans)
26 Rf_error(_("'%s' failed in '%s'"), "cholmod_start", __func__);
27 Common->error_handler = Matrix_cholmod_error_handler;
28 return ans;
29}
30
31int Matrix_cholmod_finish(cholmod_common *Common)
32{
33 int ans = cholmod_finish(Common);
34 if (!ans)
35 Rf_error(_("'%s' failed in '%s'"), "cholmod_finish", __func__);
36 return ans;
37}
38
39cholmod_factor *M2CHF(SEXP obj, int values)
40{
41 static const char *valid[] = {
42 "nsimplicialCholesky", "nsupernodalCholesky",
43 "dsimplicialCholesky", "dsupernodalCholesky",
44 "zsimplicialCholesky", "zsupernodalCholesky", "" };
45 const char *class = Matrix_class(obj, valid, -1, __func__);
46 cholmod_factor *L = (cholmod_factor *) R_alloc(1, sizeof(cholmod_factor));
47 memset(L, 0, sizeof(cholmod_factor));
48 values = values && (class[0] == 'd' || class[0] == 'z');
49 SEXP dim = PROTECT(GET_SLOT(obj, Matrix_DimSym)),
50 perm = PROTECT(GET_SLOT(obj, Matrix_permSym)),
51 colcount = PROTECT(GET_SLOT(obj, Matrix_colcountSym)),
52 ordering = PROTECT(GET_SLOT(obj, Matrix_orderingSym));
53 L->ordering = INTEGER(ordering)[0];
54 L->is_super = class[2] == 'u';
55 L->n = (size_t) INTEGER(dim)[0];
56 L->minor = L->n;
57 if (L->ordering != CHOLMOD_NATURAL)
58 L->Perm = INTEGER(perm);
59 else {
60 /* cholmod_check_factor allows L->Perm == NULL,
61 but cholmod_copy_factor does not test, so it segfaults ...
62 */
63 int n = (int) L->n, *Perm = (int *) R_alloc(L->n, sizeof(int));
64 for (int j = 0; j < n; ++j)
65 Perm[j] = j;
66 L->Perm = Perm;
67 }
68 L->ColCount = INTEGER(colcount);
69 if (L->is_super) {
70 SEXP maxcsize = PROTECT(GET_SLOT(obj, Matrix_maxcsizeSym)),
71 maxesize = PROTECT(GET_SLOT(obj, Matrix_maxesizeSym)),
72 super = PROTECT(GET_SLOT(obj, Matrix_superSym)),
73 pi = PROTECT(GET_SLOT(obj, Matrix_piSym)),
74 px = PROTECT(GET_SLOT(obj, Matrix_pxSym)),
75 s = PROTECT(GET_SLOT(obj, Matrix_sSym));
76 L->nsuper = (size_t) (LENGTH(super) - 1);
77 L->ssize = (size_t) INTEGER(pi)[L->nsuper];
78 L->xsize = (size_t) INTEGER(px)[L->nsuper];
79 L->maxcsize = (size_t) INTEGER(maxcsize)[0];
80 L->maxesize = (size_t) INTEGER(maxesize)[0];
81 L->super = INTEGER(super);
82 L->pi = INTEGER(pi);
83 L->px = INTEGER(px);
84 L->s = INTEGER(s);
85 L->is_ll = 1;
86 L->is_monotonic = 1;
87 UNPROTECT(6);
88 } else {
89 if (values) {
90 SEXP p = PROTECT(GET_SLOT(obj, Matrix_pSym)),
91 i = PROTECT(GET_SLOT(obj, Matrix_iSym)),
92 nz = PROTECT(GET_SLOT(obj, Matrix_nzSym)),
93 next = PROTECT(GET_SLOT(obj, Matrix_nextSym)),
94 prev = PROTECT(GET_SLOT(obj, Matrix_prevSym)),
95 is_ll = PROTECT(GET_SLOT(obj, Matrix_isllSym)),
96 is_monotonic = PROTECT(GET_SLOT(obj, Matrix_ismtSym));
97 L->nzmax = (size_t) INTEGER(p)[L->n];
98 L->p = INTEGER(p);
99 L->i = INTEGER(i);
100 L->nz = INTEGER(nz);
101 L->next = INTEGER(next);
102 L->prev = INTEGER(prev);
103 L->is_ll = LOGICAL(is_ll)[0] != 0;
104 L->is_monotonic = LOGICAL(is_monotonic)[0] != 0;
105 UNPROTECT(7);
106 }
107 }
108 L->itype = CHOLMOD_INT;
109 L->xtype = CHOLMOD_PATTERN;
110 L->dtype = CHOLMOD_DOUBLE;
111 if (values) {
112 SEXP minor = GET_SLOT(obj, Matrix_minorSym);
113 L->minor = (size_t) INTEGER(minor)[0];
114 SEXP x = GET_SLOT(obj, Matrix_xSym);
115 switch (class[0]) {
116 case 'd':
117 L->x = REAL(x);
118 L->xtype = CHOLMOD_REAL;
119 break;
120 case 'z':
121 L->x = COMPLEX(x);
122 L->xtype = CHOLMOD_COMPLEX;
123 break;
124 default:
125 break;
126 }
127 }
128 UNPROTECT(4);
129 return L;
130}
131
132cholmod_sparse *M2CHS(SEXP obj, int values)
133{
134 const char *class = Matrix_class(obj, valid_sparse_compressed, 6, __func__);
135 cholmod_sparse *A = (cholmod_sparse *) R_alloc(1, sizeof(cholmod_sparse));
136 memset(A, 0, sizeof(cholmod_sparse));
137 values = values && (class[0] == 'd' || class[0] == 'z');
138 int mg = (class[2] == 'C') ? 1 : 0;
139 SEXP dim = PROTECT(GET_SLOT(obj, Matrix_DimSym)),
140 p = PROTECT(GET_SLOT(obj, Matrix_pSym)),
141 i = PROTECT(GET_SLOT(obj, (mg == 1) ? Matrix_iSym : Matrix_jSym));
142 A->nrow = (size_t) INTEGER(dim)[(mg == 1) ? 0 : 1];
143 A->ncol = (size_t) INTEGER(dim)[(mg == 1) ? 1 : 0];
144 A->nzmax = (size_t) INTEGER(p)[A->ncol];
145 A->p = INTEGER(p);
146 A->i = INTEGER(i);
147 A->stype = 0;
148 A->itype = CHOLMOD_INT;
149 A->xtype = CHOLMOD_PATTERN;
150 A->dtype = CHOLMOD_DOUBLE;
151 A->sorted = 1;
152 A->packed = 1;
153 if (class[1] == 's') {
154 SEXP uplo = GET_SLOT(obj, Matrix_uploSym);
155 A->stype = ((*CHAR(STRING_ELT(uplo, 0)) == 'U') == (mg == 1)) ? 1 : -1;
156 }
157 if (values) {
158 SEXP x = GET_SLOT(obj, Matrix_xSym);
159 switch (class[0]) {
160 case 'd':
161 A->x = REAL(x);
162 A->xtype = CHOLMOD_REAL;
163 break;
164 case 'z':
165 A->x = COMPLEX(x);
166 A->xtype = CHOLMOD_COMPLEX;
167 break;
168 default:
169 break;
170 }
171 }
172 UNPROTECT(3);
173 return A;
174}
175
176cholmod_dense *M2CHD(SEXP obj, char trans)
177{
178 static const char *valid[] = { "dgeMatrix", "zgeMatrix", "" };
179 const char *class = Matrix_class(obj, valid, 0, __func__);
180 cholmod_dense *A = (cholmod_dense *) R_alloc(1, sizeof(cholmod_dense));
181 memset(A, 0, sizeof(cholmod_dense));
182 SEXP dim = PROTECT(GET_SLOT(obj, Matrix_DimSym)),
183 x = PROTECT(GET_SLOT(obj, Matrix_xSym));
184 size_t m = (size_t) INTEGER(dim)[0], n = (size_t) INTEGER(dim)[1];
185 A->nrow = ((trans == 'N') ? m : n);
186 A->ncol = ((trans == 'N') ? n : m);
187 A->nzmax = A->nrow * A->ncol;
188 A->d = A->nrow;
189 A->dtype = CHOLMOD_DOUBLE;
190 switch (class[0]) {
191 case 'd':
192 {
193 double *px = REAL(x);
194 if (trans != 'N') {
195 double *py = (double *) R_alloc(A->nzmax, sizeof(double));
196 dtrans2(py, px, m, n, trans);
197 px = py;
198 }
199 A->x = px;
200 A->xtype = CHOLMOD_REAL;
201 break;
202 }
203 case 'z':
204 {
205 Rcomplex *px = COMPLEX(x);
206 if (trans != 'N') {
207 Rcomplex *py = (Rcomplex *) R_alloc(A->nzmax, sizeof(Rcomplex));
208 ztrans2(py, px, m, n, trans);
209 px = py;
210 }
211 A->x = px;
212 A->xtype = CHOLMOD_COMPLEX;
213 break;
214 }
215 default:
216 break;
217 }
218 UNPROTECT(2);
219 return A;
220}
221
222SEXP CHF2M(cholmod_factor *L, int values)
223{
224 values = values &&
225 (L->xtype == CHOLMOD_REAL || L->xtype == CHOLMOD_COMPLEX);
226 if (L->itype != CHOLMOD_INT)
227 return errorChar(_("wrong '%s'"), "itype");
228 if (values && L->dtype != CHOLMOD_DOUBLE)
229 return errorChar(_("wrong '%s'"), "dtype");
230 if (L->n > INT_MAX)
231 return errorChar(_("dimensions cannot exceed %s"), "2^31-1");
232 if (L->super) {
233 if (L->maxcsize > INT_MAX)
234 return errorChar(_("'%s' would overflow type \"%s\""),
235 "maxcsize", "integer");
236 } else {
237 if (L->n == INT_MAX)
238 return errorChar(_("n+1 would overflow type \"%s\""),
239 "integer");
240 }
241 if (L->minor < L->n) {
242 if (L->is_ll)
243 return errorChar(_("leading principal minor of order %d is not positive"),
244 (int) L->minor + 1);
245 else
246 return errorChar(_("leading principal minor of order %d is zero"),
247 (int) L->minor + 1);
248 }
249 char class[] = "...........Cholesky";
250 class[0] = (!values) ? 'n' : ((L->xtype == CHOLMOD_REAL) ? 'd' : 'z');
251 memcpy(class + 1, (L->is_super) ? "supernodal" : "simplicial", 10);
252 SEXP obj = PROTECT(newObject(class)),
253 dim = PROTECT(GET_SLOT(obj, Matrix_DimSym)),
254 ordering = PROTECT(GET_SLOT(obj, Matrix_orderingSym));
255 INTEGER(ordering)[0] = L->ordering;
256 INTEGER(dim)[0] = INTEGER(dim)[1] = (int) L->n;
257 if (L->ordering != CHOLMOD_NATURAL) {
258 SEXP perm = PROTECT(Rf_allocVector(INTSXP, (R_xlen_t) L->n));
259 memcpy(INTEGER(perm), L->Perm, sizeof(int) * L->n);
260 SET_SLOT(obj, Matrix_permSym, perm);
261 UNPROTECT(1);
262 }
263 SEXP colcount = PROTECT(Rf_allocVector(INTSXP, (R_xlen_t) L->n));
264 memcpy(INTEGER(colcount), L->ColCount, sizeof(int) * L->n);
265 SET_SLOT(obj, Matrix_colcountSym, colcount);
266 UNPROTECT(1);
267 if (L->is_super) {
268 SEXP maxcsize = PROTECT(GET_SLOT(obj, Matrix_maxcsizeSym)),
269 maxesize = PROTECT(GET_SLOT(obj, Matrix_maxesizeSym)),
270 super = PROTECT(Rf_allocVector(INTSXP, (R_xlen_t) (L->nsuper + 1))),
271 pi = PROTECT(Rf_allocVector(INTSXP, (R_xlen_t) (L->nsuper + 1))),
272 px = PROTECT(Rf_allocVector(INTSXP, (R_xlen_t) (L->nsuper + 1))),
273 s = PROTECT(Rf_allocVector(INTSXP, (R_xlen_t) L->ssize));
274 INTEGER(maxcsize)[0] = (int) L->maxcsize;
275 INTEGER(maxesize)[0] = (int) L->maxesize;
276 memcpy(INTEGER(super), L->super, sizeof(int) * (L->nsuper + 1));
277 memcpy(INTEGER(pi), L->pi, sizeof(int) * (L->nsuper + 1));
278 memcpy(INTEGER(px), L->px, sizeof(int) * (L->nsuper + 1));
279 memcpy(INTEGER(s), L->s, sizeof(int) * L->ssize);
280 SET_SLOT(obj, Matrix_superSym, super);
281 SET_SLOT(obj, Matrix_piSym, pi);
282 SET_SLOT(obj, Matrix_pxSym, px);
283 SET_SLOT(obj, Matrix_sSym, s);
284 UNPROTECT(6);
285 } else {
286 if (values) {
287 SEXP p = PROTECT(Rf_allocVector(INTSXP, (R_xlen_t) (L->n + 1))),
288 i = PROTECT(Rf_allocVector(INTSXP, (R_xlen_t) L->nzmax)),
289 nz = PROTECT(Rf_allocVector(INTSXP, (R_xlen_t) L->n)),
290 next = PROTECT(Rf_allocVector(INTSXP, (R_xlen_t) (L->n + 2))),
291 prev = PROTECT(Rf_allocVector(INTSXP, (R_xlen_t) (L->n + 2))),
292 is_ll = PROTECT(GET_SLOT(obj, Matrix_isllSym)),
293 is_monotonic = PROTECT(GET_SLOT(obj, Matrix_ismtSym));
294 memcpy(INTEGER(p), L->p, sizeof(int) * (L->n + 1));
295 memcpy(INTEGER(i), L->i, sizeof(int) * L->nzmax);
296 memcpy(INTEGER(nz), L->nz, sizeof(int) * L->n);
297 memcpy(INTEGER(next), L->next, sizeof(int) * (L->n + 2));
298 memcpy(INTEGER(prev), L->prev, sizeof(int) * (L->n + 2));
299 LOGICAL(is_ll)[0] = L->is_ll != 0;
300 LOGICAL(is_monotonic)[0] = L->is_monotonic != 0;
301 SET_SLOT(obj, Matrix_pSym, p);
302 SET_SLOT(obj, Matrix_iSym, i);
303 SET_SLOT(obj, Matrix_nzSym, nz);
304 SET_SLOT(obj, Matrix_nextSym, next);
305 SET_SLOT(obj, Matrix_prevSym, prev);
306 UNPROTECT(7);
307 }
308 }
309 if (values) {
310 SEXP minor = GET_SLOT(obj, Matrix_minorSym);
311 INTEGER(minor)[0] = (int) L->minor;
312 SEXP x;
313 size_t nnz = (L->is_super) ? L->xsize : L->nzmax;
314 if (L->xtype == CHOLMOD_REAL) {
315 PROTECT(x = Rf_allocVector(REALSXP, (R_xlen_t) nnz));
316 memcpy(REAL(x), L->x, sizeof(double) * nnz);
317 } else {
318 PROTECT(x = Rf_allocVector(CPLXSXP, (R_xlen_t) nnz));
319 memcpy(COMPLEX(x), L->x, sizeof(Rcomplex) * nnz);
320 }
321 SET_SLOT(obj, Matrix_xSym, x);
322 UNPROTECT(1);
323 }
324 UNPROTECT(3);
325 return obj;
326}
327
328SEXP CHS2M(cholmod_sparse *A, int values, char shape)
329{
330 cholmod_sparse *A_ = A;
331 values = values &&
332 (A->xtype == CHOLMOD_REAL || A->xtype == CHOLMOD_COMPLEX);
333 if (A->itype != CHOLMOD_INT)
334 return errorChar(_("wrong '%s'"), "itype");
335 if (values && A->dtype != CHOLMOD_DOUBLE)
336 return errorChar(_("wrong '%s'"), "dtype");
337 if (A->nrow > INT_MAX || A->ncol > INT_MAX)
338 return errorChar(_("dimensions cannot exceed %s"), "2^31-1");
339 if (!A->sorted)
340 cholmod_sort(A, &c);
341 if (!A->packed || A->stype != 0)
342 A = cholmod_copy(A, A->stype, 2, &c);
343 char class[] = "..CMatrix";
344 class[0] = (!values) ? 'n' : ((A->xtype == CHOLMOD_REAL) ? 'd' : 'z');
345 class[1] = shape;
346 int nnz = ((int *) A->p)[A->ncol];
347 SEXP obj = PROTECT(newObject(class)),
348 dim = PROTECT(GET_SLOT(obj, Matrix_DimSym)),
349 p = PROTECT(Rf_allocVector(INTSXP, (R_xlen_t) (A->ncol + 1))),
350 i = PROTECT(Rf_allocVector(INTSXP, (R_xlen_t) nnz));
351 INTEGER(dim)[0] = (int) A->nrow;
352 INTEGER(dim)[1] = (int) A->ncol;
353 memcpy(INTEGER(p), A->p, sizeof(int) * (A->ncol + 1));
354 memcpy(INTEGER(i), A->i, sizeof(int) * (size_t) nnz);
355 SET_SLOT(obj, Matrix_pSym, p);
356 SET_SLOT(obj, Matrix_iSym, i);
357 if (values) {
358 SEXP x;
359 if (A->xtype == CHOLMOD_REAL) {
360 PROTECT(x = Rf_allocVector(REALSXP, nnz));
361 memcpy(REAL(x), A->x, sizeof(double) * (size_t) nnz);
362 } else {
363 PROTECT(x = Rf_allocVector(CPLXSXP, nnz));
364 memcpy(COMPLEX(x), A->x, sizeof(Rcomplex) * (size_t) nnz);
365 }
366 SET_SLOT(obj, Matrix_xSym, x);
367 UNPROTECT(1);
368 }
369 if (A != A_)
370 cholmod_free_sparse(&A, &c);
371 UNPROTECT(4);
372 return obj;
373}
374
375SEXP CHD2M(cholmod_dense *A, char trans, char shape)
376{
377 if (A->xtype != CHOLMOD_REAL && A->xtype != CHOLMOD_COMPLEX)
378 return errorChar(_("wrong '%s'"), "xtype");
379 if (A->dtype != CHOLMOD_DOUBLE)
380 return errorChar(_("wrong '%s'"), "dtype");
381 if (A->d != A->nrow) /* currently no need to support this case */
382 return errorChar(_("leading dimension not equal to number of rows"));
383 if (A->nrow > INT_MAX || A->ncol > INT_MAX)
384 return errorChar(_("dimensions cannot exceed %s"), "2^31-1");
385 size_t m = A->nrow, n = A->ncol;
386 if (m * n > R_XLEN_T_MAX)
387 return errorChar(_("attempt to allocate vector of length exceeding %s"),
388 "R_XLEN_T_MAX");
389 char class[] = "...Matrix";
390 class[0] = (A->xtype == CHOLMOD_REAL) ? 'd' : 'z';
391 class[1] = shape;
392 class[2] = (shape == 'g')
393 ? 'e' : ((shape == 's') ? 'y' : ((shape == 'p') ? 'o' : 'r'));
394 SEXP obj = PROTECT(newObject(class)),
395 dim = PROTECT(GET_SLOT(obj, Matrix_DimSym));
396 INTEGER(dim)[0] = (int) ((trans != 'N') ? n : m);
397 INTEGER(dim)[1] = (int) ((trans != 'N') ? m : n);
398 SEXP x;
399 if (A->xtype == CHOLMOD_REAL) {
400 PROTECT(x = Rf_allocVector(REALSXP, (R_xlen_t) (m * n)));
401 double *px = REAL(x), *py = (double *) A->x;
402 dtrans2(px, py, m, n, trans);
403 } else {
404 PROTECT(x = Rf_allocVector(CPLXSXP, (R_xlen_t) (m * n)));
405 Rcomplex *px = COMPLEX(x), *py = (Rcomplex *) A->x;
406 ztrans2(px, py, m, n, trans);
407 }
408 SET_SLOT(obj, Matrix_xSym, x);
409 UNPROTECT(3);
410 return obj;
411}
#define _(String)
Definition Mdefines.h:66
const char * Matrix_class(SEXP, const char **, int, const char *)
Definition objects.c:112
#define GET_SLOT(x, name)
Definition Mdefines.h:72
#define errorChar(...)
Definition Mdefines.h:68
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
static void Matrix_cholmod_error_handler(int status, const char *file, int line, const char *message)
Definition cholmod-etc.c:9
int Matrix_cholmod_start(cholmod_common *Common)
Definition cholmod-etc.c:22
cholmod_factor * M2CHF(SEXP obj, int values)
Definition cholmod-etc.c:39
int Matrix_cholmod_finish(cholmod_common *Common)
Definition cholmod-etc.c:31
cholmod_sparse * M2CHS(SEXP obj, int values)
SEXP CHF2M(cholmod_factor *L, int values)
cholmod_common c
Definition cholmod-etc.c:5
cholmod_common cl
Definition cholmod-etc.c:6
SEXP CHS2M(cholmod_sparse *A, int values, char shape)
cholmod_dense * M2CHD(SEXP obj, char trans)
SEXP CHD2M(cholmod_dense *A, char trans, char shape)
void ztrans2(Rcomplex *, const Rcomplex *, size_t, size_t, char)
void dtrans2(double *, const double *, size_t, size_t, char)
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
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_maxesizeSym
Definition init.c:616
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