mirror of
https://github.com/avitex/elixir-glicko
synced 2024-11-22 03:09:57 +00:00
Optimise calculations based on results
This commit is contained in:
parent
770a7735df
commit
0ebfbe6447
@ -59,12 +59,9 @@ defmodule Glicko do
|
|||||||
sys_const = Keyword.get(opts, :system_constant, @default_system_constant)
|
sys_const = Keyword.get(opts, :system_constant, @default_system_constant)
|
||||||
conv_tol = Keyword.get(opts, :convergence_tolerance, @default_convergence_tolerance)
|
conv_tol = Keyword.get(opts, :convergence_tolerance, @default_convergence_tolerance)
|
||||||
|
|
||||||
# Init
|
# Initialization (skips steps 1, 2 and 3)
|
||||||
player_pre_rd_sq = :math.pow(player_pre_rd, 2)
|
player_pre_rd_sq = :math.pow(player_pre_rd, 2)
|
||||||
results = Enum.map(results, &build_internal_result(player_pre_r, &1))
|
{variance_est, results_effect} = result_calculations(results, player_pre_r)
|
||||||
results_effect = calc_results_effect(results)
|
|
||||||
# Step 3
|
|
||||||
variance_est = calc_variance_estimate(results)
|
|
||||||
# Step 4
|
# Step 4
|
||||||
delta = calc_delta(results_effect, variance_est)
|
delta = calc_delta(results_effect, variance_est)
|
||||||
# Step 5.1
|
# Step 5.1
|
||||||
@ -93,24 +90,23 @@ defmodule Glicko do
|
|||||||
{player_post_r, player_post_rd, player_post_v}
|
{player_post_r, player_post_rd, player_post_v}
|
||||||
end
|
end
|
||||||
|
|
||||||
defp build_internal_result(player_pre_r, result) do
|
defp result_calculations(results, player_pre_r) do
|
||||||
result =
|
{variance_estimate_acc, result_effect_acc} =
|
||||||
Map.new
|
Enum.reduce(results, {0.0, 0.0}, fn result, {variance_estimate_acc, result_effect_acc} ->
|
||||||
|> Map.put(:score, Result.score(result))
|
opponent_rd_g =
|
||||||
|> Map.put(:opponent_r, Result.opponent_rating(result))
|
result
|
||||||
|> Map.put(:opponent_rd, Result.opponent_rating_deviation(result))
|
|> Result.opponent_rating_deviation
|
||||||
|> Map.put(:opponent_rd_g, calc_g(Result.opponent_rating_deviation(result)))
|
|> calc_g
|
||||||
|
|
||||||
Map.put(result, :e, calc_e(player_pre_r, result.opponent_r, result.opponent_rd_g))
|
win_probability = calc_e(player_pre_r, Result.opponent_rating(result), opponent_rd_g)
|
||||||
end
|
|
||||||
|
|
||||||
# Calculation of the estimated variance of the player's rating based on game outcomes
|
{
|
||||||
defp calc_variance_estimate(results) do
|
variance_estimate_acc + :math.pow(opponent_rd_g, 2) * win_probability * (1 - win_probability),
|
||||||
results
|
result_effect_acc + opponent_rd_g * (Result.score(result) - win_probability)
|
||||||
|> Enum.reduce(0.0, fn result, acc ->
|
}
|
||||||
acc + :math.pow(result.opponent_rd_g, 2) * result.e * (1 - result.e)
|
end)
|
||||||
end)
|
|
||||||
|> :math.pow(-1)
|
{:math.pow(variance_estimate_acc, -1), result_effect_acc}
|
||||||
end
|
end
|
||||||
|
|
||||||
defp calc_delta(results_effect, variance_est) do
|
defp calc_delta(results_effect, variance_est) do
|
||||||
@ -132,12 +128,6 @@ defmodule Glicko do
|
|||||||
:math.exp(a / 2)
|
:math.exp(a / 2)
|
||||||
end
|
end
|
||||||
|
|
||||||
defp calc_results_effect(results) do
|
|
||||||
Enum.reduce(results, 0.0, fn result, acc ->
|
|
||||||
acc + result.opponent_rd_g * (result.score - result.e)
|
|
||||||
end)
|
|
||||||
end
|
|
||||||
|
|
||||||
defp calc_new_player_rating(results_effect, player_pre_r, player_post_rd) do
|
defp calc_new_player_rating(results_effect, player_pre_r, player_post_rd) do
|
||||||
player_pre_r + :math.pow(player_post_rd, 2) * results_effect
|
player_pre_r + :math.pow(player_post_rd, 2) * results_effect
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user