コード例 #1
0
        private double UpdateHelper(Message <GaussianDistribution> message1, Message <GaussianDistribution> message2,
                                    Variable <GaussianDistribution> variable1, Variable <GaussianDistribution> variable2)
        {
            GaussianDistribution message1Value = message1.Value.Clone();
            GaussianDistribution message2Value = message2.Value.Clone();

            GaussianDistribution marginal1 = variable1.Value.Clone();
            GaussianDistribution marginal2 = variable2.Value.Clone();

            double a = _Precision / (_Precision + marginal2.Precision - message2Value.Precision);

            GaussianDistribution newMessage = GaussianDistribution.FromPrecisionMean(
                a * (marginal2.PrecisionMean - message2Value.PrecisionMean),
                a * (marginal2.Precision - message2Value.Precision));

            GaussianDistribution oldMarginalWithoutMessage = marginal1 / message1Value;

            GaussianDistribution newMarginal = oldMarginalWithoutMessage * newMessage;

            /// Update the message and marginal

            message1.Value  = newMessage;
            variable1.Value = newMarginal;

            /// Return the difference in the new marginal
            return(newMarginal - marginal1);
        }
コード例 #2
0
ファイル: GaussianWithinFactor.cs プロジェクト: paviad/Skills
        protected override double UpdateMessage(Message <GaussianDistribution> message,
                                                Variable <GaussianDistribution> variable)
        {
            GaussianDistribution oldMarginal         = variable.Value.Clone();
            GaussianDistribution oldMessage          = message.Value.Clone();
            GaussianDistribution messageFromVariable = oldMarginal / oldMessage;

            double c = messageFromVariable.Precision;
            double d = messageFromVariable.PrecisionMean;

            double sqrtC    = Math.Sqrt(c);
            double dOnSqrtC = d / sqrtC;

            double epsilonTimesSqrtC = _Epsilon * sqrtC;

            d = messageFromVariable.PrecisionMean;

            double denominator      = 1.0 - TruncatedGaussianCorrectionFunctions.WWithinMargin(dOnSqrtC, epsilonTimesSqrtC);
            double newPrecision     = c / denominator;
            double newPrecisionMean = (d +
                                       sqrtC *
                                       TruncatedGaussianCorrectionFunctions.VWithinMargin(dOnSqrtC, epsilonTimesSqrtC)) /
                                      denominator;

            GaussianDistribution newMarginal = GaussianDistribution.FromPrecisionMean(newPrecisionMean, newPrecision);
            GaussianDistribution newMessage  = oldMessage * newMarginal / oldMarginal;

            /// Update the message and marginal
            message.Value  = newMessage;
            variable.Value = newMarginal;

            /// Return the difference in the new marginal
            return(newMarginal - oldMarginal);
        }
コード例 #3
0
 public GaussianPriorFactor(double mean, double variance, Variable <GaussianDistribution> variable)
     : base(String.Format("Prior value going to {0}", variable))
 {
     _NewMessage = new GaussianDistribution(mean, Math.Sqrt(variance));
     CreateVariableToMessageBinding(variable,
                                    new Message <GaussianDistribution>(
                                        GaussianDistribution.FromPrecisionMean(0, 0), "message from {0} to {1}",
                                        this, variable));
 }
