-
Notifications
You must be signed in to change notification settings - Fork 33
/
rowRanges.c
156 lines (135 loc) · 4.52 KB
/
rowRanges.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
/***************************************************************************
Public methods:
SEXP rowRanges(SEXP x, ...)
Authors: Henrik Bengtsson.
Copyright Henrik Bengtsson, 2014
**************************************************************************/
#include <Rdefines.h>
#include "types.h"
#include "utils.h"
#define METHOD rowRanges
#define RETURN_TYPE void
#define ARGUMENTS_LIST X_C_TYPE *x, R_xlen_t nrow, R_xlen_t ncol, void *rows, R_xlen_t nrows, void *cols, R_xlen_t ncols, int what, int narm, int hasna, X_C_TYPE *ans, R_xlen_t nans, int *is_counted, int cores
#define X_TYPE 'i'
#include "templates-gen-matrix.h"
#define X_TYPE 'r'
#include "templates-gen-matrix.h"
SEXP rowRanges(SEXP x, SEXP dim, SEXP rows, SEXP cols, SEXP what, SEXP naRm, SEXP hasNA, SEXP cores) {
SEXP ans = NILSXP, ans2 = NILSXP;
int *mins, *maxs;
double *mins2, *maxs2;
int *is_counted, all_counted = 0;
int what2, narm, hasna, cores2;
R_xlen_t nrow, ncol, ii;
/* Argument 'x' and 'dim': */
assertArgMatrix(x, dim, (R_TYPE_INT | R_TYPE_REAL), "x");
nrow = asR_xlen_t(dim, 0);
ncol = asR_xlen_t(dim, 1);
/* Argument 'what': */
if (length(what) != 1)
error("Argument 'what' must be a single number.");
if (!isNumeric(what))
error("Argument 'what' must be a numeric number.");
what2 = asInteger(what);
if (what2 < 0 || what2 > 2)
error("Invalid value of 'what': %d", what2);
/* Argument 'naRm': */
narm = asLogicalNoNA(naRm, "na.rm");
/* Argument 'hasNA': */
hasna = asLogicalNoNA(hasNA, "hasNA");
/* Argument 'rows' and 'cols': */
R_xlen_t nrows, ncols;
int rowsType, colsType;
void *crows = validateIndices(rows, nrow, 0, &nrows, &rowsType);
void *ccols = validateIndices(cols, ncol, 0, &ncols, &colsType);
#ifdef _USE_PTHREAD_
/* Argument 'cores': */
cores2 = asInteger(cores);
if (cores2 <= 0)
error("Argument 'cores' must be a positive value.");
#else
cores2 = 1;
#endif
is_counted = (int *) R_alloc(nrows, sizeof(int));
if (isReal(x)) {
if (what2 == 2) {
PROTECT(ans = allocMatrix(REALSXP, nrows, 2));
} else {
PROTECT(ans = allocVector(REALSXP, nrows));
}
rowRanges_Real[rowsType][colsType](REAL(x), nrow, ncol, crows, nrows, ccols, ncols, what2, narm, hasna, REAL(ans), nrows, is_counted, cores2);
UNPROTECT(1);
} else if (isInteger(x)) {
if (what2 == 2) {
PROTECT(ans = allocMatrix(INTSXP, nrows, 2));
} else {
PROTECT(ans = allocVector(INTSXP, nrows));
}
rowRanges_Integer[rowsType][colsType](INTEGER(x), nrow, ncol, crows, nrows, ccols, ncols, what2, narm, hasna, INTEGER(ans), nrows, is_counted, cores2);
/* Any entries with zero non-missing values? */
all_counted = 1;
for (ii=0; ii < nrows; ii++) {
if (!is_counted[ii]) {
all_counted = 0;
break;
}
}
if (!all_counted) {
/* Handle zero non-missing values */
/* Instead of return INTSXP, we must return REALSXP (to hold -Inf, and Inf) */
if (what2 == 0) {
PROTECT(ans2 = allocVector(REALSXP, nrows));
mins = INTEGER(ans);
mins2 = REAL(ans2);
for (ii=0; ii < nrows; ii++) {
if (is_counted[ii]) {
mins2[ii] = (double)mins[ii];
} else {
mins2[ii] = R_PosInf;
}
}
UNPROTECT(1); /* ans2 */
} else if (what2 == 1) {
PROTECT(ans2 = allocVector(REALSXP, nrows));
maxs = INTEGER(ans);
maxs2 = REAL(ans2);
for (ii=0; ii < nrows; ii++) {
if (is_counted[ii]) {
maxs2[ii] = (double)maxs[ii];
} else {
maxs2[ii] = R_NegInf;
}
}
UNPROTECT(1); /* ans2 */
} else if (what2 == 2) {
PROTECT(ans2 = allocMatrix(REALSXP, nrows, 2));
mins = INTEGER(ans);
maxs = &INTEGER(ans)[nrows];
mins2 = REAL(ans2);
maxs2 = &REAL(ans2)[nrows];
for (ii=0; ii < nrows; ii++) {
if (is_counted[ii]) {
mins2[ii] = (double)mins[ii];
maxs2[ii] = (double)maxs[ii];
} else {
mins2[ii] = R_PosInf;
maxs2[ii] = R_NegInf;
}
}
UNPROTECT(1); /* ans2 */
}
ans = ans2;
}
UNPROTECT(1); /* ans */
}
return(ans);
} // rowRanges()
/***************************************************************************
HISTORY:
2015-08-10 [DJ]
o Pthread processing.
2015-06-07 [DJ]
o Supported subsetted computation.
2014-11-16 [HB]
o Created.
**************************************************************************/