From c45e5356a861cd4791a61728ae15b575f7e5e202 Mon Sep 17 00:00:00 2001 From: wo80 Date: Fri, 29 Mar 2024 11:54:31 +0100 Subject: [PATCH 1/6] Minor fixes and improvements to doc comments. --- CSparse/Complex/Factorization/SparseLDL.cs | 2 +- CSparse/Constants.cs | 2 +- CSparse/Double/Factorization/SparseLDL.cs | 2 +- CSparse/Factorization/ISolver.cs | 2 +- CSparse/Factorization/ISparseFactorization.cs | 2 +- CSparse/Factorization/SparseQR.cs | 1 + CSparse/ILinearOperator.cs | 18 +++++++------- CSparse/Matrix.cs | 2 +- CSparse/Ordering/MaximumMatching.cs | 4 ++-- .../Ordering/StronglyConnectedComponents.cs | 2 +- CSparse/Storage/CompressedColumnStorage.cs | 24 +++++++++---------- CSparse/Storage/CoordinateStorage.cs | 1 + CSparse/Storage/DenseColumnMajorStorage.cs | 10 ++++---- 13 files changed, 37 insertions(+), 35 deletions(-) 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/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..7a58810 100644 --- a/CSparse/Factorization/SparseQR.cs +++ b/CSparse/Factorization/SparseQR.cs @@ -6,6 +6,7 @@ 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 { 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..5042d1e 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 @@ -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. @@ -473,7 +473,7 @@ public abstract void Add(T alpha, T beta, CompressedColumnStorage other, /// /// Sparse matrix multiplication, C = A*B /// - /// 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]; 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) { From e2570fb3a1141b4bca4abe89843cdcd2bea174ed Mon Sep 17 00:00:00 2001 From: wo80 Date: Fri, 29 Mar 2024 12:45:03 +0100 Subject: [PATCH 2/6] Add a helper method to validate the storage of a sparse matrix. --- CSparse.Tests/HelperTest.cs | 32 ++++++++++++++++++++++++++ CSparse/Helper.cs | 46 +++++++++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+) 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/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). /// From 6b0fb46aedf430b628ae42e02debc34fe01d3676 Mon Sep 17 00:00:00 2001 From: wo80 Date: Fri, 29 Mar 2024 12:50:56 +0100 Subject: [PATCH 3/6] Remove methods marked as obsolete from Converter class. --- CSparse/Converter.cs | 80 +--------------------- CSparse/Storage/CompressedColumnStorage.cs | 26 +++---- 2 files changed, 16 insertions(+), 90 deletions(-) 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/Storage/CompressedColumnStorage.cs b/CSparse/Storage/CompressedColumnStorage.cs index 5042d1e..f8f7f36 100644 --- a/CSparse/Storage/CompressedColumnStorage.cs +++ b/CSparse/Storage/CompressedColumnStorage.cs @@ -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); } /// From ec9493c8884831f99b9354758ded39f34469a5c2 Mon Sep 17 00:00:00 2001 From: wo80 Date: Fri, 29 Mar 2024 13:10:13 +0100 Subject: [PATCH 4/6] Bump major version to 4.0.0 --- CSparse.Tests/CSparse.Tests.csproj | 4 ++-- CSparse/CSparse.csproj | 19 +++++++++---------- 2 files changed, 11 insertions(+), 12 deletions(-) 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/CSparse.csproj b/CSparse/CSparse.csproj index 1fe1fe0..b3f3335 100644 --- a/CSparse/CSparse.csproj +++ b/CSparse/CSparse.csproj @@ -9,12 +9,12 @@ 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 @@ -22,14 +22,13 @@ https://github.com/wo80/CSparse.NET 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. + * Improvements to documentation. + From 81cdafcc82c5cb3524f0a68e1c6261ba8769cb51 Mon Sep 17 00:00:00 2001 From: wo80 Date: Fri, 29 Mar 2024 13:43:29 +0100 Subject: [PATCH 5/6] Update GetHashCode() method of CompressedColumnStorage class. --- CSparse/CSparse.csproj | 3 ++- CSparse/Storage/CompressedColumnStorage.cs | 22 ++++++++-------------- 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/CSparse/CSparse.csproj b/CSparse/CSparse.csproj index b3f3335..8c0a145 100644 --- a/CSparse/CSparse.csproj +++ b/CSparse/CSparse.csproj @@ -19,7 +19,7 @@ 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 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. @@ -27,6 +27,7 @@ Other changes in version 4.0.0: * 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/Storage/CompressedColumnStorage.cs b/CSparse/Storage/CompressedColumnStorage.cs index f8f7f36..e6a1b70 100644 --- a/CSparse/Storage/CompressedColumnStorage.cs +++ b/CSparse/Storage/CompressedColumnStorage.cs @@ -471,7 +471,7 @@ 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 (from the right). /// C = A*B @@ -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; From 8c2c61dfa7daabcb96c42b84f694b9072f154957 Mon Sep 17 00:00:00 2001 From: wo80 Date: Wed, 3 Apr 2024 15:26:36 +0200 Subject: [PATCH 6/6] Fix warnings about missing XML comments in SparseQR base class. --- CSparse/Factorization/SparseQR.cs | 22 ++++++++++++++----- .../Factorization/SymbolicFactorization.cs | 6 ++--- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/CSparse/Factorization/SparseQR.cs b/CSparse/Factorization/SparseQR.cs index 7a58810..e4b883b 100644 --- a/CSparse/Factorization/SparseQR.cs +++ b/CSparse/Factorization/SparseQR.cs @@ -10,10 +10,22 @@ namespace CSparse.Factorization 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; /// @@ -21,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; }