Skip to content

Commit 24611b8

Browse files
committed
Add Value Tuple based iteration to Matrix base class and DenseColumn and CompressedColumn storage mechanisms derived from that class. Use the value-based variant in the OfMatrix helper to avoid allocations.
1 parent 9257c82 commit 24611b8

File tree

3 files changed

+32
-5
lines changed

3 files changed

+32
-5
lines changed

CSparse/Matrix.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,9 +132,18 @@ protected Matrix(int rowCount, int columnCount)
132132
/// <summary>
133133
/// Enumerates all values of the matrix.
134134
/// </summary>
135+
/// <remarks>
136+
/// <see cref="EnumerateIndexedAsValueTuples"/> for a version that returns stack-allocated value tuples to save transient heap allocations (saves performance overhead of allocations + garbage collection) of the <see cref="Tuple"/> class.
137+
/// </remarks>
135138
/// <returns>Enumeration of tuples (i, j, a[i, j]).</returns>
136139
public abstract IEnumerable<Tuple<int, int, T>> EnumerateIndexed();
137140

141+
/// <summary>
142+
/// Enumerates all values of the matrix, but returns as stack-allocated value tuples instead of heap-allocated tuples.
143+
/// </summary>
144+
/// <returns>Enumeration of tuples (i, j, a[i, j]).</returns>
145+
public abstract IEnumerable<(int row, int column, T value)> EnumerateIndexedAsValueTuples();
146+
138147
/// <summary>
139148
/// Enumerates all values of the matrix.
140149
/// </summary>

CSparse/Storage/CompressedColumnStorage.cs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ public CompressedColumnStorage(int rowCount, int columnCount, T[] values, int[]
110110
/// </summary>
111111
public static CompressedColumnStorage<T> OfMatrix(Matrix<T> matrix)
112112
{
113-
var c = Converter.FromEnumerable<T>(matrix.EnumerateIndexed(), matrix.RowCount, matrix.ColumnCount);
113+
var c = Converter.FromEnumerable<T>(matrix.EnumerateIndexedAsValueTuples(), matrix.RowCount, matrix.ColumnCount);
114114

115115
return Converter.ToCompressedColumnStorage(c);
116116
}
@@ -580,6 +580,15 @@ public CompressedColumnStorage<T> Clone(bool values = true)
580580

581581
/// <inheritdoc />
582582
public override IEnumerable<Tuple<int, int, T>> EnumerateIndexed()
583+
{
584+
foreach (var valueTuple in EnumerateIndexedAsValueTuples())
585+
{
586+
yield return Tuple.Create(valueTuple.row, valueTuple.column, valueTuple.value);
587+
}
588+
}
589+
590+
/// <inheritdoc />
591+
public override IEnumerable<(int row, int column, T value)> EnumerateIndexedAsValueTuples()
583592
{
584593
var ax = Values;
585594
var ap = ColumnPointers;
@@ -590,7 +599,7 @@ public override IEnumerable<Tuple<int, int, T>> EnumerateIndexed()
590599
var end = ap[i + 1];
591600
for (var j = ap[i]; j < end; j++)
592601
{
593-
yield return new Tuple<int, int, T>(ai[j], i, ax[j]);
602+
yield return (ai[j], i, ax[j]);
594603
}
595604
}
596605
}

CSparse/Storage/DenseColumnMajorStorage.cs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -165,8 +165,8 @@ public static DenseColumnMajorStorage<T> OfDiagonalArray(T[] diagonal)
165165
{
166166
int order = diagonal.Length;
167167

168-
var A = Create(order, order);
169-
168+
var A = Create(order, order);
169+
170170
for (int i = 0; i < order; i++)
171171
{
172172
A.At(i, i, diagonal[i]);
@@ -547,12 +547,21 @@ public override void Clear()
547547

548548
/// <inheritdoc />
549549
public override IEnumerable<Tuple<int, int, T>> EnumerateIndexed()
550+
{
551+
foreach (var valueTuple in EnumerateIndexedAsValueTuples())
552+
{
553+
yield return Tuple.Create(valueTuple.row, valueTuple.column, valueTuple.value);
554+
}
555+
}
556+
557+
/// <inheritdoc />
558+
public override IEnumerable<(int row, int column, T value)> EnumerateIndexedAsValueTuples()
550559
{
551560
for (int row = 0; row < rows; row++)
552561
{
553562
for (int column = 0; column < columns; column++)
554563
{
555-
yield return new Tuple<int, int, T>(row, column, Values[(column * rows) + row]);
564+
yield return (row, column, Values[(column * rows) + row]);
556565
}
557566
}
558567
}

0 commit comments

Comments
 (0)