Browse Source

LA: Storage always provide CopyTo, never CopyFrom

v2
Christoph Ruegg 14 years ago
parent
commit
2654f4b481
  1. 24
      src/Numerics/LinearAlgebra/Generic/Matrix.cs
  2. 4
      src/Numerics/LinearAlgebra/Generic/Vector.cs
  3. 38
      src/Numerics/LinearAlgebra/Storage/DenseColumnMajorMatrixStorage.cs
  4. 95
      src/Numerics/LinearAlgebra/Storage/DenseVectorStorage.cs
  5. 68
      src/Numerics/LinearAlgebra/Storage/MatrixStorage.cs
  6. 4
      src/Numerics/LinearAlgebra/Storage/SparseVectorStorage.cs
  7. 106
      src/Numerics/LinearAlgebra/Storage/VectorStorage.Validation.cs
  8. 107
      src/Numerics/LinearAlgebra/Storage/VectorStorage.cs

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

@ -798,45 +798,45 @@ namespace MathNet.Numerics.LinearAlgebra.Generic
}
/// <summary>
/// Copies the values of the given array to the specified column.
/// Copies the values of the given Vector to the specified column.
/// </summary>
/// <param name="columnIndex">The column to copy the values to.</param>
/// <param name="column">The array to copy the values from.</param>
/// <param name="column">The vector to copy the values from.</param>
/// <exception cref="ArgumentNullException">If <paramref name="column"/> is <see langword="null" />.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="columnIndex"/> is less than zero,
/// or greater than or equal to the number of columns.</exception>
/// <exception cref="ArgumentException">If the size of <paramref name="column"/> does not
/// equal the number of rows of this <strong>Matrix</strong>.</exception>
/// <exception cref="ArgumentException">If the size of <paramref name="column"/> does not
/// equal the number of rows of this <strong>Matrix</strong>.</exception>
public void SetColumn(int columnIndex, T[] column)
public void SetColumn(int columnIndex, Vector<T> column)
{
if (column == null)
{
throw new ArgumentNullException("column");
}
Storage.CopyColumnFrom(new DenseVectorStorage<T>(column.Length, column), columnIndex);
column.Storage.CopyToColumn(Storage, columnIndex);
}
/// <summary>
/// Copies the values of the given Vector to the specified column.
/// Copies the values of the given array to the specified column.
/// </summary>
/// <param name="columnIndex">The column to copy the values to.</param>
/// <param name="column">The vector to copy the values from.</param>
/// <param name="column">The array to copy the values from.</param>
/// <exception cref="ArgumentNullException">If <paramref name="column"/> is <see langword="null" />.</exception>
/// <exception cref="ArgumentOutOfRangeException">If <paramref name="columnIndex"/> is less than zero,
/// or greater than or equal to the number of columns.</exception>
/// <exception cref="ArgumentException">If the size of <paramref name="column"/> does not
/// equal the number of rows of this <strong>Matrix</strong>.</exception>
public void SetColumn(int columnIndex, Vector<T> column)
/// <exception cref="ArgumentException">If the size of <paramref name="column"/> does not
/// equal the number of rows of this <strong>Matrix</strong>.</exception>
public void SetColumn(int columnIndex, T[] column)
{
if (column == null)
{
throw new ArgumentNullException("column");
}
Storage.CopyColumnFrom(column.Storage, columnIndex);
new DenseVectorStorage<T>(column.Length, column).CopyToColumn(Storage, columnIndex);
}
/// <summary>
@ -899,7 +899,7 @@ namespace MathNet.Numerics.LinearAlgebra.Generic
throw new ArgumentNullException("row");
}
Storage.CopyRowFrom(row.Storage, rowIndex);
row.Storage.CopyToRow(Storage, rowIndex);
}
/// <summary>
@ -919,7 +919,7 @@ namespace MathNet.Numerics.LinearAlgebra.Generic
throw new ArgumentNullException("row");
}
Storage.CopyRowFrom(new DenseVectorStorage<T>(row.Length, row), rowIndex);
new DenseVectorStorage<T>(row.Length, row).CopyToRow(Storage, rowIndex);
}
/// <summary>

