diff --git a/src/Numerics/LinearAlgebra/Complex/SparseMatrix.cs b/src/Numerics/LinearAlgebra/Complex/SparseMatrix.cs index 85957334..5ba10240 100644 --- a/src/Numerics/LinearAlgebra/Complex/SparseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Complex/SparseMatrix.cs @@ -31,16 +31,17 @@ namespace MathNet.Numerics.LinearAlgebra.Complex { using System; + using System.Collections.Generic; using System.Numerics; using Generic; using Properties; using Threading; - + /// /// A Matrix class with sparse storage. The underlying storage scheme is 3-array compressed-sparse-row (CSR) Format. /// Wikipedia - CSR. /// - public class SparseMatrix : Matrix + public class SparseMatrix : Matrix { /// /// Object for use in "lock" @@ -58,7 +59,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex /// array using the row-major storage mapping described in a compressed sparse row (CSR) format. /// private Complex[] _nonZeroValues = new Complex[0]; - + /// /// Gets the number of non zero elements in the matrix. /// @@ -68,7 +69,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex get; private set; } - + /// /// An array containing the column indices of the non-zero values. Element "I" of the array /// is the number of the column in matrix that contains the I-th value in the array. @@ -84,11 +85,12 @@ namespace MathNet.Numerics.LinearAlgebra.Complex /// /// The number of columns. /// - public SparseMatrix(int rows, int columns) : base(rows, columns) + public SparseMatrix(int rows, int columns) + : base(rows, columns) { _rowIndex = new int[rows]; } - + /// /// Initializes a new instance of the class. This matrix is square with a given size. /// @@ -96,7 +98,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex /// /// If is less than one. /// - public SparseMatrix(int order) : this(order, order) + public SparseMatrix(int order) + : this(order, order) { } @@ -110,7 +113,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex /// The number of columns. /// /// The value which we assign to each element of the matrix. - public SparseMatrix(int rows, int columns, Complex value) : this(rows, columns) + public SparseMatrix(int rows, int columns, Complex value) + : this(rows, columns) { if (value == 0.0) { @@ -132,7 +136,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex _nonZeroValues[i] = value; _columnIndices[i] = j; } - + // Set proper row pointers for (var i = 0; i < _rowIndex.Length; i++) { @@ -148,7 +152,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex /// The one dimensional array to create this matrix from. This array should store the matrix in column-major order. see: http://en.wikipedia.org/wiki/Column-major_order /// If length is less than * . /// - public SparseMatrix(int rows, int columns, Complex[] array) : this(rows, columns) + public SparseMatrix(int rows, int columns, Complex[] array) + : this(rows, columns) { if (rows * columns > array.Length) { @@ -168,7 +173,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex /// Initializes a new instance of the class from a 2D array. /// /// The 2D array to create this matrix from. - public SparseMatrix(Complex[,] array) : this(array.GetLength(0), array.GetLength(1)) + public SparseMatrix(Complex[,] array) + : this(array.GetLength(0), array.GetLength(1)) { var rows = array.GetLength(0); var columns = array.GetLength(1); @@ -577,7 +583,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex return index >= 0 ? _nonZeroValues[index] : 0.0; } } - + /// /// Sets the value of the given element. /// @@ -682,7 +688,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex _nonZeroValues[i - 1] = _nonZeroValues[i]; _columnIndices[i - 1] = _columnIndices[i]; } - + // Decrease value in Row for (var i = row + 1; i < _rowIndex.Length; i++) { @@ -699,7 +705,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex Array.Resize(ref _columnIndices, NonZerosCount); } } - + /// /// Find item Index in nonZeroValues array /// @@ -714,7 +720,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex var endIndex = row < _rowIndex.Length - 1 ? _rowIndex[row + 1] : NonZerosCount; return Array.BinarySearch(_columnIndices, startIndex, endIndex - startIndex, column); } - + /// /// Calculates the amount with which to grow the storage array's if they need to be /// increased in size. @@ -794,7 +800,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex Array.Copy(_rowIndex, sparseTarget._rowIndex, RowCount); } } - + /// /// Returns a hash code for this instance. /// @@ -1012,7 +1018,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex resultSparseMatrix.NonZerosCount = NonZerosCount + lowerSparseMatrix.NonZerosCount; resultSparseMatrix._nonZeroValues = new Complex[resultSparseMatrix.NonZerosCount]; resultSparseMatrix._columnIndices = new int[resultSparseMatrix.NonZerosCount]; - + Array.Copy(_nonZeroValues, 0, resultSparseMatrix._nonZeroValues, 0, NonZerosCount); Array.Copy(lowerSparseMatrix._nonZeroValues, 0, resultSparseMatrix._nonZeroValues, NonZerosCount, lowerSparseMatrix.NonZerosCount); @@ -1371,8 +1377,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex /// The result of the negation. protected override void DoNegate(Matrix result) { - CopyTo(result); - DoMultiply(-1, result); + CopyTo(result); + DoMultiply(-1, result); } /// @@ -1470,5 +1476,39 @@ namespace MathNet.Numerics.LinearAlgebra.Complex } } } + + /// + /// Iterates throw each element in the matrix (row-wise). + /// + /// The value at the current iteration along with its position (row, column, value). + public override IEnumerable> IndexedEnumerator() + { + for (var row = 0; row < RowCount - 1; row++) + { + var start = _rowIndex[row]; + var end = _rowIndex[row + 1]; + + if (start == end) + { + continue; + } + + for (var index = start; index < end; index++) + { + yield return new Tuple(row, _columnIndices[index], _nonZeroValues[index]); + } + } + + var lastRow = _rowIndex.Length - 1; + + if (_rowIndex[lastRow] < NonZerosCount) + { + for (var index = _rowIndex[lastRow]; index < NonZerosCount; index++) + { + yield return new Tuple(lastRow, _columnIndices[index], _nonZeroValues[index]); + } + } + } } } + diff --git a/src/Numerics/LinearAlgebra/Complex32/SparseMatrix.cs b/src/Numerics/LinearAlgebra/Complex32/SparseMatrix.cs index 1309f7b9..7df052f3 100644 --- a/src/Numerics/LinearAlgebra/Complex32/SparseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Complex32/SparseMatrix.cs @@ -31,6 +31,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 { using System; + using System.Collections.Generic; using Generic; using Numerics; using Properties; @@ -1470,5 +1471,38 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 } } } + + /// + /// Iterates throw each element in the matrix (row-wise). + /// + /// The value at the current iteration along with its position (row, column, value). + public override IEnumerable> IndexedEnumerator() + { + for (var row = 0; row < RowCount - 1; row++) + { + var start = _rowIndex[row]; + var end = _rowIndex[row + 1]; + + if (start == end) + { + continue; + } + + for (var index = start; index < end; index++) + { + yield return new Tuple(row, _columnIndices[index], _nonZeroValues[index]); + } + } + + var lastRow = _rowIndex.Length - 1; + + if (_rowIndex[lastRow] < NonZerosCount) + { + for (var index = _rowIndex[lastRow]; index < NonZerosCount; index++) + { + yield return new Tuple(lastRow, _columnIndices[index], _nonZeroValues[index]); + } + } + } } } diff --git a/src/Numerics/LinearAlgebra/Double/SparseMatrix.cs b/src/Numerics/LinearAlgebra/Double/SparseMatrix.cs index aac70cca..a1ac50bd 100644 --- a/src/Numerics/LinearAlgebra/Double/SparseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Double/SparseMatrix.cs @@ -31,6 +31,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double { using System; + using System.Collections.Generic; using Generic; using Properties; using Threading; @@ -1469,5 +1470,38 @@ namespace MathNet.Numerics.LinearAlgebra.Double } } } + + /// + /// Iterates throw each element in the matrix (row-wise). + /// + /// The value at the current iteration along with its position (row, column, value). + public override IEnumerable> IndexedEnumerator() + { + for (var row = 0; row < RowCount - 1; row++) + { + var start = _rowIndex[row]; + var end = _rowIndex[row + 1]; + + if (start == end) + { + continue; + } + + for (var index = start; index < end; index++) + { + yield return new Tuple(row, _columnIndices[index], _nonZeroValues[index]); + } + } + + var lastRow = _rowIndex.Length - 1; + + if (_rowIndex[lastRow] < NonZerosCount) + { + for (var index = _rowIndex[lastRow]; index < NonZerosCount; index++) + { + yield return new Tuple(lastRow, _columnIndices[index], _nonZeroValues[index]); + } + } + } } } diff --git a/src/Numerics/LinearAlgebra/Generic/Matrix.cs b/src/Numerics/LinearAlgebra/Generic/Matrix.cs index 324bf73f..39a4409c 100644 --- a/src/Numerics/LinearAlgebra/Generic/Matrix.cs +++ b/src/Numerics/LinearAlgebra/Generic/Matrix.cs @@ -1788,5 +1788,20 @@ namespace MathNet.Numerics.LinearAlgebra.Generic /// Calculates the infinity norm of this matrix. /// The infinity norm of this matrix. public abstract T InfinityNorm(); + + /// + /// Iterates throw each element in the matrix (row-wise). + /// + /// The value at the current iteration along with its position (row, column, value). + public virtual IEnumerable> IndexedEnumerator() + { + for (var row = 0; row < RowCount; row++) + { + for (var column = 0; column < ColumnCount; column++) + { + yield return new Tuple(row, column, At(row, column)); + } + } + } } } diff --git a/src/Numerics/LinearAlgebra/Single/SparseMatrix.cs b/src/Numerics/LinearAlgebra/Single/SparseMatrix.cs index c50259eb..2f2f4eb2 100644 --- a/src/Numerics/LinearAlgebra/Single/SparseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Single/SparseMatrix.cs @@ -31,6 +31,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single { using System; + using System.Collections.Generic; using Generic; using Properties; using Threading; @@ -1469,5 +1470,38 @@ namespace MathNet.Numerics.LinearAlgebra.Single } } } + + /// + /// Iterates throw each element in the matrix (row-wise). + /// + /// The value at the current iteration along with its position (row, column, value). + public override IEnumerable> IndexedEnumerator() + { + for (var row = 0; row < RowCount - 1; row++) + { + var start = _rowIndex[row]; + var end = _rowIndex[row + 1]; + + if (start == end) + { + continue; + } + + for (var index = start; index < end; index++) + { + yield return new Tuple(row, _columnIndices[index], _nonZeroValues[index]); + } + } + + var lastRow = _rowIndex.Length - 1; + + if (_rowIndex[lastRow] < NonZerosCount) + { + for (var index = _rowIndex[lastRow]; index < NonZerosCount; index++) + { + yield return new Tuple(lastRow, _columnIndices[index], _nonZeroValues[index]); + } + } + } } }