Skip to content

Commit

Permalink
Merge pull request #44 from wo80/dev
Browse files Browse the repository at this point in the history
Release version 4.0.0
  • Loading branch information
wo80 authored Apr 3, 2024
2 parents 2fa5b20 + 8c2c61d commit 5547c20
Show file tree
Hide file tree
Showing 19 changed files with 172 additions and 160 deletions.
4 changes: 2 additions & 2 deletions CSparse.Tests/CSparse.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="NUnit" Version="4.0.1" />
<PackageReference Include="NUnit" Version="4.1.0" />
<PackageReference Include="NUnit3TestAdapter" Version="4.5.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.8.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.9.0" />
</ItemGroup>

<ItemGroup>
Expand Down
32 changes: 32 additions & 0 deletions CSparse.Tests/HelperTest.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@

namespace CSparse.Tests
{
using CSparse.Double;
using NUnit.Framework;

using C = System.Numerics.Complex;
Expand Down Expand Up @@ -33,5 +34,36 @@ public void TestTrimStorage()
Assert.That(A.RowIndices.Length, Is.EqualTo(0));
Assert.That(A.Values.Length, Is.EqualTo(0));
}

[Test]
public void TestValidateStorage()
{
var ap = new int[] { 0, 3, 6 };
var ai = new int[] { 0, 1, 2, 0, 1, 2 };
var ax = new double[] { 0, 0, 0, 0, 0, 0 };

var A = new SparseMatrix(3, 2, ax, ai, ap);

Assert.That(Helper.ValidateStorage(A), Is.True);

// Change order of column pointers.
ap[1] = 6; ap[2] = 3;

Assert.That(Helper.ValidateStorage(A), Is.False);

// Revert change to column pointers.
ap[1] = 3; ap[2] = 6;

// Row index larger than number of rows.
ai[2] = 3;

Assert.That(Helper.ValidateStorage(A), Is.False);

// Change order of row indices.
ai[1] = 2; ai[2] = 1;

Assert.That(Helper.ValidateStorage(A), Is.True);
Assert.That(Helper.ValidateStorage(A, true), Is.False);
}
}
}
22 changes: 11 additions & 11 deletions CSparse/CSparse.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,27 +9,27 @@
<Description>CSparse.NET provides numerical methods for sparse LU, Cholesky and QR decomposition of real and complex linear systems.</Description>
<Product>CSparse.NET</Product>
<Company />
<Copyright>Copyright Christian Woltering © 2012-2023</Copyright>
<Copyright>Copyright Christian Woltering © 2012-2024</Copyright>
<Authors>Christian Woltering</Authors>
<AssemblyVersion>3.8.1.0</AssemblyVersion>
<FileVersion>3.8.1.0</FileVersion>
<AssemblyVersion>4.0.0.0</AssemblyVersion>
<FileVersion>4.0.0.0</FileVersion>
<PackageTags>math sparse matrix lu cholesky qr decomposition factorization </PackageTags>
<Version>3.8.1</Version>
<Version>4.0.0</Version>
<AssemblyName>CSparse</AssemblyName>
<RootNamespace>CSparse</RootNamespace>
<PackageLicenseExpression>LGPL-2.1-only</PackageLicenseExpression>
<PackageProjectUrl>https://github.com/wo80/CSparse.NET</PackageProjectUrl>
<RepositoryUrl>https://github.com/wo80/CSparse.NET</RepositoryUrl>
<RepositoryUrl>https://github.com/wo80/CSparse.NET.git</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<PackageReleaseNotes>
Changes in version 3.8.1:
The major version change is due to the removal of obsolete methods in the Converter class. Visibility of that class was changed from public to internal. In case those obsolete methods were still used, please switch to the static conversion methods provided by the SparseMatrix class.

* Add overloads for permutation Invert() and IsValid() methods taking the permutation length as argument.
Other changes in version 4.0.0:

Changes in version 3.8.0:

* Add overloads for the factorization Solve() methods taking Span&lt;T&gt; as argument. Note that this introduces a dependency on System.Memory for the netstandard2.0 assembly.
</PackageReleaseNotes>
* Addition of helper method Helper.ValidateStorage(...) to validate the structure of a sparse matrix.
* Update to GetHashCode() method of CompressedColumnStorage class.
* Improvements to documentation.
</PackageReleaseNotes>
</PropertyGroup>

