@@ -9,7 +9,7 @@ namespace CSparse.Storage
99 /// <remarks>
1010 /// Used for ordering and symbolic factorization.
1111 /// </remarks>
12- internal class SymbolicColumnStorage
12+ public class SymbolicColumnStorage
1313 {
1414 private int rowCount ;
1515 private int columnCount ;
@@ -27,27 +27,26 @@ internal class SymbolicColumnStorage
2727 /// <summary>
2828 /// Gets the number of rows.
2929 /// </summary>
30- public int RowCount
31- {
32- get { return rowCount ; }
33- }
30+ public int RowCount => rowCount ;
3431
3532 /// <summary>
3633 /// Gets the number of columns.
3734 /// </summary>
38- public int ColumnCount
39- {
40- get { return columnCount ; }
41- }
35+ public int ColumnCount => columnCount ;
4236
4337 /// <summary>
4438 /// Gets the number of non-zero entries.
4539 /// </summary>
46- public int NonZerosCount
47- {
48- get { return ColumnPointers [ columnCount ] ; }
49- }
40+ public int NonZerosCount => ColumnPointers [ columnCount ] ;
5041
42+ /// <summary>
43+ /// Initializes a new instance of the <see cref="SymbolicColumnStorage"/> class.
44+ /// </summary>
45+ /// <param name="rowCount">The number of rows.</param>
46+ /// <param name="columnCount">The number of columns.</param>
47+ /// <param name="valueCount">The number of non-zero values.</param>
48+ /// <param name="allocate">If true, both <see cref="ColumnPointers"/> and <see cref="RowIndices"/> arrays will be allocated.</param>
49+ /// <exception cref="ArgumentOutOfRangeException"></exception>
5150 public SymbolicColumnStorage ( int rowCount , int columnCount , int valueCount , bool allocate )
5251 {
5352 // Explicitly allow m or n = 0 (may occur in Dulmage-Mendelsohn decomposition).
@@ -61,29 +60,79 @@ public SymbolicColumnStorage(int rowCount, int columnCount, int valueCount, bool
6160
6261 if ( allocate )
6362 {
64- this . ColumnPointers = new int [ columnCount + 1 ] ;
65- this . RowIndices = new int [ valueCount ] ;
63+ ColumnPointers = new int [ columnCount + 1 ] ;
64+ RowIndices = new int [ valueCount ] ;
6665 }
6766 }
6867
6968 /// <summary>
70- /// Change the shape of the matrix (only used by Dulmage-Mendelsohn decomposition) .
69+ /// Initializes a new instance of the <see cref="SymbolicColumnStorage"/> class .
7170 /// </summary>
72- /// <param name="rowCount"></param>
73- /// <param name="columnCount"></param>
74- internal void Reshape ( int rowCount , int columnCount )
71+ /// <param name="rowCount">The number of rows.</param>
72+ /// <param name="columnCount">The number of columns.</param>
73+ /// <param name="columnPointers">The number of non-zero values.</param>
74+ /// <param name="rowIndices">The number of non-zero values.</param>
75+ /// <param name="copy">If true, both <paramref name="columnPointers"/> and <paramref name="rowIndices"/> arrays will be copied to new arrays.</param>
76+ /// <exception cref="ArgumentOutOfRangeException"></exception>
77+ public SymbolicColumnStorage ( int rowCount , int columnCount , int [ ] columnPointers , int [ ] rowIndices , bool copy )
7578 {
76- if ( rowCount >= 0 )
79+ // Explicitly allow m or n = 0 (may occur in Dulmage-Mendelsohn decomposition).
80+ if ( rowCount < 0 || columnCount < 0 )
7781 {
78- this . rowCount = rowCount ;
82+ throw new ArgumentOutOfRangeException ( Resources . MatrixDimensionNonNegative ) ;
7983 }
80- if ( columnCount >= 0 )
84+
85+ if ( columnPointers is null )
8186 {
82- this . columnCount = columnCount ;
83- //Array.Resize(ref this.ColumnPointers, columnCount + 1);
87+ throw new ArgumentNullException ( nameof ( columnPointers ) ) ;
88+ }
89+
90+ if ( rowIndices is null )
91+ {
92+ throw new ArgumentNullException ( nameof ( rowIndices ) ) ;
93+ }
94+
95+ if ( columnPointers . Length < columnCount + 1 )
96+ {
97+ throw new ArgumentOutOfRangeException ( "Column pointers array size don't match given column count argument." ) ;
98+ }
99+
100+ if ( rowIndices . Length < columnPointers [ columnCount ] )
101+ {
102+ throw new ArgumentOutOfRangeException ( "Row indices array size don't match non-zeros count." ) ;
103+ }
104+
105+ this . rowCount = rowCount ;
106+ this . columnCount = columnCount ;
107+
108+ if ( copy )
109+ {
110+ int valueCount = rowIndices . Length ;
111+
112+ ColumnPointers = new int [ columnCount + 1 ] ;
113+ RowIndices = new int [ valueCount ] ;
114+
115+ Buffer . BlockCopy ( columnPointers , 0 , ColumnPointers , 0 , ( columnCount + 1 ) * Constants . SizeOfInt ) ;
116+ Buffer . BlockCopy ( rowIndices , 0 , RowIndices , 0 , valueCount * Constants . SizeOfInt ) ;
117+ }
118+ else
119+ {
120+ ColumnPointers = columnPointers ;
121+ RowIndices = rowIndices ;
84122 }
85123 }
86124
125+ /// <summary>
126+ /// Creates a new instance of the <see cref="SymbolicColumnStorage"/> class.
127+ /// </summary>
128+ /// <param name="A">The sparse matrix to create the <see cref="SymbolicColumnStorage"/> from.</param>
129+ /// <param name="copy">If true, both column pointers and row indices arrays of <paramref name="A"/> will be copied to new arrays.</param>
130+ public static SymbolicColumnStorage Create < T > ( CompressedColumnStorage < T > A , bool copy = true )
131+ where T : struct , IEquatable < T > , IFormattable
132+ {
133+ return new SymbolicColumnStorage ( A . RowCount , A . ColumnCount , A . ColumnPointers , A . RowIndices , copy ) ;
134+ }
135+
87136 /// <summary>
88137 /// Change the max # of entries sparse matrix
89138 /// </summary>
@@ -93,16 +142,16 @@ public bool Resize(int size)
93142 {
94143 if ( size <= 0 )
95144 {
96- size = this . ColumnPointers [ columnCount ] ;
145+ size = ColumnPointers [ columnCount ] ;
97146 }
98147
99- Array . Resize ( ref this . RowIndices , size ) ;
148+ Array . Resize ( ref RowIndices , size ) ;
100149
101150 return true ;
102151 }
103152
104153 /// <summary>
105- /// Sort column indices using insertion sort .
154+ /// Sort column indices.
106155 /// </summary>
107156 public void Sort ( )
108157 {
@@ -140,14 +189,14 @@ public void Sort()
140189
141190 public SymbolicColumnStorage Clone ( )
142191 {
143- int m = this . RowCount ;
144- int n = this . ColumnCount ;
145- int nnz = this . NonZerosCount ;
192+ int m = RowCount ;
193+ int n = ColumnCount ;
194+ int nnz = NonZerosCount ;
146195
147196 var result = new SymbolicColumnStorage ( m , n , nnz , true ) ;
148197
149- Buffer . BlockCopy ( this . ColumnPointers , 0 , result . ColumnPointers , 0 , ( n + 1 ) * Constants . SizeOfInt ) ;
150- Buffer . BlockCopy ( this . RowIndices , 0 , result . RowIndices , 0 , nnz * Constants . SizeOfInt ) ;
198+ Buffer . BlockCopy ( ColumnPointers , 0 , result . ColumnPointers , 0 , ( n + 1 ) * Constants . SizeOfInt ) ;
199+ Buffer . BlockCopy ( RowIndices , 0 , result . RowIndices , 0 , nnz * Constants . SizeOfInt ) ;
151200
152201 return result ;
153202 }
@@ -162,8 +211,8 @@ public virtual SymbolicColumnStorage Transpose()
162211 {
163212 int j , k , p ;
164213
165- int m = this . RowCount ;
166- int n = this . ColumnCount ;
214+ int m = RowCount ;
215+ int n = ColumnCount ;
167216
168217 var result = new SymbolicColumnStorage ( n , m , 0 , false ) ;
169218
@@ -232,7 +281,7 @@ public SymbolicColumnStorage Add(SymbolicColumnStorage other)
232281 {
233282 // Column j of result starts here
234283 cp [ j ] = nz ;
235- nz = this . Scatter ( j , w , j + 1 , ci , nz ) ; // A(:,j)
284+ nz = Scatter ( j , w , j + 1 , ci , nz ) ; // A(:,j)
236285 nz = other . Scatter ( j , w , j + 1 , ci , nz ) ; // B(:,j)
237286 }
238287
@@ -259,15 +308,15 @@ public SymbolicColumnStorage Multiply(SymbolicColumnStorage other)
259308 {
260309 int p , j , nz = 0 ;
261310
262- if ( this . columnCount != other . rowCount )
311+ if ( columnCount != other . rowCount )
263312 {
264313 throw new ArgumentException ( ) ;
265314 }
266315
267- int m = this . rowCount ;
316+ int m = rowCount ;
268317 int n = other . columnCount ;
269318
270- int anz = this . NonZerosCount ;
319+ int anz = NonZerosCount ;
271320 int bnz = other . NonZerosCount ;
272321
273322 var bp = other . ColumnPointers ;
@@ -292,7 +341,7 @@ public SymbolicColumnStorage Multiply(SymbolicColumnStorage other)
292341
293342 for ( p = bp [ j ] ; p < bp [ j + 1 ] ; p ++ )
294343 {
295- nz = this . Scatter ( bi [ p ] , work , j + 1 , ci , nz ) ;
344+ nz = Scatter ( bi [ p ] , work , j + 1 , ci , nz ) ;
296345 }
297346 }
298347
@@ -319,10 +368,10 @@ public virtual void Permute(int[] pinv, int[] q, SymbolicColumnStorage result)
319368 {
320369 int i , j , k , nz = 0 ;
321370
322- int n = this . columnCount ;
371+ int n = columnCount ;
323372
324- int [ ] ap = this . ColumnPointers ;
325- int [ ] ai = this . RowIndices ;
373+ int [ ] ap = ColumnPointers ;
374+ int [ ] ai = RowIndices ;
326375
327376 // Allocate memory if needed.
328377 if ( result . ColumnPointers == null )
@@ -350,6 +399,24 @@ public virtual void Permute(int[] pinv, int[] q, SymbolicColumnStorage result)
350399
351400 #endregion
352401
402+ /// <summary>
403+ /// Change the shape of the matrix (only used by Dulmage-Mendelsohn decomposition).
404+ /// </summary>
405+ /// <param name="rowCount"></param>
406+ /// <param name="columnCount"></param>
407+ internal void Reshape ( int rowCount , int columnCount )
408+ {
409+ if ( rowCount >= 0 )
410+ {
411+ this . rowCount = rowCount ;
412+ }
413+ if ( columnCount >= 0 )
414+ {
415+ this . columnCount = columnCount ;
416+ //Array.Resize(ref this.ColumnPointers, columnCount + 1);
417+ }
418+ }
419+
353420 /// <summary>
354421 /// Drops entries from a sparse matrix
355422 /// </summary>
@@ -381,7 +448,7 @@ internal int Keep(Func<int, int, bool> func)
381448 ColumnPointers [ columnCount ] = nz ;
382449
383450 // Remove extra space.
384- Array . Resize < int > ( ref this . RowIndices , nz ) ;
451+ Array . Resize ( ref RowIndices , nz ) ;
385452
386453 return nz ;
387454 }
@@ -411,28 +478,5 @@ private int Scatter(int j, int[] work, int mark, int[] ci, int nz)
411478
412479 return nz ;
413480 }
414-
415- internal static SymbolicColumnStorage Create < T > ( CompressedColumnStorage < T > mat , bool allocate = true )
416- where T : struct , IEquatable < T > , IFormattable
417- {
418- int m = mat . RowCount ;
419- int n = mat . ColumnCount ;
420- int nnz = mat . NonZerosCount ;
421-
422- var result = new SymbolicColumnStorage ( m , n , nnz , allocate ) ;
423-
424- if ( allocate )
425- {
426- Buffer . BlockCopy ( mat . ColumnPointers , 0 , result . ColumnPointers , 0 , ( n + 1 ) * Constants . SizeOfInt ) ;
427- Buffer . BlockCopy ( mat . RowIndices , 0 , result . RowIndices , 0 , nnz * Constants . SizeOfInt ) ;
428- }
429- else
430- {
431- result . ColumnPointers = mat . ColumnPointers ;
432- result . RowIndices = mat . RowIndices ;
433- }
434-
435- return result ;
436- }
437481 }
438482}
0 commit comments