diff --git a/src/FSharp/LinearAlgebra.Matrix.fs b/src/FSharp/LinearAlgebra.Matrix.fs index af4cdd20..9571016b 100644 --- a/src/FSharp/LinearAlgebra.Matrix.fs +++ b/src/FSharp/LinearAlgebra.Matrix.fs @@ -42,6 +42,12 @@ module Matrix = /// Transform a matrix into a 2D array. let inline toArray2 (A: #Matrix<_>) = A.ToArray() + /// Transform a matrix into an array of column arrays. + let inline toColArrays (m: #Matrix<_>) = m.ToColumnArrays() + + /// Transform a matrix into an array of row arrays. + let inline toRowArrays (m: #Matrix<_>) = m.ToRowArrays() + /// Transform a matrix into a sequence. let inline toSeq (m: #Matrix<_>) = m.Enumerate(Zeros.Include) diff --git a/src/FSharpUnitTests/DenseMatrixTests.fs b/src/FSharpUnitTests/DenseMatrixTests.fs index 41342e71..21243e3b 100644 --- a/src/FSharpUnitTests/DenseMatrixTests.fs +++ b/src/FSharpUnitTests/DenseMatrixTests.fs @@ -50,6 +50,13 @@ module DenseMatrixTests = a.[3..5,2..3] |> should equal smallM a.[6..8,0..1] |> should equal smallM + [] + let ``DenseMatrix.ofMatrixList2`` () = + let a = DenseMatrix.ofMatrixList2 [[smallM; smallM]; [smallM; smallM]; [smallM; smallM]] + a.[0..2,0..1] |> should equal smallM + a.[3..5,2..3] |> should equal smallM + a.[6..8,0..1] |> should equal smallM + [] let ``DenseMatrix.ofRowSeq`` () = DenseMatrix.ofRowSeq (Seq.ofList [[0.3;0.3];[0.3;0.3];[0.3;0.3]]) |> should equal smallM diff --git a/src/FSharpUnitTests/SparseMatrixTests.fs b/src/FSharpUnitTests/SparseMatrixTests.fs index efd7e16f..054424c8 100644 --- a/src/FSharpUnitTests/SparseMatrixTests.fs +++ b/src/FSharpUnitTests/SparseMatrixTests.fs @@ -30,6 +30,13 @@ module SparseMatrixTests = a.[4..7,6..11] |> should equal smallM a.[8..11,0..5] |> should equal smallM + [] + let ``SparseMatrix.ofMatrixList2`` () = + let a = SparseMatrix.ofMatrixList2 [[smallM; smallM]; [smallM; smallM]; [smallM; smallM]] + a.[0..3,0..5] |> should equal smallM + a.[4..7,6..11] |> should equal smallM + a.[8..11,0..5] |> should equal smallM + [] let ``SparseMatrix.ofRowSeq`` () = SparseMatrix.ofRowSeq (Seq.ofList [[0.;0.;0.;0.;0.;0.];[0.;0.;1.;0.;0.;0.];[0.;0.;0.;0.;0.;0.];[0.;0.;0.;0.;0.;0.]]) |> should equal smallM diff --git a/src/Numerics/LinearAlgebra/Matrix.cs b/src/Numerics/LinearAlgebra/Matrix.cs index b5f9c7e4..f139ecce 100644 --- a/src/Numerics/LinearAlgebra/Matrix.cs +++ b/src/Numerics/LinearAlgebra/Matrix.cs @@ -1362,6 +1362,22 @@ namespace MathNet.Numerics.LinearAlgebra return Storage.ToRowMajorArray(); } + /// + /// Returns this matrix as array of row arrays. + /// + public T[][] ToRowArrays() + { + return Storage.ToRowArrays(); + } + + /// + /// Returns this matrix as array of column arrays. + /// + public T[][] ToColumnArrays() + { + return Storage.ToColumnArrays(); + } + /// /// Returns an IEnumerable that can be used to iterate through all values of the matrix. /// diff --git a/src/Numerics/LinearAlgebra/Storage/DenseColumnMajorMatrixStorage.cs b/src/Numerics/LinearAlgebra/Storage/DenseColumnMajorMatrixStorage.cs index 4fedf2fb..ec4eff1e 100644 --- a/src/Numerics/LinearAlgebra/Storage/DenseColumnMajorMatrixStorage.cs +++ b/src/Numerics/LinearAlgebra/Storage/DenseColumnMajorMatrixStorage.cs @@ -557,6 +557,39 @@ namespace MathNet.Numerics.LinearAlgebra.Storage return ret; } + public override T[][] ToRowArrays() + { + var ret = new T[RowCount][]; + CommonParallel.For(0, RowCount, Math.Max(4096/ColumnCount, 32), (a, b) => + { + for (int i = a; i < b; i++) + { + var row = new T[ColumnCount]; + for (int j = 0; j < ColumnCount; j++) + { + row[j] = Data[j*RowCount + i]; + } + ret[i] = row; + } + }); + return ret; + } + + public override T[][] ToColumnArrays() + { + var ret = new T[ColumnCount][]; + CommonParallel.For(0, ColumnCount, Math.Max(4096/RowCount, 32), (a, b) => + { + for (int j = a; j < b; j++) + { + var column = new T[RowCount]; + Array.Copy(Data, j*RowCount, column, 0, RowCount); + ret[j] = column; + } + }); + return ret; + } + public override T[,] ToArray() { var ret = new T[RowCount, ColumnCount]; diff --git a/src/Numerics/LinearAlgebra/Storage/DiagonalMatrixStorage.cs b/src/Numerics/LinearAlgebra/Storage/DiagonalMatrixStorage.cs index 1101d474..593be38f 100644 --- a/src/Numerics/LinearAlgebra/Storage/DiagonalMatrixStorage.cs +++ b/src/Numerics/LinearAlgebra/Storage/DiagonalMatrixStorage.cs @@ -551,6 +551,34 @@ namespace MathNet.Numerics.LinearAlgebra.Storage return ret; } + public override T[][] ToRowArrays() + { + var ret = new T[RowCount][]; + for (int i = 0; i < RowCount; i++) + { + ret[i] = new T[ColumnCount]; + } + for (int i = 0; i < Data.Length; i++) + { + ret[i][i] = Data[i]; + } + return ret; + } + + public override T[][] ToColumnArrays() + { + var ret = new T[ColumnCount][]; + for (int j = 0; j < ColumnCount; j++) + { + ret[j] = new T[RowCount]; + } + for (int i = 0; i < Data.Length; i++) + { + ret[i][i] = Data[i]; + } + return ret; + } + public override T[,] ToArray() { var ret = new T[RowCount, ColumnCount]; diff --git a/src/Numerics/LinearAlgebra/Storage/MatrixStorage.cs b/src/Numerics/LinearAlgebra/Storage/MatrixStorage.cs index 83d6f0ab..8f609a08 100644 --- a/src/Numerics/LinearAlgebra/Storage/MatrixStorage.cs +++ b/src/Numerics/LinearAlgebra/Storage/MatrixStorage.cs @@ -472,6 +472,36 @@ namespace MathNet.Numerics.LinearAlgebra.Storage return ret; } + public virtual T[][] ToRowArrays() + { + var ret = new T[RowCount][]; + for (int i = 0; i < RowCount; i++) + { + var row = new T[ColumnCount]; + for (int j = 0; j < ColumnCount; j++) + { + row[j] = At(i, j); + } + ret[i] = row; + } + return ret; + } + + public virtual T[][] ToColumnArrays() + { + var ret = new T[ColumnCount][]; + for (int j = 0; j < ColumnCount; j++) + { + var column = new T[RowCount]; + for (int i = 0; i < RowCount; i++) + { + column[i] = At(i, j); + } + ret[j] = column; + } + return ret; + } + public virtual T[,] ToArray() { var ret = new T[RowCount, ColumnCount]; diff --git a/src/Numerics/LinearAlgebra/Storage/SparseCompressedRowMatrixStorage.cs b/src/Numerics/LinearAlgebra/Storage/SparseCompressedRowMatrixStorage.cs index 152d9520..6c4bb6c6 100644 --- a/src/Numerics/LinearAlgebra/Storage/SparseCompressedRowMatrixStorage.cs +++ b/src/Numerics/LinearAlgebra/Storage/SparseCompressedRowMatrixStorage.cs @@ -1216,6 +1216,48 @@ namespace MathNet.Numerics.LinearAlgebra.Storage return ret; } + public override T[][] ToRowArrays() + { + var ret = new T[RowCount][]; + if (ValueCount != 0) + { + for (int row = 0; row < RowCount; row++) + { + var array = new T[ColumnCount]; + var startIndex = RowPointers[row]; + var endIndex = RowPointers[row + 1]; + for (var j = startIndex; j < endIndex; j++) + { + array[ColumnIndices[j]] = Values[j]; + } + ret[row] = array; + } + } + return ret; + } + + public override T[][] ToColumnArrays() + { + var ret = new T[ColumnCount][]; + for (int j = 0; j < ColumnCount; j++) + { + ret[j] = new T[RowCount]; + } + if (ValueCount != 0) + { + for (int row = 0; row < RowCount; row++) + { + var startIndex = RowPointers[row]; + var endIndex = RowPointers[row + 1]; + for (var j = startIndex; j < endIndex; j++) + { + ret[ColumnIndices[j]][row] = Values[j]; + } + } + } + return ret; + } + public override T[,] ToArray() { var ret = new T[RowCount, ColumnCount]; diff --git a/src/UnitTests/LinearAlgebraTests/MatrixStructureTheory.cs b/src/UnitTests/LinearAlgebraTests/MatrixStructureTheory.cs index 6a5da9b3..1d3b1f67 100644 --- a/src/UnitTests/LinearAlgebraTests/MatrixStructureTheory.cs +++ b/src/UnitTests/LinearAlgebraTests/MatrixStructureTheory.cs @@ -196,6 +196,36 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests } } + [Theory] + public void CanToColumnArrays(Matrix matrix) + { + var columnArrays = matrix.ToColumnArrays(); + Assert.That(columnArrays.Length, Is.EqualTo(matrix.ColumnCount)); + Assert.That(columnArrays[0].Length, Is.EqualTo(matrix.RowCount)); + for (var i = 0; i < matrix.RowCount; i++) + { + for (var j = 0; j < matrix.ColumnCount; j++) + { + Assert.That(columnArrays[j][i], Is.EqualTo(matrix[i, j])); + } + } + } + + [Theory] + public void CanToRowArrays(Matrix matrix) + { + var rowArrays = matrix.ToRowArrays(); + Assert.That(rowArrays.Length, Is.EqualTo(matrix.RowCount)); + Assert.That(rowArrays[0].Length, Is.EqualTo(matrix.ColumnCount)); + for (var i = 0; i < matrix.RowCount; i++) + { + for (var j = 0; j < matrix.ColumnCount; j++) + { + Assert.That(rowArrays[i][j], Is.EqualTo(matrix[i, j])); + } + } + } + [Theory] public void CanToColumnWiseArray(Matrix matrix) {