Browse Source

LA: Delegate Matrix Row/Column methods to storage classes

v2
Christoph Ruegg 14 years ago
parent
commit
cc02d61121
  1. 112
      src/Numerics/LinearAlgebra/Complex/DiagonalMatrix.cs
  2. 72
      src/Numerics/LinearAlgebra/Complex/SparseMatrix.cs
  3. 112
      src/Numerics/LinearAlgebra/Complex32/DiagonalMatrix.cs
  4. 72
      src/Numerics/LinearAlgebra/Complex32/SparseMatrix.cs
  5. 112
      src/Numerics/LinearAlgebra/Double/DiagonalMatrix.cs
  6. 72
      src/Numerics/LinearAlgebra/Double/SparseMatrix.cs
  7. 118
      src/Numerics/LinearAlgebra/Generic/Matrix.cs
  8. 112
      src/Numerics/LinearAlgebra/Single/DiagonalMatrix.cs
  9. 72
      src/Numerics/LinearAlgebra/Single/SparseMatrix.cs
  10. 48
      src/Numerics/LinearAlgebra/Storage/DenseColumnMajorMatrixStorage.cs
  11. 30
      src/Numerics/LinearAlgebra/Storage/DiagonalMatrixStorage.cs
  12. 84
      src/Numerics/LinearAlgebra/Storage/MatrixStorage.Validation.cs
  13. 48
      src/Numerics/LinearAlgebra/Storage/MatrixStorage.cs
  14. 44
      src/Numerics/LinearAlgebra/Storage/SparseCompressedRowMatrixStorage.cs

112
src/Numerics/LinearAlgebra/Complex/DiagonalMatrix.cs

@ -684,118 +684,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
return ret;
}
/// <summary>
/// Copies the requested column elements into the given vector.
/// </summary>
/// <param name="columnIndex">The column to copy elements from.</param>
/// <param name="rowIndex">The row to start copying from.</param>
/// <param name="length">The number of elements to copy.</param>
/// <param name="result">The <see cref="Vector{T}"/> to copy the column into.</param>
/// <exception cref="ArgumentNullException">If the result <see cref="Vector{T}"/> is <see langword="null" />.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="columnIndex"/> is negative,
/// or greater than or equal to the number of columns.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="rowIndex"/> is negative,
/// or greater than or equal to the number of rows.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="rowIndex"/> + <paramref name="length"/>
/// is greater than or equal to the number of rows.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="length"/> is not positive.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <strong>result.Count &lt; length</strong>.</exception>
public override void Column(int columnIndex, int rowIndex, int length, Vector<Complex> result)
{
if (result == null)
{
throw new ArgumentNullException("result");
}
if (columnIndex >= ColumnCount || columnIndex < 0)
{
throw new ArgumentOutOfRangeException("columnIndex");
}
if (rowIndex >= RowCount || rowIndex < 0)
{
throw new ArgumentOutOfRangeException("rowIndex");
}
if (rowIndex + length > RowCount)
{
throw new ArgumentOutOfRangeException("length");
}
if (length < 1)
{
throw new ArgumentOutOfRangeException("length", Resources.ArgumentMustBePositive);
}
if (result.Count < length)
{
throw new ArgumentOutOfRangeException("result", Resources.ArgumentVectorsSameLength);
}
// Clear the result and copy the diagonal entry.
result.Clear();
if (columnIndex >= rowIndex && columnIndex < rowIndex + length && columnIndex < _data.Length)
{
result[columnIndex - rowIndex] = _data[columnIndex];
}
}
/// <summary>
/// Copies the requested row elements into a new <see cref="Vector{T}"/>.
/// </summary>
/// <param name="rowIndex">The row to copy elements from.</param>
/// <param name="columnIndex">The column to start copying from.</param>
/// <param name="length">The number of elements to copy.</param>
/// <param name="result">The <see cref="Vector{T}"/> to copy the column into.</param>
/// <exception cref="ArgumentNullException">If the result <see cref="Vector{T}"/> is <see langword="null" />.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="rowIndex"/> is negative,
/// or greater than or equal to the number of columns.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="columnIndex"/> is negative,
/// or greater than or equal to the number of rows.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="columnIndex"/> + <paramref name="length"/>
/// is greater than or equal to the number of rows.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="length"/> is not positive.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <strong>result.Count &lt; length</strong>.</exception>
public override void Row(int rowIndex, int columnIndex, int length, Vector<Complex> result)
{
if (result == null)
{
throw new ArgumentNullException("result");
}
if (rowIndex >= RowCount || rowIndex < 0)
{
throw new ArgumentOutOfRangeException("rowIndex");
}
if (columnIndex >= ColumnCount || columnIndex < 0)
{
throw new ArgumentOutOfRangeException("columnIndex");
}
if (columnIndex + length > ColumnCount)
{
throw new ArgumentOutOfRangeException("length");
}
if (length < 1)
{
throw new ArgumentOutOfRangeException("length", Resources.ArgumentMustBePositive);
}
if (result.Count < length)
{
throw new ArgumentOutOfRangeException("result", Resources.ArgumentVectorsSameLength);
}
// Clear the result and copy the diagonal entry.
result.Clear();
if (rowIndex >= columnIndex && rowIndex < columnIndex + length && rowIndex < _data.Length)
{
result[rowIndex - columnIndex] = _data[rowIndex];
}
}
/// <summary>Calculates the L1 norm.</summary>
/// <returns>The L1 norm of the matrix.</returns>
public override Complex L1Norm()

72
src/Numerics/LinearAlgebra/Complex/SparseMatrix.cs

