Improved accuracy of MMath.WeightedAverage and GaussianProductOp (#395)

* RpropBufferData.EnsureConvergence = false
* GetJaggedItemsOp and GetItemsFromJaggedOp use IReadOnlyList
This commit is contained in:
Tom Minka 2022-02-16 14:58:03 +00:00 коммит произвёл GitHub
Родитель 5b23c2c517
Коммит 45d2e593ba
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
13 изменённых файлов: 606 добавлений и 243 удалений

Просмотреть файл

@ -403,21 +403,19 @@ namespace Microsoft.ML.Probabilistic.Compiler.Transforms
IStatement innerStmt = ist;
while (Containers.IsContainer(innerStmt))
{
if (innerStmt is IForStatement)
innerStmt = ((IForStatement)innerStmt).Body.Statements[0];
else if (innerStmt is IConditionStatement)
innerStmt = ((IConditionStatement)innerStmt).Then.Statements[0];
if (innerStmt is IForStatement ifs)
innerStmt = ifs.Body.Statements[0];
else if (innerStmt is IConditionStatement ics)
innerStmt = ics.Then.Statements[0];
else
throw new Exception();
}
if (innerStmt is IExpressionStatement)
if (innerStmt is IExpressionStatement ies)
{
IExpressionStatement ies = (IExpressionStatement)innerStmt;
if (ies.Expression is IAssignExpression)
if (ies.Expression is IAssignExpression iae)
{
IAssignExpression iae = (IAssignExpression)ies.Expression;
IVariableDeclaration ivd = Recognizer.GetVariableDeclaration(iae.Target);
if (ivd != null && ivd.Name == "skillInSquad_F" && iae.Expression.ToString().Contains("skills_F"))
if (ivd != null && ivd.Name == "NoisyNodes_index0__Q" && iae.Expression.ToString().Contains("nodes_uses_F"))
Console.WriteLine(ivd);
}
}

Просмотреть файл

@ -4851,21 +4851,30 @@ rr = mpf('-0.99999824265582826');
// Instead of scaling by 1/weight2, choose scale so that scale*(weight1+weight2) <= double.MaxValue.
// We know that (weight1+weight2) == weight1
// weight2 < 1
double scale = double.MaxValue / weight1; // scale >= 1 but scale*weight2 < 1
// Below is equivalent to:
// result = (scale * weight1 * value1 + scale * weight2 * value2) / (scale * weight1 + scale * weight2);
double scaleWeight2Value2 = scale * weight2 * value2; // cannot overflow
result = (double.MaxValue * value1 + scaleWeight2Value2) / double.MaxValue;
if (double.IsNaN(result) || double.IsInfinity(result))
const double nextBelowOne = double.MaxValue * ScaleBM1024; // nextBelowOne < 1
if (weight1 < 1)
{
// Overflow happened. Scale down to avoid overflow.
// We scale by a power of 2 to ensure that the result is rounded the same way as above.
// Otherwise, the function would not always be monotonic in value1 and value2.
const double nextBelowOne = double.MaxValue * ScaleBM1024; // nextBelowOne < 1
// IsInfinity(result) implies value1 > 1 so the first term cannot underflow.
// This cannot overflow, because the second term's magnitude is less than 1.
result = (nextBelowOne * value1 + scaleWeight2Value2 * ScaleBM1024) / nextBelowOne;
if (double.IsNaN(result)) return value1 + value2;
double scale = nextBelowOne / weight1; // scale >= 1 but scale*weight2 << 1
double scaleWeight2Value2 = scale * weight2 * value2; // cannot overflow
result = (nextBelowOne * value1 + scaleWeight2Value2) / nextBelowOne; // cannot overflow
}
else
{
double scale = double.MaxValue / weight1; // scale >= 1 but scale*weight2 < 1
// Below is equivalent to:
// result = (scale * weight1 * value1 + scale * weight2 * value2) / (scale * weight1 + scale * weight2);
double scaleWeight2Value2 = scale * weight2 * value2; // cannot overflow
result = (double.MaxValue * value1 + scaleWeight2Value2) / double.MaxValue;
if (double.IsNaN(result) || double.IsInfinity(result))
{
// Overflow happened. Scale down to avoid overflow.
// We scale by a power of 2 to ensure that the result is rounded the same way as above.
// Otherwise, the function would not always be monotonic in value1 and value2.
// IsInfinity(result) implies value1 > 1 so the first term cannot underflow.
// This cannot overflow, because the second term's magnitude is less than 1.
result = (nextBelowOne * value1 + scaleWeight2Value2 * ScaleBM1024) / nextBelowOne;
if (double.IsNaN(result)) return value1 + value2;
}
}
}
else

Просмотреть файл

