Browse Source

LA: Migrate Matrix SetColumn/Row to storage routines

v2
Christoph Ruegg 14 years ago
parent
commit
12194f2a63
  1. 72
      src/Numerics/LinearAlgebra/Generic/Matrix.cs
  2. 56
      src/Numerics/LinearAlgebra/Storage/DenseColumnMajorMatrixStorage.cs
  3. 6
      src/Numerics/LinearAlgebra/Storage/DiagonalMatrixStorage.cs
  4. 26
      src/Numerics/LinearAlgebra/Storage/MatrixStorage.Validation.cs
  5. 100
      src/Numerics/LinearAlgebra/Storage/MatrixStorage.cs
  6. 4
      src/Numerics/LinearAlgebra/Storage/SparseCompressedRowMatrixStorage.cs

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

@ -385,7 +385,7 @@ namespace MathNet.Numerics.LinearAlgebra.Generic
throw new ArgumentNullException("result"); throw new ArgumentNullException("result");
} }
Storage.CopySubRowTo(result.Storage, index, 0, 0, ColumnCount); Storage.CopyRowTo(result.Storage, index);
} }
/// <summary> /// <summary>
@ -470,7 +470,7 @@ namespace MathNet.Numerics.LinearAlgebra.Generic
throw new ArgumentNullException("result"); throw new ArgumentNullException("result");
} }
Storage.CopySubColumnTo(result.Storage, index, 0, 0, RowCount); Storage.CopyColumnTo(result.Storage, index);
} }
/// <summary> /// <summary>
@ -804,27 +804,14 @@ namespace MathNet.Numerics.LinearAlgebra.Generic
/// equal the number of rows of this <strong>Matrix</strong>.</exception> /// equal the number of rows of this <strong>Matrix</strong>.</exception>
/// <exception cref="ArgumentException">If the size of <paramref name="column"/> does not /// <exception cref="ArgumentException">If the size of <paramref name="column"/> does not
/// equal the number of rows of this <strong>Matrix</strong>.</exception> /// equal the number of rows of this <strong>Matrix</strong>.</exception>
public virtual void SetColumn(int columnIndex, T[] column) public void SetColumn(int columnIndex, T[] column)
{ {
if (columnIndex < 0 || columnIndex >= ColumnCount)
{
throw new ArgumentOutOfRangeException("columnIndex");
}
if (column == null) if (column == null)
{ {
throw new ArgumentNullException("column"); throw new ArgumentNullException("column");
} }
if (column.Length != RowCount) Storage.CopyColumnFrom(new DenseVectorStorage<T>(column.Length, column), columnIndex);
{
throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension, "column");
}
for (var i = 0; i < RowCount; i++)
{
At(i, columnIndex, column[i]);
}
} }
/// <summary> /// <summary>
@ -837,27 +824,14 @@ namespace MathNet.Numerics.LinearAlgebra.Generic
/// or greater than or equal to the number of columns.</exception> /// or greater than or equal to the number of columns.</exception>
/// <exception cref="ArgumentException">If the size of <paramref name="column"/> does not /// <exception cref="ArgumentException">If the size of <paramref name="column"/> does not
/// equal the number of rows of this <strong>Matrix</strong>.</exception> /// equal the number of rows of this <strong>Matrix</strong>.</exception>
public virtual void SetColumn(int columnIndex, Vector<T> column) public void SetColumn(int columnIndex, Vector<T> column)
{ {
if (columnIndex < 0 || columnIndex >= ColumnCount)
{
throw new ArgumentOutOfRangeException("columnIndex");
}
if (column == null) if (column == null)
{ {
throw new ArgumentNullException("column"); throw new ArgumentNullException("column");
} }
if (column.Count != RowCount) Storage.CopyColumnFrom(column.Storage, columnIndex);
{
throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension, "column");
}
for (var i = 0; i < RowCount; i++)
{
At(i, columnIndex, column[i]);
}
} }
/// <summary> /// <summary>
@ -913,27 +887,14 @@ namespace MathNet.Numerics.LinearAlgebra.Generic
/// or greater than or equal to the number of rows.</exception> /// or greater than or equal to the number of rows.</exception>
/// <exception cref="ArgumentException">If the size of <paramref name="row"/> does not /// <exception cref="ArgumentException">If the size of <paramref name="row"/> does not
/// equal the number of columns of this <strong>Matrix</strong>.</exception> /// equal the number of columns of this <strong>Matrix</strong>.</exception>
public virtual void SetRow(int rowIndex, Vector<T> row) public void SetRow(int rowIndex, Vector<T> row)
{ {
if (rowIndex < 0 || rowIndex >= RowCount)
{
throw new ArgumentOutOfRangeException("rowIndex");
}
if (row == null) if (row == null)
{ {
throw new ArgumentNullException("row"); throw new ArgumentNullException("row");
} }
if (row.Count != ColumnCount) Storage.CopyRowFrom(row.Storage, rowIndex);
{
throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension, "row");
}
for (var i = 0; i < ColumnCount; i++)
{
At(rowIndex, i, row[i]);
}
} }
/// <summary> /// <summary>
@ -946,27 +907,14 @@ namespace MathNet.Numerics.LinearAlgebra.Generic
/// or greater than or equal to the number of rows.</exception> /// or greater than or equal to the number of rows.</exception>
/// <exception cref="ArgumentException">If the size of <paramref name="row"/> does not /// <exception cref="ArgumentException">If the size of <paramref name="row"/> does not
/// equal the number of columns of this <strong>Matrix</strong>.</exception> /// equal the number of columns of this <strong>Matrix</strong>.</exception>
public virtual void SetRow(int rowIndex, T[] row) public void SetRow(int rowIndex, T[] row)
{ {
if (rowIndex < 0 || rowIndex >= RowCount)
{
throw new ArgumentOutOfRangeException("rowIndex");
}
if (row == null) if (row == null)
{ {
throw new ArgumentNullException("row"); throw new ArgumentNullException("row");
} }
if (row.Length != ColumnCount) Storage.CopyRowFrom(new DenseVectorStorage<T>(row.Length, row), rowIndex);
{
throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension, "row");
}
for (var i = 0; i < ColumnCount; i++)
{
At(rowIndex, i, row[i]);
}
} }
/// <summary> /// <summary>

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

