Skip to content

Commit e2570fb

Browse files
committed
Add a helper method to validate the storage of a sparse matrix.
1 parent c45e535 commit e2570fb

File tree

2 files changed

+78
-0
lines changed

2 files changed

+78
-0
lines changed

CSparse.Tests/HelperTest.cs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11

22
namespace CSparse.Tests
33
{
4+
using CSparse.Double;
45
using NUnit.Framework;
56

67
using C = System.Numerics.Complex;
@@ -33,5 +34,36 @@ public void TestTrimStorage()
3334
Assert.That(A.RowIndices.Length, Is.EqualTo(0));
3435
Assert.That(A.Values.Length, Is.EqualTo(0));
3536
}
37+
38+
[Test]
39+
public void TestValidateStorage()
40+
{
41+
var ap = new int[] { 0, 3, 6 };
42+
var ai = new int[] { 0, 1, 2, 0, 1, 2 };
43+
var ax = new double[] { 0, 0, 0, 0, 0, 0 };
44+
45+
var A = new SparseMatrix(3, 2, ax, ai, ap);
46+
47+
Assert.That(Helper.ValidateStorage(A), Is.True);
48+
49+
// Change order of column pointers.
50+
ap[1] = 6; ap[2] = 3;
51+
52+
Assert.That(Helper.ValidateStorage(A), Is.False);
53+
54+
// Revert change to column pointers.
55+
ap[1] = 3; ap[2] = 6;
56+
57+
// Row index larger than number of rows.
58+
ai[2] = 3;
59+
60+
Assert.That(Helper.ValidateStorage(A), Is.False);
61+
62+
// Change order of row indices.
63+
ai[1] = 2; ai[2] = 1;
64+
65+
Assert.That(Helper.ValidateStorage(A), Is.True);
66+
Assert.That(Helper.ValidateStorage(A, true), Is.False);
67+
}
3668
}
3769
}

CSparse/Helper.cs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,52 @@ public static int CumulativeSum(int[] sum, int[] counts, int size)
3131
return nz;
3232
}
3333

34+
/// <summary>
35+
/// Validate the structure of the <see cref="CompressedColumnStorage{T}"/>.
36+
/// </summary>
37+
/// <typeparam name="T"></typeparam>
38+
/// <param name="storage">The storage to validate.</param>
39+
/// <param name="strict">If true, row indices have to be ordered and no duplicate indices are allowed (default = <c>false</c>).</param>
40+
/// <returns>Returns true if the structure of the storage is valid.</returns>
41+
public static bool ValidateStorage<T>(CompressedColumnStorage<T> storage, bool strict = false)
42+
where T : struct, IEquatable<T>, IFormattable
43+
{
44+
int rows = storage.RowCount;
45+
int columns = storage.ColumnCount;
46+
47+
var ap = storage.ColumnPointers;
48+
var ai = storage.RowIndices;
49+
50+
for (int i = 0; i < columns; i++)
51+
{
52+
int j = ap[i];
53+
int end = ap[i + 1];
54+
55+
// Check if column pointers are in ascending order.
56+
if (j > end)
57+
{
58+
return false;
59+
}
60+
61+
for (; j < end; j++)
62+
{
63+
// Check if row indices are within bounds.
64+
if (ai[j] < 0 || ai[j] >= rows)
65+
{
66+
return false;
67+
}
68+
69+
// Check if row indices are in order.
70+
if (strict && ai[j] >= ai[j + 1])
71+
{
72+
return false;
73+
}
74+
}
75+
}
76+
77+
return true;
78+
}
79+
3480
/// <summary>
3581
/// Trim row indices and values array of the storage to the exact size (non-zeros count).
3682
/// </summary>

0 commit comments

Comments
 (0)