зеркало из https://github.com/dotnet/infer.git
Fixed Rand.Sample, Vector.MaxDiff and GreaterThan (#440)
* Fixed a bug in Rand.Sample that could cause it to return a value that should have zero probability. * Added MMath.AbsDiffAllowingNaNs * Fixed SparseVector.MaxDiff * DependencyGraphView, ModelView, TaskGraphView implement IDisposable * Added missing evidence methods * Added Vector.All(Vector, Func)
This commit is contained in:
Родитель
968e3b2e8a
Коммит
5bd86ece6b
|
@ -455,7 +455,7 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
convergenceCheck = System.Math.Sqrt(invDim * currentDeriv.Inner(currentDeriv));
|
||||
break;
|
||||
case ConvergenceCriteria.Objective:
|
||||
convergenceCheck = System.Math.Abs(prevObj - currentObj) / System.Math.Max(1, System.Math.Max(prevObj, currentObj));
|
||||
convergenceCheck = MMath.AbsDiff(prevObj, currentObj, 1);
|
||||
break;
|
||||
}
|
||||
prevObj = currentObj;
|
||||
|
|
|
@ -269,12 +269,8 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
|
||||
#region LINQ-like operators
|
||||
|
||||
/// <summary>
|
||||
/// Tests if all elements in the vector satisfy the specified condition.
|
||||
/// </summary>
|
||||
/// <param name="fun"></param>
|
||||
/// <returns></returns>
|
||||
public override bool All(Converter<double, bool> fun)
|
||||
/// <inheritdoc/>
|
||||
public override bool All(Func<double, bool> fun)
|
||||
{
|
||||
int end = start + count;
|
||||
for (int i = start; i < end; ++i)
|
||||
|
@ -285,12 +281,8 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests if any elements in the vector satisfy the specified condition.
|
||||
/// </summary>
|
||||
/// <param name="fun"></param>
|
||||
/// <returns></returns>
|
||||
public override bool Any(Converter<double, bool> fun)
|
||||
/// <inheritdoc/>
|
||||
public override bool Any(Func<double, bool> fun)
|
||||
{
|
||||
int end = start + count;
|
||||
for (int i = start; i < end; ++i)
|
||||
|
@ -301,6 +293,7 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
return false;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override bool Any(Vector that, Func<double, double, bool> fun)
|
||||
{
|
||||
if (that.Sparsity == Sparsity.Dense)
|
||||
|
@ -328,13 +321,8 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns an enumeration over the indices and values of all the elements which satisfy the specified condition.
|
||||
/// Indices are returned in sorted order.
|
||||
/// </summary>
|
||||
/// <param name="fun">A function to check if the condition is satisfied.</param>
|
||||
/// <returns>An enumeration over the indices and values of all the elements which satisfy the specified condition.</returns>
|
||||
public override IEnumerable<ValueAtIndex<double>> FindAll(Converter<double, bool> fun)
|
||||
/// <inheritdoc/>
|
||||
public override IEnumerable<ValueAtIndex<double>> FindAll(Func<double, bool> fun)
|
||||
{
|
||||
if (fun == null)
|
||||
{
|
||||
|
@ -351,12 +339,8 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the number of elements in the vector which satisfy a given condition.
|
||||
/// </summary>
|
||||
/// <param name="fun">The condition for the elements to satisfy.</param>
|
||||
/// <returns>The number of elements in the vector which satisfy the condition.</returns>
|
||||
public override int CountAll(Converter<double, bool> fun)
|
||||
/// <inheritdoc/>
|
||||
public override int CountAll(Func<double, bool> fun)
|
||||
{
|
||||
if (fun == null)
|
||||
{
|
||||
|
@ -376,22 +360,14 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the index of the first element that satisfies a given condition.
|
||||
/// </summary>
|
||||
/// <param name="fun">The condition for the element to satisfy.</param>
|
||||
/// <returns>The zero-based index of the first occurrence of an element that matches the conditions defined by match, if found; otherwise, –1.</returns>
|
||||
public override int FindFirstIndex(Converter<double, bool> fun)
|
||||
/// <inheritdoc/>
|
||||
public override int FindFirstIndex(Func<double, bool> fun)
|
||||
{
|
||||
return Array.FindIndex(this.data, elt => fun(elt));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the index of the last element that satisfies a given condition.
|
||||
/// </summary>
|
||||
/// <param name="fun">The condition for the element to satisfy.</param>
|
||||
/// <returns>The zero-based index of the last occurrence of an element that matches the conditions defined by match, if found; otherwise, –1.</returns>
|
||||
public override int FindLastIndex(Converter<double, bool> fun)
|
||||
/// <inheritdoc/>
|
||||
public override int FindLastIndex(Func<double, bool> fun)
|
||||
{
|
||||
return Array.FindLastIndex(this.data, elt => fun(elt));
|
||||
}
|
||||
|
@ -1906,12 +1882,7 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
|
||||
#region Object overrides
|
||||
|
||||
/// <summary>
|
||||
/// Determines object equality.
|
||||
/// </summary>
|
||||
/// <param name="obj">Another (DenseVector) object.</param>
|
||||
/// <returns>True if equal.</returns>
|
||||
/// <exclude/>
|
||||
/// <inheritdoc/>
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
Vector that = obj as Vector;
|
||||
|
@ -1945,11 +1916,7 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests if all elements are equal to a given value.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to test against.</param>
|
||||
/// <returns>True if all elements are equal to <paramref name="value"/>.</returns>
|
||||
/// <inheritdoc/>
|
||||
public override bool EqualsAll(double value)
|
||||
{
|
||||
int end = start + count;
|
||||
|
@ -1960,11 +1927,7 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests if all elements are strictly greater than a given value.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to test against.</param>
|
||||
/// <returns>True if all elements are strictly greater than <paramref name="value"/>.</returns>
|
||||
/// <inheritdoc/>
|
||||
public override bool GreaterThan(double value)
|
||||
{
|
||||
int end = start + count;
|
||||
|
@ -1975,11 +1938,7 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests if all elements are strictly less than a given value.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to test against.</param>
|
||||
/// <returns>True if all elements are strictly less than <paramref name="value"/>.</returns>
|
||||
/// <inheritdoc/>
|
||||
public override bool LessThan(double value)
|
||||
{
|
||||
int end = start + count;
|
||||
|
@ -1990,11 +1949,7 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests if this vector is strictly greater than a second vector.
|
||||
/// </summary>
|
||||
/// <param name="that">The value to test against.</param>
|
||||
/// <returns>True if each element is strictly greater than the corresponding element of <paramref name="that"/>.</returns>
|
||||
/// <inheritdoc/>
|
||||
public override bool GreaterThan(Vector that)
|
||||
{
|
||||
if (that.Sparsity == Sparsity.Dense)
|
||||
|
@ -2012,11 +1967,7 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
return (true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests if this dense vector is strictly greater than a second dense vector.
|
||||
/// </summary>
|
||||
/// <param name="that">The value to test against.</param>
|
||||
/// <returns>True if each element is strictly greater than the corresponding element of <paramref name="that"/>.</returns>
|
||||
/// <inheritdoc cref="GreaterThan(Vector)"/>
|
||||
public bool GreaterThan(DenseVector that)
|
||||
{
|
||||
int end = start + count;
|
||||
|
@ -2026,11 +1977,7 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
return (true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests if this vector is strictly less than a second vector.
|
||||
/// </summary>
|
||||
/// <param name="that">The value to test against.</param>
|
||||
/// <returns>True if each element is strictly less than the corresponding element of <paramref name="that"/>.</returns>
|
||||
/// <inheritdoc/>
|
||||
public override bool LessThan(Vector that)
|
||||
{
|
||||
if (that.Sparsity == Sparsity.Dense)
|
||||
|
@ -2048,11 +1995,7 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
return (true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests if this dense vector is strictly less than a second dense vector.
|
||||
/// </summary>
|
||||
/// <param name="that">The value to test against.</param>
|
||||
/// <returns>True if each element is strictly less than the corresponding element of <paramref name="that"/>.</returns>
|
||||
/// <inheritdoc cref="LessThan(Vector)"/>
|
||||
public bool LessThan(DenseVector that)
|
||||
{
|
||||
int end = start + count;
|
||||
|
@ -2062,11 +2005,7 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
return (true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests if all elements are greater than or equal to a given value.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to test against.</param>
|
||||
/// <returns>True if all elements are greater than or equal to <paramref name="value"/>.</returns>
|
||||
/// <inheritdoc/>
|
||||
public override bool GreaterThanOrEqual(double value)
|
||||
{
|
||||
int end = start + count;
|
||||
|
@ -2077,11 +2016,7 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests if all elements are less than or equal to a given value.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to test against.</param>
|
||||
/// <returns>True if all elements are less than or equal to <paramref name="value"/>.</returns>
|
||||
/// <inheritdoc/>
|
||||
public override bool LessThanOrEqual(double value)
|
||||
{
|
||||
int end = start + count;
|
||||
|
@ -2092,11 +2027,7 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests if this vector is greater than or equal to a second vector.
|
||||
/// </summary>
|
||||
/// <param name="that">The value to test against.</param>
|
||||
/// <returns>True if each element is greater than or equal to the corresponding element of <paramref name="that"/>.</returns>
|
||||
/// <inheritdoc/>
|
||||
public override bool GreaterThanOrEqual(Vector that)
|
||||
{
|
||||
if (that.Sparsity == Sparsity.Dense)
|
||||
|
@ -2114,11 +2045,7 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests if this dense vector is greater than or equal to a second dense vector.
|
||||
/// </summary>
|
||||
/// <param name="that">The value to test against.</param>
|
||||
/// <returns>True if each element is greater than or equal to the corresponding element of <paramref name="that"/>.</returns>
|
||||
/// <inheritdoc cref="GreaterThanOrEqual(Vector)"/>
|
||||
public bool GreaterThanOrEqual(DenseVector that)
|
||||
{
|
||||
int end = start + count;
|
||||
|
@ -2128,11 +2055,7 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
return (true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests if this vector is less than or equal to a second vector.
|
||||
/// </summary>
|
||||
/// <param name="that">The value to test against.</param>
|
||||
/// <returns>True if each element is strictly less than or equal to the corresponding element of <paramref name="that"/>.</returns>
|
||||
/// <inheritdoc/>
|
||||
public override bool LessThanOrEqual(Vector that)
|
||||
{
|
||||
if (that.Sparsity == Sparsity.Dense)
|
||||
|
@ -2150,11 +2073,7 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
return (true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests if this dense vector is less than or equal to a second dense vector.
|
||||
/// </summary>
|
||||
/// <param name="that">The value to test against.</param>
|
||||
/// <returns>True if each element is strictly less than or equal to the corresponding element of <paramref name="that"/>.</returns>
|
||||
/// <inheritdoc cref="LessThanOrEqual(Vector)"/>
|
||||
public bool LessThanOrEqual(DenseVector that)
|
||||
{
|
||||
int end = start + count;
|
||||
|
@ -2164,15 +2083,7 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
return (true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the maximum absolute difference between this vector and another vector.
|
||||
/// </summary>
|
||||
/// <param name="that">The second vector.</param>
|
||||
/// <returns><c>max(abs(this[i] - that[i]))</c>.
|
||||
/// Matching infinities or NaNs do not count.
|
||||
/// If <c>this</c> and <paramref name="that"/> are not the same size, returns infinity.</returns>
|
||||
/// <remarks>This routine is typically used instead of <c>Equals</c>, since <c>Equals</c> is susceptible to roundoff errors.
|
||||
/// </remarks>
|
||||
/// <inheritdoc/>
|
||||
public override double MaxDiff(Vector that)
|
||||
{
|
||||
if (that.Sparsity == Sparsity.Dense)
|
||||
|
@ -2194,13 +2105,9 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
bool ynan = Double.IsNaN(y);
|
||||
if (xnan != ynan)
|
||||
return Double.PositiveInfinity;
|
||||
else if (x == y)
|
||||
{
|
||||
// catches infinities
|
||||
// do nothing
|
||||
}
|
||||
else
|
||||
{
|
||||
// matching infinities or NaNs will not change max
|
||||
double diff = System.Math.Abs(x - y);
|
||||
if (diff > max)
|
||||
{
|
||||
|
@ -2212,15 +2119,7 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
return max;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the maximum absolute difference between this dense vector and another dense vector.
|
||||
/// </summary>
|
||||
/// <param name="that">The second vector.</param>
|
||||
/// <returns><c>max(abs(this[i] - that[i]))</c>.
|
||||
/// Matching infinities or NaNs do not count.
|
||||
/// If <c>this</c> and <paramref name="that"/> are not the same size, returns infinity.</returns>
|
||||
/// <remarks>This routine is typically used instead of <c>Equals</c>, since <c>Equals</c> is susceptible to roundoff errors.
|
||||
/// </remarks>
|
||||
/// <inheritdoc cref="MaxDiff(Vector)"/>
|
||||
public double MaxDiff(DenseVector that)
|
||||
{
|
||||
if (count != that.Count)
|
||||
|
@ -2238,13 +2137,9 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
bool ynan = Double.IsNaN(y);
|
||||
if (xnan != ynan)
|
||||
return Double.PositiveInfinity;
|
||||
else if (x == y)
|
||||
{
|
||||
// catches infinities
|
||||
// do nothing
|
||||
}
|
||||
else
|
||||
{
|
||||
// matching infinities or NaNs will not change max
|
||||
double diff = System.Math.Abs(x - y);
|
||||
if (diff > max)
|
||||
{
|
||||
|
@ -2255,16 +2150,7 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
return max;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the maximum relative difference between this vector and another.
|
||||
/// </summary>
|
||||
/// <param name="that">The second vector.</param>
|
||||
/// <param name="rel">An offset to avoid division by zero.</param>
|
||||
/// <returns><c>max(abs(this[i] - that[i])/(abs(this[i]) + rel))</c>.
|
||||
/// Matching infinities or NaNs do not count.
|
||||
/// If <c>this</c> and <paramref name="that"/> are not the same size, returns infinity.</returns>
|
||||
/// <remarks>This routine is typically used instead of <c>Equals</c>, since <c>Equals</c> is susceptible to roundoff errors.
|
||||
/// </remarks>
|
||||
/// <inheritdoc/>
|
||||
public override double MaxDiff(Vector that, double rel)
|
||||
{
|
||||
if (that.Sparsity == Sparsity.Dense)
|
||||
|
@ -2286,14 +2172,10 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
bool ynan = Double.IsNaN(y);
|
||||
if (xnan != ynan)
|
||||
return Double.PositiveInfinity;
|
||||
else if (x == y)
|
||||
{
|
||||
// catches infinities
|
||||
// do nothing
|
||||
}
|
||||
else
|
||||
{
|
||||
double diff = System.Math.Abs(x - y) / (System.Math.Abs(x) + rel);
|
||||
// matching infinities or NaNs will not change max
|
||||
double diff = MMath.AbsDiff(x, y, rel);
|
||||
if (diff > max)
|
||||
{
|
||||
max = diff;
|
||||
|
@ -2304,16 +2186,7 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
return max;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the maximum relative difference between this dense vector and another.
|
||||
/// </summary>
|
||||
/// <param name="that">The second vector.</param>
|
||||
/// <param name="rel">An offset to avoid division by zero.</param>
|
||||
/// <returns><c>max(abs(this[i] - that[i])/(abs(this[i]) + rel))</c>.
|
||||
/// Matching infinities or NaNs do not count.
|
||||
/// If <c>this</c> and <paramref name="that"/> are not the same size, returns infinity.</returns>
|
||||
/// <remarks>This routine is typically used instead of <c>Equals</c>, since <c>Equals</c> is susceptible to roundoff errors.
|
||||
/// </remarks>
|
||||
/// <inheritdoc cref="MaxDiff(Vector, double)"/>
|
||||
public double MaxDiff(DenseVector that, double rel)
|
||||
{
|
||||
if (count != that.Count)
|
||||
|
@ -2323,7 +2196,6 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
|
||||
double max = 0.0;
|
||||
int end = start + count;
|
||||
DenseVector thatd = (DenseVector)that;
|
||||
for (int i = start, j = that.start; i < end;)
|
||||
{
|
||||
double x = this.data[i++];
|
||||
|
@ -2332,14 +2204,10 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
bool ynan = Double.IsNaN(y);
|
||||
if (xnan != ynan)
|
||||
return Double.PositiveInfinity;
|
||||
else if (x == y)
|
||||
{
|
||||
// catches infinities
|
||||
// do nothing
|
||||
}
|
||||
else
|
||||
{
|
||||
double diff = System.Math.Abs(x - y) / (System.Math.Abs(x) + rel);
|
||||
// matching infinities or NaNs will not change max
|
||||
double diff = MMath.AbsDiff(x, y, rel);
|
||||
if (diff > max)
|
||||
{
|
||||
max = diff;
|
||||
|
|
|
@ -195,7 +195,7 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
convergenceCheck = System.Math.Sqrt(invDim * currentDeriv.Inner(currentDeriv));
|
||||
break;
|
||||
case ConvergenceCriteria.Objective:
|
||||
convergenceCheck = System.Math.Abs(prevObj - currentObj) / System.Math.Max(1, System.Math.Max(prevObj, currentObj));
|
||||
convergenceCheck = MMath.AbsDiff(prevObj, currentObj, 1);
|
||||
break;
|
||||
}
|
||||
prevObj = currentObj;
|
||||
|
@ -429,7 +429,7 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
convergenceCheck = System.Math.Sqrt(invDim * currentDeriv.Select(o => o.Inner(o)).Sum());
|
||||
break;
|
||||
case ConvergenceCriteria.Objective:
|
||||
convergenceCheck = System.Math.Abs(prevObj - currentObj) / System.Math.Max(1, System.Math.Max(prevObj, currentObj));
|
||||
convergenceCheck = MMath.AbsDiff(prevObj, currentObj, 1);
|
||||
break;
|
||||
}
|
||||
prevObj = currentObj;
|
||||
|
|
|
@ -429,9 +429,9 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
{
|
||||
return Double.PositiveInfinity;
|
||||
}
|
||||
else if (x != y)
|
||||
else
|
||||
{
|
||||
// catches infinities
|
||||
// matching infinities will not change max
|
||||
double diff = System.Math.Abs(x - y);
|
||||
if (diff > max) max = diff;
|
||||
}
|
||||
|
|
|
@ -759,22 +759,14 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
|
||||
#region Equality
|
||||
|
||||
/// <summary>
|
||||
/// Determines object equality.
|
||||
/// </summary>
|
||||
/// <param name="obj">Another (vector) object.</param>
|
||||
/// <returns>True if equal.</returns>
|
||||
/// <exclude/>
|
||||
/// <inheritdoc/>
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
var that = obj as Vector;
|
||||
if (ReferenceEquals(this, that)) return true;
|
||||
if (ReferenceEquals(that, null))
|
||||
return false;
|
||||
if (ReferenceEquals(that, null)) return false;
|
||||
if (Count != that.Count) return false;
|
||||
// TODO: change to maxdiff?
|
||||
Vector diff = this - that;
|
||||
return diff.EqualsAll(0.0);
|
||||
return this.MaxDiff(that) == 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -790,86 +782,45 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
return hash;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests if this vector is strictly greater than a second vector.
|
||||
/// </summary>
|
||||
/// <param name="that">The value to test against.</param>
|
||||
/// <returns>True if each element is strictly greater than the corresponding element of <paramref name="that"/>.</returns>
|
||||
/// <inheritdoc/>
|
||||
public override bool GreaterThan(Vector that)
|
||||
{
|
||||
return (this - that).GreaterThan(0);
|
||||
return this.All(that, (x, y) => x > y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests if this vector is strictly less than a second vector.
|
||||
/// </summary>
|
||||
/// <param name="that">The value to test against.</param>
|
||||
/// <returns>True if each element is strictly less than the corresponding element of <paramref name="that"/>.</returns>
|
||||
/// <inheritdoc/>
|
||||
public override bool LessThan(Vector that)
|
||||
{
|
||||
return (this - that).LessThan(0);
|
||||
return this.All(that, (x, y) => x < y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests if this vector is than or equal to a second vector.
|
||||
/// </summary>
|
||||
/// <param name="that">The value to test against.</param>
|
||||
/// <returns>True if each element is greater than or equal to the corresponding element of <paramref name="that"/>.</returns>
|
||||
/// <inheritdoc/>
|
||||
public override bool GreaterThanOrEqual(Vector that)
|
||||
{
|
||||
return (this - that).GreaterThanOrEqual(0);
|
||||
return this.All(that, (x, y) => x >= y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests if this vector is less than or equal to a second vector.
|
||||
/// </summary>
|
||||
/// <param name="that">The value to test against.</param>
|
||||
/// <returns>True if each element is strictly less than or equal to the corresponding element of <paramref name="that"/>.</returns>
|
||||
/// <inheritdoc/>
|
||||
public override bool LessThanOrEqual(Vector that)
|
||||
{
|
||||
return (this - that).LessThanOrEqual(0);
|
||||
return this.All(that, (x, y) => x <= y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the maximum absolute difference between this vector and another vector.
|
||||
/// </summary>
|
||||
/// <param name="that">The second vector.</param>
|
||||
/// <returns><c>max(abs(this[i] - that[i]))</c>.
|
||||
/// Matching infinities or NaNs do not count.
|
||||
/// If <c>this</c> and <paramref name="that"/> are not the same size, returns infinity.</returns>
|
||||
/// <remarks>This routine is typically used instead of <c>Equals</c>, since <c>Equals</c> is susceptible to roundoff errors.
|
||||
/// </remarks>
|
||||
/// <inheritdoc/>
|
||||
public override double MaxDiff(Vector that)
|
||||
{
|
||||
if (Count != that.Count) return Double.PositiveInfinity;
|
||||
|
||||
var absdiff = new PiecewiseVector(Count);
|
||||
absdiff.SetToFunction(this, that, (a, b) => a == b ? 0 : System.Math.Abs(a - b));
|
||||
// TODO: consider copying behaviour of Vector, which is roughly:
|
||||
//bool xnan = Double.IsNaN(x);
|
||||
//bool ynan = Double.IsNaN(y);
|
||||
//if (xnan != ynan) return Double.PositiveInfinity;
|
||||
//else if (x != y)
|
||||
//{
|
||||
// double diff = Math.Abs(x - y);
|
||||
//}
|
||||
absdiff.SetToFunction(this, that, (a, b) => MMath.AbsDiffAllowingNaNs(a, b));
|
||||
return absdiff.Max();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the maximum relative difference between this vector and another.
|
||||
/// </summary>
|
||||
/// <param name="that">The second vector.</param>
|
||||
/// <param name="rel">An offset to avoid division by zero.</param>
|
||||
/// <returns><c>max(abs(this[i] - that[i])/(abs(this[i]) + rel))</c>.
|
||||
/// Matching infinities or NaNs do not count.
|
||||
/// If <c>this</c> and <paramref name="that"/> are not the same size, returns infinity.</returns>
|
||||
/// <remarks>This routine is typically used instead of <c>Equals</c>, since <c>Equals</c> is susceptible to roundoff errors.
|
||||
/// </remarks>
|
||||
/// <inheritdoc/>
|
||||
public override double MaxDiff(Vector that, double rel)
|
||||
{
|
||||
var absdiff = new PiecewiseVector(Count);
|
||||
absdiff.SetToFunction(this, that, (a, b) => System.Math.Abs(a - b)/(System.Math.Abs(a) + rel));
|
||||
absdiff.SetToFunction(this, that, (a, b) => MMath.AbsDiffAllowingNaNs(a, b, rel));
|
||||
return absdiff.Max();
|
||||
}
|
||||
|
||||
|
@ -877,12 +828,8 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
|
||||
#region LINQ-like operators (All, Any, FindAll etc.)
|
||||
|
||||
/// <summary>
|
||||
/// Tests if all elements in the vector satisfy the specified condition.
|
||||
/// </summary>
|
||||
/// <param name="fun">The condition for the elements to satisfy.</param>
|
||||
/// <returns>True if all elements satisfy the condition, false otherwise.</returns>
|
||||
public override bool All(Converter<double, bool> fun)
|
||||
/// <inheritdoc/>
|
||||
public override bool All(Func<double, bool> fun)
|
||||
{
|
||||
if (this.HasCommonElements() && !fun(this.CommonValue))
|
||||
{
|
||||
|
@ -900,12 +847,8 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests if any elements in the vector satisfy the specified condition.
|
||||
/// </summary>
|
||||
/// <param name="fun">The condition for the elements to satisfy.</param>
|
||||
/// <returns>True if any elements satisfy the condition, false otherwise.</returns>
|
||||
public override bool Any(Converter<double, bool> fun)
|
||||
/// <inheritdoc/>
|
||||
public override bool Any(Func<double, bool> fun)
|
||||
{
|
||||
if (this.HasCommonElements() && fun(this.CommonValue))
|
||||
{
|
||||
|
@ -923,6 +866,7 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
return false;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override bool Any(Vector that, Func<double, double, bool> fun)
|
||||
{
|
||||
if (that.Sparsity.IsPiecewise)
|
||||
|
@ -933,6 +877,7 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
return base.Any(that, fun);
|
||||
}
|
||||
|
||||
/// <inheritdoc cref="Any(Vector, Func{double, double, bool})"/>
|
||||
public bool Any(PiecewiseVector that, Func<double, double, bool> fun)
|
||||
{
|
||||
bool any = false;
|
||||
|
@ -940,13 +885,8 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
return any;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns an enumeration over the indices and values of all the elements which satisfy the specified condition.
|
||||
/// Indices are returned in sorted order.
|
||||
/// </summary>
|
||||
/// <param name="fun">A function to check if the condition is satisfied.</param>
|
||||
/// <returns>An enumeration over the indices and values of all the elements which satisfy the specified condition.</returns>
|
||||
public override IEnumerable<ValueAtIndex<double>> FindAll(Converter<double, bool> fun)
|
||||
/// <inheritdoc/>
|
||||
public override IEnumerable<ValueAtIndex<double>> FindAll(Func<double, bool> fun)
|
||||
{
|
||||
if (fun == null)
|
||||
{
|
||||
|
@ -979,12 +919,8 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the number of elements in the vector which satisfy a given condition.
|
||||
/// </summary>
|
||||
/// <param name="fun">The condition for the elements to satisfy.</param>
|
||||
/// <returns>The number of elements in the vector which satisfy the condition.</returns>
|
||||
public override int CountAll(Converter<double, bool> fun)
|
||||
/// <inheritdoc/>
|
||||
public override int CountAll(Func<double, bool> fun)
|
||||
{
|
||||
if (fun == null)
|
||||
{
|
||||
|
@ -1011,12 +947,8 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the index of the first element that satisfies a given condition.
|
||||
/// </summary>
|
||||
/// <param name="fun">The condition for the element to satisfy.</param>
|
||||
/// <returns>The zero-based index of the first occurrence of an element that matches the conditions defined by match, if found; otherwise, –1.</returns>
|
||||
public override int FindFirstIndex(Converter<double, bool> fun)
|
||||
/// <inheritdoc/>
|
||||
public override int FindFirstIndex(Func<double, bool> fun)
|
||||
{
|
||||
if (fun == null)
|
||||
{
|
||||
|
@ -1051,12 +983,8 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
return firstIndex;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the index of the last element that satisfies a given condition.
|
||||
/// </summary>
|
||||
/// <param name="fun">The condition for the element to satisfy.</param>
|
||||
/// <returns>The last index.</returns>
|
||||
public override int FindLastIndex(Converter<double, bool> fun)
|
||||
/// <inheritdoc/>
|
||||
public override int FindLastIndex(Func<double, bool> fun)
|
||||
{
|
||||
if (fun == null)
|
||||
{
|
||||
|
|
|
@ -273,7 +273,8 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
double cumsum = prob[x];
|
||||
Assert.IsTrue(prob[x] >= 0, "negative probability");
|
||||
Assert.IsTrue(sum > 0, "sum is not positive");
|
||||
double u = gen.NextDouble()*sum;
|
||||
double u = gen.NextDouble() * sum;
|
||||
u = System.Math.Max(u, double.Epsilon);
|
||||
while (u > cumsum)
|
||||
{
|
||||
++x;
|
||||
|
@ -297,7 +298,8 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
double cumsum = prob[x];
|
||||
Assert.IsTrue(prob[x] >= 0, "negative probability");
|
||||
Assert.IsTrue(sum > 0, "sum is not positive");
|
||||
double u = gen.NextDouble()*sum;
|
||||
double u = gen.NextDouble() * sum;
|
||||
u = System.Math.Max(u, double.Epsilon);
|
||||
while (u > cumsum)
|
||||
{
|
||||
++x;
|
||||
|
@ -326,15 +328,15 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
/* Generate a random point inside the unit circle */
|
||||
do
|
||||
{
|
||||
x1 = 2.0*gen.NextDouble() - 1.0;
|
||||
x2 = 2.0*gen.NextDouble() - 1.0;
|
||||
w = (x1*x1) + (x2*x2);
|
||||
x1 = 2.0 * gen.NextDouble() - 1.0;
|
||||
x2 = 2.0 * gen.NextDouble() - 1.0;
|
||||
w = (x1 * x1) + (x2 * x2);
|
||||
} while ((w >= 1.0) || (w == 0.0));
|
||||
|
||||
/* Apply the Box-Muller formula */
|
||||
w = System.Math.Sqrt(-2.0* System.Math.Log(w) / w);
|
||||
x1 = w*x1;
|
||||
x2 = w*x2;
|
||||
w = System.Math.Sqrt(-2.0 * System.Math.Log(w) / w);
|
||||
x1 = w * x1;
|
||||
x2 = w * x2;
|
||||
|
||||
usePreviousSample = true;
|
||||
previousSample = x2;
|
||||
|
@ -350,7 +352,7 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
[Stochastic]
|
||||
public static double Normal(double mean, double stdDev)
|
||||
{
|
||||
return mean + stdDev*Normal();
|
||||
return mean + stdDev * Normal();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -454,28 +456,28 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
{
|
||||
// Devroye's (Ch.9) rejection sampler with x ~ Exp(lowerBound)
|
||||
// requires lowerBound > 0
|
||||
double c = 2*lowerBound*lowerBound;
|
||||
double c = 2 * lowerBound * lowerBound;
|
||||
while (true)
|
||||
{
|
||||
// note it is possible to generate two exponential r.v.s with a single logarithm (Devroye Ch.9 sec.2.1)
|
||||
double E = -System.Math.Log(Rand.Double());
|
||||
double E2 = -System.Math.Log(Rand.Double());
|
||||
if (E*E <= c*E2) return lowerBound + E/lowerBound;
|
||||
if (E * E <= c * E2) return lowerBound + E / lowerBound;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Marsaglia's (1964) rejection sampler (Devroye Ch.9)
|
||||
// Reference: "Non-Uniform Random Variate Generation" by Luc Devroye (1986)
|
||||
double c = lowerBound*lowerBound*0.5;
|
||||
double c = lowerBound * lowerBound * 0.5;
|
||||
while (true)
|
||||
{
|
||||
double U = Rand.Double();
|
||||
double V = Rand.Double();
|
||||
double x = c - System.Math.Log(U);
|
||||
if (V*V*x <= c)
|
||||
if (V * V * x <= c)
|
||||
{
|
||||
return System.Math.Sqrt(2* x);
|
||||
return System.Math.Sqrt(2 * x);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -535,13 +537,13 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
{
|
||||
// Rejection sampler using truncated exponential proposal
|
||||
double lambda = lowerBound;
|
||||
double s = MMath.ExpMinus1(-lambda*delta);
|
||||
double c = 2*lambda*lambda;
|
||||
double s = MMath.ExpMinus1(-lambda * delta);
|
||||
double c = 2 * lambda * lambda;
|
||||
while (true)
|
||||
{
|
||||
double x = -MMath.Log1Plus(s * Rand.Double());
|
||||
double u = -System.Math.Log(Rand.Double());
|
||||
if (c*u > x*x) return x/lambda + lowerBound;
|
||||
if (c * u > x * x) return x / lambda + lowerBound;
|
||||
}
|
||||
throw new InferRuntimeException("failed to sample");
|
||||
}
|
||||
|
@ -554,9 +556,9 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
// Uniform rejection
|
||||
while (true)
|
||||
{
|
||||
double x = Rand.Double()*delta + lowerBound;
|
||||
double x = Rand.Double() * delta + lowerBound;
|
||||
double u = -System.Math.Log(Rand.Double());
|
||||
if (2*u > x*x) return x;
|
||||
if (2 * u > x * x) return x;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -577,7 +579,7 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
// http://portal.acm.org/citation.cfm?id=358414
|
||||
private static double GammaShapeGE1(double a)
|
||||
{
|
||||
double d = a - 1.0/3, c = 1.0/ System.Math.Sqrt(9* d);
|
||||
double d = a - 1.0 / 3, c = 1.0 / System.Math.Sqrt(9 * d);
|
||||
double v;
|
||||
while (true)
|
||||
{
|
||||
|
@ -585,10 +587,10 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
do
|
||||
{
|
||||
x = Normal();
|
||||
v = 1 + c*x;
|
||||
v = 1 + c * x;
|
||||
} while (v <= 0);
|
||||
v = v*v*v;
|
||||
x = x*x;
|
||||
v = v * v * v;
|
||||
x = x * x;
|
||||
double u = gen.NextDouble();
|
||||
#if false
|
||||
// first version
|
||||
|
@ -598,13 +600,13 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
}
|
||||
#else
|
||||
// faster version
|
||||
if ((u < 1 - .0331* x * x) || (System.Math.Log(u) < 0.5* x + d*(1 - v + System.Math.Log(v))))
|
||||
if ((u < 1 - .0331 * x * x) || (System.Math.Log(u) < 0.5 * x + d * (1 - v + System.Math.Log(v))))
|
||||
{
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return d*v;
|
||||
return d * v;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -672,10 +674,10 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
{
|
||||
for (int j = 0; j < i; ++j)
|
||||
{
|
||||
result[i, j] = Normal()*MMath.SqrtHalf;
|
||||
result[i, j] = Normal() * MMath.SqrtHalf;
|
||||
result[j, i] = 0;
|
||||
}
|
||||
result[i, i] = System.Math.Sqrt(Gamma(a - i*0.5));
|
||||
result[i, i] = System.Math.Sqrt(Gamma(a - i * 0.5));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -693,9 +695,9 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
{
|
||||
// To handle small counts, use Stuart's (1962) theorem:
|
||||
// gamma(a) has the same distribution as gamma(a+1)*exp(log(U)/a)
|
||||
double boost1 = System.Math.Log(gen.NextDouble())/ trueCount;
|
||||
double boost1 = System.Math.Log(gen.NextDouble()) / trueCount;
|
||||
trueCount++;
|
||||
double boost2 = System.Math.Log(gen.NextDouble())/ falseCount;
|
||||
double boost2 = System.Math.Log(gen.NextDouble()) / falseCount;
|
||||
falseCount++;
|
||||
if (boost1 > boost2)
|
||||
{
|
||||
|
@ -715,7 +717,7 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
gTrue = Rand.Gamma(trueCount);
|
||||
gFalse = Rand.Gamma(falseCount);
|
||||
}
|
||||
return gTrue/(gTrue + gFalse);
|
||||
return gTrue / (gTrue + gFalse);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -734,7 +736,7 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
// If pseudo-count is sparse and its common value is not 0, we need
|
||||
// to process it as a dense vector so that samples from common value
|
||||
// are allowed to differ
|
||||
if (pseudoCount.IsSparse && ((SparseVector) pseudoCount).CommonValue != 0.0)
|
||||
if (pseudoCount.IsSparse && ((SparseVector)pseudoCount).CommonValue != 0.0)
|
||||
pseudoCount = DenseVector.Copy(pseudoCount);
|
||||
|
||||
if (pseudoCount.Max() < 1)
|
||||
|
@ -742,16 +744,16 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
// To handle small counts, use Stuart's (1962) theorem:
|
||||
// gamma(a) has the same distribution as gamma(a+1)*exp(log(U)/a)
|
||||
Vector boost = Vector.Copy(pseudoCount);
|
||||
boost.SetToFunction(pseudoCount, a => System.Math.Log(gen.NextDouble())/ a);
|
||||
boost.SetToFunction(pseudoCount, a => System.Math.Log(gen.NextDouble()) / a);
|
||||
double maxBoost = boost.Max();
|
||||
result.SetToFunction(pseudoCount, boost, (a, b) => Rand.Gamma(a + 1)* System.Math.Exp(b - maxBoost));
|
||||
result.SetToFunction(pseudoCount, boost, (a, b) => Rand.Gamma(a + 1) * System.Math.Exp(b - maxBoost));
|
||||
}
|
||||
else
|
||||
{
|
||||
result.SetToFunction(pseudoCount, a => Rand.Gamma(a));
|
||||
}
|
||||
double sum = result.Sum();
|
||||
result.Scale(1.0/sum);
|
||||
result.Scale(1.0 / sum);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -770,7 +772,7 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
[Stochastic]
|
||||
public static int Binomial(int n, double p)
|
||||
{
|
||||
if (p*(n + 1) == n + 1) return n;
|
||||
if (p * (n + 1) == n + 1) return n;
|
||||
if (n < 15)
|
||||
{
|
||||
// coin flip method
|
||||
|
@ -782,20 +784,20 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
}
|
||||
return result;
|
||||
}
|
||||
else if (n*p < 150)
|
||||
else if (n * p < 150)
|
||||
{
|
||||
// waiting time method
|
||||
// this takes O(np) time
|
||||
double q = -System.Math.Log(1 - p);
|
||||
int r = n;
|
||||
double e = -System.Math.Log(Rand.Double());
|
||||
double s = e/r;
|
||||
double s = e / r;
|
||||
while (s <= q)
|
||||
{
|
||||
r--;
|
||||
if (r == 0) break;
|
||||
e = -System.Math.Log(Rand.Double());
|
||||
s = s + e/r;
|
||||
s = s + e / r;
|
||||
}
|
||||
return n - r;
|
||||
}
|
||||
|
@ -803,12 +805,12 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
{
|
||||
// recursive method
|
||||
// this makes O(log(log(n))) recursive calls
|
||||
int i = (int) (p*(n + 1));
|
||||
int i = (int)(p * (n + 1));
|
||||
double b = Rand.Beta(i, n + 1 - i);
|
||||
if (b <= p)
|
||||
return i + Rand.Binomial(n - i, (p - b)/(1 - b));
|
||||
return i + Rand.Binomial(n - i, (p - b) / (1 - b));
|
||||
else
|
||||
return i - 1 - Rand.Binomial(i - 1, (b - p)/b);
|
||||
return i - 1 - Rand.Binomial(i - 1, (b - p) / b);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -821,7 +823,7 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
[Stochastic]
|
||||
public static int[] Multinomial(int trialCount, Vector probs)
|
||||
{
|
||||
return Multinomial(trialCount, (DenseVector) probs);
|
||||
return Multinomial(trialCount, (DenseVector)probs);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -838,7 +840,7 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
double remainingProb = 1;
|
||||
for (int dim = 0; dim < result.Length - 1; dim++)
|
||||
{
|
||||
int sample = Binomial(trialCount, probs[dim]/remainingProb);
|
||||
int sample = Binomial(trialCount, probs[dim] / remainingProb);
|
||||
result[dim] = sample;
|
||||
trialCount -= sample;
|
||||
remainingProb -= probs[dim];
|
||||
|
@ -879,15 +881,15 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
double mu = System.Math.Floor(mean);
|
||||
double muLogFact = MMath.GammaLn(mu + 1);
|
||||
double logMeanMu = System.Math.Log(mean / mu);
|
||||
double delta = System.Math.Max(6, System.Math.Min(mu, System.Math.Sqrt(2* mu * System.Math.Log(128* mu / System.Math.PI))));
|
||||
double c1 = System.Math.Sqrt(System.Math.PI* mu / 2);
|
||||
double c2 = c1 + System.Math.Sqrt(System.Math.PI*(mu + delta/2)/2)* System.Math.Exp(1/(2* mu + delta));
|
||||
double delta = System.Math.Max(6, System.Math.Min(mu, System.Math.Sqrt(2 * mu * System.Math.Log(128 * mu / System.Math.PI))));
|
||||
double c1 = System.Math.Sqrt(System.Math.PI * mu / 2);
|
||||
double c2 = c1 + System.Math.Sqrt(System.Math.PI * (mu + delta / 2) / 2) * System.Math.Exp(1 / (2 * mu + delta));
|
||||
double c3 = c2 + 2;
|
||||
double c4 = c3 + System.Math.Exp(1.0/78);
|
||||
double c = c4 + 2/ delta * (2* mu + delta)* System.Math.Exp(-delta / (2* mu + delta)*(1 + delta/2));
|
||||
double c4 = c3 + System.Math.Exp(1.0 / 78);
|
||||
double c = c4 + 2 / delta * (2 * mu + delta) * System.Math.Exp(-delta / (2 * mu + delta) * (1 + delta / 2));
|
||||
while (true)
|
||||
{
|
||||
double u = Rand.Double()*c;
|
||||
double u = Rand.Double() * c;
|
||||
double x, w;
|
||||
if (u <= c1)
|
||||
{
|
||||
|
@ -895,15 +897,15 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
double y = -System.Math.Abs(n) * System.Math.Sqrt(mu) - 1;
|
||||
x = System.Math.Floor(y);
|
||||
if (x < -mu) continue;
|
||||
w = -n*n/2;
|
||||
w = -n * n / 2;
|
||||
}
|
||||
else if (u <= c2)
|
||||
{
|
||||
double n = Rand.Normal();
|
||||
double y = 1 + System.Math.Abs(n) * System.Math.Sqrt(mu + delta/2);
|
||||
double y = 1 + System.Math.Abs(n) * System.Math.Sqrt(mu + delta / 2);
|
||||
x = System.Math.Ceiling(y);
|
||||
if (x > delta) continue;
|
||||
w = (2 - y)*y/(2*mu + delta);
|
||||
w = (2 - y) * y / (2 * mu + delta);
|
||||
}
|
||||
else if (u <= c3)
|
||||
{
|
||||
|
@ -918,13 +920,13 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
else
|
||||
{
|
||||
double v = -System.Math.Log(Rand.Double());
|
||||
double y = delta + v*2/delta*(2*mu + delta);
|
||||
double y = delta + v * 2 / delta * (2 * mu + delta);
|
||||
x = System.Math.Ceiling(y);
|
||||
w = -delta/(2*mu + delta)*(1 + y/2);
|
||||
w = -delta / (2 * mu + delta) * (1 + y / 2);
|
||||
}
|
||||
double e = -System.Math.Log(Rand.Double());
|
||||
w -= e + x*logMeanMu;
|
||||
double qx = x* System.Math.Log(mu) - MMath.GammaLn(mu + x + 1) + muLogFact;
|
||||
w -= e + x * logMeanMu;
|
||||
double qx = x * System.Math.Log(mu) - MMath.GammaLn(mu + x + 1) + muLogFact;
|
||||
if (w <= qx) return (int)System.Math.Round(x + mu);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -564,12 +564,7 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
|
||||
#region Equality
|
||||
|
||||
/// <summary>
|
||||
/// Determines object equality.
|
||||
/// </summary>
|
||||
/// <param name="obj">Another (vector) object.</param>
|
||||
/// <returns>True if equal.</returns>
|
||||
/// <exclude/>
|
||||
/// <inheritdoc/>
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
var that = obj as Vector;
|
||||
|
@ -577,9 +572,7 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
if (ReferenceEquals(that, null))
|
||||
return false;
|
||||
if (this.Count != that.Count) return false;
|
||||
// TODO: change to maxdiff?
|
||||
Vector diff = this - that;
|
||||
return diff.EqualsAll(0.0);
|
||||
return this.MaxDiff(that) == 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -595,86 +588,45 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
return hash;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests if this vector is strictly greater than a second vector.
|
||||
/// </summary>
|
||||
/// <param name="that">The value to test against.</param>
|
||||
/// <returns>True if each element is strictly greater than the corresponding element of <paramref name="that"/>.</returns>
|
||||
/// <inheritdoc/>
|
||||
public override bool GreaterThan(Vector that)
|
||||
{
|
||||
return (this - that).GreaterThan(0);
|
||||
return this.All(that, (x, y) => x > y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests if this vector is strictly less than a second vector.
|
||||
/// </summary>
|
||||
/// <param name="that">The value to test against.</param>
|
||||
/// <returns>True if each element is strictly less than the corresponding element of <paramref name="that"/>.</returns>
|
||||
/// <inheritdoc/>
|
||||
public override bool LessThan(Vector that)
|
||||
{
|
||||
return (this - that).LessThan(0);
|
||||
return this.All(that, (x, y) => x < y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests if this vector is than or equal to a second vector.
|
||||
/// </summary>
|
||||
/// <param name="that">The value to test against.</param>
|
||||
/// <returns>True if each element is greater than or equal to the corresponding element of <paramref name="that"/>.</returns>
|
||||
/// <inheritdoc/>
|
||||
public override bool GreaterThanOrEqual(Vector that)
|
||||
{
|
||||
return (this - that).GreaterThanOrEqual(0);
|
||||
return this.All(that, (x, y) => x >= y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests if this vector is less than or equal to a second vector.
|
||||
/// </summary>
|
||||
/// <param name="that">The value to test against.</param>
|
||||
/// <returns>True if each element is strictly less than or equal to the corresponding element of <paramref name="that"/>.</returns>
|
||||
/// <inheritdoc/>
|
||||
public override bool LessThanOrEqual(Vector that)
|
||||
{
|
||||
return (this - that).LessThanOrEqual(0);
|
||||
return this.All(that, (x, y) => x <= y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the maximum absolute difference between this vector and another vector.
|
||||
/// </summary>
|
||||
/// <param name="that">The second vector.</param>
|
||||
/// <returns><c>max(abs(this[i] - that[i]))</c>.
|
||||
/// Matching infinities or NaNs do not count.
|
||||
/// If <c>this</c> and <paramref name="that"/> are not the same size, returns infinity.</returns>
|
||||
/// <remarks>This routine is typically used instead of <c>Equals</c>, since <c>Equals</c> is susceptible to roundoff errors.
|
||||
/// </remarks>
|
||||
/// <inheritdoc/>
|
||||
public override double MaxDiff(Vector that)
|
||||
{
|
||||
if (Count != that.Count) return Double.PositiveInfinity;
|
||||
|
||||
var absdiff = new SparseVector(Count);
|
||||
absdiff.SetToFunction(this, that, (a, b) => System.Math.Abs(a - b));
|
||||
// TODO: consider copying behaviour of Vector, which is roughly:
|
||||
//bool xnan = Double.IsNaN(x);
|
||||
//bool ynan = Double.IsNaN(y);
|
||||
//if (xnan != ynan) return Double.PositiveInfinity;
|
||||
//else if (x != y)
|
||||
//{
|
||||
// double diff = Math.Abs(x - y);
|
||||
//}
|
||||
absdiff.SetToFunction(this, that, (a, b) => MMath.AbsDiffAllowingNaNs(a, b));
|
||||
return absdiff.Max();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the maximum relative difference between this vector and another.
|
||||
/// </summary>
|
||||
/// <param name="that">The second vector.</param>
|
||||
/// <param name="rel">An offset to avoid division by zero.</param>
|
||||
/// <returns><c>max(abs(this[i] - that[i])/(abs(this[i]) + rel))</c>.
|
||||
/// Matching infinities or NaNs do not count.
|
||||
/// If <c>this</c> and <paramref name="that"/> are not the same size, returns infinity.</returns>
|
||||
/// <remarks>This routine is typically used instead of <c>Equals</c>, since <c>Equals</c> is susceptible to roundoff errors.
|
||||
/// </remarks>
|
||||
/// <inheritdoc/>
|
||||
public override double MaxDiff(Vector that, double rel)
|
||||
{
|
||||
var absdiff = new SparseVector(Count);
|
||||
absdiff.SetToFunction(this, that, (a, b) => System.Math.Abs(a - b)/(System.Math.Abs(a) + rel));
|
||||
absdiff.SetToFunction(this, that, (a, b) => MMath.AbsDiffAllowingNaNs(a, b, rel));
|
||||
return absdiff.Max();
|
||||
}
|
||||
|
||||
|
@ -682,12 +634,8 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
|
||||
#region LINQ-like operators (All, Any, FindAll etc.)
|
||||
|
||||
/// <summary>
|
||||
/// Tests if all elements in the vector satisfy the specified condition.
|
||||
/// </summary>
|
||||
/// <param name="fun"></param>
|
||||
/// <returns></returns>
|
||||
public override bool All(Converter<double, bool> fun)
|
||||
/// <inheritdoc/>
|
||||
public override bool All(Func<double, bool> fun)
|
||||
{
|
||||
if (HasCommonElements)
|
||||
{
|
||||
|
@ -701,12 +649,8 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests if any elements in the vector satisfy the specified condition.
|
||||
/// </summary>
|
||||
/// <param name="fun"></param>
|
||||
/// <returns></returns>
|
||||
public override bool Any(Converter<double, bool> fun)
|
||||
/// <inheritdoc/>
|
||||
public override bool Any(Func<double, bool> fun)
|
||||
{
|
||||
if (HasCommonElements)
|
||||
{
|
||||
|
@ -719,12 +663,7 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test if any corresponding elements in this and that vector satisfy a condition
|
||||
/// </summary>
|
||||
/// <param name="that"></param>
|
||||
/// <param name="fun"></param>
|
||||
/// <returns></returns>
|
||||
/// <inheritdoc/>
|
||||
public override bool Any(Vector that, Func<double, double, bool> fun)
|
||||
{
|
||||
if (that.IsSparse)
|
||||
|
@ -734,12 +673,7 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
return base.Any(that, fun);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Test if any corresponding elements in this and that vector satisfy a condition
|
||||
/// </summary>
|
||||
/// <param name="that"></param>
|
||||
/// <param name="fun"></param>
|
||||
/// <returns></returns>
|
||||
/// <inheritdoc cref="Any(Vector, Func{double, double, bool})"/>
|
||||
public bool Any(SparseVector that, Func<double, double, bool> fun)
|
||||
{
|
||||
CheckCompatible(that, nameof(that));
|
||||
|
@ -791,13 +725,8 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns an enumeration over the indices of all elements which satisfy the specified condition.
|
||||
/// Indices are returned in sorted order.
|
||||
/// </summary>
|
||||
/// <param name="fun">A function to check if the condition is satisfied.</param>
|
||||
/// <returns>An enumeration over the indices and values of all the elements which satisfy the specified condition.</returns>
|
||||
public override IEnumerable<ValueAtIndex<double>> FindAll(Converter<double, bool> fun)
|
||||
/// <inheritdoc/>
|
||||
public override IEnumerable<SparseElement> FindAll(Func<double, bool> fun)
|
||||
{
|
||||
if (fun == null)
|
||||
{
|
||||
|
@ -810,12 +739,12 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
{
|
||||
for (; index < sparseElement.Index && funIsTrueForCommonValue; ++index)
|
||||
{
|
||||
yield return new ValueAtIndex<double>(index, this.CommonValue);
|
||||
yield return new SparseElement(index, this.CommonValue);
|
||||
}
|
||||
|
||||
if (fun(sparseElement.Value))
|
||||
{
|
||||
yield return new ValueAtIndex<double>(sparseElement.Index, sparseElement.Value);
|
||||
yield return new SparseElement(sparseElement.Index, sparseElement.Value);
|
||||
}
|
||||
|
||||
index = sparseElement.Index + 1;
|
||||
|
@ -823,16 +752,12 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
|
||||
for (; index < this.Count && funIsTrueForCommonValue; ++index)
|
||||
{
|
||||
yield return new ValueAtIndex<double>(index, this.CommonValue);
|
||||
yield return new SparseElement(index, this.CommonValue);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the number of elements in the vector which satisfy a given condition.
|
||||
/// </summary>
|
||||
/// <param name="fun">The condition for the elements to satisfy.</param>
|
||||
/// <returns>The number of elements in the vector which satisfy the condition.</returns>
|
||||
public override int CountAll(Converter<double, bool> fun)
|
||||
/// <inheritdoc/>
|
||||
public override int CountAll(Func<double, bool> fun)
|
||||
{
|
||||
if (fun == null)
|
||||
{
|
||||
|
@ -858,12 +783,8 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the index of the first element that satisfies a given condition.
|
||||
/// </summary>
|
||||
/// <param name="fun">The condition for the element to satisfy.</param>
|
||||
/// <returns>The zero-based index of the first occurrence of an element that matches the conditions defined by match, if found; otherwise, –1.</returns>
|
||||
public override int FindFirstIndex(Converter<double, bool> fun)
|
||||
/// <inheritdoc/>
|
||||
public override int FindFirstIndex(Func<double, bool> fun)
|
||||
{
|
||||
if (fun == null)
|
||||
{
|
||||
|
@ -898,12 +819,8 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
return firstIndex;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the index of the last element that satisfies a given condition.
|
||||
/// </summary>
|
||||
/// <param name="fun">The condition for the element to satisfy.</param>
|
||||
/// <returns>The last index.</returns>
|
||||
public override int FindLastIndex(Converter<double, bool> fun)
|
||||
/// <inheritdoc/>
|
||||
public override int FindLastIndex(Func<double, bool> fun)
|
||||
{
|
||||
if (fun == null)
|
||||
{
|
||||
|
@ -2729,38 +2646,21 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
return hash;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the maximum absolute difference between this vector and another vector.
|
||||
/// </summary>
|
||||
/// <param name="that">The second vector.</param>
|
||||
/// <returns><c>max(abs(this[i] - that[i]))</c>.
|
||||
/// Matching infinities or NaNs do not count.
|
||||
/// If <c>this</c> and <paramref name="that"/> are not the same size, returns infinity.</returns>
|
||||
/// <remarks>This routine is typically used instead of <c>Equals</c>, since <c>Equals</c> is susceptible to roundoff errors.
|
||||
/// </remarks>
|
||||
/// <inheritdoc/>
|
||||
public override double MaxDiff(Vector that)
|
||||
{
|
||||
if (Count != that.Count) return Double.PositiveInfinity;
|
||||
|
||||
var absdiff = new ApproximateSparseVector(Count);
|
||||
absdiff.SetToFunction(this, that, (a, b) => System.Math.Abs(a - b));
|
||||
absdiff.SetToFunction(this, that, (a, b) => MMath.AbsDiffAllowingNaNs(a, b));
|
||||
return absdiff.Max();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the maximum relative difference between this vector and another.
|
||||
/// </summary>
|
||||
/// <param name="that">The second vector.</param>
|
||||
/// <param name="rel">An offset to avoid division by zero.</param>
|
||||
/// <returns><c>max(abs(this[i] - that[i])/(abs(this[i]) + rel))</c>.
|
||||
/// Matching infinities or NaNs do not count.
|
||||
/// If <c>this</c> and <paramref name="that"/> are not the same size, returns infinity.</returns>
|
||||
/// <remarks>This routine is typically used instead of <c>Equals</c>, since <c>Equals</c> is susceptible to roundoff errors.
|
||||
/// </remarks>
|
||||
/// <inheritdoc/>
|
||||
public override double MaxDiff(Vector that, double rel)
|
||||
{
|
||||
var absdiff = new ApproximateSparseVector(Count);
|
||||
absdiff.SetToFunction(this, that, (a, b) => System.Math.Abs(a - b)/(System.Math.Abs(a) + rel));
|
||||
absdiff.SetToFunction(this, that, (a, b) => MMath.AbsDiffAllowingNaNs(a, b, rel));
|
||||
return absdiff.Max();
|
||||
}
|
||||
|
||||
|
|
|
@ -4782,8 +4782,8 @@ rr = mpf('-0.99999824265582826');
|
|||
/// <param name="x"></param>
|
||||
/// <param name="y"></param>
|
||||
/// <param name="rel">An offset to avoid division by zero.</param>
|
||||
/// <returns><c>abs(x - y)/(abs(x) + rel)</c>.
|
||||
/// Matching infinities give zero.
|
||||
/// <returns><c>abs(x - y)/(min(abs(x),abs(y)) + rel)</c>.
|
||||
/// Matching infinities give zero. Any NaN gives NaN.
|
||||
/// </returns>
|
||||
/// <remarks>
|
||||
/// This routine is often used to measure the error of y in estimating x.
|
||||
|
@ -4795,13 +4795,32 @@ rr = mpf('-0.99999824265582826');
|
|||
return Math.Abs(x - y) / (Math.Min(Math.Abs(x), Math.Abs(y)) + rel);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the relative distance between two numbers.
|
||||
/// </summary>
|
||||
/// <param name="x"></param>
|
||||
/// <param name="y"></param>
|
||||
/// <param name="rel">An offset to avoid division by zero.</param>
|
||||
/// <returns><c>abs(x - y)/(min(abs(x),abs(y)) + rel)</c>.
|
||||
/// Matching infinities or NaNs give zero.
|
||||
/// </returns>
|
||||
/// <remarks>
|
||||
/// This routine is often used to measure the error of y in estimating x.
|
||||
/// </remarks>
|
||||
public static double AbsDiffAllowingNaNs(double x, double y, double rel)
|
||||
{
|
||||
if (double.IsNaN(x)) return double.IsNaN(y) ? 0 : double.PositiveInfinity;
|
||||
if (double.IsNaN(y)) return double.PositiveInfinity;
|
||||
return AbsDiff(x, y, rel);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the distance between two numbers.
|
||||
/// </summary>
|
||||
/// <param name="x"></param>
|
||||
/// <param name="y"></param>
|
||||
/// <returns><c>abs(x - y)</c>.
|
||||
/// Matching infinities give zero.
|
||||
/// Matching infinities give zero. Any NaN gives NaN.
|
||||
/// </returns>
|
||||
public static double AbsDiff(double x, double y)
|
||||
{
|
||||
|
@ -4810,6 +4829,21 @@ rr = mpf('-0.99999824265582826');
|
|||
return Math.Abs(x - y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the distance between two numbers.
|
||||
/// </summary>
|
||||
/// <param name="x"></param>
|
||||
/// <param name="y"></param>
|
||||
/// <returns><c>abs(x - y)</c>.
|
||||
/// Matching infinities or NaNs give zero.
|
||||
/// </returns>
|
||||
public static double AbsDiffAllowingNaNs(double x, double y)
|
||||
{
|
||||
if (double.IsNaN(x)) return double.IsNaN(y) ? 0 : double.PositiveInfinity;
|
||||
if (double.IsNaN(y)) return double.PositiveInfinity;
|
||||
return AbsDiff(x, y);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns true if two numbers are equal when represented in double precision.
|
||||
/// </summary>
|
||||
|
|
|
@ -645,16 +645,27 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
/// <summary>
|
||||
/// Tests if all elements in the vector satisfy the specified condition.
|
||||
/// </summary>
|
||||
/// <param name="fun">The condition for the elements to satisfy.</param>
|
||||
/// <returns>True if all elements satisfy the condition, false otherwise.</returns>
|
||||
public abstract bool All(Func<double, bool> fun);
|
||||
|
||||
/// <summary>
|
||||
/// Test if all corresponding elements in this and that vector satisfy a condition
|
||||
/// </summary>
|
||||
/// <param name="that"></param>
|
||||
/// <param name="fun"></param>
|
||||
/// <returns></returns>
|
||||
public abstract bool All(Converter<double, bool> fun);
|
||||
public bool All(Vector that, Func<double, double, bool> fun)
|
||||
{
|
||||
return !Any(that, (x, y) => !fun(x, y));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tests if any elements in the vector satisfy the specified condition.
|
||||
/// </summary>
|
||||
/// <param name="fun"></param>
|
||||
/// <returns></returns>
|
||||
public abstract bool Any(Converter<double, bool> fun);
|
||||
/// <param name="fun">The condition for the elements to satisfy.</param>
|
||||
/// <returns>True if any elements satisfy the condition, false otherwise.</returns>
|
||||
public abstract bool Any(Func<double, bool> fun);
|
||||
|
||||
/// <summary>
|
||||
/// Test if any corresponding elements in this and that vector satisfy a condition
|
||||
|
@ -664,7 +675,7 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
/// <returns></returns>
|
||||
public virtual bool Any(Vector that, Func<double, double, bool> fun)
|
||||
{
|
||||
if (that is DenseVector) return ((DenseVector) that).Any(this, (x, y) => fun(y, x));
|
||||
if (that is DenseVector denseVector) return denseVector.Any(this, (x, y) => fun(y, x));
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
|
@ -674,7 +685,7 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
/// </summary>
|
||||
/// <param name="fun">A function to check if the condition is satisfied.</param>
|
||||
/// <returns>An enumeration over the indices of all elements which satisfy the specified condition.</returns>
|
||||
public IEnumerable<int> IndexOfAll(Converter<double, bool> fun)
|
||||
public IEnumerable<int> IndexOfAll(Func<double, bool> fun)
|
||||
{
|
||||
return this.FindAll(fun).Select(valueAtIndex => valueAtIndex.Index);
|
||||
}
|
||||
|
@ -685,28 +696,28 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
/// </summary>
|
||||
/// <param name="fun">A function to check if the condition is satisfied.</param>
|
||||
/// <returns>An enumeration over the indices and values of all elements which satisfy the specified condition.</returns>
|
||||
public abstract IEnumerable<ValueAtIndex<double>> FindAll(Converter<double, bool> fun);
|
||||
public abstract IEnumerable<ValueAtIndex<double>> FindAll(Func<double, bool> fun);
|
||||
|
||||
/// <summary>
|
||||
/// Returns the number of elements in the vector which satisfy a given condition.
|
||||
/// </summary>
|
||||
/// <param name="fun">The condition for the elements to satisfy.</param>
|
||||
/// <returns>The number of elements in the vector which satisfy the condition.</returns>
|
||||
public abstract int CountAll(Converter<double, bool> fun);
|
||||
public abstract int CountAll(Func<double, bool> fun);
|
||||
|
||||
/// <summary>
|
||||
/// Returns the index of the first element that satisfies satisfy a given condition.
|
||||
/// Returns the index of the first element that satisfies a given condition.
|
||||
/// </summary>
|
||||
/// <param name="fun">The condition for the element to satisfy.</param>
|
||||
/// <returns>The zero-based index of the first occurrence of an element that matches the conditions defined by match, if found; otherwise, <EFBFBD>1.</returns>
|
||||
public abstract int FindFirstIndex(Converter<double, bool> fun);
|
||||
/// <returns>The zero-based index of the first occurrence of an element that matches the conditions defined by match, if found; otherwise, -1.</returns>
|
||||
public abstract int FindFirstIndex(Func<double, bool> fun);
|
||||
|
||||
/// <summary>
|
||||
/// Returns the index of the last element that satisfiessatisfy a given condition.
|
||||
/// Returns the index of the last element that satisfies a given condition.
|
||||
/// </summary>
|
||||
/// <param name="fun">The condition for the element to satisfy.</param>
|
||||
/// <returns>The zero-based index of the last occurrence of an element that matches the conditions defined by match, if found; otherwise, <EFBFBD>1.</returns>
|
||||
public abstract int FindLastIndex(Converter<double, bool> fun);
|
||||
/// <returns>The zero-based index of the last occurrence of an element that matches the conditions defined by match, if found; otherwise, -1.</returns>
|
||||
public abstract int FindLastIndex(Func<double, bool> fun);
|
||||
|
||||
#endregion
|
||||
|
||||
|
@ -1418,12 +1429,12 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
/// <returns>True if the vectors have the same size and element values.</returns>
|
||||
public static bool operator ==(Vector a, Vector b)
|
||||
{
|
||||
if (Object.ReferenceEquals(a, b))
|
||||
if (ReferenceEquals(a, b))
|
||||
{
|
||||
return (true);
|
||||
return true;
|
||||
}
|
||||
if (Object.ReferenceEquals(a, null) || Object.ReferenceEquals(b, null))
|
||||
return (false);
|
||||
if (ReferenceEquals(a, null) || ReferenceEquals(b, null))
|
||||
return false;
|
||||
|
||||
return a.Equals(b);
|
||||
}
|
||||
|
@ -1436,21 +1447,21 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
/// <returns>True if vectors are not equal.</returns>
|
||||
public static bool operator !=(Vector a, Vector b)
|
||||
{
|
||||
return (!(a == b));
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines object equality.
|
||||
/// </summary>
|
||||
/// <param name="obj">Another (DenseVector) object.</param>
|
||||
/// <param name="obj">Another vector.</param>
|
||||
/// <returns>True if equal.</returns>
|
||||
/// <exclude/>
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
Vector that = obj as Vector;
|
||||
if (Object.ReferenceEquals(that, null))
|
||||
if (ReferenceEquals(that, null))
|
||||
return false;
|
||||
if (Object.ReferenceEquals(this, that))
|
||||
if (ReferenceEquals(this, that))
|
||||
return true;
|
||||
if (this.Count != that.Count)
|
||||
return false;
|
||||
|
@ -1657,7 +1668,7 @@ namespace Microsoft.ML.Probabilistic.Math
|
|||
/// </summary>
|
||||
/// <param name="that">The second vector.</param>
|
||||
/// <param name="rel">An offset to avoid division by zero.</param>
|
||||
/// <returns><c>max(abs(this[i] - that[i])/(abs(this[i]) + rel))</c>.
|
||||
/// <returns><c>max(abs(this[i] - that[i])/(min(abs(this[i]),abs(that[i])) + rel))</c>.
|
||||
/// Matching infinities or NaNs do not count.
|
||||
/// If <c>this</c> and <paramref name="that"/> are not the same size, returns infinity.</returns>
|
||||
/// <remarks>This routine is typically used instead of <c>Equals</c>, since <c>Equals</c> is susceptible to roundoff errors.
|
||||
|
|
|
@ -202,7 +202,7 @@ namespace Microsoft.ML.Probabilistic.Distributions
|
|||
{
|
||||
if (IsPointMass)
|
||||
{
|
||||
return power*that.GetLogProb(Point);
|
||||
return power * that.GetLogProb(Point);
|
||||
}
|
||||
else if (that.IsPointMass)
|
||||
{
|
||||
|
@ -211,8 +211,8 @@ namespace Microsoft.ML.Probabilistic.Distributions
|
|||
}
|
||||
else
|
||||
{
|
||||
var product = this*(that ^ power);
|
||||
return product.GetLogNormalizer() - this.GetLogNormalizer() - power*that.GetLogNormalizer();
|
||||
var product = this * (that ^ power);
|
||||
return product.GetLogNormalizer() - this.GetLogNormalizer() - power * that.GetLogNormalizer();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -230,7 +230,7 @@ namespace Microsoft.ML.Probabilistic.Distributions
|
|||
{
|
||||
// p must not be 0 or 1.
|
||||
double p = GetProbTrue();
|
||||
return p*that.GetLogProbTrue() + (1 - p)*that.GetLogProbFalse();
|
||||
return p * that.GetLogProbTrue() + (1 - p) * that.GetLogProbFalse();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -299,7 +299,7 @@ namespace Microsoft.ML.Probabilistic.Distributions
|
|||
{
|
||||
if (IsPointMass) return 0.0;
|
||||
double p = GetProbTrue();
|
||||
return p*(1 - p);
|
||||
return p * (1 - p);
|
||||
}
|
||||
|
||||
#if class
|
||||
|
@ -452,7 +452,7 @@ namespace Microsoft.ML.Probabilistic.Distributions
|
|||
{
|
||||
if (exponent < 0 && dist.IsPointMass)
|
||||
throw new DivideByZeroException($"The {nameof(exponent)} is negative and the distribution is a point mass");
|
||||
LogOdds = dist.LogOdds*exponent;
|
||||
LogOdds = dist.LogOdds * exponent;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -494,7 +494,7 @@ namespace Microsoft.ML.Probabilistic.Distributions
|
|||
throw new ArgumentException($"{nameof(weight1)} ({weight1}) + {nameof(weight2)} ({weight2}) < 0");
|
||||
else if (weight1 == 0) SetTo(dist2);
|
||||
else if (weight2 == 0) SetTo(dist1);
|
||||
// if dist1 == dist2 then we must return dist1, with no roundoff error
|
||||
// if dist1 == dist2 then we must return dist1, with no roundoff error
|
||||
else if (dist1.LogOdds == dist2.LogOdds) LogOdds = dist1.LogOdds;
|
||||
else if (double.IsPositiveInfinity(weight1))
|
||||
{
|
||||
|
@ -510,7 +510,7 @@ namespace Microsoft.ML.Probabilistic.Distributions
|
|||
else if (double.IsPositiveInfinity(weight2)) SetTo(dist2);
|
||||
else
|
||||
{
|
||||
SetProbTrue((weight1*dist1.GetProbTrue() + weight2*dist2.GetProbTrue())/(weight1 + weight2));
|
||||
SetProbTrue((weight1 * dist1.GetProbTrue() + weight2 * dist2.GetProbTrue()) / (weight1 + weight2));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -545,7 +545,7 @@ namespace Microsoft.ML.Probabilistic.Distributions
|
|||
public double MaxDiff(object thatd)
|
||||
{
|
||||
if (!(thatd is Bernoulli)) return Double.PositiveInfinity;
|
||||
Bernoulli that = (Bernoulli) thatd;
|
||||
Bernoulli that = (Bernoulli)thatd;
|
||||
return MMath.AbsDiff(LogOdds, that.LogOdds);
|
||||
}
|
||||
|
||||
|
@ -558,7 +558,7 @@ namespace Microsoft.ML.Probabilistic.Distributions
|
|||
public override bool Equals(object thatd)
|
||||
{
|
||||
if (!(thatd is Bernoulli)) return false;
|
||||
Bernoulli that = (Bernoulli) thatd;
|
||||
Bernoulli that = (Bernoulli)thatd;
|
||||
return (LogOdds == that.LogOdds);
|
||||
}
|
||||
|
||||
|
@ -627,8 +627,8 @@ namespace Microsoft.ML.Probabilistic.Distributions
|
|||
if (x == y) diff = 0; // in case x and y are Inf
|
||||
//double min = 0.5 * (sum - diff); // same as Math.Min(x,y)
|
||||
double min = System.Math.Min(x, y);
|
||||
double result = min + System.Math.Log((1 + System.Math.Exp(-sum))/(1 + System.Math.Exp(-diff)));
|
||||
return result*sign;
|
||||
double result = min + System.Math.Log((1 + System.Math.Exp(-sum)) / (1 + System.Math.Exp(-diff)));
|
||||
return result * sign;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -1458,7 +1458,7 @@ namespace Microsoft.ML.Probabilistic.Distributions
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Replaces the current distribution with an improper distribution which assigns the probability of 1 to every sequence.
|
||||
/// Replaces the current distribution with an improper distribution which assigns the probability of 1 to every sequence, or a different value if <see cref="SetLogValueOverride"/> was previously called.
|
||||
/// Sequence elements are restricted to be non-zero probability elements from a given distribution.
|
||||
/// </summary>
|
||||
/// <param name="allowedElements">The distribution representing allowed sequence elements.</param>
|
||||
|
@ -1468,7 +1468,7 @@ namespace Microsoft.ML.Probabilistic.Distributions
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Replaces the current distribution with an improper distribution which assigns the probability of 1 to every sequence.
|
||||
/// Replaces the current distribution with an improper distribution which assigns the probability of 1 to every sequence, or a different value if <see cref="SetLogValueOverride"/> was previously called.
|
||||
/// </summary>
|
||||
public void SetToUniform()
|
||||
{
|
||||
|
|
|
@ -12,6 +12,16 @@ namespace Microsoft.ML.Probabilistic.Factors
|
|||
[Quality(QualityBand.Preview)]
|
||||
public static class MaxGammaOp
|
||||
{
|
||||
public static double LogEvidenceRatio(double max, Gamma a, double b)
|
||||
{
|
||||
return MaxAverageConditional(a, b).GetLogProb(max);
|
||||
}
|
||||
|
||||
public static double LogEvidenceRatio(double max, double a, Gamma b)
|
||||
{
|
||||
return LogEvidenceRatio(max, b, a);
|
||||
}
|
||||
|
||||
[Skip]
|
||||
public static double LogEvidenceRatio(TruncatedGamma max)
|
||||
{
|
||||
|
@ -46,10 +56,14 @@ namespace Microsoft.ML.Probabilistic.Factors
|
|||
[Quality(QualityBand.Preview)]
|
||||
public static class MaxTruncatedGammaOp
|
||||
{
|
||||
[Skip]
|
||||
public static double LogEvidenceRatio2(TruncatedGamma max)
|
||||
public static double LogEvidenceRatio(double max, TruncatedGamma a, double b)
|
||||
{
|
||||
return 0.0;
|
||||
return MaxAverageConditional(a, b).GetLogProb(max);
|
||||
}
|
||||
|
||||
public static double LogEvidenceRatio(double max, double a, TruncatedGamma b)
|
||||
{
|
||||
return LogEvidenceRatio(max, b, a);
|
||||
}
|
||||
|
||||
public static TruncatedGamma MaxAverageConditional(TruncatedGamma a, double b)
|
||||
|
|
|
@ -17,15 +17,15 @@ using System.Windows.Forms;
|
|||
|
||||
namespace Microsoft.ML.Probabilistic.Compiler.Visualizers
|
||||
{
|
||||
internal class DependencyGraphView
|
||||
internal class DependencyGraphView : IDisposable
|
||||
{
|
||||
private Panel panel = new Panel();
|
||||
private GViewer gviewer = new GViewer();
|
||||
private IndexedGraph dg;
|
||||
private IndexedProperty<NodeIndex, Node> nodeOf;
|
||||
private Func<NodeIndex, string> nodeName;
|
||||
private Func<EdgeIndex, string> edgeName;
|
||||
private IEnumerable<EdgeStylePredicate> edgeStyles;
|
||||
private readonly Panel panel = new Panel();
|
||||
private readonly GViewer gviewer = new GViewer();
|
||||
private readonly IndexedGraph dg;
|
||||
private readonly IndexedProperty<NodeIndex, Node> nodeOf;
|
||||
private readonly Func<NodeIndex, string> nodeName;
|
||||
private readonly Func<EdgeIndex, string> edgeName;
|
||||
private readonly IEnumerable<EdgeStylePredicate> edgeStyles;
|
||||
|
||||
internal DependencyGraphView(IndexedGraph dg, IEnumerable<EdgeStylePredicate> edgeStyles = null,
|
||||
Func<NodeIndex, string> nodeName = null,
|
||||
|
@ -168,5 +168,11 @@ namespace Microsoft.ML.Probabilistic.Compiler.Visualizers
|
|||
{
|
||||
WindowsVisualizer.FormHelper.RunInForm(panel, title, false);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
panel.Dispose();
|
||||
gviewer.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -15,9 +15,9 @@ using Microsoft.Msagl.Drawing;
|
|||
|
||||
namespace Microsoft.ML.Probabilistic.Compiler.Visualizers
|
||||
{
|
||||
internal class ModelView
|
||||
internal class ModelView : IDisposable
|
||||
{
|
||||
private GViewer gviewer = new GViewer();
|
||||
private readonly GViewer gviewer = new GViewer();
|
||||
|
||||
internal ModelBuilder modelBuilder;
|
||||
|
||||
|
@ -57,6 +57,11 @@ namespace Microsoft.ML.Probabilistic.Compiler.Visualizers
|
|||
Form f = WindowsVisualizer.FormHelper.ShowInForm(gviewer, title, maximise);
|
||||
Application.Run(f);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
gviewer.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
internal class MsaglWriter : GraphViews.GraphWriter
|
||||
|
|
|
@ -10,7 +10,6 @@ using Microsoft.Msagl.GraphViewerGdi;
|
|||
using Microsoft.Msagl.Drawing;
|
||||
using Microsoft.ML.Probabilistic.Compiler.Attributes;
|
||||
using Node = Microsoft.Msagl.Drawing.Node;
|
||||
using Microsoft.ML.Probabilistic.Compiler;
|
||||
using Microsoft.ML.Probabilistic.Compiler.Transforms;
|
||||
using Microsoft.ML.Probabilistic.Compiler.CodeModel;
|
||||
using Microsoft.ML.Probabilistic.Collections;
|
||||
|
@ -20,9 +19,9 @@ namespace Microsoft.ML.Probabilistic.Compiler.Visualizers
|
|||
/// <summary>
|
||||
/// A view of a task graph, which is a schedule when the tasks are message computations.
|
||||
/// </summary>
|
||||
internal class TaskGraphView
|
||||
internal class TaskGraphView : IDisposable
|
||||
{
|
||||
private GViewer gviewer = new GViewer();
|
||||
private readonly GViewer gviewer = new GViewer();
|
||||
|
||||
protected enum Stage
|
||||
{
|
||||
|
@ -33,7 +32,7 @@ namespace Microsoft.ML.Probabilistic.Compiler.Visualizers
|
|||
/// <summary>
|
||||
/// Helps build class declarations
|
||||
/// </summary>
|
||||
private static CodeBuilder Builder = CodeBuilder.Instance;
|
||||
private static readonly CodeBuilder Builder = CodeBuilder.Instance;
|
||||
|
||||
internal IList<IStatement> pretasks;
|
||||
internal IList<IStatement> looptasks;
|
||||
|
@ -48,9 +47,9 @@ namespace Microsoft.ML.Probabilistic.Compiler.Visualizers
|
|||
if (!context.InputAttributes.Has<OperatorMethod>(imd)) continue;
|
||||
foreach (IStatement ist in imd.Body.Statements)
|
||||
{
|
||||
if (ist is IWhileStatement)
|
||||
if (ist is IWhileStatement iws)
|
||||
{
|
||||
looptasks.AddRange(((IWhileStatement) ist).Body.Statements);
|
||||
looptasks.AddRange(iws.Body.Statements);
|
||||
continue;
|
||||
}
|
||||
if (context.InputAttributes.Has<OperatorStatement>(ist)) pretasks.Add(ist);
|
||||
|
@ -150,18 +149,16 @@ namespace Microsoft.ML.Probabilistic.Compiler.Visualizers
|
|||
//if (di.IsOutput) nd.Attr.Fillcolor = Color.LightBlue;
|
||||
nd.LabelText = s;
|
||||
if (stage == Stage.Initialisation) nd.Attr.FillColor = Color.LightGray;
|
||||
if (ist is IExpressionStatement)
|
||||
if (ist is IExpressionStatement ies)
|
||||
{
|
||||
IExpressionStatement ies = (IExpressionStatement) ist;
|
||||
IAssignExpression iae = ies.Expression as IAssignExpression;
|
||||
if ((iae != null) && (iae.Target is IVariableDeclarationExpression)) nd.Attr.LineWidth = 2;
|
||||
if ((ies.Expression is IAssignExpression iae) && (iae.Target is IVariableDeclarationExpression)) nd.Attr.LineWidth = 2;
|
||||
}
|
||||
nd.Attr.Shape = Shape.Box;
|
||||
nd.Label.FontSize = 9;
|
||||
return nd;
|
||||
}
|
||||
|
||||
private Dictionary<Stage, Dictionary<IStatement, Node>> stmtNodeMap = new Dictionary<Stage, Dictionary<IStatement, Node>>();
|
||||
private readonly Dictionary<Stage, Dictionary<IStatement, Node>> stmtNodeMap = new Dictionary<Stage, Dictionary<IStatement, Node>>();
|
||||
|
||||
protected Node GetNodeForStatement(IStatement ist, Stage stg)
|
||||
{
|
||||
|
@ -176,44 +173,36 @@ namespace Microsoft.ML.Probabilistic.Compiler.Visualizers
|
|||
stmtNodeMap[stg][ist] = nd;
|
||||
}
|
||||
|
||||
|
||||
protected bool ReferenceContains(IList<IStatement> list, object value)
|
||||
{
|
||||
foreach (object obj in list) if (object.ReferenceEquals(obj, value)) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
protected string StatementLabel(IStatement ist)
|
||||
{
|
||||
if (ist is IExpressionStatement)
|
||||
if (ist is IExpressionStatement ies)
|
||||
{
|
||||
IExpressionStatement ies = (IExpressionStatement) ist;
|
||||
string s;
|
||||
if (ies.Expression is IAssignExpression)
|
||||
if (ies.Expression is IAssignExpression iae)
|
||||
{
|
||||
s = ExpressionToString(((IAssignExpression) ies.Expression).Target);
|
||||
s = ExpressionToString(iae.Target);
|
||||
}
|
||||
else s = ExpressionToString(ies.Expression);
|
||||
if (s.StartsWith("this.")) s = s.Substring(5);
|
||||
//if (s.EndsWith("[0]")) s = s.Substring(0, s.Length - 3);
|
||||
return s;
|
||||
}
|
||||
if (ist is IForStatement)
|
||||
if (ist is IForStatement ifs)
|
||||
{
|
||||
return StatementLabel(((IForStatement) ist).Body.Statements[0]);
|
||||
return StatementLabel(ifs.Body.Statements[0]);
|
||||
}
|
||||
if (ist is IConditionStatement)
|
||||
if (ist is IConditionStatement ics)
|
||||
{
|
||||
return String.Format("if ({0}) {1}", ((IConditionStatement) ist).Condition.ToString(),
|
||||
StatementLabel(((IConditionStatement) ist).Then));
|
||||
return String.Format("if ({0}) {1}", ics.Condition.ToString(),
|
||||
StatementLabel(ics.Then));
|
||||
}
|
||||
if (ist is IBlockStatement)
|
||||
if (ist is IBlockStatement ibs)
|
||||
{
|
||||
int blockSize = ((IBlockStatement) ist).Statements.Count;
|
||||
int blockSize = ibs.Statements.Count;
|
||||
string s;
|
||||
if (blockSize > 0)
|
||||
{
|
||||
s = StatementLabel(((IBlockStatement) ist).Statements[0]);
|
||||
s = StatementLabel(ibs.Statements[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -239,5 +228,10 @@ namespace Microsoft.ML.Probabilistic.Compiler.Visualizers
|
|||
{
|
||||
WindowsVisualizer.FormHelper.RunInForm(gviewer, "Infer.NET Schedule Viewer", false);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
gviewer.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -273,7 +273,7 @@ namespace Microsoft.ML.Probabilistic.Tests
|
|||
Assert.Equal(1, v.IndexOf(commonValue));
|
||||
|
||||
// Test IndexOfAll/FindAll
|
||||
Converter<double, bool> filter = x => x >= commonValue && x < v[2];
|
||||
Func<double, bool> filter = x => x >= commonValue && x < v[2];
|
||||
int[] indexOfAll = v.IndexOfAll(filter).ToArray();
|
||||
ValueAtIndex<double>[] all = v.FindAll(filter).ToArray();
|
||||
int allCount = v.CountAll(filter);
|
||||
|
@ -1567,109 +1567,40 @@ namespace Microsoft.ML.Probabilistic.Tests
|
|||
}
|
||||
}
|
||||
|
||||
private void VectorEquality(Vector a)
|
||||
{
|
||||
Rand.Restart(12347);
|
||||
|
||||
Vector aCopy = Vector.Copy(a);
|
||||
Vector aPlusNoise = a.Clone();
|
||||
for (int i = 0; i < a.Count; i++)
|
||||
aPlusNoise[i] += Rand.Double();
|
||||
|
||||
Assert.True(a == aCopy);
|
||||
Assert.False(a != aCopy);
|
||||
Assert.Equal(a, aCopy);
|
||||
Assert.Equal(0.0, a.MaxDiff(aCopy));
|
||||
|
||||
Assert.False(a == aPlusNoise);
|
||||
Assert.True(a != aPlusNoise);
|
||||
Assert.NotEqual(Vector.Zero(aPlusNoise.Count), aPlusNoise);
|
||||
double diff = 0.0;
|
||||
for (int i = 0; i < a.Count; i++)
|
||||
{
|
||||
double d = System.Math.Abs(a[i] - aPlusNoise[i]) / (System.Math.Abs(a[i]) + TOLERANCE);
|
||||
if (d > diff) diff = d;
|
||||
}
|
||||
double diff1 = a.MaxDiff(aPlusNoise, TOLERANCE);
|
||||
Assert.Equal(diff, diff1);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void VectorEqualityTests()
|
||||
{
|
||||
double[] a = new double[] { 1.2, 2.3, 3.4, 1.2, 1.2, 2.3 };
|
||||
double[] a = new double[] { 1.2, 2.3, 3.4, 1.2, 1.2, 2.3, double.PositiveInfinity, double.NegativeInfinity };
|
||||
double[] aExt = new double[] { 5.6, 1.2, 1.2, 6.7, 7.8, 1.2, 1.2, 6.7 };
|
||||
Sparsity approxSparsity = Sparsity.ApproximateWithTolerance(0.001);
|
||||
Vector[] aVector = new Vector[5];
|
||||
aVector[0] = Vector.FromArray(a);
|
||||
aVector[1] = Vector.FromArray(a, Sparsity.Sparse);
|
||||
aVector[2] = Vector.FromArray(a, approxSparsity);
|
||||
aVector[3] = DenseVector.FromArrayReference(6, aExt, 1);
|
||||
aVector[4] = Vector.FromArray(a, Sparsity.Piecewise);
|
||||
for (int i = 0; i < aVector.Length; i++)
|
||||
VectorEquality(aVector[i]);
|
||||
}
|
||||
VectorEquality(Vector.FromArray(a));
|
||||
VectorEquality(Vector.FromArray(a, Sparsity.Sparse));
|
||||
VectorEquality(Vector.FromArray(a, approxSparsity));
|
||||
VectorEquality(Vector.FromArray(a, Sparsity.Piecewise));
|
||||
VectorEquality(DenseVector.FromArrayReference(6, aExt, 1));
|
||||
|
||||
private void VectorInequality(Vector a)
|
||||
{
|
||||
double min = a.Min();
|
||||
double max = a.Max();
|
||||
Assert.True(a.All(x => x < max + 0.1));
|
||||
Assert.True(a.Any(x => x > max - 0.1));
|
||||
void VectorEquality(Vector v)
|
||||
{
|
||||
Vector copy = Vector.Copy(v);
|
||||
Assert.True(v == copy);
|
||||
Assert.False(v != copy);
|
||||
Assert.Equal(v, copy);
|
||||
Assert.Equal(0.0, v.MaxDiff(copy));
|
||||
|
||||
int i2 = a.Count / 2;
|
||||
double delta = 0.25;
|
||||
Vector noisy = v.Clone();
|
||||
noisy[0] += delta;
|
||||
Assert.False(v == noisy);
|
||||
Assert.True(v != noisy);
|
||||
Assert.NotEqual(Vector.Zero(noisy.Count), noisy);
|
||||
double diffExpected = delta / (v[0] + TOLERANCE);
|
||||
double diff = v.MaxDiff(noisy, TOLERANCE);
|
||||
Assert.Equal(diffExpected, diff);
|
||||
|
||||
Vector b = Vector.Copy(a);
|
||||
b[i2] = a[i2] + 0.1;
|
||||
|
||||
Assert.True(b >= a);
|
||||
Assert.False(b > a);
|
||||
Assert.False(b < a);
|
||||
Assert.False(b <= a);
|
||||
Assert.True(a <= b);
|
||||
Assert.False(a < b);
|
||||
Assert.False(a > b);
|
||||
Assert.False(a >= b);
|
||||
|
||||
for (int i = 0; i < a.Count; i++)
|
||||
b[i] = a[i] + 0.1;
|
||||
Assert.True(b >= a);
|
||||
Assert.True(b > a);
|
||||
Assert.False(b < a);
|
||||
Assert.False(b <= a);
|
||||
Assert.True(a <= b);
|
||||
Assert.True(a < b);
|
||||
Assert.False(a > b);
|
||||
Assert.False(a >= b);
|
||||
|
||||
for (int i = 0; i < a.Count; i++)
|
||||
b[i] = (i % 2) == 0 ? a[i] + 0.1 : a[i] - 0.1;
|
||||
Assert.False(b >= a);
|
||||
Assert.False(b > a);
|
||||
Assert.False(b < a);
|
||||
Assert.False(b <= a);
|
||||
Assert.False(a <= b);
|
||||
Assert.False(a < b);
|
||||
Assert.False(a > b);
|
||||
Assert.False(a >= b);
|
||||
|
||||
double d = 0.5 * (min + max);
|
||||
Assert.False(a <= d);
|
||||
Assert.False(a < d);
|
||||
Assert.False(a > d);
|
||||
Assert.False(a >= d);
|
||||
|
||||
Assert.True(a <= max);
|
||||
Assert.True(a < max + 0.1);
|
||||
Assert.False(a < max);
|
||||
Assert.False(a > max);
|
||||
Assert.False(a >= max);
|
||||
|
||||
Assert.True(a >= min);
|
||||
Assert.True(a > min - 0.1);
|
||||
Assert.False(a > min);
|
||||
Assert.False(a < min);
|
||||
Assert.False(a <= min);
|
||||
v[0] = double.NaN;
|
||||
Vector withNaN = v.Clone();
|
||||
Assert.Equal(0.0, v.MaxDiff(withNaN));
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
@ -1678,14 +1609,81 @@ namespace Microsoft.ML.Probabilistic.Tests
|
|||
double[] a = new double[] { 1.2, 2.3, 3.4, 1.2, 1.2, 2.3 };
|
||||
double[] aExt = new double[] { 5.6, 1.2, 1.2, 6.7, 7.8, 1.2, 1.2, 6.7 };
|
||||
Sparsity approxSparsity = Sparsity.ApproximateWithTolerance(0.001);
|
||||
Vector[] aVector = new Vector[5];
|
||||
aVector[0] = Vector.FromArray(a);
|
||||
aVector[1] = Vector.FromArray(a, Sparsity.Sparse);
|
||||
aVector[2] = Vector.FromArray(a, approxSparsity);
|
||||
aVector[3] = DenseVector.FromArrayReference(6, aExt, 1);
|
||||
aVector[4] = Vector.FromArray(a, Sparsity.Piecewise);
|
||||
for (int i = 0; i < aVector.Length; i++)
|
||||
VectorInequality(aVector[i]);
|
||||
VectorInequality(Vector.FromArray(a));
|
||||
VectorInequality(Vector.FromArray(a, Sparsity.Sparse));
|
||||
VectorInequality(Vector.FromArray(a, approxSparsity));
|
||||
VectorInequality(Vector.FromArray(a, Sparsity.Piecewise));
|
||||
VectorInequality(DenseVector.FromArrayReference(6, aExt, 1));
|
||||
|
||||
void VectorInequality(Vector v)
|
||||
{
|
||||
double min = v.Min();
|
||||
double max = v.Max();
|
||||
Assert.True(v.All(x => x < max + 0.1));
|
||||
Assert.True(v.Any(x => x > max - 0.1));
|
||||
|
||||
int i2 = v.Count / 2;
|
||||
|
||||
Vector b = Vector.Copy(v);
|
||||
b[i2] = v[i2] + 0.1;
|
||||
|
||||
Assert.True(b >= v);
|
||||
Assert.False(b > v);
|
||||
Assert.False(b < v);
|
||||
Assert.False(b <= v);
|
||||
Assert.True(v <= b);
|
||||
Assert.False(v < b);
|
||||
Assert.False(v > b);
|
||||
Assert.False(v >= b);
|
||||
|
||||
for (int i = 0; i < v.Count; i++)
|
||||
b[i] = v[i] + 0.1;
|
||||
Assert.True(b >= v);
|
||||
Assert.True(b > v);
|
||||
Assert.False(b < v);
|
||||
Assert.False(b <= v);
|
||||
Assert.True(v <= b);
|
||||
Assert.True(v < b);
|
||||
Assert.False(v > b);
|
||||
Assert.False(v >= b);
|
||||
|
||||
for (int i = 0; i < v.Count; i++)
|
||||
b[i] = (i % 2) == 0 ? v[i] + 0.1 : v[i] - 0.1;
|
||||
Assert.False(b >= v);
|
||||
Assert.False(b > v);
|
||||
Assert.False(b < v);
|
||||
Assert.False(b <= v);
|
||||
Assert.False(v <= b);
|
||||
Assert.False(v < b);
|
||||
Assert.False(v > b);
|
||||
Assert.False(v >= b);
|
||||
|
||||
double d = 0.5 * (min + max);
|
||||
Assert.False(v <= d);
|
||||
Assert.False(v < d);
|
||||
Assert.False(v > d);
|
||||
Assert.False(v >= d);
|
||||
|
||||
Assert.True(v <= max);
|
||||
Assert.True(v < max + 0.1);
|
||||
Assert.False(v < max);
|
||||
Assert.False(v > max);
|
||||
Assert.False(v >= max);
|
||||
|
||||
Assert.True(v >= min);
|
||||
Assert.True(v > min - 0.1);
|
||||
Assert.False(v > min);
|
||||
Assert.False(v < min);
|
||||
Assert.False(v <= min);
|
||||
|
||||
v[0] = double.NegativeInfinity;
|
||||
v[1] = double.PositiveInfinity;
|
||||
b.SetTo(v);
|
||||
Assert.True(b >= v);
|
||||
Assert.True(b <= v);
|
||||
Assert.False(b > v);
|
||||
Assert.False(b < v);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
@ -1702,23 +1700,17 @@ namespace Microsoft.ML.Probabilistic.Tests
|
|||
{
|
||||
// rectangular matrix tests
|
||||
Matrix R = new Matrix(new double[,] { { 1, 2, 3 }, { 4, 5, 6 } });
|
||||
Console.WriteLine("R:\n{0}", R);
|
||||
|
||||
Matrix Rt = R.Transpose();
|
||||
Console.WriteLine("R':\n{0}", Rt);
|
||||
Matrix Rtt = new Matrix(R.Rows, R.Cols);
|
||||
Rtt.SetToTranspose(Rt);
|
||||
Assert.True(Rtt.Equals(R));
|
||||
Assert.True(Rtt.GetHashCode() == R.GetHashCode());
|
||||
Console.WriteLine("");
|
||||
|
||||
Matrix RRTrue = new Matrix(new double[,] { { 14, 32 }, { 32, 77 } });
|
||||
Matrix RR = new Matrix(R.Rows, Rt.Cols);
|
||||
RR.SetToProduct(R, Rt);
|
||||
//Rt.SetToProduct(R,Rt); RR.SetTo(Rt);
|
||||
Console.WriteLine("R*R':\n{0}", RR);
|
||||
Assert.True(RR.MaxDiff(RRTrue) < TOLERANCE);
|
||||
Console.WriteLine("");
|
||||
|
||||
RR.SetTo(RRTrue);
|
||||
Assert.Equal(RR, RRTrue);
|
||||
|
@ -1732,14 +1724,10 @@ namespace Microsoft.ML.Probabilistic.Tests
|
|||
// square matrix tests
|
||||
// A = [2 1 1; 1 2 1; 1 1 2]
|
||||
PositiveDefiniteMatrix A = new PositiveDefiniteMatrix(new double[,] { { 2, 1, 1 }, { 1, 2, 1 }, { 1, 1, 2 } });
|
||||
Console.WriteLine("A:\n{0}", A);
|
||||
Console.WriteLine("");
|
||||
Assert.True(A.SymmetryError() == 0.0);
|
||||
|
||||
double det = A.Determinant();
|
||||
Console.Write("det(A) = {0}", det);
|
||||
Assert.True(System.Math.Abs(det - 4) < TOLERANCE);
|
||||
Console.WriteLine("");
|
||||
|
||||
PositiveDefiniteMatrix AinvTrue = new PositiveDefiniteMatrix(new double[,]
|
||||
{
|
||||
|
@ -1749,16 +1737,11 @@ namespace Microsoft.ML.Probabilistic.Tests
|
|||
});
|
||||
PositiveDefiniteMatrix Ainv = new PositiveDefiniteMatrix(3, 3);
|
||||
Ainv.SetToInverse(A);
|
||||
Console.WriteLine("inv(A):\n{0}", Ainv);
|
||||
Assert.True(Ainv.MaxDiff(AinvTrue) < TOLERANCE);
|
||||
Assert.True(Ainv.SymmetryError() == 0.0);
|
||||
Console.WriteLine("");
|
||||
|
||||
Console.WriteLine("sum(b): {0}", b.Sum());
|
||||
Vector v = Ainv * b;
|
||||
Console.WriteLine("inv(A)*b:\n{0}", v);
|
||||
Assert.True(v.MaxDiff(c) < TOLERANCE);
|
||||
Console.WriteLine("");
|
||||
|
||||
v.SetTo(b);
|
||||
Assert.Equal(v, b);
|
||||
|
@ -1766,12 +1749,10 @@ namespace Microsoft.ML.Probabilistic.Tests
|
|||
|
||||
(new LuDecomposition(A)).Solve((DenseVector)v);
|
||||
// should be same as above
|
||||
Console.WriteLine("Solve(A,b):\n{0}", v);
|
||||
Assert.True(v.MaxDiff(c) < TOLERANCE);
|
||||
Vector b2 = Vector.Zero(b.Count);
|
||||
b2.SetToProduct(A, v);
|
||||
Assert.True(b.MaxDiff(b2) < TOLERANCE);
|
||||
Console.WriteLine("");
|
||||
|
||||
LowerTriangularMatrix LTrue = new LowerTriangularMatrix(new double[,]
|
||||
{
|
||||
|
@ -1781,10 +1762,7 @@ namespace Microsoft.ML.Probabilistic.Tests
|
|||
});
|
||||
LowerTriangularMatrix L = new LowerTriangularMatrix(3, 3);
|
||||
bool isPosDef = L.SetToCholesky(A);
|
||||
//Console.WriteLine("IsPosDef(A): {0}", isPosDef);
|
||||
Assert.True(isPosDef);
|
||||
//Console.WriteLine("Cholesky(A):\n{0}", L);
|
||||
Console.WriteLine("Cholesky(A) error = {0}", L.MaxDiff(LTrue));
|
||||
Assert.True(L.MaxDiff(LTrue) < TOLERANCE);
|
||||
|
||||
LowerTriangularMatrix LinvTrue = new LowerTriangularMatrix(new double[,]
|
||||
|
@ -1795,11 +1773,9 @@ namespace Microsoft.ML.Probabilistic.Tests
|
|||
});
|
||||
LowerTriangularMatrix Linv = new LowerTriangularMatrix(3, 3);
|
||||
Linv.SetToInverse(L);
|
||||
Console.WriteLine("inv(L) error = {0}", Linv.MaxDiff(LinvTrue));
|
||||
Assert.True(Linv.MaxDiff(LinvTrue) < TOLERANCE);
|
||||
Linv.SetTo(L);
|
||||
Linv.SetToInverse(Linv);
|
||||
Console.WriteLine("inv(L) error = {0}", Linv.MaxDiff(LinvTrue));
|
||||
Assert.True(Linv.MaxDiff(LinvTrue) < TOLERANCE);
|
||||
|
||||
// L*L' = A, so L'\L\A = I
|
||||
|
@ -1812,14 +1788,11 @@ namespace Microsoft.ML.Probabilistic.Tests
|
|||
eye.PredivideBy(L);
|
||||
eye.PredivideByTranspose(L);
|
||||
Assert.True(eye.MaxDiff(Matrix.Identity(3)) < TOLERANCE);
|
||||
Console.WriteLine("");
|
||||
|
||||
// L*L' = A, so inv(A)*b = inv(L')*inv(L)*b
|
||||
v.SetTo(b);
|
||||
v.PredivideBy(L);
|
||||
Console.WriteLine("v = {0}", v); // should be 2.8284, 1.633, 1.1547
|
||||
v.PredivideBy(L.Transpose());
|
||||
Console.WriteLine("v = {0}", v);
|
||||
Assert.True(v.MaxDiff(c) < TOLERANCE);
|
||||
|
||||
v.SetTo(b);
|
||||
|
@ -1949,7 +1922,7 @@ namespace Microsoft.ML.Probabilistic.Tests
|
|||
}
|
||||
|
||||
[Fact]
|
||||
public void VectorTest()
|
||||
public void VectorSetTo_WithWrongArraySize_ThrowsException()
|
||||
{
|
||||
Assert.Throws<ArgumentException>(() =>
|
||||
{
|
||||
|
@ -1957,7 +1930,6 @@ namespace Microsoft.ML.Probabilistic.Tests
|
|||
Vector x = Vector.Zero(3);
|
||||
double[] array = new double[] { 1, 2, 3 };
|
||||
x.SetTo(array);
|
||||
Console.WriteLine(x);
|
||||
for (int i = 0; i < array.Length; i++)
|
||||
{
|
||||
Assert.Equal(array[i], x[i]);
|
||||
|
@ -1990,27 +1962,21 @@ namespace Microsoft.ML.Probabilistic.Tests
|
|||
{
|
||||
// rectangular matrix tests
|
||||
Matrix R = new Matrix(new double[,] { { 1, 2, 3 }, { 4, 5, 6 } });
|
||||
Console.WriteLine("R:\n{0}", R);
|
||||
|
||||
Matrix Rt = R.Transpose();
|
||||
Console.WriteLine("R':\n{0}", Rt);
|
||||
Matrix Rtt = new Matrix(R.Rows, R.Cols);
|
||||
Rtt.SetToTranspose(Rt);
|
||||
Assert.True(Rtt.Equals(R));
|
||||
Assert.True(Rtt.GetHashCode() == R.GetHashCode());
|
||||
Console.WriteLine("");
|
||||
|
||||
Matrix RRTrue = new Matrix(new double[,] { { 14, 32 }, { 32, 77 } });
|
||||
Matrix RR = new Matrix(R.Rows, Rt.Cols);
|
||||
RR.SetToProduct(R, Rt);
|
||||
//Rt.SetToProduct(R,Rt); RR.SetTo(Rt);
|
||||
Console.WriteLine("R*R':\n{0}", RR);
|
||||
Assert.True(RR.MaxDiff(RRTrue) < TOLERANCE);
|
||||
RR.SetToOuter(R);
|
||||
Assert.True(RR.MaxDiff(RRTrue) < TOLERANCE);
|
||||
RR.SetToOuterTranspose(Rt);
|
||||
Assert.True(RR.MaxDiff(RRTrue) < TOLERANCE);
|
||||
Console.WriteLine("");
|
||||
|
||||
RR.SetTo(RRTrue);
|
||||
Assert.Equal(RR, RRTrue);
|
||||
|
@ -2024,14 +1990,10 @@ namespace Microsoft.ML.Probabilistic.Tests
|
|||
// square matrix tests
|
||||
// A = [2 1 1; 1 2 1; 1 1 2]
|
||||
PositiveDefiniteMatrix A = new PositiveDefiniteMatrix(new double[,] { { 2, 1, 1 }, { 1, 2, 1 }, { 1, 1, 2 } });
|
||||
Console.WriteLine("A:\n{0}", A);
|
||||
Console.WriteLine("");
|
||||
Assert.True(A.SymmetryError() == 0.0);
|
||||
|
||||
double det = A.Determinant();
|
||||
Console.Write("det(A) = {0}", det);
|
||||
Assert.True(System.Math.Abs(det - 4) < TOLERANCE);
|
||||
Console.WriteLine("");
|
||||
|
||||
PositiveDefiniteMatrix AinvTrue = new PositiveDefiniteMatrix(new double[,]
|
||||
{
|
||||
|
@ -2046,18 +2008,13 @@ namespace Microsoft.ML.Probabilistic.Tests
|
|||
Lapack.SymmetricInverseInPlace(t);
|
||||
Assert.True(Ainv.MaxDiff(t) < TOLERANCE);
|
||||
#endif
|
||||
Console.WriteLine("inv(A):\n{0}", Ainv);
|
||||
Assert.True(Ainv.MaxDiff(AinvTrue) < TOLERANCE);
|
||||
Assert.True(Ainv.SymmetryError() == 0.0);
|
||||
Console.WriteLine("");
|
||||
|
||||
Vector b = Vector.FromArray(new double[] { 4, 4, 4 });
|
||||
Vector c = Vector.FromArray(new double[] { 1, 1, 1 });
|
||||
Console.WriteLine("sum(b): {0}", b.Sum());
|
||||
Vector v = Ainv * b;
|
||||
Console.WriteLine("inv(A)*b:\n{0}", v);
|
||||
Assert.True(v.MaxDiff(c) < TOLERANCE);
|
||||
Console.WriteLine("");
|
||||
|
||||
v.SetTo(b);
|
||||
Assert.Equal(v, b);
|
||||
|
@ -2065,12 +2022,10 @@ namespace Microsoft.ML.Probabilistic.Tests
|
|||
|
||||
(new LuDecomposition(A)).Solve(v);
|
||||
// should be same as above
|
||||
Console.WriteLine("Solve(A,b):\n{0}", v);
|
||||
Assert.True(v.MaxDiff(c) < TOLERANCE);
|
||||
Vector b2 = Vector.Zero(b.Count);
|
||||
b2.SetToProduct(A, v);
|
||||
Assert.True(b.MaxDiff(b2) < TOLERANCE);
|
||||
Console.WriteLine("");
|
||||
|
||||
LowerTriangularMatrix LTrue = new LowerTriangularMatrix(new double[,]
|
||||
{
|
||||
|
@ -2080,17 +2035,12 @@ namespace Microsoft.ML.Probabilistic.Tests
|
|||
});
|
||||
LowerTriangularMatrix L = new LowerTriangularMatrix(3, 3);
|
||||
bool isPosDef = L.SetToCholesky(A);
|
||||
//Console.WriteLine("IsPosDef(A): {0}", isPosDef);
|
||||
Assert.True(isPosDef);
|
||||
Console.WriteLine("Cholesky(A):\n{0}", L);
|
||||
Console.WriteLine("Cholesky(A) error = {0}", L.MaxDiff(LTrue));
|
||||
Assert.True(L.MaxDiff(LTrue) < TOLERANCE);
|
||||
|
||||
PositiveDefiniteMatrix Acopy = (PositiveDefiniteMatrix)A.Clone();
|
||||
L = Acopy.CholeskyInPlace(out isPosDef);
|
||||
Assert.True(isPosDef);
|
||||
Console.WriteLine("Cholesky(A):\n{0}", L);
|
||||
Console.WriteLine("Cholesky(A) error = {0}", L.MaxDiff(LTrue));
|
||||
Assert.True(L.MaxDiff(LTrue) < TOLERANCE);
|
||||
|
||||
LowerTriangularMatrix LinvTrue = new LowerTriangularMatrix(new double[,]
|
||||
|
@ -2101,11 +2051,9 @@ namespace Microsoft.ML.Probabilistic.Tests
|
|||
});
|
||||
LowerTriangularMatrix Linv = new LowerTriangularMatrix(3, 3);
|
||||
Linv.SetToInverse(L);
|
||||
Console.WriteLine("inv(L) error = {0}", Linv.MaxDiff(LinvTrue));
|
||||
Assert.True(Linv.MaxDiff(LinvTrue) < TOLERANCE);
|
||||
Linv.SetTo(L);
|
||||
Linv.SetToInverse(Linv);
|
||||
Console.WriteLine("inv(L) error = {0}", Linv.MaxDiff(LinvTrue));
|
||||
Assert.True(Linv.MaxDiff(LinvTrue) < TOLERANCE);
|
||||
|
||||
// L*L' = A, so L'\L\A = I
|
||||
|
@ -2118,14 +2066,11 @@ namespace Microsoft.ML.Probabilistic.Tests
|
|||
eye.PredivideBy(L);
|
||||
eye.PredivideByTranspose(L);
|
||||
Assert.True(eye.MaxDiff(Matrix.Identity(3)) < TOLERANCE);
|
||||
Console.WriteLine("");
|
||||
|
||||
// L*L' = A, so inv(A)*b = inv(L')*inv(L)*b
|
||||
v.SetTo(b);
|
||||
v.PredivideBy(L);
|
||||
Console.WriteLine("v = {0}", v); // should be 2.8284, 1.633, 1.1547
|
||||
v.PredivideBy(L.Transpose());
|
||||
Console.WriteLine("v = {0}", v);
|
||||
Assert.True(v.MaxDiff(c) < TOLERANCE);
|
||||
|
||||
v.SetTo(b);
|
||||
|
@ -2242,14 +2187,14 @@ namespace Microsoft.ML.Probabilistic.Tests
|
|||
double VError = VExpected.MaxDiff(V);
|
||||
Matrix USExpected = UExpected * Matrix.FromDiagonal(SExpected);
|
||||
double USError = USExpected.MaxDiff(US);
|
||||
Console.WriteLine(StringUtil.JoinColumns("US = ", US.ToString("g17"), " expected ", USExpected.ToString("g17"), " error ", USError));
|
||||
Console.WriteLine(StringUtil.JoinColumns("U = ", U.ToString("g17"), " expected ", UExpected.ToString("g17"), " error ", UError));
|
||||
Console.WriteLine(StringUtil.JoinColumns("S = ", S, " expected ", SExpected, " error ", SError));
|
||||
Console.WriteLine(StringUtil.JoinColumns("V = ", V, " expected ", VExpected, " error ", VError));
|
||||
//Console.WriteLine(StringUtil.JoinColumns("US = ", US.ToString("g17"), " expected ", USExpected.ToString("g17"), " error ", USError));
|
||||
//Console.WriteLine(StringUtil.JoinColumns("U = ", U.ToString("g17"), " expected ", UExpected.ToString("g17"), " error ", UError));
|
||||
//Console.WriteLine(StringUtil.JoinColumns("S = ", S, " expected ", SExpected, " error ", SError));
|
||||
//Console.WriteLine(StringUtil.JoinColumns("V = ", V, " expected ", VExpected, " error ", VError));
|
||||
Matrix AExpected = UExpected * Matrix.FromDiagonal(SExpected) * VExpected.Transpose();
|
||||
Matrix USVActual = U * Matrix.FromDiagonal(S) * V.Transpose();
|
||||
Matrix AActual = US * V.Transpose();
|
||||
Console.WriteLine(StringUtil.JoinColumns("A = ", AActual.ToString("g17"), " expected ", AExpected.ToString("g17")));
|
||||
//Console.WriteLine(StringUtil.JoinColumns("A = ", AActual.ToString("g17"), " expected ", AExpected.ToString("g17")));
|
||||
Assert.True(UError < 1e-7);
|
||||
Assert.True(SError < 1e-10);
|
||||
Assert.True(VError < 1e-10);
|
||||
|
@ -2295,9 +2240,9 @@ namespace Microsoft.ML.Probabilistic.Tests
|
|||
{ 0 /* -0.60148066629825048 */, 0.608938144188165, 0.793217710690245 }
|
||||
});
|
||||
|
||||
Console.WriteLine(StringUtil.JoinColumns("U = ", U, " expected ", UExpected));
|
||||
Console.WriteLine(StringUtil.JoinColumns("S = ", S, " expected ", SExpected));
|
||||
Console.WriteLine(StringUtil.JoinColumns("V = ", V, " expected ", VExpected));
|
||||
//Console.WriteLine(StringUtil.JoinColumns("U = ", U, " expected ", UExpected));
|
||||
//Console.WriteLine(StringUtil.JoinColumns("S = ", S, " expected ", SExpected));
|
||||
//Console.WriteLine(StringUtil.JoinColumns("V = ", V, " expected ", VExpected));
|
||||
Assert.True(UExpected.MaxDiff(U) < 1e-10);
|
||||
Assert.True(SExpected.MaxDiff(S) < 1e-10);
|
||||
Assert.True(VExpected.MaxDiff(V) < 1e-10);
|
||||
|
@ -2307,7 +2252,6 @@ namespace Microsoft.ML.Probabilistic.Tests
|
|||
public void MatrixEigenvectorsSymmetricTest()
|
||||
{
|
||||
PositiveDefiniteMatrix A = new PositiveDefiniteMatrix(new double[,] { { 2, 1, 1 }, { 1, 2, 1 }, { 1, 1, 2 } });
|
||||
Console.WriteLine("A:\n{0}", A);
|
||||
PositiveDefiniteMatrix Aev;
|
||||
double[] eigenvaluesReal = new double[A.Rows];
|
||||
double[] eigenvaluesImag = new double[A.Rows];
|
||||
|
@ -2325,22 +2269,21 @@ namespace Microsoft.ML.Probabilistic.Tests
|
|||
Matrix eigenvectors = new Matrix(A.Rows, A.Cols);
|
||||
Aev = (PositiveDefiniteMatrix)A.Clone();
|
||||
eigenvectors.SetToEigenvectorsOfSymmetric(Aev);
|
||||
Console.WriteLine("eigenvectors as cols:\n{0}", eigenvectors);
|
||||
Console.WriteLine("eigenvalues:\n{0}", Aev);
|
||||
Matrix product = eigenvectors * Aev * eigenvectors.Transpose();
|
||||
Assert.True(product.MaxDiff(A) < TOLERANCE);
|
||||
|
||||
//A = new PositiveDefiniteMatrix(new double[,] { { 1, 5, 7 }, { 3, 0, 6 }, { 4, 3, 1 } });
|
||||
Aev = (PositiveDefiniteMatrix)A.Clone();
|
||||
Aev.EigenvaluesInPlace(eigenvaluesReal, eigenvaluesImag);
|
||||
Console.WriteLine("eigenvalues Real: {0}", StringUtil.CollectionToString(eigenvaluesReal, " "));
|
||||
Console.WriteLine("eigenvalues Imag: {0}", StringUtil.CollectionToString(eigenvaluesImag, " "));
|
||||
//Console.WriteLine("eigenvalues Real: {0}", StringUtil.CollectionToString(eigenvaluesReal, " "));
|
||||
//Console.WriteLine("eigenvalues Imag: {0}", StringUtil.CollectionToString(eigenvaluesImag, " "));
|
||||
// TODO: assertion
|
||||
|
||||
A.SetTo(new double[,] { { double.PositiveInfinity, 0, 0 }, { 0, 2, 1 }, { 0, 1, 2 } });
|
||||
Aev = (PositiveDefiniteMatrix)A.Clone();
|
||||
eigenvectors.SetToEigenvectorsOfSymmetric(Aev);
|
||||
Console.WriteLine("eigenvectors as cols:\n{0}", eigenvectors);
|
||||
Console.WriteLine("eigenvalues:\n{0}", Aev);
|
||||
//Console.WriteLine("eigenvectors as cols:\n{0}", eigenvectors);
|
||||
//Console.WriteLine("eigenvalues:\n{0}", Aev);
|
||||
}
|
||||
|
||||
// Test a case where balancing is required
|
||||
|
@ -2390,9 +2333,6 @@ namespace Microsoft.ML.Probabilistic.Tests
|
|||
double[] eigenvaluesImag = new double[A.Rows];
|
||||
var Aev = (Matrix)A.Clone();
|
||||
Aev.EigenvaluesInPlace(eigenvaluesReal, eigenvaluesImag);
|
||||
Console.WriteLine(Aev);
|
||||
Console.WriteLine("eigenvalues Real: {0}", StringUtil.CollectionToString(eigenvaluesReal, " "));
|
||||
Console.WriteLine("eigenvalues Imag: {0}", StringUtil.CollectionToString(eigenvaluesImag, " "));
|
||||
for (int i = 0; i < A.Rows; i++)
|
||||
{
|
||||
bool found = false;
|
||||
|
@ -2430,10 +2370,11 @@ namespace Microsoft.ML.Probabilistic.Tests
|
|||
{
|
||||
Matrix A = new Matrix(new double[,] { { 1, 2 }, { 3, 4 } });
|
||||
Matrix C = A.Kronecker(A);
|
||||
Console.WriteLine(C);
|
||||
//Console.WriteLine(C);
|
||||
// TODO: assertion
|
||||
|
||||
Matrix K = Matrix.Commutation(4, 3);
|
||||
Console.WriteLine(K);
|
||||
//Console.WriteLine(K);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,37 +3,24 @@
|
|||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
using Microsoft.ML.Probabilistic.Math;
|
||||
|
||||
using Xunit;
|
||||
|
||||
using Assert = Xunit.Assert;
|
||||
|
||||
namespace Microsoft.ML.Probabilistic.Tests
|
||||
{
|
||||
|
||||
public class RandomTests
|
||||
{
|
||||
public const double TOLERANCE = 4.0e-2;
|
||||
public const int nsamples = 100000;
|
||||
|
||||
/*
|
||||
[STAThread]
|
||||
public static void Main(string[] args)
|
||||
{
|
||||
RandUniform();
|
||||
RandNormal();
|
||||
RandGamma();
|
||||
RandNormal2();
|
||||
RandNormalP();
|
||||
RandWishart();
|
||||
Console.ReadKey();
|
||||
}
|
||||
*/
|
||||
|
||||
[Fact]
|
||||
public void RandUniform()
|
||||
public void RandSample_HasCorrectDistribution()
|
||||
{
|
||||
double error = 0.0;
|
||||
|
||||
// Uniform integers
|
||||
Vector hist = Vector.Zero(4);
|
||||
for (int i = 0; i < nsamples; i++)
|
||||
|
@ -42,31 +29,48 @@ namespace Microsoft.ML.Probabilistic.Tests
|
|||
hist[x]++;
|
||||
}
|
||||
|
||||
hist = hist*(1.0/nsamples);
|
||||
Console.WriteLine("[0.25,0.25,0.25,0.25]: {0}", hist);
|
||||
hist *= (1.0 / nsamples);
|
||||
Vector unif = Vector.Constant(4, 0.25);
|
||||
error = hist.MaxDiff(unif);
|
||||
double error = hist.MaxDiff(unif);
|
||||
if (error > TOLERANCE)
|
||||
{
|
||||
Assert.True(false, String.Format("Uniform: error={0}", error));
|
||||
Assert.True(false, $"Uniform: error={error}");
|
||||
}
|
||||
|
||||
hist.SetAllElementsTo(0);
|
||||
double[] init1 = new double[] {0.1, 0.2, 0.3, 0.4};
|
||||
double[] init1 = new double[] { 0.1, 0.2, 0.3, 0.4 };
|
||||
Vector p = Vector.FromArray(init1);
|
||||
for (int i = 0; i < nsamples; i++)
|
||||
{
|
||||
int x = Rand.Sample(p);
|
||||
hist[x]++;
|
||||
}
|
||||
hist = hist*(1.0/nsamples);
|
||||
Console.WriteLine("\n[0.1,0.2,0.3,0.4]: {0}", hist);
|
||||
hist *= (1.0 / nsamples);
|
||||
error = hist.MaxDiff(p);
|
||||
if (error > TOLERANCE)
|
||||
{
|
||||
Assert.True(false, String.Format("Sample([0.1,0.2,0.3,0.4]) error={0}", error));
|
||||
Assert.True(false, $"Sample([0.1,0.2,0.3,0.4]) error={error}");
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RandSample_NeverDrawsZero()
|
||||
{
|
||||
const int nsamples = 1_000_000;
|
||||
double[] init1 = new double[] { 0, double.Epsilon };
|
||||
Vector p = Vector.FromArray(init1);
|
||||
for (int i = 0; i < nsamples; i++)
|
||||
{
|
||||
int x = Rand.Sample(p);
|
||||
Assert.Equal(1, x);
|
||||
x = Rand.Sample((IList<double>)p, p[1]);
|
||||
Assert.Equal(1, x);
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RandRestart()
|
||||
{
|
||||
Rand.Restart(7);
|
||||
double first = Rand.Double();
|
||||
Rand.Restart(7);
|
||||
|
@ -82,22 +86,22 @@ namespace Microsoft.ML.Probabilistic.Tests
|
|||
{
|
||||
double x = Rand.Normal();
|
||||
sum += x;
|
||||
sum2 += x*x;
|
||||
sum2 += x * x;
|
||||
}
|
||||
double m = sum/nsamples;
|
||||
double v = sum2/nsamples - m*m;
|
||||
double m = sum / nsamples;
|
||||
double v = sum2 / nsamples - m * m;
|
||||
// the sample mean has stddev = 1/sqrt(n)
|
||||
double dError = System.Math.Abs(m);
|
||||
if (dError > 4/ System.Math.Sqrt(nsamples))
|
||||
if (dError > 4 / System.Math.Sqrt(nsamples))
|
||||
{
|
||||
Assert.True(false, string.Format("m: error = {0}", dError));
|
||||
Assert.True(false, $"m: error = {dError}");
|
||||
}
|
||||
|
||||
// the sample variance is Gamma(n/2,n/2) whose stddev = sqrt(2/n)
|
||||
dError = System.Math.Abs(v - 1.0);
|
||||
if (dError > 4* System.Math.Sqrt(2.0/ nsamples))
|
||||
if (dError > 4 * System.Math.Sqrt(2.0 / nsamples))
|
||||
{
|
||||
Assert.True(false, string.Format("v: error = {0}", dError));
|
||||
Assert.True(false, $"v: error = {dError}");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -116,8 +120,7 @@ namespace Microsoft.ML.Probabilistic.Tests
|
|||
|
||||
private void RandNormalGreaterThan(double lowerBound)
|
||||
{
|
||||
double meanExpected, varianceExpected;
|
||||
new Microsoft.ML.Probabilistic.Distributions.TruncatedGaussian(0, 1, lowerBound, double.PositiveInfinity).GetMeanAndVariance(out meanExpected, out varianceExpected);
|
||||
new Probabilistic.Distributions.TruncatedGaussian(0, 1, lowerBound, double.PositiveInfinity).GetMeanAndVariance(out double meanExpected, out double varianceExpected);
|
||||
|
||||
MeanVarianceAccumulator mva = new MeanVarianceAccumulator();
|
||||
for (int i = 0; i < nsamples; i++)
|
||||
|
@ -127,20 +130,18 @@ namespace Microsoft.ML.Probabilistic.Tests
|
|||
}
|
||||
double m = mva.Mean;
|
||||
double v = mva.Variance;
|
||||
Console.WriteLine("mean = {0} should be {1}", m, meanExpected);
|
||||
Console.WriteLine("variance = {0} should be {1}", v, varianceExpected);
|
||||
// the sample mean has stddev = 1/sqrt(n)
|
||||
double dError = System.Math.Abs(m - meanExpected);
|
||||
if (dError > 4/ System.Math.Sqrt(nsamples))
|
||||
if (dError > 4 / System.Math.Sqrt(nsamples))
|
||||
{
|
||||
Assert.True(false, string.Format("m: error = {0}", dError));
|
||||
Assert.True(false, $"m: error = {dError}");
|
||||
}
|
||||
|
||||
// the sample variance is Gamma(n/2,n/2) whose stddev = sqrt(2/n)
|
||||
dError = System.Math.Abs(v - varianceExpected);
|
||||
if (dError > 4* System.Math.Sqrt(2.0/ nsamples))
|
||||
if (dError > 4 * System.Math.Sqrt(2.0 / nsamples))
|
||||
{
|
||||
Assert.True(false, string.Format("v: error = {0}", dError));
|
||||
Assert.True(false, $"v: error = {dError}");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -156,8 +157,7 @@ namespace Microsoft.ML.Probabilistic.Tests
|
|||
|
||||
private void RandNormalBetween(double lowerBound, double upperBound)
|
||||
{
|
||||
double meanExpected, varianceExpected;
|
||||
new Microsoft.ML.Probabilistic.Distributions.TruncatedGaussian(0, 1, lowerBound, upperBound).GetMeanAndVariance(out meanExpected, out varianceExpected);
|
||||
new Probabilistic.Distributions.TruncatedGaussian(0, 1, lowerBound, upperBound).GetMeanAndVariance(out double meanExpected, out double varianceExpected);
|
||||
|
||||
MeanVarianceAccumulator mva = new MeanVarianceAccumulator();
|
||||
for (int i = 0; i < nsamples; i++)
|
||||
|
@ -167,20 +167,18 @@ namespace Microsoft.ML.Probabilistic.Tests
|
|||
}
|
||||
double m = mva.Mean;
|
||||
double v = mva.Variance;
|
||||
Console.WriteLine("mean = {0} should be {1}", m, meanExpected);
|
||||
Console.WriteLine("variance = {0} should be {1}", v, varianceExpected);
|
||||
// the sample mean has stddev = 1/sqrt(n)
|
||||
double dError = System.Math.Abs(m - meanExpected);
|
||||
if (dError > 4/ System.Math.Sqrt(nsamples))
|
||||
if (dError > 4 / System.Math.Sqrt(nsamples))
|
||||
{
|
||||
Assert.True(false, string.Format("m: error = {0}", dError));
|
||||
Assert.True(false, $"m: error = {dError}");
|
||||
}
|
||||
|
||||
// the sample variance is Gamma(n/2,n/2) whose stddev = sqrt(2/n)
|
||||
dError = System.Math.Abs(v - varianceExpected);
|
||||
if (dError > 4* System.Math.Sqrt(2.0/ nsamples))
|
||||
if (dError > 4 * System.Math.Sqrt(2.0 / nsamples))
|
||||
{
|
||||
Assert.True(false, string.Format("v: error = {0}", dError));
|
||||
Assert.True(false, $"v: error = {dError}");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -199,33 +197,32 @@ namespace Microsoft.ML.Probabilistic.Tests
|
|||
{
|
||||
double x = Rand.Gamma(a);
|
||||
sum += x;
|
||||
sum2 += x*x;
|
||||
sum2 += x * x;
|
||||
}
|
||||
double m = sum/nsamples;
|
||||
double v = sum2/nsamples - m*m;
|
||||
Console.WriteLine("Gamma({2}) mean: {0} variance: {1}", m, v, a);
|
||||
double m = sum / nsamples;
|
||||
double v = sum2 / nsamples - m * m;
|
||||
|
||||
// sample mean has stddev = sqrt(a/n)
|
||||
double dError = System.Math.Abs(m - a);
|
||||
if (dError > 4* System.Math.Sqrt(a / nsamples))
|
||||
if (dError > 4 * System.Math.Sqrt(a / nsamples))
|
||||
{
|
||||
Assert.True(false, string.Format("m: error = {0}", dError));
|
||||
Assert.True(false, $"m: error = {dError}");
|
||||
}
|
||||
|
||||
dError = System.Math.Abs(v - a);
|
||||
if (dError > TOLERANCE)
|
||||
{
|
||||
Assert.True(false, String.Format("v: error = {0}", dError));
|
||||
Assert.True(false, $"v: error = {dError}");
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RandNormal2()
|
||||
{
|
||||
double[] m_init = {1, 2, 3};
|
||||
double[] m_init = { 1, 2, 3 };
|
||||
Vector mt = Vector.FromArray(m_init);
|
||||
|
||||
double[,] v_init = {{2, 1, 1}, {1, 2, 1}, {1, 1, 2}};
|
||||
double[,] v_init = { { 2, 1, 1 }, { 1, 2, 1 }, { 1, 1, 2 } };
|
||||
PositiveDefiniteMatrix vt = new PositiveDefiniteMatrix(v_init);
|
||||
|
||||
int d = mt.Count;
|
||||
|
@ -238,35 +235,28 @@ namespace Microsoft.ML.Probabilistic.Tests
|
|||
}
|
||||
Vector m = mva.Mean;
|
||||
Matrix v = mva.Variance;
|
||||
|
||||
Console.WriteLine("");
|
||||
Console.WriteLine("Multivariate Normal");
|
||||
Console.WriteLine("-------------------");
|
||||
|
||||
Console.WriteLine("m = {0}", m);
|
||||
double dError = m.MaxDiff(mt);
|
||||
if (dError > TOLERANCE)
|
||||
{
|
||||
Assert.True(false, String.Format("m: error = {0}", dError));
|
||||
Assert.True(false, $"m: error = {dError}");
|
||||
}
|
||||
|
||||
Console.WriteLine("v = \n{0}", v);
|
||||
dError = v.MaxDiff(vt);
|
||||
if (dError > TOLERANCE)
|
||||
{
|
||||
Assert.True(false, String.Format("v: error = {0}", dError));
|
||||
Assert.True(false, $"v: error = {dError}");
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void RandNormalP()
|
||||
{
|
||||
double[] m_init = {1, 2, 3};
|
||||
double[] m_init = { 1, 2, 3 };
|
||||
Vector mt = Vector.FromArray(m_init);
|
||||
|
||||
double[,] v_init = {{2, 1, 1}, {1, 2, 1}, {1, 1, 2}};
|
||||
double[,] v_init = { { 2, 1, 1 }, { 1, 2, 1 }, { 1, 1, 2 } };
|
||||
PositiveDefiniteMatrix vt = new PositiveDefiniteMatrix(v_init);
|
||||
PositiveDefiniteMatrix pt = ((PositiveDefiniteMatrix) vt.Clone()).SetToInverse(vt);
|
||||
PositiveDefiniteMatrix pt = ((PositiveDefiniteMatrix)vt.Clone()).SetToInverse(vt);
|
||||
|
||||
int d = mt.Count;
|
||||
Vector x = Vector.Zero(d);
|
||||
|
@ -279,22 +269,16 @@ namespace Microsoft.ML.Probabilistic.Tests
|
|||
Vector m = mva.Mean;
|
||||
PositiveDefiniteMatrix v = mva.Variance;
|
||||
|
||||
Console.WriteLine("");
|
||||
Console.WriteLine("Multivariate NormalP");
|
||||
Console.WriteLine("--------------------");
|
||||
|
||||
Console.WriteLine("m = {0}", m);
|
||||
double dError = m.MaxDiff(mt);
|
||||
if (dError > TOLERANCE)
|
||||
{
|
||||
Assert.True(false, String.Format("m: error = {0}", dError));
|
||||
Assert.True(false, $"m: error = {dError}");
|
||||
}
|
||||
|
||||
Console.WriteLine("v = \n{0}", v);
|
||||
dError = v.MaxDiff(vt);
|
||||
if (dError > TOLERANCE)
|
||||
{
|
||||
Assert.True(false, String.Format("v: error = {0}", dError));
|
||||
Assert.True(false, $"v: error = {dError}");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -316,27 +300,22 @@ namespace Microsoft.ML.Probabilistic.Tests
|
|||
{
|
||||
Rand.Wishart(a, L);
|
||||
X.SetToProduct(L, L.Transpose());
|
||||
m = m + X;
|
||||
s = s + X.LogDeterminant();
|
||||
m += X;
|
||||
s += X.LogDeterminant();
|
||||
}
|
||||
double sTrue = 0;
|
||||
for (int i = 0; i < d; i++) sTrue += MMath.Digamma(a - i*0.5);
|
||||
m.Scale(1.0/nsamples);
|
||||
s = s/nsamples;
|
||||
for (int i = 0; i < d; i++) sTrue += MMath.Digamma(a - i * 0.5);
|
||||
m.Scale(1.0 / nsamples);
|
||||
s /= nsamples;
|
||||
|
||||
Console.WriteLine("");
|
||||
Console.WriteLine("Multivariate Gamma");
|
||||
Console.WriteLine("-------------------");
|
||||
|
||||
Console.WriteLine("m = \n{0}", m);
|
||||
double dError = m.MaxDiff(mTrue);
|
||||
if (dError > TOLERANCE)
|
||||
{
|
||||
Assert.True(false, String.Format("Wishart({0}) mean: (should be {0}*I), error = {1}", a, dError));
|
||||
Assert.True(false, $"Wishart({a}) mean: (should be {a}*I), error = {dError}");
|
||||
}
|
||||
if (System.Math.Abs(s - sTrue) > TOLERANCE)
|
||||
{
|
||||
Assert.True(false, string.Format("E[logdet]: {0} (should be {1})", s, sTrue));
|
||||
Assert.True(false, $"E[logdet]: {s} (should be {sTrue})");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -354,27 +333,27 @@ namespace Microsoft.ML.Probabilistic.Tests
|
|||
|
||||
private void RandBinomial(double p, int n)
|
||||
{
|
||||
double meanExpected = p*n;
|
||||
double varianceExpected = p*(1 - p)*n;
|
||||
double meanExpected = p * n;
|
||||
double varianceExpected = p * (1 - p) * n;
|
||||
double sum = 0;
|
||||
double sum2 = 0;
|
||||
for (int i = 0; i < nsamples; i++)
|
||||
{
|
||||
double x = Rand.Binomial(n, p);
|
||||
sum += x;
|
||||
sum2 += x*x;
|
||||
sum2 += x * x;
|
||||
}
|
||||
double mean = sum/nsamples;
|
||||
double variance = sum2/nsamples - mean*mean;
|
||||
double mean = sum / nsamples;
|
||||
double variance = sum2 / nsamples - mean * mean;
|
||||
double error = MMath.AbsDiff(meanExpected, mean, 1e-6);
|
||||
if (error > System.Math.Sqrt(varianceExpected) *5)
|
||||
if (error > System.Math.Sqrt(varianceExpected) * 5)
|
||||
{
|
||||
Assert.True(false, string.Format("Binomial({0},{1}) mean = {2} should be {3}, error = {4}", p, n, mean, meanExpected, error));
|
||||
Assert.True(false, $"Binomial({p},{n}) mean = {mean} should be {meanExpected}, error = {error}");
|
||||
}
|
||||
error = MMath.AbsDiff(varianceExpected, variance, 1e-6);
|
||||
if (error > System.Math.Sqrt(varianceExpected) *5)
|
||||
if (error > System.Math.Sqrt(varianceExpected) * 5)
|
||||
{
|
||||
Assert.True(false, string.Format("Binomial({0},{1}) variance = {2} should be {3}, error = {4}", p, n, variance, varianceExpected, error));
|
||||
Assert.True(false, $"Binomial({p},{n}) variance = {variance} should be {varianceExpected}, error = {error}");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -394,8 +373,8 @@ namespace Microsoft.ML.Probabilistic.Tests
|
|||
|
||||
private void RandMultinomial(DenseVector p, int n)
|
||||
{
|
||||
Vector meanExpected = p*n;
|
||||
Vector varianceExpected = p*(1 - p)*n;
|
||||
Vector meanExpected = p * n;
|
||||
Vector varianceExpected = p * (1 - p) * n;
|
||||
DenseVector sum = DenseVector.Zero(p.Count);
|
||||
DenseVector sum2 = DenseVector.Zero(p.Count);
|
||||
for (int i = 0; i < nsamples; i++)
|
||||
|
@ -404,18 +383,18 @@ namespace Microsoft.ML.Probabilistic.Tests
|
|||
for (int dim = 0; dim < x.Length; dim++)
|
||||
{
|
||||
sum[dim] += x[dim];
|
||||
sum2[dim] += x[dim]*x[dim];
|
||||
sum2[dim] += x[dim] * x[dim];
|
||||
}
|
||||
}
|
||||
Vector mean = sum*(1.0/nsamples);
|
||||
Vector variance = sum2*(1.0/nsamples) - mean*mean;
|
||||
Vector mean = sum * (1.0 / nsamples);
|
||||
Vector variance = sum2 * (1.0 / nsamples) - mean * mean;
|
||||
for (int dim = 0; dim < p.Count; dim++)
|
||||
{
|
||||
double error = MMath.AbsDiff(meanExpected[dim], mean[dim], 1e-6);
|
||||
Console.WriteLine("Multinomial({0},{1}) mean[{5}] = {2} should be {3}, error = {4}", p, n, mean[dim], meanExpected[dim], error, dim);
|
||||
////Console.WriteLine("Multinomial({0},{1}) mean[{5}] = {2} should be {3}, error = {4}", p, n, mean[dim], meanExpected[dim], error, dim);
|
||||
Assert.True(error < TOLERANCE);
|
||||
error = MMath.AbsDiff(varianceExpected[dim], variance[dim], 1e-6);
|
||||
Console.WriteLine("Multinomial({0},{1}) variance[{5}] = {2} should be {3}, error = {4}", p, n, variance[dim], varianceExpected[dim], error, dim);
|
||||
////Console.WriteLine("Multinomial({0},{1}) variance[{5}] = {2} should be {3}, error = {4}", p, n, variance[dim], varianceExpected[dim], error, dim);
|
||||
Assert.True(error < TOLERANCE);
|
||||
}
|
||||
}
|
||||
|
@ -425,7 +404,7 @@ namespace Microsoft.ML.Probabilistic.Tests
|
|||
{
|
||||
Assert.Throws<ArgumentException>(() =>
|
||||
{
|
||||
Rand.Int(9, 9);
|
||||
Rand.Int(9, 9);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче