From 2876913afe7c2f1ac8d604ff8569c94e9257681b Mon Sep 17 00:00:00 2001 From: Christoph Ruegg Date: Mon, 8 Apr 2013 18:20:57 +0200 Subject: [PATCH] LA: matrices of indexed enumerable --- src/FSharp/LinearAlgebra.Double.Matrix.fs | 12 ++++++ .../LinearAlgebra/Complex/DenseMatrix.cs | 11 +++++ .../LinearAlgebra/Complex/DiagonalMatrix.cs | 22 ++++++++++ .../LinearAlgebra/Complex/SparseMatrix.cs | 11 +++++ .../LinearAlgebra/Complex32/DenseMatrix.cs | 11 +++++ .../LinearAlgebra/Complex32/DiagonalMatrix.cs | 22 ++++++++++ .../LinearAlgebra/Complex32/SparseMatrix.cs | 11 +++++ .../LinearAlgebra/Double/DenseMatrix.cs | 11 +++++ .../LinearAlgebra/Double/DiagonalMatrix.cs | 22 ++++++++++ .../LinearAlgebra/Double/SparseMatrix.cs | 11 +++++ .../LinearAlgebra/Single/DenseMatrix.cs | 11 +++++ .../LinearAlgebra/Single/DiagonalMatrix.cs | 22 ++++++++++ .../LinearAlgebra/Single/SparseMatrix.cs | 11 +++++ .../Storage/DenseColumnMajorMatrixStorage.cs | 15 +++++++ .../Storage/DiagonalMatrixStorage.cs | 34 +++++++++++++++ .../SparseCompressedRowMatrixStorage.cs | 43 +++++++++++++++++++ 16 files changed, 280 insertions(+) diff --git a/src/FSharp/LinearAlgebra.Double.Matrix.fs b/src/FSharp/LinearAlgebra.Double.Matrix.fs index f87f2911..66c0e8b6 100644 --- a/src/FSharp/LinearAlgebra.Double.Matrix.fs +++ b/src/FSharp/LinearAlgebra.Double.Matrix.fs @@ -249,6 +249,12 @@ module DenseMatrix = /// Initialize a matrix by calling a construction function for every element. let inline init (n: int) (m: int) (f: int -> int -> float) = DenseMatrix.Create(n, m, fun n m -> f n m) + /// Create a matrix with a given dimension from an indexed list of row, column, value tuples. + let inline ofListi (n: int) (m: int) (fl: list) = DenseMatrix.OfIndexed(n, m, Seq.ofList fl) + + /// Create a matrix with a given dimension from an indexed sequences of row, column, value tuples. + let inline ofSeqi (n: int) (m: int) (fs: #seq) = DenseMatrix.OfIndexed(n, m, fs) + /// Create a matrix from a list of float lists. Every list in the master list specifies a row. let inline ofList (fll: float list list) = let n = List.length fll @@ -311,6 +317,12 @@ module SparseMatrix = /// Initialize a matrix by calling a construction function for every element. let inline init (n: int) (m: int) (f: int -> int -> float) = SparseMatrix.Create(n, m, fun n m -> f n m) + /// Create a matrix with a given dimension from an indexed list of row, column, value tuples. + let inline ofListi (n: int) (m: int) (fl: list) = SparseMatrix.OfIndexed(n, m, Seq.ofList fl) + + /// Create a matrix with a given dimension from an indexed sequences of row, column, value tuples. + let inline ofSeqi (n: int) (m: int) (fs: #seq) = SparseMatrix.OfIndexed(n, m, fs) + /// Create a matrix from a list of float lists. Every list in the master list specifies a row. let inline ofList (rows: int) (cols: int) (fll: list) = let A = new SparseMatrix(rows, cols) diff --git a/src/Numerics/LinearAlgebra/Complex/DenseMatrix.cs b/src/Numerics/LinearAlgebra/Complex/DenseMatrix.cs index 28d36aa8..3d4cc355 100644 --- a/src/Numerics/LinearAlgebra/Complex/DenseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Complex/DenseMatrix.cs @@ -134,6 +134,17 @@ namespace MathNet.Numerics.LinearAlgebra.Complex return new DenseMatrix(DenseColumnMajorMatrixStorage.OfArray(array)); } + /// + /// Create a new dense matrix as a copy of the given indexed enumerable. + /// Keys must be provided at most once, zero is assumed if a key is omitted. + /// This new matrix will be independent from the enumerable. + /// A new memory block will be allocated for storing the matrix. + /// + public static DenseMatrix OfIndexed(int rows, int columns, IEnumerable> enumerable) + { + return new DenseMatrix(DenseColumnMajorMatrixStorage.OfIndexedEnumerable(rows, columns, enumerable)); + } + /// /// Create a new dense matrix as a copy of the given enumerable. /// The enumerable is assumed to be in column-major order (column by column). diff --git a/src/Numerics/LinearAlgebra/Complex/DiagonalMatrix.cs b/src/Numerics/LinearAlgebra/Complex/DiagonalMatrix.cs index 71e0a335..76af3b3d 100644 --- a/src/Numerics/LinearAlgebra/Complex/DiagonalMatrix.cs +++ b/src/Numerics/LinearAlgebra/Complex/DiagonalMatrix.cs @@ -35,6 +35,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex using Properties; using Storage; using System; + using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Numerics; @@ -142,6 +143,27 @@ namespace MathNet.Numerics.LinearAlgebra.Complex return new DiagonalMatrix(DiagonalMatrixStorage.OfArray(array)); } + /// + /// Create a new diagonal matrix and initialize each diagonal value from the provided indexed enumerable. + /// Keys must be provided at most once, zero is assumed if a key is omitted. + /// This new matrix will be independent from the enumerable. + /// A new memory block will be allocated for storing the matrix. + /// + public static DiagonalMatrix OfIndexedDiagonal(int rows, int columns, IEnumerable> diagonal) + { + return new DiagonalMatrix(DiagonalMatrixStorage.OfIndexedEnumerable(rows, columns, diagonal)); + } + + /// + /// Create a new diagonal matrix and initialize each diagonal value from the provided enumerable. + /// This new matrix will be independent from the enumerable. + /// A new memory block will be allocated for storing the matrix. + /// + public static DiagonalMatrix OfDiagonal(int rows, int columns, IEnumerable diagonal) + { + return new DiagonalMatrix(DiagonalMatrixStorage.OfEnumerable(rows, columns, diagonal)); + } + /// /// Create a new diagonal matrix and initialize each diagonal value using the provided init function. /// diff --git a/src/Numerics/LinearAlgebra/Complex/SparseMatrix.cs b/src/Numerics/LinearAlgebra/Complex/SparseMatrix.cs index 1a96c2fe..9ab581c3 100644 --- a/src/Numerics/LinearAlgebra/Complex/SparseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Complex/SparseMatrix.cs @@ -112,6 +112,17 @@ namespace MathNet.Numerics.LinearAlgebra.Complex return new SparseMatrix(SparseCompressedRowMatrixStorage.OfArray(array)); } + /// + /// Create a new sparse matrix as a copy of the given indexed enumerable. + /// Keys must be provided at most once, zero is assumed if a key is omitted. + /// This new matrix will be independent from the enumerable. + /// A new memory block will be allocated for storing the matrix. + /// + public static SparseMatrix OfIndexed(int rows, int columns, IEnumerable> enumerable) + { + return new SparseMatrix(SparseCompressedRowMatrixStorage.OfIndexedEnumerable(rows, columns, enumerable)); + } + /// /// Create a new sparse matrix as a copy of the given enumerable. /// The enumerable is assumed to be in row-major order (row by row). diff --git a/src/Numerics/LinearAlgebra/Complex32/DenseMatrix.cs b/src/Numerics/LinearAlgebra/Complex32/DenseMatrix.cs index aa5e147a..a5badf05 100644 --- a/src/Numerics/LinearAlgebra/Complex32/DenseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Complex32/DenseMatrix.cs @@ -134,6 +134,17 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 return new DenseMatrix(DenseColumnMajorMatrixStorage.OfArray(array)); } + /// + /// Create a new dense matrix as a copy of the given indexed enumerable. + /// Keys must be provided at most once, zero is assumed if a key is omitted. + /// This new matrix will be independent from the enumerable. + /// A new memory block will be allocated for storing the matrix. + /// + public static DenseMatrix OfIndexed(int rows, int columns, IEnumerable> enumerable) + { + return new DenseMatrix(DenseColumnMajorMatrixStorage.OfIndexedEnumerable(rows, columns, enumerable)); + } + /// /// Create a new dense matrix as a copy of the given enumerable. /// The enumerable is assumed to be in column-major order (column by column). diff --git a/src/Numerics/LinearAlgebra/Complex32/DiagonalMatrix.cs b/src/Numerics/LinearAlgebra/Complex32/DiagonalMatrix.cs index 6348a231..baab65d3 100644 --- a/src/Numerics/LinearAlgebra/Complex32/DiagonalMatrix.cs +++ b/src/Numerics/LinearAlgebra/Complex32/DiagonalMatrix.cs @@ -36,6 +36,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 using Properties; using Storage; using System; + using System.Collections.Generic; using System.Diagnostics; using System.Linq; @@ -142,6 +143,27 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 return new DiagonalMatrix(DiagonalMatrixStorage.OfArray(array)); } + /// + /// Create a new diagonal matrix and initialize each diagonal value from the provided indexed enumerable. + /// Keys must be provided at most once, zero is assumed if a key is omitted. + /// This new matrix will be independent from the enumerable. + /// A new memory block will be allocated for storing the matrix. + /// + public static DiagonalMatrix OfIndexedDiagonal(int rows, int columns, IEnumerable> diagonal) + { + return new DiagonalMatrix(DiagonalMatrixStorage.OfIndexedEnumerable(rows, columns, diagonal)); + } + + /// + /// Create a new diagonal matrix and initialize each diagonal value from the provided enumerable. + /// This new matrix will be independent from the enumerable. + /// A new memory block will be allocated for storing the matrix. + /// + public static DiagonalMatrix OfDiagonal(int rows, int columns, IEnumerable diagonal) + { + return new DiagonalMatrix(DiagonalMatrixStorage.OfEnumerable(rows, columns, diagonal)); + } + /// /// Create a new diagonal matrix and initialize each diagonal value using the provided init function. /// diff --git a/src/Numerics/LinearAlgebra/Complex32/SparseMatrix.cs b/src/Numerics/LinearAlgebra/Complex32/SparseMatrix.cs index 122e1a50..3a7e0704 100644 --- a/src/Numerics/LinearAlgebra/Complex32/SparseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Complex32/SparseMatrix.cs @@ -112,6 +112,17 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 return new SparseMatrix(SparseCompressedRowMatrixStorage.OfArray(array)); } + /// + /// Create a new sparse matrix as a copy of the given indexed enumerable. + /// Keys must be provided at most once, zero is assumed if a key is omitted. + /// This new matrix will be independent from the enumerable. + /// A new memory block will be allocated for storing the matrix. + /// + public static SparseMatrix OfIndexed(int rows, int columns, IEnumerable> enumerable) + { + return new SparseMatrix(SparseCompressedRowMatrixStorage.OfIndexedEnumerable(rows, columns, enumerable)); + } + /// /// Create a new sparse matrix as a copy of the given enumerable. /// The enumerable is assumed to be in row-major order (row by row). diff --git a/src/Numerics/LinearAlgebra/Double/DenseMatrix.cs b/src/Numerics/LinearAlgebra/Double/DenseMatrix.cs index ee262973..461609aa 100644 --- a/src/Numerics/LinearAlgebra/Double/DenseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Double/DenseMatrix.cs @@ -136,6 +136,17 @@ namespace MathNet.Numerics.LinearAlgebra.Double return new DenseMatrix(DenseColumnMajorMatrixStorage.OfArray(array)); } + /// + /// Create a new dense matrix as a copy of the given indexed enumerable. + /// Keys must be provided at most once, zero is assumed if a key is omitted. + /// This new matrix will be independent from the enumerable. + /// A new memory block will be allocated for storing the matrix. + /// + public static DenseMatrix OfIndexed(int rows, int columns, IEnumerable> enumerable) + { + return new DenseMatrix(DenseColumnMajorMatrixStorage.OfIndexedEnumerable(rows, columns, enumerable)); + } + /// /// Create a new dense matrix as a copy of the given enumerable. /// The enumerable is assumed to be in column-major order (column by column). diff --git a/src/Numerics/LinearAlgebra/Double/DiagonalMatrix.cs b/src/Numerics/LinearAlgebra/Double/DiagonalMatrix.cs index e812322b..72a8b0ee 100644 --- a/src/Numerics/LinearAlgebra/Double/DiagonalMatrix.cs +++ b/src/Numerics/LinearAlgebra/Double/DiagonalMatrix.cs @@ -35,6 +35,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double using Properties; using Storage; using System; + using System.Collections.Generic; using System.Diagnostics; using System.Linq; @@ -141,6 +142,27 @@ namespace MathNet.Numerics.LinearAlgebra.Double return new DiagonalMatrix(DiagonalMatrixStorage.OfArray(array)); } + /// + /// Create a new diagonal matrix and initialize each diagonal value from the provided indexed enumerable. + /// Keys must be provided at most once, zero is assumed if a key is omitted. + /// This new matrix will be independent from the enumerable. + /// A new memory block will be allocated for storing the matrix. + /// + public static DiagonalMatrix OfIndexedDiagonal(int rows, int columns, IEnumerable> diagonal) + { + return new DiagonalMatrix(DiagonalMatrixStorage.OfIndexedEnumerable(rows, columns, diagonal)); + } + + /// + /// Create a new diagonal matrix and initialize each diagonal value from the provided enumerable. + /// This new matrix will be independent from the enumerable. + /// A new memory block will be allocated for storing the matrix. + /// + public static DiagonalMatrix OfDiagonal(int rows, int columns, IEnumerable diagonal) + { + return new DiagonalMatrix(DiagonalMatrixStorage.OfEnumerable(rows, columns, diagonal)); + } + /// /// Create a new diagonal matrix and initialize each diagonal value using the provided init function. /// diff --git a/src/Numerics/LinearAlgebra/Double/SparseMatrix.cs b/src/Numerics/LinearAlgebra/Double/SparseMatrix.cs index ca0e3792..71b73280 100644 --- a/src/Numerics/LinearAlgebra/Double/SparseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Double/SparseMatrix.cs @@ -111,6 +111,17 @@ namespace MathNet.Numerics.LinearAlgebra.Double return new SparseMatrix(SparseCompressedRowMatrixStorage.OfArray(array)); } + /// + /// Create a new sparse matrix as a copy of the given indexed enumerable. + /// Keys must be provided at most once, zero is assumed if a key is omitted. + /// This new matrix will be independent from the enumerable. + /// A new memory block will be allocated for storing the matrix. + /// + public static SparseMatrix OfIndexed(int rows, int columns, IEnumerable> enumerable) + { + return new SparseMatrix(SparseCompressedRowMatrixStorage.OfIndexedEnumerable(rows, columns, enumerable)); + } + /// /// Create a new sparse matrix as a copy of the given enumerable. /// The enumerable is assumed to be in row-major order (row by row). diff --git a/src/Numerics/LinearAlgebra/Single/DenseMatrix.cs b/src/Numerics/LinearAlgebra/Single/DenseMatrix.cs index 9a16110a..2b12b9d0 100644 --- a/src/Numerics/LinearAlgebra/Single/DenseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Single/DenseMatrix.cs @@ -134,6 +134,17 @@ namespace MathNet.Numerics.LinearAlgebra.Single return new DenseMatrix(DenseColumnMajorMatrixStorage.OfArray(array)); } + /// + /// Create a new dense matrix as a copy of the given indexed enumerable. + /// Keys must be provided at most once, zero is assumed if a key is omitted. + /// This new matrix will be independent from the enumerable. + /// A new memory block will be allocated for storing the matrix. + /// + public static DenseMatrix OfIndexed(int rows, int columns, IEnumerable> enumerable) + { + return new DenseMatrix(DenseColumnMajorMatrixStorage.OfIndexedEnumerable(rows, columns, enumerable)); + } + /// /// Create a new dense matrix as a copy of the given enumerable. /// The enumerable is assumed to be in column-major order (column by column). diff --git a/src/Numerics/LinearAlgebra/Single/DiagonalMatrix.cs b/src/Numerics/LinearAlgebra/Single/DiagonalMatrix.cs index 46ea9455..34886fdd 100644 --- a/src/Numerics/LinearAlgebra/Single/DiagonalMatrix.cs +++ b/src/Numerics/LinearAlgebra/Single/DiagonalMatrix.cs @@ -35,6 +35,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single using Properties; using Storage; using System; + using System.Collections.Generic; using System.Diagnostics; using System.Linq; @@ -141,6 +142,27 @@ namespace MathNet.Numerics.LinearAlgebra.Single return new DiagonalMatrix(DiagonalMatrixStorage.OfArray(array)); } + /// + /// Create a new diagonal matrix and initialize each diagonal value from the provided indexed enumerable. + /// Keys must be provided at most once, zero is assumed if a key is omitted. + /// This new matrix will be independent from the enumerable. + /// A new memory block will be allocated for storing the matrix. + /// + public static DiagonalMatrix OfIndexedDiagonal(int rows, int columns, IEnumerable> diagonal) + { + return new DiagonalMatrix(DiagonalMatrixStorage.OfIndexedEnumerable(rows, columns, diagonal)); + } + + /// + /// Create a new diagonal matrix and initialize each diagonal value from the provided enumerable. + /// This new matrix will be independent from the enumerable. + /// A new memory block will be allocated for storing the matrix. + /// + public static DiagonalMatrix OfDiagonal(int rows, int columns, IEnumerable diagonal) + { + return new DiagonalMatrix(DiagonalMatrixStorage.OfEnumerable(rows, columns, diagonal)); + } + /// /// Create a new diagonal matrix and initialize each diagonal value using the provided init function. /// diff --git a/src/Numerics/LinearAlgebra/Single/SparseMatrix.cs b/src/Numerics/LinearAlgebra/Single/SparseMatrix.cs index f075724c..eddc400f 100644 --- a/src/Numerics/LinearAlgebra/Single/SparseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Single/SparseMatrix.cs @@ -111,6 +111,17 @@ namespace MathNet.Numerics.LinearAlgebra.Single return new SparseMatrix(SparseCompressedRowMatrixStorage.OfArray(array)); } + /// + /// Create a new sparse matrix as a copy of the given indexed enumerable. + /// Keys must be provided at most once, zero is assumed if a key is omitted. + /// This new matrix will be independent from the enumerable. + /// A new memory block will be allocated for storing the matrix. + /// + public static SparseMatrix OfIndexed(int rows, int columns, IEnumerable> enumerable) + { + return new SparseMatrix(SparseCompressedRowMatrixStorage.OfIndexedEnumerable(rows, columns, enumerable)); + } + /// /// Create a new sparse matrix as a copy of the given enumerable. /// The enumerable is assumed to be in row-major order (row by row). diff --git a/src/Numerics/LinearAlgebra/Storage/DenseColumnMajorMatrixStorage.cs b/src/Numerics/LinearAlgebra/Storage/DenseColumnMajorMatrixStorage.cs index 2293b671..1378e612 100644 --- a/src/Numerics/LinearAlgebra/Storage/DenseColumnMajorMatrixStorage.cs +++ b/src/Numerics/LinearAlgebra/Storage/DenseColumnMajorMatrixStorage.cs @@ -136,6 +136,21 @@ namespace MathNet.Numerics.LinearAlgebra.Storage return storage; } + public static DenseColumnMajorMatrixStorage OfIndexedEnumerable(int rows, int columns, IEnumerable> data) + { + if (data == null) + { + throw new ArgumentNullException("data"); + } + + var array = new T[rows * columns]; + foreach (var item in data) + { + array[(item.Item2 * rows) + item.Item1] = item.Item3; + } + return new DenseColumnMajorMatrixStorage(rows, columns, array); + } + public static DenseColumnMajorMatrixStorage OfColumnMajorEnumerable(int rows, int columns, IEnumerable data) { if (data == null) diff --git a/src/Numerics/LinearAlgebra/Storage/DiagonalMatrixStorage.cs b/src/Numerics/LinearAlgebra/Storage/DiagonalMatrixStorage.cs index 70a293f5..5b5a7393 100644 --- a/src/Numerics/LinearAlgebra/Storage/DiagonalMatrixStorage.cs +++ b/src/Numerics/LinearAlgebra/Storage/DiagonalMatrixStorage.cs @@ -29,6 +29,7 @@ // using System; +using System.Collections.Generic; using System.Linq; using MathNet.Numerics.Properties; @@ -209,6 +210,39 @@ namespace MathNet.Numerics.LinearAlgebra.Storage return storage; } + public static DiagonalMatrixStorage OfEnumerable(int rows, int columns, IEnumerable data) + { + if (data == null) + { + throw new ArgumentNullException("data"); + } + + var arrayData = data as T[]; + if (arrayData != null) + { + var copy = new T[arrayData.Length]; + Array.Copy(arrayData, copy, arrayData.Length); + return new DiagonalMatrixStorage(rows, columns, copy); + } + + return new DiagonalMatrixStorage(rows, columns, data.ToArray()); + } + + public static DiagonalMatrixStorage OfIndexedEnumerable(int rows, int columns, IEnumerable> data) + { + if (data == null) + { + throw new ArgumentNullException("data"); + } + + var storage = new DiagonalMatrixStorage(rows, columns); + foreach(var item in data) + { + storage.Data[item.Item1] = item.Item2; + } + return storage; + } + // MATRIX COPY internal override void CopyToUnchecked(MatrixStorage target, bool skipClearing = false) diff --git a/src/Numerics/LinearAlgebra/Storage/SparseCompressedRowMatrixStorage.cs b/src/Numerics/LinearAlgebra/Storage/SparseCompressedRowMatrixStorage.cs index e13710c1..f2a0b73d 100644 --- a/src/Numerics/LinearAlgebra/Storage/SparseCompressedRowMatrixStorage.cs +++ b/src/Numerics/LinearAlgebra/Storage/SparseCompressedRowMatrixStorage.cs @@ -428,6 +428,49 @@ namespace MathNet.Numerics.LinearAlgebra.Storage return storage; } + public static SparseCompressedRowMatrixStorage OfIndexedEnumerable(int rows, int columns, IEnumerable> data) + { + if (data == null) + { + throw new ArgumentNullException("data"); + } + + var trows = new List>[rows]; + foreach (var item in data) + { + if (!Zero.Equals(item.Item3)) + { + var row = trows[item.Item1] ?? (trows[item.Item1] = new List>()); + row.Add(new Tuple(item.Item2, item.Item3)); + } + } + + var storage = new SparseCompressedRowMatrixStorage(rows, columns); + var rowPointers = storage.RowPointers; + var columnIndices = new List(); + var values = new List(); + + int index = 0; + for (int row = 0; row < rows; row++) + { + rowPointers[row] = index; + if (trows[row] != null) + { + foreach (var item in trows[row]) + { + values.Add(item.Item2); + columnIndices.Add(item.Item1); + index++; + } + } + } + + storage.ColumnIndices = columnIndices.ToArray(); + storage.Values = values.ToArray(); + storage.ValueCount = values.Count; + return storage; + } + public static SparseCompressedRowMatrixStorage OfRowMajorEnumerable(int rows, int columns, IEnumerable data) { if (data == null)