Skip to content

Commit 61fff70

Browse files
author
Daniel C. Dillon
committed
Added algorithm min/max and fixed unit tests
1 parent b0bfc65 commit 61fff70

File tree

3 files changed

+207
-3
lines changed

3 files changed

+207
-3
lines changed

inst/include/Rcpp/algorithm.h

Lines changed: 88 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,18 @@ namespace algorithm {
1010
namespace helpers {
1111
template< typename T >
1212
struct rtype_helper {
13+
/*
14+
typedef T type;
1315
static RCPP_CONSTEXPR int RTYPE = REALSXP;
1416
static inline double NA() { return NA_REAL; }
1517
static inline RCPP_CONSTEXPR double ZERO() { return 0.0; }
1618
static inline RCPP_CONSTEXPR double ONE() { return 1.0; }
19+
*/
1720
};
1821

1922
template<>
2023
struct rtype_helper< double > {
24+
typedef double type;
2125
static RCPP_CONSTEXPR int RTYPE = REALSXP;
2226
static inline double NA() { return NA_REAL; }
2327
static inline RCPP_CONSTEXPR double ZERO() { return 0.0; }
@@ -26,6 +30,7 @@ namespace helpers {
2630

2731
template<>
2832
struct rtype_helper< int > {
33+
typedef int type;
2934
static RCPP_CONSTEXPR int RTYPE = INTSXP;
3035
static inline int NA() { return NA_INTEGER; }
3136
static inline RCPP_CONSTEXPR int ZERO() { return 0; }
@@ -34,6 +39,7 @@ namespace helpers {
3439

3540
template< typename T >
3641
struct rtype {
42+
typedef typename rtype_helper< typename traits::remove_const_and_reference< T >::type >::type type;
3743
static RCPP_CONSTEXPR int RTYPE =
3844
rtype_helper< typename traits::remove_const_and_reference< T >::type >::RTYPE;
3945
static inline T NA() { return rtype_helper< typename traits::remove_const_and_reference< T >::type >::NA(); }
@@ -137,7 +143,7 @@ typename std::iterator_traits< InputIterator >::value_type prod(InputIterator be
137143
return start;
138144
}
139145

140-
return rtype::ZERO();
146+
return rtype::ONE();
141147
}
142148

143149
template< typename InputIterator >
@@ -156,7 +162,87 @@ typename std::iterator_traits< InputIterator >::value_type prod_nona(InputIterat
156162
return start;
157163
}
158164

159-
return rtype::ZERO();
165+
return rtype::ONE();
166+
}
167+
168+
template< typename InputIterator >
169+
typename std::iterator_traits< InputIterator >::value_type max(InputIterator begin, InputIterator end) {
170+
typedef typename std::iterator_traits< InputIterator >::value_type value_type;
171+
typedef typename helpers::rtype< value_type > rtype;
172+
173+
if (begin != end) {
174+
value_type max = *begin;
175+
176+
while (begin != end) {
177+
if (!Vector< rtype::RTYPE >::is_na(*begin)) {
178+
max = std::max(max, *begin++);
179+
} else {
180+
return rtype::NA();
181+
}
182+
}
183+
184+
return max;
185+
}
186+
187+
return std::numeric_limits< typename rtype::type >::infinity() * -rtype::ONE();
188+
}
189+
190+
template< typename InputIterator >
191+
typename std::iterator_traits< InputIterator >::value_type max_nona(InputIterator begin, InputIterator end) {
192+
typedef typename std::iterator_traits< InputIterator >::value_type value_type;
193+
typedef typename helpers::rtype< value_type > rtype;
194+
195+
if (begin != end) {
196+
value_type max = *begin;
197+
198+
while (begin != end) {
199+
max = std::max(max, *begin++);
200+
}
201+
202+
return max;
203+
}
204+
205+
return std::numeric_limits< typename rtype::type >::infinity() * -rtype::ONE();
206+
}
207+
208+
template< typename InputIterator >
209+
typename std::iterator_traits< InputIterator >::value_type min(InputIterator begin, InputIterator end) {
210+
typedef typename std::iterator_traits< InputIterator >::value_type value_type;
211+
typedef typename helpers::rtype< value_type > rtype;
212+
213+
if (begin != end) {
214+
value_type min = *begin;
215+
216+
while (begin != end) {
217+
if (!Vector< rtype::RTYPE >::is_na(*begin)) {
218+
min = std::min(min, *begin++);
219+
} else {
220+
return rtype::NA();
221+
}
222+
}
223+
224+
return min;
225+
}
226+
227+
return std::numeric_limits< typename rtype::type >::infinity();
228+
}
229+
230+
template< typename InputIterator >
231+
typename std::iterator_traits< InputIterator >::value_type min_nona(InputIterator begin, InputIterator end) {
232+
typedef typename std::iterator_traits< InputIterator >::value_type value_type;
233+
typedef typename helpers::rtype< value_type > rtype;
234+
235+
if (begin != end) {
236+
value_type min = *begin;
237+
238+
while (begin != end) {
239+
min = std::min(min, *begin++);
240+
}
241+
242+
return min;
243+
}
244+
245+
return std::numeric_limits< typename rtype::type >::infinity();
160246
}
161247

162248
template< typename InputIterator, typename OutputIterator >

inst/unitTests/cpp/algorithm.cpp

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,21 @@ double sumTest(Rcpp::NumericVector v, int begin, int end) {
55
return Rcpp::algorithm::sum(v.begin() + (begin - 1), v.begin() + end);
66
}
77

8+
// [[Rcpp::export]]
9+
double sumTest_nona(Rcpp::NumericVector v, int begin, int end) {
10+
return Rcpp::algorithm::sum_nona(v.begin() + (begin - 1), v.begin() + end);
11+
}
12+
813
// [[Rcpp::export]]
914
double prodTest(Rcpp::NumericVector v, int begin, int end) {
1015
return Rcpp::algorithm::prod(v.begin() + (begin - 1), v.begin() + end);
1116
}
1217

18+
// [[Rcpp::export]]
19+
double prodTest_nona(Rcpp::NumericVector v, int begin, int end) {
20+
return Rcpp::algorithm::prod_nona(v.begin() + (begin - 1), v.begin() + end);
21+
}
22+
1323
// [[Rcpp::export]]
1424
Rcpp::NumericVector logTest(Rcpp::NumericVector v) {
1525
Rcpp::NumericVector x = Rcpp::clone(v);
@@ -30,3 +40,43 @@ Rcpp::NumericVector sqrtTest(Rcpp::NumericVector v) {
3040
Rcpp::algorithm::sqrt(v.begin(), v.end(), x.begin());
3141
return x;
3242
}
43+
44+
// [[Rcpp::export]]
45+
double minTest(Rcpp::NumericVector v) {
46+
return Rcpp::algorithm::min(v.begin(), v.end());
47+
}
48+
49+
// [[Rcpp::export]]
50+
double maxTest(Rcpp::NumericVector v) {
51+
return Rcpp::algorithm::max(v.begin(), v.end());
52+
}
53+
54+
// [[Rcpp::export]]
55+
double minTest_nona(Rcpp::NumericVector v) {
56+
return Rcpp::algorithm::min_nona(v.begin(), v.end());
57+
}
58+
59+
// [[Rcpp::export]]
60+
double maxTest_nona(Rcpp::NumericVector v) {
61+
return Rcpp::algorithm::max_nona(v.begin(), v.end());
62+
}
63+
64+
// [[Rcpp::export]]
65+
int minTest_int(Rcpp::IntegerVector v) {
66+
return Rcpp::algorithm::min(v.begin(), v.end());
67+
}
68+
69+
// [[Rcpp::export]]
70+
int maxTest_int(Rcpp::IntegerVector v) {
71+
return Rcpp::algorithm::max(v.begin(), v.end());
72+
}
73+
74+
// [[Rcpp::export]]
75+
int minTest_int_nona(Rcpp::IntegerVector v) {
76+
return Rcpp::algorithm::min_nona(v.begin(), v.end());
77+
}
78+
79+
// [[Rcpp::export]]
80+
int maxTest_int_nona(Rcpp::IntegerVector v) {
81+
return Rcpp::algorithm::max_nona(v.begin(), v.end());
82+
}

inst/unitTests/runit.algorithm.R

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,30 +21,98 @@
2121

2222
if (.runThisTest) {
2323

24-
.setUp <- Rcpp:::unitTestSetup("algorithms.cpp")
24+
.setUp <- Rcpp:::unitTestSetup("algorithm.cpp")
2525

2626
test.sum <- function() {
2727
v <- c(1.0, 2.0, 3.0, 4.0, 5.0)
2828
checkEquals(sum(v), sumTest(v, 1, 5))
29+
v <- c(NA, 1.0, 2.0, 3.0, 4.0)
30+
checkEquals(sum(v), sumTest(v, 1, 5))
31+
}
32+
33+
test.sum.nona <- function() {
34+
v <- c(1.0, 2.0, 3.0, 4.0, 5.0)
35+
checkEquals(sum(v), sumTest_nona(v, 1, 5))
2936
}
3037

3138
test.prod <- function() {
3239
v <- c(1.0, 2.0, 3.0, 4.0, 5.0)
3340
checkEquals(prod(v), prodTest(v, 1, 5))
41+
v <- c(NA, 1.0, 2.0, 3.0, 4.0)
42+
checkEquals(prod(v), prodTest(v, 1, 5))
43+
}
44+
45+
test.prod.nona <- function() {
46+
v <- c(1.0, 2.0, 3.0, 4.0, 5.0)
47+
checkEquals(prod(v), prodTest_nona(v, 1, 5))
3448
}
3549

3650
test.log <- function() {
3751
v <- c(1.0, 2.0, 3.0, 4.0, 5.0)
3852
checkEquals(log(v), logTest(v))
53+
v <- c(NA, 1.0, 2.0, 3.0, 4.0)
54+
checkEquals(log(v), logTest(v))
3955
}
4056

4157
test.exp <- function() {
4258
v <- c(1.0, 2.0, 3.0, 4.0, 5.0)
4359
checkEquals(exp(v), expTest(v))
60+
v <- c(NA, 1.0, 2.0, 3.0, 4.0)
61+
checkEquals(exp(v), expTest(v))
4462
}
4563

4664
test.sqrt <- function() {
4765
v <- c(1.0, 2.0, 3.0, 4.0, 5.0)
4866
checkEquals(sqrt(v), sqrtTest(v))
67+
v <- c(NA, 1.0, 2.0, 3.0, 4.0)
68+
checkEquals(sqrt(v), sqrtTest(v))
69+
}
70+
71+
test.min <- function() {
72+
v <- c(1.0, 2.0, 3.0, 4.0, 5.0)
73+
checkEquals(min(v), minTest(v))
74+
v <- c(NA, 1.0, 2.0, 3.0, 4.0)
75+
checkEquals(min(v), minTest(v))
76+
}
77+
78+
test.min.nona <- function() {
79+
v <- c(1.0, 2.0, 3.0, 4.0, 5.0)
80+
checkEquals(min(v), minTest_nona(v))
81+
}
82+
83+
test.min.int <- function() {
84+
v <- c(1, 2, 3, 4, 5)
85+
checkEquals(min(v), minTest_int(v))
86+
v <- c(NA, 1, 2, 3, 4)
87+
checkEquals(min(v), minTest_int(v))
88+
}
89+
90+
test.min.int.nona <- function() {
91+
v <- c(1, 2, 3, 4, 5)
92+
checkEquals(min(v), minTest_int_nona(v))
93+
}
94+
95+
test.max <- function() {
96+
v <- c(1.0, 2.0, 3.0, 4.0, 5.0)
97+
checkEquals(max(v), maxTest(v))
98+
v <- c(NA, 1.0, 2.0, 3.0, 4.0)
99+
checkEquals(max(v), maxTest(v))
100+
}
101+
102+
test.max.nona <- function() {
103+
v <- c(1.0, 2.0, 3.0, 4.0, 5.0)
104+
checkEquals(max(v), maxTest_nona(v))
105+
}
106+
107+
test.max.int <- function() {
108+
v <- c(1, 2, 3, 4, 5)
109+
checkEquals(max(v), maxTest_int(v))
110+
v <- c(NA, 1, 2, 3, 4)
111+
checkEquals(max(v), maxTest_int(v))
112+
}
113+
114+
test.max.int.nona <- function() {
115+
v <- c(1, 2, 3, 4, 5)
116+
checkEquals(max(v), maxTest_int_nona(v))
49117
}
50118
}

0 commit comments

Comments
 (0)