/// <summary>EP message to <c>indexOfMaximumDouble</c>.</summary> /// <param name="list">Incoming message from <c>list</c>. Must be a proper distribution. If any element is uniform, the result will be uniform.</param> /// <param name="result">Modified to contain the outgoing message.</param> /// <returns> /// <paramref name="result" /> /// </returns> /// <remarks> /// <para>The outgoing message is a distribution matching the moments of <c>indexOfMaximumDouble</c> as the random arguments are varied. The formula is <c>proj[p(indexOfMaximumDouble) sum_(list) p(list) factor(indexOfMaximumDouble,list)]/p(indexOfMaximumDouble)</c>.</para> /// </remarks> /// <exception cref="ImproperMessageException"> /// <paramref name="list" /> is not a proper distribution.</exception> public static Discrete IndexOfMaximumDoubleAverageConditional2(IList <Gaussian> list, Discrete result) { // Fast approximate calculation of downward message // TODO: sort list first // best accuracy is achieved by processing in decreasing order of means Gaussian max = list[0]; Vector probs = result.GetWorkspace(); probs[0] = 1.0; for (int i = 1; i < list.Count; i++) { Gaussian A = max; Gaussian B = list[i]; double pMax = ProbGreater(A, B).GetProbTrue(); for (int j = 0; j < i; j++) { probs[j] *= pMax; } probs[i] = 1 - pMax; max = MaxGaussianOp.MaxAverageConditional(Gaussian.Uniform(), A, B); } result.SetProbs(probs); return(result); }
/// <summary>EP message to <c>indexOfMaximumDouble</c>.</summary> /// <param name="list">Incoming message from <c>list</c>. Must be a proper distribution. If any element is uniform, the result will be uniform.</param> /// <param name="result">Modified to contain the outgoing message.</param> /// <returns> /// <paramref name="result" /> /// </returns> /// <remarks> /// <para>The outgoing message is a distribution matching the moments of <c>indexOfMaximumDouble</c> as the random arguments are varied. The formula is <c>proj[p(indexOfMaximumDouble) sum_(list) p(list) factor(indexOfMaximumDouble,list)]/p(indexOfMaximumDouble)</c>.</para> /// </remarks> /// <exception cref="ImproperMessageException"> /// <paramref name="list" /> is not a proper distribution.</exception> public static Discrete IndexOfMaximumDoubleAverageConditional([SkipIfAnyUniform, Proper] IList <Gaussian> list, Discrete result) { // Fast approximate calculation of downward message if (list.Count <= 1) { return(result); } Gaussian[] maxBefore = new Gaussian[list.Count]; maxBefore[1] = list[0]; for (int i = 2; i < list.Count; i++) { maxBefore[i] = MaxGaussianOp.MaxAverageConditional(Gaussian.Uniform(), maxBefore[i - 1], list[i - 1]); } Gaussian[] maxAfter = new Gaussian[list.Count]; maxAfter[list.Count - 2] = list[list.Count - 1]; for (int i = list.Count - 3; i >= 0; i--) { maxAfter[i] = MaxGaussianOp.MaxAverageConditional(Gaussian.Uniform(), maxAfter[i + 1], list[i + 1]); } Vector probs = result.GetWorkspace(); probs[0] = ProbGreater(list[0], maxAfter[0]).GetProbTrue(); int last = list.Count - 1; probs[last] = ProbGreater(list[last], maxBefore[last]).GetProbTrue(); for (int i = 1; i < last; i++) { Gaussian maxOther = MaxGaussianOp.MaxAverageConditional(Gaussian.Uniform(), maxBefore[i], maxAfter[i]); probs[i] = ProbGreater(list[i], maxOther).GetProbTrue(); } result.SetProbs(probs); return(result); }