#include <vector>
#include <string>
#include <algorithm>
+#include <Eigen/Cholesky>
+#include <Eigen/Dense>
#include "ziggurat.hpp"
using namespace std;
+using namespace Eigen;
#define MAX_PLAYERS 16
vector<string> players;
map<string, int> player_map;
- float ratings[MAX_PLAYERS];
- float ratings_stddev[MAX_PLAYERS];
+ Matrix<float, Dynamic, 1, 0, MAX_PLAYERS, 1> ratings(num_players);
bool has_scores[MAX_PLAYERS][MAX_PLAYERS];
for (int pl1 = 0; pl1 < num_players; ++pl1) {
for (int pl2 = 0; pl2 < num_players; ++pl2) {
int scores[MAX_PLAYERS][MAX_PLAYERS];
for (int i = 0; i < num_players; ++i) {
char buf[256];
- float rating, rating_stddev;
- int ret = scanf("%s %f %f", buf, &rating, &rating_stddev);
+ float rating;
+ int ret = scanf("%s %f", buf, &rating);
if (ret < 1) {
fprintf(stderr, "Couldn't read player %d\n", i);
exit(1);
if (ret < 2) {
rating = 1500.0f;
}
- if (ret < 3) {
- rating_stddev = 0.0f;
- }
players.push_back(buf);
player_map[buf] = i;
- ratings[i] = rating;
- ratings_stddev[i] = rating_stddev;
+ ratings(i) = rating;
+ }
+
+ Matrix<float, Dynamic, Dynamic, 0, MAX_PLAYERS, MAX_PLAYERS> ratings_cov(num_players, num_players);
+ for (int i = 0; i < num_players; ++i) {
+ for (int j = 0; j < num_players; ++j) {
+ float f;
+ if (scanf("%f", &f) != 1) {
+ fprintf(stderr, "Couldn't read covariance matrix element (%d,%d)\n", i, j);
+ exit(1);
+ }
+ ratings_cov(i, j) = f;
+ }
}
+ Matrix<float, Dynamic, Dynamic, 0, MAX_PLAYERS, MAX_PLAYERS> ratings_cholesky =
+ ratings_cov.llt().matrixLLT();
for ( ;; ) {
char pl1[256], pl2[256];
for (int i = 0; i < trials; ++i) {
// draw true strength for all players
- float drawn_ratings[MAX_PLAYERS];
+ Matrix<float, Dynamic, 1, 0, MAX_PLAYERS, 1> drawn_normals(num_players);
for (int p = 0; p < num_players; ++p) {
- drawn_ratings[p] = draw_gaussian(ratings[p], ratings_stddev[p]);
+ drawn_normals(p) = draw_gaussian(0.0f, 1.0f);
}
+ Matrix<float, Dynamic, 1, 0, MAX_PLAYERS, 1> drawn_ratings = ratings_cholesky * drawn_normals + ratings;
// draw the missing matches
for (int pl1 = 0; pl1 < num_players; ++pl1) {
continue;
}
- float mu = drawn_ratings[pl1] - drawn_ratings[pl2];
+ float mu = drawn_ratings(pl1) - drawn_ratings(pl2);
int score = lrintf(draw_gaussian(mu, match_stddev));
scores[pl1][pl2] = score;
}
sub make_table {
- my ($lowest_division, $used_ratings, $used_ratings_stddev) = @_;
+ my ($lowest_division, $used_ratings, $used_cov) = @_;
print <<"EOF";
for my $id (keys %players) {
my $rating = $used_ratings->{$id} // 1500.0;
- my $rating_stddev = $used_ratings_stddev->{$id} // $parms{-3};
- printf MCCALC "%s %f %f\n", $id, $rating, $rating_stddev;
+ printf MCCALC "%s %f\n", $id, $rating;
+ }
+
+ # covariance matrix
+ for my $id1 (keys %players) {
+ for my $id2 (keys %players) {
+ if ($id1 == $id2) {
+ printf MCCALC "%f ", ($used_cov->{$id1}{$id2} // $parms{-3});
+ } else {
+ printf MCCALC "%f ", ($used_cov->{$id1}{$id2} // 0.0);
+ }
+ }
+ printf MCCALC "\n";
}
for my $match (@matches) {
}
$q->finish;
+# Pick up covariance matrix
+my $player_sql = '{' . join(',', keys %players ) . '}';
+my $q = $dbh->prepare('SELECT * FROM covariance WHERE player1=ANY(?::smallint[]) AND player2=ANY(?::smallint[])', { pg_prepare_now => 0 });
+$q->execute($player_sql, $player_sql);
+
+my $cov = {};
+while (my $ref = $q->fetchrow_hashref) {
+ $cov->{$ref->{'player1'}}{$ref->{'player2'}} = $ref->{'cov'};
+}
+
my $lowest_division = ($division == $max_division);
make_table($lowest_division, {}, {});
se <a href="/rating">ratingsiden</a>.</p>
EOF
-make_table($lowest_division, \%ratings, \%ratings_stddev);
+make_table($lowest_division, \%ratings, $cov);
-print << "EOF";
+print <<"EOF";
</body>
</html>
EOF