| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160 | 
							- /*
 
-  *  Created by Joachim on 16/04/2019.
 
-  *  Adapted from donated nonius code.
 
-  *
 
-  *  Distributed under the Boost Software License, Version 1.0. (See accompanying
 
-  *  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 
-  */
 
- // Statistical analysis tools
 
- #ifndef TWOBLUECUBES_CATCH_DETAIL_ANALYSIS_HPP_INCLUDED
 
- #define TWOBLUECUBES_CATCH_DETAIL_ANALYSIS_HPP_INCLUDED
 
- #include "../catch_clock.hpp"
 
- #include "../catch_estimate.hpp"
 
- #include "../catch_outlier_classification.hpp"
 
- #include <algorithm>
 
- #include <functional>
 
- #include <vector>
 
- #include <iterator>
 
- #include <numeric>
 
- #include <tuple>
 
- #include <cmath>
 
- #include <utility>
 
- #include <cstddef>
 
- #include <random>
 
- namespace Catch {
 
-     namespace Benchmark {
 
-         namespace Detail {
 
-             using sample = std::vector<double>;
 
-             double weighted_average_quantile(int k, int q, std::vector<double>::iterator first, std::vector<double>::iterator last);
 
-             template <typename Iterator>
 
-             OutlierClassification classify_outliers(Iterator first, Iterator last) {
 
-                 std::vector<double> copy(first, last);
 
-                 auto q1 = weighted_average_quantile(1, 4, copy.begin(), copy.end());
 
-                 auto q3 = weighted_average_quantile(3, 4, copy.begin(), copy.end());
 
-                 auto iqr = q3 - q1;
 
-                 auto los = q1 - (iqr * 3.);
 
-                 auto lom = q1 - (iqr * 1.5);
 
-                 auto him = q3 + (iqr * 1.5);
 
-                 auto his = q3 + (iqr * 3.);
 
-                 OutlierClassification o;
 
-                 for (; first != last; ++first) {
 
-                     auto&& t = *first;
 
-                     if (t < los) ++o.low_severe;
 
-                     else if (t < lom) ++o.low_mild;
 
-                     else if (t > his) ++o.high_severe;
 
-                     else if (t > him) ++o.high_mild;
 
-                     ++o.samples_seen;
 
-                 }
 
-                 return o;
 
-             }
 
-             template <typename Iterator>
 
-             double mean(Iterator first, Iterator last) {
 
-                 auto count = last - first;
 
-                 double sum = std::accumulate(first, last, 0.);
 
-                 return sum / count;
 
-             }
 
-             template <typename URng, typename Iterator, typename Estimator>
 
-             sample resample(URng& rng, int resamples, Iterator first, Iterator last, Estimator& estimator) {
 
-                 auto n = last - first;
 
-                 std::uniform_int_distribution<decltype(n)> dist(0, n - 1);
 
-                 sample out;
 
-                 out.reserve(resamples);
 
-                 std::generate_n(std::back_inserter(out), resamples, [n, first, &estimator, &dist, &rng] {
 
-                     std::vector<double> resampled;
 
-                     resampled.reserve(n);
 
-                     std::generate_n(std::back_inserter(resampled), n, [first, &dist, &rng] { return first[dist(rng)]; });
 
-                     return estimator(resampled.begin(), resampled.end());
 
-                 });
 
-                 std::sort(out.begin(), out.end());
 
-                 return out;
 
-             }
 
-             template <typename Estimator, typename Iterator>
 
-             sample jackknife(Estimator&& estimator, Iterator first, Iterator last) {
 
-                 auto n = last - first;
 
-                 auto second = std::next(first);
 
-                 sample results;
 
-                 results.reserve(n);
 
-                 for (auto it = first; it != last; ++it) {
 
-                     std::iter_swap(it, first);
 
-                     results.push_back(estimator(second, last));
 
-                 }
 
-                 return results;
 
-             }
 
-             inline double normal_cdf(double x) {
 
-                 return std::erfc(-x / std::sqrt(2.0)) / 2.0;
 
-             }
 
-             double erfc_inv(double x);
 
-             double normal_quantile(double p);
 
-             template <typename Iterator, typename Estimator>
 
-             Estimate<double> bootstrap(double confidence_level, Iterator first, Iterator last, sample const& resample, Estimator&& estimator) {
 
-                 auto n_samples = last - first;
 
-                 double point = estimator(first, last);
 
-                 // Degenerate case with a single sample
 
-                 if (n_samples == 1) return { point, point, point, confidence_level };
 
-                 sample jack = jackknife(estimator, first, last);
 
-                 double jack_mean = mean(jack.begin(), jack.end());
 
-                 double sum_squares, sum_cubes;
 
-                 std::tie(sum_squares, sum_cubes) = std::accumulate(jack.begin(), jack.end(), std::make_pair(0., 0.), [jack_mean](std::pair<double, double> sqcb, double x) -> std::pair<double, double> {
 
-                     auto d = jack_mean - x;
 
-                     auto d2 = d * d;
 
-                     auto d3 = d2 * d;
 
-                     return { sqcb.first + d2, sqcb.second + d3 };
 
-                 });
 
-                 double accel = sum_cubes / (6 * std::pow(sum_squares, 1.5));
 
-                 int n = static_cast<int>(resample.size());
 
-                 double prob_n = std::count_if(resample.begin(), resample.end(), [point](double x) { return x < point; }) / (double)n;
 
-                 // degenerate case with uniform samples
 
-                 if (prob_n == 0) return { point, point, point, confidence_level };
 
-                 double bias = normal_quantile(prob_n);
 
-                 double z1 = normal_quantile((1. - confidence_level) / 2.);
 
-                 auto cumn = [n](double x) -> int {
 
-                     return std::lround(normal_cdf(x) * n); };
 
-                 auto a = [bias, accel](double b) { return bias + b / (1. - accel * b); };
 
-                 double b1 = bias + z1;
 
-                 double b2 = bias - z1;
 
-                 double a1 = a(b1);
 
-                 double a2 = a(b2);
 
-                 auto lo = (std::max)(cumn(a1), 0);
 
-                 auto hi = (std::min)(cumn(a2), n - 1);
 
-                 return { point, resample[lo], resample[hi], confidence_level };
 
-             }
 
-             double outlier_variance(Estimate<double> mean, Estimate<double> stddev, int n);
 
-             struct bootstrap_analysis {
 
-                 Estimate<double> mean;
 
-                 Estimate<double> standard_deviation;
 
-                 double outlier_variance;
 
-             };
 
-             bootstrap_analysis analyse_samples(double confidence_level, int n_resamples, std::vector<double>::iterator first, std::vector<double>::iterator last);
 
-         } // namespace Detail
 
-     } // namespace Benchmark
 
- } // namespace Catch
 
- #endif // TWOBLUECUBES_CATCH_DETAIL_ANALYSIS_HPP_INCLUDED
 
 
  |