#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;
+ rating = 500.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;