@ -16687,48 +16687,48 @@
<doc>
<summary>Provides outgoing messages for <see cref="Collection.GetItemsFromJagged{T}(IReadOnlyList{IReadOnlyList{T}}, IReadOnlyList{int}, IReadOnlyList{int})" />, given random arguments to the function.</summary>
</doc>
<message_doc name="LogAverageFactor(IList{T}, IList{IList{T}}, IList{int}, IList{int})">
<message_doc name="LogAverageFactor(IList{T}, IList{IList{T}}, IReadOnlyList{int}, IReadOnlyList{int})">
<summary>Evidence message for EP.</summary>
<param name="items">Incoming message from <c>items</c>.</param>
<param name="array">Incoming message from <c>array</c>.</param>
<param name="indices">Incoming message from <c>indices</c>.</param>
<param name="indices2">Incoming message from <c>indices2</c>.</param>
<param name="indices">Constant value for <c>indices</c>.</param>
<param name="indices2">Constant value for <c>indices2</c>.</param>
<returns>Logarithm of the factor's average value across the given argument distributions.</returns>
<remarks>
<para>The formula for the result is <c>log(sum_(items,array,indices,indices2) p(items,array,indices,indices2) factor(items,array,indices,indices2))</c>.</para>
<para>The formula for the result is <c>log(sum_(items,array) p(items,array) factor(items,array,indices,indices2))</c>.</para>
</remarks>
</message_doc>
<message_doc name="LogEvidenceRatio(IList{T}, IList{IList{T}}, IList{int}, IList{int})">
<message_doc name="LogEvidenceRatio(IList{T}, IList{IList{T}}, IReadOnlyList{int}, IReadOnlyList{int})">
<summary>Evidence message for EP.</summary>
<param name="items">Incoming message from <c>items</c>.</param>
<param name="array">Incoming message from <c>array</c>.</param>
<param name="indices">Incoming message from <c>indices</c>.</param>
<param name="indices2">Incoming message from <c>indices2</c>.</param>
<param name="indices">Constant value for <c>indices</c>.</param>
<param name="indices2">Constant value for <c>indices2</c>.</param>
<returns>Logarithm of the factor's contribution the EP model evidence.</returns>
<remarks>
<para>The formula for the result is <c>log(sum_(items,array,indices,indices2) p(items,array,indices,indices2) factor(items,array,indices,indices2) / sum_items p(items) messageTo(items))</c>. Adding up these values across all factors and variables gives the log-evidence estimate for EP.</para>
<para>The formula for the result is <c>log(sum_(items,array) p(items,array) factor(items,array,indices,indices2) / sum_items p(items) messageTo(items))</c>. Adding up these values across all factors and variables gives the log-evidence estimate for EP.</para>
</remarks>
</message_doc>
<message_doc name="AverageLogFactor(IList{T}, IList{IList{T}}, IList{int}, IList{int})">
<message_doc name="AverageLogFactor(IList{T}, IList{IList{T}}, IReadOnlyList{int}, IReadOnlyList{int})">
<summary>Evidence message for VMP.</summary>
<param name="items">Incoming message from <c>items</c>.</param>
<param name="array">Incoming message from <c>array</c>.</param>
<param name="indices">Incoming message from <c>indices</c>.</param>
<param name="indices2">Incoming message from <c>indices2</c>.</param>
<param name="indices">Constant value for <c>indices</c>.</param>
<param name="indices2">Constant value for <c>indices2</c>.</param>
<returns>Zero.</returns>
<remarks>
<para>In Variational Message Passing, the evidence contribution of a deterministic factor is zero. Adding up these values across all factors and variables gives the log-evidence estimate for VMP.</para>
</remarks>
</message_doc>
<message_doc name="LogAverageFactor{DistributionArrayType, DistributionType}(IList{DistributionType}, IList{DistributionArrayType}, IList{int}, IList{int})">
<message_doc name="LogAverageFactor{DistributionArrayType, DistributionType}(IList{DistributionType}, IList{DistributionArrayType}, IReadOnlyList{int}, IReadOnlyList{int})">
<summary>Evidence message for EP.</summary>
<param name="items">Incoming message from <c>items</c>.</param>
<param name="array">Incoming message from <c>array</c>.</param>
<param name="indices">Incoming message from <c>indices</c>.</param>
<param name="indices2">Incoming message from <c>indices2</c>.</param>
<param name="indices">Constant value for <c>indices</c>.</param>
<param name="indices2">Constant value for <c>indices2</c>.</param>
<returns>Logarithm of the factor's average value across the given argument distributions.</returns>
<remarks>
<para>The formula for the result is <c>log(sum_(items,array,indices,indices2) p(items,array,indices,indices2) factor(items,array,indices,indices2))</c>.</para>
<para>The formula for the result is <c>log(sum_(items,array) p(items,array) factor(items,array,indices,indices2))</c>.</para>
</remarks>
</message_doc>
<message_doc name="AverageLogFactor{DistributionArrayType, DistributionType}(IList{DistributionType}, IList{DistributionArrayType})">
@ -16740,26 +16740,26 @@
<para>In Variational Message Passing, the evidence contribution of a deterministic factor is zero. Adding up these values across all factors and variables gives the log-evidence estimate for VMP.</para>
</remarks>
</message_doc>
<message_doc name="LogAverageFactor{DistributionArrayType, DistributionType}(IList{T}, IList{DistributionArrayType}, IList{int}, IList{int})">
<message_doc name="LogAverageFactor{DistributionArrayType, DistributionType}(IList{T}, IList{DistributionArrayType}, IReadOnlyList{int}, IReadOnlyList{int})">
<summary>Evidence message for EP.</summary>
<param name="items">Incoming message from <c>items</c>.</param>
<param name="array">Incoming message from <c>array</c>.</param>
<param name="indices">Incoming message from <c>indices</c>.</param>
<param name="indices2">Incoming message from <c>indices2</c>.</param>
<param name="indices">Constant value for <c>indices</c>.</param>
<param name="indices2">Constant value for <c>indices2</c>.</param>
<returns>Logarithm of the factor's average value across the given argument distributions.</returns>
<remarks>
<para>The formula for the result is <c>log(sum_(items,array,indices,indices2) p(items,array,indices,indices2) factor(items,array,indices,indices2))</c>.</para>
<para>The formula for the result is <c>log(sum_(items,array) p(items,array) factor(items,array,indices,indices2))</c>.</para>
</remarks>
</message_doc>
<message_doc name="LogEvidenceRatio{DistributionArrayType, DistributionType}(IList{T}, IList{DistributionArrayType}, IList{int}, IList{int})">
<message_doc name="LogEvidenceRatio{DistributionArrayType, DistributionType}(IList{T}, IList{DistributionArrayType}, IReadOnlyList{int}, IReadOnlyList{int})">
<summary>Evidence message for EP.</summary>
<param name="items">Incoming message from <c>items</c>.</param>
<param name="array">Incoming message from <c>array</c>.</param>
<param name="indices">Incoming message from <c>indices</c>.</param>
<param name="indices2">Incoming message from <c>indices2</c>.</param>
<param name="indices">Constant value for <c>indices</c>.</param>
<param name="indices2">Constant value for <c>indices2</c>.</param>
<returns>Logarithm of the factor's contribution the EP model evidence.</returns>
<remarks>
<para>The formula for the result is <c>log(sum_(items,array,indices,indices2) p(items,array,indices,indices2) factor(items,array,indices,indices2) / sum_items p(items) messageTo(items))</c>. Adding up these values across all factors and variables gives the log-evidence estimate for EP.</para>
<para>The formula for the result is <c>log(sum_(items,array) p(items,array) factor(items,array,indices,indices2) / sum_items p(items) messageTo(items))</c>. Adding up these values across all factors and variables gives the log-evidence estimate for EP.</para>
</remarks>
</message_doc>
<message_doc name="AverageLogFactor{DistributionArrayType, DistributionType}(IList{T}, IList{DistributionArrayType})">
@ -16771,26 +16771,26 @@
<para>In Variational Message Passing, the evidence contribution of a deterministic factor is zero. Adding up these values across all factors and variables gives the log-evidence estimate for VMP.</para>
</remarks>
</message_doc>
<message_doc name="LogAverageFactor{DistributionType}(IList{DistributionType}, IList{IList{T}}, IList{int}, IList{int})">
<message_doc name="LogAverageFactor{DistributionType}(IList{DistributionType}, IList{IList{T}}, IReadOnlyList{int}, IReadOnlyList{int})">
<summary>Evidence message for EP.</summary>
<param name="items">Incoming message from <c>items</c>.</param>
<param name="array">Incoming message from <c>array</c>.</param>
<param name="indices">Incoming message from <c>indices</c>.</param>
<param name="indices2">Incoming message from <c>indices2</c>.</param>
<param name="indices">Constant value for <c>indices</c>.</param>
<param name="indices2">Constant value for <c>indices2</c>.</param>
<returns>Logarithm of the factor's average value across the given argument distributions.</returns>
<remarks>
<para>The formula for the result is <c>log(sum_(items,array,indices,indices2) p(items,array,indices,indices2) factor(items,array,indices,indices2))</c>.</para>
<para>The formula for the result is <c>log(sum_(items,array) p(items,array) factor(items,array,indices,indices2))</c>.</para>
</remarks>
</message_doc>
<message_doc name="LogEvidenceRatio{DistributionType}(IList{DistributionType}, IList{IList{T}}, IList{int}, IList{int})">
<message_doc name="LogEvidenceRatio{DistributionType}(IList{DistributionType}, IList{IList{T}}, IReadOnlyList{int}, IReadOnlyList{int})">
<summary>Evidence message for EP.</summary>
<param name="items">Incoming message from <c>items</c>.</param>
<param name="array">Incoming message from <c>array</c>.</param>
<param name="indices">Incoming message from <c>indices</c>.</param>
<param name="indices2">Incoming message from <c>indices2</c>.</param>
<param name="indices">Constant value for <c>indices</c>.</param>
<param name="indices2">Constant value for <c>indices2</c>.</param>
<returns>Logarithm of the factor's contribution the EP model evidence.</returns>
<remarks>
<para>The formula for the result is <c>log(sum_(items,array,indices,indices2) p(items,array,indices,indices2) factor(items,array,indices,indices2) / sum_items p(items) messageTo(items))</c>. Adding up these values across all factors and variables gives the log-evidence estimate for EP.</para>
<para>The formula for the result is <c>log(sum_(items,array) p(items,array) factor(items,array,indices,indices2) / sum_items p(items) messageTo(items))</c>. Adding up these values across all factors and variables gives the log-evidence estimate for EP.</para>
</remarks>
</message_doc>
<message_doc name="AverageLogFactor{DistributionType}(IList{DistributionType}, IList{IList{T}})">
@ -16802,16 +16802,16 @@
<para>In Variational Message Passing, the evidence contribution of a deterministic factor is zero. Adding up these values across all factors and variables gives the log-evidence estimate for VMP.</para>
</remarks>
</message_doc>
<message_doc name="LogEvidenceRatio{DistributionArrayType, DistributionType}(IList{DistributionType}, IList{DistributionArrayType}, IList{int}, IList{int}, IList{DistributionType})">
<message_doc name="LogEvidenceRatio{DistributionArrayType, DistributionType}(IList{DistributionType}, IList{DistributionArrayType}, IReadOnlyList{int}, IReadOnlyList{int}, IList{DistributionType})">
<summary>Evidence message for EP.</summary>
<param name="items">Incoming message from <c>items</c>.</param>
<param name="array">Incoming message from <c>array</c>.</param>
<param name="indices">Incoming message from <c>indices</c>.</param>
<param name="indices2">Incoming message from <c>indices2</c>.</param>
<param name="indices">Constant value for <c>indices</c>.</param>
<param name="indices2">Constant value for <c>indices2</c>.</param>
<param name="to_items">Previous outgoing message to <c>items</c>.</param>
<returns>Logarithm of the factor's contribution the EP model evidence.</returns>
<remarks>
<para>The formula for the result is <c>log(sum_(items,array,indices,indices2) p(items,array,indices,indices2) factor(items,array,indices,indices2) / sum_items p(items) messageTo(items))</c>. Adding up these values across all factors and variables gives the log-evidence estimate for EP.</para>
<para>The formula for the result is <c>log(sum_(items,array) p(items,array) factor(items,array,indices,indices2) / sum_items p(items) messageTo(items))</c>. Adding up these values across all factors and variables gives the log-evidence estimate for EP.</para>
</remarks>
</message_doc>
<message_doc name="MarginalInit{ArrayType}(ArrayType)">
@ -16836,13 +16836,13 @@
<para />
</remarks>
</message_doc>
<message_doc name="MarginalIncrement{ArrayType, DistributionArrayType, DistributionType}(ArrayType, DistributionType, DistributionType, IList{int}, IList{int}, int)">
<message_doc name="MarginalIncrement{ArrayType, DistributionArrayType, DistributionType}(ArrayType, DistributionType, DistributionType, IReadOnlyList{int}, IReadOnlyList{int}, int)">
<summary />
<param name="result">Modified to contain the outgoing message.</param>
<param name="to_item" />
<param name="item" />
<param name="indices">Incoming message from <c>indices</c>.</param>
<param name="indices2">Incoming message from <c>indices2</c>.</param>
<param name="indices">Constant value for <c>indices</c>.</param>
<param name="indices2">Constant value for <c>indices2</c>.</param>
<param name="resultIndex">Index of the <c>marginal</c> for which a message is desired.</param>
<returns>
<paramref name="result" />
@ -16851,114 +16851,114 @@
<para />
</remarks>
</message_doc>
<message_doc name="ItemsAverageConditional{ArrayType, DistributionArrayType, DistributionType}(DistributionType, ArrayType, ArrayType, IList{int}, IList{int}, int, DistributionType)">
<message_doc name="ItemsAverageConditional{ArrayType, DistributionArrayType, DistributionType}(DistributionType, ArrayType, ArrayType, IReadOnlyList{int}, IReadOnlyList{int}, int, DistributionType)">
<summary>EP message to <c>items</c>.</summary>
<param name="items">Incoming message from <c>items</c>.</param>
<param name="array">Incoming message from <c>array</c>.</param>
<param name="marginal">Buffer <c>marginal</c>.</param>
<param name="indices">Incoming message from <c>indices</c>.</param>
<param name="indices2">Incoming message from <c>indices2</c>.</param>
<param name="indices">Constant value for <c>indices</c>.</param>
<param name="indices2">Constant value for <c>indices2</c>.</param>
<param name="resultIndex">Index of the <c>items</c> for which a message is desired.</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>items</c> as the random arguments are varied. The formula is <c>proj[p(items) sum_(array,indices,indices2) p(array,indices,indices2) factor(items,array,indices,indices2)]/p(items)</c>.</para>
<para>The outgoing message is a distribution matching the moments of <c>items</c> as the random arguments are varied. The formula is <c>proj[p(items) sum_(array) p(array) factor(items,array,indices,indices2)]/p(items)</c>.</para>
</remarks>
</message_doc>
<message_doc name="ArrayAverageConditional{ArrayType, DistributionArrayType, DistributionType}(IList{DistributionType}, IList{int}, IList{int}, ArrayType)">
<message_doc name="ArrayAverageConditional{ArrayType, DistributionArrayType, DistributionType}(IList{DistributionType}, IReadOnlyList{int}, IReadOnlyList{int}, ArrayType)">
<summary>EP message to <c>array</c>.</summary>
<param name="items">Incoming message from <c>items</c>. Must be a proper distribution. If all elements are uniform, the result will be uniform.</param>
<param name="indices">Incoming message from <c>indices</c>.</param>
<param name="indices2">Incoming message from <c>indices2</c>.</param>
<param name="indices">Constant value for <c>indices</c>.</param>
<param name="indices2">Constant value for <c>indices2</c>.</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>array</c> as the random arguments are varied. The formula is <c>proj[p(array) sum_(items,indices,indices2) p(items,indices,indices2) factor(items,array,indices,indices2)]/p(array)</c>.</para>
<para>The outgoing message is a distribution matching the moments of <c>array</c> as the random arguments are varied. The formula is <c>proj[p(array) sum_(items) p(items) factor(items,array,indices,indices2)]/p(array)</c>.</para>
</remarks>
<exception cref="ImproperMessageException">
<paramref name="items" /> is not a proper distribution.</exception>
</message_doc>
<message_doc name="ArrayAverageConditional{ArrayType, DistributionArrayType, DistributionType}(IList{T}, IList{int}, IList{int}, ArrayType)">
<message_doc name="ArrayAverageConditional{ArrayType, DistributionArrayType, DistributionType}(IList{T}, IReadOnlyList{int}, IReadOnlyList{int}, ArrayType)">
<summary>EP message to <c>array</c>.</summary>
<param name="items">Incoming message from <c>items</c>. Must be a proper distribution. If all elements are uniform, the result will be uniform.</param>
<param name="indices">Incoming message from <c>indices</c>.</param>
<param name="indices2">Incoming message from <c>indices2</c>.</param>
<param name="indices">Constant value for <c>indices</c>.</param>
<param name="indices2">Constant value for <c>indices2</c>.</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>array</c> as the random arguments are varied. The formula is <c>proj[p(array) sum_(items,indices,indices2) p(items,indices,indices2) factor(items,array,indices,indices2)]/p(array)</c>.</para>
<para>The outgoing message is a distribution matching the moments of <c>array</c> as the random arguments are varied. The formula is <c>proj[p(array) sum_(items) p(items) factor(items,array,indices,indices2)]/p(array)</c>.</para>
</remarks>
<exception cref="ImproperMessageException">
<paramref name="items" /> is not a proper distribution.</exception>
</message_doc>
<message_doc name="ItemsAverageLogarithm{DistributionArrayType, DistributionType}(IList{DistributionArrayType}, IList{int}, IList{int}, int, DistributionType)">
<message_doc name="ItemsAverageLogarithm{DistributionArrayType, DistributionType}(IList{DistributionArrayType}, IReadOnlyList{int}, IReadOnlyList{int}, int, DistributionType)">
<summary>VMP message to <c>items</c>.</summary>
<param name="array">Incoming message from <c>array</c>. Must be a proper distribution. If all elements are uniform, the result will be uniform.</param>
<param name="indices">Incoming message from <c>indices</c>.</param>
<param name="indices2">Incoming message from <c>indices2</c>.</param>
<param name="indices">Constant value for <c>indices</c>.</param>
<param name="indices2">Constant value for <c>indices2</c>.</param>
<param name="resultIndex">Index of the <c>items</c> for which a message is desired.</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>items</c> as the random arguments are varied. The formula is <c>proj[sum_(array,indices,indices2) p(array,indices,indices2) factor(items,array,indices,indices2)]</c>.</para>
<para>The outgoing message is a distribution matching the moments of <c>items</c> as the random arguments are varied. The formula is <c>proj[sum_(array) p(array) factor(items,array,indices,indices2)]</c>.</para>
</remarks>
<exception cref="ImproperMessageException">
<paramref name="array" /> is not a proper distribution.</exception>
</message_doc>
<message_doc name="ItemsAverageLogarithmInit{TDist}(IList{DistributionStructArray{TDist, T}}, IList{int}, IList{int})">
<message_doc name="ItemsAverageLogarithmInit{TDist}(IList{DistributionStructArray{TDist, T}}, IReadOnlyList{int}, IReadOnlyList{int})">
<summary />
<param name="array">Incoming message from <c>array</c>.</param>
<param name="indices">Incoming message from <c>indices</c>.</param>
<param name="indices2">Incoming message from <c>indices2</c>.</param>
<param name="indices">Constant value for <c>indices</c>.</param>
<param name="indices2">Constant value for <c>indices2</c>.</param>
<returns />
<remarks>
<para />
</remarks>
</message_doc>
<message_doc name="ItemsAverageLogarithmInit{TDist}(IList{DistributionRefArray{TDist, T}}, IList{int}, IList{int})">
<message_doc name="ItemsAverageLogarithmInit{TDist}(IList{DistributionRefArray{TDist, T}}, IReadOnlyList{int}, IReadOnlyList{int})">
<summary />
<param name="array">Incoming message from <c>array</c>.</param>
<param name="indices">Incoming message from <c>indices</c>.</param>
<param name="indices2">Incoming message from <c>indices2</c>.</param>
<param name="indices">Constant value for <c>indices</c>.</param>
<param name="indices2">Constant value for <c>indices2</c>.</param>
<returns />
<remarks>
<para />
</remarks>
</message_doc>
<message_doc name="ArrayAverageLogarithm{DistributionArrayType, DistributionType, ArrayType}(IList{DistributionType}, IList{int}, IList{int}, ArrayType)">
<message_doc name="ArrayAverageLogarithm{DistributionArrayType, DistributionType, ArrayType}(IList{DistributionType}, IReadOnlyList{int}, IReadOnlyList{int}, ArrayType)">
<summary>VMP message to <c>array</c>.</summary>
<param name="items">Incoming message from <c>items</c>. Must be a proper distribution. If all elements are uniform, the result will be uniform.</param>
<param name="indices">Incoming message from <c>indices</c>.</param>
<param name="indices2">Incoming message from <c>indices2</c>.</param>
<param name="indices">Constant value for <c>indices</c>.</param>
<param name="indices2">Constant value for <c>indices2</c>.</param>
<param name="result">Modified to contain the outgoing message.</param>
<returns>
<paramref name="result" />
</returns>
<remarks>
<para>The outgoing message is the exponential of the average log-factor value, where the average is over all arguments except <c>array</c>. Because the factor is deterministic, <c>items</c> is integrated out before taking the logarithm. The formula is <c>exp(sum_(indices,indices2) p(indices,indices2) log(sum_items p(items) factor(items,array,indices,indices2)))</c>.</para>
<para>The outgoing message is the factor viewed as a function of <c>array</c> with <c>items</c> integrated out. The formula is <c>sum_items p(items) factor(items,array,indices,indices2)</c>.</para>
</remarks>
<exception cref="ImproperMessageException">
<paramref name="items" /> is not a proper distribution.</exception>
</message_doc>
<message_doc name="ArrayAverageLogarithm{ArrayType, DistributionArrayType, DistributionType}(IList{T}, IList{int}, IList{int}, ArrayType)">
<message_doc name="ArrayAverageLogarithm{ArrayType, DistributionArrayType, DistributionType}(IList{T}, IReadOnlyList{int}, IReadOnlyList{int}, ArrayType)">
<summary>VMP message to <c>array</c>.</summary>
<param name="items">Incoming message from <c>items</c>.</param>
<param name="indices">Incoming message from <c>indices</c>.</param>
<param name="indices2">Incoming message from <c>indices2</c>.</param>
<param name="indices">Constant value for <c>indices</c>.</param>
<param name="indices2">Constant value for <c>indices2</c>.</param>
<param name="result">Modified to contain the outgoing message.</param>
<returns>
<paramref name="result" />
</returns>
<remarks>
<para>The outgoing message is the exponential of the average log-factor value, where the average is over all arguments except <c>array</c>. Because the factor is deterministic, <c>items</c> is integrated out before taking the logarithm. The formula is <c>exp(sum_(indices,indices2) p(indices,indices2) log(sum_items p(items) factor(items,array,indices,indices2)))</c>.</para>
<para>The outgoing message is the factor viewed as a function of <c>array</c> with <c>items</c> integrated out. The formula is <c>sum_items p(items) factor(items,array,indices,indices2)</c>.</para>
</remarks>
</message_doc>
</message_op_class>
@ -17007,44 +17007,44 @@
<doc>
<summary>Provides outgoing messages for <see cref="Collection.GetJaggedItems{T}(IReadOnlyList{T}, IReadOnlyList{IReadOnlyList{int}})" />, given random arguments to the function.</summary>
</doc>
<message_doc name="LogAverageFactor(IList{IList{T}}, IList{T}, IList{IList{int}})">
<message_doc name="LogAverageFactor(IList{IList{T}}, IList{T}, IReadOnlyList{IReadOnlyList{int}})">
<summary>Evidence message for EP.</summary>
<param name="items">Incoming message from <c>items</c>.</param>
<param name="array">Incoming message from <c>array</c>.</param>
<param name="indices">Incoming message from <c>indices</c>.</param>
<param name="indices">Constant value for <c>indices</c>.</param>
<returns>Logarithm of the factor's average value across the given argument distributions.</returns>
<remarks>
<para>The formula for the result is <c>log(sum_(items,array,indices) p(items,array,indices) factor(items,array,indices))</c>.</para>
<para>The formula for the result is <c>log(sum_(items,array) p(items,array) factor(items,array,indices))</c>.</para>
</remarks>
</message_doc>
<message_doc name="LogEvidenceRatio(IList{IList{T}}, IList{T}, IList{IList{int}})">
<message_doc name="LogEvidenceRatio(IList{IList{T}}, IList{T}, IReadOnlyList{IReadOnlyList{int}})">
<summary>Evidence message for EP.</summary>
<param name="items">Incoming message from <c>items</c>.</param>
<param name="array">Incoming message from <c>array</c>.</param>
<param name="indices">Incoming message from <c>indices</c>.</param>
<param name="indices">Constant value for <c>indices</c>.</param>
<returns>Logarithm of the factor's contribution the EP model evidence.</returns>
<remarks>
<para>The formula for the result is <c>log(sum_(items,array,indices) p(items,array,indices) factor(items,array,indices) / sum_items p(items) messageTo(items))</c>. Adding up these values across all factors and variables gives the log-evidence estimate for EP.</para>
<para>The formula for the result is <c>log(sum_(items,array) p(items,array) factor(items,array,indices) / sum_items p(items) messageTo(items))</c>. Adding up these values across all factors and variables gives the log-evidence estimate for EP.</para>
</remarks>
</message_doc>
<message_doc name="AverageLogFactor(IList{IList{T}}, IList{T}, IList{IList{int}})">
<message_doc name="AverageLogFactor(IList{IList{T}}, IList{T}, IReadOnlyList{IReadOnlyList{int}})">
<summary>Evidence message for VMP.</summary>
<param name="items">Incoming message from <c>items</c>.</param>
<param name="array">Incoming message from <c>array</c>.</param>
<param name="indices">Incoming message from <c>indices</c>.</param>
<param name="indices">Constant value for <c>indices</c>.</param>
<returns>Zero.</returns>
<remarks>
<para>In Variational Message Passing, the evidence contribution of a deterministic factor is zero. Adding up these values across all factors and variables gives the log-evidence estimate for VMP.</para>
</remarks>
</message_doc>
<message_doc name="LogAverageFactor{ItemType, DistributionType}(IList{ItemType}, IList{DistributionType}, IList{IList{int}})">
<message_doc name="LogAverageFactor{ItemType, DistributionType}(IList{ItemType}, IList{DistributionType}, IReadOnlyList{IReadOnlyList{int}})">
<summary>Evidence message for EP.</summary>
<param name="items">Incoming message from <c>items</c>.</param>
<param name="array">Incoming message from <c>array</c>.</param>
<param name="indices">Incoming message from <c>indices</c>.</param>
<param name="indices">Constant value for <c>indices</c>.</param>
<returns>Logarithm of the factor's average value across the given argument distributions.</returns>
<remarks>
<para>The formula for the result is <c>log(sum_(items,array,indices) p(items,array,indices) factor(items,array,indices))</c>.</para>
<para>The formula for the result is <c>log(sum_(items,array) p(items,array) factor(items,array,indices))</c>.</para>
</remarks>
</message_doc>
<message_doc name="AverageLogFactor{ItemType, DistributionType}(IList{ItemType}, IList{DistributionType})">
@ -17056,24 +17056,24 @@
<para>In Variational Message Passing, the evidence contribution of a deterministic factor is zero. Adding up these values across all factors and variables gives the log-evidence estimate for VMP.</para>
</remarks>
</message_doc>
<message_doc name="LogAverageFactor{DistributionType}(IList{IList{T}}, IList{DistributionType}, IList{IList{int}})">
<message_doc name="LogAverageFactor{DistributionType}(IList{IList{T}}, IList{DistributionType}, IReadOnlyList{IReadOnlyList{int}})">
<summary>Evidence message for EP.</summary>
<param name="items">Incoming message from <c>items</c>.</param>
<param name="array">Incoming message from <c>array</c>.</param>
<param name="indices">Incoming message from <c>indices</c>.</param>
<param name="indices">Constant value for <c>indices</c>.</param>
<returns>Logarithm of the factor's average value across the given argument distributions.</returns>
<remarks>
<para>The formula for the result is <c>log(sum_(items,array,indices) p(items,array,indices) factor(items,array,indices))</c>.</para>
<para>The formula for the result is <c>log(sum_(items,array) p(items,array) factor(items,array,indices))</c>.</para>
</remarks>
</message_doc>
<message_doc name="LogEvidenceRatio{DistributionType}(IList{IList{T}}, IList{DistributionType}, IList{IList{int}})">
<message_doc name="LogEvidenceRatio{DistributionType}(IList{IList{T}}, IList{DistributionType}, IReadOnlyList{IReadOnlyList{int}})">
<summary>Evidence message for EP.</summary>
<param name="items">Incoming message from <c>items</c>.</param>
<param name="array">Incoming message from <c>array</c>.</param>
<param name="indices">Incoming message from <c>indices</c>.</param>
<param name="indices">Constant value for <c>indices</c>.</param>
<returns>Logarithm of the factor's contribution the EP model evidence.</returns>
<remarks>
<para>The formula for the result is <c>log(sum_(items,array,indices) p(items,array,indices) factor(items,array,indices) / sum_items p(items) messageTo(items))</c>. Adding up these values across all factors and variables gives the log-evidence estimate for EP.</para>
<para>The formula for the result is <c>log(sum_(items,array) p(items,array) factor(items,array,indices) / sum_items p(items) messageTo(items))</c>. Adding up these values across all factors and variables gives the log-evidence estimate for EP.</para>
</remarks>
</message_doc>
<message_doc name="AverageLogFactor{DistributionType}(IList{IList{T}}, IList{DistributionType})">
@ -17085,24 +17085,24 @@
<para>In Variational Message Passing, the evidence contribution of a deterministic factor is zero. Adding up these values across all factors and variables gives the log-evidence estimate for VMP.</para>
</remarks>
</message_doc>
<message_doc name="LogAverageFactor{ItemType, DistributionType}(IList{ItemType}, IList{T}, IList{IList{int}})">
<message_doc name="LogAverageFactor{ItemType, DistributionType}(IList{ItemType}, IList{T}, IReadOnlyList{IReadOnlyList{int}})">
<summary>Evidence message for EP.</summary>
<param name="items">Incoming message from <c>items</c>.</param>
<param name="array">Incoming message from <c>array</c>.</param>
<param name="indices">Incoming message from <c>indices</c>.</param>
<param name="indices">Constant value for <c>indices</c>.</param>
<returns>Logarithm of the factor's average value across the given argument distributions.</returns>
<remarks>
<para>The formula for the result is <c>log(sum_(items,array,indices) p(items,array,indices) factor(items,array,indices))</c>.</para>
<para>The formula for the result is <c>log(sum_(items,array) p(items,array) factor(items,array,indices))</c>.</para>
</remarks>
</message_doc>
<message_doc name="LogEvidenceRatio{ItemType, DistributionType}(IList{ItemType}, IList{T}, IList{IList{int}})">
<message_doc name="LogEvidenceRatio{ItemType, DistributionType}(IList{ItemType}, IList{T}, IReadOnlyList{IReadOnlyList{int}})">
<summary>Evidence message for EP.</summary>
<param name="items">Incoming message from <c>items</c>.</param>
<param name="array">Incoming message from <c>array</c>.</param>
<param name="indices">Incoming message from <c>indices</c>.</param>
<param name="indices">Constant value for <c>indices</c>.</param>
<returns>Logarithm of the factor's contribution the EP model evidence.</returns>
<remarks>
<para>The formula for the result is <c>log(sum_(items,array,indices) p(items,array,indices) factor(items,array,indices) / sum_items p(items) messageTo(items))</c>. Adding up these values across all factors and variables gives the log-evidence estimate for EP.</para>
<para>The formula for the result is <c>log(sum_(items,array) p(items,array) factor(items,array,indices) / sum_items p(items) messageTo(items))</c>. Adding up these values across all factors and variables gives the log-evidence estimate for EP.</para>
</remarks>
</message_doc>
<message_doc name="AverageLogFactor{ItemType, DistributionType}(IList{ItemType}, IList{T})">
@ -17114,15 +17114,15 @@
<para>In Variational Message Passing, the evidence contribution of a deterministic factor is zero. Adding up these values across all factors and variables gives the log-evidence estimate for VMP.</para>
</remarks>
</message_doc>
<message_doc name="LogEvidenceRatio{ItemType, DistributionType}(IList{ItemType}, IList{DistributionType}, IList{IList{int}}, IList{ItemType})">
<message_doc name="LogEvidenceRatio{ItemType, DistributionType}(IList{ItemType}, IList{DistributionType}, IReadOnlyList{IReadOnlyList{int}}, IList{ItemType})">
<summary>Evidence message for EP.</summary>
<param name="items">Incoming message from <c>items</c>.</param>
<param name="array">Incoming message from <c>array</c>.</param>
<param name="indices">Incoming message from <c>indices</c>.</param>
<param name="indices">Constant value for <c>indices</c>.</param>
<param name="to_items">Previous outgoing message to <c>items</c>.</param>
<returns>Logarithm of the factor's contribution the EP model evidence.</returns>
<remarks>
<para>The formula for the result is <c>log(sum_(items,array,indices) p(items,array,indices) factor(items,array,indices) / sum_items p(items) messageTo(items))</c>. Adding up these values across all factors and variables gives the log-evidence estimate for EP.</para>
<para>The formula for the result is <c>log(sum_(items,array) p(items,array) factor(items,array,indices) / sum_items p(items) messageTo(items))</c>. Adding up these values across all factors and variables gives the log-evidence estimate for EP.</para>
</remarks>
</message_doc>
<message_doc name="MarginalInit{ArrayType}(ArrayType)">
@ -17147,12 +17147,12 @@
<para />
</remarks>
</message_doc>
<message_doc name="MarginalIncrement{ArrayType, ItemType, DistributionType}(ArrayType, ItemType, ItemType, IList{IList{int}}, int)">
<message_doc name="MarginalIncrement{ArrayType, ItemType, DistributionType}(ArrayType, ItemType, ItemType, IReadOnlyList{IReadOnlyList{int}}, int)">
<summary />
<param name="result">Modified to contain the outgoing message.</param>
<param name="to_item" />
<param name="item" />
<param name="indices">Incoming message from <c>indices</c>.</param>
<param name="indices">Constant value for <c>indices</c>.</param>
<param name="resultIndex">Index of the <c>marginal</c> for which a message is desired.</param>
<returns>
<paramref name="result" />
@ -17161,88 +17161,88 @@
<para />
</remarks>
</message_doc>
<message_doc name="ItemsAverageConditional{ArrayType, ItemType, DistributionType}(ItemType, ArrayType, ArrayType, IList{IList{int}}, int, ItemType)">
<message_doc name="ItemsAverageConditional{ArrayType, ItemType, DistributionType}(ItemType, ArrayType, ArrayType, IReadOnlyList{IReadOnlyList{int}}, int, ItemType)">
<summary>EP message to <c>items</c>.</summary>
<param name="items">Incoming message from <c>items</c>.</param>
<param name="array">Incoming message from <c>array</c>.</param>
<param name="marginal">Buffer <c>marginal</c>.</param>
<param name="indices">Incoming message from <c>indices</c>.</param>
<param name="indices">Constant value for <c>indices</c>.</param>
<param name="resultIndex">Index of the <c>items</c> for which a message is desired.</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>items</c> as the random arguments are varied. The formula is <c>proj[p(items) sum_(array,indices) p(array,indices) factor(items,array,indices)]/p(items)</c>.</para>
<para>The outgoing message is a distribution matching the moments of <c>items</c> as the random arguments are varied. The formula is <c>proj[p(items) sum_(array) p(array) factor(items,array,indices)]/p(items)</c>.</para>
</remarks>
</message_doc>
<message_doc name="ArrayAverageConditional{ItemType, DistributionType, ArrayType}(IList{ItemType}, IList{IList{int}}, ArrayType)">
<message_doc name="ArrayAverageConditional{ItemType, DistributionType, ArrayType}(IList{ItemType}, IReadOnlyList{IReadOnlyList{int}}, ArrayType)">
<summary>EP message to <c>array</c>.</summary>
<param name="items">Incoming message from <c>items</c>. Must be a proper distribution. If all elements are uniform, the result will be uniform.</param>
<param name="indices">Incoming message from <c>indices</c>.</param>
<param name="indices">Constant value for <c>indices</c>.</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>array</c> as the random arguments are varied. The formula is <c>proj[p(array) sum_(items,indices) p(items,indices) factor(items,array,indices)]/p(array)</c>.</para>
<para>The outgoing message is a distribution matching the moments of <c>array</c> as the random arguments are varied. The formula is <c>proj[p(array) sum_(items) p(items) factor(items,array,indices)]/p(array)</c>.</para>
</remarks>
<exception cref="ImproperMessageException">
<paramref name="items" /> is not a proper distribution.</exception>
</message_doc>
<message_doc name="ArrayAverageConditional{DistributionType, ArrayType}(IList{IList{T}}, IList{IList{int}}, ArrayType)">
<message_doc name="ArrayAverageConditional{DistributionType, ArrayType}(IList{IList{T}}, IReadOnlyList{IReadOnlyList{int}}, ArrayType)">
<summary>EP message to <c>array</c>.</summary>
<param name="items">Incoming message from <c>items</c>. Must be a proper distribution. If all elements are uniform, the result will be uniform.</param>
<param name="indices">Incoming message from <c>indices</c>.</param>
<param name="indices">Constant value for <c>indices</c>.</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>array</c> as the random arguments are varied. The formula is <c>proj[p(array) sum_(items,indices) p(items,indices) factor(items,array,indices)]/p(array)</c>.</para>
<para>The outgoing message is a distribution matching the moments of <c>array</c> as the random arguments are varied. The formula is <c>proj[p(array) sum_(items) p(items) factor(items,array,indices)]/p(array)</c>.</para>
</remarks>
<exception cref="ImproperMessageException">
<paramref name="items" /> is not a proper distribution.</exception>
</message_doc>
<message_doc name="ItemsAverageLogarithm{ItemType, DistributionType}(IList{DistributionType}, IList{IList{int}}, int, ItemType)">
<message_doc name="ItemsAverageLogarithm{ItemType, DistributionType}(IList{DistributionType}, IReadOnlyList{IReadOnlyList{int}}, int, ItemType)">
<summary>VMP message to <c>items</c>.</summary>
<param name="array">Incoming message from <c>array</c>. Must be a proper distribution. If all elements are uniform, the result will be uniform.</param>
<param name="indices">Incoming message from <c>indices</c>.</param>
<param name="indices">Constant value for <c>indices</c>.</param>
<param name="resultIndex">Index of the <c>items</c> for which a message is desired.</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>items</c> as the random arguments are varied. The formula is <c>proj[sum_(array,indices) p(array,indices) factor(items,array,indices)]</c>.</para>
<para>The outgoing message is a distribution matching the moments of <c>items</c> as the random arguments are varied. The formula is <c>proj[sum_(array) p(array) factor(items,array,indices)]</c>.</para>
</remarks>
<exception cref="ImproperMessageException">
<paramref name="array" /> is not a proper distribution.</exception>
</message_doc>
<message_doc name="ArrayAverageLogarithm{ItemType, DistributionType, ArrayType}(IList{ItemType}, IList{IList{int}}, ArrayType)">
<message_doc name="ArrayAverageLogarithm{ItemType, DistributionType, ArrayType}(IList{ItemType}, IReadOnlyList{IReadOnlyList{int}}, ArrayType)">
<summary>VMP message to <c>array</c>.</summary>
<param name="items">Incoming message from <c>items</c>. Must be a proper distribution. If all elements are uniform, the result will be uniform.</param>
<param name="indices">Incoming message from <c>indices</c>.</param>
<param name="indices">Constant value for <c>indices</c>.</param>
<param name="result">Modified to contain the outgoing message.</param>
<returns>
<paramref name="result" />
</returns>
<remarks>
<para>The outgoing message is the exponential of the average log-factor value, where the average is over all arguments except <c>array</c>. Because the factor is deterministic, <c>items</c> is integrated out before taking the logarithm. The formula is <c>exp(sum_(indices) p(indices) log(sum_items p(items) factor(items,array,indices)))</c>.</para>
<para>The outgoing message is the factor viewed as a function of <c>array</c> with <c>items</c> integrated out. The formula is <c>sum_items p(items) factor(items,array,indices)</c>.</para>
</remarks>
<exception cref="ImproperMessageException">
<paramref name="items" /> is not a proper distribution.</exception>
</message_doc>
<message_doc name="ArrayAverageLogarithm{DistributionType, ArrayType}(IList{IList{T}}, IList{IList{int}}, ArrayType)">
<message_doc name="ArrayAverageLogarithm{DistributionType, ArrayType}(IList{IList{T}}, IReadOnlyList{IReadOnlyList{int}}, ArrayType)">
<summary>VMP message to <c>array</c>.</summary>
<param name="items">Incoming message from <c>items</c>.</param>
<param name="indices">Incoming message from <c>indices</c>.</param>
<param name="indices">Constant value for <c>indices</c>.</param>
<param name="result">Modified to contain the outgoing message.</param>
<returns>
<paramref name="result" />
</returns>
<remarks>
<para>The outgoing message is the exponential of the average log-factor value, where the average is over all arguments except <c>array</c>. Because the factor is deterministic, <c>items</c> is integrated out before taking the logarithm. The formula is <c>exp(sum_(indices) p(indices) log(sum_items p(items) factor(items,array,indices)))</c>.</para>
<para>The outgoing message is the factor viewed as a function of <c>array</c> with <c>items</c> integrated out. The formula is <c>sum_items p(items) factor(items,array,indices)</c>.</para>
</remarks>
</message_doc>
</message_op_class>