4
src/Numerics/LinearAlgebra/Generic/Vector.cs

@ -1176,7 +1176,7 @@ namespace MathNet.Numerics.LinearAlgebra.Generic
public virtual Matrix<T> ToColumnMatrix()
{
var result = CreateMatrix(Count, 1);
result.Storage.CopyColumnFrom(Storage, 0, skipClearing: true);
Storage.CopyToColumnUnchecked(result.Storage, 0, skipClearing: true);
return result;
}
@ -1189,7 +1189,7 @@ namespace MathNet.Numerics.LinearAlgebra.Generic
public virtual Matrix<T> ToRowMatrix()
{
var result = CreateMatrix(1, Count);
result.Storage.CopyRowFrom(Storage, 0, skipClearing: true);
Storage.CopyToRowUnchecked(result.Storage, 0, skipClearing: true);
return result;
}

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

@ -174,26 +174,6 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
}
}
internal override void CopySubRowFromUnchecked(VectorStorage<T> source, int rowIndex, int sourceColumnIndex, int targetColumnIndex, int columnCount, bool skipClearing = false)
{
var sourceDense = source as DenseVectorStorage<T>;
if (sourceDense != null)
{
for (int j = 0; j < columnCount; j++)
{
Data[(j + targetColumnIndex) * RowCount + rowIndex] = sourceDense.Data[j + sourceColumnIndex];
}
return;
}
// FALL BACK
for (int j = sourceColumnIndex, jj = targetColumnIndex; j < sourceColumnIndex + columnCount; j++, jj++)
{
Data[(jj * RowCount) + rowIndex] = source.At(j);
}
}
// COLUMN COPY
internal override void CopySubColumnToUnchecked(VectorStorage<T> target, int columnIndex, int sourceRowIndex, int targetRowIndex, int rowCount, bool skipClearing = false)
@ -214,24 +194,6 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
}
}
internal override void CopySubColumnFromUnchecked(VectorStorage<T> source, int columnIndex, int sourceRowIndex, int targetRowIndex, int rowCount, bool skipClearing = false)
{
var sourceDense = source as DenseVectorStorage<T>;
if (sourceDense != null)
{
Array.Copy(sourceDense.Data, sourceRowIndex, Data, columnIndex * RowCount + targetRowIndex, rowCount);
return;
}
// FALL BACK
var offset = columnIndex * RowCount;
for (int i = sourceRowIndex, ii = targetRowIndex; i < sourceRowIndex + rowCount; i++, ii++)
{
Data[offset + ii] = source.At(i);
}
}
// EXTRACT
public override T[] ToRowMajorArray()

95
src/Numerics/LinearAlgebra/Storage/DenseVectorStorage.cs

