Skip to content

Add ValueTuple overload for creating CompressedColumnStorage #46

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jun 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading