public void IndexOfMaximumFastTest() { int n = 5; Range item = new Range(n).Named("item"); var priors = Variable <Gaussian> .Array(item); priors.ObservedValue = Util.ArrayInit(n, i => Gaussian.FromMeanAndVariance(i * 0.5, i)); var x = Variable.Array <double>(item).Named("x"); x[item] = Variable <double> .Random(priors[item]); var y = Variable <int> .Factor(MMath.IndexOfMaximumDouble, x); InferenceEngine engine = new InferenceEngine(); engine.ShowProgress = false; string format = "f4"; var yActual = engine.Infer <Discrete>(y); Console.WriteLine("Quadratic: {0}", yActual.ToString(format)); // Monte Carlo estimate Rand.Restart(0); DiscreteEstimator est = new DiscreteEstimator(n); for (int iter = 0; iter < 100000; iter++) { double[] samples = Util.ArrayInit(n, i => priors.ObservedValue[i].Sample()); int argmax = MMath.IndexOfMaximumDouble(samples); est.Add(argmax); } var yExpected = est.GetDistribution(Discrete.Uniform(n)); Console.WriteLine("Sampling: {0}", yExpected.ToString(format)); Assert.True(yExpected.MaxDiff(yActual) < 1e-2); engine.Compiler.GivePriorityTo(typeof(IndexOfMaximumOp_Fast)); yActual = engine.Infer <Discrete>(y); Console.WriteLine("Linear: {0}", yActual.ToString(format)); Assert.True(yExpected.MaxDiff(yActual) < 1e-2); bool compareApproximation = false; if (compareApproximation) { var yPost2 = IndexOfMaximumOp_Fast.IndexOfMaximumDoubleAverageConditional(priors.ObservedValue, Discrete.Uniform(n)); Console.WriteLine(yPost2); var yPost3 = IndexOfMaximumOp_Fast.IndexOfMaximumDoubleAverageConditional2(priors.ObservedValue, Discrete.Uniform(n)); Console.WriteLine(yPost3); } }
/// <summary> /// Estimates rating distribution in the given set of observations. /// </summary> /// <param name="observations">The set of observations for which the rating distribution should be estimated.</param> /// <returns>The estimated rating distribution.</returns> /// <remarks>The support of the resulting distribution is shifted by -MinRating to handle negative rating values.</remarks> private Discrete EstimateRatingDistribution(IEnumerable <RatedUserItem> observations) { // TODO: this code should be rewritten properly (without offseting ratings) as soon as Discrete supports negative values var estimator = new DiscreteEstimator(this.starRatingInfo.MaxStarRating - this.starRatingInfo.MinStarRating + 1); foreach (RatedUserItem observation in observations) { estimator.Add(observation.Rating - this.starRatingInfo.MinStarRating); } var result = Discrete.Uniform(this.starRatingInfo.MaxStarRating - this.starRatingInfo.MinStarRating + 1); return(estimator.GetDistribution(result)); }