@ -89,33 +89,71 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
Array.Clear(Data, index, count);
}
// VECTOR COPY
internal override void CopyToUnchecked(VectorStorage<T> target, bool skipClearing = false)
{
var denseTarget = target as DenseVectorStorage<T>;
if (denseTarget != null)
{
CopyToUnchecked(denseTarget);
if (!ReferenceEquals(this, denseTarget))
{
Array.Copy(Data, 0, denseTarget.Data, 0, Data.Length);
}
return;
}
// FALL BACK
for (int i = 0; i < Length; i++)
for (int i = 0; i < Data.Length; i++)
{
target.At(i, Data[i]);
}
}
void CopyToUnchecked(DenseVectorStorage<T> target)
// ROW COPY
internal override void CopyToRowUnchecked(MatrixStorage<T> target, int rowIndex, bool skipClearing = false)
{
var denseTarget = target as DenseColumnMajorMatrixStorage<T>;
if (denseTarget != null)
{
for (int j = 0; j < Data.Length; j++)
{
denseTarget.Data[j*target.RowCount + rowIndex] = Data[j];
}
return;
}
// FALL BACK
for (int j = 0; j < Length; j++)
{
target.At(rowIndex, j, Data[j]);
}
}
// COLUMN COPY
internal override void CopyToColumnUnchecked(MatrixStorage<T> target, int columnIndex, bool skipClearing = false)
{
if (ReferenceEquals(this, target))
var denseTarget = target as DenseColumnMajorMatrixStorage<T>;
if (denseTarget != null)
{
Array.Copy(Data, 0, denseTarget.Data, columnIndex * denseTarget.RowCount, Data.Length);
return;
}
Array.Copy(Data, 0, target.Data, 0, Data.Length);
// FALL BACK
for (int i = 0; i < Length; i++)
{
target.At(i, columnIndex, Data[i]);
}
}
// SUB-VECTOR COPY
internal override void CopySubVectorToUnchecked(VectorStorage<T> target,
int sourceIndex, int targetIndex, int count,
bool skipClearing = false)
@ -123,7 +161,7 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
var denseTarget = target as DenseVectorStorage<T>;
if (denseTarget != null)
{
CopySubVectorToUnchecked(denseTarget, sourceIndex, targetIndex, count);
Array.Copy(Data, sourceIndex, denseTarget.Data, targetIndex, count);
return;
}
@ -132,10 +170,49 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
base.CopySubVectorToUnchecked(target, sourceIndex, targetIndex, count, skipClearing);
}
void CopySubVectorToUnchecked(DenseVectorStorage<T> target,
int sourceIndex, int targetIndex, int count)
// SUB-ROW COPY
internal override void CopyToSubRowUnchecked(MatrixStorage<T> target, int rowIndex,
int sourceColumnIndex, int targetColumnIndex, int columnCount,
bool skipClearing = false)
{
var denseTarget = target as DenseColumnMajorMatrixStorage<T>;
if (denseTarget != null)
{
for (int j = 0; j < Data.Length; j++)
{
denseTarget.Data[(j + targetColumnIndex) * target.RowCount + rowIndex] = Data[j + sourceColumnIndex];
}
return;
}
// FALL BACK
for (int j = sourceColumnIndex, jj = targetColumnIndex; j < sourceColumnIndex + columnCount; j++, jj++)
{
target.At(rowIndex, jj, Data[j]);
}
}
// SUB-COLUMN COPY
internal override void CopyToSubColumnUnchecked(MatrixStorage<T> target, int columnIndex,
int sourceRowIndex, int targetRowIndex, int rowCount,
bool skipClearing = false)
{
Array.Copy(Data, sourceIndex, target.Data, targetIndex, count);
var denseTarget = target as DenseColumnMajorMatrixStorage<T>;
if (denseTarget != null)
{
Array.Copy(Data, sourceRowIndex, denseTarget.Data, columnIndex*denseTarget.RowCount + targetRowIndex, rowCount);
return;
}
// FALL BACK
for (int i = sourceRowIndex, ii = targetRowIndex; i < sourceRowIndex + rowCount; i++, ii++)
{
target.At(ii, columnIndex, Data[i]);
}
}
}
}

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

@ -332,40 +332,6 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
}
}
public void CopyRowFrom(VectorStorage<T> source, int rowIndex, bool skipClearing = false)
{
if (source == null)
{
throw new ArgumentNullException("source");
}
ValidateRowRange(source, rowIndex);
CopySubRowFromUnchecked(source, rowIndex, 0, 0, ColumnCount, skipClearing);
}
public void CopySubRowFrom(VectorStorage<T> source, int rowIndex,
int sourceColumnIndex, int targetColumnIndex, int columnCount,
bool skipClearing = false)
{
if (source == null)
{
throw new ArgumentNullException("source");
}
ValidateSubRowRange(source, rowIndex, targetColumnIndex, sourceColumnIndex, columnCount);
CopySubRowFromUnchecked(source, rowIndex, sourceColumnIndex, targetColumnIndex, columnCount, skipClearing);
}
internal virtual void CopySubRowFromUnchecked(VectorStorage<T> source, int rowIndex,
int sourceColumnIndex, int targetColumnIndex, int columnCount,
bool skipClearing = false)
{
for (int j = sourceColumnIndex, jj = targetColumnIndex; j < sourceColumnIndex + columnCount; j++, jj++)
{
At(rowIndex, jj, source.At(j));
}
}
// COLUMN COPY
public void CopyColumnTo(VectorStorage<T> target, int columnIndex, bool skipClearing = false)
@ -402,40 +368,6 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
}
}
public void CopyColumnFrom(VectorStorage<T> source, int columnIndex, bool skipClearing = false)
{
if (source == null)
{
throw new ArgumentNullException("source");
}
ValidateColumnRange(source, columnIndex);
CopySubColumnFromUnchecked(source, columnIndex, 0, 0, RowCount, skipClearing);
}
public void CopySubColumnFrom(VectorStorage<T> source, int columnIndex,
int sourceRowIndex, int targetRowIndex, int rowCount,
bool skipClearing = false)
{
if (source == null)
{
throw new ArgumentNullException("source");
}
ValidateSubColumnRange(source, columnIndex, targetRowIndex, sourceRowIndex, rowCount);
CopySubColumnFromUnchecked(source, columnIndex, sourceRowIndex, targetRowIndex, rowCount, skipClearing);
}
internal virtual void CopySubColumnFromUnchecked(VectorStorage<T> source, int columnIndex,
int sourceRowIndex, int targetRowIndex, int rowCount,
bool skipClearing = false)
{
for (int i = sourceRowIndex, ii = targetRowIndex; i < sourceRowIndex + rowCount; i++, ii++)
{
At(ii, columnIndex, source.At(i));
}
}
// EXTRACT
public virtual T[] ToRowMajorArray()

