Rcpp Version 1.0.14
Loading...
Searching...
No Matches
algorithm.h
Go to the documentation of this file.
1// -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; indent-tabs-mode: nil; -*-
2//
3// algorithm.h: Rcpp R/C++ interface class library -- data frames
4//
5// Copyright (C) 2016 - 2017 Daniel C. Dillon
6//
7// This file is part of Rcpp.
8//
9// Rcpp is free software: you can redistribute it and/or modify it
10// under the terms of the GNU General Public License as published by
11// the Free Software Foundation, either version 2 of the License, or
12// (at your option) any later version.
13//
14// Rcpp is distributed in the hope that it will be useful, but
15// WITHOUT ANY WARRANTY; without even the implied warranty of
16// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17// GNU General Public License for more details.
18//
19// You should have received a copy of the GNU General Public License
20// along with Rcpp. If not, see <http://www.gnu.org/licenses/>.
21
22#ifndef Rcpp__Algorithm_h
23#define Rcpp__Algorithm_h
24
25#if __cplusplus >= 201103L || __INTEL_CXX11_MODE__ == 1
26# define RCPP_CONSTEXPR_FUNC constexpr
27# define RCPP_CONSTEXPR_VAR constexpr
28#else
29# define RCPP_CONSTEXPR_FUNC
30# define RCPP_CONSTEXPR_VAR const
31#endif
32
33namespace Rcpp {
34namespace algorithm {
35
36namespace helpers {
37 typedef struct {char a[1];} CTYPE_CHAR;
38 typedef struct {char a[2];} CTYPE_SHORT;
39 typedef struct {char a[3];} CTYPE_INT;
40 typedef struct {char a[4];} CTYPE_LONG;
41#ifdef RCPP_HAS_LONG_LONG_TYPES
42 typedef struct {char a[5];} CTYPE_LONG_LONG;
43#endif
44 typedef struct {char a[6];} CTYPE_FLOAT;
45 typedef struct {char a[7];} CTYPE_DOUBLE;
46 typedef struct {char a[8];} CTYPE_LONG_DOUBLE;
47 typedef struct {char a[9];} CTYPE_STRING;
48 typedef struct {char a[10];} CTYPE_UNSIGNED_CHAR;
49 typedef struct {char a[11];} CTYPE_UNSIGNED_SHORT;
50 typedef struct {char a[12];} CTYPE_UNSIGNED_INT;
51 typedef struct {char a[13];} CTYPE_UNSIGNED_LONG;
52#ifdef RCPP_HAS_LONG_LONG_TYPES
53 typedef struct {char a[14];} CTYPE_UNSIGNED_LONG_LONG;
54#endif
55 typedef struct {char a[128];} CTYPE_UNKNOWN;
56
57 template< std::size_t I >
58 struct ctype_helper { static const bool value = false; };
59
60 template<>
61 struct ctype_helper< sizeof(CTYPE_CHAR) > { typedef char type; static const bool value = true; };
62
63 template<>
64 struct ctype_helper< sizeof(CTYPE_SHORT) > { typedef short type; static const bool value = true; };
65
66 template<>
67 struct ctype_helper< sizeof(CTYPE_INT) > { typedef int type; static const bool value = true; };
68
69 template<>
70 struct ctype_helper< sizeof(CTYPE_LONG) > { typedef long type; static const bool value = true; };
71
72#ifdef RCPP_HAS_LONG_LONG_TYPES
73 template<>
74 struct ctype_helper< sizeof(CTYPE_LONG_LONG) > { typedef rcpp_long_long_type type; static const bool value = true; };
75#endif
76
77 template<>
78 struct ctype_helper< sizeof(CTYPE_FLOAT) > { typedef float type; static const bool value = true; };
79
80 template<>
81 struct ctype_helper< sizeof(CTYPE_DOUBLE) > { typedef double type; static const bool value = true; };
82
83 template<>
84 struct ctype_helper< sizeof(CTYPE_LONG_DOUBLE) > { typedef long double type; static const bool value = true; };
85
86 template<>
87 struct ctype_helper< sizeof(CTYPE_STRING) > { typedef std::string type; static const bool value = true; };
88
89 template<>
90 struct ctype_helper< sizeof(CTYPE_UNSIGNED_CHAR) > { typedef unsigned char type; static const bool value = true; };
91
92 template<>
93 struct ctype_helper< sizeof(CTYPE_UNSIGNED_SHORT) > { typedef unsigned short type; static const bool value = true; };
94
95 template<>
96 struct ctype_helper< sizeof(CTYPE_UNSIGNED_INT) > { typedef unsigned int type; static const bool value = true; };
97
98 template<>
99 struct ctype_helper< sizeof(CTYPE_UNSIGNED_LONG) > { typedef unsigned long type; static const bool value = true; };
100
101#ifdef RCPP_HAS_LONG_LONG_TYPES
102 template<>
103 struct ctype_helper< sizeof(CTYPE_UNSIGNED_LONG_LONG) > { typedef rcpp_ulong_long_type type; static const bool value = true; };
104#endif
105
106
107 template< typename T >
108 struct ctype
109 {
110 static CTYPE_CHAR test(const char &);
111 static CTYPE_SHORT test(const short &);
112 static CTYPE_INT test(const int &);
113 static CTYPE_LONG test(const long &);
114#ifdef RCPP_HAS_LONG_LONG_TYPES
116#endif
117 static CTYPE_FLOAT test(const float &);
118 static CTYPE_DOUBLE test(const double &);
119 static CTYPE_LONG_DOUBLE test(const long double &);
120 static CTYPE_STRING test(const std::string &);
121 static CTYPE_UNSIGNED_CHAR test(const unsigned char &);
122 static CTYPE_UNSIGNED_SHORT test(const unsigned short &);
123 static CTYPE_UNSIGNED_INT test(const unsigned int &);
124 static CTYPE_UNSIGNED_LONG test(const unsigned long &);
125#ifdef RCPP_HAS_LONG_LONG_TYPES
127#endif
128 static CTYPE_UNKNOWN test(...);
129
130 static T make();
131
132 typedef typename ctype_helper< sizeof(test(make())) >::type type;
133 };
134
135 template< typename T >
137 {
138 static CTYPE_CHAR test(const char &);
139 static CTYPE_SHORT test(const short &);
140 static CTYPE_INT test(const int &);
141 static CTYPE_LONG test(const long &);
142#ifdef RCPP_HAS_LONG_LONG_TYPES
144#endif
145 static CTYPE_FLOAT test(const float &);
146 static CTYPE_DOUBLE test(const double &);
147 static CTYPE_LONG_DOUBLE test(const long double &);
148 static CTYPE_STRING test(const std::string &);
149 static CTYPE_UNSIGNED_CHAR test(const unsigned char &);
150 static CTYPE_UNSIGNED_SHORT test(const unsigned short &);
151 static CTYPE_UNSIGNED_INT test(const unsigned int &);
152 static CTYPE_UNSIGNED_LONG test(const unsigned long &);
153#ifdef RCPP_HAS_LONG_LONG_TYPES
155#endif
156 static CTYPE_UNKNOWN test(...);
157
158 static T make();
159
160 static const bool value = ctype_helper< sizeof(test(make())) >::value;
161 };
162
163 template< typename T >
165 };
166
167 template<>
169 typedef double type;
170 static RCPP_CONSTEXPR_VAR int RTYPE = REALSXP;
171 static inline double NA() { return NA_REAL; }
172 static inline RCPP_CONSTEXPR_FUNC double ZERO() { return 0.0; }
173 static inline RCPP_CONSTEXPR_FUNC double ONE() { return 1.0; }
174 };
175
176 template<>
177 struct rtype_helper< int > {
178 typedef int type;
179 static RCPP_CONSTEXPR_VAR int RTYPE = INTSXP;
180 static inline int NA() { return NA_INTEGER; }
181 static inline RCPP_CONSTEXPR_FUNC int ZERO() { return 0; }
182 static inline RCPP_CONSTEXPR_FUNC int ONE() { return 1; }
183 };
184
185 template< typename T >
186 struct rtype {
189 static RCPP_CONSTEXPR_VAR int RTYPE = helper_type::RTYPE;
190 static inline T NA() { return helper_type::NA(); }
191 static inline RCPP_CONSTEXPR_FUNC T ZERO() { return helper_type::ZERO(); }
192 static inline RCPP_CONSTEXPR_FUNC T ONE() { return helper_type::ONE(); }
193 };
194
195 struct log {
196 template< typename T >
197 inline double operator()(T val) {
199 return std::log(val);
200 }
201
202 return rtype< double >::NA();
203 }
204 };
205
206 struct exp {
207 template< typename T >
208 inline double operator()(T val) {
210 return std::exp(val);
211 }
212
213 return rtype< double >::NA();
214 }
215 };
216
217 struct sqrt {
218 template< typename T >
219 inline double operator()(T val) {
221 return std::sqrt(val);
222 }
223
224 return rtype< double >::NA();
225 }
226 };
227} // namespace helpers
228
229template< typename InputIterator >
231 typename helpers::ctype< typename std::iterator_traits< InputIterator >::value_type >::type >::type
233
235 typedef typename helpers::rtype< value_type > rtype;
236
237 if (begin != end) {
238 value_type start = rtype::ZERO();
239
240 while (begin != end) {
241 if (!Vector< rtype::RTYPE >::is_na(*begin)) {
242 start += *begin++;
243 } else {
244 return rtype::NA();
245 }
246 }
247
248 return start;
249 }
250
251 return rtype::ZERO();
252}
253
254template< typename InputIterator >
256 typename helpers::ctype< typename std::iterator_traits< InputIterator >::value_type >::type >::type
258
260 typedef typename helpers::rtype< value_type > rtype;
261
262 if (begin != end) {
263 value_type start = rtype::ZERO();
264
265 while (begin != end) {
266 start += *begin++;
267 }
268
269 return start;
270 }
271
272 return rtype::ZERO();
273}
274
275template< typename InputIterator >
277 typename helpers::ctype< typename std::iterator_traits< InputIterator >::value_type >::type >::type
279
281 typedef typename helpers::rtype< value_type > rtype;
282
283 if (begin != end) {
284 value_type start = rtype::ONE();
285
286 while (begin != end) {
287 if (!Vector< rtype::RTYPE >::is_na(*begin)) {
288 start *= *begin++;
289 } else {
290 return rtype::NA();
291 }
292 }
293
294 return start;
295 }
296
297 return rtype::ONE();
298}
299
300template< typename InputIterator >
302 typename helpers::ctype< typename std::iterator_traits< InputIterator >::value_type >::type >::type
304
306 typedef typename helpers::rtype< value_type > rtype;
307
308 if (begin != end) {
309 value_type start = rtype::ONE();
310
311 while (begin != end) {
312 start *= *begin++;
313 }
314
315 return start;
316 }
317
318 return rtype::ONE();
319}
320
321template< typename InputIterator >
323 typename helpers::ctype< typename std::iterator_traits< InputIterator >::value_type >::type >::type
325
327 typedef typename helpers::rtype< value_type > rtype;
328
329 if (begin != end) {
330 value_type max = *begin;
331
332 while (begin != end) {
333 if (!Vector< rtype::RTYPE >::is_na(*begin)) {
334 max = std::max(max, *begin++);
335 } else {
336 return rtype::NA();
337 }
338 }
339
340 return max;
341 }
342
343 return std::numeric_limits< typename rtype::type >::infinity() * -rtype::ONE();
344}
345
346template< typename InputIterator >
348 typename helpers::ctype< typename std::iterator_traits< InputIterator >::value_type >::type >::type
350
352 typedef typename helpers::rtype< value_type > rtype;
353
354 if (begin != end) {
355 value_type max = *begin;
356
357 while (begin != end) {
358 max = std::max(max, *begin++);
359 }
360
361 return max;
362 }
363
364 return std::numeric_limits< typename rtype::type >::infinity() * -rtype::ONE();
365}
366
367template< typename InputIterator >
369 typename helpers::ctype< typename std::iterator_traits< InputIterator >::value_type >::type >::type
371
373 typedef typename helpers::rtype< value_type > rtype;
374
375 if (begin != end) {
376 value_type min = *begin;
377
378 while (begin != end) {
379 if (!Vector< rtype::RTYPE >::is_na(*begin)) {
380 min = std::min(min, *begin++);
381 } else {
382 return rtype::NA();
383 }
384 }
385
386 return min;
387 }
388
389 return std::numeric_limits< typename rtype::type >::infinity();
390}
391
392template< typename InputIterator >
394 typename helpers::ctype< typename std::iterator_traits< InputIterator >::value_type >::type >::type
396
398 typedef typename helpers::rtype< value_type > rtype;
399
400 if (begin != end) {
401 value_type min = *begin;
402
403 while (begin != end) {
404 min = std::min(min, *begin++);
405 }
406
407 return min;
408 }
409
410 return std::numeric_limits< typename rtype::type >::infinity();
411}
412
413// for REALSXP
414template< typename InputIterator >
418{
419 if (begin != end)
420 {
421 std::size_t n = end - begin;
422 long double s = std::accumulate(begin, end, 0.0L);
423 s /= n;
424
425 if (R_FINITE((double) s)) {
426 long double t = 0.0L;
427 while (begin != end) {
428 t += *begin++ - s;
429 }
430
431 s += t / n;
432 }
433
434 return (double) s;
435 }
436
438}
439
440// for LGLSXP and INTSXP
441template< typename InputIterator >
445{
446 if (begin != end)
447 {
448 std::size_t n = end - begin;
449 long double s = std::accumulate(begin, end, 0.0L);
450 s /= n;
451
452 if (R_FINITE((double) s)) {
453 long double t = 0.0L;
454 while (begin != end) {
456 t += *begin++ - s;
457 }
458
459 s += t / n;
460 }
461
462 return (double) s;
463 }
464
466}
467
468template< typename InputIterator, typename OutputIterator >
470 std::transform(begin, end, out, helpers::log());
471}
472
473template< typename InputIterator, typename OutputIterator >
475 std::transform(begin, end, out, helpers::exp());
476}
477
478template< typename InputIterator, typename OutputIterator >
480 std::transform(begin, end, out, helpers::sqrt());
481}
482
483} // namespace algorithm
484} // namespace Rcpp
485
486#undef RCPP_CONSTEXPR_FUNC
487#undef RCPP_CONSTEXPR_VAR
488
489#endif
#define RCPP_CONSTEXPR_VAR
Definition algorithm.h:30
#define RCPP_CONSTEXPR_FUNC
Definition algorithm.h:29
void exp(InputIterator begin, InputIterator end, OutputIterator out)
Definition algorithm.h:474
traits::enable_if< helpers::decays_to_ctype< typenamestd::iterator_traits< InputIterator >::value_type >::value, typenamehelpers::ctype< typenamestd::iterator_traits< InputIterator >::value_type >::type >::type max_nona(InputIterator begin, InputIterator end)
Definition algorithm.h:349
traits::enable_if< helpers::decays_to_ctype< typenamestd::iterator_traits< InputIterator >::value_type >::value &&traits::same_type< typenamehelpers::ctype< typenamestd::iterator_traits< InputIterator >::value_type >::type, double >::value, double >::type mean(InputIterator begin, InputIterator end)
Definition algorithm.h:417
traits::enable_if< helpers::decays_to_ctype< typenamestd::iterator_traits< InputIterator >::value_type >::value, typenamehelpers::ctype< typenamestd::iterator_traits< InputIterator >::value_type >::type >::type sum(InputIterator begin, InputIterator end)
Definition algorithm.h:232
traits::enable_if< helpers::decays_to_ctype< typenamestd::iterator_traits< InputIterator >::value_type >::value, typenamehelpers::ctype< typenamestd::iterator_traits< InputIterator >::value_type >::type >::type prod(InputIterator begin, InputIterator end)
Definition algorithm.h:278
void log(InputIterator begin, InputIterator end, OutputIterator out)
Definition algorithm.h:469
void sqrt(InputIterator begin, InputIterator end, OutputIterator out)
Definition algorithm.h:479
traits::enable_if< helpers::decays_to_ctype< typenamestd::iterator_traits< InputIterator >::value_type >::value, typenamehelpers::ctype< typenamestd::iterator_traits< InputIterator >::value_type >::type >::type max(InputIterator begin, InputIterator end)
Definition algorithm.h:324
traits::enable_if< helpers::decays_to_ctype< typenamestd::iterator_traits< InputIterator >::value_type >::value, typenamehelpers::ctype< typenamestd::iterator_traits< InputIterator >::value_type >::type >::type min(InputIterator begin, InputIterator end)
Definition algorithm.h:370
traits::enable_if< helpers::decays_to_ctype< typenamestd::iterator_traits< InputIterator >::value_type >::value, typenamehelpers::ctype< typenamestd::iterator_traits< InputIterator >::value_type >::type >::type sum_nona(InputIterator begin, InputIterator end)
Definition algorithm.h:257
traits::enable_if< helpers::decays_to_ctype< typenamestd::iterator_traits< InputIterator >::value_type >::value, typenamehelpers::ctype< typenamestd::iterator_traits< InputIterator >::value_type >::type >::type prod_nona(InputIterator begin, InputIterator end)
Definition algorithm.h:303
traits::enable_if< helpers::decays_to_ctype< typenamestd::iterator_traits< InputIterator >::value_type >::value, typenamehelpers::ctype< typenamestd::iterator_traits< InputIterator >::value_type >::type >::type min_nona(InputIterator begin, InputIterator end)
Definition algorithm.h:395
Rcpp API.
Definition algo.h:28
sugar::IsNa< RTYPE, NA, T > is_na(const Rcpp::VectorBase< RTYPE, NA, T > &t)
Definition is_na.h:91
T as(SEXP x)
Definition as.h:151
static CTYPE_STRING test(const std::string &)
static CTYPE_LONG test(const long &)
static CTYPE_CHAR test(const char &)
static CTYPE_UNSIGNED_INT test(const unsigned int &)
static CTYPE_INT test(const int &)
static CTYPE_UNSIGNED_SHORT test(const unsigned short &)
static CTYPE_UNSIGNED_CHAR test(const unsigned char &)
static CTYPE_SHORT test(const short &)
static CTYPE_UNKNOWN test(...)
ctype_helper< sizeof(test(make()))>::type type
Definition algorithm.h:132
static CTYPE_DOUBLE test(const double &)
static CTYPE_FLOAT test(const float &)
static CTYPE_UNSIGNED_LONG test(const unsigned long &)
static CTYPE_LONG_DOUBLE test(const long double &)
static CTYPE_CHAR test(const char &)
static CTYPE_FLOAT test(const float &)
static CTYPE_UNSIGNED_LONG test(const unsigned long &)
static CTYPE_SHORT test(const short &)
static CTYPE_UNSIGNED_INT test(const unsigned int &)
static CTYPE_UNSIGNED_CHAR test(const unsigned char &)
static CTYPE_DOUBLE test(const double &)
static CTYPE_LONG_DOUBLE test(const long double &)
static CTYPE_STRING test(const std::string &)
static CTYPE_INT test(const int &)
static CTYPE_LONG test(const long &)
static CTYPE_UNSIGNED_SHORT test(const unsigned short &)
static RCPP_CONSTEXPR_FUNC double ZERO()
Definition algorithm.h:172
static RCPP_CONSTEXPR_FUNC double ONE()
Definition algorithm.h:173
static RCPP_CONSTEXPR_FUNC int ZERO()
Definition algorithm.h:181
static RCPP_CONSTEXPR_FUNC int ONE()
Definition algorithm.h:182
static RCPP_CONSTEXPR_VAR int RTYPE
Definition algorithm.h:189
rtype_helper< typename ctype< T >::type > helper_type
Definition algorithm.h:188
static RCPP_CONSTEXPR_FUNC T ONE()
Definition algorithm.h:192
static RCPP_CONSTEXPR_FUNC T ZERO()
Definition algorithm.h:191
rtype_helper< typenamectype< T >::type >::type type
Definition algorithm.h:187