diff --git a/src/Numerics/LinearAlgebra/Complex/DiagonalMatrix.cs b/src/Numerics/LinearAlgebra/Complex/DiagonalMatrix.cs index dd9d7885..d463e5d8 100644 --- a/src/Numerics/LinearAlgebra/Complex/DiagonalMatrix.cs +++ b/src/Numerics/LinearAlgebra/Complex/DiagonalMatrix.cs @@ -189,59 +189,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex return new SparseVector(size); } - /// - /// Indicates whether the current object is equal to another object of the same type. - /// - /// - /// An object to compare with this object. - /// - /// - /// true if the current object is equal to the parameter; otherwise, false. - /// - public override bool Equals(object obj) - { - var diagonalMatrix = obj as DiagonalMatrix; - - if (diagonalMatrix == null) - { - return base.Equals(obj); - } - - // Accept if the argument is the same object as this - if (ReferenceEquals(this, diagonalMatrix)) - { - return true; - } - - if (diagonalMatrix._data.Length != _data.Length) - { - return false; - } - - // If all else fails, perform element wise comparison. - return !_data.Where((t, i) => t != diagonalMatrix._data[i]).Any(); - } - - /// - /// Returns a hash code for this instance. - /// - /// - /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. - /// - public override int GetHashCode() - { - var hashNum = Math.Min(_data.Length, 25); - int hash = 17; - unchecked - { - for (var i = 0; i < hashNum; i++) - { - hash = hash*31 + _data[i].GetHashCode(); - } - } - return hash; - } - #region Elementary operations /// diff --git a/src/Numerics/LinearAlgebra/Complex/SparseMatrix.cs b/src/Numerics/LinearAlgebra/Complex/SparseMatrix.cs index 48dd3926..4dd867fb 100644 --- a/src/Numerics/LinearAlgebra/Complex/SparseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Complex/SparseMatrix.cs @@ -588,27 +588,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex return ret; } - /// - /// Returns a hash code for this instance. - /// - /// - /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. - /// - public override int GetHashCode() - { - var values = _storage.Values; - var hashNum = Math.Min(_storage.ValueCount, 25); - int hash = 17; - unchecked - { - for (var i = 0; i < hashNum; i++) - { - hash = hash*31 + values[i].GetHashCode(); - } - } - return hash; - } - /// /// Returns the transpose of this matrix. /// @@ -867,57 +846,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex } #endregion - /// - /// Indicates whether the current object is equal to another object of the same type. - /// - /// - /// An object to compare with this object. - /// - /// - /// true if the current object is equal to the parameter; otherwise, false. - /// - public override bool Equals(Matrix other) - { - if (other == null) - { - return false; - } - - if (ColumnCount != other.ColumnCount || RowCount != other.RowCount) - { - return false; - } - - // Accept if the argument is the same object as this. - if (ReferenceEquals(this, other)) - { - return true; - } - - var sparseMatrix = other as SparseMatrix; - if (sparseMatrix == null) - { - return base.Equals(other); - } - - var otherStorage = sparseMatrix.Raw; - if (_storage.ValueCount != otherStorage.ValueCount) - { - return false; - } - - // If all else fails, perform element wise comparison. - for (var index = 0; index < _storage.ValueCount; index++) - { - if (!_storage.Values[index].AlmostEqual(otherStorage.Values[index]) || _storage.ColumnIndices[index] != otherStorage.ColumnIndices[index]) - { - return false; - } - } - - return true; - } - /// /// Adds another matrix to this matrix. /// diff --git a/src/Numerics/LinearAlgebra/Complex32/DiagonalMatrix.cs b/src/Numerics/LinearAlgebra/Complex32/DiagonalMatrix.cs index fac1a33b..34fa4184 100644 --- a/src/Numerics/LinearAlgebra/Complex32/DiagonalMatrix.cs +++ b/src/Numerics/LinearAlgebra/Complex32/DiagonalMatrix.cs @@ -189,59 +189,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 return new SparseVector(size); } - /// - /// Indicates whether the current object is equal to another object of the same type. - /// - /// - /// An object to compare with this object. - /// - /// - /// true if the current object is equal to the parameter; otherwise, false. - /// - public override bool Equals(object obj) - { - var diagonalMatrix = obj as DiagonalMatrix; - - if (diagonalMatrix == null) - { - return base.Equals(obj); - } - - // Accept if the argument is the same object as this - if (ReferenceEquals(this, diagonalMatrix)) - { - return true; - } - - if (diagonalMatrix._data.Length != _data.Length) - { - return false; - } - - // If all else fails, perform element wise comparison. - return !_data.Where((t, i) => t != diagonalMatrix._data[i]).Any(); - } - - /// - /// Returns a hash code for this instance. - /// - /// - /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. - /// - public override int GetHashCode() - { - var hashNum = Math.Min(_data.Length, 25); - int hash = 17; - unchecked - { - for (var i = 0; i < hashNum; i++) - { - hash = hash*31 + _data[i].GetHashCode(); - } - } - return hash; - } - #region Elementary operations /// diff --git a/src/Numerics/LinearAlgebra/Complex32/SparseMatrix.cs b/src/Numerics/LinearAlgebra/Complex32/SparseMatrix.cs index be05bce5..224b7b2c 100644 --- a/src/Numerics/LinearAlgebra/Complex32/SparseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Complex32/SparseMatrix.cs @@ -588,27 +588,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 return ret; } - /// - /// Returns a hash code for this instance. - /// - /// - /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. - /// - public override int GetHashCode() - { - var values = _storage.Values; - var hashNum = Math.Min(_storage.ValueCount, 25); - int hash = 17; - unchecked - { - for (var i = 0; i < hashNum; i++) - { - hash = hash*31 + values[i].GetHashCode(); - } - } - return hash; - } - /// /// Returns the transpose of this matrix. /// @@ -867,57 +846,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 } #endregion - /// - /// Indicates whether the current object is equal to another object of the same type. - /// - /// - /// An object to compare with this object. - /// - /// - /// true if the current object is equal to the parameter; otherwise, false. - /// - public override bool Equals(Matrix other) - { - if (other == null) - { - return false; - } - - if (ColumnCount != other.ColumnCount || RowCount != other.RowCount) - { - return false; - } - - // Accept if the argument is the same object as this. - if (ReferenceEquals(this, other)) - { - return true; - } - - var sparseMatrix = other as SparseMatrix; - if (sparseMatrix == null) - { - return base.Equals(other); - } - - var otherStorage = sparseMatrix.Raw; - if (_storage.ValueCount != otherStorage.ValueCount) - { - return false; - } - - // If all else fails, perform element wise comparison. - for (var index = 0; index < _storage.ValueCount; index++) - { - if (!_storage.Values[index].AlmostEqual(otherStorage.Values[index]) || _storage.ColumnIndices[index] != otherStorage.ColumnIndices[index]) - { - return false; - } - } - - return true; - } - /// /// Adds another matrix to this matrix. /// diff --git a/src/Numerics/LinearAlgebra/Double/DiagonalMatrix.cs b/src/Numerics/LinearAlgebra/Double/DiagonalMatrix.cs index f43217f6..5832e075 100644 --- a/src/Numerics/LinearAlgebra/Double/DiagonalMatrix.cs +++ b/src/Numerics/LinearAlgebra/Double/DiagonalMatrix.cs @@ -188,59 +188,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double return new SparseVector(size); } - /// - /// Indicates whether the current object is equal to another object of the same type. - /// - /// - /// An object to compare with this object. - /// - /// - /// true if the current object is equal to the parameter; otherwise, false. - /// - public override bool Equals(object obj) - { - var diagonalMatrix = obj as DiagonalMatrix; - - if (diagonalMatrix == null) - { - return base.Equals(obj); - } - - // Accept if the argument is the same object as this - if (ReferenceEquals(this, diagonalMatrix)) - { - return true; - } - - if (diagonalMatrix._data.Length != _data.Length) - { - return false; - } - - // If all else fails, perform element wise comparison. - return !_data.Where((t, i) => t != diagonalMatrix._data[i]).Any(); - } - - /// - /// Returns a hash code for this instance. - /// - /// - /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. - /// - public override int GetHashCode() - { - var hashNum = Math.Min(_data.Length, 25); - int hash = 17; - unchecked - { - for (var i = 0; i < hashNum; i++) - { - hash = hash*31 + _data[i].GetHashCode(); - } - } - return hash; - } - #region Elementary operations /// diff --git a/src/Numerics/LinearAlgebra/Double/SparseMatrix.cs b/src/Numerics/LinearAlgebra/Double/SparseMatrix.cs index 1e702faa..dc7ead37 100644 --- a/src/Numerics/LinearAlgebra/Double/SparseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Double/SparseMatrix.cs @@ -587,27 +587,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double return ret; } - /// - /// Returns a hash code for this instance. - /// - /// - /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. - /// - public override int GetHashCode() - { - var values = _storage.Values; - var hashNum = Math.Min(_storage.ValueCount, 25); - int hash = 17; - unchecked - { - for (var i = 0; i < hashNum; i++) - { - hash = hash*31 + values[i].GetHashCode(); - } - } - return hash; - } - /// /// Returns the transpose of this matrix. /// @@ -865,57 +844,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double } #endregion - /// - /// Indicates whether the current object is equal to another object of the same type. - /// - /// - /// An object to compare with this object. - /// - /// - /// true if the current object is equal to the parameter; otherwise, false. - /// - public override bool Equals(Matrix other) - { - if (other == null) - { - return false; - } - - if (ColumnCount != other.ColumnCount || RowCount != other.RowCount) - { - return false; - } - - // Accept if the argument is the same object as this. - if (ReferenceEquals(this, other)) - { - return true; - } - - var sparseMatrix = other as SparseMatrix; - if (sparseMatrix == null) - { - return base.Equals(other); - } - - var otherStorage = sparseMatrix.Raw; - if (_storage.ValueCount != otherStorage.ValueCount) - { - return false; - } - - // If all else fails, perform element wise comparison. - for (var index = 0; index < _storage.ValueCount; index++) - { - if (!_storage.Values[index].AlmostEqual(otherStorage.Values[index]) || _storage.ColumnIndices[index] != otherStorage.ColumnIndices[index]) - { - return false; - } - } - - return true; - } - /// /// Adds another matrix to this matrix. /// diff --git a/src/Numerics/LinearAlgebra/Generic/Matrix.cs b/src/Numerics/LinearAlgebra/Generic/Matrix.cs index 276fa18d..eeb4edb4 100644 --- a/src/Numerics/LinearAlgebra/Generic/Matrix.cs +++ b/src/Numerics/LinearAlgebra/Generic/Matrix.cs @@ -221,7 +221,7 @@ namespace MathNet.Numerics.LinearAlgebra.Generic public virtual Matrix Clone() { var result = CreateMatrix(RowCount, ColumnCount); - CopyTo(result); + Storage.CopyTo(result.Storage); return result; } @@ -1331,38 +1331,14 @@ namespace MathNet.Numerics.LinearAlgebra.Generic /// /// true if the current object is equal to the parameter; otherwise, false. /// - public virtual bool Equals(Matrix other) + public bool Equals(Matrix other) { - // Reject equality when the argument is null or has a different shape. if (other == null) { return false; } - if (ColumnCount != other.ColumnCount || RowCount != other.RowCount) - { - return false; - } - - // Accept if the argument is the same object as this. - if (ReferenceEquals(this, other)) - { - return true; - } - - // If all else fails, perform element wise comparison. - for (var row = 0; row < RowCount; row++) - { - for (var column = 0; column < ColumnCount; column++) - { - if (!At(row, column).Equals(other.At(row, column))) - { - return false; - } - } - } - - return true; + return Storage.Equals(other.Storage); } #endregion @@ -1419,7 +1395,8 @@ namespace MathNet.Numerics.LinearAlgebra.Generic /// public override bool Equals(object obj) { - return Equals(obj as Matrix); + var other = obj as Matrix; + return other != null && Storage.Equals(other.Storage); } /// @@ -1430,18 +1407,7 @@ namespace MathNet.Numerics.LinearAlgebra.Generic /// public override int GetHashCode() { - var hashNum = Math.Min(RowCount*ColumnCount, 25); - int hash = 17; - unchecked - { - for (var i = 0; i < hashNum; i++) - { - var col = i%ColumnCount; - var row = (i - col)/RowCount; - hash = hash*31 + At(row, col).GetHashCode(); - } - } - return hash; + return Storage.GetHashCode(); } #endregion diff --git a/src/Numerics/LinearAlgebra/Single/DiagonalMatrix.cs b/src/Numerics/LinearAlgebra/Single/DiagonalMatrix.cs index 41d84eda..f43e28b5 100644 --- a/src/Numerics/LinearAlgebra/Single/DiagonalMatrix.cs +++ b/src/Numerics/LinearAlgebra/Single/DiagonalMatrix.cs @@ -188,59 +188,6 @@ namespace MathNet.Numerics.LinearAlgebra.Single return new SparseVector(size); } - /// - /// Indicates whether the current object is equal to another object of the same type. - /// - /// - /// An object to compare with this object. - /// - /// - /// true if the current object is equal to the parameter; otherwise, false. - /// - public override bool Equals(object obj) - { - var diagonalMatrix = obj as DiagonalMatrix; - - if (diagonalMatrix == null) - { - return base.Equals(obj); - } - - // Accept if the argument is the same object as this - if (ReferenceEquals(this, diagonalMatrix)) - { - return true; - } - - if (diagonalMatrix._data.Length != _data.Length) - { - return false; - } - - // If all else fails, perform element wise comparison. - return !_data.Where((t, i) => t != diagonalMatrix._data[i]).Any(); - } - - /// - /// Returns a hash code for this instance. - /// - /// - /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. - /// - public override int GetHashCode() - { - var hashNum = Math.Min(_data.Length, 25); - int hash = 17; - unchecked - { - for (var i = 0; i < hashNum; i++) - { - hash = hash*31 + _data[i].GetHashCode(); - } - } - return hash; - } - #region Elementary operations /// diff --git a/src/Numerics/LinearAlgebra/Single/SparseMatrix.cs b/src/Numerics/LinearAlgebra/Single/SparseMatrix.cs index 60719210..7aa3bcfc 100644 --- a/src/Numerics/LinearAlgebra/Single/SparseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Single/SparseMatrix.cs @@ -586,27 +586,6 @@ namespace MathNet.Numerics.LinearAlgebra.Single return ret; } - - /// - /// Returns a hash code for this instance. - /// - /// - /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. - /// - public override int GetHashCode() - { - var values = _storage.Values; - var hashNum = Math.Min(_storage.ValueCount, 25); - int hash = 17; - unchecked - { - for (var i = 0; i < hashNum; i++) - { - hash = hash*31 + values[i].GetHashCode(); - } - } - return hash; - } /// /// Returns the transpose of this matrix. @@ -865,57 +844,6 @@ namespace MathNet.Numerics.LinearAlgebra.Single } #endregion - /// - /// Indicates whether the current object is equal to another object of the same type. - /// - /// - /// An object to compare with this object. - /// - /// - /// true if the current object is equal to the parameter; otherwise, false. - /// - public override bool Equals(Matrix other) - { - if (other == null) - { - return false; - } - - if (ColumnCount != other.ColumnCount || RowCount != other.RowCount) - { - return false; - } - - // Accept if the argument is the same object as this. - if (ReferenceEquals(this, other)) - { - return true; - } - - var sparseMatrix = other as SparseMatrix; - if (sparseMatrix == null) - { - return base.Equals(other); - } - - var otherStorage = sparseMatrix.Raw; - if (_storage.ValueCount != otherStorage.ValueCount) - { - return false; - } - - // If all else fails, perform element wise comparison. - for (var index = 0; index < _storage.ValueCount; index++) - { - if (!_storage.Values[index].AlmostEqual(otherStorage.Values[index]) || _storage.ColumnIndices[index] != otherStorage.ColumnIndices[index]) - { - return false; - } - } - - return true; - } - /// /// Adds another matrix to this matrix. /// diff --git a/src/Numerics/LinearAlgebra/Storage/DiagonalMatrixStorage.cs b/src/Numerics/LinearAlgebra/Storage/DiagonalMatrixStorage.cs index fb97ae3c..21cd0988 100644 --- a/src/Numerics/LinearAlgebra/Storage/DiagonalMatrixStorage.cs +++ b/src/Numerics/LinearAlgebra/Storage/DiagonalMatrixStorage.cs @@ -1,4 +1,5 @@ using System; +using System.Linq; using MathNet.Numerics.Properties; namespace MathNet.Numerics.LinearAlgebra.Storage @@ -63,6 +64,64 @@ namespace MathNet.Numerics.LinearAlgebra.Storage Array.Clear(Data, 0, Data.Length); } + /// + /// Indicates whether the current object is equal to another object of the same type. + /// + /// + /// An object to compare with this object. + /// + /// + /// true if the current object is equal to the parameter; otherwise, false. + /// + public override bool Equals(MatrixStorage other) + { + var diagonal = other as DiagonalMatrixStorage; + if (diagonal == null) + { + return base.Equals(other); + } + + // Reject equality when the argument is null or has a different shape. + if (ColumnCount != other.ColumnCount || RowCount != other.RowCount) + { + return false; + } + + // Accept if the argument is the same object as this. + if (ReferenceEquals(this, other)) + { + return true; + } + + if (diagonal.Data.Length != Data.Length) + { + return false; + } + + // If all else fails, perform element wise comparison. + return !Data.Where((t, i) => !t.Equals(diagonal.Data[i])).Any(); + } + + /// + /// Returns a hash code for this instance. + /// + /// + /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. + /// + public override int GetHashCode() + { + var hashNum = Math.Min(Data.Length, 25); + int hash = 17; + unchecked + { + for (var i = 0; i < hashNum; i++) + { + hash = hash * 31 + Data[i].GetHashCode(); + } + } + return hash; + } + /// Parameters assumed to be validated already. public override void CopyTo(MatrixStorage target, bool skipClearing = false) { diff --git a/src/Numerics/LinearAlgebra/Storage/MatrixStorage.cs b/src/Numerics/LinearAlgebra/Storage/MatrixStorage.cs index 9aace840..b3ac5bab 100644 --- a/src/Numerics/LinearAlgebra/Storage/MatrixStorage.cs +++ b/src/Numerics/LinearAlgebra/Storage/MatrixStorage.cs @@ -3,7 +3,8 @@ using MathNet.Numerics.Properties; namespace MathNet.Numerics.LinearAlgebra.Storage { - public abstract partial class MatrixStorage where T : struct, IEquatable, IFormattable + public abstract partial class MatrixStorage : IEquatable> + where T : struct, IEquatable, IFormattable { // [ruegg] public fields are OK here @@ -106,6 +107,82 @@ namespace MathNet.Numerics.LinearAlgebra.Storage } } + /// + /// Indicates whether the current object is equal to another object of the same type. + /// + /// + /// An object to compare with this object. + /// + /// + /// true if the current object is equal to the parameter; otherwise, false. + /// + public virtual bool Equals(MatrixStorage other) + { + // Reject equality when the argument is null or has a different shape. + if (other == null) + { + return false; + } + if (ColumnCount != other.ColumnCount || RowCount != other.RowCount) + { + return false; + } + + // Accept if the argument is the same object as this. + if (ReferenceEquals(this, other)) + { + return true; + } + + // If all else fails, perform element wise comparison. + for (var row = 0; row < RowCount; row++) + { + for (var column = 0; column < ColumnCount; column++) + { + if (!At(row, column).Equals(other.At(row, column))) + { + return false; + } + } + } + + return true; + } + + /// + /// Determines whether the specified is equal to the current . + /// + /// + /// true if the specified is equal to the current ; otherwise, false. + /// + /// The to compare with the current . 2 + public override sealed bool Equals(object obj) + { + return Equals(obj as MatrixStorage); + } + + /// + /// Serves as a hash function for a particular type. + /// + /// + /// A hash code for the current . + /// + public override int GetHashCode() + { + var hashNum = Math.Min(RowCount*ColumnCount, 25); + int hash = 17; + unchecked + { + for (var i = 0; i < hashNum; i++) + { + var col = i%ColumnCount; + var row = (i - col)/RowCount; + hash = hash*31 + At(row, col).GetHashCode(); + } + } + return hash; + } + /// Parameters assumed to be validated already. public virtual void CopyTo(MatrixStorage target, bool skipClearing = false) { diff --git a/src/Numerics/LinearAlgebra/Storage/SparseCompressedRowMatrixStorage.cs b/src/Numerics/LinearAlgebra/Storage/SparseCompressedRowMatrixStorage.cs index 75bb574b..c7ac806b 100644 --- a/src/Numerics/LinearAlgebra/Storage/SparseCompressedRowMatrixStorage.cs +++ b/src/Numerics/LinearAlgebra/Storage/SparseCompressedRowMatrixStorage.cs @@ -217,6 +217,79 @@ namespace MathNet.Numerics.LinearAlgebra.Storage return delta; } + /// + /// Indicates whether the current object is equal to another object of the same type. + /// + /// + /// An object to compare with this object. + /// + /// + /// true if the current object is equal to the parameter; otherwise, false. + /// + public override bool Equals(MatrixStorage other) + { + // Reject equality when the argument is null or has a different shape. + if (other == null) + { + return false; + } + if (ColumnCount != other.ColumnCount || RowCount != other.RowCount) + { + return false; + } + + // Accept if the argument is the same object as this. + if (ReferenceEquals(this, other)) + { + return true; + } + + var sparse = other as SparseCompressedRowMatrixStorage; + if (sparse == null) + { + return base.Equals(other); + } + + if (ValueCount != sparse.ValueCount) + { + // TODO: this is not always correct + return false; + } + + // If all else fails, perform element wise comparison. + for (var index = 0; index < ValueCount; index++) + { + // TODO: AlmostEquals + if (!Values[index].Equals(sparse.Values[index]) || ColumnIndices[index] != sparse.ColumnIndices[index]) + { + return false; + } + } + + return true; + } + + /// + /// Returns a hash code for this instance. + /// + /// + /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. + /// + public override int GetHashCode() + { + var values = Values; + var hashNum = Math.Min(ValueCount, 25); + int hash = 17; + unchecked + { + for (var i = 0; i < hashNum; i++) + { + hash = hash * 31 + values[i].GetHashCode(); + } + } + return hash; + } + /// Parameters assumed to be validated already. public override void CopyTo(MatrixStorage target, bool skipClearing = false) {