diff --git a/CSparse.Tests/CSparse.Tests.csproj b/CSparse.Tests/CSparse.Tests.csproj
index 195baf0..f58e88a 100644
--- a/CSparse.Tests/CSparse.Tests.csproj
+++ b/CSparse.Tests/CSparse.Tests.csproj
@@ -41,9 +41,9 @@
-
-
-
+
+
+
diff --git a/CSparse.Tests/Ordering/TestAMD.cs b/CSparse.Tests/Ordering/TestAMD.cs
new file mode 100644
index 0000000..60d3df4
--- /dev/null
+++ b/CSparse.Tests/Ordering/TestAMD.cs
@@ -0,0 +1,89 @@
+using CSparse.Ordering;
+using CSparse.Storage;
+using NUnit.Framework;
+
+namespace CSparse.Tests.Ordering
+{
+ class TestAMD
+ {
+ [Test]
+ public void TestAMD1()
+ {
+ int[] ap = [0, 9, 15, 21, 27, 33, 39, 48, 57, 61, 70, 76, 82, 88, 94, 100, 106, 110, 119, 128, 137, 143, 152, 156, 160];
+ int[] ai = [
+ /* col 0 */ 0, 5, 6, 12, 13, 17, 18, 19, 21,
+ /* col 1 */ 1, 8, 9, 13, 14, 17,
+ /* col 2 */ 2, 6, 11, 20, 21, 22,
+ /* col 3 */ 3, 7, 10, 15, 18, 19,
+ /* col 4 */ 4, 7, 9, 14, 15, 16,
+ /* col 5 */ 0, 5, 6, 12, 13, 17,
+ /* col 6 */ 0, 2, 5, 6, 11, 12, 19, 21, 23,
+ /* col 7 */ 3, 4, 7, 9, 14, 15, 16, 17, 18,
+ /* col 8 */ 1, 8, 9, 14,
+ /* col 9 */ 1, 4, 7, 8, 9, 13, 14, 17, 18,
+ /* col 10 */ 3, 10, 18, 19, 20, 21,
+ /* col 11 */ 2, 6, 11, 12, 21, 23,
+ /* col 12 */ 0, 5, 6, 11, 12, 23,
+ /* col 13 */ 0, 1, 5, 9, 13, 17,
+ /* col 14 */ 1, 4, 7, 8, 9, 14,
+ /* col 15 */ 3, 4, 7, 15, 16, 18,
+ /* col 16 */ 4, 7, 15, 16,
+ /* col 17 */ 0, 1, 5, 7, 9, 13, 17, 18, 19,
+ /* col 18 */ 0, 3, 7, 9, 10, 15, 17, 18, 19,
+ /* col 19 */ 0, 3, 6, 10, 17, 18, 19, 20, 21,
+ /* col 20 */ 2, 10, 19, 20, 21, 22,
+ /* col 21 */ 0, 2, 6, 10, 11, 19, 20, 21, 22,
+ /* col 22 */ 2, 20, 21, 22,
+ /* col 23 */ 6, 11, 12, 23 ];
+
+ var S = new SymbolicColumnStorage(24, 24, ap, ai, false);
+
+ var p = AMD.Generate(S, ColumnOrdering.MinimumDegreeAtA);
+
+ int[] expected = [8, 16, 4, 14, 15, 1, 7, 9, 22, 23, 2, 11, 3, 12, 13, 17, 18, 0, 10, 19, 20, 6, 21, 5, 24];
+
+ Assert.That(Permutation.IsValid(p), Is.True);
+ Assert.That(p, Is.EqualTo(expected).AsCollection);
+ }
+
+ [Test]
+ public void TestAMD2()
+ {
+ int[] ap = [0, 9, 14, 20, 28, 33, 37, 44, 53, 58, 63, 63, 66, 69, 72, 75, 78, 82, 86, 91, 97, 101, 112, 112, 116];
+ int[] ai = [
+ /* col 0 */ 0, 17, 18, 21, 5, 12, 5, 0, 13,
+ /* col 1 */ 14, 1, 8, 13, 17,
+ /* col 2 */ 2, 20, 11, 6, 11, 22,
+ /* col 3 */ 3, 3, 10, 7, 18, 18, 15, 19,
+ /* col 4 */ 7, 9, 15, 14, 16,
+ /* col 5 */ 5, 13, 6, 17,
+ /* col 6 */ 5, 0, 11, 6, 12, 6, 23,
+ /* col 7 */ 3, 4, 9, 7, 14, 16, 15, 17, 18,
+ /* col 8 */ 1, 9, 14, 14, 14,
+ /* col 9 */ 7, 13, 8, 1, 17,
+ /* col 10 */
+ /* col 11 */ 2, 12, 23,
+ /* col 12 */ 5, 11, 12,
+ /* col 13 */ 0, 13, 17,
+ /* col 14 */ 1, 9, 14,
+ /* col 15 */ 3, 15, 16,
+ /* col 16 */ 16, 4, 4, 15,
+ /* col 17 */ 13, 17, 19, 17,
+ /* col 18 */ 15, 17, 19, 9, 10,
+ /* col 19 */ 17, 19, 20, 0, 6, 10,
+ /* col 20 */ 22, 10, 20, 21,
+ /* col 21 */ 6, 2, 10, 19, 20, 11, 21, 22, 22, 22, 22,
+ /* col 22 */
+ /* col 23 */ 12, 11, 12, 23 ];
+
+ var S = new SymbolicColumnStorage(24, 24, ap, ai, false);
+
+ var p = AMD.Generate(S, ColumnOrdering.MinimumDegreeAtA);
+
+ int[] expected = [10, 11, 23, 12, 2, 6, 8, 14, 15, 16, 4, 1, 9, 7, 18, 3, 5, 17, 0, 19, 20, 21, 13, 22, 24];
+
+ Assert.That(Permutation.IsValid(p), Is.True);
+ Assert.That(p, Is.EqualTo(expected).AsCollection);
+ }
+ }
+}
diff --git a/CSparse.Tests/Ordering/TestDulmageMendelsohn.cs b/CSparse.Tests/Ordering/TestDulmageMendelsohn.cs
index 43faaf9..7dd64e0 100644
--- a/CSparse.Tests/Ordering/TestDulmageMendelsohn.cs
+++ b/CSparse.Tests/Ordering/TestDulmageMendelsohn.cs
@@ -1,6 +1,8 @@
namespace CSparse.Tests.Ordering
{
+ using CSparse.Double;
using CSparse.Ordering;
+ using CSparse.Storage;
using NUnit.Framework;
using System;
@@ -33,5 +35,46 @@ public void TestGenerate2()
Assert.That(dm.StructuralRank == n, Is.True);
}
+
+ [Test]
+ public void TestGenerate3()
+ {
+ var A = SparseMatrix.OfRowMajor(8, 8,
+ [
+ 11, 12, 0, 0, 0, 0, 0, 0,
+ 0, 22, 23, 0, 25, 26, 0, 0,
+ 0, 0, 33, 34, 0, 0, 37, 0,
+ 0, 0, 43, 44, 0, 0, 0, 48,
+ 51, 0, 0, 0, 55, 56, 0, 0,
+ 0, 0, 0, 0, 0, 66, 67, 0,
+ 0, 0, 0, 0, 0, 76, 77, 0,
+ 0, 0, 0, 84, 0, 0, 87, 88
+ ]);
+
+ var S = SymbolicColumnStorage.Create(A);
+
+ var dm = DulmageMendelsohn.Generate(S, 1);
+
+ Assert.That(dm.StructuralRank, Is.EqualTo(8));
+ Assert.That(dm.Blocks, Is.EqualTo(3));
+
+ int[] expected = [0, 1, 4, 2, 3, 7, 5, 6];
+
+ Assert.That(dm.RowPermutation, Is.EqualTo(expected).AsCollection);
+ Assert.That(dm.ColumnPermutation, Is.EqualTo(expected).AsCollection);
+
+ expected = [0, 3, 6, 8];
+
+ Assert.That(dm.BlockRowPointers, Is.EqualTo(expected).AsCollection);
+ Assert.That(dm.BlockColumnPointers, Is.EqualTo(expected).AsCollection);
+
+ expected = [0, 0, 8, 8, 8];
+
+ Assert.That(dm.CoarseRowDecomposition, Is.EqualTo(expected).AsCollection);
+
+ expected = [0, 0, 0, 8, 8];
+
+ Assert.That(dm.CoarseColumnDecomposition, Is.EqualTo(expected).AsCollection);
+ }
}
}
diff --git a/CSparse/CSparse.csproj b/CSparse/CSparse.csproj
index 05c3d12..87c411d 100644
--- a/CSparse/CSparse.csproj
+++ b/CSparse/CSparse.csproj
@@ -11,10 +11,10 @@
Copyright Christian Woltering © 2012-2024
Christian Woltering
- 4.1.0.0
- 4.1.0.0
+ 4.2.0.0
+ 4.2.0.0
math sparse matrix lu cholesky qr decomposition factorization
- 4.1.0
+ 4.2.0
CSparse
CSparse
LGPL-2.1-only
@@ -22,6 +22,10 @@
https://github.com/wo80/CSparse.NET.git
git
+ Version 4.2.0
+
+ * Make SymbolicColumnStorage class public and update StronglyConnectedComponents and DulmageMendelsohn decomposition accordingly.
+
Version 4.1.0
* Add overload for creating a sparse matrix from an enumerable of ValueTuple.
diff --git a/CSparse/Ordering/AMD.cs b/CSparse/Ordering/AMD.cs
index 0c71f76..8943232 100644
--- a/CSparse/Ordering/AMD.cs
+++ b/CSparse/Ordering/AMD.cs
@@ -25,6 +25,22 @@ public static class AMD
///
public static int[] Generate(CompressedColumnStorage A, ColumnOrdering order)
where T : struct, IEquatable, IFormattable
+ {
+ return Generate(SymbolicColumnStorage.Create(A), order);
+ }
+
+ ///
+ /// Generate minimum degree ordering of A+A' (if A is symmetric) or A'A.
+ ///
+ /// Column-compressed matrix
+ /// Column ordering method
+ /// amd(A+A') if A is symmetric, or amd(A'A) otherwise, null on
+ /// error or for natural ordering
+ ///
+ /// See Chapter 7.1 (Fill-reducing orderings: Minimum degree ordering) in
+ /// "Direct Methods for Sparse Linear Systems" by Tim Davis.
+ ///
+ public static int[] Generate(SymbolicColumnStorage A, ColumnOrdering order)
{
int[] Cp, Ci, P, W, nv, next, head, elen, degree, w, hhead;
@@ -42,7 +58,7 @@ public static int[] Generate(CompressedColumnStorage A, ColumnOrdering ord
return Permutation.Create(n);
}
- var C = ConstructMatrix(SymbolicColumnStorage.Create(A), order);
+ var C = ConstructMatrix(A, order);
Cp = C.ColumnPointers;
cnz = Cp[n];
@@ -139,7 +155,7 @@ public static int[] Generate(CompressedColumnStorage A, ColumnOrdering ord
Ci[p] = -(j + 2); // first entry is now CS_FLIP(j)
}
}
- for (q = 0, p = 0; p < cnz; ) // scan all of memory
+ for (q = 0, p = 0; p < cnz;) // scan all of memory
{
if ((j = FLIP(Ci[p++])) >= 0) // found object j
{
@@ -303,7 +319,7 @@ public static int[] Generate(CompressedColumnStorage A, ColumnOrdering ord
eln = elen[i];
for (p = Cp[i] + 1; p <= Cp[i] + ln - 1; p++) w[Ci[p]] = mark;
jlast = i;
- for (j = next[i]; j != -1; ) // compare i with all j
+ for (j = next[i]; j != -1;) // compare i with all j
{
ok = (W[j] == ln) && (elen[j] == eln);
for (p = Cp[j] + 1; ok && p <= Cp[j] + ln - 1; p++)
@@ -411,13 +427,13 @@ private static bool KeepOffDiag(int i, int j)
private static SymbolicColumnStorage ConstructMatrix(SymbolicColumnStorage A, ColumnOrdering order)
{
SymbolicColumnStorage result = null;
-
+
// Compute A'
var AT = A.Transpose();
int m = A.RowCount;
int n = A.ColumnCount;
-
+
if (order == ColumnOrdering.MinimumDegreeAtPlusA)
{
if (n != m)
@@ -444,7 +460,7 @@ private static SymbolicColumnStorage ConstructMatrix(SymbolicColumnStorage A, Co
{
// Column j of AT starts here.
p = colptr[j];
-
+
// New column j starts here.
colptr[j] = p2;
diff --git a/CSparse/Ordering/DulmageMendelsohn.cs b/CSparse/Ordering/DulmageMendelsohn.cs
index fd9fdf7..10636cd 100644
--- a/CSparse/Ordering/DulmageMendelsohn.cs
+++ b/CSparse/Ordering/DulmageMendelsohn.cs
@@ -22,7 +22,7 @@ public sealed class DulmageMendelsohn
private int nb; // number of blocks in fine dmperm decomposition
///
- /// Create a new Decomposition instance.
+ /// Create a new decomposition instance.
///
private DulmageMendelsohn(int m, int n)
{
@@ -97,22 +97,29 @@ public int Singletons
public int[] CoarseColumnDecomposition => cc;
///
- /// Compute coarse and then fine Dulmage-Mendelsohn decomposition. seed
- /// optionally selects a randomized algorithm.
+ /// Compute coarse and fine Dulmage-Mendelsohn decomposition.
///
/// column-compressed matrix
- /// 0: natural, -1: reverse, random order otherwise
+ /// The seed optionally selects a randomized algorithm (0 = default (natural), -1 = reverse, random order otherwise).
/// Dulmage-Mendelsohn analysis
public static DulmageMendelsohn Generate(CompressedColumnStorage matrix, int seed = 0)
where T : struct, IEquatable, IFormattable
+ {
+ return Generate(SymbolicColumnStorage.Create(matrix), seed);
+ }
+
+ ///
+ /// Compute coarse and fine Dulmage-Mendelsohn decomposition.
+ ///
+ /// The matrix represented by .
+ /// The seed optionally selects a randomized algorithm (0 = default (natural), -1 = reverse, random order otherwise).
+ /// Dulmage-Mendelsohn analysis
+ public static DulmageMendelsohn Generate(SymbolicColumnStorage A, int seed = 0)
{
int i, j, k, cnz, nc, nb1, nb2;
int[] Cp, ps, rs;
bool ok;
- // We are not interested in the actual matrix values.
- var A = SymbolicColumnStorage.Create(matrix);
-
// Maximum matching
int m = A.RowCount;
int n = A.ColumnCount;
@@ -147,7 +154,7 @@ public static DulmageMendelsohn Generate(CompressedColumnStorage matrix, i
// Fine decomposition
int[] pinv = Permutation.Invert(p); // pinv=p'
- var C = SymbolicColumnStorage.Create(matrix);
+ var C = A.Clone();
A.Permute(pinv, q, C); // C=A(p,q) (it will hold A(R2,C2))
Cp = C.ColumnPointers;
diff --git a/CSparse/Ordering/StronglyConnectedComponents.cs b/CSparse/Ordering/StronglyConnectedComponents.cs
index cf38d30..434be23 100644
--- a/CSparse/Ordering/StronglyConnectedComponents.cs
+++ b/CSparse/Ordering/StronglyConnectedComponents.cs
@@ -48,19 +48,31 @@ private StronglyConnectedComponents(int m, int n)
public static StronglyConnectedComponents Generate(CompressedColumnStorage matrix)
where T : struct, IEquatable, IFormattable
{
- return Generate(SymbolicColumnStorage.Create(matrix, false), matrix.ColumnCount);
+ return Generate(SymbolicColumnStorage.Create(matrix, false));
}
-
+
///
- /// Find strongly connected components of A.
+ /// Compute strongly connected components of A.
///
- ///
- ///
- ///
- internal static StronglyConnectedComponents Generate(SymbolicColumnStorage A, int n)
+ /// The matrix represented by .
+ /// Strongly connected components
+ public static StronglyConnectedComponents Generate(SymbolicColumnStorage A)
+ {
+ return Generate(A, A.ColumnCount);
+ }
+
+ ///
+ /// Compute strongly connected components of A.
+ ///
+ /// The matrix represented by .
+ /// The size of the matrix.
+ /// Strongly connected components
+ public static StronglyConnectedComponents Generate(SymbolicColumnStorage A, int size)
{
// matrix A temporarily modified, then restored
+ int n = size;
+
int i, k, b, nb = 0, top;
int[] xi, p, r, Ap, ATp;
diff --git a/CSparse/Storage/CompressedColumnStorage.cs b/CSparse/Storage/CompressedColumnStorage.cs
index 47d2593..feb8169 100644
--- a/CSparse/Storage/CompressedColumnStorage.cs
+++ b/CSparse/Storage/CompressedColumnStorage.cs
@@ -40,10 +40,7 @@ public abstract class CompressedColumnStorage : Matrix
///
/// Gets the number of non-zero entries.
///
- public int NonZerosCount
- {
- get { return ColumnPointers[columns]; }
- }
+ public int NonZerosCount => ColumnPointers[columns];
///
/// Initializes a new instance of the class.
diff --git a/CSparse/Storage/SymbolicColumnStorage.cs b/CSparse/Storage/SymbolicColumnStorage.cs
index 04715ac..c3c88dc 100644
--- a/CSparse/Storage/SymbolicColumnStorage.cs
+++ b/CSparse/Storage/SymbolicColumnStorage.cs
@@ -9,7 +9,7 @@ namespace CSparse.Storage
///
/// Used for ordering and symbolic factorization.
///
- internal class SymbolicColumnStorage
+ public class SymbolicColumnStorage
{
private int rowCount;
private int columnCount;
@@ -27,27 +27,26 @@ internal class SymbolicColumnStorage
///
/// Gets the number of rows.
///
- public int RowCount
- {
- get { return rowCount; }
- }
+ public int RowCount => rowCount;
///
/// Gets the number of columns.
///
- public int ColumnCount
- {
- get { return columnCount; }
- }
+ public int ColumnCount => columnCount;
///
/// Gets the number of non-zero entries.
///
- public int NonZerosCount
- {
- get { return ColumnPointers[columnCount]; }
- }
+ public int NonZerosCount => ColumnPointers[columnCount];
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The number of rows.
+ /// The number of columns.
+ /// The number of non-zero values.
+ /// If true, both and arrays will be allocated.
+ ///
public SymbolicColumnStorage(int rowCount, int columnCount, int valueCount, bool allocate)
{
// Explicitly allow m or n = 0 (may occur in Dulmage-Mendelsohn decomposition).
@@ -61,27 +60,77 @@ public SymbolicColumnStorage(int rowCount, int columnCount, int valueCount, bool
if (allocate)
{
- this.ColumnPointers = new int[columnCount + 1];
- this.RowIndices = new int[valueCount];
+ ColumnPointers = new int[columnCount + 1];
+ RowIndices = new int[valueCount];
}
}
///
- /// Change the shape of the matrix (only used by Dulmage-Mendelsohn decomposition).
+ /// Initializes a new instance of the class.
///
- ///
- ///
- internal void Reshape(int rowCount, int columnCount)
+ /// The number of rows.
+ /// The number of columns.
+ /// The number of non-zero values.
+ /// The number of non-zero values.
+ /// If true, both and arrays will be copied to new arrays.
+ ///
+ public SymbolicColumnStorage(int rowCount, int columnCount, int[] columnPointers, int[] rowIndices, bool copy)
{
- if (rowCount >= 0)
+ // Explicitly allow m or n = 0 (may occur in Dulmage-Mendelsohn decomposition).
+ if (rowCount < 0 || columnCount < 0)
{
- this.rowCount = rowCount;
+ throw new ArgumentOutOfRangeException(Resources.MatrixDimensionNonNegative);
}
- if (columnCount >= 0)
+
+ if (columnPointers is null)
{
- this.columnCount = columnCount;
- //Array.Resize(ref this.ColumnPointers, columnCount + 1);
+ throw new ArgumentNullException(nameof(columnPointers));
}
+
+ if (rowIndices is null)
+ {
+ throw new ArgumentNullException(nameof(rowIndices));
+ }
+
+ if (columnPointers.Length < columnCount + 1)
+ {
+ throw new ArgumentOutOfRangeException(nameof(columnPointers), "Column pointers array size doesn't match given column count argument.");
+ }
+
+ if (rowIndices.Length < columnPointers[columnCount])
+ {
+ throw new ArgumentOutOfRangeException(nameof(rowIndices), "Row indices array size doesn't match non-zeros count.");
+ }
+
+ this.rowCount = rowCount;
+ this.columnCount = columnCount;
+
+ if (copy)
+ {
+ int valueCount = rowIndices.Length;
+
+ ColumnPointers = new int[columnCount + 1];
+ RowIndices = new int[valueCount];
+
+ Buffer.BlockCopy(columnPointers, 0, ColumnPointers, 0, (columnCount + 1) * Constants.SizeOfInt);
+ Buffer.BlockCopy(rowIndices, 0, RowIndices, 0, valueCount * Constants.SizeOfInt);
+ }
+ else
+ {
+ ColumnPointers = columnPointers;
+ RowIndices = rowIndices;
+ }
+ }
+
+ ///
+ /// Creates a new instance of the class.
+ ///
+ /// The sparse matrix to create the from.
+ /// If true, both column pointers and row indices arrays of will be copied to new arrays.
+ public static SymbolicColumnStorage Create(CompressedColumnStorage A, bool copy = true)
+ where T : struct, IEquatable, IFormattable
+ {
+ return new SymbolicColumnStorage(A.RowCount, A.ColumnCount, A.ColumnPointers, A.RowIndices, copy);
}
///
@@ -93,16 +142,16 @@ public bool Resize(int size)
{
if (size <= 0)
{
- size = this.ColumnPointers[columnCount];
+ size = ColumnPointers[columnCount];
}
- Array.Resize(ref this.RowIndices, size);
+ Array.Resize(ref RowIndices, size);
return true;
}
///
- /// Sort column indices using insertion sort.
+ /// Sort column indices.
///
public void Sort()
{
@@ -138,16 +187,19 @@ public void Sort()
}
}
+ ///
+ /// Returns a copy of the .
+ ///
+ ///
public SymbolicColumnStorage Clone()
{
- int m = this.RowCount;
- int n = this.ColumnCount;
- int nnz = this.NonZerosCount;
+ int n = ColumnCount;
+ int nnz = NonZerosCount;
- var result = new SymbolicColumnStorage(m, n, nnz, true);
+ var result = new SymbolicColumnStorage(RowCount, n, nnz, true);
- Buffer.BlockCopy(this.ColumnPointers, 0, result.ColumnPointers, 0, (n + 1) * Constants.SizeOfInt);
- Buffer.BlockCopy(this.RowIndices, 0, result.RowIndices, 0, nnz * Constants.SizeOfInt);
+ Buffer.BlockCopy(ColumnPointers, 0, result.ColumnPointers, 0, (n + 1) * Constants.SizeOfInt);
+ Buffer.BlockCopy(RowIndices, 0, result.RowIndices, 0, nnz * Constants.SizeOfInt);
return result;
}
@@ -162,8 +214,8 @@ public virtual SymbolicColumnStorage Transpose()
{
int j, k, p;
- int m = this.RowCount;
- int n = this.ColumnCount;
+ int m = RowCount;
+ int n = ColumnCount;
var result = new SymbolicColumnStorage(n, m, 0, false);
@@ -232,7 +284,7 @@ public SymbolicColumnStorage Add(SymbolicColumnStorage other)
{
// Column j of result starts here
cp[j] = nz;
- nz = this.Scatter(j, w, j + 1, ci, nz); // A(:,j)
+ nz = Scatter(j, w, j + 1, ci, nz); // A(:,j)
nz = other.Scatter(j, w, j + 1, ci, nz); // B(:,j)
}
@@ -259,15 +311,15 @@ public SymbolicColumnStorage Multiply(SymbolicColumnStorage other)
{
int p, j, nz = 0;
- if (this.columnCount != other.rowCount)
+ if (columnCount != other.rowCount)
{
throw new ArgumentException();
}
- int m = this.rowCount;
+ int m = rowCount;
int n = other.columnCount;
- int anz = this.NonZerosCount;
+ int anz = NonZerosCount;
int bnz = other.NonZerosCount;
var bp = other.ColumnPointers;
@@ -292,7 +344,7 @@ public SymbolicColumnStorage Multiply(SymbolicColumnStorage other)
for (p = bp[j]; p < bp[j + 1]; p++)
{
- nz = this.Scatter(bi[p], work, j + 1, ci, nz);
+ nz = Scatter(bi[p], work, j + 1, ci, nz);
}
}
@@ -319,10 +371,10 @@ public virtual void Permute(int[] pinv, int[] q, SymbolicColumnStorage result)
{
int i, j, k, nz = 0;
- int n = this.columnCount;
+ int n = columnCount;
- int[] ap = this.ColumnPointers;
- int[] ai = this.RowIndices;
+ int[] ap = ColumnPointers;
+ int[] ai = RowIndices;
// Allocate memory if needed.
if (result.ColumnPointers == null)
@@ -350,6 +402,24 @@ public virtual void Permute(int[] pinv, int[] q, SymbolicColumnStorage result)
#endregion
+ ///
+ /// Change the shape of the matrix (only used by Dulmage-Mendelsohn decomposition).
+ ///
+ ///
+ ///
+ internal void Reshape(int rowCount, int columnCount)
+ {
+ if (rowCount >= 0)
+ {
+ this.rowCount = rowCount;
+ }
+ if (columnCount >= 0)
+ {
+ this.columnCount = columnCount;
+ //Array.Resize(ref this.ColumnPointers, columnCount + 1);
+ }
+ }
+
///
/// Drops entries from a sparse matrix
///
@@ -381,7 +451,7 @@ internal int Keep(Func func)
ColumnPointers[columnCount] = nz;
// Remove extra space.
- Array.Resize(ref this.RowIndices, nz);
+ Array.Resize(ref RowIndices, nz);
return nz;
}
@@ -411,28 +481,5 @@ private int Scatter(int j, int[] work, int mark, int[] ci, int nz)
return nz;
}
-
- internal static SymbolicColumnStorage Create(CompressedColumnStorage mat, bool allocate = true)
- where T : struct, IEquatable, IFormattable
- {
- int m = mat.RowCount;
- int n = mat.ColumnCount;
- int nnz = mat.NonZerosCount;
-
- var result = new SymbolicColumnStorage(m, n, nnz, allocate);
-
- if (allocate)
- {
- Buffer.BlockCopy(mat.ColumnPointers, 0, result.ColumnPointers, 0, (n + 1) * Constants.SizeOfInt);
- Buffer.BlockCopy(mat.RowIndices, 0, result.RowIndices, 0, nnz * Constants.SizeOfInt);
- }
- else
- {
- result.ColumnPointers = mat.ColumnPointers;
- result.RowIndices = mat.RowIndices;
- }
-
- return result;
- }
}
}