diff --git a/ChangeLog b/ChangeLog index 1cb8afd8a..e6a2a39aa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2014-12-30 Dirk Eddelbuettel + + * inst/include/Rcpp/sugar/functions/mean.h: Use two-pass method + 2014-12-29 Kevin Ushey * inst/include/Rcpp/macros/macros.h: reformat for legibility diff --git a/DESCRIPTION b/DESCRIPTION index 5238ca73b..5d59869bc 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: Rcpp Title: Seamless R and C++ Integration -Version: 0.11.3.3 -Date: 2014-11-30 +Version: 0.11.3.5 +Date: 2014-12-30 Author: Dirk Eddelbuettel, Romain Francois, JJ Allaire, Kevin Ushey, Douglas Bates, and John Chambers Maintainer: Dirk Eddelbuettel diff --git a/inst/NEWS.Rd b/inst/NEWS.Rd index cd12ca53d..657eb2fa2 100644 --- a/inst/NEWS.Rd +++ b/inst/NEWS.Rd @@ -20,6 +20,7 @@ \code{List}, \code{RawVector} and \code{ExpressionVector}. \item Vectors now have a \code{Vector::const\_iterator} that is 'const correct' thanks to fix by Romain following bug report in rcpp-devel by Martyn Plummer + \item The \code{mean()} sugar function now uses a more robust two-pass method. } \item Changes in Rcpp Attributes: \itemize{ diff --git a/inst/include/Rcpp/sugar/functions/mean.h b/inst/include/Rcpp/sugar/functions/mean.h index b8d0cbf3c..a418883c9 100644 --- a/inst/include/Rcpp/sugar/functions/mean.h +++ b/inst/include/Rcpp/sugar/functions/mean.h @@ -2,7 +2,7 @@ // // mean.h: Rcpp R/C++ interface class library -- mean // -// Copyright (C) 2011 Dirk Eddelbuettel and Romain Francois +// Copyright (C) 2011 - 2014 Dirk Eddelbuettel and Romain Francois // // This file is part of Rcpp. // @@ -28,23 +28,36 @@ namespace sugar{ template class Mean : public Lazy< typename Rcpp::traits::storage_type::type , Mean > { public: - typedef typename Rcpp::VectorBase VEC_TYPE ; - typedef typename Rcpp::traits::storage_type::type STORAGE ; + typedef typename Rcpp::VectorBase VEC_TYPE ; + typedef typename Rcpp::traits::storage_type::type STORAGE ; - Mean( const VEC_TYPE& object_ ) : object(object_){} + Mean( const VEC_TYPE& object_ ) : object(object_){} - STORAGE get() const { - return sum(object).get() / object.size() ; - } + STORAGE get() const { + //return sum(object).get() / object.size() ; + NumericVector input = object; + + int n = input.size(); // double pass (as in summary.c) + long double s = std::accumulate(input.begin(), input.end(), 0.0L); + s /= n; + if (R_FINITE((double)s)) { + long double t = 0.0; + for (int i = 0; i < n; i++) { + t += input[i] - s; + } + s += t/n; + } + return (double)s ; + } private: - const VEC_TYPE& object ; + const VEC_TYPE& object ; } ; } // sugar template inline sugar::Mean mean( const VectorBase& t){ - return sugar::Mean( t ) ; + return sugar::Mean( t ) ; }