@ -612,78 +612,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
return norm;
}
/// <summary>
/// Copies the requested row elements into a new <see cref="Vector{T}"/>.
/// </summary>
/// <param name="rowIndex">The row to copy elements from.</param>
/// <param name="columnIndex">The column to start copying from.</param>
/// <param name="length">The number of elements to copy.</param>
/// <param name="result">The <see cref="Vector{T}"/> to copy the column into.</param>
/// <exception cref="ArgumentNullException">If the result <see cref="Vector{T}"/> is <see langword="null" />.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="rowIndex"/> is negative,
/// or greater than or equal to the number of columns.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="columnIndex"/> is negative,
/// or greater than or equal to the number of rows.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="columnIndex"/> + <paramref name="length"/>
/// is greater than or equal to the number of rows.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="length"/> is not positive.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <strong>result.Count &lt; length</strong>.</exception>
public override void Row(int rowIndex, int columnIndex, int length, Vector<Complex> result)
{
if (result == null)
{
throw new ArgumentNullException("result");
}
if (rowIndex >= RowCount || rowIndex < 0)
{
throw new ArgumentOutOfRangeException("rowIndex");
}
if (columnIndex >= ColumnCount || columnIndex < 0)
{
throw new ArgumentOutOfRangeException("columnIndex");
}
if (columnIndex + length > ColumnCount)
{
throw new ArgumentOutOfRangeException("length");
}
if (length < 1)
{
throw new ArgumentOutOfRangeException("length", Resources.ArgumentMustBePositive);
}
if (result.Count < length)
{
throw new ArgumentOutOfRangeException("result", Resources.ArgumentVectorsSameLength);
}
var rowPointers = _storage.RowPointers;
var values = _storage.Values;
var valueCount = _storage.ValueCount;
// Determine bounds in columnIndices array where this item should be searched (using rowIndex)
var startIndex = rowPointers[rowIndex];
var endIndex = rowIndex < rowPointers.Length - 1 ? rowPointers[rowIndex + 1] : valueCount;
if (startIndex == endIndex)
{
result.Clear();
}
else
{
// If there are non-zero elements use base class implementation
for (int i = columnIndex, j = 0; i < columnIndex + length; i++, j++)
{
// Copy code from At(row, column) to avoid unnecessary lock
var index = _storage.FindItem(rowIndex, i);
result[j] = index >= 0 ? values[index] : Complex.Zero;
}
}
}
#region Static constructors for special matrices.
/// <summary>
/// Initializes a square <see cref="SparseMatrix"/> with all zero's except for ones on the diagonal.

112
src/Numerics/LinearAlgebra/Complex32/DiagonalMatrix.cs

@ -684,118 +684,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
return ret;
}
/// <summary>
/// Copies the requested column elements into the given vector.
/// </summary>
/// <param name="columnIndex">The column to copy elements from.</param>
/// <param name="rowIndex">The row to start copying from.</param>
/// <param name="length">The number of elements to copy.</param>
/// <param name="result">The <see cref="Vector{T}"/> to copy the column into.</param>
/// <exception cref="ArgumentNullException">If the result <see cref="Vector{T}"/> is <see langword="null" />.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="columnIndex"/> is negative,
/// or greater than or equal to the number of columns.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="rowIndex"/> is negative,
/// or greater than or equal to the number of rows.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="rowIndex"/> + <paramref name="length"/>
/// is greater than or equal to the number of rows.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="length"/> is not positive.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <strong>result.Count &lt; length</strong>.</exception>
public override void Column(int columnIndex, int rowIndex, int length, Vector<Complex32> result)
{
if (result == null)
{
throw new ArgumentNullException("result");
}
if (columnIndex >= ColumnCount || columnIndex < 0)
{
throw new ArgumentOutOfRangeException("columnIndex");
}
if (rowIndex >= RowCount || rowIndex < 0)
{
throw new ArgumentOutOfRangeException("rowIndex");
}
if (rowIndex + length > RowCount)
{
throw new ArgumentOutOfRangeException("length");
}
if (length < 1)
{
throw new ArgumentOutOfRangeException("length", Resources.ArgumentMustBePositive);
}
if (result.Count < length)
{
throw new ArgumentOutOfRangeException("result", Resources.ArgumentVectorsSameLength);
}
// Clear the result and copy the diagonal entry.
result.Clear();
if (columnIndex >= rowIndex && columnIndex < rowIndex + length && columnIndex < _data.Length)
{
result[columnIndex - rowIndex] = _data[columnIndex];
}
}
/// <summary>
/// Copies the requested row elements into a new <see cref="Vector{T}"/>.
/// </summary>
/// <param name="rowIndex">The row to copy elements from.</param>
/// <param name="columnIndex">The column to start copying from.</param>
/// <param name="length">The number of elements to copy.</param>
/// <param name="result">The <see cref="Vector{T}"/> to copy the column into.</param>
/// <exception cref="ArgumentNullException">If the result <see cref="Vector{T}"/> is <see langword="null" />.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="rowIndex"/> is negative,
/// or greater than or equal to the number of columns.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="columnIndex"/> is negative,
/// or greater than or equal to the number of rows.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="columnIndex"/> + <paramref name="length"/>
/// is greater than or equal to the number of rows.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="length"/> is not positive.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <strong>result.Count &lt; length</strong>.</exception>
public override void Row(int rowIndex, int columnIndex, int length, Vector<Complex32> result)
{
if (result == null)
{
throw new ArgumentNullException("result");
}
if (rowIndex >= RowCount || rowIndex < 0)
{
throw new ArgumentOutOfRangeException("rowIndex");
}
if (columnIndex >= ColumnCount || columnIndex < 0)
{
throw new ArgumentOutOfRangeException("columnIndex");
}
if (columnIndex + length > ColumnCount)
{
throw new ArgumentOutOfRangeException("length");
}
if (length < 1)
{
throw new ArgumentOutOfRangeException("length", Resources.ArgumentMustBePositive);
}
if (result.Count < length)
{
throw new ArgumentOutOfRangeException("result", Resources.ArgumentVectorsSameLength);
}
// Clear the result and copy the diagonal entry.
result.Clear();
if (rowIndex >= columnIndex && rowIndex < columnIndex + length && rowIndex < _data.Length)
{
result[rowIndex - columnIndex] = _data[rowIndex];
}
}
/// <summary>Calculates the L1 norm.</summary>
/// <returns>The L1 norm of the matrix.</returns>
public override Complex32 L1Norm()

