From: Steinar H. Gunderson Date: Sat, 17 Mar 2012 00:12:59 +0000 (+0100) Subject: Optimize global sigma. X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=b48d3244dd4ed5f61e4e1e1d21bca88e918ccff9;p=wloh Optimize global sigma. --- diff --git a/bayeswf.cpp b/bayeswf.cpp index f518edd..48d5232 100644 --- a/bayeswf.cpp +++ b/bayeswf.cpp @@ -112,6 +112,42 @@ void update_sigma(float *mu, float *sigma, int player_num, const vector & sigma[player_num] = sqrt(sum / matches.size()); } +/* + * diff(logL, sigma) = w ( (x - mu)² - sigma² ) / sigma³ + * maximizer for sigma is given by: sum_i[ (w_i/sigma)³ ((x - mu)² - sigma²) ] = 0 + * sum_i[ w_i ( (x - mu)² - sigma² ) ] = 0 |: sigma != 0 + * sum_i[ w_i (x - mu)² ] = sum[ w_i sigma² ] + * sigma = sqrt( sum_i[ w_i (x - mu)² ] / sum[w_i] ) + */ +void update_global_sigma(float *mu, float *sigma, int num_players) +{ + float nom = 0.0f, denom = 0.0f; + 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 mu = mu1 - mu2; + float x = m.margin; + float w = m.weight; + + nom += w * ((x - mu) * (x - mu)); + denom += w; + } + } + + float best_sigma = sqrt(nom / denom) / sqrt(2.0f); // Divide evenly between the two players. + for (int i = 0; i < num_players; ++i) { + sigma[i] = best_sigma; + } +} + void renormalize(float *mu, float *sigma, int num_players) { float avg = 0.0f; @@ -247,6 +283,7 @@ int main(int argc, char **argv) update_mu(mu, sigma, i, matches_for_player[i]); renormalize(mu, sigma, num_players); } + update_global_sigma(mu, sigma, num_players); /* for (int i = 0; i < num_players; ++i) { update_sigma(mu, sigma, i, matches_for_player[i]); dump_scores(players, mu, sigma, num_players); @@ -263,6 +300,7 @@ int main(int argc, char **argv) } } dump_scores(players, mu, sigma, num_players); + fprintf(stderr, "Optimal sigma: %f (two-player: %f)\n", sigma[0], sigma[0] * sqrt(2.0f)); // construct_fim(mu, sigma, num_players); }