From 3fd92a7e1d7532301342752436e8084f73e1163a Mon Sep 17 00:00:00 2001 From: Christoph Ruegg Date: Mon, 16 Jul 2012 16:29:31 +0200 Subject: [PATCH] LA Storage: IMatrixStorage --- .../Storage/DenseColumnMajorMatrixStorage.cs | 49 ++++++++++++++- .../LinearAlgebra/Storage/IMatrixStorage.cs | 51 ++++++++++++++++ .../SparseCompressedRowMatrixStorage.cs | 60 ++++++++++++++++++- .../Storage/SparseDiagonalMatrixStorage.cs | 59 +++++++++++++++++- src/Numerics/Numerics.csproj | 1 + src/Portable/Portable.csproj | 3 + 6 files changed, 220 insertions(+), 3 deletions(-) create mode 100644 src/Numerics/LinearAlgebra/Storage/IMatrixStorage.cs diff --git a/src/Numerics/LinearAlgebra/Storage/DenseColumnMajorMatrixStorage.cs b/src/Numerics/LinearAlgebra/Storage/DenseColumnMajorMatrixStorage.cs index 3d7d65cb..5e4abb41 100644 --- a/src/Numerics/LinearAlgebra/Storage/DenseColumnMajorMatrixStorage.cs +++ b/src/Numerics/LinearAlgebra/Storage/DenseColumnMajorMatrixStorage.cs @@ -1,9 +1,10 @@ using System; using MathNet.Numerics.Properties; +using MathNet.Numerics.Threading; namespace MathNet.Numerics.LinearAlgebra.Storage { - internal class DenseColumnMajorMatrixStorage + internal class DenseColumnMajorMatrixStorage : IMatrixStorage where T : struct, IEquatable, IFormattable { // [ruegg] public fields are OK here @@ -95,6 +96,42 @@ namespace MathNet.Numerics.LinearAlgebra.Storage Array.Clear(Data, 0, Data.Length); } + public void CopyTo(IMatrixStorage target, bool skipClearing = false) + { + var denseTarget = target as DenseColumnMajorMatrixStorage; + if (denseTarget != null) + { + CopyTo(denseTarget); + return; + } + + // FALL BACK + + 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"); + } + + for (int j = 0, offset = 0; j < ColumnCount; j++, offset += RowCount) + { + for (int i = 0; i < RowCount; i++) + { + target.At(i, j, Data[i + offset]); + } + } + } + public void CopyTo(DenseColumnMajorMatrixStorage target) { if (ReferenceEquals(this, target)) @@ -142,5 +179,15 @@ namespace MathNet.Numerics.LinearAlgebra.Storage Array.Copy(Data, j*RowCount + sourceRowIndex, target.Data, jj*target.RowCount + targetRowIndex, rowCount); } } + + int IMatrixStorage.RowCount + { + get { return RowCount; } + } + + int IMatrixStorage.ColumnCount + { + get { return ColumnCount; } + } } } diff --git a/src/Numerics/LinearAlgebra/Storage/IMatrixStorage.cs b/src/Numerics/LinearAlgebra/Storage/IMatrixStorage.cs new file mode 100644 index 00000000..081edf68 --- /dev/null +++ b/src/Numerics/LinearAlgebra/Storage/IMatrixStorage.cs @@ -0,0 +1,51 @@ +using System; + +namespace MathNet.Numerics.LinearAlgebra.Storage +{ + public interface IMatrixStorage where T : struct, IEquatable, IFormattable + { + int RowCount { get; } + int ColumnCount { get; } + + /// + /// Gets or sets the value at the given row and column, with range checking. + /// + /// + /// The row of the element. + /// + /// + /// The column of the element. + /// + /// The value to get or set. + /// This method is ranged checked. and + /// to get and set values without range checking. + T this[int row, int column] { get; set; } + + /// + /// Retrieves the requested element without range checking. + /// + /// + /// The row of the element. + /// + /// + /// The column of the element. + /// + /// + /// The requested element. + /// + /// Not range-checked. + T At(int row, int column); + + /// + /// Sets the element without range checking. + /// + /// The row of the element. + /// The column of the element. + /// The value to set the element to. + /// WARNING: This method is not thread safe. Use "lock" with it and be sure to avoid deadlocks. + void At(int row, int column, T value); + + void Clear(); + void CopyTo(IMatrixStorage target, bool skipClearing = false); + } +} diff --git a/src/Numerics/LinearAlgebra/Storage/SparseCompressedRowMatrixStorage.cs b/src/Numerics/LinearAlgebra/Storage/SparseCompressedRowMatrixStorage.cs index db896129..b5646c0c 100644 --- a/src/Numerics/LinearAlgebra/Storage/SparseCompressedRowMatrixStorage.cs +++ b/src/Numerics/LinearAlgebra/Storage/SparseCompressedRowMatrixStorage.cs @@ -3,7 +3,7 @@ using MathNet.Numerics.Properties; namespace MathNet.Numerics.LinearAlgebra.Storage { - internal class SparseCompressedRowMatrixStorage + internal class SparseCompressedRowMatrixStorage : IMatrixStorage where T : struct, IEquatable, IFormattable { // [ruegg] public fields are OK here @@ -266,6 +266,54 @@ namespace MathNet.Numerics.LinearAlgebra.Storage return delta; } + public void CopyTo(IMatrixStorage target, bool skipClearing = false) + { + var sparseTarget = target as SparseCompressedRowMatrixStorage; + if (sparseTarget != null) + { + CopyTo(sparseTarget); + return; + } + + var denseTarget = target as DenseColumnMajorMatrixStorage; + if (denseTarget != null) + { + CopyTo(denseTarget, skipClearing); + return; + } + + // FALL BACK + + 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]); + } + } + } + } + public void CopyTo(SparseCompressedRowMatrixStorage target) { if (ReferenceEquals(this, target)) @@ -327,5 +375,15 @@ namespace MathNet.Numerics.LinearAlgebra.Storage } } } + + int IMatrixStorage.RowCount + { + get { return RowCount; } + } + + int IMatrixStorage.ColumnCount + { + get { return ColumnCount; } + } } } diff --git a/src/Numerics/LinearAlgebra/Storage/SparseDiagonalMatrixStorage.cs b/src/Numerics/LinearAlgebra/Storage/SparseDiagonalMatrixStorage.cs index e23cf8a8..29c5da2a 100644 --- a/src/Numerics/LinearAlgebra/Storage/SparseDiagonalMatrixStorage.cs +++ b/src/Numerics/LinearAlgebra/Storage/SparseDiagonalMatrixStorage.cs @@ -3,7 +3,7 @@ using MathNet.Numerics.Properties; namespace MathNet.Numerics.LinearAlgebra.Storage { - internal class SparseDiagonalMatrixStorage + internal class SparseDiagonalMatrixStorage : IMatrixStorage where T : struct, IEquatable, IFormattable { // [ruegg] public fields are OK here @@ -105,6 +105,53 @@ namespace MathNet.Numerics.LinearAlgebra.Storage Array.Clear(Data, 0, Data.Length); } + public void CopyTo(IMatrixStorage target, bool skipClearing = false) + { + var diagonalTarget = target as SparseDiagonalMatrixStorage; + if (diagonalTarget != null) + { + CopyTo(diagonalTarget); + return; + } + + var denseTarget = target as DenseColumnMajorMatrixStorage; + if (denseTarget != null) + { + CopyTo(denseTarget, skipClearing); + return; + } + + var sparseTarget = target as SparseCompressedRowMatrixStorage; + if (sparseTarget != null) + { + CopyTo(sparseTarget, skipClearing); + return; + } + + // FALL BACK + + 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(); + } + + for (int i = 0; i < Data.Length; i++) + { + target.At(i, i, Data[i]); + } + } + public void CopyTo(SparseDiagonalMatrixStorage target) { if (ReferenceEquals(this, target)) @@ -282,5 +329,15 @@ namespace MathNet.Numerics.LinearAlgebra.Storage } } } + + int IMatrixStorage.RowCount + { + get { return RowCount; } + } + + int IMatrixStorage.ColumnCount + { + get { return ColumnCount; } + } } } diff --git a/src/Numerics/Numerics.csproj b/src/Numerics/Numerics.csproj index d0f376b1..8652bbb1 100644 --- a/src/Numerics/Numerics.csproj +++ b/src/Numerics/Numerics.csproj @@ -332,6 +332,7 @@ + diff --git a/src/Portable/Portable.csproj b/src/Portable/Portable.csproj index b6ab9e48..22020468 100644 --- a/src/Portable/Portable.csproj +++ b/src/Portable/Portable.csproj @@ -894,6 +894,9 @@ LinearAlgebra\Storage\DenseColumnMajorMatrixStorage.cs + + LinearAlgebra\Storage\IMatrixStorage.cs + LinearAlgebra\Storage\SparseCompressedRowMatrixStorage.cs