<ItemGroup>
Expand Down
2 changes: 1 addition & 1 deletion CSparse/Complex/Factorization/SparseLDL.cs
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ void Factorize(CompressedColumnStorage<Complex> A, IProgress<double> progress)
y[k] = 0.0;
for (; top < n; top++)
{
i = pattern[top]; // Pattern [top:n-1] is pattern of L(:,k)
i = pattern[top]; // Pattern [top:n-1] is pattern of L(k,:)
yi = y[i]; // get and clear Y(i)
y[i] = 0.0;
p2 = lp[i] + lnz[i];
Expand Down
2 changes: 1 addition & 1 deletion CSparse/Constants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public static class Constants
public const int SizeOfDouble = sizeof(double);

/// <summary>
/// The default threshold used for matrix values comparision.
/// The default threshold used for matrix values comparison.
/// </summary>
public const double EqualsThreshold = 1e-12;

Expand Down
80 changes: 3 additions & 77 deletions CSparse/Converter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,29 +7,16 @@ namespace CSparse
/// <summary>
/// Converter for different types of storages.
/// </summary>
public static class Converter
internal static class Converter
{
/// <summary>
/// Convert a coordinate storage to compressed sparse column (CSC) format.
/// </summary>
/// <param name="storage">Coordinate storage.</param>
/// <param name="cleanup">Remove and sum duplicate entries.</param>
/// <returns>Compressed sparse column storage.</returns>
[Obsolete("Will be removed in future versions. Use SparseMatrix.OfIndexed(...) instead.")]
public static CompressedColumnStorage<T> ToCompressedColumnStorage<T>(CoordinateStorage<T> storage,
bool cleanup = true) where T : struct, IEquatable<T>, IFormattable
{
return ToCompressedColumnStorage_(storage, cleanup);
}

/// <summary>
/// Convert a coordinate storage to compressed sparse column (CSC) format.
/// </summary>
/// <param name="storage">Coordinate storage.</param>
/// <param name="cleanup">Remove and sum duplicate entries.</param>
/// <param name="inplace">Do the conversion in place (re-using the coordinate storage arrays).</param>
/// <returns>Compressed sparse column storage.</returns>
internal static CompressedColumnStorage<T> ToCompressedColumnStorage_<T>(CoordinateStorage<T> storage,
public static CompressedColumnStorage<T> ToCompressedColumnStorage<T>(CoordinateStorage<T> storage,
bool cleanup = true, bool inplace = false) where T : struct, IEquatable<T>, IFormattable
{
int nrows = storage.RowCount;
Expand Down Expand Up @@ -110,7 +97,7 @@ internal static CompressedColumnStorage<T> ToCompressedColumnStorage_<T>(Coordin
/// <remarks>
/// On return, the coordinate storage input arrays contain the compressed sparse
/// column data structure for the resulting matrix. The <paramref name="work"/>
/// array contains a copy of the column pointer.
/// array contains a copy of the column pointers.
///
/// The entries of the output matrix are not sorted (the row indices in each
/// column are not in increasing order).
Expand Down Expand Up @@ -193,15 +180,8 @@ private static void ConvertInPlace<T>(int columns, int nz, T[] values, int[] row
/// </summary>
/// <param name="array">2D array storage.</param>
/// <returns>Coordinate storage.</returns>
[Obsolete("Will be removed in future versions. Use SparseMatrix.OfArray(...) instead.")]
public static CoordinateStorage<T> FromDenseArray<T>(T[,] array)
where T : struct, IEquatable<T>, IFormattable
{
return FromDenseArray_(array);
}

internal static CoordinateStorage<T> FromDenseArray_<T>(T[,] array)
where T : struct, IEquatable<T>, IFormattable
{
int rowCount = array.GetLength(0);
int columnCount = array.GetLength(1);
Expand All @@ -219,48 +199,15 @@ internal static CoordinateStorage<T> FromDenseArray_<T>(T[,] array)
return storage;
}

/// <summary>
/// Convert a jagged array to compressed sparse column (CSC) format.
/// </summary>
/// <param name="array">Jagged array storage.</param>
/// <returns>Compressed sparse column storage.</returns>
[Obsolete("Will be removed in future versions. Use SparseMatrix.OfJaggedArray(...) instead.")]
public static CompressedColumnStorage<T> ToCompressedColumnStorage<T>(T[][] array)
where T : struct, IEquatable<T>, IFormattable
{
int nrows = array.Length;
int ncols = array[0].Length;

var storage = new CoordinateStorage<T>(nrows, ncols, nrows);

for (int i = 0; i < nrows; i++)
{
for (int j = 0; j < ncols; j++)
{
storage.At(i, j, array[i][j]);
}
}

return ToCompressedColumnStorage_<T>(storage, false);
}


/// <summary>
/// Convert a column major array to coordinate storage.
/// </summary>
/// <param name="array">Column major array storage.</param>
/// <param name="rowCount">Number of rows.</param>
/// <param name="columnCount">Number of columns.</param>
/// <returns>Coordinate storage.</returns>
[Obsolete("Will be removed in future versions. Use SparseMatrix.OfColumnMajor(...) instead.")]
public static CoordinateStorage<T> FromColumnMajorArray<T>(T[] array, int rowCount, int columnCount)
where T : struct, IEquatable<T>, IFormattable
{
return FromColumnMajorArray_(array, rowCount, columnCount);
}

internal static CoordinateStorage<T> FromColumnMajorArray_<T>(T[] array, int rowCount, int columnCount)
where T : struct, IEquatable<T>, IFormattable
{
var storage = new CoordinateStorage<T>(rowCount, columnCount, Math.Max(rowCount, columnCount));

Expand All @@ -281,15 +228,8 @@ internal static CoordinateStorage<T> FromColumnMajorArray_<T>(T[] array, int row
/// <param name="array">jagged array storage.</param>
/// <returns>Coordinate storage.</returns>
/// <remarks>All rows of the array are assumed to be equal in length</remarks>
[Obsolete("Will be removed in future versions. Use SparseMatrix.OfColumnMajor(...) instead.")]
public static CoordinateStorage<T> FromJaggedArray<T>(T[][] array)
where T : struct, IEquatable<T>, IFormattable
{
return FromJaggedArray_(array);
}

internal static CoordinateStorage<T> FromJaggedArray_<T>(T[][] array)
where T : struct, IEquatable<T>, IFormattable
{
int rowCount = array.Length;
int columnCount = array[0].Length;
Expand All @@ -314,15 +254,8 @@ internal static CoordinateStorage<T> FromJaggedArray_<T>(T[][] array)
/// <param name="rowCount">Number of rows.</param>
/// <param name="columnCount">Number of columns.</param>
/// <returns>Coordinate storage.</returns>
[Obsolete("Will be removed in future versions. Use SparseMatrix.OfRowMajor(...) instead.")]
public static CoordinateStorage<T> FromRowMajorArray<T>(T[] array, int rowCount, int columnCount)
where T : struct, IEquatable<T>, IFormattable
{
return FromRowMajorArray_(array, rowCount, columnCount);
}

internal static CoordinateStorage<T> FromRowMajorArray_<T>(T[] array, int rowCount, int columnCount)
where T : struct, IEquatable<T>, IFormattable
{
var storage = new CoordinateStorage<T>(rowCount, columnCount, Math.Max(rowCount, columnCount));

Expand All @@ -344,15 +277,8 @@ internal static CoordinateStorage<T> FromRowMajorArray_<T>(T[] array, int rowCou
/// <param name="rowCount">Number of rows.</param>
/// <param name="columnCount">Number of columns.</param>
/// <returns>Coordinate storage.</returns>
[Obsolete("Will be removed in future versions. Use SparseMatrix.OfIndexed(...) instead.")]
public static CoordinateStorage<T> FromEnumerable<T>(IEnumerable<Tuple<int, int, T>> enumerable, int rowCount, int columnCount)
where T : struct, IEquatable<T>, IFormattable
{
return FromEnumerable_(enumerable, rowCount, columnCount);
}

internal static CoordinateStorage<T> FromEnumerable_<T>(IEnumerable<Tuple<int, int, T>> enumerable, int rowCount, int columnCount)
where T : struct, IEquatable<T>, IFormattable
{
var storage = new CoordinateStorage<T>(rowCount, columnCount, Math.Max(rowCount, columnCount));

Expand Down
2 changes: 1 addition & 1 deletion CSparse/Double/Factorization/SparseLDL.cs
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ void Factorize(CompressedColumnStorage<double> A, IProgress<double> progress)
y[k] = 0.0;
for (; top < n; top++)
{
i = pattern[top]; // Pattern [top:n-1] is pattern of L(:,k)
i = pattern[top]; // Pattern [top:n-1] is pattern of L(k,:)
yi = y[i]; // get and clear Y(i)
y[i] = 0.0;
p2 = lp[i] + lnz[i];
Expand Down
2 changes: 1 addition & 1 deletion CSparse/Factorization/ISolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ namespace CSparse.Factorization
/// <summary>
/// Classes that solve a system of linear equations, <c>Ax = b</c>.
/// </summary>
/// <typeparam name="T">Supported data types are double and <see cref="Complex"/>.</typeparam>
/// <typeparam name="T">Supported data types are <c>double</c> and <see cref="System.Numerics.Complex"/>.</typeparam>
public interface ISolver<T> where T : struct, IEquatable<T>, IFormattable
{
/// <summary>
Expand Down
2 changes: 1 addition & 1 deletion CSparse/Factorization/ISparseFactorization.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ namespace CSparse.Factorization
/// <summary>
/// Interface for factorization methods.
/// </summary>
/// <typeparam name="T">Supported data types are <c>double</c> and <see cref="Complex"/>.</typeparam>
/// <typeparam name="T">Supported data types are <c>double</c> and <see cref="System.Numerics.Complex"/>.</typeparam>
public interface ISparseFactorization<T> : ISolver<T>
where T : struct, IEquatable<T>, IFormattable
{
Expand Down
23 changes: 18 additions & 5 deletions CSparse/Factorization/SparseQR.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,39 @@ namespace CSparse.Factorization
/// <summary>
/// Sparse QR decomposition abstract base class.
/// </summary>
/// <typeparam name="T">Supported data types are <c>double</c> and <see cref="System.Numerics.Complex"/>.</typeparam>
public abstract class SparseQR<T> : ISparseFactorization<T>
where T : struct, IEquatable<T>, IFormattable
{
protected readonly int m, n;
/// <summary>number of rows</summary>
protected readonly int m;

/// <summary>number of columns</summary>
protected readonly int n;

/// <summary>symbolic factorization</summary>
protected SymbolicFactorization S;
protected CompressedColumnStorage<T> Q, R;

/// <summary>Q factor</summary>
protected CompressedColumnStorage<T> Q;

/// <summary>R factor</summary>
protected CompressedColumnStorage<T> R;

/// <summary>factors for Householder reflection</summary>
protected double[] beta;

/// <summary>
/// Initializes a new instance of the SparseQR class.
/// </summary>
protected SparseQR(int rows, int columns)
{
this.m = rows;
this.n = columns;
m = rows;
n = columns;
}

/// <summary>
/// Gets the number of nonzeros in both Q and R factors together.
/// Gets the number of non-zeros in both Q and R factors together.
/// </summary>
public int NonZerosCount
{
Expand Down
6 changes: 3 additions & 3 deletions CSparse/Factorization/SymbolicFactorization.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,17 @@ public class SymbolicFactorization
public int[] leftmost;

/// <summary>
/// # of rows for QR, after adding fictitious rows
/// number of rows for QR, after adding fictitious rows
/// </summary>
public int m2;

/// <summary>
/// # entries in L for LU or Cholesky; in V for QR
/// number of entries in L for LU or Cholesky; in V for QR
/// </summary>
public int lnz;

/// <summary>
/// # entries in U for LU; in R for QR
/// number of entries in U for LU; in R for QR
/// </summary>
public int unz;
}
Expand Down
Loading

0 comments on commit 5547c20

Please sign in to comment.