public GaussianPriorFactor(double mean, double variance, Variable <GaussianDistribution> variable) : base(string.Format("Prior value going to {0}", variable)) { mNewMessage = new GaussianDistribution(mean, Math.Sqrt(variance)); CreateVariableToMessageBinding(variable, new Message <GaussianDistribution>(GaussianDistribution.FromPrecisionMean(0, 0), "message from {0} to {1}", this, variable)); }
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); }
protected override double UpdateMessage(Message <GaussianDistribution> message, Variable <GaussianDistribution> variable) { var oldMarginal = variable.Value.Clone(); var oldMessage = message; var newMarginal = GaussianDistribution.FromPrecisionMean( oldMarginal.PrecisionMean + mNewMessage.PrecisionMean - oldMessage.Value.PrecisionMean, oldMarginal.Precision + mNewMessage.Precision - oldMessage.Value.Precision); variable.Value = newMarginal; message.Value = mNewMessage; return(oldMarginal - newMarginal); }
public TrueSkillFactorGraph(GameInfo gameInfo, IEnumerable <IDictionary <TPlayer, Rating> > teams, int[] teamRanks) { mPriorLayer = new PlayerPriorValuesToSkillsLayer <TPlayer>(this, teams); GameInfo = gameInfo; VariableFactory = new VariableFactory <GaussianDistribution>(() => GaussianDistribution.FromPrecisionMean(0, 0)); mLayers = new List <FactorGraphLayerBase <GaussianDistribution> > { mPriorLayer, new PlayerSkillsToPerformancesLayer <TPlayer>(this), new PlayerPerformancesToTeamPerformancesLayer <TPlayer>(this), new IteratedTeamDifferencesInnerLayer <TPlayer>( this, new TeamPerformancesToTeamPerformanceDifferencesLayer <TPlayer>(this), new TeamDifferencesComparisonLayer <TPlayer>(this, teamRanks)) }; }
/// <summary> /// Get a partial update of a rating. /// </summary> /// <param name="prior">The rating before adjustment.</param> /// <param name="fullPosterior">The rating after adjustment.</param> /// <param name="updatePercentage">The percentage of the update to apply.</param> /// <returns>The resulting rating after a partial update.</returns> public static Rating GetPartialUpdate(Rating prior, Rating fullPosterior, double updatePercentage) { var priorGaussian = new GaussianDistribution(prior.Mean, prior.StandardDeviation); var posteriorGaussian = new GaussianDistribution(fullPosterior.Mean, fullPosterior.StandardDeviation); var precisionDifference = posteriorGaussian.Precision - priorGaussian.Precision; var partialPrecisionDifference = updatePercentage * precisionDifference; var precisionMeanDifference = posteriorGaussian.PrecisionMean - priorGaussian.PrecisionMean; double partialPrecisionMeanDifference = updatePercentage * precisionMeanDifference; GaussianDistribution partialPosteriorGaussian = GaussianDistribution.FromPrecisionMean( priorGaussian.PrecisionMean + partialPrecisionMeanDifference, priorGaussian.Precision + partialPrecisionDifference); return(new Rating(partialPosteriorGaussian.Mean, partialPosteriorGaussian.StandardDeviation, prior.mConservativeStandardDeviationMultiplier)); }
private double UpdateHelper(double[] weights, double[] weightsSquared, IList <Message <GaussianDistribution> > messages, IList <Variable <GaussianDistribution> > variables) { var message0 = messages[0].Value.Clone(); var marginal0 = variables[0].Value.Clone(); var inverseOfNewPrecisionSum = 0.0; var anotherInverseOfNewPrecisionSum = 0.0; var weightedMeanSum = 0.0; var anotherWeightedMeanSum = 0.0; for (var i = 0; i < weightsSquared.Length; ++i) { inverseOfNewPrecisionSum += weightsSquared[i] / (variables[i + 1].Value.Precision - messages[i + 1].Value.Precision); var diff = (variables[i + 1].Value / messages[i + 1].Value); anotherInverseOfNewPrecisionSum += weightsSquared[i] / diff.Precision; weightedMeanSum += weights[i] * (variables[i + 1].Value.PrecisionMean - messages[i + 1].Value.PrecisionMean) / (variables[i + 1].Value.Precision - messages[i + 1].Value.Precision); anotherWeightedMeanSum += weights[i] * diff.PrecisionMean / diff.Precision; } var newPrecision = 1.0 / inverseOfNewPrecisionSum; var anotherNewPrecision = 1.0 / anotherInverseOfNewPrecisionSum; var newPrecisionMean = newPrecision * weightedMeanSum; var anotherNewPrecisionMean = anotherNewPrecision * anotherWeightedMeanSum; var newMessage = GaussianDistribution.FromPrecisionMean(newPrecisionMean, newPrecision); var oldMarginalWithoutMessage = marginal0 / message0; var newMarginal = oldMarginalWithoutMessage * newMessage; messages[0].Value = newMessage; variables[0].Value = newMarginal; return(newMarginal - marginal0); }
private double UpdateHelper(Message <GaussianDistribution> message1, Message <GaussianDistribution> message2, Variable <GaussianDistribution> variable1, Variable <GaussianDistribution> variable2) { var message1Value = message1.Value.Clone(); var message2Value = message2.Value.Clone(); var marginal1 = variable1.Value.Clone(); var marginal2 = variable2.Value.Clone(); var a = mPrecision / (mPrecision + marginal2.Precision - message2Value.Precision); var newMessage = GaussianDistribution.FromPrecisionMean( a * (marginal2.PrecisionMean - message2Value.PrecisionMean), a * (marginal2.Precision - message2Value.Precision)); var oldMarginalWithoutMessage = marginal1 / message1Value; var newMarginal = oldMarginalWithoutMessage * newMessage; message1.Value = newMessage; variable1.Value = newMarginal; return(newMarginal - marginal1); }