protected override double UpdateMessage(Message <GaussianDistribution> message, Variable <GaussianDistribution> variable) { var oldMarginal = variable.Value.Clone(); var oldMessage = message.Value.Clone(); var messageFromVar = oldMarginal / oldMessage; var c = messageFromVar.Precision; var d = messageFromVar.PrecisionMean; var sqrtC = Math.Sqrt(c); var dOnSqrtC = d / sqrtC; var epsilonTimesSqrtC = mEpsilon * sqrtC; d = messageFromVar.PrecisionMean; var denom = 1.0 - TruncatedGaussianCorrectionFunctions.WExceedsMargin(dOnSqrtC, epsilonTimesSqrtC); var newPrecision = c / denom; var newPrecisionMean = (d + sqrtC * TruncatedGaussianCorrectionFunctions.VExceedsMargin(dOnSqrtC, epsilonTimesSqrtC)) / denom; var newMarginal = GaussianDistribution.FromPrecisionMean(newPrecisionMean, newPrecision); var newMessage = oldMessage * newMarginal / oldMarginal; message.Value = newMessage; variable.Value = newMarginal; return(newMarginal - oldMarginal); }
private static void UpdatePlayerRatings <TPlayer>(GameInfo gameInfo, IDictionary <TPlayer, Rating> newPlayerRatings, IDictionary <TPlayer, Rating> selfTeam, IDictionary <TPlayer, Rating> otherTeam, PairwiseComparison selfToOtherTeamComparison) { var drawMargin = DrawMargin.GetDrawMarginFromDrawProbability(gameInfo.DrawProbability, gameInfo.Beta); var betaSquared = gameInfo.Beta * gameInfo.Beta; var tauSquared = gameInfo.DynamicsFactor * gameInfo.DynamicsFactor; var totalPlayers = selfTeam.Count() + otherTeam.Count(); var selfMeanSum = selfTeam.Values.Sum(r => r.Mean); var otherTeamMeanSum = otherTeam.Values.Sum(r => r.Mean); var c = Math.Sqrt(selfTeam.Values.Sum(r => r.StandardDeviation * r.StandardDeviation) + otherTeam.Values.Sum(r => r.StandardDeviation * r.StandardDeviation) + totalPlayers * betaSquared); var winningMean = selfMeanSum; var losingMean = otherTeamMeanSum; if (selfToOtherTeamComparison == PairwiseComparison.Lose) { winningMean = otherTeamMeanSum; losingMean = selfMeanSum; } var meanDelta = winningMean - losingMean; double v, w, rankMultiplier; if (selfToOtherTeamComparison != PairwiseComparison.Draw) { v = TruncatedGaussianCorrectionFunctions.VExceedsMargin(meanDelta, drawMargin, c); w = TruncatedGaussianCorrectionFunctions.WExceedsMargin(meanDelta, drawMargin, c); rankMultiplier = (int)selfToOtherTeamComparison; } else { v = TruncatedGaussianCorrectionFunctions.VWithinMargin(meanDelta, drawMargin, c); w = TruncatedGaussianCorrectionFunctions.WWithinMargin(meanDelta, drawMargin, c); rankMultiplier = 1; } foreach (var teamPlayerRatingPair in selfTeam) { Rating previousPlayerRating = teamPlayerRatingPair.Value; var meanMultiplier = ((previousPlayerRating.StandardDeviation * previousPlayerRating.StandardDeviation) + tauSquared) / c; var stdDevMultiplier = ((previousPlayerRating.StandardDeviation * previousPlayerRating.StandardDeviation) + tauSquared) / (c * c); var playerMeanDelta = rankMultiplier * meanMultiplier * v; var newMean = previousPlayerRating.Mean + playerMeanDelta; var newStdDev = Math.Sqrt(((previousPlayerRating.StandardDeviation * previousPlayerRating.StandardDeviation) + tauSquared) * (1 - w * stdDevMultiplier)); newPlayerRatings[teamPlayerRatingPair.Key] = new Rating(newMean, newStdDev); } }
private static Rating CalculateNewRating(GameInfo gameInfo, Rating selfRating, Rating opponentRating, PairwiseComparison comparison) { var drawMargin = DrawMargin.GetDrawMarginFromDrawProbability(gameInfo.DrawProbability, gameInfo.Beta); var c = Math.Sqrt((selfRating.StandardDeviation * selfRating.StandardDeviation) + (opponentRating.StandardDeviation * opponentRating.StandardDeviation) + 2 * (gameInfo.Beta * gameInfo.Beta)); var winningMean = selfRating.Mean; var losingMean = opponentRating.Mean; if (comparison == PairwiseComparison.Lose) { winningMean = opponentRating.Mean; losingMean = selfRating.Mean; } var meanDelta = winningMean - losingMean; double v; double w; double rankMultiplier; if (comparison != PairwiseComparison.Draw) { v = TruncatedGaussianCorrectionFunctions.VExceedsMargin(meanDelta, drawMargin, c); w = TruncatedGaussianCorrectionFunctions.WExceedsMargin(meanDelta, drawMargin, c); rankMultiplier = (int)comparison; } else { v = TruncatedGaussianCorrectionFunctions.VWithinMargin(meanDelta, drawMargin, c); w = TruncatedGaussianCorrectionFunctions.WWithinMargin(meanDelta, drawMargin, c); rankMultiplier = 1; } var meanMultiplier = ((selfRating.StandardDeviation * selfRating.StandardDeviation) + (gameInfo.DynamicsFactor * gameInfo.DynamicsFactor)) / c; var varianceWithDynamics = (selfRating.StandardDeviation * selfRating.StandardDeviation) + (gameInfo.DynamicsFactor * gameInfo.DynamicsFactor); var stdDevMultiplier = varianceWithDynamics / (c * c); var newMean = selfRating.Mean + (rankMultiplier * meanMultiplier * v); var newStdDev = Math.Sqrt(varianceWithDynamics * (1 - w * stdDevMultiplier)); return(new Rating(newMean, newStdDev)); }