72
src/Numerics/LinearAlgebra/Complex32/SparseMatrix.cs

@ -612,78 +612,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
return norm;
}
/// <summary>
/// Copies the requested row elements into a new <see cref="Vector{T}"/>.
/// </summary>
/// <param name="rowIndex">The row to copy elements from.</param>
/// <param name="columnIndex">The column to start copying from.</param>
/// <param name="length">The number of elements to copy.</param>
/// <param name="result">The <see cref="Vector{T}"/> to copy the column into.</param>
/// <exception cref="ArgumentNullException">If the result <see cref="Vector{T}"/> is <see langword="null" />.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="rowIndex"/> is negative,
/// or greater than or equal to the number of columns.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="columnIndex"/> is negative,
/// or greater than or equal to the number of rows.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="columnIndex"/> + <paramref name="length"/>
/// is greater than or equal to the number of rows.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="length"/> is not positive.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <strong>result.Count &lt; length</strong>.</exception>
public override void Row(int rowIndex, int columnIndex, int length, Vector<Complex32> result)
{
if (result == null)
{
throw new ArgumentNullException("result");
}
if (rowIndex >= RowCount || rowIndex < 0)
{
throw new ArgumentOutOfRangeException("rowIndex");
}
if (columnIndex >= ColumnCount || columnIndex < 0)
{
throw new ArgumentOutOfRangeException("columnIndex");
}
if (columnIndex + length > ColumnCount)
{
throw new ArgumentOutOfRangeException("length");
}
if (length < 1)
{
throw new ArgumentOutOfRangeException("length", Resources.ArgumentMustBePositive);
}
if (result.Count < length)
{
throw new ArgumentOutOfRangeException("result", Resources.ArgumentVectorsSameLength);
}
var rowPointers = _storage.RowPointers;
var values = _storage.Values;
var valueCount = _storage.ValueCount;
// Determine bounds in columnIndices array where this item should be searched (using rowIndex)
var startIndex = rowPointers[rowIndex];
var endIndex = rowIndex < rowPointers.Length - 1 ? rowPointers[rowIndex + 1] : valueCount;
if (startIndex == endIndex)
{
result.Clear();
}
else
{
// If there are non-zero elements use base class implementation
for (int i = columnIndex, j = 0; i < columnIndex + length; i++, j++)
{
// Copy code from At(row, column) to avoid unnecessary lock
var index = _storage.FindItem(rowIndex, i);
result[j] = index >= 0 ? values[index] : Complex32.Zero;
}
}
}
#region Static constructors for special matrices.
/// <summary>
/// Initializes a square <see cref="SparseMatrix"/> with all zero's except for ones on the diagonal.

112
src/Numerics/LinearAlgebra/Double/DiagonalMatrix.cs

@ -678,118 +678,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double
return ret;
}
/// <summary>
/// Copies the requested column elements into the given vector.
/// </summary>
/// <param name="columnIndex">The column to copy elements from.</param>
/// <param name="rowIndex">The row to start copying from.</param>
/// <param name="length">The number of elements to copy.</param>
/// <param name="result">The <see cref="Vector{T}"/> to copy the column into.</param>
/// <exception cref="ArgumentNullException">If the result <see cref="Vector{T}"/> is <see langword="null" />.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="columnIndex"/> is negative,
/// or greater than or equal to the number of columns.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="rowIndex"/> is negative,
/// or greater than or equal to the number of rows.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="rowIndex"/> + <paramref name="length"/>
/// is greater than or equal to the number of rows.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="length"/> is not positive.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <strong>result.Count &lt; length</strong>.</exception>
public override void Column(int columnIndex, int rowIndex, int length, Vector<double> result)
{
if (result == null)
{
throw new ArgumentNullException("result");
}
if (columnIndex >= ColumnCount || columnIndex < 0)
{
throw new ArgumentOutOfRangeException("columnIndex");
}
if (rowIndex >= RowCount || rowIndex < 0)
{
throw new ArgumentOutOfRangeException("rowIndex");
}
if (rowIndex + length > RowCount)
{
throw new ArgumentOutOfRangeException("length");
}
if (length < 1)
{
throw new ArgumentOutOfRangeException("length", Resources.ArgumentMustBePositive);
}
if (result.Count < length)
{
throw new ArgumentOutOfRangeException("result", Resources.ArgumentVectorsSameLength);
}
// Clear the result and copy the diagonal entry.
result.Clear();
if (columnIndex >= rowIndex && columnIndex < rowIndex + length && columnIndex < _data.Length)
{
result[columnIndex - rowIndex] = _data[columnIndex];
}
}
/// <summary>
/// Copies the requested row elements into a new <see cref="Vector{T}"/>.
/// </summary>
/// <param name="rowIndex">The row to copy elements from.</param>
/// <param name="columnIndex">The column to start copying from.</param>
/// <param name="length">The number of elements to copy.</param>
/// <param name="result">The <see cref="Vector{T}"/> to copy the column into.</param>
/// <exception cref="ArgumentNullException">If the result <see cref="Vector{T}"/> is <see langword="null" />.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="rowIndex"/> is negative,
/// or greater than or equal to the number of columns.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="columnIndex"/> is negative,
/// or greater than or equal to the number of rows.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="columnIndex"/> + <paramref name="length"/>
/// is greater than or equal to the number of rows.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="length"/> is not positive.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <strong>result.Count &lt; length</strong>.</exception>
public override void Row(int rowIndex, int columnIndex, int length, Vector<double> result)
{
if (result == null)
{
throw new ArgumentNullException("result");
}
if (rowIndex >= RowCount || rowIndex < 0)
{
throw new ArgumentOutOfRangeException("rowIndex");
}
if (columnIndex >= ColumnCount || columnIndex < 0)
{
throw new ArgumentOutOfRangeException("columnIndex");
}
if (columnIndex + length > ColumnCount)
{
throw new ArgumentOutOfRangeException("length");
}
if (length < 1)
{
throw new ArgumentOutOfRangeException("length", Resources.ArgumentMustBePositive);
}
if (result.Count < length)
{
throw new ArgumentOutOfRangeException("result", Resources.ArgumentVectorsSameLength);
}
// Clear the result and copy the diagonal entry.
result.Clear();
if (rowIndex >= columnIndex && rowIndex < columnIndex + length && rowIndex < _data.Length)
{
result[rowIndex - columnIndex] = _data[rowIndex];
}
}
/// <summary>Calculates the L1 norm.</summary>
/// <returns>The L1 norm of the matrix.</returns>
public override double L1Norm()