Просмотреть файл

@ -18,8 +18,8 @@ namespace Microsoft.ML.Probabilistic.Factors
[Buffers("marginal")]
public static class GetItemsFromJaggedOp<T>
{
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GetItemsFromJaggedOp{T}"]/message_doc[@name="LogAverageFactor(IList{T}, IList{T}, IList{int})"]/*'/>
public static double LogAverageFactor(IList<T> items, IList<IList<T>> array, IList<int> indices, IList<int> indices2)
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GetItemsFromJaggedOp{T}"]/message_doc[@name="LogAverageFactor(IList{T}, IList{T}, IReadOnlyList{int}, IReadOnlyList{int})"]/*'/>
public static double LogAverageFactor(IList<T> items, IList<IList<T>> array, IReadOnlyList<int> indices, IReadOnlyList<int> indices2)
{
IEqualityComparer<T> equalityComparer = Utilities.Util.GetEqualityComparer<T>();
for (int i = 0; i < items.Count; i++)
@ -30,22 +30,22 @@ namespace Microsoft.ML.Probabilistic.Factors
return 0.0;
}
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GetItemsFromJaggedOp{T}"]/message_doc[@name="LogEvidenceRatio(IList{T}, IList{T}, IList{int})"]/*'/>
public static double LogEvidenceRatio(IList<T> items, IList<IList<T>> array, IList<int> indices, IList<int> indices2)
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GetItemsFromJaggedOp{T}"]/message_doc[@name="LogEvidenceRatio(IList{T}, IList{T}, IReadOnlyList{int}, IReadOnlyList{int})"]/*'/>
public static double LogEvidenceRatio(IList<T> items, IList<IList<T>> array, IReadOnlyList<int> indices, IReadOnlyList<int> indices2)
{
return LogAverageFactor(items, array, indices, indices2);
}
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GetItemsFromJaggedOp{T}"]/message_doc[@name="AverageLogFactor(IList{T}, IList{T}, IList{int})"]/*'/>
public static double AverageLogFactor(IList<T> items, IList<IList<T>> array, IList<int> indices, IList<int> indices2)
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GetItemsFromJaggedOp{T}"]/message_doc[@name="AverageLogFactor(IList{T}, IList{T}, IReadOnlyList{int}, IReadOnlyList{int})"]/*'/>
public static double AverageLogFactor(IList<T> items, IList<IList<T>> array, IReadOnlyList<int> indices, IReadOnlyList<int> indices2)
{
return LogAverageFactor(items, array, indices, indices2);
}
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GetItemsFromJaggedOp{T}"]/message_doc[@name="LogAverageFactor{DistributionType}(IList{DistributionType}, IList{DistributionType}, IList{int})"]/*'/>
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GetItemsFromJaggedOp{T}"]/message_doc[@name="LogAverageFactor{DistributionType}(IList{DistributionType}, IList{DistributionType}, IReadOnlyList{int}, IReadOnlyList{int})"]/*'/>
/// <typeparam name="DistributionArrayType">The type of a distribution over array elements.</typeparam>
/// <typeparam name="DistributionType">The type of a distribution over inner array elements.</typeparam>
public static double LogAverageFactor<DistributionArrayType, DistributionType>(IList<DistributionType> items, IList<DistributionArrayType> array, IList<int> indices, IList<int> indices2)
public static double LogAverageFactor<DistributionArrayType, DistributionType>(IList<DistributionType> items, IList<DistributionArrayType> array, IReadOnlyList<int> indices, IReadOnlyList<int> indices2)
where DistributionArrayType : IList<DistributionType>
where DistributionType : IDistribution<T>, SettableToProduct<DistributionType>, CanGetLogAverageOf<DistributionType>
{
@ -77,10 +77,10 @@ namespace Microsoft.ML.Probabilistic.Factors
return 0.0;
}
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GetItemsFromJaggedOp{T}"]/message_doc[@name="LogAverageFactor{DistributionType}(IList{T}, IList{DistributionType}, IList{int})"]/*'/>
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GetItemsFromJaggedOp{T}"]/message_doc[@name="LogAverageFactor{DistributionType}(IList{T}, IList{DistributionType}, IReadOnlyList{int}, IReadOnlyList{int})"]/*'/>
/// <typeparam name="DistributionArrayType">The type of a distribution over array elements.</typeparam>
/// <typeparam name="DistributionType">The type of a distribution over inner array elements.</typeparam>
public static double LogAverageFactor<DistributionArrayType, DistributionType>(IList<T> items, IList<DistributionArrayType> array, IList<int> indices, IList<int> indices2)
public static double LogAverageFactor<DistributionArrayType, DistributionType>(IList<T> items, IList<DistributionArrayType> array, IReadOnlyList<int> indices, IReadOnlyList<int> indices2)
where DistributionArrayType : IList<DistributionType>
where DistributionType : HasPoint<T>, CanGetLogProb<T>
{
@ -101,10 +101,10 @@ namespace Microsoft.ML.Probabilistic.Factors
return z;
}
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GetItemsFromJaggedOp{T}"]/message_doc[@name="LogEvidenceRatio{DistributionType}(IList{T}, IList{DistributionType}, IList{int})"]/*'/>
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GetItemsFromJaggedOp{T}"]/message_doc[@name="LogEvidenceRatio{DistributionType}(IList{T}, IList{DistributionType}, IReadOnlyList{int}, IReadOnlyList{int})"]/*'/>
/// <typeparam name="DistributionArrayType">The type of a distribution over array elements.</typeparam>
/// <typeparam name="DistributionType">The type of a distribution over inner array elements.</typeparam>
public static double LogEvidenceRatio<DistributionArrayType, DistributionType>(IList<T> items, IList<DistributionArrayType> array, IList<int> indices, IList<int> indices2)
public static double LogEvidenceRatio<DistributionArrayType, DistributionType>(IList<T> items, IList<DistributionArrayType> array, IReadOnlyList<int> indices, IReadOnlyList<int> indices2)
where DistributionArrayType : IList<DistributionType>
where DistributionType : HasPoint<T>, CanGetLogProb<T>
{
@ -122,9 +122,9 @@ namespace Microsoft.ML.Probabilistic.Factors
return 0.0;
}
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GetItemsFromJaggedOp{T}"]/message_doc[@name="LogAverageFactor{DistributionType}(IList{DistributionType}, IList{T}, IList{int})"]/*'/>
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GetItemsFromJaggedOp{T}"]/message_doc[@name="LogAverageFactor{DistributionType}(IList{DistributionType}, IList{T}, IReadOnlyList{int}, IReadOnlyList{int})"]/*'/>
/// <typeparam name="DistributionType">The type of a distribution over array elements.</typeparam>
public static double LogAverageFactor<DistributionType>(IList<DistributionType> items, IList<IList<T>> array, IList<int> indices, IList<int> indices2)
public static double LogAverageFactor<DistributionType>(IList<DistributionType> items, IList<IList<T>> array, IReadOnlyList<int> indices, IReadOnlyList<int> indices2)
where DistributionType : CanGetLogProb<T>
{
double z = 0.0;
@ -133,10 +133,10 @@ namespace Microsoft.ML.Probabilistic.Factors
return z;
}
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GetItemsFromJaggedOp{T}"]/message_doc[@name="LogEvidenceRatio{DistributionType}(IList{DistributionType}, IList{T}, IList{int})"]/*'/>
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GetItemsFromJaggedOp{T}"]/message_doc[@name="LogEvidenceRatio{DistributionType}(IList{DistributionType}, IList{T}, IReadOnlyList{int}, IReadOnlyList{int})"]/*'/>
/// <typeparam name="DistributionType">The type of a distribution over array elements.</typeparam>
[Skip]
public static double LogEvidenceRatio<DistributionType>(IList<DistributionType> items, IList<IList<T>> array, IList<int> indices, IList<int> indices2)
public static double LogEvidenceRatio<DistributionType>(IList<DistributionType> items, IList<IList<T>> array, IReadOnlyList<int> indices, IReadOnlyList<int> indices2)
where DistributionType : CanGetLogProb<T>
{
return 0.0;
@ -153,11 +153,11 @@ namespace Microsoft.ML.Probabilistic.Factors
#if true
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GetItemsFromJaggedOp{T}"]/message_doc[@name="LogEvidenceRatio{DistributionType}(IList{DistributionType}, IList{DistributionType}, IList{int}, IList{DistributionType})"]/*'/>
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GetItemsFromJaggedOp{T}"]/message_doc[@name="LogEvidenceRatio{DistributionType}(IList{DistributionType}, IList{DistributionType}, IReadOnlyList{int}, IReadOnlyList{int}, IList{DistributionType})"]/*'/>
/// <typeparam name="DistributionArrayType">The type of a distribution over array elements.</typeparam>
/// <typeparam name="DistributionType">The type of a distribution over inner array elements.</typeparam>
public static double LogEvidenceRatio<DistributionArrayType, DistributionType>(
IList<DistributionType> items, IList<DistributionArrayType> array, IList<int> indices, IList<int> indices2, IList<DistributionType> to_items)
IList<DistributionType> items, IList<DistributionArrayType> array, IReadOnlyList<int> indices, IReadOnlyList<int> indices2, IList<DistributionType> to_items)
where DistributionArrayType : IList<DistributionType>
where DistributionType : SettableToUniform, SettableToProduct<DistributionType>, CanGetLogAverageOf<DistributionType>, ICloneable
{
@ -264,12 +264,12 @@ namespace Microsoft.ML.Probabilistic.Factors
return result;
}
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GetItemsFromJaggedOp{T}"]/message_doc[@name="MarginalIncrement{ArrayType, DistributionType}(ArrayType, DistributionType, DistributionType, IList{int}, int)"]/*'/>
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GetItemsFromJaggedOp{T}"]/message_doc[@name="MarginalIncrement{ArrayType, DistributionType}(ArrayType, DistributionType, DistributionType, IReadOnlyList{int}, IReadOnlyList{int}, int)"]/*'/>
/// <typeparam name="ArrayType">The type of an array for the marginal.</typeparam>
/// <typeparam name="DistributionArrayType">The type of a distribution over array elements.</typeparam>
/// <typeparam name="DistributionType">The type of a distribution over inner array elements.</typeparam>
public static ArrayType MarginalIncrement<ArrayType, DistributionArrayType, DistributionType>(
ArrayType result, DistributionType to_item, [SkipIfUniform] DistributionType item, IList<int> indices, IList<int> indices2, int resultIndex)
ArrayType result, DistributionType to_item, [SkipIfUniform] DistributionType item, IReadOnlyList<int> indices, IReadOnlyList<int> indices2, int resultIndex)
where ArrayType : IList<DistributionArrayType>, SettableTo<ArrayType>
where DistributionArrayType : IList<DistributionType>
where DistributionType : SettableToProduct<DistributionType>
@ -281,7 +281,7 @@ namespace Microsoft.ML.Probabilistic.Factors
return result;
}
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GetItemsFromJaggedOp{T}"]/message_doc[@name="ItemsAverageConditional{ArrayType, DistributionType}(DistributionType, ArrayType, ArrayType, IList{int}, int, DistributionType)"]/*'/>
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GetItemsFromJaggedOp{T}"]/message_doc[@name="ItemsAverageConditional{ArrayType, DistributionType}(DistributionType, ArrayType, ArrayType, IReadOnlyList{int}, IReadOnlyList{int}, int, DistributionType)"]/*'/>
/// <typeparam name="ArrayType">The type of an array for the marginal.</typeparam>
/// <typeparam name="DistributionArrayType">The type of a distribution over array elements.</typeparam>
/// <typeparam name="DistributionType">The type of a distribution over inner array elements.</typeparam>
@ -289,7 +289,7 @@ namespace Microsoft.ML.Probabilistic.Factors
[Indexed, Cancels] DistributionType items,
[IgnoreDependency] ArrayType array, // must have an (unused) 'array' argument to determine the type of 'marginal' buffer
[SkipIfAllUniform] ArrayType marginal,
IList<int> indices, IList<int> indices2,
IReadOnlyList<int> indices, IReadOnlyList<int> indices2,
int resultIndex,
DistributionType result)
where ArrayType : IList<DistributionArrayType>
@ -301,12 +301,12 @@ namespace Microsoft.ML.Probabilistic.Factors
return result;
}
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GetItemsFromJaggedOp{T}"]/message_doc[@name="ArrayAverageConditional{ArrayType, DistributionArrayType, DistributionType}(IList{DistributionType}, IList{int}, ArrayType)"]/*'/>
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GetItemsFromJaggedOp{T}"]/message_doc[@name="ArrayAverageConditional{ArrayType, DistributionArrayType, DistributionType}(IList{DistributionType}, IReadOnlyList{int}, IReadOnlyList{int}, ArrayType)"]/*'/>
/// <typeparam name="ArrayType">The type of the resulting array.</typeparam>
/// <typeparam name="DistributionArrayType">The type of a distribution over array elements.</typeparam>
/// <typeparam name="DistributionType">The type of a distribution over inner array elements.</typeparam>
public static ArrayType ArrayAverageConditional<ArrayType, DistributionArrayType, DistributionType>(
[SkipIfAllUniform] IList<DistributionType> items, IList<int> indices, IList<int> indices2, ArrayType result)
[SkipIfAllUniform] IList<DistributionType> items, IReadOnlyList<int> indices, IReadOnlyList<int> indices2, ArrayType result)
where ArrayType : IList<DistributionArrayType>, SettableToUniform
where DistributionArrayType : IList<DistributionType>
where DistributionType : SettableToProduct<DistributionType>
@ -322,12 +322,12 @@ namespace Microsoft.ML.Probabilistic.Factors
return result;
}
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GetItemsFromJaggedOp{T}"]/message_doc[@name="ArrayAverageConditional{ArrayType, DistributionArrayType, DistributionType}(IList{T}, IList{int}, ArrayType)"]/*'/>
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GetItemsFromJaggedOp{T}"]/message_doc[@name="ArrayAverageConditional{ArrayType, DistributionArrayType, DistributionType}(IList{T}, IReadOnlyList{int}, IReadOnlyList{int}, ArrayType)"]/*'/>
/// <typeparam name="ArrayType">The type of the resulting array.</typeparam>
/// <typeparam name="DistributionArrayType">The type of a distribution over array elements.</typeparam>
/// <typeparam name="DistributionType">The type of a distribution over inner array elements.</typeparam>
public static ArrayType ArrayAverageConditional<ArrayType, DistributionArrayType, DistributionType>(
[SkipIfAllUniform] IList<T> items, IList<int> indices, IList<int> indices2, ArrayType result)
[SkipIfAllUniform] IList<T> items, IReadOnlyList<int> indices, IReadOnlyList<int> indices2, ArrayType result)
where ArrayType : IList<DistributionArrayType>, SettableToUniform
where DistributionArrayType : IList<DistributionType>
where DistributionType : HasPoint<T>
@ -345,11 +345,11 @@ namespace Microsoft.ML.Probabilistic.Factors
//-- VMP -------------------------------------------------------------------------------------------------------------
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GetItemsFromJaggedOp{T}"]/message_doc[@name="ItemsAverageLogarithm{DistributionArrayType, DistributionType}(IList{DistributionType}, IList{int}, int, DistributionType)"]/*'/>
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GetItemsFromJaggedOp{T}"]/message_doc[@name="ItemsAverageLogarithm{DistributionArrayType, DistributionType}(IList{DistributionType}, IReadOnlyList{int}, IReadOnlyList{int}, int, DistributionType)"]/*'/>
/// <typeparam name="DistributionArrayType">The type of a distribution over array elements.</typeparam>
/// <typeparam name="DistributionType">The type of a distribution over inner array elements.</typeparam>
public static DistributionType ItemsAverageLogarithm<DistributionArrayType, DistributionType>(
[SkipIfAllUniform] IList<DistributionArrayType> array, IList<int> indices, IList<int> indices2, int resultIndex, DistributionType result)
[SkipIfAllUniform] IList<DistributionArrayType> array, IReadOnlyList<int> indices, IReadOnlyList<int> indices2, int resultIndex, DistributionType result)
where DistributionArrayType : IList<DistributionType>
where DistributionType : SettableTo<DistributionType>
{
@ -358,11 +358,11 @@ namespace Microsoft.ML.Probabilistic.Factors
return result;
}
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GetItemsFromJaggedOp{T}"]/message_doc[@name="ItemsAverageLogarithmInit{TDist}(DistributionStructArray{TDist, T}, IList{int})"]/*'/>
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GetItemsFromJaggedOp{T}"]/message_doc[@name="ItemsAverageLogarithmInit{TDist}(DistributionStructArray{TDist, T}, IReadOnlyList{int}, IReadOnlyList{int})"]/*'/>
/// <typeparam name="TDist">The type of a distribution over array elements.</typeparam>
[Skip]
public static DistributionStructArray<TDist, T> ItemsAverageLogarithmInit<TDist>(
[IgnoreDependency] IList<DistributionStructArray<TDist, T>> array, IList<int> indices, IList<int> indices2)
[IgnoreDependency] IList<DistributionStructArray<TDist, T>> array, IReadOnlyList<int> indices, IReadOnlyList<int> indices2)
where TDist : struct,
SettableToProduct<TDist>,
SettableToRatio<TDist>,
@ -377,11 +377,11 @@ namespace Microsoft.ML.Probabilistic.Factors
return new DistributionStructArray<TDist, T>(indices.Count, i => (TDist)array[indices[i]][indices2[i]].Clone());
}
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GetItemsFromJaggedOp{T}"]/message_doc[@name="ItemsAverageLogarithmInit{TDist}(DistributionRefArray{TDist, T}, IList{int})"]/*'/>
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GetItemsFromJaggedOp{T}"]/message_doc[@name="ItemsAverageLogarithmInit{TDist}(DistributionRefArray{TDist, T}, IReadOnlyList{int}, IReadOnlyList{int})"]/*'/>
/// <typeparam name="TDist">The type of a distribution over array elements.</typeparam>
[Skip]
public static DistributionRefArray<TDist, T> ItemsAverageLogarithmInit<TDist>(
[IgnoreDependency] IList<DistributionRefArray<TDist, T>> array, IList<int> indices, IList<int> indices2)
[IgnoreDependency] IList<DistributionRefArray<TDist, T>> array, IReadOnlyList<int> indices, IReadOnlyList<int> indices2)
where TDist : class,
SettableTo<TDist>,
SettableToProduct<TDist>,
@ -397,12 +397,12 @@ namespace Microsoft.ML.Probabilistic.Factors
return new DistributionRefArray<TDist, T>(indices.Count, i => (TDist)array[indices[i]][indices2[i]].Clone());
}
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GetItemsFromJaggedOp{T}"]/message_doc[@name="ArrayAverageLogarithm{DistributionType, ArrayType}(IList{DistributionType}, IList{int}, ArrayType)"]/*'/>
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GetItemsFromJaggedOp{T}"]/message_doc[@name="ArrayAverageLogarithm{DistributionType, ArrayType}(IList{DistributionType}, IReadOnlyList{int}, IReadOnlyList{int}, ArrayType)"]/*'/>
/// <typeparam name="DistributionArrayType">The type of a distribution over array elements.</typeparam>
/// <typeparam name="DistributionType">The type of a distribution over inner array elements.</typeparam>
/// <typeparam name="ArrayType">The type of the resulting array.</typeparam>
public static ArrayType ArrayAverageLogarithm<DistributionArrayType, DistributionType, ArrayType>(
[SkipIfAllUniform] IList<DistributionType> items, IList<int> indices, IList<int> indices2, ArrayType result)
[SkipIfAllUniform] IList<DistributionType> items, IReadOnlyList<int> indices, IReadOnlyList<int> indices2, ArrayType result)
where ArrayType : IList<DistributionArrayType>, SettableToUniform
where DistributionArrayType : IList<DistributionType>
where DistributionType : SettableToUniform, SettableToProduct<DistributionType>
@ -418,11 +418,11 @@ namespace Microsoft.ML.Probabilistic.Factors
return result;
}
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GetItemsFromJaggedOp{T}"]/message_doc[@name="ArrayAverageLogarithm{DistributionType, ArrayType}(IList{T}, IList{int}, ArrayType)"]/*'/>
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GetItemsFromJaggedOp{T}"]/message_doc[@name="ArrayAverageLogarithm{DistributionType, ArrayType}(IList{T}, IReadOnlyList{int}, IReadOnlyList{int}, ArrayType)"]/*'/>
/// <typeparam name="DistributionArrayType">The type of a distribution over array elements.</typeparam>
/// <typeparam name="DistributionType">The type of a distribution over inner array elements.</typeparam>
/// <typeparam name="ArrayType">The type of the resulting array.</typeparam>
public static ArrayType ArrayAverageLogarithm<ArrayType, DistributionArrayType, DistributionType>(IList<T> items, IList<int> indices, IList<int> indices2, ArrayType result)
public static ArrayType ArrayAverageLogarithm<ArrayType, DistributionArrayType, DistributionType>(IList<T> items, IReadOnlyList<int> indices, IReadOnlyList<int> indices2, ArrayType result)
where ArrayType : IList<DistributionArrayType>, SettableToUniform
where DistributionArrayType : IList<DistributionType>
where DistributionType : HasPoint<T>

