Skip to content

Commit efb7c70

Browse files
committed
Fix coordinate storage in-place conversion.
1 parent bdbb7d5 commit efb7c70

File tree

3 files changed

+58
-27
lines changed

3 files changed

+58
-27
lines changed

CSparse.Tests/Double/SparseMatrixTest.cs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -506,6 +506,34 @@ public void TestOfIndexed_Coo(int rows, int columns)
506506
Assert.IsNull(coo.ColumnIndices);
507507
}
508508

509+
[Test]
510+
public void TestOfIndexed_Coo_InPlace()
511+
{
512+
// rows > columns
513+
514+
var coo = new CoordinateStorage<double>(10, 5, 3);
515+
516+
coo.At(0, 0, 1.0);
517+
coo.At(1, 1, 1.0);
518+
coo.At(4, 4, 1.0);
519+
520+
var A = SparseMatrix.OfIndexed(coo, true);
521+
522+
Assert.AreEqual(3, A.NonZerosCount);
523+
524+
// rows < columns
525+
526+
coo = new CoordinateStorage<double>(5, 10, 3);
527+
528+
coo.At(0, 0, 1.0);
529+
coo.At(1, 1, 1.0);
530+
coo.At(4, 4, 1.0);
531+
532+
A = SparseMatrix.OfIndexed(coo, true);
533+
534+
Assert.AreEqual(3, A.NonZerosCount);
535+
}
536+
509537
[Test]
510538
public void TestOfIndexed_Empty()
511539
{

CSparse/CSparse.csproj

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,19 @@
1111
<Company />
1212
<Copyright>Copyright Christian Woltering © 2012-2020</Copyright>
1313
<Authors>Christian Woltering</Authors>
14-
<AssemblyVersion>3.4.7.0</AssemblyVersion>
15-
<FileVersion>3.4.7.0</FileVersion>
14+
<AssemblyVersion>3.4.9.0</AssemblyVersion>
15+
<FileVersion>3.4.9.0</FileVersion>
1616
<PackageTags>math sparse matrix lu cholesky qr decomposition factorization </PackageTags>
17-
<Version>3.4.7</Version>
17+
<Version>3.4.9</Version>
1818
<AssemblyName>CSparse</AssemblyName>
1919
<RootNamespace>CSparse</RootNamespace>
2020
<PackageLicenseExpression>LGPL-2.1-only</PackageLicenseExpression>
2121
<PackageProjectUrl>https://github.com/wo80/CSparse.NET</PackageProjectUrl>
2222
<RepositoryUrl>https://github.com/wo80/CSparse.NET</RepositoryUrl>
2323
<RepositoryType>git</RepositoryType>
24-
<PackageReleaseNotes>* BREAKING: make SparseLDL constructor private (use static create methods instead).
25-
* Add complex version of SparseLDL.
26-
* Add matrix.EnumerateIndexed(action) overload.</PackageReleaseNotes>
24+
<PackageReleaseNotes>Coordinate storage improvements:
25+
* Add constructor that uses existing arrays for storage.
26+
* Convert to sparse matrix in place.</PackageReleaseNotes>
2727
</PropertyGroup>
2828

2929
<ItemGroup>

CSparse/Converter.cs

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -35,23 +35,25 @@ internal static CompressedColumnStorage<T> ToCompressedColumnStorage_<T>(Coordin
3535
int nrows = storage.RowCount;
3636
int ncols = storage.ColumnCount;
3737

38-
var values = storage.Values;
39-
var rowind = storage.RowIndices;
40-
var colind = storage.ColumnIndices;
38+
int nz = storage.NonZerosCount;
4139

4240
var result = CompressedColumnStorage<T>.Create(nrows, ncols);
4341

44-
int nz = storage.NonZerosCount;
42+
var ap = result.ColumnPointers = new int[ncols + 1];
4543

46-
if (inplace)
44+
if (nz == 0)
4745
{
48-
var work = new int[ncols + 1];
46+
return result;
47+
}
4948

50-
ConvertInPlace(ncols, nz, values, rowind, colind, work);
49+
var values = storage.Values;
50+
var rowind = storage.RowIndices;
51+
var colind = storage.ColumnIndices;
5152

52-
Array.Copy(colind, work, ncols + 1);
53+
if (inplace)
54+
{
55+
ConvertInPlace(ncols, nz, values, rowind, colind, ap);
5356

54-
result.ColumnPointers = work;
5557
result.RowIndices = rowind;
5658
result.Values = values;
5759

@@ -60,7 +62,6 @@ internal static CompressedColumnStorage<T> ToCompressedColumnStorage_<T>(Coordin
6062
}
6163
else
6264
{
63-
var columnPointers = new int[ncols + 1];
6465
var columnCounts = new int[ncols];
6566

6667
for (int k = 0; k < nz; k++)
@@ -70,21 +71,20 @@ internal static CompressedColumnStorage<T> ToCompressedColumnStorage_<T>(Coordin
7071
}
7172

7273
// Get column pointers
73-
int valueCount = Helper.CumulativeSum(columnPointers, columnCounts, ncols);
74+
int valueCount = Helper.CumulativeSum(ap, columnCounts, ncols);
7475

75-
var rowIndices = new int[valueCount];
76-
var storageValues = new T[valueCount];
76+
var ai = new int[valueCount];
77+
var ax = new T[valueCount];
7778

7879
for (int k = 0; k < nz; k++)
7980
{
8081
int p = columnCounts[colind[k]]++;
81-
rowIndices[p] = rowind[k];
82-
storageValues[p] = values[k];
82+
ai[p] = rowind[k];
83+
ax[p] = values[k];
8384
}
8485

85-
result.RowIndices = rowIndices;
86-
result.ColumnPointers = columnPointers;
87-
result.Values = storageValues;
86+
result.RowIndices = ai;
87+
result.Values = ax;
8888
}
8989

9090
Helper.SortIndices(result);
@@ -182,10 +182,13 @@ private static void ConvertInPlace<T>(int columns, int nz, T[] values, int[] row
182182
// Restart chasing.
183183
}
184184

185-
colind[0] = 0;
185+
// Fix column pointers.
186+
for (i = columns - 1; i > 0; i--)
187+
{
188+
work[i] = work[i - 1];
189+
}
186190

187-
// Copy column pointers.
188-
Array.Copy(work, 0, colind, 1, columns);
191+
work[0] = 0;
189192
}
190193

191194
/// <summary>

0 commit comments

Comments
 (0)