diff --git a/CHANGELOG.md b/CHANGELOG.md
index 045a391..bc3bab2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,7 @@
+### Version 4.4.0 - 2026-06-10
+
+* Add Refactorize methods to SparseCholesky, SparseLDL and SparseLU
+
### Version 4.3.0 - 2025-11-11
* Add net10.0 and remove net6.0 target framework.
diff --git a/CSparse.Tests/CSparse.Tests.csproj b/CSparse.Tests/CSparse.Tests.csproj
index a795c2b..e4cb7b0 100644
--- a/CSparse.Tests/CSparse.Tests.csproj
+++ b/CSparse.Tests/CSparse.Tests.csproj
@@ -41,9 +41,9 @@
-
-
-
+
+
+
diff --git a/CSparse.Tests/Complex/ComplexNumberComparer.cs b/CSparse.Tests/Complex/ComplexNumberComparer.cs
index 0a98cdd..ab2adce 100644
--- a/CSparse.Tests/Complex/ComplexNumberComparer.cs
+++ b/CSparse.Tests/Complex/ComplexNumberComparer.cs
@@ -11,7 +11,7 @@ namespace CSparse.Tests.Complex
public class ComplexNumberComparer : IComparer, IComparer
{
- public static ComplexNumberComparer Default = new ComplexNumberComparer();
+ public static ComplexNumberComparer Default = new();
// Floating point tolerance
const double TOL = 1e-8;
diff --git a/CSparse.Tests/Complex/MatrixHelper.cs b/CSparse.Tests/Complex/MatrixHelper.cs
index db1081d..b5dfdc6 100644
--- a/CSparse.Tests/Complex/MatrixHelper.cs
+++ b/CSparse.Tests/Complex/MatrixHelper.cs
@@ -4,22 +4,18 @@ namespace CSparse.Tests.Complex
using CSparse.Storage;
using System.Collections.Generic;
using System.IO;
- using System.Linq;
using System.Numerics;
class MatrixHelper
{
- private static Dictionary> dense = new Dictionary>();
-
- private static Dictionary> sparse = new Dictionary>();
+ private static readonly Dictionary> dense = [];
+ private static readonly Dictionary> sparse = [];
public static SparseTestData LoadSparse(int rows, int columns)
{
string resource = string.Format("test-data-dense-{0}x{1}.txt", rows, columns);
- SparseTestData data;
-
- if (!sparse.TryGetValue(resource, out data))
+ if (!sparse.TryGetValue(resource, out SparseTestData data))
{
var dense = LoadDense(rows, columns);
@@ -35,9 +31,7 @@ public static DenseTestData LoadDense(int rows, int columns)
{
string resource = string.Format("test-data-dense-{0}x{1}.txt", rows, columns);
- DenseTestData data;
-
- if (!dense.TryGetValue(resource, out data))
+ if (!dense.TryGetValue(resource, out DenseTestData data))
{
var stream = ResourceLoader.GetStream(resource, "Double");
@@ -53,22 +47,21 @@ private static DenseTestData ReadDenseTestData(Stream stream)
{
var data = Tests.Double.DenseTestDataReader.Read(stream);
- var result = new DenseTestData();
-
- result.A = ToComplex(data.A);
- result.B = ToComplex(data.B);
- result.x = ToComplex(data.x);
- result.y = ToComplex(data.y);
- result.AT = ToComplex(data.AT);
- result.BT = ToComplex(data.BT);
- result.ApB = ToComplex(data.ApB);
- result.AmBT = ToComplex(data.AmBT);
- result.ATmB = ToComplex(data.ATmB);
- result.Ax = ToComplex(data.Ax);
- result.ATy = ToComplex(data.ATy);
- result.xTBT = ToComplex(data.xTBT);
-
- return result;
+ return new DenseTestData
+ {
+ A = ToComplex(data.A),
+ B = ToComplex(data.B),
+ x = ToComplex(data.x),
+ y = ToComplex(data.y),
+ AT = ToComplex(data.AT),
+ BT = ToComplex(data.BT),
+ ApB = ToComplex(data.ApB),
+ AmBT = ToComplex(data.AmBT),
+ ATmB = ToComplex(data.ATmB),
+ Ax = ToComplex(data.Ax),
+ ATy = ToComplex(data.ATy),
+ xTBT = ToComplex(data.xTBT)
+ };
}
private static Complex[] ToComplex(double[] vec)
@@ -101,26 +94,23 @@ private static DenseColumnMajorStorage ToComplex(DenseColumnMajorStorag
private static SparseTestData DenseToSparse(DenseTestData dense)
{
- var data = new SparseTestData()
+ return new SparseTestData
{
RowCount = dense.RowCount,
- ColumnCount = dense.ColumnCount
+ ColumnCount = dense.ColumnCount,
+ A = DenseToSparse(dense.A),
+ B = DenseToSparse(dense.B),
+ x = dense.x,
+ y = dense.y,
+ AT = DenseToSparse(dense.AT),
+ BT = DenseToSparse(dense.BT),
+ ApB = DenseToSparse(dense.ApB),
+ AmBT = DenseToSparse(dense.AmBT),
+ ATmB = DenseToSparse(dense.ATmB),
+ Ax = dense.Ax,
+ ATy = dense.ATy,
+ xTBT = dense.xTBT
};
-
- data.A = DenseToSparse(dense.A);
- data.B = DenseToSparse(dense.B);
- data.x = dense.x;
- data.y = dense.y;
- data.AT = DenseToSparse(dense.AT);
- data.BT = DenseToSparse(dense.BT);
- data.ApB = DenseToSparse(dense.ApB);
- data.AmBT = DenseToSparse(dense.AmBT);
- data.ATmB = DenseToSparse(dense.ATmB);
- data.Ax = dense.Ax;
- data.ATy = dense.ATy;
- data.xTBT = dense.xTBT;
-
- return data;
}
private static CompressedColumnStorage DenseToSparse(DenseColumnMajorStorage dense)
diff --git a/CSparse.Tests/Double/DenseTestDataReader.cs b/CSparse.Tests/Double/DenseTestDataReader.cs
index 72b99b5..06504c7 100644
--- a/CSparse.Tests/Double/DenseTestDataReader.cs
+++ b/CSparse.Tests/Double/DenseTestDataReader.cs
@@ -9,80 +9,77 @@ class DenseTestDataReader
{
public static DenseTestData Read(Stream stream)
{
- using (var reader = new StreamReader(stream))
+ using var reader = new StreamReader(stream);
+
+ string line = reader.ReadLine();
+
+ GetItem(line, out string name, out string value);
+
+ if (name != "size")
{
- string line, name, value;
+ throw new FormatException("Expected first line = size.");
+ }
- line = reader.ReadLine();
+ var data = ReadSize(value);
+ int m = data.RowCount;
+ int n = data.ColumnCount;
+
+ while ((line = reader.ReadLine()) != null)
+ {
GetItem(line, out name, out value);
- if (name != "size")
+ if (name == "A")
{
- throw new FormatException("Expected first line = size.");
+ data.A = ReadMatrix(value, m, n);
}
-
- var data = ReadSize(value);
-
- int m = data.RowCount;
- int n = data.ColumnCount;
-
- while ((line = reader.ReadLine()) != null)
+ else if (name == "B")
{
- GetItem(line, out name, out value);
-
- if (name == "A")
- {
- data.A = ReadMatrix(value, m, n);
- }
- else if (name == "B")
- {
- data.B = ReadMatrix(value, m, n);
- }
- else if (name == "x")
- {
- data.x = ReadVector(value, n);
- }
- else if (name == "y")
- {
- data.y = ReadVector(value, m);
- }
- else if (name == "A'")
- {
- data.AT = ReadMatrix(value, n, m);
- }
- else if (name == "B'")
- {
- data.BT = ReadMatrix(value, n, m);
- }
- else if (name == "A+B")
- {
- data.ApB = ReadMatrix(value, m, n);
- }
- else if (name == "A*B'")
- {
- data.AmBT = ReadMatrix(value, m, m);
- }
- else if (name == "A'*B")
- {
- data.ATmB = ReadMatrix(value, n, n);
- }
- else if (name == "A*x")
- {
- data.Ax = ReadVector(value, m);
- }
- else if (name == "A'*y")
- {
- data.ATy = ReadVector(value, n);
- }
- else if (name == "x'*B'")
- {
- data.xTBT = ReadVector(value, m);
- }
+ data.B = ReadMatrix(value, m, n);
+ }
+ else if (name == "x")
+ {
+ data.x = ReadVector(value, n);
+ }
+ else if (name == "y")
+ {
+ data.y = ReadVector(value, m);
+ }
+ else if (name == "A'")
+ {
+ data.AT = ReadMatrix(value, n, m);
+ }
+ else if (name == "B'")
+ {
+ data.BT = ReadMatrix(value, n, m);
+ }
+ else if (name == "A+B")
+ {
+ data.ApB = ReadMatrix(value, m, n);
+ }
+ else if (name == "A*B'")
+ {
+ data.AmBT = ReadMatrix(value, m, m);
+ }
+ else if (name == "A'*B")
+ {
+ data.ATmB = ReadMatrix(value, n, n);
+ }
+ else if (name == "A*x")
+ {
+ data.Ax = ReadVector(value, m);
+ }
+ else if (name == "A'*y")
+ {
+ data.ATy = ReadVector(value, n);
+ }
+ else if (name == "x'*B'")
+ {
+ data.xTBT = ReadVector(value, m);
}
-
- return data;
}
+
+ return data;
}
private static void GetItem(string line, out string name, out string value)
diff --git a/CSparse.Tests/Double/MatrixHelper.cs b/CSparse.Tests/Double/MatrixHelper.cs
index a2cff13..363332d 100644
--- a/CSparse.Tests/Double/MatrixHelper.cs
+++ b/CSparse.Tests/Double/MatrixHelper.cs
@@ -5,17 +5,14 @@ namespace CSparse.Tests.Double
class MatrixHelper
{
- private static Dictionary> dense = new Dictionary>();
-
- private static Dictionary> sparse = new Dictionary>();
+ private static readonly Dictionary> dense = [];
+ private static readonly Dictionary> sparse = [];
public static SparseTestData LoadSparse(int rows, int columns)
{
string resource = string.Format("test-data-dense-{0}x{1}.txt", rows, columns);
- SparseTestData data;
-
- if (!sparse.TryGetValue(resource, out data))
+ if (!sparse.TryGetValue(resource, out SparseTestData data))
{
var dense = LoadDense(rows, columns);
@@ -31,9 +28,7 @@ public static DenseTestData LoadDense(int rows, int columns)
{
string resource = string.Format("test-data-dense-{0}x{1}.txt", rows, columns);
- DenseTestData data;
-
- if (!dense.TryGetValue(resource, out data))
+ if (!dense.TryGetValue(resource, out DenseTestData data))
{
var stream = ResourceLoader.GetStream(resource, "Double");
@@ -47,26 +42,23 @@ public static DenseTestData LoadDense(int rows, int columns)
private static SparseTestData DenseToSparse(DenseTestData dense)
{
- var data = new SparseTestData()
+ return new SparseTestData
{
RowCount = dense.RowCount,
- ColumnCount = dense.ColumnCount
+ ColumnCount = dense.ColumnCount,
+ A = DenseToSparse(dense.A),
+ B = DenseToSparse(dense.B),
+ x = dense.x,
+ y = dense.y,
+ AT = DenseToSparse(dense.AT),
+ BT = DenseToSparse(dense.BT),
+ ApB = DenseToSparse(dense.ApB),
+ AmBT = DenseToSparse(dense.AmBT),
+ ATmB = DenseToSparse(dense.ATmB),
+ Ax = dense.Ax,
+ ATy = dense.ATy,
+ xTBT = dense.xTBT
};
-
- data.A = DenseToSparse(dense.A);
- data.B = DenseToSparse(dense.B);
- data.x = dense.x;
- data.y = dense.y;
- data.AT = DenseToSparse(dense.AT);
- data.BT = DenseToSparse(dense.BT);
- data.ApB = DenseToSparse(dense.ApB);
- data.AmBT = DenseToSparse(dense.AmBT);
- data.ATmB = DenseToSparse(dense.ATmB);
- data.Ax = dense.Ax;
- data.ATy = dense.ATy;
- data.xTBT = dense.xTBT;
-
- return data;
}
private static CompressedColumnStorage DenseToSparse(DenseColumnMajorStorage dense)
diff --git a/CSparse.Tests/IO/TestMatrixMarketReader.cs b/CSparse.Tests/IO/TestMatrixMarketReader.cs
index 0a26212..d7edfcb 100644
--- a/CSparse.Tests/IO/TestMatrixMarketReader.cs
+++ b/CSparse.Tests/IO/TestMatrixMarketReader.cs
@@ -10,35 +10,31 @@ public class TestMatrixMarketReader
[Test]
public void TestSymmetric()
{
- var stream = ResourceLoader.GetStream("LFAT5.mtx", "Double");
+ using var stream = ResourceLoader.GetStream("LFAT5.mtx", "Double");
+ using var reader = new StreamReader(stream);
- using (var reader = new StreamReader(stream))
- {
- var A = MatrixMarketReader.ReadStorage(reader);
+ var A = MatrixMarketReader.ReadStorage(reader);
- Assert.That(14, Is.EqualTo(A.RowCount));
- Assert.That(14, Is.EqualTo(A.ColumnCount));
+ Assert.That(14, Is.EqualTo(A.RowCount));
+ Assert.That(14, Is.EqualTo(A.ColumnCount));
- // Symmetric mtx file has 30 entries -> auto expand = 2 * 30 - 14 = 46.
- Assert.That(46, Is.EqualTo(A.NonZerosCount));
- }
+ // Symmetric mtx file has 30 entries -> auto expand = 2 * 30 - 14 = 46.
+ Assert.That(46, Is.EqualTo(A.NonZerosCount));
}
[Test]
public void TestPatternSymmetric()
{
- var stream = ResourceLoader.GetStream("bcspwr01.mtx", "Double");
+ using var stream = ResourceLoader.GetStream("bcspwr01.mtx", "Double");
+ using var reader = new StreamReader(stream);
- using (var reader = new StreamReader(stream))
- {
- var A = MatrixMarketReader.ReadStorage(reader, false);
+ var A = MatrixMarketReader.ReadStorage(reader, false);
- Assert.That(39, Is.EqualTo(A.RowCount));
- Assert.That(39, Is.EqualTo(A.ColumnCount));
+ Assert.That(39, Is.EqualTo(A.RowCount));
+ Assert.That(39, Is.EqualTo(A.ColumnCount));
- // Symmetric mtx file has 85 entries, no auto expand.
- Assert.That(85, Is.EqualTo(A.NonZerosCount));
- }
+ // Symmetric mtx file has 85 entries, no auto expand.
+ Assert.That(85, Is.EqualTo(A.NonZerosCount));
}
}
}
diff --git a/CSparse.Tests/IO/TestMatrixMarketWriter.cs b/CSparse.Tests/IO/TestMatrixMarketWriter.cs
index d10c984..e3584b2 100644
--- a/CSparse.Tests/IO/TestMatrixMarketWriter.cs
+++ b/CSparse.Tests/IO/TestMatrixMarketWriter.cs
@@ -8,12 +8,12 @@ namespace CSparse.Tests.IO
public class TestMatrixMarketWriter
{
- private static readonly double[] DenseA = new[]
- {
+ private static readonly double[] DenseA =
+ [
1.0, 0.0, 0.5,
0.0, 2.0, 0.1,
0.5, 0.1, 3.0,
- };
+ ];
[Test]
public void TestWriteSparse()
diff --git a/CSparse.Tests/Ordering/TestStronglyConnectedComponents.cs b/CSparse.Tests/Ordering/TestStronglyConnectedComponents.cs
index dda086c..2aaa7c7 100644
--- a/CSparse.Tests/Ordering/TestStronglyConnectedComponents.cs
+++ b/CSparse.Tests/Ordering/TestStronglyConnectedComponents.cs
@@ -25,8 +25,8 @@ public void TestScc()
//
// Adjacency matrix:
- var A = SparseMatrix.OfRowMajor(8, 8, new double[8 * 8]
- {
+ var A = SparseMatrix.OfRowMajor(8, 8,
+ [
1, 1, 0, 0, 0, 0, 0, 0,
0, 1, 1, 0, 1, 1, 0, 0,
0, 0, 1, 1, 0, 0, 1, 0,
@@ -35,7 +35,7 @@ public void TestScc()
0, 0, 0, 0, 0, 1, 1, 0,
0, 0, 0, 0, 0, 1, 1, 0,
0, 0, 0, 1, 0, 0, 1, 1
- });
+ ]);
int n = A.ColumnCount;
diff --git a/CSparse.Tests/ResourceLoader.cs b/CSparse.Tests/ResourceLoader.cs
index 5e2fa69..dd1df57 100644
--- a/CSparse.Tests/ResourceLoader.cs
+++ b/CSparse.Tests/ResourceLoader.cs
@@ -11,7 +11,7 @@ static class ResourceLoader
{
private const string NS = "CSparse.Tests.{Type}.Data";
- private static Dictionary cache = new Dictionary();
+ private static readonly Dictionary cache = [];
public static Stream GetStream(string resource, string type)
{
@@ -29,14 +29,13 @@ public static CompressedColumnStorage Get(string resource)
string path = NS.Replace("{Type}", type) + "." + resource;
- object obj;
- if (cache.TryGetValue(path, out obj))
+ if (cache.TryGetValue(path, out object obj))
{
return (CompressedColumnStorage)obj;
}
- var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(path);
+ using var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(path);
var matrix = MatrixMarketReader.ReadMatrix(stream);
diff --git a/CSparse/CSparse.csproj b/CSparse/CSparse.csproj
index b5eb86b..52a920a 100644
--- a/CSparse/CSparse.csproj
+++ b/CSparse/CSparse.csproj
@@ -9,19 +9,23 @@
CSparse.NET provides numerical methods for sparse LU, Cholesky and QR decomposition of real and complex linear systems.
CSparse.NET
- Copyright Christian Woltering © 2012-2025
+ Copyright Christian Woltering © 2012-2026
Christian Woltering
- 4.3.0.0
- 4.3.0.0
- math sparse matrix lu cholesky qr decomposition factorization
- 4.3.0
+ 4.4.0.0
+ 4.4.0.0
+ math sparse matrix lu cholesky qr decomposition factorization
+ 4.4.0
CSparse
CSparse
LGPL-2.1-only
https://github.com/wo80/CSparse.NET
https://github.com/wo80/CSparse.NET.git
git
- Version 4.3.0
+ Version 4.4.0
+
+* Add Refactorize methods to SparseCholesky, SparseLDL and SparseLU
+
+Version 4.3.0
* Add net10.0 and remove net6.0 target framework.
* Minor optimizations for matrix-vector multiplication.