Matrix r5059
Loading...
Searching...
No Matches
utils-R.c
Go to the documentation of this file.
1#include "Mdefines.h"
2#include "M5.h"
3
4SEXP R_index_triangle(SEXP s_n, SEXP s_packed, SEXP s_upper, SEXP s_diag)
5{
6 SEXP r;
7 int i, j, n = Rf_asInteger(s_n), packed = Rf_asLogical(s_packed),
8 upper = Rf_asLogical(s_upper), diag = Rf_asLogical(s_diag);
9 int_fast64_t
10 nn = (int_fast64_t) n * n,
11 nx = (packed) ? n + (nn - n) / 2 : nn,
12 nr = (diag) ? n + (nn - n) / 2 : (nn - n) / 2;
13 if (nx > (1LL << 53))
14 Rf_error(_("maximum index would exceed %s"), "2^53");
15 if (nr > R_XLEN_T_MAX)
16 Rf_error(_("attempt to allocate vector of length exceeding %s"),
17 "R_XLEN_T_MAX");
18
19#define DO_INDEX \
20 do { \
21 if (packed) { \
22 if (diag) { \
23 while (k <= nr_) \
24 *(pr++) = k++; \
25 } else if (upper) { \
26 for (j = 0; j < n; ++j) { \
27 for (i = 0; i < j; ++i) \
28 *(pr++) = k++; \
29 k++; \
30 } \
31 } else { \
32 for (j = 0; j < n; ++j) { \
33 k++; \
34 for (i = j+1; i < n; ++i) \
35 *(pr++) = k++; \
36 } \
37 } \
38 } else if (diag) { \
39 if (upper) { \
40 for (j = 0; j < n; ++j) { \
41 for (i = 0; i <= j; ++i) \
42 *(pr++) = k++; \
43 k += n-j-1; \
44 } \
45 } else { \
46 for (j = 0; j < n; ++j) { \
47 k += j; \
48 for (i = j; i < n; ++i) \
49 *(pr++) = k++; \
50 } \
51 } \
52 } else { \
53 if (upper) { \
54 for (j = 0; j < n; ++j) { \
55 for (i = 0; i < j; ++i) \
56 *(pr++) = k++; \
57 k += n-j; \
58 } \
59 } else { \
60 for (j = 0; j < n; ++j) { \
61 k += j+1; \
62 for (i = j+1; i < n; ++i) \
63 *(pr++) = k++; \
64 } \
65 } \
66 } \
67 } while (0)
68
69 if (nx > INT_MAX) {
70
71 PROTECT(r = Rf_allocVector(REALSXP, (R_xlen_t) nr));
72 double k = 1.0, nr_ = (double) nr, *pr = REAL(r);
73
75
76 } else {
77
78 PROTECT(r = Rf_allocVector(INTSXP, (R_xlen_t) nr));
79 int k = 1, nr_ = (int) nr, *pr = INTEGER(r);
80
82
83 }
84
85#undef DO_INDEX
86
87 UNPROTECT(1);
88 return r;
89}
90
91SEXP R_index_diagonal(SEXP s_n, SEXP s_packed, SEXP s_upper)
92{
93 SEXP r;
94 int j, n = Rf_asInteger(s_n), packed = Rf_asLogical(s_packed),
95 upper = Rf_asLogical(s_upper);
96 int_fast64_t
97 nn = (int_fast64_t) n * n,
98 nx = (packed) ? n + (nn - n) / 2 : nn;
99 if (nx > (1LL << 53))
100 Rf_error(_("maximum index would exceed %s"), "2^53");
101
102#define DO_INDEX \
103 do { \
104 if (!packed) { \
105 for (j = 0; j < n; ++j) { \
106 *(pr++) = k++; \
107 k += n; \
108 } \
109 } else if (upper) { \
110 for (j = 0; j < n; ++j) { \
111 *(pr++) = k; \
112 k += j+2; \
113 } \
114 } else { \
115 for (j = 0; j < n; ++j) { \
116 *(pr++) = k; \
117 k += n-j; \
118 } \
119 } \
120 } while (0)
121
122 if (nx > INT_MAX) {
123
124 PROTECT(r = Rf_allocVector(REALSXP, n));
125 double k = 1.0, *pr = REAL(r);
126
127 DO_INDEX;
128
129 } else {
130
131 PROTECT(r = Rf_allocVector(INTSXP, n));
132 int k = 1, *pr = INTEGER(r);
133 DO_INDEX;
134
135 }
136
137#undef DO_INDEX
138
139 UNPROTECT(1);
140 return r;
141}
142
143SEXP R_nnz(SEXP s_x, SEXP s_countNA, SEXP s_nnzmax)
144{
145 int countNA = Rf_asLogical(s_countNA);
146 R_xlen_t n = XLENGTH(s_x), nnz = 0;
147 double nnzmax = Rf_asReal(s_nnzmax);
148 if (!ISNAN(nnzmax) && nnzmax >= 0.0 && nnzmax < (double) n)
149 n = (R_xlen_t) nnzmax;
150
151#define TEMPLATE(c) \
152 do { \
153 c##TYPE *px = c##PTR(s_x); \
154 if (countNA == NA_LOGICAL) { \
155 while (n-- > 0) { \
156 if (!c##NOT_NA(*px)) \
157 return Rf_ScalarInteger(NA_INTEGER); \
158 if (c##NOT_ZERO(*px)) \
159 ++nnz; \
160 ++px; \
161 } \
162 } else if (countNA != 0) { \
163 while (n-- > 0) { \
164 if (c##NOT_ZERO(*px)) \
165 ++nnz; \
166 ++px; \
167 } \
168 } else { \
169 while (n-- > 0) { \
170 if (c##NOT_NA(*px) && c##NOT_ZERO(*px)) \
171 ++nnz; \
172 ++px; \
173 } \
174 } \
175 } while (0)
176
178
179#undef TEMPLATE
180
181 return (nnz <= INT_MAX)
182 ? Rf_ScalarInteger((int) nnz) : Rf_ScalarReal((double) nnz);
183}
184
185
186/* ================================================================== */
187/* ================================================================== */
188
189
190#define TRUE_ Rf_ScalarLogical(1)
191#define FALSE_ Rf_ScalarLogical(0)
192
193// Fast implementation of [ originally in ../R/Auxiliaries.R ]
194// all0 <- function(x) !any(is.na(x)) && all(!x) ## ~= allFalse
195// allFalse <- function(x) !any(x) && !any(is.na(x)) ## ~= all0
196SEXP R_all0(SEXP x) {
197 if (!Rf_isVectorAtomic(x)) {
198 if (Rf_length(x) == 0) return TRUE_;
199 // Typically S4. TODO: Call the R code above, instead!
200 Rf_error(_("Argument must be numeric-like atomic vector"));
201 }
202 R_xlen_t i, n = XLENGTH(x);
203 if (n == 0) return TRUE_;
204
205 switch (TYPEOF(x)) {
206 case LGLSXP:
207 {
208 int *xx = LOGICAL(x);
209 for (i = 0; i < n; i++)
210 if (xx[i] == NA_LOGICAL || xx[i] != 0) return FALSE_;
211 return TRUE_;
212 }
213 case INTSXP:
214 {
215 int *xx = INTEGER(x);
216 for (i = 0; i < n; i++)
217 if (xx[i] == NA_INTEGER || xx[i] != 0) return FALSE_;
218 return TRUE_;
219 }
220 case REALSXP:
221 {
222 double *xx = REAL(x);
223 for (i = 0; i < n; i++)
224 if (ISNAN(xx[i]) || xx[i] != 0.) return FALSE_;
225 return TRUE_;
226 }
227 case RAWSXP:
228 {
229 unsigned char *xx = RAW(x);
230 for (i = 0; i < n; i++)
231 if (xx[i] != 0) return FALSE_;
232 return TRUE_;
233 }
234 }
235 Rf_error(_("Argument must be numeric-like atomic vector"));
236 return R_NilValue; // -Wall
237}
238
239// Fast implementation of [ originally in ../R/Auxiliaries.R ]
240// any0 <- function(x) isTRUE(any(x == 0)) ## ~= anyFalse
241// anyFalse <- function(x) isTRUE(any(!x)) ## ~= any0
242SEXP R_any0(SEXP x) {
243 if (!Rf_isVectorAtomic(x)) {
244 if (Rf_length(x) == 0) return FALSE_;
245 // Typically S4. TODO: Call the R code above, instead!
246 Rf_error(_("Argument must be numeric-like atomic vector"));
247 }
248 R_xlen_t i, n = XLENGTH(x);
249 if (n == 0) return FALSE_;
250
251 switch (TYPEOF(x)) {
252 case LGLSXP:
253 {
254 int *xx = LOGICAL(x);
255 for (i = 0; i < n; i++) if (xx[i] == 0) return TRUE_;
256 return FALSE_;
257 }
258 case INTSXP:
259 {
260 int *xx = INTEGER(x);
261 for (i = 0; i < n; i++) if (xx[i] == 0) return TRUE_;
262 return FALSE_;
263 }
264 case REALSXP:
265 {
266 double *xx = REAL(x);
267 for (i = 0; i < n; i++) if (xx[i] == 0.) return TRUE_;
268 return FALSE_;
269 }
270 case RAWSXP:
271 {
272 unsigned char *xx = RAW(x);
273 for (i = 0; i < n; i++) if (xx[i] == 0) return TRUE_;
274 return FALSE_;
275 }
276 }
277 Rf_error(_("Argument must be numeric-like atomic vector"));
278 return R_NilValue; // -Wall
279}
280
281#undef TRUE_
282#undef FALSE_
283
284// Almost "Cut n Paste" from ...R../src/main/array.c do_matrix() :
285// used in ../R/Matrix.R as
286//
287// .External(Mmatrix,
288// data, nrow, ncol, byrow, dimnames,
289// missing(nrow), missing(ncol))
290SEXP Mmatrix(SEXP args)
291{
292 SEXP vals, ans, snr, snc, dimnames;
293 int nr = 1, nc = 1, byrow, miss_nr, miss_nc;
294 R_xlen_t lendat;
295
296 args = CDR(args); /* skip 'name' */
297 vals = CAR(args); args = CDR(args);
298 /* Supposedly as.vector() gave a vector type, but we check */
299 switch (TYPEOF(vals)) {
300 case LGLSXP:
301 case INTSXP:
302 case REALSXP:
303 case CPLXSXP:
304 case STRSXP:
305 case RAWSXP:
306 case EXPRSXP:
307 case VECSXP:
308 break;
309 default:
310 Rf_error(_("'data' must be of a vector type"));
311 }
312 lendat = XLENGTH(vals);
313 snr = CAR(args); args = CDR(args);
314 snc = CAR(args); args = CDR(args);
315 byrow = Rf_asLogical(CAR(args)); args = CDR(args);
316 if (byrow == NA_INTEGER)
317 Rf_error(_("invalid '%s' argument"), "byrow");
318 dimnames = CAR(args);
319 args = CDR(args);
320 miss_nr = Rf_asLogical(CAR(args)); args = CDR(args);
321 miss_nc = Rf_asLogical(CAR(args));
322
323 if (!miss_nr) {
324 if (!Rf_isNumeric(snr)) Rf_error(_("non-numeric matrix extent"));
325 nr = Rf_asInteger(snr);
326 if (nr == NA_INTEGER)
327 Rf_error(_("invalid 'nrow' value (too large or NA)"));
328 if (nr < 0)
329 Rf_error(_("invalid 'nrow' value (< 0)"));
330 }
331 if (!miss_nc) {
332 if (!Rf_isNumeric(snc)) Rf_error(_("non-numeric matrix extent"));
333 nc = Rf_asInteger(snc);
334 if (nc == NA_INTEGER)
335 Rf_error(_("invalid 'ncol' value (too large or NA)"));
336 if (nc < 0)
337 Rf_error(_("invalid 'ncol' value (< 0)"));
338 }
339 if (miss_nr && miss_nc) {
340 if (lendat > INT_MAX) Rf_error("data is too long");
341 nr = (int) lendat;
342 } else if (miss_nr) {
343 if (lendat > (double) nc * INT_MAX) Rf_error("data is too long");
344 nr = (int) ceil((double) lendat / (double) nc);
345 } else if (miss_nc) {
346 if (lendat > (double) nr * INT_MAX) Rf_error("data is too long");
347 nc = (int) ceil((double) lendat / (double) nr);
348 }
349
350 if (lendat > 0) {
351 R_xlen_t nrc = (R_xlen_t) nr * nc;
352 if (lendat > 1 && nrc % lendat != 0) {
353 if ((lendat > nr && (lendat / nr) * nr != lendat) ||
354 (lendat < nr && (nr / lendat) * lendat != nr))
355 Rf_warning(_("data length [%lld] is not a sub-multiple "
356 "or multiple of the number of rows [%d]"),
357 (long long) lendat, nr);
358 else if ((lendat > nc && (lendat / nc) * nc != lendat) ||
359 (lendat < nc && (nc / lendat) * lendat != nc))
360 Rf_warning(_("data length [%lld] is not a sub-multiple "
361 "or multiple of the number of columns [%d]"),
362 (long long) lendat, nc);
363 } else if (lendat > 1 && nrc == 0)
364 Rf_warning(_("data length exceeds size of matrix"));
365 }
366
367#ifndef LONG_VECTOR_SUPPORT
368 if ((double) nr * (double) nc > INT_MAX)
369 Rf_error(_("too many elements specified"));
370#endif
371
372 PROTECT(ans = Rf_allocMatrix(TYPEOF(vals), nr, nc));
373 if (Rf_isVector(vals)) {
374 if(lendat)
375 Rf_copyMatrix(ans, vals, (Rboolean) byrow);
376 else { /* fill with NAs */
377 R_xlen_t N = (R_xlen_t) nr * nc, i;
378 switch (TYPEOF(vals)) {
379 case STRSXP:
380 for (i = 0; i < N; i++)
381 SET_STRING_ELT(ans, i, NA_STRING);
382 break;
383 case LGLSXP:
384 for (i = 0; i < N; i++)
385 LOGICAL(ans)[i] = NA_LOGICAL;
386 break;
387 case INTSXP:
388 for (i = 0; i < N; i++)
389 INTEGER(ans)[i] = NA_INTEGER;
390 break;
391 case REALSXP:
392 for (i = 0; i < N; i++)
393 REAL(ans)[i] = NA_REAL;
394 break;
395 case CPLXSXP:
396 {
397 /* Initialization must work whether Rcomplex is typedef-ed
398 to a struct { R < 4.3.0 } or to a union { R >= 4.3.0 }
399 */
400 Rcomplex zna = { .r = NA_REAL, .i = 0.0 };
401 for (i = 0; i < N; i++)
402 COMPLEX(ans)[i] = zna;
403 break;
404 }
405 case RAWSXP:
406 // FIXME: N may overflow size_t !!
407 memset(RAW(ans), 0, N);
408 break;
409 default:
410 /* don't fill with anything */
411 ;
412 }
413 }
414 }
415 if (dimnames != R_NilValue && Rf_length(dimnames) > 0)
416 ans = Rf_dimnamesgets(ans, dimnames);
417 UNPROTECT(1);
418 return ans;
419}
420
431static
432int *expand_cmprPt(int ncol, const int mp[], int mj[])
433{
434 int j;
435 for (j = 0; j < ncol; j++) {
436 int j2 = mp[j+1], jj;
437 for (jj = mp[j]; jj < j2; jj++)
438 mj[jj] = j;
439 }
440 return mj;
441}
442
447SEXP compressed_non_0_ij(SEXP x, SEXP colP)
448{
449 int col = Rf_asLogical(colP); /* 1 if "C"olumn compressed; 0 if "R"ow */
450 SEXP ans, indSym = col ? Matrix_iSym : Matrix_jSym;
451 SEXP indP = PROTECT(GET_SLOT(x, indSym)),
452 pP = PROTECT(GET_SLOT(x, Matrix_pSym));
453 int i, *ij;
454 int nouter = INTEGER(GET_SLOT(x, Matrix_DimSym))[col ? 1 : 0],
455 n_el = INTEGER(pP)[nouter]; /* is only == length(indP), if the
456 inner slot is not over-allocated */
457
458 ij = INTEGER(ans = PROTECT(Rf_allocMatrix(INTSXP, n_el, 2)));
459 /* expand the compressed margin to 'i' or 'j' : */
460 expand_cmprPt(nouter, INTEGER(pP), &ij[col ? n_el : 0]);
461 /* and copy the other one: */
462 if (col)
463 for(i = 0; i < n_el; i++)
464 ij[i] = INTEGER(indP)[i];
465 else /* row compressed */
466 for(i = 0; i < n_el; i++)
467 ij[i + n_el] = INTEGER(indP)[i];
468
469 UNPROTECT(3);
470 return ans;
471}
472
474{
475 int n = Rf_length(pP) - 1;
476 int *p = INTEGER(pP);
477 SEXP ans = PROTECT(Rf_allocVector(INTSXP, p[n]));
478
479 expand_cmprPt(n, p, INTEGER(ans));
480 UNPROTECT(1);
481 return ans;
482}
483
493SEXP m_encodeInd(SEXP ij, SEXP di, SEXP orig_1, SEXP chk_bnds)
494{
495 SEXP ans;
496 int *ij_di = NULL, n, nprot=1;
497 int check_bounds = Rf_asLogical(chk_bnds), one_ind = Rf_asLogical(orig_1);
498
499 if (TYPEOF(di) != INTSXP) {
500 di = PROTECT(Rf_coerceVector(di, INTSXP));
501 nprot++;
502 }
503 if (TYPEOF(ij) != INTSXP) {
504 ij = PROTECT(Rf_coerceVector(ij, INTSXP));
505 nprot++;
506 }
507 if (!Rf_isMatrix(ij) ||
508 (ij_di = INTEGER(Rf_getAttrib(ij, R_DimSymbol)))[1] != 2)
509 Rf_error(_("Argument ij must be 2-column integer matrix"));
510 n = ij_di[0];
511 int *Di = INTEGER(di), *IJ = INTEGER(ij),
512 *j_ = IJ+n;/* pointer offset! */
513
514 if ((Di[0] * (double) Di[1]) >= 1 + (double)INT_MAX) { /* need double */
515 ans = PROTECT(Rf_allocVector(REALSXP, n));
516 double *ii = REAL(ans), nr = (double) Di[0];
517
518#define do_ii_FILL(_i_, _j_) \
519 int i; \
520 if (check_bounds) { \
521 for (i = 0; i < n; i++) { \
522 if (_i_[i] == NA_INTEGER || _j_[i] == NA_INTEGER) \
523 ii[i] = NA_INTEGER; \
524 else { \
525 register int i_i, j_i; \
526 if (one_ind) { \
527 i_i = _i_[i]-1; \
528 j_i = _j_[i]-1; \
529 } else { \
530 i_i = _i_[i]; \
531 j_i = _j_[i]; \
532 } \
533 if (i_i < 0 || i_i >= Di[0]) \
534 Rf_error(_("subscript 'i' out of bounds in M[ij]")); \
535 if (j_i < 0 || j_i >= Di[1]) \
536 Rf_error(_("subscript 'j' out of bounds in M[ij]")); \
537 ii[i] = i_i + j_i * nr; \
538 } \
539 } \
540 } else { \
541 for (i = 0; i < n; i++) \
542 ii[i] = (_i_[i] == NA_INTEGER || _j_[i] == NA_INTEGER) \
543 ? NA_INTEGER \
544 : ((one_ind) \
545 ? ((_i_[i]-1) + (_j_[i]-1) * nr) \
546 : _i_[i] + _j_[i] * nr); \
547 }
548
549 do_ii_FILL(IJ, j_);
550 } else {
551 ans = PROTECT(Rf_allocVector(INTSXP, n));
552 int *ii = INTEGER(ans), nr = Di[0];
553
554 do_ii_FILL(IJ, j_);
555 }
556 UNPROTECT(nprot);
557 return ans;
558}
559
571SEXP m_encodeInd2(SEXP i, SEXP j, SEXP di, SEXP orig_1, SEXP chk_bnds)
572{
573 SEXP ans;
574 int n = LENGTH(i), nprot = 1;
575 int check_bounds = Rf_asLogical(chk_bnds), one_ind = Rf_asLogical(orig_1);
576
577 if (TYPEOF(di)!= INTSXP) {
578 di = PROTECT(Rf_coerceVector(di,INTSXP));
579 nprot++;
580 }
581 if (TYPEOF(i) != INTSXP) {
582 i = PROTECT(Rf_coerceVector(i, INTSXP));
583 nprot++;
584 }
585 if (TYPEOF(j) != INTSXP) {
586 j = PROTECT(Rf_coerceVector(j, INTSXP));
587 nprot++;
588 }
589 if (LENGTH(j) != n)
590 Rf_error(_("i and j must be integer vectors of the same length"));
591
592 int *Di = INTEGER(di), *i_ = INTEGER(i), *j_ = INTEGER(j);
593
594 if ((Di[0] * (double) Di[1]) >= 1 + (double) INT_MAX) { /* need double */
595 ans = PROTECT(Rf_allocVector(REALSXP, n));
596 double *ii = REAL(ans), nr = (double) Di[0];
597
598 do_ii_FILL(i_, j_);
599 } else {
600 ans = PROTECT(Rf_allocVector(INTSXP, n));
601 int *ii = INTEGER(ans), nr = Di[0];
602
603 do_ii_FILL(i_, j_);
604 }
605 UNPROTECT(nprot);
606 return ans;
607}
608#undef do_ii_FILL
609
610#define _rle_d_
611#include "t_rle.c"
612#undef _rle_d_
613
614#define _rle_i_
615#include "t_rle.c"
616#undef _rle_i_
#define SWITCH4(c, template)
Definition M5.h:315
#define _(String)
Definition Mdefines.h:66
char typeToKind(SEXPTYPE)
Definition objects.c:20
#define GET_SLOT(x, name)
Definition Mdefines.h:72
#define TYPEOF(s)
Definition Mdefines.h:123
SEXP Matrix_DimSym
Definition init.c:598
SEXP Matrix_iSym
Definition init.c:607
SEXP Matrix_jSym
Definition init.c:610
SEXP Matrix_pSym
Definition init.c:622
SEXP R_all0(SEXP x)
Definition utils-R.c:196
SEXP m_encodeInd2(SEXP i, SEXP j, SEXP di, SEXP orig_1, SEXP chk_bnds)
Encode Matrix index (i,j) |--> i + j * nrow {i,j : 0-origin}.
Definition utils-R.c:571
SEXP R_nnz(SEXP s_x, SEXP s_countNA, SEXP s_nnzmax)
Definition utils-R.c:143
SEXP compressed_non_0_ij(SEXP x, SEXP colP)
Return a 2 column matrix '' cbind(i, j) '' of 0-origin index vectors (i,j) which entirely correspond ...
Definition utils-R.c:447
#define TEMPLATE(c)
static int * expand_cmprPt(int ncol, const int mp[], int mj[])
Expand compressed pointers in the array mp into a full set of indices in the array mj.
Definition utils-R.c:432
#define do_ii_FILL(_i_, _j_)
SEXP m_encodeInd(SEXP ij, SEXP di, SEXP orig_1, SEXP chk_bnds)
Encode Matrix index (i,j) |--> i + j * nrow {i,j : 0-origin}.
Definition utils-R.c:493
SEXP R_index_triangle(SEXP s_n, SEXP s_packed, SEXP s_upper, SEXP s_diag)
Definition utils-R.c:4
#define TRUE_
Definition utils-R.c:190
#define FALSE_
Definition utils-R.c:191
SEXP R_index_diagonal(SEXP s_n, SEXP s_packed, SEXP s_upper)
Definition utils-R.c:91
SEXP R_any0(SEXP x)
Definition utils-R.c:242
#define DO_INDEX
SEXP Matrix_expand_pointers(SEXP pP)
Definition utils-R.c:473
SEXP Mmatrix(SEXP args)
Definition utils-R.c:290