72
src/Numerics/LinearAlgebra/Double/SparseMatrix.cs

@ -610,78 +610,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double
return norm;
}
/// <summary>
/// Copies the requested row elements into a new <see cref="Vector{T}"/>.
/// </summary>
/// <param name="rowIndex">The row to copy elements from.</param>
/// <param name="columnIndex">The column to start copying from.</param>
/// <param name="length">The number of elements to copy.</param>
/// <param name="result">The <see cref="Vector{T}"/> to copy the column into.</param>
/// <exception cref="ArgumentNullException">If the result <see cref="Vector{T}"/> is <see langword="null" />.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="rowIndex"/> is negative,
/// or greater than or equal to the number of columns.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="columnIndex"/> is negative,
/// or greater than or equal to the number of rows.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="columnIndex"/> + <paramref name="length"/>
/// is greater than or equal to the number of rows.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="length"/> is not positive.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <strong>result.Count &lt; length</strong>.</exception>
public override void Row(int rowIndex, int columnIndex, int length, Vector<double> result)
{
if (result == null)
{
throw new ArgumentNullException("result");
}
if (rowIndex >= RowCount || rowIndex < 0)
{
throw new ArgumentOutOfRangeException("rowIndex");
}
if (columnIndex >= ColumnCount || columnIndex < 0)
{
throw new ArgumentOutOfRangeException("columnIndex");
}
if (columnIndex + length > ColumnCount)
{
throw new ArgumentOutOfRangeException("length");
}
if (length < 1)
{
throw new ArgumentOutOfRangeException("length", Resources.ArgumentMustBePositive);
}
if (result.Count < length)
{
throw new ArgumentOutOfRangeException("result", Resources.ArgumentVectorsSameLength);
}
var rowPointers = _storage.RowPointers;
var values = _storage.Values;
var valueCount = _storage.ValueCount;
// Determine bounds in columnIndices array where this item should be searched (using rowIndex)
var startIndex = rowPointers[rowIndex];
var endIndex = rowIndex < rowPointers.Length - 1 ? rowPointers[rowIndex + 1] : valueCount;
if (startIndex == endIndex)
{
result.Clear();
}
else
{
// If there are non-zero elements use base class implementation
for (int i = columnIndex, j = 0; i < columnIndex + length; i++, j++)
{
// Copy code from At(row, column) to avoid unnecessary lock
var index = _storage.FindItem(rowIndex, i);
result[j] = index >= 0 ? values[index] : 0d;
}
}
}
#region Static constructors for special matrices.
/// <summary>
/// Initializes a square <see cref="SparseMatrix"/> with all zero's except for ones on the diagonal.

118
src/Numerics/LinearAlgebra/Generic/Matrix.cs

