Matrix r5059
Loading...
Searching...
No Matches
dropzero.c
Go to the documentation of this file.
1#include "Mdefines.h"
2#include "M5.h"
3
4SEXP sparse_dropzero(SEXP from, const char *class, double tol)
5{
6 /* defined in ./aggregate.c : */
7 SEXP sparse_aggregate(SEXP, const char *);
8 from = sparse_aggregate(from, class);
9 if (class[0] == 'n')
10 return from;
11 PROTECT(from);
12
13 char ct = '\0';
14 if (class[1] == 's' && class[0] == 'z')
15 ct = TRANS(from);
16
17 SEXP to;
18 int strict = ISNAN(tol) || tol <= 0.0;
19
20#define NZ(c, x) ((strict) ? c##NOT_ZERO(x) : c##NOT_ZERO_TOL(x, tol))
21
22 if (class[2] != 'T') {
23
24 SEXP iSym = (class[2] == 'C') ? Matrix_iSym : Matrix_jSym,
25 p0 = PROTECT(GET_SLOT(from, Matrix_pSym)),
26 i0 = PROTECT(GET_SLOT(from, iSym)),
27 x0 = PROTECT(GET_SLOT(from, Matrix_xSym));
28 int *pp0 = INTEGER(p0), *pi0 = INTEGER(i0),
29 n = (int) (XLENGTH(p0) - 1), j, k, kend,
30 nnz0 = pp0[n], nnz1 = 0;
31 pp0++;
32
33 if (ct != 'C') {
34
35#define TEMPLATE(c) \
36 do { \
37 c##TYPE *px0 = c##PTR(x0); \
38 for (k = 0; k < nnz0; ++k) \
39 if (NZ(c, px0[k])) \
40 ++nnz1; \
41 } while (0)
42
43 SWITCH4(class[0], TEMPLATE);
44
45#undef TEMPLATE
46
47 } else {
48
49 Rcomplex *px0 = COMPLEX(x0);
50 for (j = 0, k = 0; j < n; ++j) {
51 kend = pp0[j];
52 while (k < kend) {
53 if ((pi0[k] == j) ? NZ(d, px0[k].r) : NZ(z, px0[k]))
54 ++nnz1;
55 ++k;
56 }
57 }
58
59 }
60
61 if (nnz1 == nnz0) {
62 UNPROTECT(4); /* x0, i0, p0, from */
63 return from;
64 }
65
66 PROTECT(to = newObject(class));
67
68 SEXP p1 = PROTECT(Rf_allocVector(INTSXP, XLENGTH(p0))),
69 i1 = PROTECT(Rf_allocVector(INTSXP, nnz1)),
70 x1 = PROTECT(Rf_allocVector(TYPEOF(x0), nnz1));
71 int *pp1 = INTEGER(p1), *pi1 = INTEGER(i1);
72 *(pp1++) = 0;
73 SET_SLOT(to, Matrix_pSym, p1);
74 SET_SLOT(to, iSym, i1);
75 SET_SLOT(to, Matrix_xSym, x1);
76
77 if (ct != 'C') {
78
79#define TEMPLATE(c) \
80 do { \
81 c##TYPE *px0 = c##PTR(x0), *px1 = c##PTR(x1); \
82 for (j = 0, k = 0; j < n; ++j) { \
83 pp1[j] = pp1[j - 1]; \
84 kend = pp0[j]; \
85 while (k < kend) { \
86 if (NZ(c, px0[k])) { \
87 pi1[pp1[j] ] = pi0[k]; \
88 px1[pp1[j]++] = px0[k]; \
89 } \
90 ++k; \
91 } \
92 } \
93 } while (0)
94
95 SWITCH4(class[0], TEMPLATE);
96
97#undef TEMPLATE
98
99 } else {
100
101 Rcomplex *px0 = COMPLEX(x0), *px1 = COMPLEX(x1);
102 for (j = 0, k = 0; j < n; ++j) {
103 pp1[j] = pp1[j - 1];
104 kend = pp0[j];
105 while (k < kend) {
106 if ((pi0[k] == j) ? NZ(d, px0[k].r) : NZ(z, px0[k])) {
107 pi1[pp1[j] ] = pi0[k];
108 px1[pp1[j]++] = px0[k];
109 }
110 ++k;
111 }
112 }
113
114 }
115
116 UNPROTECT(7); /* x1, i1, p1, to, x0, i0, p0 */
117
118 } else {
119
120 SEXP i0 = PROTECT(GET_SLOT(from, Matrix_iSym)),
121 j0 = PROTECT(GET_SLOT(from, Matrix_jSym)),
122 x0 = PROTECT(GET_SLOT(from, Matrix_xSym));
123 int *pi0 = INTEGER(i0), *pj0 = INTEGER(j0);
124 R_xlen_t k, nnz0 = XLENGTH(x0), nnz1 = 0;
125
126 if (ct != 'C') {
127
128#define TEMPLATE(c) \
129 do { \
130 c##TYPE *px0 = c##PTR(x0); \
131 for (k = 0; k < nnz0; ++k) \
132 if (NZ(c, px0[k])) \
133 ++nnz1; \
134 } while (0)
135
136 SWITCH4(class[0], TEMPLATE);
137
138#undef TEMPLATE
139
140 } else {
141
142 Rcomplex *px0 = COMPLEX(x0);
143 for (k = 0; k < nnz0; ++k)
144 if ((pi0[k] == pj0[k]) ? NZ(d, px0[k].r) : NZ(z, px0[k]))
145 ++nnz1;
146
147 }
148
149 if (nnz1 == nnz0) {
150 UNPROTECT(4); /* x0, j0, i0, from */
151 return from;
152 }
153
154 PROTECT(to = newObject(class));
155
156 SEXP i1 = PROTECT(Rf_allocVector(INTSXP, nnz1)),
157 j1 = PROTECT(Rf_allocVector(INTSXP, nnz1)),
158 x1 = PROTECT(Rf_allocVector(TYPEOF(x0), nnz1));
159 int *pi1 = INTEGER(i1), *pj1 = INTEGER(j1);
160 SET_SLOT(to, Matrix_iSym, i1);
161 SET_SLOT(to, Matrix_jSym, j1);
162 SET_SLOT(to, Matrix_xSym, x1);
163
164 if (ct != 'C') {
165
166#define TEMPLATE(c) \
167 do { \
168 c##TYPE *px0 = c##PTR(x0), *px1 = c##PTR(x1); \
169 for (k = 0; k < nnz0; ++k) \
170 if (NZ(c, px0[k])) { \
171 *(pi1++) = pi0[k]; \
172 *(pj1++) = pj0[k]; \
173 *(px1++) = px0[k]; \
174 } \
175 } while (0)
176
177 SWITCH4(class[0], TEMPLATE);
178
179#undef TEMPLATE
180
181 } else {
182
183 Rcomplex *px0 = COMPLEX(x0), *px1 = COMPLEX(x1);
184 for (k = 0; k < nnz0; ++k)
185 if ((pi0[k] == pj0[k]) ? NZ(d, px0[k].r) : NZ(z, px0[k])) {
186 *(pi1++) = pi0[k];
187 *(pj1++) = pj0[k];
188 *(px1++) = px0[k];
189 }
190
191 }
192
193 UNPROTECT(7); /* x1, j1, i1, to, x0, j0, i0 */
194
195 }
196
197 PROTECT(to);
198 int *pdim = DIM(from), m = pdim[0], n = pdim[1];
199 SET_DIM(to, m, n);
200 SET_DIMNAMES(to, 0, DIMNAMES(from, 0));
201 if (class[1] != 'g' && UPLO(from) != 'U')
202 SET_UPLO(to);
203 if (class[1] == 's' && class[0] == 'z' && ct != 'C')
204 SET_TRANS(to);
205 if (class[1] == 't' && DIAG(from) != 'N')
206 SET_DIAG(to);
207 UNPROTECT(2); /* to, from */
208 return to;
209}
210
211SEXP R_sparse_dropzero(SEXP s_from, SEXP s_tol)
212{
213 const char *class = Matrix_class(s_from, valid_sparse, 6, __func__);
214
215 double tol;
216 if (TYPEOF(s_tol) != REALSXP || LENGTH(s_tol) < 1 ||
217 ISNAN(tol = REAL(s_tol)[0]))
218 Rf_error(_("'%s' is not a number"), "tol");
219
220 return sparse_dropzero(s_from, class, tol);
221}
#define SWITCH4(c, template)
Definition M5.h:315
#define SET_DIM(x, m, n)
Definition Mdefines.h:87
#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 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
SEXP newObject(const char *)
Definition objects.c:13
const char * valid_sparse[]
Definition Mdefines.h:328
#define SET_SLOT(x, name, value)
Definition Mdefines.h:73
#define TYPEOF(s)
Definition Mdefines.h:123
SEXP sparse_aggregate(SEXP from, const char *class)
Definition aggregate.c:5
SEXP R_sparse_dropzero(SEXP s_from, SEXP s_tol)
Definition dropzero.c:211
#define TEMPLATE(c)
#define NZ(c, x)
SEXP sparse_dropzero(SEXP from, const char *class, double tol)
Definition dropzero.c:4
SEXP Matrix_xSym
Definition init.c:635
SEXP Matrix_iSym
Definition init.c:607
SEXP Matrix_jSym
Definition init.c:610
SEXP Matrix_pSym
Definition init.c:622