From baad7c920041291f9b338ad72599b7179b50c1c3 Mon Sep 17 00:00:00 2001 From: wo80 Date: Fri, 29 Nov 2024 12:06:56 +0100 Subject: [PATCH 01/10] Add changelog file. --- CHANGELOG.md | 119 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..7612ab3 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,119 @@ +### Version 4.2.0 - 2024-09-15 + +* Make `SymbolicColumnStorage` class public and update `StronglyConnectedComponents` and `DulmageMendelsohn` decomposition accordingly. + +### Version 4.1.0 - 2024-06-14 + +* Add overload for creating a sparse matrix from an enumerable of `ValueTuple`. +* Add matrix `EnumerateIndexedAsValueTuples()` to enumerate entries as `ValueTuple`. + +### Version 4.0.0 - 2024-04-03 + +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. + +Additional changes: + +* Add helper method `Helper.ValidateStorage(...)` to validate the structure of a sparse matrix. +* Update to `GetHashCode()` method of `CompressedColumnStorage` class. +* Improvements to documentation. + +### Version 3.8.1 - 2023-11-15 + +* Add overloads for permutation `Invert()` and `IsValid()` methods taking the permutation length as argument. + +### Version 3.8.0 - 2023-05-20 + +* Add overloads for the factorization `Solve()` methods taking `Span` as argument. Note that this introduces a dependency on `System.Memory` for the netstandard2.0 assembly. + +### Version 3.7.0 - 2022-05-04 + +* Add sparse matrix `OfDiagonals` static method (similar to MATLAB spdiags). + +### Version 3.6.0 - 2021-11-25 + +* Remove .NET 4.5 target framework, upgrade .NET 5.0 to 6.0. +* Add constructor that takes explicit non-zeros count to `CoordinateStorage` class. + +### Version 3.5.0 - 2021-01-14 + +* Remove .NET 4.0 target framework, add .NET 5.0. + +### Version 3.4.9 - 2020-11-06 + +* Add `CoordinateStorage` constructor that uses existing storage arrays. +* Convert `CoordinateStorage` to sparse matrix in place. + +### Version 3.4.7 - 2020-08-28 + +* BREAKING: make `SparseLDL` constructor private (use static create methods instead). +* Add complex version of `SparseLDL`. +* Add `matrix.EnumerateIndexed(action)` overload. + +### Version 3.4.6 - 2020-07-21 + +* Add `SolveTranspose` method for `SparseQR`. + +### Version 3.4.5 - 2020-06-11 + +This release introduces the static `SparseMatrix.AutoTrimStorage` option, which enables control over hidden memory allocations in matrix addition and multiplication. By default, the matrix storage will be resized to exactly fit the non-zeros count, which involves new memory allocations. If you want to avoid this, set `AutoTrimStorage` to `false`. + +Additional changes: + +* Add public helper methods `Helper.TrimStrorage(...)` and `Helper.SortIndices(...)` +* Add `DenseMatrix.OfJaggedArray(...)` + +### Version 3.4.3 - 2020-05-25 + +* Add a sparse matrix multiplication overload that accepts the result matrix as a parameter. + +### Version 3.4.2 - 2020-05-13 + +* Make CSparse.NET CLS compliant +* Mark public methods of Converter class as obsolete + +### Version 3.4.1 - 2019-10-02 + +* Improved validation of matrix constructor arguments +* Fixes an issue with `CoordinateStorage` throwing `IndexOutOfRangeException` (introduced in v3.4.0) + +### Version 3.4.0 - 2019-09-15 + +* Parallel dense and sparse matrix multiplication (by Andreas Girgensohn) +* General performance improvements for sparse matrix addition and multiplication + +### Version 3.3.0 - 2019-04-29 + +* Support more target frameworks (including netstandard2.0). +* Public access to members of Dulmage-Mendelsohn decomposition. +* Compute strongly connected components. + +### Version 3.2.3 - 2018-11-30 + +* Added matrix creation helper (e.g. call `SparseMatrix.OfIndexed(s)` to convert coordinate storage). + +### Version 3.2.2 - 2018-10-12 + +* Added MatrixMarket writer. +* BREAKING: make `IProgress interface` compatible with .NET 4.5. + +### Version 3.2.1 - 2018-09-17 + +### Version 3.2.0 - 2018-03-09 + +* Added new `DenseMatrix` type. +* BREAKING: removed deprecated `CompressedColumnStorage` type. +* BREAKING: removed deprecated `matrix.Norm(int)` method. + +### Version 3.1.10 - 2018-03-06 + +* Rename `CompressedColumnStorage` to `SparseMatrix`. +* BREAKING: `matrix.Multiply(x, y)` overwrites y (instead of update). +* BREAKING: sparse matrix `PermuteColumns` returns a new matrix (instead of update). + +### Version 3.1.9 - 2017-01-06 + +* BREAKING: use static `Create` methods (e.g. `SparseLU.Create(...)`) instead of constructors. + +### Version 3.1.4 - 2015-09-19 + +* Initial release of CSparse.NET (based on Tim Davis CSparse version 3.1.4) From 504c1158ced350a2a87ecef389f286d4a3a4fb31 Mon Sep 17 00:00:00 2001 From: wo80 Date: Thu, 6 Mar 2025 20:07:26 +0100 Subject: [PATCH 02/10] Remove net6.0 target framework. --- CSparse/CSparse.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CSparse/CSparse.csproj b/CSparse/CSparse.csproj index 87c411d..c07dcea 100644 --- a/CSparse/CSparse.csproj +++ b/CSparse/CSparse.csproj @@ -1,7 +1,7 @@ - netstandard2.0;net6.0;net8.0 + netstandard2.0;net8.0 False True CSparse From 01fe120c3d25901bc0032dcd91d6e0b6a999e812 Mon Sep 17 00:00:00 2001 From: wo80 Date: Fri, 14 Mar 2025 00:20:44 +0100 Subject: [PATCH 03/10] Update System.Memory dependency for netstandard2.0 target. Update test project dependencies. --- CSparse.Tests/CSparse.Tests.csproj | 6 +++--- CSparse/CSparse.csproj | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CSparse.Tests/CSparse.Tests.csproj b/CSparse.Tests/CSparse.Tests.csproj index f58e88a..ce40de6 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 c07dcea..b3a947b 100644 --- a/CSparse/CSparse.csproj +++ b/CSparse/CSparse.csproj @@ -44,7 +44,7 @@ - + From 50eb7c9bb78ee2b41808237ed1edad5387b9911d Mon Sep 17 00:00:00 2001 From: wo80 Date: Mon, 3 Nov 2025 15:56:57 +0100 Subject: [PATCH 04/10] Minor performance optimization Co-authored-by: epsi1on --- CSparse/Complex/SparseMatrix.cs | 5 ++++- CSparse/Double/SparseMatrix.cs | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/CSparse/Complex/SparseMatrix.cs b/CSparse/Complex/SparseMatrix.cs index eb0ce2e..d591fed 100644 --- a/CSparse/Complex/SparseMatrix.cs +++ b/CSparse/Complex/SparseMatrix.cs @@ -171,15 +171,18 @@ public override void Multiply(ReadOnlySpan x, Span y) } int end; + Complex xj; for (int j = 0; j < columns; j++) { end = ap[j + 1]; + xj = x[j]; + // Loop over the rows for (int k = ap[j]; k < end; k++) { - y[ai[k]] += x[j] * ax[k]; + y[ai[k]] += xj * ax[k]; } } } diff --git a/CSparse/Double/SparseMatrix.cs b/CSparse/Double/SparseMatrix.cs index 6537cb4..b18aabc 100644 --- a/CSparse/Double/SparseMatrix.cs +++ b/CSparse/Double/SparseMatrix.cs @@ -171,15 +171,18 @@ public override void Multiply(ReadOnlySpan x, Span y) } int end; + double xj; for (int j = 0; j < columns; j++) { end = ap[j + 1]; + xj = x[j]; + // Loop over the rows. for (int k = ap[j]; k < end; k++) { - y[ai[k]] += x[j] * ax[k]; + y[ai[k]] += xj * ax[k]; } } } From abdb1b7b1a20afe3be2028dbe77a78567f505e6a Mon Sep 17 00:00:00 2001 From: wo80 Date: Tue, 11 Nov 2025 20:12:58 +0100 Subject: [PATCH 05/10] Add net10.0 target framework. --- CSparse.Tests/CSparse.Tests.csproj | 2 +- CSparse/CSparse.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CSparse.Tests/CSparse.Tests.csproj b/CSparse.Tests/CSparse.Tests.csproj index ce40de6..a795c2b 100644 --- a/CSparse.Tests/CSparse.Tests.csproj +++ b/CSparse.Tests/CSparse.Tests.csproj @@ -1,7 +1,7 @@  - net8.0 + net10.0 false diff --git a/CSparse/CSparse.csproj b/CSparse/CSparse.csproj index b3a947b..372534e 100644 --- a/CSparse/CSparse.csproj +++ b/CSparse/CSparse.csproj @@ -1,7 +1,7 @@ - netstandard2.0;net8.0 + netstandard2.0;net8.0;net10.0 False True CSparse From 307e55b991dc2a3bb603b59a42580ae35f36efc9 Mon Sep 17 00:00:00 2001 From: wo80 Date: Tue, 11 Nov 2025 20:17:12 +0100 Subject: [PATCH 06/10] Update workflow. --- .github/workflows/dotnet.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 893ffa2..dccce14 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -12,11 +12,11 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v5 - name: Setup .NET - uses: actions/setup-dotnet@v3 + uses: actions/setup-dotnet@v5 with: - dotnet-version: 8.0.x + dotnet-version: 10.0.x - name: Restore dependencies run: dotnet restore - name: Build From ef577944f7d93e82b38313f162f12f26c0142401 Mon Sep 17 00:00:00 2001 From: wo80 Date: Tue, 11 Nov 2025 20:18:00 +0100 Subject: [PATCH 07/10] Update FUNDING.yml --- .github/FUNDING.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index ee0aafb..ee21827 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -2,4 +2,4 @@ ko_fi: cwoltering liberapay: cwoltering -custom: ['http://wo80.bplaced.net/donate.html'] +custom: ['https://wo80.webspace.rocks/donate/'] From 2f3cfd3a594e8897630abaf9f631b0fa1078dd9d Mon Sep 17 00:00:00 2001 From: wo80 Date: Tue, 11 Nov 2025 20:34:16 +0100 Subject: [PATCH 08/10] Fix checking empty span. --- CSparse/Complex/Factorization/SparseCholesky.cs | 4 ++-- CSparse/Complex/Factorization/SparseLDL.cs | 4 ++-- CSparse/Complex/Factorization/SparseLU.cs | 4 ++-- CSparse/Complex/Factorization/SparseQR.cs | 8 ++++---- CSparse/Double/Factorization/SparseCholesky.cs | 4 ++-- CSparse/Double/Factorization/SparseLDL.cs | 4 ++-- CSparse/Double/Factorization/SparseLU.cs | 8 ++++---- CSparse/Double/Factorization/SparseQR.cs | 8 ++++---- 8 files changed, 22 insertions(+), 22 deletions(-) diff --git a/CSparse/Complex/Factorization/SparseCholesky.cs b/CSparse/Complex/Factorization/SparseCholesky.cs index e129694..e7c7c74 100644 --- a/CSparse/Complex/Factorization/SparseCholesky.cs +++ b/CSparse/Complex/Factorization/SparseCholesky.cs @@ -120,9 +120,9 @@ public int NonZerosCount /// The left hand side vector, x. public void Solve(ReadOnlySpan input, Span result) { - if (input == null) throw new ArgumentNullException(nameof(input)); + if (input.IsEmpty) throw new ArgumentNullException(nameof(input)); - if (result == null) throw new ArgumentNullException(nameof(result)); + if (result.IsEmpty) throw new ArgumentNullException(nameof(result)); var x = this.temp; diff --git a/CSparse/Complex/Factorization/SparseLDL.cs b/CSparse/Complex/Factorization/SparseLDL.cs index 71e72b1..01f7807 100644 --- a/CSparse/Complex/Factorization/SparseLDL.cs +++ b/CSparse/Complex/Factorization/SparseLDL.cs @@ -126,9 +126,9 @@ public int NonZerosCount /// Solution vector x. public void Solve(ReadOnlySpan input, Span result) { - if (input == null) throw new ArgumentNullException(nameof(input)); + if (input.IsEmpty) throw new ArgumentNullException(nameof(input)); - if (result == null) throw new ArgumentNullException(nameof(result)); + if (result.IsEmpty) throw new ArgumentNullException(nameof(result)); var x = temp; diff --git a/CSparse/Complex/Factorization/SparseLU.cs b/CSparse/Complex/Factorization/SparseLU.cs index 6161654..c7ab391 100644 --- a/CSparse/Complex/Factorization/SparseLU.cs +++ b/CSparse/Complex/Factorization/SparseLU.cs @@ -124,9 +124,9 @@ public int NonZerosCount /// The left hand side vector, x. public void Solve(ReadOnlySpan input, Span result) { - if (input == null) throw new ArgumentNullException(nameof(input)); + if (input.IsEmpty) throw new ArgumentNullException(nameof(input)); - if (result == null) throw new ArgumentNullException(nameof(result)); + if (result.IsEmpty) throw new ArgumentNullException(nameof(result)); var x = this.temp; diff --git a/CSparse/Complex/Factorization/SparseQR.cs b/CSparse/Complex/Factorization/SparseQR.cs index e2f7b1e..0e88785 100644 --- a/CSparse/Complex/Factorization/SparseQR.cs +++ b/CSparse/Complex/Factorization/SparseQR.cs @@ -99,9 +99,9 @@ private SparseQR(int rows, int columns) /// public override void Solve(ReadOnlySpan input, Span result) { - if (input == null) throw new ArgumentNullException(nameof(input)); + if (input.IsEmpty) throw new ArgumentNullException(nameof(input)); - if (result == null) throw new ArgumentNullException(nameof(result)); + if (result.IsEmpty) throw new ArgumentNullException(nameof(result)); var x = new Complex[S.m2]; @@ -154,9 +154,9 @@ public override void Solve(ReadOnlySpan input, Span result) /// The left hand side vector, x. public void SolveTranspose(ReadOnlySpan input, Span result) { - if (input == null) throw new ArgumentNullException(nameof(input)); + if (input.IsEmpty) throw new ArgumentNullException(nameof(input)); - if (result == null) throw new ArgumentNullException(nameof(result)); + if (result.IsEmpty) throw new ArgumentNullException(nameof(result)); int m2 = S.m2; diff --git a/CSparse/Double/Factorization/SparseCholesky.cs b/CSparse/Double/Factorization/SparseCholesky.cs index c96555b..28b07f4 100644 --- a/CSparse/Double/Factorization/SparseCholesky.cs +++ b/CSparse/Double/Factorization/SparseCholesky.cs @@ -119,9 +119,9 @@ public int NonZerosCount /// The left hand side vector, x. public void Solve(ReadOnlySpan input, Span result) { - if (input == null) throw new ArgumentNullException(nameof(input)); + if (input.IsEmpty) throw new ArgumentNullException(nameof(input)); - if (result == null) throw new ArgumentNullException(nameof(result)); + if (result.IsEmpty) throw new ArgumentNullException(nameof(result)); var x = this.temp; diff --git a/CSparse/Double/Factorization/SparseLDL.cs b/CSparse/Double/Factorization/SparseLDL.cs index 740da8e..de2713a 100644 --- a/CSparse/Double/Factorization/SparseLDL.cs +++ b/CSparse/Double/Factorization/SparseLDL.cs @@ -125,9 +125,9 @@ public int NonZerosCount /// Solution vector x. public void Solve(ReadOnlySpan input, Span result) { - if (input == null) throw new ArgumentNullException(nameof(input)); + if (input.IsEmpty) throw new ArgumentNullException(nameof(input)); - if (result == null) throw new ArgumentNullException(nameof(result)); + if (result.IsEmpty) throw new ArgumentNullException(nameof(result)); var x = temp; diff --git a/CSparse/Double/Factorization/SparseLU.cs b/CSparse/Double/Factorization/SparseLU.cs index 8d7d0a2..6ff2c26 100644 --- a/CSparse/Double/Factorization/SparseLU.cs +++ b/CSparse/Double/Factorization/SparseLU.cs @@ -123,9 +123,9 @@ public int NonZerosCount /// The left hand side vector, x. public void Solve(ReadOnlySpan input, Span result) { - if (input == null) throw new ArgumentNullException(nameof(input)); + if (input.IsEmpty) throw new ArgumentNullException(nameof(input)); - if (result == null) throw new ArgumentNullException(nameof(result)); + if (result.IsEmpty) throw new ArgumentNullException(nameof(result)); var x = this.temp; @@ -152,9 +152,9 @@ public void Solve(ReadOnlySpan input, Span result) /// The left hand side vector, x. public void SolveTranspose(ReadOnlySpan input, Span result) { - if (input == null) throw new ArgumentNullException(nameof(input)); + if (input.IsEmpty) throw new ArgumentNullException(nameof(input)); - if (result == null) throw new ArgumentNullException(nameof(result)); + if (result.IsEmpty) throw new ArgumentNullException(nameof(result)); var x = this.temp; diff --git a/CSparse/Double/Factorization/SparseQR.cs b/CSparse/Double/Factorization/SparseQR.cs index fea3394..9f88ee8 100644 --- a/CSparse/Double/Factorization/SparseQR.cs +++ b/CSparse/Double/Factorization/SparseQR.cs @@ -98,9 +98,9 @@ private SparseQR(int rows, int columns) /// public override void Solve(ReadOnlySpan input, Span result) { - if (input == null) throw new ArgumentNullException(nameof(input)); + if (input.IsEmpty) throw new ArgumentNullException(nameof(input)); - if (result == null) throw new ArgumentNullException(nameof(result)); + if (result.IsEmpty) throw new ArgumentNullException(nameof(result)); var x = new double[S.m2]; @@ -152,9 +152,9 @@ public override void Solve(ReadOnlySpan input, Span result) /// The left hand side vector, x. public void SolveTranspose(ReadOnlySpan input, Span result) { - if (input == null) throw new ArgumentNullException(nameof(input)); + if (input.IsEmpty) throw new ArgumentNullException(nameof(input)); - if (result == null) throw new ArgumentNullException(nameof(result)); + if (result.IsEmpty) throw new ArgumentNullException(nameof(result)); int m2 = S.m2; From 15ea612a91a009b7b56f2b629b706f2ecf93e964 Mon Sep 17 00:00:00 2001 From: wo80 Date: Tue, 11 Nov 2025 20:36:17 +0100 Subject: [PATCH 09/10] Add simple test for empty span check. --- CSparse.Tests/Complex/Factorization/SparseLUTest.cs | 9 +++++++++ CSparse.Tests/Double/Factorization/SparseLUTest.cs | 9 +++++++++ CSparse/Complex/Factorization/SparseLU.cs | 4 ++-- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/CSparse.Tests/Complex/Factorization/SparseLUTest.cs b/CSparse.Tests/Complex/Factorization/SparseLUTest.cs index de063ec..9ffac2d 100644 --- a/CSparse.Tests/Complex/Factorization/SparseLUTest.cs +++ b/CSparse.Tests/Complex/Factorization/SparseLUTest.cs @@ -3,6 +3,7 @@ namespace CSparse.Tests.Complex.Factorization using CSparse.Complex; using CSparse.Complex.Factorization; using NUnit.Framework; + using System; using Complex = System.Numerics.Complex; public class SparseLUTest @@ -30,6 +31,14 @@ public void TestSolve() A.Multiply(-1.0, x, 1.0, r); Assert.That(Vector.Norm(r.Length, r) < EPS, Is.True); + + // Test exceptions: + + var e1 = Assert.Throws(() => lu.Solve(b, null)); + var e2 = Assert.Throws(() => lu.Solve(null, x)); + + Assert.That(e1.ParamName, Is.EqualTo("result")); + Assert.That(e2.ParamName, Is.EqualTo("input")); } [Test] diff --git a/CSparse.Tests/Double/Factorization/SparseLUTest.cs b/CSparse.Tests/Double/Factorization/SparseLUTest.cs index 625d635..87d3bbc 100644 --- a/CSparse.Tests/Double/Factorization/SparseLUTest.cs +++ b/CSparse.Tests/Double/Factorization/SparseLUTest.cs @@ -3,6 +3,7 @@ namespace CSparse.Tests.Double.Factorization using CSparse.Double; using CSparse.Double.Factorization; using NUnit.Framework; + using System; public class SparseLUTest { @@ -29,6 +30,14 @@ public void TestSolve() A.Multiply(-1.0, x, 1.0, r); Assert.That(Vector.Norm(r.Length, r) < EPS, Is.True); + + // Test exceptions: + + var e1 = Assert.Throws(() => lu.Solve(b, null)); + var e2 = Assert.Throws(() => lu.Solve(null, x)); + + Assert.That(e1.ParamName, Is.EqualTo("result")); + Assert.That(e2.ParamName, Is.EqualTo("input")); } [Test] diff --git a/CSparse/Complex/Factorization/SparseLU.cs b/CSparse/Complex/Factorization/SparseLU.cs index c7ab391..60553bf 100644 --- a/CSparse/Complex/Factorization/SparseLU.cs +++ b/CSparse/Complex/Factorization/SparseLU.cs @@ -153,9 +153,9 @@ public void Solve(ReadOnlySpan input, Span result) /// The left hand side vector, x. public void SolveTranspose(ReadOnlySpan input, Span result) { - if (input == null) throw new ArgumentNullException(nameof(input)); + if (input.IsEmpty) throw new ArgumentNullException(nameof(input)); - if (result == null) throw new ArgumentNullException(nameof(result)); + if (result.IsEmpty) throw new ArgumentNullException(nameof(result)); var x = this.temp; From 6024091f6cda4793e2fc581ab9226365766913c5 Mon Sep 17 00:00:00 2001 From: wo80 Date: Tue, 11 Nov 2025 21:27:29 +0100 Subject: [PATCH 10/10] Update package version and release notes. --- CHANGELOG.md | 6 ++++++ CSparse.sln | 5 +++-- CSparse/CSparse.csproj | 39 ++++++++++++++++++++++----------------- 3 files changed, 31 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7612ab3..045a391 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +### Version 4.3.0 - 2025-11-11 + +* Add net10.0 and remove net6.0 target framework. +* Minor optimizations for matrix-vector multiplication. +* Minor optimizations checking empty Span. + ### Version 4.2.0 - 2024-09-15 * Make `SymbolicColumnStorage` class public and update `StronglyConnectedComponents` and `DulmageMendelsohn` decomposition accordingly. diff --git a/CSparse.sln b/CSparse.sln index 57511aa..7105c81 100644 --- a/CSparse.sln +++ b/CSparse.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.31025.194 +# Visual Studio Version 17 +VisualStudioVersion = 17.14.36705.20 d17.14 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CSparse", "CSparse\CSparse.csproj", "{BE369FD3-02F6-4A13-8DA2-E44A819FAE3C}" EndProject @@ -9,6 +9,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CSparse.Tests", "CSparse.Te EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{A01A8F54-DCC1-4E01-B6B4-1C653B382D30}" ProjectSection(SolutionItems) = preProject + CHANGELOG.md = CHANGELOG.md README.md = README.md EndProjectSection EndProject diff --git a/CSparse/CSparse.csproj b/CSparse/CSparse.csproj index 372534e..b5eb86b 100644 --- a/CSparse/CSparse.csproj +++ b/CSparse/CSparse.csproj @@ -9,38 +9,43 @@ CSparse.NET provides numerical methods for sparse LU, Cholesky and QR decomposition of real and complex linear systems. CSparse.NET - Copyright Christian Woltering © 2012-2024 + Copyright Christian Woltering © 2012-2025 Christian Woltering - 4.2.0.0 - 4.2.0.0 + 4.3.0.0 + 4.3.0.0 math sparse matrix lu cholesky qr decomposition factorization - 4.2.0 + 4.3.0 CSparse CSparse LGPL-2.1-only https://github.com/wo80/CSparse.NET https://github.com/wo80/CSparse.NET.git git - - Version 4.2.0 + Version 4.3.0 - * Make SymbolicColumnStorage class public and update StronglyConnectedComponents and DulmageMendelsohn decomposition accordingly. +* Add net10.0 and remove net6.0 target framework. +* Minor optimizations for matrix-vector multiplication. +* Minor optimizations checking empty Span. - Version 4.1.0 +Version 4.2.0 - * Add overload for creating a sparse matrix from an enumerable of ValueTuple. - * Add matrix EnumerateIndexedAsValueTuples() to enumerate entries as ValueTuple. +* Make SymbolicColumnStorage class public and update StronglyConnectedComponents and DulmageMendelsohn decomposition accordingly. - Version 4.0.0 +Version 4.1.0 - 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 overload for creating a sparse matrix from an enumerable of ValueTuple. +* Add matrix EnumerateIndexedAsValueTuples() to enumerate entries as ValueTuple. - Other changes in this version: +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. - +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. + +Other changes in this version: + +* Addition of helper method Helper.ValidateStorage(...) to validate the structure of a sparse matrix. +* Update to GetHashCode() method of CompressedColumnStorage class. +* Improvements to documentation. +