@ -283,7 +283,7 @@ namespace MathNet.Numerics.LinearAlgebra.Generic
/// <returns>
/// A clone of the instance.
/// </returns>
public virtual Matrix<T> Clone()
public Matrix<T> Clone()
{
var result = CreateMatrix(RowCount, ColumnCount);
Storage.CopyToUnchecked(result.Storage, skipClearing: true);
@ -357,10 +357,15 @@ namespace MathNet.Numerics.LinearAlgebra.Generic
/// <returns>A Vector containing the copied elements.</returns>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="index"/> is negative,
/// or greater than or equal to the number of rows.</exception>
public virtual Vector<T> Row(int index)
public Vector<T> Row(int index)
{
if (index >= RowCount || index < 0)
{
throw new ArgumentOutOfRangeException("index");
}
var ret = CreateVector(ColumnCount);
Row(index, 0, ColumnCount, ret);
Storage.CopySubRowToUnchecked(ret.Storage, index, 0, 0, ColumnCount);
return ret;
}
@ -373,9 +378,14 @@ namespace MathNet.Numerics.LinearAlgebra.Generic
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="index"/> is negative,
/// or greater than or equal to the number of rows.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <b>this.Columns != result.Count</b>.</exception>
public virtual void Row(int index, Vector<T> result)
public void Row(int index, Vector<T> result)
{
Row(index, 0, ColumnCount, result);
if (result == null)
{
throw new ArgumentNullException("result");
}
Storage.CopySubRowTo(result.Storage, index, 0, 0, ColumnCount);
}
/// <summary>
@ -392,10 +402,10 @@ namespace MathNet.Numerics.LinearAlgebra.Generic
/// or greater than or equal to the number of columns.</item>
/// <item><c>(columnIndex + length) &gt;= Columns.</c></item></list></exception>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="length"/> is not positive.</exception>
public virtual Vector<T> Row(int rowIndex, int columnIndex, int length)
public Vector<T> Row(int rowIndex, int columnIndex, int length)
{
var ret = CreateVector(length);
Row(rowIndex, columnIndex, length, ret);
Storage.CopySubRowTo(ret.Storage, rowIndex, columnIndex, 0, length);
return ret;
}
@ -415,42 +425,14 @@ namespace MathNet.Numerics.LinearAlgebra.Generic
/// is greater than or equal to the number of rows.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="length"/> is not positive.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <strong>result.Count &lt; length</strong>.</exception>
public virtual void Row(int rowIndex, int columnIndex, int length, Vector<T> result)
public void Row(int rowIndex, int columnIndex, int length, Vector<T> result)
{
if (result == null)
{
throw new ArgumentNullException("result");
}
if (rowIndex >= RowCount || rowIndex < 0)
{
throw new ArgumentOutOfRangeException("rowIndex");
}
if (columnIndex >= ColumnCount || columnIndex < 0)
{
throw new ArgumentOutOfRangeException("columnIndex");
}
if (columnIndex + length > ColumnCount)
{
throw new ArgumentOutOfRangeException("length");
}
if (length < 1)
{
throw new ArgumentOutOfRangeException("length", Resources.ArgumentMustBePositive);
}
if (result.Count < length)
{
throw new ArgumentOutOfRangeException("result", Resources.ArgumentVectorsSameLength);
}
for (int i = columnIndex, j = 0; i < columnIndex + length; i++, j++)
{
result[j] = At(rowIndex, i);
}
Storage.CopySubRowTo(result.Storage, rowIndex, columnIndex, 0, length);
}
/// <summary>
@ -460,11 +442,16 @@ namespace MathNet.Numerics.LinearAlgebra.Generic
/// <returns>A Vector containing the copied elements.</returns>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="index"/> is negative,
/// or greater than or equal to the number of columns.</exception>
public virtual Vector<T> Column(int index)
public Vector<T> Column(int index)
{
var result = CreateVector(RowCount);
Column(index, 0, RowCount, result);
return result;
if (index >= ColumnCount || index < 0)
{
throw new ArgumentOutOfRangeException("index");
}
var ret = CreateVector(RowCount);
Storage.CopySubColumnToUnchecked(ret.Storage, index, 0, 0, RowCount);
return ret;
}
/// <summary>
@ -476,9 +463,14 @@ namespace MathNet.Numerics.LinearAlgebra.Generic
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="index"/> is negative,
/// or greater than or equal to the number of columns.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <b>this.Rows != result.Count</b>.</exception>
public virtual void Column(int index, Vector<T> result)
public void Column(int index, Vector<T> result)
{
Column(index, 0, RowCount, result);
if (result == null)
{
throw new ArgumentNullException("result");
}
Storage.CopySubColumnTo(result.Storage, index, 0, 0, RowCount);
}
/// <summary>
@ -496,11 +488,11 @@ namespace MathNet.Numerics.LinearAlgebra.Generic
/// <item><c>(rowIndex + length) &gt;= Rows.</c></item></list>
/// </exception>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="length"/> is not positive.</exception>
public virtual Vector<T> Column(int columnIndex, int rowIndex, int length)
public Vector<T> Column(int columnIndex, int rowIndex, int length)
{
var result = CreateVector(length);
Column(columnIndex, rowIndex, length, result);
return result;
var ret = CreateVector(length);
Storage.CopySubColumnTo(ret.Storage, columnIndex, rowIndex, 0, length);
return ret;
}
/// <summary>
@ -519,42 +511,14 @@ namespace MathNet.Numerics.LinearAlgebra.Generic
/// is greater than or equal to the number of rows.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="length"/> is not positive.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <strong>result.Count &lt; length</strong>.</exception>
public virtual void Column(int columnIndex, int rowIndex, int length, Vector<T> result)
public void Column(int columnIndex, int rowIndex, int length, Vector<T> result)
{
if (result == null)
{
throw new ArgumentNullException("result");
}
if (columnIndex >= ColumnCount || columnIndex < 0)
{
throw new ArgumentOutOfRangeException("columnIndex");
}
if (rowIndex >= RowCount || rowIndex < 0)
{
throw new ArgumentOutOfRangeException("rowIndex");
}
if (rowIndex + length > RowCount)
{
throw new ArgumentOutOfRangeException("length");
}
if (length < 1)
{
throw new ArgumentOutOfRangeException("length", Resources.ArgumentMustBePositive);
}
if (result.Count < length)
{
throw new ArgumentOutOfRangeException("result", Resources.ArgumentVectorsSameLength);
}
for (int i = rowIndex, j = 0; i < rowIndex + length; i++, j++)
{
result[j] = At(i, columnIndex);
}
Storage.CopySubColumnTo(result.Storage, columnIndex, rowIndex, 0, length);
}
/// <summary>

112
src/Numerics/LinearAlgebra/Single/DiagonalMatrix.cs

@ -678,118 +678,6 @@ namespace MathNet.Numerics.LinearAlgebra.Single
return ret;
}
/// <summary>
/// Copies the requested column elements into the given vector.
/// </summary>
/// <param name="columnIndex">The column to copy elements from.</param>
/// <param name="rowIndex">The row to start copying from.</param>
/// <param name="length">The number of elements to copy.</param>
/// <param name="result">The <see cref="Vector{T}"/> to copy the column into.</param>
/// <exception cref="ArgumentNullException">If the result <see cref="Vector{T}"/> is <see langword="null" />.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="columnIndex"/> is negative,
/// or greater than or equal to the number of columns.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="rowIndex"/> is negative,
/// or greater than or equal to the number of rows.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="rowIndex"/> + <paramref name="length"/>
/// is greater than or equal to the number of rows.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="length"/> is not positive.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <strong>result.Count &lt; length</strong>.</exception>
public override void Column(int columnIndex, int rowIndex, int length, Vector<float> result)
{
if (result == null)
{
throw new ArgumentNullException("result");
}
if (columnIndex >= ColumnCount || columnIndex < 0)
{
throw new ArgumentOutOfRangeException("columnIndex");
}
if (rowIndex >= RowCount || rowIndex < 0)
{
throw new ArgumentOutOfRangeException("rowIndex");
}
if (rowIndex + length > RowCount)
{
throw new ArgumentOutOfRangeException("length");
}
if (length < 1)
{
throw new ArgumentOutOfRangeException("length", Resources.ArgumentMustBePositive);
}
if (result.Count < length)
{
throw new ArgumentOutOfRangeException("result", Resources.ArgumentVectorsSameLength);
}
// Clear the result and copy the diagonal entry.
result.Clear();
if (columnIndex >= rowIndex && columnIndex < rowIndex + length && columnIndex < _data.Length)
{
result[columnIndex - rowIndex] = _data[columnIndex];
}
}
/// <summary>
/// Copies the requested row elements into a new <see cref="Vector{T}"/>.
/// </summary>
/// <param name="rowIndex">The row to copy elements from.</param>
/// <param name="columnIndex">The column to start copying from.</param>
/// <param name="length">The number of elements to copy.</param>
/// <param name="result">The <see cref="Vector{T}"/> to copy the column into.</param>
/// <exception cref="ArgumentNullException">If the result <see cref="Vector{T}"/> is <see langword="null" />.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="rowIndex"/> is negative,
/// or greater than or equal to the number of columns.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="columnIndex"/> is negative,
/// or greater than or equal to the number of rows.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="columnIndex"/> + <paramref name="length"/>
/// is greater than or equal to the number of rows.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="length"/> is not positive.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <strong>result.Count &lt; length</strong>.</exception>
public override void Row(int rowIndex, int columnIndex, int length, Vector<float> result)
{
if (result == null)
{
throw new ArgumentNullException("result");
}
if (rowIndex >= RowCount || rowIndex < 0)
{
throw new ArgumentOutOfRangeException("rowIndex");
}
if (columnIndex >= ColumnCount || columnIndex < 0)
{
throw new ArgumentOutOfRangeException("columnIndex");
}
if (columnIndex + length > ColumnCount)
{
throw new ArgumentOutOfRangeException("length");
}
if (length < 1)
{
throw new ArgumentOutOfRangeException("length", Resources.ArgumentMustBePositive);
}
if (result.Count < length)
{
throw new ArgumentOutOfRangeException("result", Resources.ArgumentVectorsSameLength);
}
// Clear the result and copy the diagonal entry.
result.Clear();
if (rowIndex >= columnIndex && rowIndex < columnIndex + length && rowIndex < _data.Length)
{
result[rowIndex - columnIndex] = _data[rowIndex];
}
}
/// <summary>Calculates the L1 norm.</summary>
/// <returns>The L1 norm of the matrix.</returns>
public override float L1Norm()

