diff --git a/src/Numerics/LinearAlgebra/Complex/DenseMatrix.cs b/src/Numerics/LinearAlgebra/Complex/DenseMatrix.cs index 2a45e38f..4d59ec3e 100644 --- a/src/Numerics/LinearAlgebra/Complex/DenseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Complex/DenseMatrix.cs @@ -428,42 +428,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex return Control.LinearAlgebraProvider.MatrixNorm(Norm.FrobeniusNorm, _rowCount, _columnCount, _values); } - /// - /// Returns the transpose of this matrix. - /// - /// The transpose of this matrix. - public override Matrix Transpose() - { - var ret = new DenseMatrix(_columnCount, _rowCount); - for (var j = 0; j < _columnCount; j++) - { - var index = j * _rowCount; - for (var i = 0; i < _rowCount; i++) - { - ret._values[(i * _columnCount) + j] = _values[index + i]; - } - } - return ret; - } - - /// - /// Returns the conjugate transpose of this matrix. - /// - /// The conjugate transpose of this matrix. - public override Matrix ConjugateTranspose() - { - var ret = new DenseMatrix(_columnCount, _rowCount); - for (var j = 0; j < _columnCount; j++) - { - var index = j * _rowCount; - for (var i = 0; i < _rowCount; i++) - { - ret._values[(i * _columnCount) + j] = _values[index + i].Conjugate(); - } - } - return ret; - } - /// /// Negate each element of this matrix and place the results into the result matrix. /// diff --git a/src/Numerics/LinearAlgebra/Complex/DiagonalMatrix.cs b/src/Numerics/LinearAlgebra/Complex/DiagonalMatrix.cs index a685a329..8bc9df23 100644 --- a/src/Numerics/LinearAlgebra/Complex/DiagonalMatrix.cs +++ b/src/Numerics/LinearAlgebra/Complex/DiagonalMatrix.cs @@ -728,17 +728,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex return new DenseVector(_data).Clone(); } - /// - /// Returns the transpose of this matrix. - /// - /// The transpose of this matrix. - public override Matrix Transpose() - { - var ret = new DiagonalMatrix(ColumnCount, RowCount); - Array.Copy(_data, ret._data, _data.Length); - return ret; - } - /// Calculates the induced L1 norm of this matrix. /// The maximum absolute column sum of the matrix. public override double L1Norm() diff --git a/src/Numerics/LinearAlgebra/Complex/Matrix.cs b/src/Numerics/LinearAlgebra/Complex/Matrix.cs index 1e16da7f..f407e563 100644 --- a/src/Numerics/LinearAlgebra/Complex/Matrix.cs +++ b/src/Numerics/LinearAlgebra/Complex/Matrix.cs @@ -110,16 +110,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex /// Returns the conjugate transpose of this matrix. /// /// The conjugate transpose of this matrix. - public override Matrix ConjugateTranspose() + public override sealed Matrix ConjugateTranspose() { - var ret = Build.SameAs(this, ColumnCount, RowCount); - for (var j = 0; j < ColumnCount; j++) - { - for (var i = 0; i < RowCount; i++) - { - ret.At(j, i, At(i, j).Conjugate()); - } - } + var ret = Transpose(); + ret.MapInplace(c => c.Conjugate(), forceMapZeros: false); return ret; } diff --git a/src/Numerics/LinearAlgebra/Complex/SparseMatrix.cs b/src/Numerics/LinearAlgebra/Complex/SparseMatrix.cs index b335c960..bfc90f2c 100644 --- a/src/Numerics/LinearAlgebra/Complex/SparseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Complex/SparseMatrix.cs @@ -648,42 +648,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex DoMultiply(-1, result); } - /// - /// Returns the transpose of this matrix. - /// - /// The transpose of this matrix. - public override Matrix Transpose() - { - var rowPointers = _storage.RowPointers; - var columnIndices = _storage.ColumnIndices; - var values = _storage.Values; - - var ret = new SparseCompressedRowMatrixStorage(ColumnCount, RowCount) - { - ColumnIndices = new int[_storage.ValueCount], - Values = new Complex[_storage.ValueCount] - }; - - // Do an 'inverse' CopyTo iterate over the rows - for (var i = 0; i < RowCount; i++) - { - var startIndex = rowPointers[i]; - var endIndex = rowPointers[i + 1]; - - if (startIndex == endIndex) - { - continue; - } - - for (var j = startIndex; j < endIndex; j++) - { - ret.At(columnIndices[j], i, values[j]); - } - } - - return new SparseMatrix(ret); - } - /// Calculates the induced infinity norm of this matrix. /// The maximum absolute row sum of the matrix. public override double InfinityNorm() diff --git a/src/Numerics/LinearAlgebra/Complex32/DenseMatrix.cs b/src/Numerics/LinearAlgebra/Complex32/DenseMatrix.cs index f1ef1fe6..6e50b40e 100644 --- a/src/Numerics/LinearAlgebra/Complex32/DenseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Complex32/DenseMatrix.cs @@ -455,42 +455,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 base.DoConjugate(result); } - /// - /// Returns the transpose of this matrix. - /// - /// The transpose of this matrix. - public override Matrix Transpose() - { - var ret = new DenseMatrix(_columnCount, _rowCount); - for (var j = 0; j < _columnCount; j++) - { - var index = j * _rowCount; - for (var i = 0; i < _rowCount; i++) - { - ret._values[(i * _columnCount) + j] = _values[index + i]; - } - } - return ret; - } - - /// - /// Returns the conjugate transpose of this matrix. - /// - /// The conjugate transpose of this matrix. - public override Matrix ConjugateTranspose() - { - var ret = new DenseMatrix(_columnCount, _rowCount); - for (var j = 0; j < _columnCount; j++) - { - var index = j * _rowCount; - for (var i = 0; i < _rowCount; i++) - { - ret._values[(i * _columnCount) + j] = _values[index + i].Conjugate(); - } - } - return ret; - } - /// /// Add a scalar to each element of the matrix and stores the result in the result vector. /// diff --git a/src/Numerics/LinearAlgebra/Complex32/DiagonalMatrix.cs b/src/Numerics/LinearAlgebra/Complex32/DiagonalMatrix.cs index e71f3e38..a7c25fa1 100644 --- a/src/Numerics/LinearAlgebra/Complex32/DiagonalMatrix.cs +++ b/src/Numerics/LinearAlgebra/Complex32/DiagonalMatrix.cs @@ -722,17 +722,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 return new DenseVector(_data).Clone(); } - /// - /// Returns the transpose of this matrix. - /// - /// The transpose of this matrix. - public override Matrix Transpose() - { - var ret = new DiagonalMatrix(ColumnCount, RowCount); - Array.Copy(_data, ret._data, _data.Length); - return ret; - } - /// Calculates the induced L1 norm of this matrix. /// The maximum absolute column sum of the matrix. public override double L1Norm() diff --git a/src/Numerics/LinearAlgebra/Complex32/Matrix.cs b/src/Numerics/LinearAlgebra/Complex32/Matrix.cs index 78471bcb..61987e91 100644 --- a/src/Numerics/LinearAlgebra/Complex32/Matrix.cs +++ b/src/Numerics/LinearAlgebra/Complex32/Matrix.cs @@ -104,16 +104,10 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 /// Returns the conjugate transpose of this matrix. /// /// The conjugate transpose of this matrix. - public override Matrix ConjugateTranspose() + public override sealed Matrix ConjugateTranspose() { - var ret = Build.SameAs(this, ColumnCount, RowCount); - for (var j = 0; j < ColumnCount; j++) - { - for (var i = 0; i < RowCount; i++) - { - ret.At(j, i, At(i, j).Conjugate()); - } - } + var ret = Transpose(); + ret.MapInplace(c => c.Conjugate(), forceMapZeros: false); return ret; } diff --git a/src/Numerics/LinearAlgebra/Complex32/SparseMatrix.cs b/src/Numerics/LinearAlgebra/Complex32/SparseMatrix.cs index bd5cbb40..2a7a52b2 100644 --- a/src/Numerics/LinearAlgebra/Complex32/SparseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Complex32/SparseMatrix.cs @@ -643,42 +643,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 DoMultiply(-1, result); } - /// - /// Returns the transpose of this matrix. - /// - /// The transpose of this matrix. - public override Matrix Transpose() - { - var rowPointers = _storage.RowPointers; - var columnIndices = _storage.ColumnIndices; - var values = _storage.Values; - - var ret = new SparseCompressedRowMatrixStorage(ColumnCount, RowCount) - { - ColumnIndices = new int[_storage.ValueCount], - Values = new Complex32[_storage.ValueCount] - }; - - // Do an 'inverse' CopyTo iterate over the rows - for (var i = 0; i < RowCount; i++) - { - var startIndex = rowPointers[i]; - var endIndex = rowPointers[i + 1]; - - if (startIndex == endIndex) - { - continue; - } - - for (var j = startIndex; j < endIndex; j++) - { - ret.At(columnIndices[j], i, values[j]); - } - } - - return new SparseMatrix(ret); - } - /// Calculates the induced infinity norm of this matrix. /// The maximum absolute row sum of the matrix. public override double InfinityNorm() diff --git a/src/Numerics/LinearAlgebra/Double/DenseMatrix.cs b/src/Numerics/LinearAlgebra/Double/DenseMatrix.cs index c91c3192..c433b597 100644 --- a/src/Numerics/LinearAlgebra/Double/DenseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Double/DenseMatrix.cs @@ -436,25 +436,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double base.DoNegate(result); } - /// - /// Returns the transpose of this matrix. - /// - /// The transpose of this matrix. - public override Matrix Transpose() - { - var ret = new DenseMatrix(_columnCount, _rowCount); - for (var j = 0; j < _columnCount; j++) - { - var index = j * _rowCount; - for (var i = 0; i < _rowCount; i++) - { - ret._values[(i * _columnCount) + j] = _values[index + i]; - } - } - - return ret; - } - /// /// Add a scalar to each element of the matrix and stores the result in the result vector. /// diff --git a/src/Numerics/LinearAlgebra/Double/DiagonalMatrix.cs b/src/Numerics/LinearAlgebra/Double/DiagonalMatrix.cs index ac89caf5..6b3d04e6 100644 --- a/src/Numerics/LinearAlgebra/Double/DiagonalMatrix.cs +++ b/src/Numerics/LinearAlgebra/Double/DiagonalMatrix.cs @@ -572,17 +572,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double return new DenseVector(_data).Clone(); } - /// - /// Returns the transpose of this matrix. - /// - /// The transpose of this matrix. - public override Matrix Transpose() - { - var ret = new DiagonalMatrix(ColumnCount, RowCount); - Buffer.BlockCopy(_data, 0, ret._data, 0, _data.Length * Constants.SizeOfDouble); - return ret; - } - /// Calculates the induced L1 norm of this matrix. /// The maximum absolute column sum of the matrix. public override double L1Norm() diff --git a/src/Numerics/LinearAlgebra/Double/SparseMatrix.cs b/src/Numerics/LinearAlgebra/Double/SparseMatrix.cs index b85afa4a..fa8e7740 100644 --- a/src/Numerics/LinearAlgebra/Double/SparseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Double/SparseMatrix.cs @@ -641,43 +641,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double DoMultiply(-1, result); } - /// - /// Returns the transpose of this matrix. - /// - /// The transpose of this matrix. - public override Matrix Transpose() - { - var rowPointers = _storage.RowPointers; - var columnIndices = _storage.ColumnIndices; - var values = _storage.Values; - - var ret = new SparseCompressedRowMatrixStorage(ColumnCount, RowCount) - { - ColumnIndices = new int[_storage.ValueCount], - Values = new double[_storage.ValueCount] - }; - - // Do an 'inverse' CopyTo iterate over the rows - for (var i = 0; i < RowCount; i++) - { - var startIndex = rowPointers[i]; - var endIndex = rowPointers[i + 1]; - - if (startIndex == endIndex) - { - // Begin and end are equal. There are no values in the row, Move to the next row - continue; - } - - for (var j = startIndex; j < endIndex; j++) - { - ret.At(columnIndices[j], i, values[j]); - } - } - - return new SparseMatrix(ret); - } - /// Calculates the induced infinity norm of this matrix. /// The maximum absolute row sum of the matrix. public override double InfinityNorm() diff --git a/src/Numerics/LinearAlgebra/Matrix.cs b/src/Numerics/LinearAlgebra/Matrix.cs index 54190a89..14314ac7 100644 --- a/src/Numerics/LinearAlgebra/Matrix.cs +++ b/src/Numerics/LinearAlgebra/Matrix.cs @@ -980,16 +980,10 @@ namespace MathNet.Numerics.LinearAlgebra /// Returns the transpose of this matrix. /// /// The transpose of this matrix. - public virtual Matrix Transpose() + public Matrix Transpose() { var result = Build.SameAs(this, ColumnCount, RowCount); - for (var j = 0; j < ColumnCount; j++) - { - for (var i = 0; i < RowCount; i++) - { - result.At(j, i, At(i, j)); - } - } + Storage.TransposeToUnchecked(result.Storage, skipClearing:true); return result; } diff --git a/src/Numerics/LinearAlgebra/Single/DenseMatrix.cs b/src/Numerics/LinearAlgebra/Single/DenseMatrix.cs index 0904e179..49830598 100644 --- a/src/Numerics/LinearAlgebra/Single/DenseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Single/DenseMatrix.cs @@ -436,25 +436,6 @@ namespace MathNet.Numerics.LinearAlgebra.Single base.DoNegate(result); } - /// - /// Returns the transpose of this matrix. - /// - /// The transpose of this matrix. - public override Matrix Transpose() - { - var ret = new DenseMatrix(_columnCount, _rowCount); - for (var j = 0; j < _columnCount; j++) - { - var index = j * _rowCount; - for (var i = 0; i < _rowCount; i++) - { - ret._values[(i * _columnCount) + j] = _values[index + i]; - } - } - - return ret; - } - /// /// Add a scalar to each element of the matrix and stores the result in the result vector. /// diff --git a/src/Numerics/LinearAlgebra/Single/DiagonalMatrix.cs b/src/Numerics/LinearAlgebra/Single/DiagonalMatrix.cs index 30f77e45..d37baf8c 100644 --- a/src/Numerics/LinearAlgebra/Single/DiagonalMatrix.cs +++ b/src/Numerics/LinearAlgebra/Single/DiagonalMatrix.cs @@ -572,17 +572,6 @@ namespace MathNet.Numerics.LinearAlgebra.Single return new DenseVector(_data).Clone(); } - /// - /// Returns the transpose of this matrix. - /// - /// The transpose of this matrix. - public override Matrix Transpose() - { - var ret = new DiagonalMatrix(ColumnCount, RowCount); - Buffer.BlockCopy(_data, 0, ret._data, 0, _data.Length * Constants.SizeOfFloat); - return ret; - } - /// Calculates the induced L1 norm of this matrix. /// The maximum absolute column sum of the matrix. public override double L1Norm() diff --git a/src/Numerics/LinearAlgebra/Single/SparseMatrix.cs b/src/Numerics/LinearAlgebra/Single/SparseMatrix.cs index 5a93f58a..97bc8a6f 100644 --- a/src/Numerics/LinearAlgebra/Single/SparseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Single/SparseMatrix.cs @@ -641,45 +641,6 @@ namespace MathNet.Numerics.LinearAlgebra.Single DoMultiply(-1, result); } - /// - /// Returns the transpose of this matrix. - /// - /// The transpose of this matrix. - public override Matrix Transpose() - { - var rowPointers = _storage.RowPointers; - var columnIndices = _storage.ColumnIndices; - var values = _storage.Values; - - var ret = new SparseCompressedRowMatrixStorage(ColumnCount, RowCount) - { - ColumnIndices = new int[_storage.ValueCount], - Values = new float[_storage.ValueCount] - }; - - // Do an 'inverse' CopyTo iterate over the rows - for (var i = 0; i < RowCount; i++) - { - // Get the begin / end index for the current row - var startIndex = rowPointers[i]; - var endIndex = rowPointers[i + 1]; - - // Get the values for the current row - if (startIndex == endIndex) - { - // Begin and end are equal. There are no values in the row, Move to the next row - continue; - } - - for (var j = startIndex; j < endIndex; j++) - { - ret.At(columnIndices[j], i, values[j]); - } - } - - return new SparseMatrix(ret); - } - /// Calculates the induced infinity norm of this matrix. /// The maximum absolute row sum of the matrix. public override double InfinityNorm() diff --git a/src/Numerics/LinearAlgebra/Storage/DenseColumnMajorMatrixStorage.cs b/src/Numerics/LinearAlgebra/Storage/DenseColumnMajorMatrixStorage.cs index d85298f4..63550164 100644 --- a/src/Numerics/LinearAlgebra/Storage/DenseColumnMajorMatrixStorage.cs +++ b/src/Numerics/LinearAlgebra/Storage/DenseColumnMajorMatrixStorage.cs @@ -432,6 +432,72 @@ namespace MathNet.Numerics.LinearAlgebra.Storage } } + // TRANSPOSE + + internal override void TransposeToUnchecked(MatrixStorage target, bool skipClearing = false) + { + var denseTarget = target as DenseColumnMajorMatrixStorage; + if (denseTarget != null) + { + TransposeToUnchecked(denseTarget); + return; + } + + var sparseTarget = target as SparseCompressedRowMatrixStorage; + if (sparseTarget != null) + { + TransposeToUnchecked(sparseTarget); + return; + } + + // FALL BACK + + for (int j = 0, offset = 0; j < ColumnCount; j++, offset += RowCount) + { + for (int i = 0; i < RowCount; i++) + { + target.At(j, i, Data[i + offset]); + } + } + } + + void TransposeToUnchecked(DenseColumnMajorMatrixStorage target) + { + for (var j = 0; j < ColumnCount; j++) + { + var index = j * RowCount; + for (var i = 0; i < RowCount; i++) + { + target.Data[(i * ColumnCount) + j] = Data[index + i]; + } + } + } + + void TransposeToUnchecked(SparseCompressedRowMatrixStorage target) + { + var rowPointers = target.RowPointers; + var columnIndices = new List(); + var values = new List(); + + for (int j = 0; j < ColumnCount; j++) + { + rowPointers[j] = values.Count; + var index = j * RowCount; + for (int i = 0; i < RowCount; i++) + { + if (!Zero.Equals(Data[index + i])) + { + values.Add(Data[index + i]); + columnIndices.Add(i); + } + } + } + + rowPointers[ColumnCount] = values.Count; + target.ColumnIndices = columnIndices.ToArray(); + target.Values = values.ToArray(); + } + // EXTRACT public override T[] ToRowMajorArray() diff --git a/src/Numerics/LinearAlgebra/Storage/DiagonalMatrixStorage.cs b/src/Numerics/LinearAlgebra/Storage/DiagonalMatrixStorage.cs index 1e43ae21..10865949 100644 --- a/src/Numerics/LinearAlgebra/Storage/DiagonalMatrixStorage.cs +++ b/src/Numerics/LinearAlgebra/Storage/DiagonalMatrixStorage.cs @@ -494,6 +494,13 @@ namespace MathNet.Numerics.LinearAlgebra.Storage } } + // TRANSPOSE + + internal override void TransposeToUnchecked(MatrixStorage target, bool skipClearing = false) + { + CopyToUnchecked(target, skipClearing); + } + // EXTRACT public override T[] ToRowMajorArray() diff --git a/src/Numerics/LinearAlgebra/Storage/MatrixStorage.cs b/src/Numerics/LinearAlgebra/Storage/MatrixStorage.cs index b6971ecd..604dc40f 100644 --- a/src/Numerics/LinearAlgebra/Storage/MatrixStorage.cs +++ b/src/Numerics/LinearAlgebra/Storage/MatrixStorage.cs @@ -384,6 +384,40 @@ namespace MathNet.Numerics.LinearAlgebra.Storage } } + // TRANSPOSE + + public void TransposeTo(MatrixStorage target, bool skipClearing = false) + { + if (target == null) + { + throw new ArgumentNullException("target"); + } + + if (ReferenceEquals(this, target)) + { + throw new NotSupportedException("In-place transpose is not supported."); + } + + if (RowCount != target.ColumnCount || ColumnCount != target.RowCount) + { + var message = string.Format(Resources.ArgumentMatrixDimensions2, RowCount + "x" + ColumnCount, target.RowCount + "x" + target.ColumnCount); + throw new ArgumentException(message, "target"); + } + + TransposeToUnchecked(target, skipClearing); + } + + internal virtual void TransposeToUnchecked(MatrixStorage target, bool skipClearing = false) + { + for (int j = 0; j < ColumnCount; j++) + { + for (int i = 0; i < RowCount; i++) + { + target.At(j, i, At(i, j)); + } + } + } + // EXTRACT public virtual T[] ToRowMajorArray() diff --git a/src/Numerics/LinearAlgebra/Storage/SparseCompressedRowMatrixStorage.cs b/src/Numerics/LinearAlgebra/Storage/SparseCompressedRowMatrixStorage.cs index cd2aa145..36a5d284 100644 --- a/src/Numerics/LinearAlgebra/Storage/SparseCompressedRowMatrixStorage.cs +++ b/src/Numerics/LinearAlgebra/Storage/SparseCompressedRowMatrixStorage.cs @@ -851,6 +851,8 @@ namespace MathNet.Numerics.LinearAlgebra.Storage target.Clear(); } + // TODO: proper implementation + if (ValueCount != 0) { for (int row = 0; row < RowCount; row++) @@ -1008,6 +1010,105 @@ namespace MathNet.Numerics.LinearAlgebra.Storage } } + // TRANSPOSE + + internal override void TransposeToUnchecked(MatrixStorage target, bool skipClearing = false) + { + var sparseTarget = target as SparseCompressedRowMatrixStorage; + if (sparseTarget != null) + { + TransposeToUnchecked(sparseTarget); + return; + } + + var denseTarget = target as DenseColumnMajorMatrixStorage; + if (denseTarget != null) + { + TransposeToUnchecked(denseTarget, skipClearing); + return; + } + + // FALL BACK + + if (!skipClearing) + { + target.Clear(); + } + + if (ValueCount != 0) + { + for (int row = 0; row < RowCount; row++) + { + var startIndex = RowPointers[row]; + var endIndex = RowPointers[row + 1]; + for (var j = startIndex; j < endIndex; j++) + { + target.At(ColumnIndices[j], row, Values[j]); + } + } + } + } + + void TransposeToUnchecked(SparseCompressedRowMatrixStorage target) + { + target.Values = new T[ValueCount]; + target.ColumnIndices = new int[ValueCount]; + var cx = target.Values; + var cp = target.RowPointers; + var ci = target.ColumnIndices; + + // Column counts + int[] w = new int[ColumnCount]; + for (int p = 0; p < RowPointers[RowCount]; p++) + { + w[ColumnIndices[p]]++; + } + + // Column pointers + int nz = 0; + for (int i = 0; i < ColumnCount; i++) + { + cp[i] = nz; + nz += w[i]; + w[i] = cp[i]; + } + cp[ColumnCount] = nz; + + for (int i = 0; i < RowCount; i++) + { + for (int p = RowPointers[i]; p < RowPointers[i + 1]; p++) + { + int j = w[ColumnIndices[p]]++; + + // Place A(i,j) as entry C(j,i) + ci[j] = i; + cx[j] = Values[p]; + } + } + } + + void TransposeToUnchecked(DenseColumnMajorMatrixStorage target, bool skipClearing) + { + if (!skipClearing) + { + target.Clear(); + } + + if (ValueCount != 0) + { + for (int row = 0; row < RowCount; row++) + { + var targetIndex = row * ColumnCount; + var startIndex = RowPointers[row]; + var endIndex = RowPointers[row + 1]; + for (var j = startIndex; j < endIndex; j++) + { + target.Data[targetIndex + ColumnIndices[j]] = Values[j]; + } + } + } + } + // EXTRACT public override T[] ToRowMajorArray()