diff --git a/CSparse.Tests/CSparse.Tests.csproj b/CSparse.Tests/CSparse.Tests.csproj index ffcf742..195baf0 100644 --- a/CSparse.Tests/CSparse.Tests.csproj +++ b/CSparse.Tests/CSparse.Tests.csproj @@ -41,9 +41,9 @@ - + - + diff --git a/CSparse.Tests/HelperTest.cs b/CSparse.Tests/HelperTest.cs index 95f6c41..c2788d1 100644 --- a/CSparse.Tests/HelperTest.cs +++ b/CSparse.Tests/HelperTest.cs @@ -1,6 +1,7 @@  namespace CSparse.Tests { + using CSparse.Double; using NUnit.Framework; using C = System.Numerics.Complex; @@ -33,5 +34,36 @@ public void TestTrimStorage() Assert.That(A.RowIndices.Length, Is.EqualTo(0)); Assert.That(A.Values.Length, Is.EqualTo(0)); } + + [Test] + public void TestValidateStorage() + { + var ap = new int[] { 0, 3, 6 }; + var ai = new int[] { 0, 1, 2, 0, 1, 2 }; + var ax = new double[] { 0, 0, 0, 0, 0, 0 }; + + var A = new SparseMatrix(3, 2, ax, ai, ap); + + Assert.That(Helper.ValidateStorage(A), Is.True); + + // Change order of column pointers. + ap[1] = 6; ap[2] = 3; + + Assert.That(Helper.ValidateStorage(A), Is.False); + + // Revert change to column pointers. + ap[1] = 3; ap[2] = 6; + + // Row index larger than number of rows. + ai[2] = 3; + + Assert.That(Helper.ValidateStorage(A), Is.False); + + // Change order of row indices. + ai[1] = 2; ai[2] = 1; + + Assert.That(Helper.ValidateStorage(A), Is.True); + Assert.That(Helper.ValidateStorage(A, true), Is.False); + } } } diff --git a/CSparse/CSparse.csproj b/CSparse/CSparse.csproj index 1fe1fe0..8c0a145 100644 --- a/CSparse/CSparse.csproj +++ b/CSparse/CSparse.csproj @@ -9,27 +9,27 @@ CSparse.NET provides numerical methods for sparse LU, Cholesky and QR decomposition of real and complex linear systems. CSparse.NET - Copyright Christian Woltering © 2012-2023 + Copyright Christian Woltering © 2012-2024 Christian Woltering - 3.8.1.0 - 3.8.1.0 + 4.0.0.0 + 4.0.0.0 math sparse matrix lu cholesky qr decomposition factorization - 3.8.1 + 4.0.0 CSparse CSparse LGPL-2.1-only https://github.com/wo80/CSparse.NET - https://github.com/wo80/CSparse.NET + https://github.com/wo80/CSparse.NET.git git -Changes in version 3.8.1: + The major version change is due to the removal of obsolete methods in the Converter class. Visibility of that class was changed from public to internal. In case those obsolete methods were still used, please switch to the static conversion methods provided by the SparseMatrix class. -* Add overloads for permutation Invert() and IsValid() methods taking the permutation length as argument. + Other changes in version 4.0.0: -Changes in version 3.8.0: - -* Add overloads for the factorization Solve() methods taking Span<T> as argument. Note that this introduces a dependency on System.Memory for the netstandard2.0 assembly. - + * Addition of helper method Helper.ValidateStorage(...) to validate the structure of a sparse matrix. + * Update to GetHashCode() method of CompressedColumnStorage class. + * Improvements to documentation. + diff --git a/CSparse/Complex/Factorization/SparseLDL.cs b/CSparse/Complex/Factorization/SparseLDL.cs index 148ef70..71e72b1 100644 --- a/CSparse/Complex/Factorization/SparseLDL.cs +++ b/CSparse/Complex/Factorization/SparseLDL.cs @@ -315,7 +315,7 @@ void Factorize(CompressedColumnStorage A, IProgress progress) y[k] = 0.0; for (; top < n; top++) { - i = pattern[top]; // Pattern [top:n-1] is pattern of L(:,k) + i = pattern[top]; // Pattern [top:n-1] is pattern of L(k,:) yi = y[i]; // get and clear Y(i) y[i] = 0.0; p2 = lp[i] + lnz[i]; diff --git a/CSparse/Constants.cs b/CSparse/Constants.cs index a267470..d18d6f2 100644 --- a/CSparse/Constants.cs +++ b/CSparse/Constants.cs @@ -18,7 +18,7 @@ public static class Constants public const int SizeOfDouble = sizeof(double); /// - /// The default threshold used for matrix values comparision. + /// The default threshold used for matrix values comparison. /// public const double EqualsThreshold = 1e-12; diff --git a/CSparse/Converter.cs b/CSparse/Converter.cs index a5766a6..131cb91 100644 --- a/CSparse/Converter.cs +++ b/CSparse/Converter.cs @@ -7,21 +7,8 @@ namespace CSparse /// /// Converter for different types of storages. /// - public static class Converter + internal static class Converter { - /// - /// Convert a coordinate storage to compressed sparse column (CSC) format. - /// - /// Coordinate storage. - /// Remove and sum duplicate entries. - /// Compressed sparse column storage. - [Obsolete("Will be removed in future versions. Use SparseMatrix.OfIndexed(...) instead.")] - public static CompressedColumnStorage ToCompressedColumnStorage(CoordinateStorage storage, - bool cleanup = true) where T : struct, IEquatable, IFormattable - { - return ToCompressedColumnStorage_(storage, cleanup); - } - /// /// Convert a coordinate storage to compressed sparse column (CSC) format. /// @@ -29,7 +16,7 @@ public static CompressedColumnStorage ToCompressedColumnStorage(Coordinate /// Remove and sum duplicate entries. /// Do the conversion in place (re-using the coordinate storage arrays). /// Compressed sparse column storage. - internal static CompressedColumnStorage ToCompressedColumnStorage_(CoordinateStorage storage, + public static CompressedColumnStorage ToCompressedColumnStorage(CoordinateStorage storage, bool cleanup = true, bool inplace = false) where T : struct, IEquatable, IFormattable { int nrows = storage.RowCount; @@ -110,7 +97,7 @@ internal static CompressedColumnStorage ToCompressedColumnStorage_(Coordin /// /// On return, the coordinate storage input arrays contain the compressed sparse /// column data structure for the resulting matrix. The - /// array contains a copy of the column pointer. + /// array contains a copy of the column pointers. /// /// The entries of the output matrix are not sorted (the row indices in each /// column are not in increasing order). @@ -193,15 +180,8 @@ private static void ConvertInPlace(int columns, int nz, T[] values, int[] row /// /// 2D array storage. /// Coordinate storage. - [Obsolete("Will be removed in future versions. Use SparseMatrix.OfArray(...) instead.")] public static CoordinateStorage FromDenseArray(T[,] array) where T : struct, IEquatable, IFormattable - { - return FromDenseArray_(array); - } - - internal static CoordinateStorage FromDenseArray_(T[,] array) - where T : struct, IEquatable, IFormattable { int rowCount = array.GetLength(0); int columnCount = array.GetLength(1); @@ -219,32 +199,6 @@ internal static CoordinateStorage FromDenseArray_(T[,] array) return storage; } - /// - /// Convert a jagged array to compressed sparse column (CSC) format. - /// - /// Jagged array storage. - /// Compressed sparse column storage. - [Obsolete("Will be removed in future versions. Use SparseMatrix.OfJaggedArray(...) instead.")] - public static CompressedColumnStorage ToCompressedColumnStorage(T[][] array) - where T : struct, IEquatable, IFormattable - { - int nrows = array.Length; - int ncols = array[0].Length; - - var storage = new CoordinateStorage(nrows, ncols, nrows); - - for (int i = 0; i < nrows; i++) - { - for (int j = 0; j < ncols; j++) - { - storage.At(i, j, array[i][j]); - } - } - - return ToCompressedColumnStorage_(storage, false); - } - - /// /// Convert a column major array to coordinate storage. /// @@ -252,15 +206,8 @@ public static CompressedColumnStorage ToCompressedColumnStorage(T[][] arra /// Number of rows. /// Number of columns. /// Coordinate storage. - [Obsolete("Will be removed in future versions. Use SparseMatrix.OfColumnMajor(...) instead.")] public static CoordinateStorage FromColumnMajorArray(T[] array, int rowCount, int columnCount) where T : struct, IEquatable, IFormattable - { - return FromColumnMajorArray_(array, rowCount, columnCount); - } - - internal static CoordinateStorage FromColumnMajorArray_(T[] array, int rowCount, int columnCount) - where T : struct, IEquatable, IFormattable { var storage = new CoordinateStorage(rowCount, columnCount, Math.Max(rowCount, columnCount)); @@ -281,15 +228,8 @@ internal static CoordinateStorage FromColumnMajorArray_(T[] array, int row /// jagged array storage. /// Coordinate storage. /// All rows of the array are assumed to be equal in length - [Obsolete("Will be removed in future versions. Use SparseMatrix.OfColumnMajor(...) instead.")] public static CoordinateStorage FromJaggedArray(T[][] array) where T : struct, IEquatable, IFormattable - { - return FromJaggedArray_(array); - } - - internal static CoordinateStorage FromJaggedArray_(T[][] array) - where T : struct, IEquatable, IFormattable { int rowCount = array.Length; int columnCount = array[0].Length; @@ -314,15 +254,8 @@ internal static CoordinateStorage FromJaggedArray_(T[][] array) /// Number of rows. /// Number of columns. /// Coordinate storage. - [Obsolete("Will be removed in future versions. Use SparseMatrix.OfRowMajor(...) instead.")] public static CoordinateStorage FromRowMajorArray(T[] array, int rowCount, int columnCount) where T : struct, IEquatable, IFormattable - { - return FromRowMajorArray_(array, rowCount, columnCount); - } - - internal static CoordinateStorage FromRowMajorArray_(T[] array, int rowCount, int columnCount) - where T : struct, IEquatable, IFormattable { var storage = new CoordinateStorage(rowCount, columnCount, Math.Max(rowCount, columnCount)); @@ -344,15 +277,8 @@ internal static CoordinateStorage FromRowMajorArray_(T[] array, int rowCou /// Number of rows. /// Number of columns. /// Coordinate storage. - [Obsolete("Will be removed in future versions. Use SparseMatrix.OfIndexed(...) instead.")] public static CoordinateStorage FromEnumerable(IEnumerable> enumerable, int rowCount, int columnCount) where T : struct, IEquatable, IFormattable - { - return FromEnumerable_(enumerable, rowCount, columnCount); - } - - internal static CoordinateStorage FromEnumerable_(IEnumerable> enumerable, int rowCount, int columnCount) - where T : struct, IEquatable, IFormattable { var storage = new CoordinateStorage(rowCount, columnCount, Math.Max(rowCount, columnCount)); diff --git a/CSparse/Double/Factorization/SparseLDL.cs b/CSparse/Double/Factorization/SparseLDL.cs index 6225636..740da8e 100644 --- a/CSparse/Double/Factorization/SparseLDL.cs +++ b/CSparse/Double/Factorization/SparseLDL.cs @@ -314,7 +314,7 @@ void Factorize(CompressedColumnStorage A, IProgress progress) y[k] = 0.0; for (; top < n; top++) { - i = pattern[top]; // Pattern [top:n-1] is pattern of L(:,k) + i = pattern[top]; // Pattern [top:n-1] is pattern of L(k,:) yi = y[i]; // get and clear Y(i) y[i] = 0.0; p2 = lp[i] + lnz[i]; diff --git a/CSparse/Factorization/ISolver.cs b/CSparse/Factorization/ISolver.cs index a5bb4f5..4e59f39 100644 --- a/CSparse/Factorization/ISolver.cs +++ b/CSparse/Factorization/ISolver.cs @@ -5,7 +5,7 @@ namespace CSparse.Factorization /// /// Classes that solve a system of linear equations, Ax = b. /// - /// Supported data types are double and . + /// Supported data types are double and . public interface ISolver where T : struct, IEquatable, IFormattable { /// diff --git a/CSparse/Factorization/ISparseFactorization.cs b/CSparse/Factorization/ISparseFactorization.cs index b53623c..65f49cf 100644 --- a/CSparse/Factorization/ISparseFactorization.cs +++ b/CSparse/Factorization/ISparseFactorization.cs @@ -5,7 +5,7 @@ namespace CSparse.Factorization /// /// Interface for factorization methods. /// - /// Supported data types are double and . + /// Supported data types are double and . public interface ISparseFactorization : ISolver where T : struct, IEquatable, IFormattable { diff --git a/CSparse/Factorization/SparseQR.cs b/CSparse/Factorization/SparseQR.cs index 7890ad7..e4b883b 100644 --- a/CSparse/Factorization/SparseQR.cs +++ b/CSparse/Factorization/SparseQR.cs @@ -6,13 +6,26 @@ namespace CSparse.Factorization /// /// Sparse QR decomposition abstract base class. /// + /// Supported data types are double and . public abstract class SparseQR : ISparseFactorization where T : struct, IEquatable, IFormattable { - protected readonly int m, n; + /// number of rows + protected readonly int m; + /// number of columns + protected readonly int n; + + /// symbolic factorization protected SymbolicFactorization S; - protected CompressedColumnStorage Q, R; + + /// Q factor + protected CompressedColumnStorage Q; + + /// R factor + protected CompressedColumnStorage R; + + /// factors for Householder reflection protected double[] beta; /// @@ -20,12 +33,12 @@ public abstract class SparseQR : ISparseFactorization /// protected SparseQR(int rows, int columns) { - this.m = rows; - this.n = columns; + m = rows; + n = columns; } /// - /// Gets the number of nonzeros in both Q and R factors together. + /// Gets the number of non-zeros in both Q and R factors together. /// public int NonZerosCount { diff --git a/CSparse/Factorization/SymbolicFactorization.cs b/CSparse/Factorization/SymbolicFactorization.cs index 21088d3..ce38b63 100644 --- a/CSparse/Factorization/SymbolicFactorization.cs +++ b/CSparse/Factorization/SymbolicFactorization.cs @@ -31,17 +31,17 @@ public class SymbolicFactorization public int[] leftmost; /// - /// # of rows for QR, after adding fictitious rows + /// number of rows for QR, after adding fictitious rows /// public int m2; /// - /// # entries in L for LU or Cholesky; in V for QR + /// number of entries in L for LU or Cholesky; in V for QR /// public int lnz; /// - /// # entries in U for LU; in R for QR + /// number of entries in U for LU; in R for QR /// public int unz; } diff --git a/CSparse/Helper.cs b/CSparse/Helper.cs index 65a20c8..6ab628e 100644 --- a/CSparse/Helper.cs +++ b/CSparse/Helper.cs @@ -31,6 +31,52 @@ public static int CumulativeSum(int[] sum, int[] counts, int size) return nz; } + /// + /// Validate the structure of the . + /// + /// + /// The storage to validate. + /// If true, row indices have to be ordered and no duplicate indices are allowed (default = false). + /// Returns true if the structure of the storage is valid. + public static bool ValidateStorage(CompressedColumnStorage storage, bool strict = false) + where T : struct, IEquatable, IFormattable + { + int rows = storage.RowCount; + int columns = storage.ColumnCount; + + var ap = storage.ColumnPointers; + var ai = storage.RowIndices; + + for (int i = 0; i < columns; i++) + { + int j = ap[i]; + int end = ap[i + 1]; + + // Check if column pointers are in ascending order. + if (j > end) + { + return false; + } + + for (; j < end; j++) + { + // Check if row indices are within bounds. + if (ai[j] < 0 || ai[j] >= rows) + { + return false; + } + + // Check if row indices are in order. + if (strict && ai[j] >= ai[j + 1]) + { + return false; + } + } + } + + return true; + } + /// /// Trim row indices and values array of the storage to the exact size (non-zeros count). /// diff --git a/CSparse/ILinearOperator.cs b/CSparse/ILinearOperator.cs index a8ec70f..7e5d885 100644 --- a/CSparse/ILinearOperator.cs +++ b/CSparse/ILinearOperator.cs @@ -5,7 +5,7 @@ namespace CSparse /// /// Linear operator interface. /// - /// Supported data types are double and . + /// Supported data types are double and . public interface ILinearOperator where T : struct, IEquatable, IFormattable { /// @@ -35,9 +35,9 @@ public interface ILinearOperator where T : struct, IEquatable, IFormattabl /// /// Multiplies a (m-by-n) matrix by a vector, y = alpha * A * x + beta * y. /// - /// Scaling factor fo vertor x. + /// Scaling factor for vector x. /// Vector of length n (column count). - /// Scaling factor fo vertor y. + /// Scaling factor for vector y. /// Vector of length m (row count), containing the result. /// /// Input values of vector will be accumulated. @@ -47,9 +47,9 @@ public interface ILinearOperator where T : struct, IEquatable, IFormattabl /// /// Multiplies a (m-by-n) matrix by a vector, y = alpha * A * x + beta * y. /// - /// Scaling factor fo vertor x. + /// Scaling factor for vector x. /// Vector of length n (column count). - /// Scaling factor fo vertor y. + /// Scaling factor for vector y. /// Vector of length m (row count), containing the result. /// /// Input values of vector will be accumulated. @@ -73,9 +73,9 @@ public interface ILinearOperator where T : struct, IEquatable, IFormattabl /// /// Multiplies the transpose of a (m-by-n) matrix by a vector, y = alpha * A^t * x + beta * y. /// - /// Scaling factor fo vertor x. + /// Scaling factor for vector x. /// Vector of length m (column count of A'). - /// Scaling factor fo vertor y. + /// Scaling factor for vector y. /// Vector of length n (row count of A'), containing the result. /// /// Input values of vector will be accumulated. @@ -85,9 +85,9 @@ public interface ILinearOperator where T : struct, IEquatable, IFormattabl /// /// Multiplies the transpose of a (m-by-n) matrix by a vector, y = alpha * A^t * x + beta * y. /// - /// Scaling factor fo vertor x. + /// Scaling factor for vector x. /// Vector of length m (column count of A'). - /// Scaling factor fo vertor y. + /// Scaling factor for vector y. /// Vector of length n (row count of A'), containing the result. /// /// Input values of vector will be accumulated. diff --git a/CSparse/Matrix.cs b/CSparse/Matrix.cs index 4a10877..907254e 100644 --- a/CSparse/Matrix.cs +++ b/CSparse/Matrix.cs @@ -9,7 +9,7 @@ namespace CSparse /// /// Abstract base class for matrix implementations. /// - /// Supported data types are double and . + /// Supported data types are double and . [Serializable] public abstract class Matrix : ILinearOperator where T : struct, IEquatable, IFormattable diff --git a/CSparse/Ordering/MaximumMatching.cs b/CSparse/Ordering/MaximumMatching.cs index f970669..fe907e7 100644 --- a/CSparse/Ordering/MaximumMatching.cs +++ b/CSparse/Ordering/MaximumMatching.cs @@ -4,7 +4,7 @@ namespace CSparse.Ordering using System; /// - /// Maximum matching of any matrix A (also called maximum transveral). + /// Maximum matching of any matrix A (also called maximum transversal). /// /// /// See Chapter 7.2 (Fill-reducing orderings: Maximum matching) in @@ -13,7 +13,7 @@ namespace CSparse.Ordering internal static class MaximumMatching { /// - /// Find a maximum transveral (zero-free diagonal). Seed optionally selects a + /// Find a maximum transversal (zero-free diagonal). Seed optionally selects a /// randomized algorithm. /// /// column-compressed matrix diff --git a/CSparse/Ordering/StronglyConnectedComponents.cs b/CSparse/Ordering/StronglyConnectedComponents.cs index 71076cc..cf38d30 100644 --- a/CSparse/Ordering/StronglyConnectedComponents.cs +++ b/CSparse/Ordering/StronglyConnectedComponents.cs @@ -91,7 +91,7 @@ internal static StronglyConnectedComponents Generate(SymbolicColumnStorage A, in } top = n; nb = n; - for (k = 0; k < n; k++) // dfs(A') to find strongly connnected comp + for (k = 0; k < n; k++) // dfs(A') to find strongly connected comp { i = xi[k]; // get i in reverse order of finish times if (ATp[i] < 0) diff --git a/CSparse/Storage/CompressedColumnStorage.cs b/CSparse/Storage/CompressedColumnStorage.cs index de38faf..e6a1b70 100644 --- a/CSparse/Storage/CompressedColumnStorage.cs +++ b/CSparse/Storage/CompressedColumnStorage.cs @@ -8,7 +8,7 @@ namespace CSparse.Storage /// /// Compressed sparse column storage. /// - /// + /// Supported data types are double and . [Serializable] public abstract class CompressedColumnStorage : Matrix where T : struct, IEquatable, IFormattable @@ -110,9 +110,9 @@ public CompressedColumnStorage(int rowCount, int columnCount, T[] values, int[] /// public static CompressedColumnStorage OfMatrix(Matrix matrix) { - var c = Converter.FromEnumerable_(matrix.EnumerateIndexed(), matrix.RowCount, matrix.ColumnCount); + var c = Converter.FromEnumerable(matrix.EnumerateIndexed(), matrix.RowCount, matrix.ColumnCount); - return Converter.ToCompressedColumnStorage_(c); + return Converter.ToCompressedColumnStorage(c); } /// @@ -120,9 +120,9 @@ public static CompressedColumnStorage OfMatrix(Matrix matrix) /// public static CompressedColumnStorage OfArray(T[,] array) { - var c = Converter.FromDenseArray_(array); + var c = Converter.FromDenseArray(array); - return Converter.ToCompressedColumnStorage_(c); + return Converter.ToCompressedColumnStorage(c); } /// @@ -130,9 +130,9 @@ public static CompressedColumnStorage OfArray(T[,] array) /// public static CompressedColumnStorage OfJaggedArray(T[][] array) { - var c = Converter.FromJaggedArray_(array); + var c = Converter.FromJaggedArray(array); - return Converter.ToCompressedColumnStorage_(c); + return Converter.ToCompressedColumnStorage(c); } /// @@ -140,7 +140,7 @@ public static CompressedColumnStorage OfJaggedArray(T[][] array) /// public static CompressedColumnStorage OfIndexed(CoordinateStorage coordinateStorage, bool inplace = false) { - return Converter.ToCompressedColumnStorage_(coordinateStorage, true, inplace); + return Converter.ToCompressedColumnStorage(coordinateStorage, true, inplace); } /// @@ -148,9 +148,9 @@ public static CompressedColumnStorage OfIndexed(CoordinateStorage coordina /// public static CompressedColumnStorage OfIndexed(int rows, int columns, IEnumerable> enumerable) { - var c = Converter.FromEnumerable_(enumerable, rows, columns); + var c = Converter.FromEnumerable(enumerable, rows, columns); - return Converter.ToCompressedColumnStorage_(c); + return Converter.ToCompressedColumnStorage(c); } /// @@ -158,9 +158,9 @@ public static CompressedColumnStorage OfIndexed(int rows, int columns, IEnume /// public static CompressedColumnStorage OfRowMajor(int rows, int columns, T[] rowMajor) { - var c = Converter.FromRowMajorArray_(rowMajor, rows, columns); + var c = Converter.FromRowMajorArray(rowMajor, rows, columns); - return Converter.ToCompressedColumnStorage_(c); + return Converter.ToCompressedColumnStorage(c); } /// @@ -168,9 +168,9 @@ public static CompressedColumnStorage OfRowMajor(int rows, int columns, T[] r /// public static CompressedColumnStorage OfColumnMajor(int rows, int columns, T[] columnMajor) { - var c = Converter.FromColumnMajorArray_(columnMajor, rows, columns); + var c = Converter.FromColumnMajorArray(columnMajor, rows, columns); - return Converter.ToCompressedColumnStorage_(c); + return Converter.ToCompressedColumnStorage(c); } /// @@ -381,7 +381,7 @@ public CompressedColumnStorage Transpose() /// /// Transpose this matrix and store the result in given matrix. /// - /// Storage for the tranposed matrix. + /// Storage for the transposed matrix. public void Transpose(CompressedColumnStorage result) { Transpose(result, false); @@ -401,7 +401,7 @@ public CompressedColumnStorage Transpose(bool storage) /// /// Transpose this matrix and store the result in given matrix. /// - /// Storage for the tranposed matrix. + /// Storage for the transposed matrix. /// A value indicating, whether the transpose should be done on storage level (without complex conjugation). public virtual void Transpose(CompressedColumnStorage result, bool storage) { @@ -436,7 +436,7 @@ public virtual void Transpose(CompressedColumnStorage result, bool storage) } /// - /// Adds two matrices in CSC format, C = A + B, where A is current instance. + /// Adds two matrices in CSC format, C = A + B, where A is the current instance. /// public CompressedColumnStorage Add(CompressedColumnStorage other) { @@ -456,9 +456,9 @@ public CompressedColumnStorage Add(CompressedColumnStorage other) } /// - /// Adds two matrices, C = alpha*A + beta*B, where A is current instance. + /// Adds two matrices, C = alpha*A + beta*B, where A is the current instance. /// - /// Scalar factor for A, current instance. + /// Scalar factor for A, the current instance. /// Scalar factor for B, other instance. /// The matrix added to this instance. /// Contains the sum. @@ -471,9 +471,9 @@ public abstract void Add(T alpha, T beta, CompressedColumnStorage other, CompressedColumnStorage result); /// - /// Sparse matrix multiplication, C = A*B + /// Sparse matrix multiplication, C = A * B, where A is the current instance. /// - /// The sparse matrix multiplied to this instance. + /// The sparse matrix multiplied to this instance (from the right). /// C = A*B public CompressedColumnStorage Multiply(CompressedColumnStorage other) { @@ -485,9 +485,9 @@ public CompressedColumnStorage Multiply(CompressedColumnStorage other) } /// - /// Sparse matrix multiplication, C = A*B + /// Sparse matrix multiplication, C = A * B, where A is the current instance. /// - /// The sparse matrix multiplied to this instance. + /// The sparse matrix multiplied to this instance (from the right). /// Contains the matrix product. /// /// The matrix has to be fully initialized, but doesn't have @@ -497,9 +497,9 @@ public CompressedColumnStorage Multiply(CompressedColumnStorage other) public abstract void Multiply(CompressedColumnStorage other, CompressedColumnStorage result); /// - /// Sparse matrix multiplication, C = A*B + /// Sparse matrix multiplication, C = A * B, where A is the current instance. /// - /// The sparse matrix multiplied to this instance. + /// The sparse matrix multiplied to this instance (from the right). /// Parallel options (optional). /// C = A*B public virtual CompressedColumnStorage ParallelMultiply(CompressedColumnStorage other, System.Threading.Tasks.ParallelOptions options = null) @@ -757,7 +757,7 @@ protected void PermuteColumns(T[] ax, int[] ai, int[] aj, T[] bx, int[] bi, int[ { int k; - // Determine pointers for output matix. + // Determine pointers for output matrix. for (int i = 0; i < columns; i++) { k = perm[i]; @@ -896,26 +896,20 @@ internal bool Resize(int size) /// Serves as a hash function for a particular type. /// /// - /// A hash code for the current . + /// A hash code for the current . /// public override int GetHashCode() { - var hashNum = Math.Min(this.NonZerosCount, 25); + var hashNum = Math.Min(NonZerosCount, 50); int hash = 17; - int i, p, k = 0; unchecked { - for (i = 0; i < columns; i++) - { - for (p = ColumnPointers[i]; p < ColumnPointers[i + 1]; p++) - { - hash = hash * 31 + Values[p].GetHashCode(); + hash = hash * 31 + NonZerosCount; - if (++k > hashNum) - { - return hash; - } - } + for (int i = 0; i < hashNum; i++) + { + hash = hash * 31 + RowIndices[i]; + hash = hash * 31 + Values[i].GetHashCode(); } } return hash; diff --git a/CSparse/Storage/CoordinateStorage.cs b/CSparse/Storage/CoordinateStorage.cs index 0b7080e..448e21e 100644 --- a/CSparse/Storage/CoordinateStorage.cs +++ b/CSparse/Storage/CoordinateStorage.cs @@ -6,6 +6,7 @@ namespace CSparse.Storage /// /// Coordinate storage sparse matrix format. /// + /// Supported data types are double and . public class CoordinateStorage where T : struct, IEquatable, IFormattable { diff --git a/CSparse/Storage/DenseColumnMajorStorage.cs b/CSparse/Storage/DenseColumnMajorStorage.cs index 177dbb3..053a6da 100644 --- a/CSparse/Storage/DenseColumnMajorStorage.cs +++ b/CSparse/Storage/DenseColumnMajorStorage.cs @@ -9,7 +9,7 @@ namespace CSparse.Storage /// /// Dense column-major matrix storage. /// - /// Supported data types are double and . + /// Supported data types are double and . [Serializable] public abstract class DenseColumnMajorStorage : Matrix where T : struct, IEquatable, IFormattable @@ -310,7 +310,7 @@ public virtual void Transpose(DenseColumnMajorStorage result) } /// - /// Adds two dense matrices, C = A + B. + /// Adds two dense matrices, C = A + B, where A is the current instance. /// public DenseColumnMajorStorage Add(DenseColumnMajorStorage other) { @@ -328,16 +328,16 @@ public DenseColumnMajorStorage Add(DenseColumnMajorStorage other) } /// - /// Adds two dense matrices, C = A + B. + /// Adds two dense matrices, C = A + B, where A is the current instance. /// /// The matrix added to this instance. /// Contains the sum. public abstract void Add(DenseColumnMajorStorage other, DenseColumnMajorStorage result); /// - /// Dense matrix multiplication, C = A*B + /// Dense matrix multiplication, C = A * B, where A is the current instance. /// - /// The dense matrix multiplied with this instance. + /// The dense matrix multiplied to this instance (from the right). /// C = A*B public DenseColumnMajorStorage Multiply(DenseColumnMajorStorage other) {