72
src/Numerics/LinearAlgebra/Single/SparseMatrix.cs

@ -610,78 +610,6 @@ namespace MathNet.Numerics.LinearAlgebra.Single
return norm;
}
/// <summary>
/// Copies the requested row elements into a new <see cref="Vector{T}"/>.
/// </summary>
/// <param name="rowIndex">The row to copy elements from.</param>
/// <param name="columnIndex">The column to start copying from.</param>
/// <param name="length">The number of elements to copy.</param>
/// <param name="result">The <see cref="Vector{T}"/> to copy the column into.</param>
/// <exception cref="ArgumentNullException">If the result <see cref="Vector{T}"/> is <see langword="null" />.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="rowIndex"/> is negative,
/// or greater than or equal to the number of columns.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="columnIndex"/> is negative,
/// or greater than or equal to the number of rows.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="columnIndex"/> + <paramref name="length"/>
/// is greater than or equal to the number of rows.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="length"/> is not positive.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <strong>result.Count &lt; length</strong>.</exception>
public override void Row(int rowIndex, int columnIndex, int length, Vector<float> result)
{
if (result == null)
{
throw new ArgumentNullException("result");
}
if (rowIndex >= RowCount || rowIndex < 0)
{
throw new ArgumentOutOfRangeException("rowIndex");
}
if (columnIndex >= ColumnCount || columnIndex < 0)
{
throw new ArgumentOutOfRangeException("columnIndex");
}
if (columnIndex + length > ColumnCount)
{
throw new ArgumentOutOfRangeException("length");
}
if (length < 1)
{
throw new ArgumentOutOfRangeException("length", Resources.ArgumentMustBePositive);
}
if (result.Count < length)
{
throw new ArgumentOutOfRangeException("result", Resources.ArgumentVectorsSameLength);
}
var rowPointers = _storage.RowPointers;
var values = _storage.Values;
var valueCount = _storage.ValueCount;
// Determine bounds in columnIndices array where this item should be searched (using rowIndex)
var startIndex = rowPointers[rowIndex];
var endIndex = rowIndex < rowPointers.Length - 1 ? rowPointers[rowIndex + 1] : valueCount;
if (startIndex == endIndex)
{
result.Clear();
}
else
{
// If there are non-zero elements use base class implementation
for (int i = columnIndex, j = 0; i < columnIndex + length; i++, j++)
{
// Copy code from At(row, column) to avoid unnecessary lock
var index = _storage.FindItem(rowIndex, i);
result[j] = index >= 0 ? values[index] : 0f;
}
}
}
#region Static constructors for special matrices.
/// <summary>
/// Initializes a square <see cref="SparseMatrix"/> with all zero's except for ones on the diagonal.

