/// <summary>
        /// VMP message to 'probsTrue'
        /// </summary>
        /// <param name="sample">Incoming message from 'sample'. Must be a proper distribution.  If any element is uniform, the result will be uniform.</param>
        /// <returns>The outgoing VMP message to the 'probsTrue' argument</returns>
        /// <remarks><para>
        /// The outgoing message is the exponential of the average log-factor value, where the average is over all arguments except 'probsTrue'.
        /// The formula is <c>exp(sum_(sample) p(sample) log(factor(sample,probsTrue)))</c>.
        /// </para></remarks>
        /// <exception cref="ImproperMessageException"><paramref name="sample"/> is not a proper distribution</exception>
        public static SparseBetaList ProbsTrueAverageLogarithm([Proper] SparseBernoulliListBase sample)
        {
            // E[x*log(p) + (1-x)*log(1-p)] = E[x]*log(p) + (1-E[x])*log(1-p)
            SparseVector ex = sample.GetProbTrueVector();

            return(new SparseBetaList((SparseVector)(ex + 1), (SparseVector)(2 - ex)));
        }
        /// <summary>
        /// The maximum 'difference' between this instance and that instance.
        /// This returns the maximum absolute difference between the Log-odds of any element
        /// </summary>
        /// <param name="that">The other distribution</param>
        /// <returns>The resulting maximum difference</returns>
        /// <remarks><c>a.MaxDiff(b) == b.MaxDiff(a)</c></remarks>
        public double MaxDiff(object that)
        {
            SparseBernoulliListBase sbl = (SparseBernoulliListBase)that;
            // differences in log odds
            SparseVector absDiff = SparseVector.Zero(LogOddsVector.Count);

            absDiff.SetToFunction(LogOddsVector, sbl.LogOddsVector, (a, b) => MMath.AbsDiff(a, b));
            return(absDiff.Max());
        }
        //-- VMP -------------------------------------------------------------------------------------------

        /// <summary>
        /// Evidence message for VMP
        /// </summary>
        /// <param name="sample">Incoming message from 'sample'. Must be a proper distribution.  If any element is uniform, the result will be uniform.</param>
        /// <param name="probsTrue">Incoming message from 'probsTrue'. Must be a proper distribution.  If any element is uniform, the result will be uniform.</param>
        /// <param name="MeanLog">Buffer 'MeanLog'.</param>
        /// <param name="MeanLogOneMinus">Buffer 'MeanLogOneMinus'.</param>
        /// <returns>Average of the factor's log-value across the given argument distributions</returns>
        /// <remarks><para>
        /// The formula for the result is <c>sum_(sample,probsTrue) p(sample,probsTrue) log(factor(sample,probsTrue))</c>.
        /// Adding up these values across all factors and variables gives the log-evidence estimate for VMP.
        /// </para></remarks>
        /// <exception cref="ImproperMessageException"><paramref name="sample"/> is not a proper distribution</exception>
        /// <exception cref="ImproperMessageException"><paramref name="probsTrue"/> is not a proper distribution</exception>
        public static double AverageLogFactor([Proper] SparseBernoulliListBase sample,
                                              [Proper] SparseBetaList probsTrue, SparseVector MeanLog, SparseVector MeanLogOneMinus)
        {
            //var MeanLogOneMinus = probsTrue.GetMeanLogOneMinus();
            var p   = sample.GetProbTrueVector();
            var res = p * MeanLog + (1 - p) * MeanLogOneMinus;

            return(res.Sum());
        }
 /// <summary>
 /// Evidence message for VMP
 /// </summary>
 /// <param name="sample">Incoming message from 'sample'. Must be a proper distribution.  If any element is uniform, the result will be uniform.</param>
 /// <param name="probsTrue">Constant value for 'probsTrue'.</param>
 /// <param name="MeanLog">Buffer 'MeanLog'.</param>
 /// <param name="MeanLogOneMinus">Buffer 'MeanLogOneMinus'.</param>
 /// <returns>Average of the factor's log-value across the given argument distributions</returns>
 /// <remarks><para>
 /// The formula for the result is <c>sum_(sample) p(sample) log(factor(sample,probsTrue))</c>.
 /// Adding up these values across all factors and variables gives the log-evidence estimate for VMP.
 /// </para></remarks>
 /// <exception cref="ImproperMessageException"><paramref name="sample"/> is not a proper distribution</exception>
 public static double AverageLogFactor([Proper] SparseBernoulliListBase sample, SparseVector probsTrue, SparseVector MeanLog, SparseVector MeanLogOneMinus)
 {
     return(AverageLogFactor(sample, SparseBetaList.PointMass(probsTrue), MeanLog, MeanLogOneMinus));
 }