Matrix r5059
Loading...
Searching...
No Matches
aggregate.c
Go to the documentation of this file.
1#include "Mdefines.h"
2#include "M5.h"
3#include "idz.h"
4
5SEXP sparse_aggregate(SEXP from, const char *class)
6{
7 if (class[2] != 'T')
8 return from;
9
10 SEXP i0 = GET_SLOT(from, Matrix_iSym);
11 if (XLENGTH(i0) < 2)
12 return from;
13 if (XLENGTH(i0) > INT_MAX)
14 Rf_error(_("number of triplets to be aggregated exceeds %s"),
15 "2^31-1");
16 PROTECT(i0);
17 SEXP j0 = PROTECT(GET_SLOT(from, Matrix_jSym)), i1, j1,
18 to = R_NilValue;
19 int *pi0 = INTEGER(i0), *pi1 = NULL,
20 *pj0 = INTEGER(j0), *pj1 = NULL,
21 *pdim = DIM(from), m = pdim[0], n = pdim[1],
22 nnz = (int) XLENGTH(i0), nnz_ = nnz, *iwork = NULL;
23 size_t liwork = (size_t) ((int_fast64_t) n + 1 + n + m + nnz),
24 lwork = (size_t) nnz;
25 Matrix_Calloc(iwork, liwork, int);
26
27#define TEMPLATE(c) \
28 do { \
29 c##TYPE *px0 = NULL, *px1 = NULL, *work = NULL; \
30 c##IF_NPATTERN( \
31 SEXP x0 = PROTECT(GET_SLOT(from, Matrix_xSym)); \
32 px0 = c##PTR(x0); \
33 Matrix_Calloc(work, lwork, c##TYPE); \
34 ); \
35 c##tspaggr(pj1, pi1, px1, pj0, pi0, px0, n, m, &nnz, iwork, work); \
36 if (nnz != nnz_) { \
37 PROTECT(to = newObject(class)); \
38 PROTECT(i1 = Rf_allocVector(INTSXP, nnz)), \
39 PROTECT(j1 = Rf_allocVector(INTSXP, nnz)); \
40 pi1 = INTEGER(i1); \
41 pj1 = INTEGER(j1); \
42 SET_SLOT(to, Matrix_iSym, i1); \
43 SET_SLOT(to, Matrix_jSym, j1); \
44 c##IF_NPATTERN( \
45 SEXP x1 = PROTECT(Rf_allocVector(c##TYPESXP, nnz)); \
46 px1 = c##PTR(x1); \
47 SET_SLOT(to, Matrix_xSym, x1); \
48 ); \
49 c##tspaggr(pj1, pi1, px1, pj0, pi0, px0, n, m, &nnz, iwork, work); \
50 c##IF_NPATTERN( \
51 UNPROTECT(1); /* x1 */ \
52 ); \
53 UNPROTECT(3); /* j1, i1, to */ \
54 } \
55 c##IF_NPATTERN( \
56 Matrix_Free(work, lwork); \
57 UNPROTECT(1); /* x0 */ \
58 ); \
59 } while (0)
60
61 SWITCH5(class[0], TEMPLATE);
62
63#undef TEMPLATE
64
65 Matrix_Free(iwork, liwork);
66 UNPROTECT(2); /* j0, i0 */
67
68 if (nnz == nnz_)
69 return from;
70
71 PROTECT(to);
72 SET_DIM(to, m, n);
73 SET_DIMNAMES(to, 0, DIMNAMES(from, 0));
74 if (class[1] != 'g' && UPLO(from) != 'U')
75 SET_UPLO(to);
76 if (class[1] == 's' && class[0] == 'z' && TRANS(from) != 'C')
77 SET_TRANS(to);
78 if (class[1] == 't' && DIAG(from) != 'N')
79 SET_DIAG(to);
80 if (class[1] != 't')
82 UNPROTECT(1); /* to */
83 return to;
84}
85
86SEXP R_sparse_aggregate(SEXP s_from)
87{
88 const char *class = Matrix_class(s_from, valid_sparse, 2, __func__);
89 return sparse_aggregate(s_from, class);
90}
#define SWITCH5(c, template)
Definition M5.h:327
#define SET_DIM(x, m, n)
Definition Mdefines.h:87
#define Matrix_Calloc(p, n, t)
Definition Mdefines.h:45
#define _(String)
Definition Mdefines.h:66
#define SET_UPLO(x)
Definition Mdefines.h:103
#define DIAG(x)
Definition Mdefines.h:111
#define UPLO(x)
Definition Mdefines.h:101
#define SET_DIMNAMES(x, mode, value)
Definition Mdefines.h:98
const char * Matrix_class(SEXP, const char **, int, const char *)
Definition objects.c:112
#define Matrix_Free(p, n)
Definition Mdefines.h:56
#define DIMNAMES(x, mode)
Definition Mdefines.h:96
#define SET_TRANS(x)
Definition Mdefines.h:108
#define TRANS(x)
Definition Mdefines.h:106
#define SET_DIAG(x)
Definition Mdefines.h:113
#define DIM(x)
Definition Mdefines.h:85
#define GET_SLOT(x, name)
Definition Mdefines.h:72
#define COPY_SLOT(dest, src, name)
Definition Mdefines.h:75
const char * valid_sparse[]
Definition Mdefines.h:328
SEXP R_sparse_aggregate(SEXP s_from)
Definition aggregate.c:86
SEXP sparse_aggregate(SEXP from, const char *class)
Definition aggregate.c:5
#define TEMPLATE(c)
SEXP Matrix_factorsSym
Definition init.c:606
SEXP Matrix_iSym
Definition init.c:607
SEXP Matrix_jSym
Definition init.c:610