48
src/Numerics/LinearAlgebra/Storage/DenseColumnMajorMatrixStorage.cs

@ -121,5 +121,53 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
Array.Copy(Data, j*RowCount + sourceRowIndex, target.Data, jj*target.RowCount + targetRowIndex, rowCount);
}
}
internal override void CopySubRowToUnchecked(VectorStorage<T> target, int rowIndex, int sourceColumnIndex, int targetColumnIndex, int columnCount, bool skipClearing = false)
{
var denseTarget = target as DenseVectorStorage<T>;
if (denseTarget != null)
{
CopySubRowToUnchecked(denseTarget, rowIndex, sourceColumnIndex, targetColumnIndex, columnCount);
return;
}
// FALL BACK
for (int j = sourceColumnIndex, jj = targetColumnIndex; j < sourceColumnIndex + columnCount; j++, jj++)
{
target.At(jj, Data[(j * RowCount) + rowIndex]);
}
}
void CopySubRowToUnchecked(DenseVectorStorage<T> target, int rowIndex, int sourceColumnIndex, int targetColumnIndex, int columnCount, bool skipClearing = false)
{
for (int j = 0; j<columnCount; j++)
{
target.Data[j + targetColumnIndex] = Data[(j + sourceColumnIndex) * RowCount + rowIndex];
}
}
internal override void CopySubColumnToUnchecked(VectorStorage<T> target, int columnIndex, int sourceRowIndex, int targetRowIndex, int rowCount, bool skipClearing = false)
{
var denseTarget = target as DenseVectorStorage<T>;
if (denseTarget != null)
{
CopySubColumnToUnchecked(denseTarget, columnIndex, sourceRowIndex, targetRowIndex, rowCount);
return;
}
// FALL BACK
var offset = columnIndex * RowCount;
for (int i = sourceRowIndex, ii = targetRowIndex; i < sourceRowIndex + rowCount; i++, ii++)
{
target.At(ii, Data[offset + i]);
}
}
void CopySubColumnToUnchecked(DenseVectorStorage<T> target, int columnIndex, int sourceRowIndex, int targetRowIndex, int rowCount, bool skipClearing = false)
{
Array.Copy(Data, columnIndex*RowCount + sourceRowIndex, target.Data, targetRowIndex, rowCount);
}
}
}

30
src/Numerics/LinearAlgebra/Storage/DiagonalMatrixStorage.cs

@ -355,5 +355,35 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
// else: all zero, nop
}
internal override void CopySubRowToUnchecked(VectorStorage<T> target, int rowIndex,
int sourceColumnIndex, int targetColumnIndex, int columnCount,
bool skipClearing = false)
{
if (!skipClearing)
{
target.Clear(targetColumnIndex, columnCount);
}
if (rowIndex >= sourceColumnIndex && rowIndex < sourceColumnIndex + columnCount && rowIndex < Data.Length)
{
target.At(rowIndex - sourceColumnIndex + targetColumnIndex, Data[rowIndex]);
}
}
internal override void CopySubColumnToUnchecked(VectorStorage<T> target, int columnIndex,
int sourceRowIndex, int targetRowIndex, int rowCount,
bool skipClearing = false)
{
if (!skipClearing)
{
target.Clear(targetRowIndex, rowCount);
}
if (columnIndex >= sourceRowIndex && columnIndex < sourceRowIndex + rowCount && columnIndex < Data.Length)
{
target.At(columnIndex - sourceRowIndex + targetRowIndex, Data[columnIndex]);
}
}
}
}

84
src/Numerics/LinearAlgebra/Storage/MatrixStorage.Validation.cs