@ -122,12 +122,17 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
} }
} }
// ROW COPY
internal override void CopySubRowToUnchecked(VectorStorage<T> target, int rowIndex, int sourceColumnIndex, int targetColumnIndex, int columnCount, bool skipClearing = false) internal override void CopySubRowToUnchecked(VectorStorage<T> target, int rowIndex, int sourceColumnIndex, int targetColumnIndex, int columnCount, bool skipClearing = false)
{ {
var denseTarget = target as DenseVectorStorage<T>; var targetDense = target as DenseVectorStorage<T>;
if (denseTarget != null) if (targetDense != null)
{ {
CopySubRowToUnchecked(denseTarget, rowIndex, sourceColumnIndex, targetColumnIndex, columnCount); for (int j = 0; j<columnCount; j++)
{
targetDense.Data[j + targetColumnIndex] = Data[(j + sourceColumnIndex) * RowCount + rowIndex];
}
return; return;
} }
@ -139,20 +144,34 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
} }
} }
void CopySubRowToUnchecked(DenseVectorStorage<T> target, int rowIndex, int sourceColumnIndex, int targetColumnIndex, int columnCount, bool skipClearing = false) internal override void CopySubRowFromUnchecked(VectorStorage<T> source, int rowIndex, int sourceColumnIndex, int targetColumnIndex, int columnCount, bool skipClearing = false)
{ {
for (int j = 0; j<columnCount; j++) 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++)
{ {
target.Data[j + targetColumnIndex] = Data[(j + sourceColumnIndex) * RowCount + rowIndex]; 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) internal override void CopySubColumnToUnchecked(VectorStorage<T> target, int columnIndex, int sourceRowIndex, int targetRowIndex, int rowCount, bool skipClearing = false)
{ {
var denseTarget = target as DenseVectorStorage<T>; var targetDense = target as DenseVectorStorage<T>;
if (denseTarget != null) if (targetDense != null)
{ {
CopySubColumnToUnchecked(denseTarget, columnIndex, sourceRowIndex, targetRowIndex, rowCount); Array.Copy(Data, columnIndex*RowCount + sourceRowIndex, targetDense.Data, targetRowIndex, rowCount);
return; return;
} }
@ -165,11 +184,26 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
} }
} }
void CopySubColumnToUnchecked(DenseVectorStorage<T> target, int columnIndex, int sourceRowIndex, int targetRowIndex, int rowCount, bool skipClearing = false) internal override void CopySubColumnFromUnchecked(VectorStorage<T> source, int columnIndex, int sourceRowIndex, int targetRowIndex, int rowCount, bool skipClearing = false)
{ {
Array.Copy(Data, columnIndex*RowCount + sourceRowIndex, target.Data, targetRowIndex, rowCount); 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() public override T[] ToRowMajorArray()
{ {
var ret = new T[Data.Length]; var ret = new T[Data.Length];

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

@ -356,6 +356,8 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
// else: all zero, nop // else: all zero, nop
} }
// ROW COPY
internal override void CopySubRowToUnchecked(VectorStorage<T> target, int rowIndex, internal override void CopySubRowToUnchecked(VectorStorage<T> target, int rowIndex,
int sourceColumnIndex, int targetColumnIndex, int columnCount, int sourceColumnIndex, int targetColumnIndex, int columnCount,
bool skipClearing = false) bool skipClearing = false)
@ -371,6 +373,8 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
} }
} }
// COLUMN COPY
internal override void CopySubColumnToUnchecked(VectorStorage<T> target, int columnIndex, internal override void CopySubColumnToUnchecked(VectorStorage<T> target, int columnIndex,
int sourceRowIndex, int targetRowIndex, int rowCount, int sourceRowIndex, int targetRowIndex, int rowCount,
bool skipClearing = false) bool skipClearing = false)
@ -386,6 +390,8 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
} }
} }
// EXTRACT
public override T[] ToRowMajorArray() public override T[] ToRowMajorArray()
{ {
var ret = new T[RowCount * ColumnCount]; var ret = new T[RowCount * ColumnCount];

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

@ -84,6 +84,32 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
} }
} }
void ValidateRowRange(VectorStorage<T> target, int rowIndex)
{
if (rowIndex >= RowCount || rowIndex < 0)
{
throw new ArgumentOutOfRangeException("rowIndex");
}
if (ColumnCount != target.Length)
{
throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension, "target");
}
}
void ValidateColumnRange(VectorStorage<T> target, int columnIndex)
{
if (columnIndex >= ColumnCount || columnIndex < 0)
{
throw new ArgumentOutOfRangeException("columnIndex");
}
if (RowCount != target.Length)
{
throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension, "target");
}
}
void ValidateSubRowRange(VectorStorage<T> target, int rowIndex, void ValidateSubRowRange(VectorStorage<T> target, int rowIndex,
int sourceColumnIndex, int targetColumnIndex, int columnCount) int sourceColumnIndex, int targetColumnIndex, int columnCount)
{ {

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

@ -195,6 +195,8 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
return hash; return hash;
} }
// MATRIX COPY
public void CopyTo(MatrixStorage<T> target, bool skipClearing = false) public void CopyTo(MatrixStorage<T> target, bool skipClearing = false)
{ {
if (target == null) if (target == null)
@ -264,6 +266,19 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
} }
} }
// ROW COPY
public void CopyRowTo(VectorStorage<T> target, int rowIndex, bool skipClearing = false)
{
if (target == null)
{
throw new ArgumentNullException("target");
}
ValidateRowRange(target, rowIndex);
CopySubRowToUnchecked(target, rowIndex, 0, 0, ColumnCount, skipClearing);
}
public void CopySubRowTo(VectorStorage<T> target, int rowIndex, public void CopySubRowTo(VectorStorage<T> target, int rowIndex,
int sourceColumnIndex, int targetColumnIndex, int columnCount, int sourceColumnIndex, int targetColumnIndex, int columnCount,
bool skipClearing = false) bool skipClearing = false)
@ -274,7 +289,6 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
} }
ValidateSubRowRange(target, rowIndex, sourceColumnIndex, targetColumnIndex, columnCount); ValidateSubRowRange(target, rowIndex, sourceColumnIndex, targetColumnIndex, columnCount);
CopySubRowToUnchecked(target, rowIndex, sourceColumnIndex, targetColumnIndex, columnCount, skipClearing); CopySubRowToUnchecked(target, rowIndex, sourceColumnIndex, targetColumnIndex, columnCount, skipClearing);
} }
@ -288,6 +302,53 @@ 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)
{
if (target == null)
{
throw new ArgumentNullException("target");
}
ValidateColumnRange(target, columnIndex);
CopySubColumnToUnchecked(target, columnIndex, 0, 0, RowCount, skipClearing);
}
public void CopySubColumnTo(VectorStorage<T> target, int columnIndex, public void CopySubColumnTo(VectorStorage<T> target, int columnIndex,
int sourceRowIndex, int targetRowIndex, int rowCount, int sourceRowIndex, int targetRowIndex, int rowCount,
bool skipClearing = false) bool skipClearing = false)
@ -298,7 +359,6 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
} }
ValidateSubColumnRange(target, columnIndex, sourceRowIndex, targetRowIndex, rowCount); ValidateSubColumnRange(target, columnIndex, sourceRowIndex, targetRowIndex, rowCount);
CopySubColumnToUnchecked(target, columnIndex, sourceRowIndex, targetRowIndex, rowCount, skipClearing); CopySubColumnToUnchecked(target, columnIndex, sourceRowIndex, targetRowIndex, rowCount, skipClearing);
} }
@ -312,6 +372,42 @@ 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() public virtual T[] ToRowMajorArray()
{ {
var ret = new T[RowCount * ColumnCount]; var ret = new T[RowCount * ColumnCount];

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

@ -525,6 +525,8 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
} }
} }
// ROW COPY
internal override void CopySubRowToUnchecked(VectorStorage<T> target, int rowIndex, internal override void CopySubRowToUnchecked(VectorStorage<T> target, int rowIndex,
int sourceColumnIndex, int targetColumnIndex, int columnCount, int sourceColumnIndex, int targetColumnIndex, int columnCount,
bool skipClearing = false) bool skipClearing = false)
@ -551,6 +553,8 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
} }
} }
// EXTRACT
public override T[] ToRowMajorArray() public override T[] ToRowMajorArray()
{ {
var ret = new T[RowCount * ColumnCount]; var ret = new T[RowCount * ColumnCount];

Loading…
Cancel
Save