Skip to content

Commit

Permalink
Merge pull request #46 from miniksa/valuetuple
Browse files Browse the repository at this point in the history
Add ValueTuple overload for creating CompressedColumnStorage
  • Loading branch information
wo80 authored Jun 12, 2024
2 parents 5547c20 + 24611b8 commit f145e93
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 5 deletions.
20 changes: 20 additions & 0 deletions CSparse/Converter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -289,5 +289,25 @@ public static CoordinateStorage<T> FromEnumerable<T>(IEnumerable<Tuple<int, int,

return storage;
}

/// <summary>
/// Convert a row major array to coordinate storage.
/// </summary>
/// <param name="enumerable">Enumerates the entries of a matrix with value tuples.</param>
/// <param name="rowCount">Number of rows.</param>
/// <param name="columnCount">Number of columns.</param>
/// <returns>Coordinate storage.</returns>
public static CoordinateStorage<T> FromEnumerable<T>(IEnumerable<(int row, int column, T value)> enumerable, int rowCount, int columnCount)
where T : struct, IEquatable<T>, IFormattable
{
var storage = new CoordinateStorage<T>(rowCount, columnCount, Math.Max(rowCount, columnCount));

foreach (var item in enumerable)
{
storage.At(item.row, item.column, item.value);
}

return storage;
}
}
}
9 changes: 9 additions & 0 deletions CSparse/Matrix.cs
Original file line number Diff line number Diff line change
Expand Up @@ -132,9 +132,18 @@ protected Matrix(int rowCount, int columnCount)
/// <summary>
/// Enumerates all values of the matrix.
/// </summary>
/// <remarks>
/// <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.
/// </remarks>
/// <returns>Enumeration of tuples (i, j, a[i, j]).</returns>
public abstract IEnumerable<Tuple<int, int, T>> EnumerateIndexed();

/// <summary>
/// Enumerates all values of the matrix, but returns as stack-allocated value tuples instead of heap-allocated tuples.
/// </summary>
/// <returns>Enumeration of tuples (i, j, a[i, j]).</returns>
public abstract IEnumerable<(int row, int column, T value)> EnumerateIndexedAsValueTuples();

/// <summary>
/// Enumerates all values of the matrix.
/// </summary>
Expand Down
29 changes: 27 additions & 2 deletions CSparse/Storage/CompressedColumnStorage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ public CompressedColumnStorage(int rowCount, int columnCount, T[] values, int[]
/// </summary>
public static CompressedColumnStorage<T> OfMatrix(Matrix<T> matrix)
{
var c = Converter.FromEnumerable<T>(matrix.EnumerateIndexed(), matrix.RowCount, matrix.ColumnCount);
var c = Converter.FromEnumerable<T>(matrix.EnumerateIndexedAsValueTuples(), matrix.RowCount, matrix.ColumnCount);

return Converter.ToCompressedColumnStorage(c);
}
Expand Down Expand Up @@ -146,13 +146,29 @@ public static CompressedColumnStorage<T> OfIndexed(CoordinateStorage<T> coordina
/// <summary>
/// Create a new sparse matrix as a copy of the given indexed enumerable.
/// </summary>
/// <param name="rows">The number of rows.</param>
/// <param name="columns">The number of columns.</param>
/// <param name="enumerable">Tuples with the three elements of row, column, and the value that belongs at that position.</param>
public static CompressedColumnStorage<T> OfIndexed(int rows, int columns, IEnumerable<Tuple<int, int, T>> enumerable)
{
var c = Converter.FromEnumerable<T>(enumerable, rows, columns);

return Converter.ToCompressedColumnStorage(c);
}

/// <summary>
/// Create a new sparse matrix as a copy of the given indexed enumerable using a value tuple.
/// </summary>
/// <param name="rows">The number of rows.</param>
/// <param name="columns">The number of columns.</param>
/// <param name="enumerable">Value tuples with the three elements of row, column, and the value that belongs at that position.</param>
public static CompressedColumnStorage<T> OfIndexed(int rows, int columns, IEnumerable<(int row, int column, T value)> enumerable)
{
var c = Converter.FromEnumerable<T>(enumerable, rows, columns);

return Converter.ToCompressedColumnStorage(c);
}

/// <summary>
/// Create a new sparse matrix as a copy of the given array (row-major).
/// </summary>
Expand Down Expand Up @@ -564,6 +580,15 @@ public CompressedColumnStorage<T> Clone(bool values = true)

/// <inheritdoc />
public override IEnumerable<Tuple<int, int, T>> EnumerateIndexed()
{
foreach (var valueTuple in EnumerateIndexedAsValueTuples())
{
yield return Tuple.Create(valueTuple.row, valueTuple.column, valueTuple.value);
}
}

/// <inheritdoc />
public override IEnumerable<(int row, int column, T value)> EnumerateIndexedAsValueTuples()
{
var ax = Values;
var ap = ColumnPointers;
Expand All @@ -574,7 +599,7 @@ public override IEnumerable<Tuple<int, int, T>> EnumerateIndexed()
var end = ap[i + 1];
for (var j = ap[i]; j < end; j++)
{
yield return new Tuple<int, int, T>(ai[j], i, ax[j]);
yield return (ai[j], i, ax[j]);
}
}
}
Expand Down
15 changes: 12 additions & 3 deletions CSparse/Storage/DenseColumnMajorStorage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -165,8 +165,8 @@ public static DenseColumnMajorStorage<T> OfDiagonalArray(T[] diagonal)
{
int order = diagonal.Length;

var A = Create(order, order);
var A = Create(order, order);

for (int i = 0; i < order; i++)
{
A.At(i, i, diagonal[i]);
Expand Down Expand Up @@ -547,12 +547,21 @@ public override void Clear()

/// <inheritdoc />
public override IEnumerable<Tuple<int, int, T>> EnumerateIndexed()
{
foreach (var valueTuple in EnumerateIndexedAsValueTuples())
{
yield return Tuple.Create(valueTuple.row, valueTuple.column, valueTuple.value);
}
}

/// <inheritdoc />
public override IEnumerable<(int row, int column, T value)> EnumerateIndexedAsValueTuples()
{
for (int row = 0; row < rows; row++)
{
for (int column = 0; column < columns; column++)
{
yield return new Tuple<int, int, T>(row, column, Values[(column * rows) + row]);
yield return (row, column, Values[(column * rows) + row]);
}
}
}
Expand Down

0 comments on commit f145e93

Please sign in to comment.