From 34d0d4d4f8531a35d6d6af661b25512684292bbe Mon Sep 17 00:00:00 2001 From: Christoph Ruegg Date: Sun, 15 Jul 2012 22:26:14 +0200 Subject: [PATCH] LA Storage: CopyTo --- .../LinearAlgebra/Complex/DiagonalMatrix.cs | 7 ++ .../LinearAlgebra/Complex/SparseMatrix.cs | 27 ++------ .../LinearAlgebra/Complex32/DiagonalMatrix.cs | 7 ++ .../LinearAlgebra/Complex32/SparseMatrix.cs | 28 ++------ .../LinearAlgebra/Double/DiagonalMatrix.cs | 7 ++ .../LinearAlgebra/Double/SparseMatrix.cs | 27 ++------ .../LinearAlgebra/Single/DiagonalMatrix.cs | 7 ++ .../LinearAlgebra/Single/SparseMatrix.cs | 27 ++------ .../SparseCompressedRowMatrixStorage.cs | 66 ++++++++++++++++++- .../Storage/SparseDiagonalMatrixStorage.cs | 28 +++++++- 10 files changed, 142 insertions(+), 89 deletions(-) diff --git a/src/Numerics/LinearAlgebra/Complex/DiagonalMatrix.cs b/src/Numerics/LinearAlgebra/Complex/DiagonalMatrix.cs index 3ebafe3b..75abe302 100644 --- a/src/Numerics/LinearAlgebra/Complex/DiagonalMatrix.cs +++ b/src/Numerics/LinearAlgebra/Complex/DiagonalMatrix.cs @@ -823,6 +823,13 @@ namespace MathNet.Numerics.LinearAlgebra.Complex return; } + var sparseTarget = target as SparseMatrix; + if (sparseTarget != null) + { + _storage.CopyTo(sparseTarget.Storage); + return; + } + base.CopyTo(target); } diff --git a/src/Numerics/LinearAlgebra/Complex/SparseMatrix.cs b/src/Numerics/LinearAlgebra/Complex/SparseMatrix.cs index 5c263e59..415891c5 100644 --- a/src/Numerics/LinearAlgebra/Complex/SparseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Complex/SparseMatrix.cs @@ -692,35 +692,20 @@ namespace MathNet.Numerics.LinearAlgebra.Complex public override void CopyTo(Matrix target) { var sparseTarget = target as SparseMatrix; - if (sparseTarget == null) + if (sparseTarget != null) { - base.CopyTo(target); + _storage.CopyTo(sparseTarget.Storage); return; } - if (ReferenceEquals(this, target)) + var denseTarget = target as DenseMatrix; + if (denseTarget != null) { + _storage.CopyTo(denseTarget.Storage); return; } - if (RowCount != target.RowCount || ColumnCount != target.ColumnCount) - { - throw DimensionsDontMatch(this, target, "target"); - } - - var targetStorage = sparseTarget.Storage; - - // Lets copy only needed data. Portion of needed data is determined by NonZerosCount value - targetStorage.ValueCount = _storage.ValueCount; - targetStorage.Values = new Complex[_storage.ValueCount]; - targetStorage.ColumnIndices = new int[_storage.ValueCount]; - - if (_storage.ValueCount != 0) - { - Array.Copy(_storage.Values, targetStorage.Values, _storage.ValueCount); - Buffer.BlockCopy(_storage.ColumnIndices, 0, targetStorage.ColumnIndices, 0, _storage.ValueCount * Constants.SizeOfInt); - Buffer.BlockCopy(_storage.RowPointers, 0, targetStorage.RowPointers, 0, RowCount * Constants.SizeOfInt); - } + base.CopyTo(target); } /// diff --git a/src/Numerics/LinearAlgebra/Complex32/DiagonalMatrix.cs b/src/Numerics/LinearAlgebra/Complex32/DiagonalMatrix.cs index c50f2dae..ca5408cc 100644 --- a/src/Numerics/LinearAlgebra/Complex32/DiagonalMatrix.cs +++ b/src/Numerics/LinearAlgebra/Complex32/DiagonalMatrix.cs @@ -828,6 +828,13 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 return; } + var sparseTarget = target as SparseMatrix; + if (sparseTarget != null) + { + _storage.CopyTo(sparseTarget.Storage); + return; + } + base.CopyTo(target); } diff --git a/src/Numerics/LinearAlgebra/Complex32/SparseMatrix.cs b/src/Numerics/LinearAlgebra/Complex32/SparseMatrix.cs index 27c047af..06d5ab8f 100644 --- a/src/Numerics/LinearAlgebra/Complex32/SparseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Complex32/SparseMatrix.cs @@ -692,36 +692,20 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 public override void CopyTo(Matrix target) { var sparseTarget = target as SparseMatrix; - if (sparseTarget == null) + if (sparseTarget != null) { - base.CopyTo(target); + _storage.CopyTo(sparseTarget.Storage); return; } - if (ReferenceEquals(this, target)) + var denseTarget = target as DenseMatrix; + if (denseTarget != null) { + _storage.CopyTo(denseTarget.Storage); return; } - if (RowCount != target.RowCount || ColumnCount != target.ColumnCount) - { - throw DimensionsDontMatch(this, target, "target"); - } - - - var targetStorage = sparseTarget.Storage; - - // Lets copy only needed data. Portion of needed data is determined by NonZerosCount value - targetStorage.ValueCount = _storage.ValueCount; - targetStorage.Values = new Complex32[_storage.ValueCount]; - targetStorage.ColumnIndices = new int[_storage.ValueCount]; - - if (_storage.ValueCount != 0) - { - Array.Copy(_storage.Values, targetStorage.Values, _storage.ValueCount); - Buffer.BlockCopy(_storage.ColumnIndices, 0, targetStorage.ColumnIndices, 0, _storage.ValueCount * Constants.SizeOfInt); - Buffer.BlockCopy(_storage.RowPointers, 0, targetStorage.RowPointers, 0, RowCount * Constants.SizeOfInt); - } + base.CopyTo(target); } /// diff --git a/src/Numerics/LinearAlgebra/Double/DiagonalMatrix.cs b/src/Numerics/LinearAlgebra/Double/DiagonalMatrix.cs index be2f1357..7fa78a1d 100644 --- a/src/Numerics/LinearAlgebra/Double/DiagonalMatrix.cs +++ b/src/Numerics/LinearAlgebra/Double/DiagonalMatrix.cs @@ -817,6 +817,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double return; } + var sparseTarget = target as SparseMatrix; + if (sparseTarget != null) + { + _storage.CopyTo(sparseTarget.Storage); + return; + } + base.CopyTo(target); } diff --git a/src/Numerics/LinearAlgebra/Double/SparseMatrix.cs b/src/Numerics/LinearAlgebra/Double/SparseMatrix.cs index 406eede6..1cffbb80 100644 --- a/src/Numerics/LinearAlgebra/Double/SparseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Double/SparseMatrix.cs @@ -691,35 +691,20 @@ namespace MathNet.Numerics.LinearAlgebra.Double public override void CopyTo(Matrix target) { var sparseTarget = target as SparseMatrix; - if (sparseTarget == null) + if (sparseTarget != null) { - base.CopyTo(target); + _storage.CopyTo(sparseTarget.Storage); return; } - if (ReferenceEquals(this, target)) + var denseTarget = target as DenseMatrix; + if (denseTarget != null) { + _storage.CopyTo(denseTarget.Storage); return; } - if (RowCount != target.RowCount || ColumnCount != target.ColumnCount) - { - throw DimensionsDontMatch(this, target, "target"); - } - - var targetStorage = sparseTarget.Storage; - - // Lets copy only needed data. Portion of needed data is determined by NonZerosCount value - targetStorage.ValueCount = _storage.ValueCount; - targetStorage.Values = new double[_storage.ValueCount]; - targetStorage.ColumnIndices = new int[_storage.ValueCount]; - - if (_storage.ValueCount != 0) - { - Buffer.BlockCopy(_storage.Values, 0, targetStorage.Values, 0, _storage.ValueCount * Constants.SizeOfDouble); - Buffer.BlockCopy(_storage.ColumnIndices, 0, targetStorage.ColumnIndices, 0, _storage.ValueCount * Constants.SizeOfInt); - Buffer.BlockCopy(_storage.RowPointers, 0, targetStorage.RowPointers, 0, RowCount * Constants.SizeOfInt); - } + base.CopyTo(target); } /// diff --git a/src/Numerics/LinearAlgebra/Single/DiagonalMatrix.cs b/src/Numerics/LinearAlgebra/Single/DiagonalMatrix.cs index 94a48a8a..c1cbd102 100644 --- a/src/Numerics/LinearAlgebra/Single/DiagonalMatrix.cs +++ b/src/Numerics/LinearAlgebra/Single/DiagonalMatrix.cs @@ -821,6 +821,13 @@ namespace MathNet.Numerics.LinearAlgebra.Single _storage.CopyTo(denseTarget.Storage); return; } + + var sparseTarget = target as SparseMatrix; + if (sparseTarget != null) + { + _storage.CopyTo(sparseTarget.Storage); + return; + } base.CopyTo(target); } diff --git a/src/Numerics/LinearAlgebra/Single/SparseMatrix.cs b/src/Numerics/LinearAlgebra/Single/SparseMatrix.cs index f251b6f6..99668cd7 100644 --- a/src/Numerics/LinearAlgebra/Single/SparseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Single/SparseMatrix.cs @@ -691,35 +691,20 @@ namespace MathNet.Numerics.LinearAlgebra.Single public override void CopyTo(Matrix target) { var sparseTarget = target as SparseMatrix; - if (sparseTarget == null) + if (sparseTarget != null) { - base.CopyTo(target); + _storage.CopyTo(sparseTarget.Storage); return; } - if (ReferenceEquals(this, target)) + var denseTarget = target as DenseMatrix; + if (denseTarget != null) { + _storage.CopyTo(denseTarget.Storage); return; } - if (RowCount != target.RowCount || ColumnCount != target.ColumnCount) - { - throw DimensionsDontMatch(this, target, "target"); - } - - var targetStorage = sparseTarget.Storage; - - // Lets copy only needed data. Portion of needed data is determined by NonZerosCount value - targetStorage.ValueCount = _storage.ValueCount; - targetStorage.Values = new float[_storage.ValueCount]; - targetStorage.ColumnIndices = new int[_storage.ValueCount]; - - if (_storage.ValueCount != 0) - { - Buffer.BlockCopy(_storage.Values, 0, targetStorage.Values, 0, _storage.ValueCount * Constants.SizeOfFloat); - Buffer.BlockCopy(_storage.ColumnIndices, 0, targetStorage.ColumnIndices, 0, _storage.ValueCount * Constants.SizeOfInt); - Buffer.BlockCopy(_storage.RowPointers, 0, targetStorage.RowPointers, 0, RowCount * Constants.SizeOfInt); - } + base.CopyTo(target); } /// diff --git a/src/Numerics/LinearAlgebra/Storage/SparseCompressedRowMatrixStorage.cs b/src/Numerics/LinearAlgebra/Storage/SparseCompressedRowMatrixStorage.cs index ed1ae2aa..db896129 100644 --- a/src/Numerics/LinearAlgebra/Storage/SparseCompressedRowMatrixStorage.cs +++ b/src/Numerics/LinearAlgebra/Storage/SparseCompressedRowMatrixStorage.cs @@ -197,7 +197,7 @@ namespace MathNet.Numerics.LinearAlgebra.Storage /// Index of value in nonZeroValues array /// Row number of matrix /// WARNING: This method is not thread safe. Use "lock" with it and be sure to avoid deadlocks - private void DeleteItemByIndex(int itemIndex, int row) + void DeleteItemByIndex(int itemIndex, int row) { // Move all values (with an position larger than index) in the value array to the previous position // move all values (with an position larger than index) in the columIndices array to the previous position @@ -244,7 +244,7 @@ namespace MathNet.Numerics.LinearAlgebra.Storage /// increased in size. /// /// The amount grown. - private int GrowthSize() + int GrowthSize() { int delta; if (Values.Length > 1024) @@ -265,5 +265,67 @@ namespace MathNet.Numerics.LinearAlgebra.Storage return delta; } + + public void CopyTo(SparseCompressedRowMatrixStorage target) + { + if (ReferenceEquals(this, target)) + { + return; + } + + if (target == null) + { + throw new ArgumentNullException("target"); + } + + if (RowCount != target.RowCount || ColumnCount != target.ColumnCount) + { + var message = string.Format(Resources.ArgumentMatrixDimensions2, RowCount + "x" + ColumnCount, target.RowCount + "x" + target.ColumnCount); + throw new ArgumentException(message, "target"); + } + + target.ValueCount = ValueCount; + target.Values = new T[ValueCount]; + target.ColumnIndices = new int[ValueCount]; + + if (ValueCount != 0) + { + Array.Copy(Values, target.Values, ValueCount); + Buffer.BlockCopy(ColumnIndices, 0, target.ColumnIndices, 0, ValueCount * Constants.SizeOfInt); + Buffer.BlockCopy(RowPointers, 0, target.RowPointers, 0, RowCount * Constants.SizeOfInt); + } + } + + public void CopyTo(DenseColumnMajorMatrixStorage target, bool skipClearing = false) + { + if (target == null) + { + throw new ArgumentNullException("target"); + } + + if (RowCount != target.RowCount || ColumnCount != target.ColumnCount) + { + var message = string.Format(Resources.ArgumentMatrixDimensions2, RowCount + "x" + ColumnCount, target.RowCount + "x" + target.ColumnCount); + throw new ArgumentException(message, "target"); + } + + if (!skipClearing) + { + target.Clear(); + } + + if (ValueCount != 0) + { + for (int row = 0; row < RowCount; row++) + { + var startIndex = RowPointers[row]; + var endIndex = row < RowPointers.Length - 1 ? RowPointers[row + 1] : ValueCount; + for (var j = startIndex; j < endIndex; j++) + { + target.At(row, ColumnIndices[j], Values[j]); + } + } + } + } } } diff --git a/src/Numerics/LinearAlgebra/Storage/SparseDiagonalMatrixStorage.cs b/src/Numerics/LinearAlgebra/Storage/SparseDiagonalMatrixStorage.cs index 05964d9c..20e3d722 100644 --- a/src/Numerics/LinearAlgebra/Storage/SparseDiagonalMatrixStorage.cs +++ b/src/Numerics/LinearAlgebra/Storage/SparseDiagonalMatrixStorage.cs @@ -127,7 +127,7 @@ namespace MathNet.Numerics.LinearAlgebra.Storage Array.Copy(Data, 0, target.Data, 0, Data.Length); } - public void CopyTo(DenseColumnMajorMatrixStorage target, bool targetKnownClear = false) + public void CopyTo(SparseCompressedRowMatrixStorage target, bool skipClearing = false) { if (target == null) { @@ -140,7 +140,31 @@ namespace MathNet.Numerics.LinearAlgebra.Storage throw new ArgumentException(message, "target"); } - if (!targetKnownClear) + if (!skipClearing) + { + target.Clear(); + } + + for (int i = 0; i < Data.Length; i++) + { + target.At(i, i, Data[i]); + } + } + + public void CopyTo(DenseColumnMajorMatrixStorage target, bool skipClearing = false) + { + if (target == null) + { + throw new ArgumentNullException("target"); + } + + if (RowCount != target.RowCount || ColumnCount != target.ColumnCount) + { + var message = string.Format(Resources.ArgumentMatrixDimensions2, RowCount + "x" + ColumnCount, target.RowCount + "x" + target.ColumnCount); + throw new ArgumentException(message, "target"); + } + + if (!skipClearing) { target.Clear(); }