Games-Go-AGA-BayRate

 view release on metacpan or  search on metacpan

bin/bayrate.pl  view on Meta::CPAN

                or die "Couldn't prepare statement: " . $dbh->errstr;

    $sth->execute($tournament_code)     # Execute the query
        or die "Couldn't execute statement: " . $sth->errstr;

    my (@games, %player_seeds_by_id);
    while (my @data = $sth->fetchrow_array) {
        # Process and locally store the game information
        my %game;
        if ($data[$g_color_1] eq 'W') {
            $game{white} = $data[$g_pin_player_1];
            $game{black} = $data[$g_pin_player_2];
        }
        elsif ($data[$g_color_1] eq 'B') {
            $game{white} = $data[$g_pin_player_2];
            $game{black} = $data[$g_pin_player_1];
        }
        else {
            croak("unknown player colour:  $data[$g_color_1]\n");
        }

        if ($data[$g_result] eq 'W') {
            $game{whiteWins} = 1;
        }
        elsif ($data[$g_result] eq 'B') {
            $game{whiteWins} = 0;
        }
        else {
            croak("unknown game result: $data[$g_result]\n");
        }

        $game{handicap}  = $data[$g_handicap];
        $game{komi}      = $data[$g_komi];

        push @games, \%game;

        # Process and locally store the player information
        foreach my $which (0 .. 1) {
            my $pin_idx  = $which ? $g_pin_player_2 : $g_pin_player_1;
            my $rank_idx = $which ? $g_rank_2 : $g_rank_1;
            my $id = $data[$pin_idx];
            next if (exists $player_seeds_by_id{$id});

            my $rank = $data[$rank_idx];
            if (my ($rating, $range) = $rank =~ m/^(\d+)([KDkd])$/) {
                $rating += 0.5; # make e.g: 5d = 5.5
                $player_seeds_by_id{$id} = (uc $range eq 'D') ? $rating : -$rating;
            }
            else {
                croak("Illegal rank: " . $data["\$g_rank_$which"]);
            }
        }
    }
    $sth->finish;
    return if (not @games);

    my $collection = Games::Go::AGA::BayRate::Collection->new(
            iter_hook         => \&iter_hook,
            tournamentDate    => $tournamentDate,
            strict_compliance => $strict_compliance, # match original bayrate C++ code exactly
            #f_iterations     => 50,
            #fdf_iterations   => 50,
    );

    # enter all the players who were in a game
    my %players_by_id;
    foreach my $id (sort { $a <=> $b } keys %player_seeds_by_id) {
        $players_by_id{$id} = $collection->add_player(
            id     => $id,
            seed   => $player_seeds_by_id{$id},
            sigma  => 6.0,  # will get changed later
        );
    }

    # enter all the games
    foreach my $game (@games) {
        $collection->add_game(
            white     => $players_by_id{$game->{white}},
            black     => $players_by_id{$game->{black}},
            whiteWins => $game->{whiteWins},
            handicap  => $game->{handicap},
            komi      => $game->{komi},
        );
    }

    printf("%s\t%s\t%s (%d players in %d games)\n",
        $tournament_code,
        $collection->tournamentDate_ymd,
        $tournamentName,
        scalar (keys %players_by_id),
        scalar @games,
    );

    return $collection;
}

# hook called for each F(DF)Minimzer iteration
sub iter_hook {
    my ($collection, $state, $iter, $status) = @_;

    if (ref $state eq 'Math::GSL::Multimin::gsl_multimin_fminimizer') {
        my $f = # gsl_multimin_fminimizer_fval($state),    # hmm, struct member, not a function
                # ok, do it this way instead:
            raw_gsl_multimin_fminimizer_fval($state),
        my $size = gsl_multimin_fminimizer_size($state);
        printf("F Iteration %d\tf() = %g\tsimplex size = %g\n", $iter, $f, $size);
        if ($status == $GSL_SUCCESS) {
            printf "\nConverged to minimum. f() = %g\n", $f;
        }
    }
    elsif (ref $state eq 'Math::GSL::Multimin::gsl_multimin_fdfminimizer') {
        my $gradient = raw_gsl_multimin_fdfminimizer_gradient($state);
        my $minimum = gsl_multimin_fdfminimizer_minimum($state);
        printf("FDF Iteration %d\tf() = %g\tnorm = %g\tStatus = %d\n",
            $iter,
            $minimum,
            gsl_blas_dnrm2($gradient),
            $status);
        if ($status == $GSL_SUCCESS) {
            printf "\nConverged to minimum. Norm(gradient) = %g\n",
                gsl_blas_dnrm2($gradient),
        }



( run in 0.932 second using v1.01-cache-2.11-cpan-cdf2f3d4e48 )