Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 20 additions & 6 deletions app/src/matchmaking/sprt/sprt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,11 @@ static double regularize(int value) {
return value;
}

static double regularize(double value) {
if (value <= 1e-32) return 1e-32;
return value;
}

double SPRT::getLLR(const Stats& stats, bool penta) const noexcept {
if (penta)
return getLLR(stats.penta_WW, stats.penta_WD, stats.penta_WL, stats.penta_DD, stats.penta_LD, stats.penta_LL);
Expand Down Expand Up @@ -176,8 +181,8 @@ static double itp(F f, double a, double b, double f_a, double f_b, double k_1, d

double x_f = (f_b * a - f_a * b) / (f_b - f_a);

double sigma = (x_half - x_f) / std::abs(x_half - x_f);
double x_t = delta <= std::abs(x_half - x_f) ? x_f + sigma * delta : x_half;
int sigma = (x_half - x_f) >= 0 ? 1 : -1;
double x_t = delta <= std::abs(x_half - x_f) ? x_f + sigma * delta : x_half;

double x_itp = std::abs(x_t - x_half) <= r ? x_t : x_half - sigma * r;

Expand All @@ -204,7 +209,7 @@ double SPRT::getLLR_logistic(double total, std::array<double, N> scores, std::ar
// given an empirical distribution. See proposition 1.1 of [1] for details.
//
// [1]: Michel Van den Bergh, Comments on Normalized Elo,
// https://www.cantate.be/Fishtest/normalized_elo_practical.pdf
// https://www.cantate.be/Fishtest/comparing_approximations.pdf
const auto mle = [&](double s) -> std::array<double, N> {
const double theta_epsilon = 1e-3;

Expand Down Expand Up @@ -236,7 +241,9 @@ double SPRT::getLLR_logistic(double total, std::array<double, N> scores, std::ar
std::array<double, N> p0 = mle(s0);
std::array<double, N> p1 = mle(s1);
std::array<double, N> lpr;
for (size_t i = 0; i < N; i++) lpr[i] = std::log(p1[i]) - std::log(p0[i]);
for (size_t i = 0; i < N; i++)
lpr[i] = std::log(regularize(p1[i])) - std::log(regularize(p0[i]));

return total * mean(lpr, probs);
}

Expand All @@ -249,6 +256,7 @@ double SPRT::getLLR_normalized(double total, std::array<double, N> scores, std::
// [1]: Michel Van den Bergh, Comments on Normalized Elo,
// https://www.cantate.be/Fishtest/normalized_elo_practical.pdf
const auto mle = [&](double mu_ref, double t_star) -> std::array<double, N> {
const double var_epsilon = 1e-15;
const double theta_epsilon = 1e-7;
const double mle_epsilon = 1e-4;

Expand All @@ -260,10 +268,14 @@ double SPRT::getLLR_normalized(double total, std::array<double, N> scores, std::
for (int iterations = 0; iterations < 10; iterations++) {
// Calculate phi.
auto [mu, var] = mean_and_variance(scores, p);

// Variance too small?
if (var < var_epsilon) break;

double sigma = std::sqrt(var);
std::array<double, N> phi;
for (size_t i = 0; i < N; i++) {
double a_i = scores[i];
double sigma = std::sqrt(var);
phi[i] = a_i - mu_ref - 0.5 * t_star * sigma * (1.0 + ((a_i - mu) / sigma) * ((a_i - mu) / sigma));
}

Expand Down Expand Up @@ -305,7 +317,9 @@ double SPRT::getLLR_normalized(double total, std::array<double, N> scores, std::
std::array<double, N> p0 = mle(0.5, t0);
std::array<double, N> p1 = mle(0.5, t1);
std::array<double, N> lpr;
for (size_t i = 0; i < N; i++) lpr[i] = std::log(p1[i]) - std::log(p0[i]);
for (size_t i = 0; i < N; i++)
lpr[i] = std::log(regularize(p1[i])) - std::log(regularize(p0[i]));

return total * mean(lpr, probs);
}

Expand Down