20 double normalCDF(
double x)
22 return std::erfc(-x / std::sqrt(2)) / 2;
25 inline double linear_interp(
const double& x,
26 const std::vector<double>& grid,
27 const std::vector<double>& values)
31 while(x > grid[i]) i++;
34 double w = (x - grid[i - 1]) / (grid[i] - grid[i - 1]);
35 return w * values[i - 1] + (1 - w) * values[i];
38 inline void check_sizes(
const std::vector<double>& x,
39 const std::vector<double>& y,
40 const std::vector<double>& weights)
42 if (y.size() != x.size())
43 throw std::runtime_error(
"x and y must have the same size.");
44 if ((weights.size() > 0) && (weights.size() != y.size()))
45 throw std::runtime_error(
"x, y, and weights must have the same size.");
53 inline std::vector<double> pow(
const std::vector<double>& x,
size_t n)
55 std::vector<double> res(x.size(), 1.0);
57 for (
size_t i = 0; i < x.size(); i++) {
58 for (
size_t j = 0; j < n; j++) {
69 inline double sum(
const std::vector<double>& x)
72 for (
size_t i = 0; i < x.size(); i++)
82 inline double perm_sum(
const std::vector<double>& x,
size_t k)
87 for (
size_t i = 1; i <= k; i++)
88 s += std::pow(-1.0, i - 1) * perm_sum(x, k - i) * sum(pow(x, i));
95 inline double effective_sample_size(
size_t n,
const std::vector<double>& weights)
98 if (weights.size() == 0) {
99 n_eff =
static_cast<double>(n);
101 n_eff = std::pow(sum(weights), 2);
102 n_eff /= sum(pow(weights, 2));
111 inline std::vector<size_t> invert_permutation(
const std::vector<size_t>& perm)
113 std::vector<size_t> inv_perm(perm.size());
114 for (
size_t i = 0; i < perm.size(); i++)
115 inv_perm[perm[i]] = i;
122 inline std::vector<size_t> get_order(
const std::vector<double>& x,
123 bool ascending =
true)
126 std::vector<size_t> perm(n);
127 for (
size_t i = 0; i < n; i++)
129 auto sorter = [&] (
size_t i,
size_t j) {
131 return (x[i] < x[j]);
133 return (x[i] > x[j]);
135 std::sort(perm.begin(), perm.end(), sorter);
142 inline void sort_all(std::vector<double>& x,
143 std::vector<double>& y,
144 std::vector<double>& weights)
147 std::vector<size_t> order(n);
148 for (
size_t i = 0; i < n; i++)
150 auto sorter_with_tie_break = [&] (
size_t i,
size_t j) {
151 return (x[i] < x[j]) | ((x[i] == x[j]) && (y[i] < y[j]));
153 std::sort(order.begin(), order.end(), sorter_with_tie_break);
155 std::vector<double> xx(n), yy(n);
156 for (
size_t i = 0; i < n; i++) {
162 std::vector<double> w = weights;
163 if (weights.size() > 0) {
164 for (
size_t i = 0; i < n; i++) {
165 w[i] = weights[order[i]];
179 inline double count_ties_v(
const std::vector<double>& x,
180 const std::vector<double>& weights)
182 bool weighted = (weights.size() > 0);
183 double count = 0.0, w1 = 0.0, w2 = 0.0;
185 for (
size_t i = 1; i < x.size(); i++) {
186 if ((x[i] == x[i - 1])) {
193 w2 += std::pow(weights[i], 2);
196 }
else if (reps > 1) {
198 count += (w1 * w1 - w2) * (2 * w1 + 5);
200 count += reps * (reps - 1)* (2 * reps + 5);
208 count += (w1 * w1 - w2) * (2 * w1 + 5);
210 count += reps * (reps - 1) * (2 * reps + 5);
222 inline double count_tied_pairs(
const std::vector<double>& x,
223 const std::vector<double>& weights)
225 bool weighted = (weights.size() > 0);
226 double count = 0.0, w1 = 0.0, w2 = 0.0;
228 for (
size_t i = 1; i < x.size(); i++) {
229 if ((x[i] == x[i - 1])) {
236 w2 += std::pow(weights[i], 2);
239 }
else if (reps > 1) {
241 count += (w1 * w1 - w2) / 2.0;
243 count += reps * (reps - 1) / 2.0;
251 count += (w1 * w1 - w2) / 2.0;
253 count += reps * (reps - 1) / 2.0;
265 inline double count_tied_triplets(
const std::vector<double>& x,
266 const std::vector<double>& weights)
268 bool weighted = (weights.size() > 0);
269 double count = 0.0, w1 = 0.0, w2 = 0.0, w3 = 0.0;
271 for (
size_t i = 2; i < x.size(); i++) {
272 if ((x[i] == x[i - 1]) & (x[i] == x[i - 2])) {
276 w2 = std::pow(weights[i - 1], 2);
277 w3 = std::pow(weights[i - 1], 3);
280 w2 += std::pow(weights[i], 2);
281 w3 += std::pow(weights[i], 3);
284 }
else if (reps > 2) {
286 count += (std::pow(w1, 3) - 3 * w2 * w1 + 2 * w3) / 6.0;
288 count += reps * (reps - 1) * (reps - 2) / 6.0;
296 count += (std::pow(w1, 3) - 3 * w2 * w1 + 2 * w3) / 6.0;
298 count += reps * (reps - 1) * (reps - 2) / 6.0;
310 inline double count_joint_ties(
const std::vector<double>& x,
311 const std::vector<double>& y,
312 const std::vector<double>& weights)
314 bool weighted = (weights.size() > 0);
315 double count = 0.0, w1 = 0.0, w2 = 0.0;
317 for (
size_t i = 1; i < x.size(); i++) {
318 if ((x[i] == x[i - 1]) && (y[i] == y[i - 1])) {
322 w2 = weights[i - 1] * weights[i - 1];
325 w2 += weights[i] * weights[i];
328 }
else if (reps > 1) {
330 count += (w1 * w1 - w2) / 2.0;
332 count += reps * (reps - 1) / 2.0;
340 count += (w1 * w1 - w2) / 2.0;
342 count += reps * (reps - 1) / 2.0;
357 inline void merge(std::vector<double>& vec,
358 const std::vector<double>& vec1,
359 const std::vector<double>& vec2,
360 std::vector<double>& weights,
361 const std::vector<double>& weights1,
362 const std::vector<double>& weights2,
365 double w_acc = 0.0, w1_sum = 0.0;
366 bool weighted = (weights.size() > 0);
368 for (
size_t i = 0; i < weights1.size(); i++)
369 w1_sum += weights1[i];
372 for (i = 0, j = 0, k = 0; i < vec1.size() && j < vec2.size(); k++) {
373 if (vec1[i] <= vec2[j]) {
376 weights[k] = weights1[i];
377 w_acc += weights1[i];
383 weights[k] = weights2[j];
384 count += weights2[j] * (w1_sum - w_acc);
386 count += vec1.size() - i;
392 while (i < vec1.size()) {
395 weights[k] = weights1[i];
400 while (j < vec2.size()) {
403 weights[k] = weights2[j];
414 inline void merge_sort(std::vector<double>& vec,
415 std::vector<double>& weights,
418 if (vec.size() > 1) {
419 size_t n = vec.size();
420 std::vector<double> vec1(vec.begin(), vec.begin() + n / 2);
421 std::vector<double> vec2(vec.begin() + n / 2, vec.end());
424 std::vector<double> weights1(weights.begin(), weights.begin() + n / 2);
425 std::vector<double> weights2(weights.begin() + n / 2, weights.end());
427 merge_sort(vec1, weights1, count);
428 merge_sort(vec2, weights2, count);
429 merge(vec, vec1, vec2, weights, weights1, weights2, count);
444 inline void merge_count_per_element(std::vector<double>& vec,
445 const std::vector<double>& vec1,
446 const std::vector<double>& vec2,
447 std::vector<double>& weights,
448 const std::vector<double>& weights1,
449 const std::vector<double>& weights2,
450 std::vector<double>& counts,
451 const std::vector<double>& counts1,
452 const std::vector<double>& counts2)
455 bool weighted = (weights.size() > 0);
458 for (
size_t i = 0; i < weights1.size(); i++)
459 w1_sum += weights1[i];
462 for (i = 0, j = 0, k = 0; i < vec1.size() && j < vec2.size(); k++) {
463 if (vec1[i] > vec2[j]) {
465 counts[k] = counts1[i];
467 weights[k] = weights1[i];
468 w_acc += weights1[i];
474 counts[k] = counts2[j] + w1_sum - w_acc;
475 weights[k] = weights2[j];
477 counts[k] = counts2[j] + vec1.size() - i;
483 while (i < vec1.size()) {
486 weights[k] = weights1[i];
487 counts[k] = counts1[i];
492 while (j < vec2.size()) {
495 weights[k] = weights2[j];
496 counts[k] = counts2[j];
509 inline void merge_sort_count_per_element(std::vector<double>& vec,
510 std::vector<double>& weights,
511 std::vector<double>& counts)
513 if (vec.size() > 1) {
514 size_t n = vec.size();
515 std::vector<double> vec1(vec.begin(), vec.begin() + n / 2);
516 std::vector<double> vec2(vec.begin() + n / 2, vec.end());
519 std::vector<double> weights1(weights.begin(), weights.begin() + n / 2);
520 std::vector<double> weights2(weights.begin() + n / 2, weights.end());
523 std::vector<double> counts1(counts.begin(), counts.begin() + n / 2);
524 std::vector<double> counts2(counts.begin() + n / 2, counts.end());
526 merge_sort_count_per_element(vec1, weights1, counts1);
527 merge_sort_count_per_element(vec2, weights2, counts2);
528 merge_count_per_element(vec, vec1, vec2,
529 weights, weights1, weights2,
530 counts, counts1, counts2);
Weighted dependence measures.
Definition: bbeta.hpp:11