Просмотреть файл

@ -18,8 +18,8 @@ namespace Microsoft.ML.Probabilistic.Factors
[Buffers("marginal")]
public static class GetJaggedItemsOp<T>
{
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GetJaggedItemsOp{T}"]/message_doc[@name="LogAverageFactor(IList{T}, IList{T}, IList{int})"]/*'/>
public static double LogAverageFactor(IList<IList<T>> items, IList<T> array, IList<IList<int>> indices)
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GetJaggedItemsOp{T}"]/message_doc[@name="LogAverageFactor(IList{IList{T}}, IList{T}, IReadOnlyList{IReadOnlyList{int}})"]/*'/>
public static double LogAverageFactor(IList<IList<T>> items, IList<T> array, IReadOnlyList<IReadOnlyList<int>> indices)
{
IEqualityComparer<T> equalityComparer = Utilities.Util.GetEqualityComparer<T>();
for (int i = 0; i < indices.Count; i++)
@ -36,22 +36,22 @@ namespace Microsoft.ML.Probabilistic.Factors
return 0.0;
}
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GetJaggedItemsOp{T}"]/message_doc[@name="LogEvidenceRatio(IList{T}, IList{T}, IList{int})"]/*'/>
public static double LogEvidenceRatio(IList<IList<T>> items, IList<T> array, IList<IList<int>> indices)
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GetJaggedItemsOp{T}"]/message_doc[@name="LogEvidenceRatio(IList{IList{T}}, IList{T}, IReadOnlyList{IReadOnlyList{int}})"]/*'/>
public static double LogEvidenceRatio(IList<IList<T>> items, IList<T> array, IReadOnlyList<IReadOnlyList<int>> indices)
{
return LogAverageFactor(items, array, indices);
}
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GetJaggedItemsOp{T}"]/message_doc[@name="AverageLogFactor(IList{T}, IList{T}, IList{int})"]/*'/>
public static double AverageLogFactor(IList<IList<T>> items, IList<T> array, IList<IList<int>> indices)
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GetJaggedItemsOp{T}"]/message_doc[@name="AverageLogFactor(IList{IList{T}}, IList{T}, IReadOnlyList{IReadOnlyList{int}})"]/*'/>
public static double AverageLogFactor(IList<IList<T>> items, IList<T> array, IReadOnlyList<IReadOnlyList<int>> indices)
{
return LogAverageFactor(items, array, indices);
}
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GetJaggedItemsOp{T}"]/message_doc[@name="LogAverageFactor{DistributionType}(IList{DistributionType}, IList{DistributionType}, IList{int})"]/*'/>
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GetJaggedItemsOp{T}"]/message_doc[@name="LogAverageFactor{ItemType, DistributionType}(IList{ItemType}, IList{DistributionType}, IReadOnlyList{IReadOnlyList{int}})"]/*'/>
/// <typeparam name="DistributionType">The type of a distribution over array elements.</typeparam>
/// <typeparam name="ItemType">The type of a sub-array.</typeparam>
public static double LogAverageFactor<ItemType, DistributionType>(IList<ItemType> items, IList<DistributionType> array, IList<IList<int>> indices)
public static double LogAverageFactor<ItemType, DistributionType>(IList<ItemType> items, IList<DistributionType> array, IReadOnlyList<IReadOnlyList<int>> indices)
where DistributionType : IDistribution<T>, SettableToProduct<DistributionType>, CanGetLogAverageOf<DistributionType>
where ItemType : IList<DistributionType>
{
@ -79,7 +79,7 @@ namespace Microsoft.ML.Probabilistic.Factors
return z;
}
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GetJaggedItemsOp{T}"]/message_doc[@name="AverageLogFactor{DistributionType}(IList{DistributionType}, IList{DistributionType})"]/*'/>
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GetJaggedItemsOp{T}"]/message_doc[@name="AverageLogFactor{ItemType, DistributionType}(IList{ItemType}, IList{DistributionType})"]/*'/>
/// <typeparam name="DistributionType">The type of a distribution over array elements.</typeparam>
/// <typeparam name="ItemType">The type of a sub-array.</typeparam>
[Skip]
@ -90,9 +90,9 @@ namespace Microsoft.ML.Probabilistic.Factors
return 0.0;
}
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GetJaggedItemsOp{T}"]/message_doc[@name="LogAverageFactor{DistributionType}(IList{T}, IList{DistributionType}, IList{int})"]/*'/>
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GetJaggedItemsOp{T}"]/message_doc[@name="LogAverageFactor{DistributionType}(IList{IList{T}}, IList{DistributionType}, IReadOnlyList{IReadOnlyList{int}})"]/*'/>
/// <typeparam name="DistributionType">The type of a distribution over array elements.</typeparam>
public static double LogAverageFactor<DistributionType>(IList<IList<T>> items, IList<DistributionType> array, IList<IList<int>> indices)
public static double LogAverageFactor<DistributionType>(IList<IList<T>> items, IList<DistributionType> array, IReadOnlyList<IReadOnlyList<int>> indices)
where DistributionType : HasPoint<T>, CanGetLogProb<T>
{
double z = 0.0;
@ -119,15 +119,15 @@ namespace Microsoft.ML.Probabilistic.Factors
return z;
}
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GetJaggedItemsOp{T}"]/message_doc[@name="LogEvidenceRatio{DistributionType}(IList{T}, IList{DistributionType}, IList{int})"]/*'/>
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GetJaggedItemsOp{T}"]/message_doc[@name="LogEvidenceRatio{DistributionType}(IList{IList{T}}, IList{DistributionType}, IReadOnlyList{IReadOnlyList{int}})"]/*'/>
/// <typeparam name="DistributionType">The type of a distribution over array elements.</typeparam>
public static double LogEvidenceRatio<DistributionType>(IList<IList<T>> items, IList<DistributionType> array, IList<IList<int>> indices)
public static double LogEvidenceRatio<DistributionType>(IList<IList<T>> items, IList<DistributionType> array, IReadOnlyList<IReadOnlyList<int>> indices)
where DistributionType : HasPoint<T>, CanGetLogProb<T>
{
return LogAverageFactor<DistributionType>(items, array, indices);
}
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GetJaggedItemsOp{T}"]/message_doc[@name="AverageLogFactor{DistributionType}(IList{T}, IList{DistributionType})"]/*'/>
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GetJaggedItemsOp{T}"]/message_doc[@name="AverageLogFactor{DistributionType}(IList{IList{T}}, IList{DistributionType})"]/*'/>
/// <typeparam name="DistributionType">The type of a distribution over array elements.</typeparam>
[Skip]
public static double AverageLogFactor<DistributionType>(IList<IList<T>> items, IList<DistributionType> array)
@ -136,10 +136,10 @@ namespace Microsoft.ML.Probabilistic.Factors
return 0.0;
}
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GetJaggedItemsOp{T}"]/message_doc[@name="LogAverageFactor{DistributionType}(IList{DistributionType}, IList{T}, IList{int})"]/*'/>
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GetJaggedItemsOp{T}"]/message_doc[@name="LogAverageFactor{ItemType, DistributionType}(IList{ItemType}, IList{T}, IReadOnlyList{IReadOnlyList{int}})"]/*'/>
/// <typeparam name="DistributionType">The type of a distribution over array elements.</typeparam>
/// <typeparam name="ItemType">The type of a sub-array.</typeparam>
public static double LogAverageFactor<ItemType, DistributionType>(IList<ItemType> items, IList<T> array, IList<IList<int>> indices)
public static double LogAverageFactor<ItemType, DistributionType>(IList<ItemType> items, IList<T> array, IReadOnlyList<IReadOnlyList<int>> indices)
where DistributionType : CanGetLogProb<T>
where ItemType : IList<DistributionType>
{
@ -157,18 +157,18 @@ namespace Microsoft.ML.Probabilistic.Factors
return z;
}
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GetJaggedItemsOp{T}"]/message_doc[@name="LogEvidenceRatio{DistributionType}(IList{DistributionType}, IList{T}, IList{int})"]/*'/>
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GetJaggedItemsOp{T}"]/message_doc[@name="LogEvidenceRatio{ItemType, DistributionType}(IList{ItemType}, IList{T}, IReadOnlyList{IReadOnlyList{int}})"]/*'/>
/// <typeparam name="DistributionType">The type of a distribution over array elements.</typeparam>
/// <typeparam name="ItemType">The type of a sub-array.</typeparam>
[Skip]
public static double LogEvidenceRatio<ItemType, DistributionType>(IList<ItemType> items, IList<T> array, IList<IList<int>> indices)
public static double LogEvidenceRatio<ItemType, DistributionType>(IList<ItemType> items, IList<T> array, IReadOnlyList<IReadOnlyList<int>> indices)
where DistributionType : CanGetLogProb<T>
where ItemType : IList<DistributionType>
{
return 0.0;
}
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GetJaggedItemsOp{T}"]/message_doc[@name="AverageLogFactor{DistributionType}(IList{DistributionType}, IList{T})"]/*'/>
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GetJaggedItemsOp{T}"]/message_doc[@name="AverageLogFactor{ItemType, DistributionType}(IList{ItemType}, IList{T})"]/*'/>
/// <typeparam name="DistributionType">The type of a distribution over array elements.</typeparam>
/// <typeparam name="ItemType">The type of a sub-array.</typeparam>
[Skip]
@ -180,11 +180,11 @@ namespace Microsoft.ML.Probabilistic.Factors
}
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GetJaggedItemsOp{T}"]/message_doc[@name="LogEvidenceRatio{DistributionType}(IList{DistributionType}, IList{DistributionType}, IList{int}, IList{DistributionType})"]/*'/>
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GetJaggedItemsOp{T}"]/message_doc[@name="LogEvidenceRatio{ItemType, DistributionType}(IList{ItemType}, IList{DistributionType}, IReadOnlyList{IReadOnlyList{int}}, IList{ItemType})"]/*'/>
/// <typeparam name="DistributionType">The type of a distribution over array elements.</typeparam>
/// <typeparam name="ItemType">The type of a sub-array.</typeparam>
public static double LogEvidenceRatio<ItemType, DistributionType>(
IList<ItemType> items, IList<DistributionType> array, IList<IList<int>> indices, IList<ItemType> to_items)
IList<ItemType> items, IList<DistributionType> array, IReadOnlyList<IReadOnlyList<int>> indices, IList<ItemType> to_items)
where DistributionType : SettableToUniform, SettableToProduct<DistributionType>, CanGetLogAverageOf<DistributionType>, ICloneable
where ItemType : IList<DistributionType>
{
@ -241,12 +241,12 @@ namespace Microsoft.ML.Probabilistic.Factors
return result;
}
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GetJaggedItemsOp{T}"]/message_doc[@name="MarginalIncrement{ArrayType, DistributionType}(ArrayType, DistributionType, DistributionType, IList{int}, int)"]/*'/>
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GetJaggedItemsOp{T}"]/message_doc[@name="MarginalIncrement{ArrayType, ItemType, DistributionType}(ArrayType, ItemType, ItemType, IReadOnlyList{IReadOnlyList{int}}, int)"]/*'/>
/// <typeparam name="ArrayType">The type of an array for the marginal.</typeparam>
/// <typeparam name="DistributionType">The type of a distribution over array elements.</typeparam>
/// <typeparam name="ItemType">The type of a sub-array.</typeparam>
public static ArrayType MarginalIncrement<ArrayType, ItemType, DistributionType>(
ArrayType result, ItemType to_item, [SkipIfUniform] ItemType item, IList<IList<int>> indices, int resultIndex)
ArrayType result, ItemType to_item, [SkipIfUniform] ItemType item, IReadOnlyList<IReadOnlyList<int>> indices, int resultIndex)
where ArrayType : IList<DistributionType>, SettableTo<ArrayType>
where DistributionType : SettableToProduct<DistributionType>
where ItemType : IList<DistributionType>
@ -264,7 +264,7 @@ namespace Microsoft.ML.Probabilistic.Factors
return result;
}
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GetJaggedItemsOp{T}"]/message_doc[@name="ItemsAverageConditional{ArrayType, DistributionType}(DistributionType, ArrayType, ArrayType, IList{int}, int, DistributionType)"]/*'/>
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GetJaggedItemsOp{T}"]/message_doc[@name="ItemsAverageConditional{ArrayType, ItemType, DistributionType}(ItemType, ArrayType, ArrayType, IReadOnlyList{IReadOnlyList{int}}, int, ItemType)"]/*'/>
/// <typeparam name="ArrayType">The type of an array for the marginal.</typeparam>
/// <typeparam name="DistributionType">The type of a distribution over array elements.</typeparam>
/// <typeparam name="ItemType">The type of a sub-array.</typeparam>
@ -272,7 +272,7 @@ namespace Microsoft.ML.Probabilistic.Factors
[Indexed, Cancels] ItemType items,
[IgnoreDependency] ArrayType array, // must have an (unused) 'array' argument to determine the type of 'marginal' buffer
[SkipIfAllUniform] ArrayType marginal,
IList<IList<int>> indices,
IReadOnlyList<IReadOnlyList<int>> indices,
int resultIndex,
ItemType result)
where ArrayType : IList<DistributionType>
@ -292,12 +292,12 @@ namespace Microsoft.ML.Probabilistic.Factors
return result;
}
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GetJaggedItemsOp{T}"]/message_doc[@name="ArrayAverageConditional{DistributionType, ArrayType}(IList{DistributionType}, IList{int}, ArrayType)"]/*'/>
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GetJaggedItemsOp{T}"]/message_doc[@name="ArrayAverageConditional{ItemType, DistributionType, ArrayType}(IList{ItemType}, IReadOnlyList{IReadOnlyList{int}}, ArrayType)"]/*'/>
/// <typeparam name="ItemType">The type of a sub-array.</typeparam>
/// <typeparam name="DistributionType">The type of a distribution over array elements.</typeparam>
/// <typeparam name="ArrayType">The type of the resulting array.</typeparam>
public static ArrayType ArrayAverageConditional<ItemType, DistributionType, ArrayType>(
[SkipIfAllUniform] IList<ItemType> items, IList<IList<int>> indices, ArrayType result)
[SkipIfAllUniform] IList<ItemType> items, IReadOnlyList<IReadOnlyList<int>> indices, ArrayType result)
where ArrayType : IList<DistributionType>, SettableToUniform
where DistributionType : SettableToProduct<DistributionType>
where ItemType : IList<DistributionType>
@ -320,11 +320,11 @@ namespace Microsoft.ML.Probabilistic.Factors
return result;
}
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GetJaggedItemsOp{T}"]/message_doc[@name="ArrayAverageConditional{DistributionType, ArrayType}(IList{T}, IList{int}, ArrayType)"]/*'/>
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GetJaggedItemsOp{T}"]/message_doc[@name="ArrayAverageConditional{DistributionType, ArrayType}(IList{IList{T}}, IReadOnlyList{IReadOnlyList{int}}, ArrayType)"]/*'/>
/// <typeparam name="DistributionType">The type of a distribution over array elements.</typeparam>
/// <typeparam name="ArrayType">The type of the resulting array.</typeparam>
public static ArrayType ArrayAverageConditional<DistributionType, ArrayType>(
[SkipIfAllUniform] IList<IList<T>> items, IList<IList<int>> indices, ArrayType result)
[SkipIfAllUniform] IList<IList<T>> items, IReadOnlyList<IReadOnlyList<int>> indices, ArrayType result)
where ArrayType : IList<DistributionType>, SettableToUniform
where DistributionType : HasPoint<T>
{
@ -348,11 +348,11 @@ namespace Microsoft.ML.Probabilistic.Factors
//-- VMP -------------------------------------------------------------------------------------------------------------
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GetJaggedItemsOp{T}"]/message_doc[@name="ItemsAverageLogarithm{DistributionType}(IList{DistributionType}, IList{int}, int, DistributionType)"]/*'/>
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GetJaggedItemsOp{T}"]/message_doc[@name="ItemsAverageLogarithm{ItemType, DistributionType}(IList{DistributionType}, IReadOnlyList{IReadOnlyList{int}}, int, ItemType)"]/*'/>
/// <typeparam name="ItemType">The type of a sub-array.</typeparam>
/// <typeparam name="DistributionType">The type of a distribution over array elements.</typeparam>
public static ItemType ItemsAverageLogarithm<ItemType, DistributionType>(
[SkipIfAllUniform] IList<DistributionType> array, IList<IList<int>> indices, int resultIndex, ItemType result)
[SkipIfAllUniform] IList<DistributionType> array, IReadOnlyList<IReadOnlyList<int>> indices, int resultIndex, ItemType result)
where DistributionType : SettableTo<DistributionType>
where ItemType : IList<DistributionType>
{
@ -368,12 +368,12 @@ namespace Microsoft.ML.Probabilistic.Factors
return result;
}
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GetJaggedItemsOp{T}"]/message_doc[@name="ArrayAverageLogarithm{DistributionType, ArrayType}(IList{DistributionType}, IList{int}, ArrayType)"]/*'/>
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GetJaggedItemsOp{T}"]/message_doc[@name="ArrayAverageLogarithm{ItemType, DistributionType, ArrayType}(IList{ItemType}, IReadOnlyList{IReadOnlyList{int}}, ArrayType)"]/*'/>
/// <typeparam name="ItemType">The type of a sub-array.</typeparam>
/// <typeparam name="DistributionType">The type of a distribution over array elements.</typeparam>
/// <typeparam name="ArrayType">The type of the resulting array.</typeparam>
public static ArrayType ArrayAverageLogarithm<ItemType, DistributionType, ArrayType>(
[SkipIfAllUniform] IList<ItemType> items, IList<IList<int>> indices, ArrayType result)
[SkipIfAllUniform] IList<ItemType> items, IReadOnlyList<IReadOnlyList<int>> indices, ArrayType result)
where ArrayType : IList<DistributionType>, SettableToUniform
where DistributionType : SettableToUniform, SettableToProduct<DistributionType>
where ItemType : IList<DistributionType>
@ -381,10 +381,10 @@ namespace Microsoft.ML.Probabilistic.Factors
return ArrayAverageConditional<ItemType, DistributionType, ArrayType>(items, indices, result);
}
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GetJaggedItemsOp{T}"]/message_doc[@name="ArrayAverageLogarithm{DistributionType, ArrayType}(IList{T}, IList{int}, ArrayType)"]/*'/>
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="GetJaggedItemsOp{T}"]/message_doc[@name="ArrayAverageLogarithm{DistributionType, ArrayType}(IList{IList{T}}, IReadOnlyList{IReadOnlyList{int}}, ArrayType)"]/*'/>
/// <typeparam name="DistributionType">The type of a distribution over array elements.</typeparam>
/// <typeparam name="ArrayType">The type of the resulting array.</typeparam>
public static ArrayType ArrayAverageLogarithm<DistributionType, ArrayType>(IList<IList<T>> items, IList<IList<int>> indices, ArrayType result)
public static ArrayType ArrayAverageLogarithm<DistributionType, ArrayType>(IList<IList<T>> items, IReadOnlyList<IReadOnlyList<int>> indices, ArrayType result)
where ArrayType : IList<DistributionType>, SettableToUniform
where DistributionType : HasPoint<T>
{

Просмотреть файл

@ -51,6 +51,11 @@ namespace Microsoft.ML.Probabilistic.Factors
if (b.IsPointMass)
return SumAverageConditional(a, b.Point);
if (a.IsUniform() || b.IsUniform()) return Gaussian.Uniform();
// E[sum] = E[a] + E[b]
// var(sum) = var(a) + var(b) = 1/aPrec + 1/bPrec
// E[sum]/var(sum) = E[a]/var(sum) + E[b]/var(sum)
// = E[a]/var(a)*var(a)/(1/aPrec + 1/bPrec) + E[b]/var(sum)
// var(a)/(1/aPrec + 1/bPrec) = 1/(1 + aPrec/bPrec) = bPrec/(aPrec + bPrec)
double meanTimesPrec = MMath.WeightedAverage(b.Precision, a.MeanTimesPrecision, a.Precision, b.MeanTimesPrecision);
return Gaussian.FromNatural(meanTimesPrec, GetPrecisionOfSum(a, b));
}

Просмотреть файл

@ -227,7 +227,7 @@ namespace Microsoft.ML.Probabilistic.Factors
if (B.IsPointMass)
return ProductAverageConditional(A, B.Point);
if (Product.IsPointMass)
throw new NotImplementedException();
return GaussianProductOp_Slow.ProductAverageConditional(Product, A, B);
if (Product.Precision < 1e-100)
return GaussianProductVmpOp.ProductAverageLogarithm(A, B);
double mA, vA;
@ -381,14 +381,14 @@ namespace Microsoft.ML.Probabilistic.Factors
sumA2 += a * a * fInvA;
}
double mean = sumA / z;
double var = sumA2 / z - mean * mean;
if (z == 0 || var <= 0)
double variance = sumA2 / z - mean * mean;
if (z == 0 || variance <= 0 || variance >= vA)
{
return GaussianProductOp_Slow.AAverageConditional(Product, A, B);
//throw new Exception("quadrature failed");
}
Gaussian result = new Gaussian();
result.SetMeanAndVariance(mean, var);
result.SetMeanAndVariance(mean, variance);
result.SetToRatio(result, A, ForceProper);
return result;
}
@ -542,9 +542,7 @@ namespace Microsoft.ML.Probabilistic.Factors
double diff = mProduct - a * mB;
double diffv = diff / v;
double diffv2 = diffv * diffv;
double v2 = v * v;
double dlogf = -diffv;
double avb = a * vB;
double ddlogf = diffv2 -1/v;
if ((i == 0 || i == n - 1) && (logf > -49))
throw new Exception("invalid integration bounds");
@ -566,23 +564,41 @@ namespace Microsoft.ML.Probabilistic.Factors
else
{
// Compute the marginal and then divide
double rmin = Math.Sign(amin) * Math.Pow(Math.Abs(amin), 1.0 / 3);
double rmax = Math.Sign(amax) * Math.Pow(Math.Abs(amax), 1.0 / 3);
double rinc = (rmax - rmin) / (n - 1);
bool useCube = 1000 * vB > vProduct;
MeanVarianceAccumulator mva = new MeanVarianceAccumulator();
for (int i = 0; i < n; i++)
{
double a = amin + i * inc;
double a, r = default;
if (useCube)
{
r = rmin + i * rinc;
a = Math.Pow(r, 3);
}
else
{
a = amin + i * inc;
}
double logfA = LogLikelihoodRatio(a, a0, mProduct, vProduct, mA, pA, mB, vB);
double fA = Math.Exp(logfA);
double v = vProduct + a * a * vB;
double mX = a * (mProduct * a * vB + vProduct * mB)/v;
double vX = a*a*vB*vProduct / v;
if (useCube)
{
fA *= 3 * r * r;
}
double avB = a * vB;
double v = vProduct + a * avB;
double mX = a * (mProduct * avB + vProduct * mB) / v;
double vX = a * avB * vProduct / v;
mva.Add(mX, vX, fA);
}
double mean = mva.Mean;
double var = mva.Variance;
if (var <= 0)
double variance = mva.Variance;
if (variance <= 0)
throw new Exception("quadrature failed");
Gaussian result = new Gaussian();
result.SetMeanAndVariance(mean, var);
result.SetMeanAndVariance(mean, variance);
result.SetToRatio(result, Product, GaussianProductOp.ForceProper);
return result;
}
@ -662,11 +678,11 @@ namespace Microsoft.ML.Probabilistic.Factors
mva.Add(a, fA);
}
double mean = mva.Mean;
double var = mva.Variance;
if (var <= 0)
double variance = mva.Variance;
if (variance <= 0)
throw new Exception("quadrature failed");
Gaussian result = new Gaussian();
result.SetMeanAndVariance(mean, var);
result.SetMeanAndVariance(mean, variance);
result.SetToRatio(result, A, GaussianProductOp.ForceProper);
return result;
}

Просмотреть файл

@ -136,7 +136,7 @@ namespace Microsoft.ML.Probabilistic.Factors
bool hasPrevious;
double prevPoint;
double prevSign2 = double.NaN, prevSign3 = double.NaN;
public static bool EnsureConvergence = true;
public static bool EnsureConvergence = false;
int updateCount = 0;
int updateLimit = int.MaxValue;
int recoveryCount = 10;

Просмотреть файл

@ -77,7 +77,7 @@ namespace TestApp
//InferenceEngine.DefaultEngine.Compiler.UseLocals = false;
TestUtils.SetDebugOptions();
TestUtils.SetBrowserMode(BrowserMode.OnError);
TestUtils.SetBrowserMode(BrowserMode.Always);
//TestUtils.SetBrowserMode(BrowserMode.Always);
//TestUtils.SetBrowserMode(BrowserMode.WriteFiles);
Stopwatch watch = new Stopwatch();
@ -113,7 +113,6 @@ namespace TestApp
watch.Stop();
Console.WriteLine("elapsed time = {0}ms", watch.ElapsedMilliseconds);
}
}
}

Просмотреть файл

@ -21,6 +21,7 @@ namespace Microsoft.ML.Probabilistic.Tests
[Fact]
public void WeightedAverageTest()
{
Assert.Equal(Environment.Is64BitProcess ? 3.86361619394904E-311 : 3.86361619394162E-311, MMath.WeightedAverage(0.82912896852490248, 2.5484859206000203E-311, 3.50752234977395E-313, 31.087830618727477));
Assert.Equal(MMath.WeightedAverage(0.1, double.MinValue, 0.01, double.MinValue), double.MinValue);
Assert.Equal(MMath.WeightedAverage(0.1, -double.Epsilon, double.MaxValue, -double.Epsilon), -double.Epsilon);
Assert.Equal(MMath.WeightedAverage(1e-100, 2e-250, 1e-100, 4e-250), MMath.Average(2e-250, 4e-250));
@ -47,8 +48,8 @@ namespace Microsoft.ML.Probabilistic.Tests
if (count > limit) break;
if (double.IsNaN(a + b)) continue;
double midpoint = MMath.WeightedAverage(wa, a, wb, b);
Assert.True(midpoint >= System.Math.Min(a, b), $"Failed assertion: {midpoint} >= {System.Math.Min(a, b)}, wa={wa:r}, a={a:r}, wb={wb:r}, b={b:r}");
Assert.True(midpoint <= System.Math.Max(a, b), $"Failed assertion: {midpoint} <= {System.Math.Max(a, b)}, wa={wa:r}, a={a:r}, wb={wb:r}, b={b:r}");
Assert.True(midpoint >= System.Math.Min(a, b), $"Failed assertion: MMath.WeightedAverage({wa:r}, {a:r}, {wb:r}, {b:r}) {midpoint} >= {System.Math.Min(a, b)}");
Assert.True(midpoint <= System.Math.Max(a, b), $"Failed assertion: MMath.WeightedAverage({wa:r}, {a:r}, {wb:r}, {b:r}) {midpoint} <= {System.Math.Max(a, b)}");
if (wa == wb) Assert.Equal(MMath.Average(a, b), midpoint);
Interlocked.Add(ref count, 1);
}

Просмотреть файл

@ -966,11 +966,14 @@ namespace Microsoft.ML.Probabilistic.Tests
var basePrecision = Variable.GammaFromShapeAndRate(1, basePrecisionRate);
basePrecision.AddAttribute(new PointEstimate());
//basePrecision.InitialiseTo(Gamma.PointMass(0.01));
basePrecision.Name = nameof(basePrecision);
var baseSkill = Variable.Array<double>(player);
baseSkill.Name = nameof(baseSkill);
baseSkill[player] = Variable.GaussianFromMeanAndPrecision(0, basePrecision).ForEach(player);
Range mode = new Range(2);
var offsetPrecisionRate = Variable.GammaFromShapeAndRate(1, 1);
var offsetPrecision = Variable.Array<double>(mode);
offsetPrecision.Name = nameof(offsetPrecision);
offsetPrecision[mode] = Variable.GammaFromShapeAndRate(1, offsetPrecisionRate).ForEach(mode);
offsetPrecision.AddAttribute(new PointEstimate());
var offset = Variable.Array(Variable.Array<double>(mode), player);
@ -995,18 +998,28 @@ namespace Microsoft.ML.Probabilistic.Tests
if (gaussianLikelihood)
{
var data = Variable.Observed(default(Gaussian[][]), player, mode);
Range game = new Range(100);
using (Variable.ForEach(game))
double dataPrecision = 100;
bool redundantAddition = false;
if (redundantAddition)
{
var skillInGame = Variable.Array(Variable.Array<double>(mode), player);
skillInGame[player][mode] = baseSkill[player] + offset[player][mode];
Variable.ConstrainEqualRandom(skillInGame[player][mode], data[player][mode]);
int gameCount = 100;
Range game = new Range(gameCount);
using (Variable.ForEach(game))
{
var skillInGame = Variable.Array(Variable.Array<double>(mode), player);
skillInGame[player][mode] = baseSkill[player] + offset[player][mode];
Variable.ConstrainEqualRandom(skillInGame[player][mode], data[player][mode]);
}
dataPrecision /= gameCount;
}
else
{
Variable.ConstrainEqualRandom(skill[player][mode], data[player][mode]);
}
//Variable.ConstrainEqualRandom(skill[player][mode], data[player][mode]);
data.ObservedValue = Util.ArrayInit(player.SizeAsInt, i =>
Util.ArrayInit(mode.SizeAsInt, j =>
Gaussian.FromMeanAndPrecision(trueSkills[i][j], 1)));
Gaussian.FromMeanAndPrecision(trueSkills[i][j], dataPrecision)));
}
else
{
@ -1042,15 +1055,259 @@ namespace Microsoft.ML.Probabilistic.Tests
InferenceEngine engine = new InferenceEngine();
engine.NumberOfIterations = 100;
engine.Compiler.GivePriorityTo(typeof(VariablePointOp_Mean<>));
engine.Compiler.GivePriorityTo(typeof(GammaFromShapeAndRateOp_Laplace));
//engine.Compiler.GivePriorityTo(typeof(VariablePointOp_Mean<>));
//engine.Compiler.GivePriorityTo(typeof(GammaFromShapeAndRateOp_Laplace));
var baseSkillActual = engine.Infer<IList<Gaussian>>(baseSkill);
for (int i = 0; i < 3; i++)
for (int i = 0; i < 5; i++)
{
Console.WriteLine("baseSkill[{0}] = {1} should be {2}", i, baseSkillActual[i], trueBaseSkills[i]);
Trace.WriteLine($"baseSkill[{i}] = {baseSkillActual[i]} should be {trueBaseSkills[i]}");
}
Console.WriteLine("basePrecision = {0} should be {1}", engine.Infer(basePrecision), trueBasePrecision);
Console.WriteLine(StringUtil.JoinColumns(engine.Infer(offsetPrecision), " should be ", StringUtil.VerboseToString(trueOffsetPrecisions)));
Trace.WriteLine($"basePrecision = {engine.Infer(basePrecision)} should be {trueBasePrecision}");
Trace.WriteLine(StringUtil.JoinColumns(engine.Infer(offsetPrecision), " should be ", StringUtil.VerboseToString(trueOffsetPrecisions)));
}
/// <summary>
/// Test different ways of representing a model
/// </summary>
internal void FactorAnalysisTest2()
{
Range player = new Range(1000);
player.Name = nameof(player);
var baseVariance = Variable.Exp(Variable.GaussianFromMeanAndPrecision(-2, 1e-2));
baseVariance.AddAttribute(new PointEstimate());
bool initialiseSmall = false;
if (initialiseSmall)
{
baseVariance.InitialiseTo(Gamma.PointMass(0.01));
}
else
{
// If baseVariance is initialised smaller than offsetVariance, baseVariance will get stuck at zero.
baseVariance.InitialiseTo(Gamma.PointMass(1));
}
baseVariance.Name = nameof(baseVariance);
var baseSkill = Variable.Array<double>(player);
baseSkill.Name = nameof(baseSkill);
baseSkill[player] = Variable.GaussianFromMeanAndVariance(0, baseVariance).ForEach(player);
Range mode = new Range(2);
mode.Name = nameof(mode);
var offsetVariance = Variable.Array<double>(mode);
offsetVariance.Name = nameof(offsetVariance);
offsetVariance[mode] = Variable.Exp(Variable.GaussianFromMeanAndPrecision(-2, 1e-2).ForEach(mode));
offsetVariance.AddAttribute(new PointEstimate());
offsetVariance[mode].InitialiseTo(Gamma.PointMass(0.1));
var offset = Variable.Array(Variable.Array<double>(mode), player);
offset.Name = nameof(offset);
offset[player][mode] = Variable.GaussianFromMeanAndVariance(0, offsetVariance[mode]).ForEach(player);
var skill = Variable.Array(Variable.Array<double>(mode), player);
skill.Name = nameof(skill);
// equivalent to: Variable.GaussianFromMeanAndVariance(baseSkill[player], offsetVariance[mode])
skill[player][mode] = baseSkill[player] + offset[player][mode];
// sample from model
Rand.Restart(0);
double trueBaseVariance = 5;
Gaussian basePrior = Gaussian.FromMeanAndVariance(0, trueBaseVariance);
double[] trueBaseSkills = Util.ArrayInit(player.SizeAsInt, i => basePrior.Sample());
double[] trueOffsetVariances = Util.ArrayInit(mode.SizeAsInt, j => 1.0);
double[][] trueOffsets = Util.ArrayInit(player.SizeAsInt, i =>
Util.ArrayInit(mode.SizeAsInt, j =>
Gaussian.FromMeanAndVariance(0, trueOffsetVariances[j]).Sample()));
double[][] trueSkills = Util.ArrayInit(player.SizeAsInt, i =>
Util.ArrayInit(mode.SizeAsInt, j =>
trueBaseSkills[i] + trueOffsets[i][j]));
int teamSize = 1;
bool redundantAddition = false;
bool gaussianLikelihood = true;
bool sequential = false;
if (gaussianLikelihood)
{
var data = Variable.Observed(default(Gaussian[][]), player, mode);
// If dataPrecision is smaller than true offsetVariance, learned offsetVariance goes to zero.
double dataPrecision = 10;
if (redundantAddition)
{
int gameCount = 100;
Range game = new Range(gameCount);
using (Variable.ForEach(game))
{
var skillInGame = Variable.Array(Variable.Array<double>(mode), player);
skillInGame[player][mode] = baseSkill[player] + offset[player][mode];
Variable.ConstrainEqualRandom(skillInGame[player][mode], data[player][mode]);
}
dataPrecision /= gameCount;
}
else
{
Variable.ConstrainEqualRandom(skill[player][mode], data[player][mode]);
}
data.ObservedValue = Util.ArrayInit(player.SizeAsInt, i =>
Util.ArrayInit(mode.SizeAsInt, j =>
Gaussian.FromMeanAndPrecision(trueSkills[i][j], dataPrecision)));
}
else
{
var gameCount = 20000;
// With too few games and teamSize=1, redundantAddition causes learned all offsetVariances to be zero, or
// one learned offsetVariance is zero, and the others are inflated to compensate.
// More games just slows down convergence.
// Sequential does not affect this.
// The estimates have similar accuracy, but posterior variance is lower.
// Because estimates tend to be smoothed versions of the truth, low posterior variance leads to smaller variance estimates.
//if (redundantAddition) gameCount *= 10;
Range game = new Range(gameCount);
if (teamSize > 2 || (teamSize == 2 && redundantAddition))
{
// teamSize>2 causes estimates to go to infinity if games are not sequential
// teamSize=2 with redundantAddition causes stuck state if games are not sequential
game.AddAttribute(new Sequential());
sequential = true;
}
var observedModes = Variable.Observed(Util.ArrayInit(gameCount, i => Rand.Int(mode.SizeAsInt)), game);
observedModes.Name = nameof(observedModes);
var allPlayers = Enumerable.Range(0, player.SizeAsInt).ToArray();
if (teamSize == 1)
{
// works for redundantAddition=false and true without Sequential
// teamSize=1, redundantAddition=true Sequential gives baseVariance=9 (others are fine)
// schedule is ruining the results?
List<int> observedWinner = new List<int>();
List<int> observedLoser = new List<int>();
for (int i = 0; i < gameCount; i++)
{
var modeOfGame = observedModes.ObservedValue[i];
var players = Rand.SampleWithoutReplacement(allPlayers, 2).ToList();
var team0Performance = trueSkills[players[0]][modeOfGame] + Rand.Normal();
var team1Performance = trueSkills[players[1]][modeOfGame] + Rand.Normal();
if (team0Performance > team1Performance)
{
observedWinner.Add(players[0]);
observedLoser.Add(players[1]);
}
else
{
observedWinner.Add(players[1]);
observedLoser.Add(players[0]);
}
}
var winner = Variable.Observed(observedWinner, game);
winner.Name = nameof(winner);
var loser = Variable.Observed(observedLoser, game);
loser.Name = nameof(loser);
using (Variable.ForEach(game))
{
var modeOfGame = observedModes[game];
Variable<double> winnerSkill;
Variable<double> loserSkill;
if (redundantAddition)
{
winnerSkill = baseSkill[winner[game]] + offset[winner[game]][modeOfGame];
loserSkill = baseSkill[loser[game]] + offset[loser[game]][modeOfGame];
}
else
{
winnerSkill = skill[winner[game]][modeOfGame];
loserSkill = skill[loser[game]][modeOfGame];
}
var winnerPerformance = Variable.GaussianFromMeanAndPrecision(winnerSkill, 1);
winnerPerformance.Name = nameof(winnerPerformance);
var loserPerformance = Variable.GaussianFromMeanAndPrecision(loserSkill, 1);
loserPerformance.Name = nameof(loserPerformance);
Variable.ConstrainTrue(winnerPerformance > loserPerformance);
}
}
else
{
// teamSize=1, redundantAddition=true gives baseVariance=9 (others are fine)
// teamSize=2, redundantAddition=true gives baseVariance=14 (others are fine)
// teamSize=3, redundantAddition=true gives baseVariance=18 (others are fine)
// teamSize=4, redundantAddition=true gives baseVariance=22 (others are fine)
List<int[]> observedWinner = new List<int[]>();
List<int[]> observedLoser = new List<int[]>();
for (int i = 0; i < gameCount; i++)
{
var modeOfGame = observedModes.ObservedValue[i];
var players = Rand.SampleWithoutReplacement(allPlayers, 2 * teamSize).ToList();
var team0 = Collection.Split(players, teamSize, out int[] team1);
var team0Performance = team0.Select(p => trueSkills[p][modeOfGame] + Rand.Normal()).Sum();
var team1Performance = team1.Select(p => trueSkills[p][modeOfGame] + Rand.Normal()).Sum();
if (team0Performance > team1Performance)
{
observedWinner.Add(team0);
observedLoser.Add(team1);
}
else
{
observedWinner.Add(team1);
observedLoser.Add(team0);
}
}
Range playerOnTeam = new Range(teamSize);
playerOnTeam.Name = nameof(playerOnTeam);
var winner = Variable.Observed(observedWinner, game, playerOnTeam);
winner.Name = nameof(winner);
var loser = Variable.Observed(observedLoser, game, playerOnTeam);
loser.Name = nameof(loser);
using (Variable.ForEach(game))
{
var modeOfGame = observedModes[game];
VariableArray<double> winnerSkills = Variable.Array<double>(playerOnTeam);
winnerSkills.Name = nameof(winnerSkills);
VariableArray<double> loserSkills = Variable.Array<double>(playerOnTeam);
loserSkills.Name = nameof(loserSkills);
if (redundantAddition)
{
winnerSkills[playerOnTeam] = baseSkill[winner[game][playerOnTeam]] + offset[winner[game][playerOnTeam]][modeOfGame];
loserSkills[playerOnTeam] = baseSkill[loser[game][playerOnTeam]] + offset[loser[game][playerOnTeam]][modeOfGame];
}
else
{
winnerSkills[playerOnTeam] = skill[winner[game][playerOnTeam]][modeOfGame];
loserSkills[playerOnTeam] = skill[loser[game][playerOnTeam]][modeOfGame];
}
var winnerPerformances = Variable.Array<double>(playerOnTeam);
winnerPerformances.Name = nameof(winnerPerformances);
winnerPerformances[playerOnTeam] = Variable.GaussianFromMeanAndPrecision(winnerSkills[playerOnTeam], 1);
var winnerPerformance = Variable.Sum(winnerPerformances);
winnerPerformance.Name = nameof(winnerPerformance);
var loserPerformances = Variable.Array<double>(playerOnTeam);
loserPerformances.Name = nameof(loserPerformances);
loserPerformances[playerOnTeam] = Variable.GaussianFromMeanAndPrecision(loserSkills[playerOnTeam], 1);
var loserPerformance = Variable.Sum(loserPerformances);
loserPerformance.Name = nameof(loserPerformance);
Variable.ConstrainTrue(winnerPerformance > loserPerformance);
}
}
}
InferenceEngine engine = new InferenceEngine();
engine.Compiler.UseParallelForLoops = !sequential;
//engine.Compiler.GivePriorityTo(typeof(VariablePointOp_Mean<>));
//engine.Compiler.GivePriorityTo(typeof(GammaFromShapeAndRateOp_Laplace));
engine.Compiler.GivePriorityTo(typeof(GaussianOp_PointPrecision));
engine.Compiler.GivePriorityTo(typeof(GaussianFromMeanAndVarianceOp_PointVariance));
for (int i = 0; i < 1000; i++)
{
engine.NumberOfIterations = i + 1;
Trace.WriteLine($"baseVariance = {engine.Infer(baseVariance)} should be {trueBaseVariance}");
Trace.WriteLine(StringUtil.JoinColumns(engine.Infer(offsetVariance), " should be ", StringUtil.VerboseToString(trueOffsetVariances)));
}
var baseSkillActual = engine.Infer<IReadOnlyList<Gaussian>>(baseSkill);
var offsetSkillActual = engine.Infer<IReadOnlyList<IReadOnlyList<Gaussian>>>(offset);
for (int i = 0; i < 5; i++)
{
// baseSkills are not always accurate since they are inferred to be between the mode skills.
Trace.WriteLine($"baseSkill[{i}] = {baseSkillActual[i]} should be {trueBaseSkills[i]}");
for (int j = 0; j < mode.SizeAsInt; j++)
{
Trace.WriteLine($"offset[{i}][{j}] = {offsetSkillActual[i][j]} should be {trueOffsets[i][j]}");
}
}
Trace.WriteLine($"baseVariance = {engine.Infer(baseVariance)} should be {trueBaseVariance}");
Trace.WriteLine(StringUtil.JoinColumns(engine.Infer(offsetVariance), " should be ", StringUtil.VerboseToString(trueOffsetVariances)));
}
/// <summary>

Просмотреть файл

@ -34,6 +34,19 @@ namespace Microsoft.ML.Probabilistic.Tests
[Fact]
public void ProductOpTest()
{
Assert.True(GaussianProductOp_Slow.ProductAverageConditional(
Gaussian.FromNatural(0.0019528178431691338, 3.25704676859826E-06),
Gaussian.FromNatural(-1.4311468676808659E-17, 5.4527745979495584E-21),
Gaussian.FromNatural(2157531.2967657731, 1830.6558666566498)).Precision > 0); // Gaussian.FromNatural()
Assert.True(GaussianProductOp_Slow.ProductAverageConditional(
Gaussian.FromNatural(6.2927332361739073E-13, 0.00099999696614431447),
Gaussian.FromNatural(-3.4418586572681724E-14, 4.2560312731693555E-12),
Gaussian.FromNatural(-2.58594546750577, 0.1)).Precision > 0); // Gaussian.FromNatural(1.262909232222487E-15, 6.6429067108186857E-15)
Assert.True(GaussianProductOp_Slow.ProductAverageConditional(
Gaussian.FromNatural(1.0947079898711334E-15, 0.00099999696759297),
Gaussian.FromNatural(-9.7432361496028023E-16, 2.630301623215118E-09),
Gaussian.FromNatural(-2.5848205615986561, 0.1)).Precision > 0); // Gaussian.FromNatural(7.0300069947451969E-17, 4.2701144269824409E-12)
var testCases = new[]
{
(4.94065645841247E-324, 0, -1e-5, 29),
@ -77,7 +90,10 @@ namespace Microsoft.ML.Probabilistic.Tests
Gaussian.FromMeanAndVariance(BMean, BVariance)).MaxDiff(expected) < 1e-5);
}
Assert.True(GaussianProductOp.AAverageConditional(
Gaussian.FromNatural(0.11690888200261176, 0.00021561758318567543),
Gaussian.FromNatural(2.3189502343045755E-17, 0.00024804962073216578),
Gaussian.FromNatural(3825912.925085804, 3815545.0940052439)).Precision > 0); // Gaussian.FromNatural(0.11722698913727095, 0.00021679261874209184)
Assert.True(GaussianProductOp.AAverageConditional(6.0, 2.0)
.MaxDiff(Gaussian.PointMass(6.0 / 2.0)) < tolerance);
Assert.True(GaussianProductOp.AAverageConditional(6.0, new Gaussian(1, 3), Gaussian.PointMass(2.0))

Просмотреть файл

@ -128,6 +128,68 @@ namespace Microsoft.ML.Probabilistic.Tests
//}
}
/// <summary>
/// Tests a model that needs a fresh node to appear twice in the iteration schedule.
/// Otherwise, the schedule cannot be initialised.
/// </summary>
[Fact]
[Trait("Category", "OpenBug")]
public void FreshChainTest()
{
double[] data = new double[] {
0.592,
0.708,
0.789,
0.621,
0.873,
1.074,
4.634,
3.945,
2.118,
4.207,
2.884,
1.462,
2.851 };
Range n = new Range(data.Length);
VariableArray<double> nodes = Variable.Array<double>(n).Named("nodes");
VariableArray<double> NoisyNodes = Variable.Array<double>(n).Named("NoisyNodes");
// workaround
//nodes[n].InitialiseTo(Variable<Gamma>.Factor(Gamma.PointMass, NoisyNodes[n]));
using (var mblock = Variable.ForEach(n))
{
var i = mblock.Index;
var mIs0 = (i == 0);
var mIsGr = (i > 0);
using (Variable.If(mIs0))
{
nodes[n] = Variable.GammaFromMeanAndVariance(1, 1);
}
using (Variable.If(mIsGr))
{
var prevM = i - 1;
nodes[n] = nodes[prevM] * Variable.GammaFromMeanAndVariance(1, 1);
}
NoisyNodes[n] = nodes[n] * Variable.GammaFromMeanAndVariance(1, 1);
}
NoisyNodes.ObservedValue = data;
InferenceEngine engine = new InferenceEngine(new ExpectationPropagation());
Gamma[] postNodes = engine.Infer<Gamma[]>(nodes);
for (int i = 0; i < n.SizeAsInt; i++)
{
Console.WriteLine("{0}: {1}", data[i], postNodes[i]);
}
}
/// <summary>
/// Test a model where inference fails due to incorrect initial messages.
/// Fails with "The distribution is improper" because D_uses_F[4] is uniform.