/// <summary>
        /// Infers parameters for a given cold item.
        /// </summary>
        /// <param name="itemFeatures">The item features.</param>
        /// <returns>A distribution over the item parameters.</returns>
        public ItemParameterDistribution InferItemParameters(SparseFeatureVector itemFeatures)
        {
            ItemParameterDistribution result;

            if (this.itemFeatureParameterPosteriors.FeatureCount == 0)
            {
                Debug.Assert(
                    itemFeatures.FeatureCount == 0,
                    "The number of item features passed must be equal to the number of item features learned.");

                result = this.itemParameterDistributionAverage;
            }
            else
            {
                GaussianArray traits;
                Gaussian      bias;

                AlgorithmUtils.AddFeatureContribution(
                    this.itemParameterDistributionAverage,
                    this.itemFeatureParameterPosteriors,
                    itemFeatures,
                    out traits,
                    out bias);

                result = new ItemParameterDistribution(traits, bias);
            }

            return(result);
        }
        /// <summary>
        /// Sets up the inference algorithm to operate on a single item given the posteriors over the parameters of the item.
        /// </summary>
        /// <param name="itemParameterPosteriors">The posteriors over the parameters of the item.</param>
        private void SetupItemFromPosteriors(ItemParameterDistribution itemParameterPosteriors)
        {
            Debug.Assert(itemParameterPosteriors != null, "Valid item parameter posteriors must be provided.");

            this.inferenceAlgorithm.ItemCount       = 1;
            this.inferenceAlgorithm.ItemTraitsPrior = new GaussianMatrix(new[] { itemParameterPosteriors.Traits });
            this.inferenceAlgorithm.ItemBiasPrior   = new GaussianArray(new[] { itemParameterPosteriors.Bias });
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="ColdUserItemParameterAlgorithm"/> class.
 /// </summary>
 /// <param name="userFeatureParameterPosteriors">The posteriors over the user feature related parameters learned during community training.</param>
 /// <param name="itemFeatureParameterPosteriors">The posteriors over the item feature related parameters learned during community training.</param>
 /// <param name="userParameterDistributionAverage">The average trait, bias, and threshold posterior over all users in training.</param>
 /// <param name="itemParameterDistributionAverage">The average trait and bias posterior over all items in training.</param>
 public ColdUserItemParameterAlgorithm(
     FeatureParameterDistribution userFeatureParameterPosteriors,
     FeatureParameterDistribution itemFeatureParameterPosteriors,
     UserParameterDistribution userParameterDistributionAverage,
     ItemParameterDistribution itemParameterDistributionAverage)
 {
     this.userFeatureParameterPosteriors   = userFeatureParameterPosteriors;
     this.itemFeatureParameterPosteriors   = itemFeatureParameterPosteriors;
     this.userParameterDistributionAverage = userParameterDistributionAverage;
     this.itemParameterDistributionAverage = itemParameterDistributionAverage;
 }
        /// <summary>
        /// Infers the distribution over the rating which a given user will give to an item.
        /// </summary>
        /// <param name="userParameterPosteriors">The posteriors over user parameters.</param>
        /// <param name="itemParameterPosteriors">The posteriors over item parameters.</param>
        /// <returns>The distribution over the rating.</returns>
        public Discrete InferRatingDistribution(
            UserParameterDistribution userParameterPosteriors, ItemParameterDistribution itemParameterPosteriors)
        {
            Debug.Assert(userParameterPosteriors != null && itemParameterPosteriors != null, "A valid posteriors must be provided.");
            Debug.Assert(
                userParameterPosteriors.Traits.Count == itemParameterPosteriors.Traits.Count,
                "Given posteriors should have the same associated number of traits.");

            this.inferenceAlgorithm.TraitCount = userParameterPosteriors.Traits.Count;

            this.SetupUserFromPosteriors(userParameterPosteriors);
            this.SetupItemFromPosteriors(itemParameterPosteriors);

            this.inferenceAlgorithm.ObservationCount = 1;
            this.inferenceAlgorithm.UserIds          = new[] { 0 };
            this.inferenceAlgorithm.ItemIds          = new[] { 0 };

            this.inferenceAlgorithm.Execute(1);

            return(this.inferenceAlgorithm.RatingsMarginal()[0]);
        }