X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=bayeswf.cpp;h=a691b8fe915ac8f6bb8714e62bd2349c173201b1;hb=35021b4f76156feb48fd9420a9116da50acee3e1;hp=6441801e23c32c17bab637f4c8ad09b7b609b23c;hpb=72a2eedd021d38d6bb0786033c6f100062363789;p=wloh diff --git a/bayeswf.cpp b/bayeswf.cpp index 6441801..a691b8f 100644 --- a/bayeswf.cpp +++ b/bayeswf.cpp @@ -2,6 +2,8 @@ #include #include #include +#include +#include #include #include @@ -9,6 +11,7 @@ #include using namespace std; +using namespace Eigen; #define PRIOR_MU 1500 #define PRIOR_WEIGHT 1.0 @@ -196,11 +199,15 @@ float compute_total_logl(float *mu, int num_players) * * Note that this does not depend on mu or the margin at all. */ -double hessian[MAX_PLAYERS][MAX_PLAYERS]; +Matrix hessian; void construct_hessian(const float *mu, int num_players) { - memset(hessian, 0, sizeof(hessian)); + hessian = Matrix(num_players, num_players); + hessian.fill(0.0f); + for (int i = 0; i < num_players; ++i) { + hessian(i, i) += 1.0f / (prior_sigma * prior_sigma); + } for (unsigned i = 0; i < all_matches.size(); ++i) { const match &m = all_matches[i]; @@ -210,35 +217,22 @@ void construct_hessian(const float *mu, int num_players) double sigma_sq = global_sigma * global_sigma; float w = m.weight; - hessian[p1][p2] -= w / sigma_sq; - hessian[p2][p1] -= w / sigma_sq; + hessian(p1, p2) -= w / sigma_sq; + hessian(p2, p1) -= w / sigma_sq; - hessian[p1][p1] += w / sigma_sq; - hessian[p2][p2] += w / sigma_sq; + hessian(p1, p1) += w / sigma_sq; + hessian(p2, p2) += w / sigma_sq; } } -// Compute uncertainty (stddev) of mu estimates, which is 1/sqrt(H_ii), +// Compute uncertainty (stddev) of mu estimates, which is sqrt((H^-1)_ii), // where H is the Hessian (see construct_hessian()). void compute_mu_uncertainty(const float *mu, int num_players) { - memset(mu_stddev, 0, sizeof(mu_stddev)); - - for (unsigned i = 0; i < all_matches.size(); ++i) { - const match &m = all_matches[i]; - - int p1 = m.player; - int p2 = m.other_player; - - double sigma_sq = global_sigma * global_sigma; - float w = m.weight; - - // Temporarily use mu_stddev to store the diagonal of the Hessian. - mu_stddev[p1] += w / sigma_sq; - mu_stddev[p2] += w / sigma_sq; - } + // FIXME: Use pseudoinverse if applicable. + Matrix ih = hessian.inverse(); for (int i = 0; i < num_players; ++i) { - mu_stddev[i] = 1.0f / sqrt(mu_stddev[i]); + mu_stddev[i] = sqrt(ih(i, i)); } } @@ -337,7 +331,7 @@ int main(int argc, char **argv) sumdiff += (global_sigma - old_global_sigma) * (global_sigma - old_global_sigma); if (sumdiff < EPSILON) { //fprintf(stderr, "Converged after %d iterations. Stopping.\n", j); - printf("%d -1\n", j + 1); + printf("%d 0 -1\n", j + 1); break; } } @@ -345,15 +339,14 @@ int main(int argc, char **argv) #if DUMP_RAW dump_raw(mu, num_players); #else + construct_hessian(mu, num_players); compute_mu_uncertainty(mu, num_players); dump_scores(players, mu, mu_stddev, num_players); //fprintf(stderr, "Optimal sigma: %f (two-player: %f)\n", sigma[0], sigma[0] * sqrt(2.0f)); - printf("%f -2\n", global_sigma / sqrt(2.0f)); - printf("%f -3\n", prior_sigma); + printf("%f 0 -2\n", global_sigma / sqrt(2.0f)); + printf("%f 0 -3\n", prior_sigma); float total_logl = compute_total_logl(mu, num_players); - printf("%f -4\n", total_logl); - -// construct_hessian(mu, sigma, num_players); + printf("%f 0 -4\n", total_logl); #endif }