56 std::vector<double> below;
57 std::vector<double> above;
59 below.reserve(x.size());
60 above.reserve(x.size());
64 std::back_inserter(below),
65 std::back_inserter(above),
66 [mu](
double v) { return v <= mu; }
69 return {below, above};
87 if (S.empty())
throw std::invalid_argument(
"No samples");
89 const std::size_t N = S.size();
90 const std::size_t D = S[0].size();
92 for (
const auto& v : S) {
93 if (v.size() != D)
throw std::invalid_argument(
"Jagged samples");
96 std::vector<BinnedObservableId> ids;
97 for (
const auto& v : S[0]) {
98 ids.push_back(v.first);
101 std::map<BinnedObservableId, ColumnStats> out;
103 std::vector<double> x;
106 for (
size_t d = 0; d < D; d++) {
108 for (
const auto& v : S) {
109 x.push_back(v.at(ids[d]));
111 std::sort(x.begin(), x.end());
114 for (
double x_i : x) mean += x_i;
115 mean /=
static_cast<double>(N);
117 double s = 0.0, m3 = 0.0;
118 for (
double x_i : x) {
119 const double r = x_i - mean;
124 out[ids[d]].mean = mean;
125 out[ids[d]].std_unbiased = std::sqrt(s /
static_cast<double>(N - 1));
127 const double m2 = s /
static_cast<double>(N);
129 const double m3bar = m3 /
static_cast<double>(N);
130 out[ids[d]].b1_skew = m3bar / std::pow(m2, 1.5);
132 out[ids[d]].b1_skew = 0.0;
135 auto obj = [x, N] (std::size_t i) {
138 for (
size_t j = 0; j < i; j++) s_m += (x[j] - x[i]) * (x[j] - x[i]);
139 for (
size_t j = i; j < N; j++) s_p += (x[j] - x[i]) * (x[j] - x[i]);
140 return std::cbrt(s_m) + std::cbrt(s_p);
144 double min_obj = std::numeric_limits<double>::infinity();
146 for (std::size_t i = 0; i < N; ++i) {
147 double obj_i = obj(i);
149 if (obj_i < min_obj) {
158 for (
double x_i : x_m) s_m += (x_i - mu_hat) * (x_i - mu_hat);
159 for (
double x_i : x_p) s_p += (x_i - mu_hat) * (x_i - mu_hat);
161 out[ids[d]].mode = mu_hat;
162 out[ids[d]].std_m = std::sqrt(min_obj / N) * std::cbrt(s_m);
163 out[ids[d]].std_p = std::sqrt(min_obj / N) * std::cbrt(s_p);
std::pair< std::vector< double >, std::vector< double > > split_vector(const std::vector< double > &x, double mu)
Splits a vector around a reference value.