4
src/Numerics/LinearAlgebra/Storage/SparseVectorStorage.cs

@ -284,6 +284,8 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
return hash;
}
// VECTOR COPY
internal override void CopyToUnchecked(VectorStorage<T> target, bool skipClearing = false)
{
var sparseTarget = target as SparseVectorStorage<T>;
@ -333,6 +335,8 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
}
}
// SUB-VECTOR COPY
internal override void CopySubVectorToUnchecked(VectorStorage<T> target,
int sourceIndex, int targetIndex, int count,
bool skipClearing = false)

106
src/Numerics/LinearAlgebra/Storage/VectorStorage.Validation.cs

@ -36,7 +36,7 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
// ReSharper disable UnusedParameter.Global
public partial class VectorStorage<T>
{
protected void ValidateRange(int index)
void ValidateRange(int index)
{
if (index < 0 || index >= Length)
{
@ -44,7 +44,7 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
}
}
protected void ValidateSubVectorRange(VectorStorage<T> target,
void ValidateSubVectorRange(VectorStorage<T> target,
int sourceIndex, int targetIndex, int count)
{
if (count < 1)
@ -80,6 +80,108 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
throw new ArgumentOutOfRangeException("count");
}
}
void ValidateRowRange(MatrixStorage<T> target, int rowIndex)
{
if (rowIndex >= target.RowCount || rowIndex < 0)
{
throw new ArgumentOutOfRangeException("rowIndex");
}
if (target.ColumnCount != Length)
{
throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension, "target");
}
}
void ValidateColumnRange(MatrixStorage<T> target, int columnIndex)
{
if (columnIndex >= target.ColumnCount || columnIndex < 0)
{
throw new ArgumentOutOfRangeException("columnIndex");
}
if (target.RowCount != Length)
{
throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension, "target");
}
}
void ValidateSubRowRange(MatrixStorage<T> target, int rowIndex,
int sourceColumnIndex, int targetColumnIndex, int columnCount)
{
if (columnCount < 1)
{
throw new ArgumentOutOfRangeException("columnCount", Resources.ArgumentMustBePositive);
}
// Verify Source
if (sourceColumnIndex >= Length || sourceColumnIndex < 0)
{
throw new ArgumentOutOfRangeException("sourceColumnIndex");
}
if (sourceColumnIndex + columnCount > Length)
{
throw new ArgumentOutOfRangeException("columnCount");
}
// Verify Target
if (rowIndex >= target.RowCount || rowIndex < 0)
{
throw new ArgumentOutOfRangeException("rowIndex");
}
if (targetColumnIndex >= target.ColumnCount || targetColumnIndex < 0)
{
throw new ArgumentOutOfRangeException("targetColumnIndex");
}
if (targetColumnIndex + columnCount > target.ColumnCount)
{
throw new ArgumentOutOfRangeException("columnCount");
}
}
void ValidateSubColumnRange(MatrixStorage<T> target, int columnIndex,
int sourceRowIndex, int targetRowIndex, int rowCount)
{
if (rowCount < 1)
{
throw new ArgumentOutOfRangeException("rowCount", Resources.ArgumentMustBePositive);
}
// Verify Source
if (sourceRowIndex >= Length || sourceRowIndex < 0)
{
throw new ArgumentOutOfRangeException("sourceRowIndex");
}
if (sourceRowIndex + rowCount > Length)
{
throw new ArgumentOutOfRangeException("rowCount");
}
// Verify Target
if (columnIndex >= target.ColumnCount || columnIndex < 0)
{
throw new ArgumentOutOfRangeException("columnIndex");
}
if (targetRowIndex >= target.RowCount || targetRowIndex < 0)
{
throw new ArgumentOutOfRangeException("targetRowIndex");
}
if (targetRowIndex + rowCount > target.RowCount)
{
throw new ArgumentOutOfRangeException("rowCount");
}
}
}
// ReSharper restore UnusedParameter.Global
}

