Skip to content

Commit 8cc3564

Browse files
author
Daniel C. Dillon
committed
Added Rcpp::algorithm::mean
1 parent 5dc11ac commit 8cc3564

File tree

3 files changed

+98
-0
lines changed

3 files changed

+98
-0
lines changed

inst/include/Rcpp/algorithm.h

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,59 @@ typename std::iterator_traits< InputIterator >::value_type min_nona(InputIterato
245245
return std::numeric_limits< typename rtype::type >::infinity();
246246
}
247247

248+
// for REALSXP
249+
template< typename InputIterator >
250+
typename traits::enable_if< traits::same_type< typename std::iterator_traits< InputIterator >::value_type, double >::value, double >::type
251+
mean(InputIterator begin, InputIterator end)
252+
{
253+
if (begin != end)
254+
{
255+
std::size_t n = end - begin;
256+
long double s = std::accumulate(begin, end, 0.0L);
257+
s /= n;
258+
259+
if (R_FINITE((double) s)) {
260+
long double t = 0.0L;
261+
while (begin != end) {
262+
t += *begin++ - s;
263+
}
264+
265+
s += t / n;
266+
}
267+
268+
return (double) s;
269+
}
270+
271+
return helpers::rtype< double >::NA();
272+
}
273+
274+
// for LGLSXP and INTSXP
275+
template< typename InputIterator >
276+
typename traits::enable_if< traits::same_type< typename std::iterator_traits< InputIterator >::value_type, int >::value, double >::type
277+
mean(InputIterator begin, InputIterator end)
278+
{
279+
if (begin != end)
280+
{
281+
std::size_t n = end - begin;
282+
long double s = std::accumulate(begin, end, 0.0L);
283+
s /= n;
284+
285+
if (R_FINITE((double) s)) {
286+
long double t = 0.0L;
287+
while (begin != end) {
288+
if (*begin == helpers::rtype< int >::NA()) return helpers::rtype< double >::NA();
289+
t += *begin++ - s;
290+
}
291+
292+
s += t / n;
293+
}
294+
295+
return (double) s;
296+
}
297+
298+
return helpers::rtype< double >::NA();
299+
}
300+
248301
template< typename InputIterator, typename OutputIterator >
249302
void log(InputIterator begin, InputIterator end, OutputIterator out) {
250303
std::transform(begin, end, out, helpers::log());

inst/unitTests/cpp/algorithm.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,3 +80,18 @@ int minTest_int_nona(Rcpp::IntegerVector v) {
8080
int maxTest_int_nona(Rcpp::IntegerVector v) {
8181
return Rcpp::algorithm::max_nona(v.begin(), v.end());
8282
}
83+
84+
// [[Rcpp::export]]
85+
double meanTest(Rcpp::NumericVector v) {
86+
return Rcpp::algorithm::mean(v.begin(), v.end());
87+
}
88+
89+
// [[Rcpp::export]]
90+
double meanTest_int(Rcpp::IntegerVector v) {
91+
return Rcpp::algorithm::mean(v.begin(), v.end());
92+
}
93+
94+
// [[Rcpp::export]]
95+
double meanTest_logical(Rcpp::LogicalVector v) {
96+
return Rcpp::algorithm::mean(v.begin(), v.end());
97+
}

inst/unitTests/runit.algorithm.R

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,4 +115,34 @@ if (.runThisTest) {
115115
v <- c(1, 2, 3, 4, 5)
116116
checkEquals(max(v), maxTest_int_nona(v))
117117
}
118+
119+
test.mean <- function() {
120+
v <- c(1.0, 2.0, 3.0, 4.0, 5.0)
121+
checkEquals(mean(v), meanTest(v))
122+
v <- c(1.0, 2.0, 3.0, 4.0, NA)
123+
checkEquals(mean(v), meanTest(v))
124+
v <- c(1.0, 2.0, 3.0, 4.0, NaN)
125+
checkEquals(mean(v), meanTest(v))
126+
v <- c(1.0, 2.0, 3.0, 4.0, 1.0/0.0)
127+
checkEquals(mean(v), meanTest(v))
128+
v <- c(1.0, 2.0, 3.0, 4.0, -1.0/0.0)
129+
checkEquals(mean(v), meanTest(v))
130+
v <- c(1.0, 2.0, 1.0/0.0, NA, NaN)
131+
checkEquals(mean(v), meanTest(v))
132+
v <- c(1.0, 2.0, 1.0/0.0, NaN, NA)
133+
}
134+
135+
test.mean.int <- function() {
136+
v <- c(1, 2, 3, 4, 5)
137+
checkEquals(mean(v), meanTest_int(v))
138+
v <- c(1, 2, 3, 4, NA)
139+
checkEquals(mean(v), meanTest_int(v))
140+
}
141+
142+
test.mean.logical <- function() {
143+
v <- c(TRUE, FALSE, FALSE)
144+
checkEquals(mean(v), meanTest_logical(v))
145+
v <- c(TRUE, FALSE, FALSE, NA)
146+
checkEquals(mean(v), meanTest_logical(v))
147+
}
118148
}

0 commit comments

Comments
 (0)