@@ -53,7 +53,8 @@ template <class T> inline auto interquartile_range(T &v)
5353
5454template <class T > inline auto calc_stats (const T &data)
5555{
56- using vec_fp_t = std::vector<double >;
56+ using fp_t = double ;
57+ using vec_fp_t = std::vector<fp_t >;
5758 using duration_t = typename T::value_type;
5859 using ratio_t = typename duration_t ::period;
5960 using boost::copy;
@@ -71,27 +72,35 @@ template <class T> inline auto calc_stats(const T &data)
7172 using workaround::interquartile_range;
7273#endif
7374
74- constexpr double nscale = ratio_t ::num;
75- constexpr double dscale = ratio_t ::den;
75+ const auto n = data.size ();
76+ constexpr fp_t nscale = ratio_t ::num;
77+ constexpr fp_t dscale = ratio_t ::den;
7678
77- vec_fp_t fp_data (data. size () );
78- copy (data | transformed ([nscale, dscale](auto & &x) {
79+ vec_fp_t fp_data (n );
80+ copy (data | transformed ([nscale, dscale](const auto &x) {
7981 return x.count () * nscale / dscale;
8082 }),
8183 fp_data.begin ());
82- if (data.size () < 2 ) {
83- const auto point = fp_data.size ()
84- ? fp_data[0 ]
85- : std::numeric_limits<double >::quiet_NaN ();
86- return std::make_tuple (point, std::numeric_limits<double >::quiet_NaN (),
87- point, std::numeric_limits<double >::quiet_NaN (),
88- std::numeric_limits<double >::quiet_NaN ());
84+ if (n < 2 ) {
85+ if (n == 0 ) {
86+ return std::make_tuple (std::numeric_limits<fp_t >::quiet_NaN (),
87+ std::numeric_limits<fp_t >::quiet_NaN (),
88+ std::numeric_limits<fp_t >::quiet_NaN (),
89+ std::numeric_limits<fp_t >::quiet_NaN (),
90+ std::numeric_limits<fp_t >::quiet_NaN ());
91+ } else {
92+ return std::make_tuple (
93+ fp_data[0 ], std::numeric_limits<fp_t >::quiet_NaN (), fp_data[0 ],
94+ std::numeric_limits<fp_t >::quiet_NaN (),
95+ std::numeric_limits<fp_t >::quiet_NaN ());
96+ }
97+ } else {
98+ const auto [smean, uvar] = mean_and_sample_variance (fp_data);
99+ const auto smedian = median (fp_data);
100+ const auto smad = median_absolute_deviation (fp_data, smedian);
101+ const auto siqr = interquartile_range (fp_data);
102+ return std::make_tuple (smean, uvar, smedian, smad, siqr);
89103 }
90- const auto [smean, uvar] = mean_and_sample_variance (fp_data);
91- const auto smedian = median (fp_data);
92- const auto smad = median_absolute_deviation (fp_data, smedian);
93- const auto siqr = interquartile_range (fp_data);
94- return std::make_tuple (smean, uvar, smedian, smad, siqr);
95104}
96105
97106/* *
0 commit comments