107
src/Numerics/LinearAlgebra/Storage/VectorStorage.cs

@ -196,6 +196,8 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
return hash;
}
// VECTOR COPY
public void CopyTo(VectorStorage<T> target, bool skipClearing = false)
{
if (target == null)
@ -224,6 +226,60 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
}
}
// ROW COPY
public void CopyToRow(MatrixStorage<T> target, int rowIndex, bool skipClearing = false)
{
if (target == null)
{
throw new ArgumentNullException("target");
}
if (Length != target.ColumnCount)
{
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "target");
}
ValidateRowRange(target, rowIndex);
CopyToRowUnchecked(target, rowIndex, skipClearing);
}
internal virtual void CopyToRowUnchecked(MatrixStorage<T> target, int rowIndex, bool skipClearing = false)
{
for (int j = 0; j < Length; j++)
{
target.At(rowIndex, j, At(j));
}
}
// COLUMN COPY
public void CopyToColumn(MatrixStorage<T> target, int columnIndex, bool skipClearing = false)
{
if (target == null)
{
throw new ArgumentNullException("target");
}
if (Length != target.RowCount)
{
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "target");
}
ValidateColumnRange(target, columnIndex);
CopyToColumnUnchecked(target, columnIndex, skipClearing);
}
internal virtual void CopyToColumnUnchecked(MatrixStorage<T> target, int columnIndex, bool skipClearing = false)
{
for (int i = 0; i < Length; i++)
{
target.At(i, columnIndex, At(i));
}
}
// SUB-VECTOR COPY
public void CopySubVectorTo(VectorStorage<T> target,
int sourceIndex, int targetIndex, int count,
bool skipClearing = false)
@ -234,7 +290,6 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
}
ValidateSubVectorRange(target, sourceIndex, targetIndex, count);
CopySubVectorToUnchecked(target, sourceIndex, targetIndex, count, skipClearing);
}
@ -262,5 +317,55 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
target.At(ii, At(i));
}
}
// SUB-ROW COPY
public void CopyToSubRow(MatrixStorage<T> target, int rowIndex,
int sourceColumnIndex, int targetColumnIndex, int columnCount,
bool skipClearing = false)
{
if (target == null)
{
throw new ArgumentNullException("target");
}
ValidateSubRowRange(target, rowIndex, targetColumnIndex, sourceColumnIndex, columnCount);
CopyToSubRowUnchecked(target, rowIndex, sourceColumnIndex, targetColumnIndex, columnCount, skipClearing);
}
internal virtual void CopyToSubRowUnchecked(MatrixStorage<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(rowIndex, jj, At(j));
}
}
// SUB-COLUMN COPY
public void CopyToSubColumn(MatrixStorage<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);
CopyToSubColumnUnchecked(target, columnIndex, sourceRowIndex, targetRowIndex, rowCount, skipClearing);
}
internal virtual void CopyToSubColumnUnchecked(MatrixStorage<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, columnIndex, At(i));
}
}
}
}

Loading…
Cancel
Save