@ -3,10 +3,10 @@ using MathNet.Numerics.Properties;
namespace MathNet.Numerics.LinearAlgebra.Storage
{
// ReSharper disable UnusedParameter.Global
// ReSharper disable UnusedParameter.Local
public partial class MatrixStorage<T>
{
protected void ValidateRange(int row, int column)
void ValidateRange(int row, int column)
{
if (row < 0 || row >= RowCount)
{
@ -19,7 +19,7 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
}
}
protected void ValidateSubMatrixRange(MatrixStorage<T> target,
void ValidateSubMatrixRange(MatrixStorage<T> target,
int sourceRowIndex, int targetRowIndex, int rowCount,
int sourceColumnIndex, int targetColumnIndex, int columnCount)
{
@ -83,6 +83,82 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
throw new ArgumentOutOfRangeException("columnCount");
}
}
void ValidateSubRowRange(VectorStorage<T> target, int rowIndex,
int sourceColumnIndex, int targetColumnIndex, int columnCount)
{
if (columnCount < 1)
{
throw new ArgumentOutOfRangeException("columnCount", Resources.ArgumentMustBePositive);
}
// Verify Source
if (rowIndex >= RowCount || rowIndex < 0)
{
throw new ArgumentOutOfRangeException("rowIndex");
}
if (sourceColumnIndex >= ColumnCount || sourceColumnIndex < 0)
{
throw new ArgumentOutOfRangeException("sourceColumnIndex");
}
if (sourceColumnIndex + columnCount > ColumnCount)
{
throw new ArgumentOutOfRangeException("columnCount");
}
// Verify Target
if (targetColumnIndex >= target.Length || targetColumnIndex < 0)
{
throw new ArgumentOutOfRangeException("targetColumnIndex");
}
if (targetColumnIndex + columnCount > target.Length)
{
throw new ArgumentOutOfRangeException("columnCount");
}
}
void ValidateSubColumnRange(VectorStorage<T> target, int columnIndex,
int sourceRowIndex, int targetRowIndex, int rowCount)
{
if (rowCount < 1)
{
throw new ArgumentOutOfRangeException("rowCount", Resources.ArgumentMustBePositive);
}
// Verify Source
if (columnIndex >= ColumnCount || columnIndex < 0)
{
throw new ArgumentOutOfRangeException("columnIndex");
}
if (sourceRowIndex >= RowCount || sourceRowIndex < 0)
{
throw new ArgumentOutOfRangeException("sourceRowIndex");
}
if (sourceRowIndex + rowCount > RowCount)
{
throw new ArgumentOutOfRangeException("rowCount");
}
// Verify Target
if (targetRowIndex >= target.Length || targetRowIndex < 0)
{
throw new ArgumentOutOfRangeException("targetRowIndex");
}
if (targetRowIndex + rowCount > target.Length)
{
throw new ArgumentOutOfRangeException("rowCount");
}
}
}
// ReSharper restore UnusedParameter.Global
// ReSharper restore UnusedParameter.Local
}

48
src/Numerics/LinearAlgebra/Storage/MatrixStorage.cs

@ -263,5 +263,53 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
}
}
}
public void CopySubRowTo(VectorStorage<T> target, int rowIndex,
int sourceColumnIndex, int targetColumnIndex, int columnCount,
bool skipClearing = false)
{
if (target == null)
{
throw new ArgumentNullException("target");
}
ValidateSubRowRange(target, rowIndex, sourceColumnIndex, targetColumnIndex, columnCount);
CopySubRowToUnchecked(target, rowIndex, sourceColumnIndex, targetColumnIndex, columnCount, skipClearing);
}
internal virtual void CopySubRowToUnchecked(VectorStorage<T> target, int rowIndex,
int sourceColumnIndex, int targetColumnIndex, int columnCount,
bool skipClearing = false)
{
for (int j = sourceColumnIndex, jj = targetColumnIndex; j < sourceColumnIndex + columnCount; j++, jj++)
{
target.At(jj, At(rowIndex, j));
}
}
public void CopySubColumnTo(VectorStorage<T> target, int columnIndex,
int sourceRowIndex, int targetRowIndex, int rowCount,
bool skipClearing = false)
{
if (target == null)
{
throw new ArgumentNullException("target");
}
ValidateSubColumnRange(target, columnIndex, sourceRowIndex, targetRowIndex, rowCount);
CopySubColumnToUnchecked(target, columnIndex, sourceRowIndex, targetRowIndex, rowCount, skipClearing);
}
internal virtual void CopySubColumnToUnchecked(VectorStorage<T> target, int columnIndex,
int sourceRowIndex, int targetRowIndex, int rowCount,
bool skipClearing = false)
{
for (int i = sourceRowIndex, ii = targetRowIndex; i < sourceRowIndex + rowCount; i++, ii++)
{
target.At(ii, At(i, columnIndex));
}
}
}
}

44
src/Numerics/LinearAlgebra/Storage/SparseCompressedRowMatrixStorage.cs

@ -432,15 +432,6 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
// FALL BACK
if (ReferenceEquals(this, target))
{
throw new NotSupportedException();
}
ValidateSubMatrixRange(target,
sourceRowIndex, targetRowIndex, rowCount,
sourceColumnIndex, targetColumnIndex, columnCount);
if (!skipClearing)
{
target.Clear(targetRowIndex, rowCount, targetColumnIndex, columnCount);
@ -468,15 +459,6 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
int sourceColumnIndex, int targetColumnIndex, int columnCount,
bool skipClearing)
{
if (ReferenceEquals(this, target))
{
throw new NotSupportedException();
}
ValidateSubMatrixRange(target,
sourceRowIndex, targetRowIndex, rowCount,
sourceColumnIndex, targetColumnIndex, columnCount);
var rowOffset = targetRowIndex - sourceRowIndex;
var columnOffset = targetColumnIndex - sourceColumnIndex;
@ -542,5 +524,31 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
}
}
}
internal override void CopySubRowToUnchecked(VectorStorage<T> target, int rowIndex,
int sourceColumnIndex, int targetColumnIndex, int columnCount,
bool skipClearing = false)
{
if (!skipClearing)
{
target.Clear(targetColumnIndex, columnCount);
}
// Determine bounds in columnIndices array where this item should be searched (using rowIndex)
var startIndex = RowPointers[rowIndex];
var endIndex = rowIndex < RowPointers.Length - 1 ? RowPointers[rowIndex + 1] : ValueCount;
if (startIndex == endIndex)
{
return;
}
// If there are non-zero elements use base class implementation
for (int i = sourceColumnIndex, j = 0; i < sourceColumnIndex + columnCount; i++, j++)
{
var index = FindItem(rowIndex, i);
target.At(j, index >= 0 ? Values[index] : _zero);
}
}
}
}

Loading…
Cancel
Save