mirror of
https://github.com/furyfire/trueskill.git
synced 2025-01-16 01:47:39 +00:00
Fixed a rounding bug in the Matrix GetHashCode that would cause matrices that were deemed equal to not have the same hash code
This commit is contained in:
@ -9,6 +9,10 @@ namespace Moserware.Numerics
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
internal class Matrix
|
internal class Matrix
|
||||||
{
|
{
|
||||||
|
// Anything smaller than this will be assumed to be rounding error in terms of equality matching
|
||||||
|
private const int FractionalDigitsToRoundTo = 10;
|
||||||
|
private static readonly double ErrorTolerance = Math.Pow(0.1, FractionalDigitsToRoundTo); // e.g. 1/10^10
|
||||||
|
|
||||||
protected double[][] _MatrixRowValues;
|
protected double[][] _MatrixRowValues;
|
||||||
// Note: some properties like Determinant, Inverse, etc are properties instead
|
// Note: some properties like Determinant, Inverse, etc are properties instead
|
||||||
// of methods to make the syntax look nicer even though this sort of goes against
|
// of methods to make the syntax look nicer even though this sort of goes against
|
||||||
@ -386,9 +390,7 @@ namespace Moserware.Numerics
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
const double errorTolerance = 0.0000000000001;
|
|
||||||
|
|
||||||
for (int currentRow = 0; currentRow < a.Rows; currentRow++)
|
for (int currentRow = 0; currentRow < a.Rows; currentRow++)
|
||||||
{
|
{
|
||||||
for (int currentColumn = 0; currentColumn < a.Columns; currentColumn++)
|
for (int currentColumn = 0; currentColumn < a.Columns; currentColumn++)
|
||||||
@ -397,7 +399,7 @@ namespace Moserware.Numerics
|
|||||||
Math.Abs(a._MatrixRowValues[currentRow][currentColumn] -
|
Math.Abs(a._MatrixRowValues[currentRow][currentColumn] -
|
||||||
b._MatrixRowValues[currentRow][currentColumn]);
|
b._MatrixRowValues[currentRow][currentColumn]);
|
||||||
|
|
||||||
if (delta > errorTolerance)
|
if (delta > ErrorTolerance)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -426,7 +428,9 @@ namespace Moserware.Numerics
|
|||||||
|
|
||||||
for (int currentColumn = 0; currentColumn < Columns; currentColumn++)
|
for (int currentColumn = 0; currentColumn < Columns; currentColumn++)
|
||||||
{
|
{
|
||||||
result += multiplier*_MatrixRowValues[currentRow][currentColumn];
|
double cellValue = _MatrixRowValues[currentRow][currentColumn];
|
||||||
|
double roundedValue = Math.Round(cellValue, FractionalDigitsToRoundTo);
|
||||||
|
result += multiplier*roundedValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -443,7 +447,7 @@ namespace Moserware.Numerics
|
|||||||
int hashCode = BitConverter.ToInt32(finalBytes, 0);
|
int hashCode = BitConverter.ToInt32(finalBytes, 0);
|
||||||
return hashCode;
|
return hashCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool Equals(object obj)
|
public override bool Equals(object obj)
|
||||||
{
|
{
|
||||||
var other = obj as Matrix;
|
var other = obj as Matrix;
|
||||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -121,6 +121,16 @@ namespace UnitTests.Numerics
|
|||||||
Assert.AreEqual(d, f);
|
Assert.AreEqual(d, f);
|
||||||
Assert.AreEqual(d.GetHashCode(), f.GetHashCode());
|
Assert.AreEqual(d.GetHashCode(), f.GetHashCode());
|
||||||
|
|
||||||
|
// Test rounding (thanks to nsp on GitHub for finding this case)
|
||||||
|
var g = new SquareMatrix(1, 2.00000000000001,
|
||||||
|
3, 4);
|
||||||
|
|
||||||
|
var h = new SquareMatrix(1, 2,
|
||||||
|
3, 4);
|
||||||
|
|
||||||
|
Assert.IsTrue(g == h);
|
||||||
|
Assert.AreEqual(g, h);
|
||||||
|
Assert.AreEqual(g.GetHashCode(), h.GetHashCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
Reference in New Issue
Block a user