コード例 #4
0
        private double UpdateHelper(double[] weights, double[] weightsSquared,
                                    IList <Message <GaussianDistribution> > messages,
                                    IList <Variable <GaussianDistribution> > variables)
        {
            // Potentially look at http://mathworld.wolfram.com/NormalSumDistribution.html for clues as
            // to what it's doing

            GaussianDistribution message0  = messages[0].Value.Clone();
            GaussianDistribution marginal0 = variables[0].Value.Clone();

            // The math works out so that 1/newPrecision = sum of a_i^2 /marginalsWithoutMessages[i]
            double inverseOfNewPrecisionSum        = 0.0;
            double anotherInverseOfNewPrecisionSum = 0.0;
            double weightedMeanSum        = 0.0;
            double anotherWeightedMeanSum = 0.0;

            for (int i = 0; i < weightsSquared.Length; i++)
            {
                // These flow directly from the paper

                inverseOfNewPrecisionSum += weightsSquared[i] /
                                            (variables[i + 1].Value.Precision - messages[i + 1].Value.Precision);

                GaussianDistribution 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;
            }

            double newPrecision        = 1.0 / inverseOfNewPrecisionSum;
            double anotherNewPrecision = 1.0 / anotherInverseOfNewPrecisionSum;

            double newPrecisionMean        = newPrecision * weightedMeanSum;
            double anotherNewPrecisionMean = anotherNewPrecision * anotherWeightedMeanSum;

            GaussianDistribution newMessage = GaussianDistribution.FromPrecisionMean(newPrecisionMean, newPrecision);
            GaussianDistribution oldMarginalWithoutMessage = marginal0 / message0;

            GaussianDistribution newMarginal = oldMarginalWithoutMessage * newMessage;

            /// Update the message and marginal

            messages[0].Value  = newMessage;
            variables[0].Value = newMarginal;

            /// Return the difference in the new marginal
            return(newMarginal - marginal0);
        }
コード例 #5
0
        protected override double UpdateMessage(Message <GaussianDistribution> message,
                                                Variable <GaussianDistribution> variable)
        {
            GaussianDistribution           oldMarginal = variable.Value.Clone();
            Message <GaussianDistribution> oldMessage  = message;
            GaussianDistribution           newMarginal =
                GaussianDistribution.FromPrecisionMean(
                    oldMarginal.PrecisionMean + _NewMessage.PrecisionMean - oldMessage.Value.PrecisionMean,
                    oldMarginal.Precision + _NewMessage.Precision - oldMessage.Value.Precision);

            variable.Value = newMarginal;
            message.Value  = _NewMessage;
            return(oldMarginal - newMarginal);
        }
コード例 #6
0
        public TrueSkillFactorGraph(GameInfo gameInfo, IEnumerable <IDictionary <TPlayer, Rating> > teams, int[] teamRanks)
        {
            _PriorLayer     = new PlayerPriorValuesToSkillsLayer <TPlayer>(this, teams);
            GameInfo        = gameInfo;
            VariableFactory =
                new VariableFactory <GaussianDistribution>(() => GaussianDistribution.FromPrecisionMean(0, 0));

            _Layers = new List <FactorGraphLayerBase <GaussianDistribution> >
            {
                _PriorLayer,
                new PlayerSkillsToPerformancesLayer <TPlayer>(this),
                new PlayerPerformancesToTeamPerformancesLayer <TPlayer>(this),
                new IteratedTeamDifferencesInnerLayer <TPlayer>(
                    this,
                    new TeamPerformancesToTeamPerformanceDifferencesLayer <TPlayer>(this),
                    new TeamDifferencesComparisonLayer <TPlayer>(this, teamRanks))
            };
        }
コード例 #7
0
ファイル: Rating.cs プロジェクト: paviad/Skills
        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);

            // From a clarification email from Ralf Herbrich:
            // "the idea is to compute a linear interpolation between the prior and posterior skills of each player
            //  ... in the canonical space of parameters"

            double precisionDifference        = posteriorGaussian.Precision - priorGaussian.Precision;
            double partialPrecisionDifference = updatePercentage * precisionDifference;

            double precisionMeanDifference        = posteriorGaussian.PrecisionMean - priorGaussian.PrecisionMean;
            double partialPrecisionMeanDifference = updatePercentage * precisionMeanDifference;

            GaussianDistribution partialPosteriorGaussion = GaussianDistribution.FromPrecisionMean(
                priorGaussian.PrecisionMean + partialPrecisionMeanDifference,
                priorGaussian.Precision + partialPrecisionDifference);

            return(new Rating(partialPosteriorGaussion.Mean, partialPosteriorGaussion.StandardDeviation,
                              prior._ConservativeStandardDeviationMultiplier));
        }