26
26
#ifndef Rcpp__sugar__sample_h
27
27
#define Rcpp__sugar__sample_h
28
28
29
- #if defined(WIN32) || defined(__WIN32) || defined(__WIN32__)
30
- #include < malloc.h>
31
- #else
32
- #include < alloca.h>
33
- #endif
34
-
35
- // In order to mirror the behavior of `base::sample`
36
- // as closely as possible, this file contains adaptations
29
+ #include < vector>
30
+
31
+ // In order to mirror the behavior of `base::sample`
32
+ // as closely as possible, this file contains adaptations
37
33
// of several functions in R/src/main/random.c:
38
34
//
39
35
// * do_sample - general logic as well as the empirical sampling routine.
43
39
// * walker_ProbSampleReplace, ProbSampleReplace, and ProbSampleNoReplace -
44
40
// algorithms for sampling according to a supplied probability vector.
45
41
//
46
- // For each of the sampling routines, two signatures are provided:
42
+ // For each of the sampling routines, two signatures are provided:
47
43
//
48
- // * A version that returns an integer vector, which can be used to
49
- // generate 0-based indices (one_based = false) or 1-based indices
50
- // (one_based = true) -- where the latter corresponds to the
51
- // bahavior of `base::sample.int`.
44
+ // * A version that returns an integer vector, which can be used to
45
+ // generate 0-based indices (one_based = false) or 1-based indices
46
+ // (one_based = true) -- where the latter corresponds to the
47
+ // bahavior of `base::sample.int`.
52
48
//
53
49
// * A version which takes an input Vector<> (rather than an integer 'n'),
54
50
// and samples its elements -- this corresponds to `base::sample`.
@@ -150,26 +146,19 @@ inline Vector<RTYPE> SampleReplace(Vector<REALSXP>& p, int k, const Vector<RTYPE
150
146
151
147
// Adapted from `walker_ProbSampleReplace`
152
148
// Index version
153
- #define SMALL 10000
154
149
inline Vector<INTSXP> WalkerSample (const Vector<REALSXP>& p, int n, int nans, bool one_based)
155
150
{
156
151
Vector<INTSXP> a = no_init (n), ans = no_init (nans);
157
- double *q, rU;
158
152
int i, j, k;
159
- int *HL, *H, *L;
153
+ std::vector<double > q (n);
154
+ double rU;
160
155
161
- int adj = one_based ? 1 : 0 ;
156
+ std::vector<int > HL (n);
157
+ std::vector<int >::iterator H, L;
162
158
163
- if (n <= SMALL) {
164
- R_CheckStack2 (n * (sizeof (int ) + sizeof (double )));
165
- HL = static_cast <int *>(::alloca (n * sizeof (int )));
166
- q = static_cast <double *>(::alloca (n * sizeof (double )));
167
- } else {
168
- HL = static_cast <int *>(Calloc (n, int ));
169
- q = static_cast <double *>(Calloc (n, double ));
170
- }
159
+ int adj = one_based ? 1 : 0 ;
171
160
172
- H = HL - 1 ; L = HL + n;
161
+ H = HL. begin () - 1 ; L = HL. begin () + n;
173
162
for (i = 0 ; i < n; i++) {
174
163
q[i] = p[i] * n;
175
164
if (q[i] < 1.0 ) {
@@ -179,7 +168,7 @@ inline Vector<INTSXP> WalkerSample(const Vector<REALSXP>& p, int n, int nans, bo
179
168
}
180
169
}
181
170
182
- if (H >= HL && L < HL + n) {
171
+ if (H >= HL. begin () && L < HL. begin () + n) {
183
172
for (k = 0 ; k < n - 1 ; k++) {
184
173
i = HL[k];
185
174
j = *L;
@@ -188,7 +177,7 @@ inline Vector<INTSXP> WalkerSample(const Vector<REALSXP>& p, int n, int nans, bo
188
177
189
178
L += (q[j] < 1.0 );
190
179
191
- if (L >= HL + n) {
180
+ if (L >= HL. begin () + n) {
192
181
break ;
193
182
}
194
183
}
@@ -204,11 +193,6 @@ inline Vector<INTSXP> WalkerSample(const Vector<REALSXP>& p, int n, int nans, bo
204
193
ans[i] = (rU < q[k]) ? k + adj : a[k] + adj;
205
194
}
206
195
207
- if (n > SMALL) {
208
- Free (HL);
209
- Free (q);
210
- }
211
-
212
196
return ans;
213
197
}
214
198
@@ -221,20 +205,14 @@ inline Vector<RTYPE> WalkerSample(const Vector<REALSXP>& p, int nans, const Vect
221
205
Vector<INTSXP> a = no_init (n);
222
206
Vector<RTYPE> ans = no_init (nans);
223
207
224
- double *q, rU;
225
208
int i, j, k;
226
- int *HL, *H, *L;
227
-
228
- if (n <= SMALL) {
229
- R_CheckStack2 (n * (sizeof (int ) + sizeof (double )));
230
- HL = static_cast <int *>(::alloca (n * sizeof (int )));
231
- q = static_cast <double *>(::alloca (n * sizeof (double )));
232
- } else {
233
- HL = static_cast <int *>(Calloc (n, int ));
234
- q = static_cast <double *>(Calloc (n, double ));
235
- }
209
+ std::vector<double > q (n);
210
+ double rU;
211
+
212
+ std::vector<int > HL (n);
213
+ std::vector<int >::iterator H, L;
236
214
237
- H = HL - 1 ; L = HL + n;
215
+ H = HL. begin () - 1 ; L = HL. begin () + n;
238
216
for (i = 0 ; i < n; i++) {
239
217
q[i] = p[i] * n;
240
218
if (q[i] < 1.0 ) {
@@ -244,7 +222,7 @@ inline Vector<RTYPE> WalkerSample(const Vector<REALSXP>& p, int nans, const Vect
244
222
}
245
223
}
246
224
247
- if (H >= HL && L < HL + n) {
225
+ if (H >= HL. begin () && L < HL. begin () + n) {
248
226
for (k = 0 ; k < n - 1 ; k++) {
249
227
i = HL[k];
250
228
j = *L;
@@ -253,7 +231,7 @@ inline Vector<RTYPE> WalkerSample(const Vector<REALSXP>& p, int nans, const Vect
253
231
254
232
L += (q[j] < 1.0 );
255
233
256
- if (L >= HL + n) {
234
+ if (L >= HL. begin () + n) {
257
235
break ;
258
236
}
259
237
}
@@ -269,14 +247,8 @@ inline Vector<RTYPE> WalkerSample(const Vector<REALSXP>& p, int nans, const Vect
269
247
ans[i] = (rU < q[k]) ? ref[k] : ref[a[k]];
270
248
}
271
249
272
- if (n > SMALL) {
273
- Free (HL);
274
- Free (q);
275
- }
276
-
277
250
return ans;
278
251
}
279
- #undef SMALL
280
252
281
253
// Adapted from `ProbSampleNoReplace`
282
254
// Index version
@@ -425,7 +397,7 @@ typedef Nullable< Vector<REALSXP> > probs_t;
425
397
} // sugar
426
398
427
399
// Adapted from `do_sample`
428
- inline Vector<INTSXP>
400
+ inline Vector<INTSXP>
429
401
sample (int n, int size, bool replace = false , sugar::probs_t probs = R_NilValue, bool one_based = true )
430
402
{
431
403
if (probs.isNotNull ()) {
@@ -461,7 +433,7 @@ sample(int n, int size, bool replace = false, sugar::probs_t probs = R_NilValue,
461
433
}
462
434
463
435
template <int RTYPE>
464
- inline Vector<RTYPE>
436
+ inline Vector<RTYPE>
465
437
sample (const Vector<RTYPE>& x, int size, bool replace = false , sugar::probs_t probs = R_NilValue)
466
438
{
467
439
int n = x.size ();
0 commit comments