X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=bayeswf.cpp;h=f2047bbf69549d510522bb316b33cf9788db3b5b;hb=8c1fa23431ade9bec578e4a0dd6a0e1108a6b53d;hp=5eba4790bc2749f6a5ed1faf6264b6bee3884d3d;hpb=b0f2024b2a7e87cbe8d59f4c0365e0b49e16f532;p=wloh diff --git a/bayeswf.cpp b/bayeswf.cpp index 5eba479..f2047bb 100644 --- a/bayeswf.cpp +++ b/bayeswf.cpp @@ -11,7 +11,9 @@ using namespace std; #define PRIOR_MU 1500 +#define PRIOR_WEIGHT 1.0 #define MAX_PLAYERS 4096 +#define DUMP_RAW 0 float mu[MAX_PLAYERS]; float sigma[MAX_PLAYERS]; @@ -73,8 +75,8 @@ void update_mu(float *mu, float *sigma, int player_num, const vector &mat // Prior. { float inv_sigma2 = 1.0f / (prior_sigma * prior_sigma); - nom += PRIOR_MU * inv_sigma2; - denom += inv_sigma2; + nom += PRIOR_WEIGHT * PRIOR_MU * inv_sigma2; + denom += PRIOR_WEIGHT * inv_sigma2; } // All matches. @@ -90,6 +92,31 @@ void update_mu(float *mu, float *sigma, int player_num, const vector &mat mu[player_num] = nom / denom; } +void dump_raw(const float *mu, const float *sigma, int num_players) +{ + for (int i = 0; i < num_players; ++i) { + for (unsigned j = 0; j < matches_for_player[i].size(); ++j) { + const match& m = matches_for_player[i][j]; + + // Only count each match once. + if (m.other_player <= i) { + continue; + } + + float mu1 = mu[i]; + float mu2 = mu[m.other_player]; + float sigma1 = sigma[i]; + float sigma2 = sigma[m.other_player]; + float sigma = sqrt(sigma1 * sigma1 + sigma2 * sigma2); + float mu = mu1 - mu2; + float x = m.margin; + float w = m.weight; + + printf("%f %f\n", (x - mu) / sigma, w); + } + } +} + /* * diff(logL, sigma1) = sigma1 (-sigma1² - sigma2² + (x - mu)²) / sigma_c² * maximizer for sigma1 is given by: sum_i[ (1/sigma_c_i)² sigma1 ((x - mu)² - (sigma1² + sigma2²) ] = 0 @@ -179,12 +206,56 @@ void update_prior_sigma(float *mu, float *sigma, int num_players) float mu1 = mu[i]; - nom += ((mu1 - PRIOR_MU) * (mu1 - PRIOR_MU)); - denom += 1.0f; + float w = m.weight; + nom += w * ((mu1 - PRIOR_MU) * (mu1 - PRIOR_MU)); + denom += w * 1.0f; } } prior_sigma = sqrt(nom / denom); + if (!(prior_sigma > 40.0f)) { + prior_sigma = 40.0f; + } +} + +float compute_logl(float z) +{ + return -0.5 * (log(2.0f / M_PI) + z * z); +} + +float compute_total_logl(float *mu, float *sigma, int num_players) +{ + float total_logl = 0.0f; + + // Prior. + for (int i = 0; i < num_players; ++i) { + total_logl += PRIOR_WEIGHT * compute_logl((mu[i] - PRIOR_MU) / prior_sigma); + } + + // Matches. + for (int i = 0; i < num_players; ++i) { + for (unsigned j = 0; j < matches_for_player[i].size(); ++j) { + const match& m = matches_for_player[i][j]; + + // Only count each match once. + if (m.other_player <= i) { + continue; + } + + float mu1 = mu[i]; + float mu2 = mu[m.other_player]; + float sigma1 = sigma[i]; + float sigma2 = sigma[m.other_player]; + float sigma = sqrt(sigma1 * sigma1 + sigma2 * sigma2); + float mu = mu1 - mu2; + float x = m.margin; + float w = m.weight; + + total_logl += w * compute_logl((x - mu) / sigma); + } + } + + return total_logl; } /* @@ -290,7 +361,7 @@ int main(int argc, char **argv) float sigma[MAX_PLAYERS]; for (int i = 0; i < num_players; ++i) { - mu[i] = 1500.0f; + mu[i] = PRIOR_MU; sigma[i] = 70.0f / sqrt(2.0f); } @@ -322,10 +393,18 @@ int main(int argc, char **argv) break; } } + +#if DUMP_RAW + dump_raw(mu, sigma, num_players); +#else dump_scores(players, mu, sigma, num_players); //fprintf(stderr, "Optimal sigma: %f (two-player: %f)\n", sigma[0], sigma[0] * sqrt(2.0f)); printf("%f -2\n", sigma[0]); printf("%f -3\n", prior_sigma); + float total_logl = compute_total_logl(mu, sigma, num_players); + printf("%f -4\n", total_logl); + // construct_hessian(mu, sigma, num_players); +#endif }