From 46ef39b84ba3ca05dabfd868bb659484e5e5b91d Mon Sep 17 00:00:00 2001 From: Christoph Ruegg Date: Sun, 7 Apr 2013 22:04:48 +0200 Subject: [PATCH] LA: Functional matrix init --- .../LinearAlgebra/Complex/DenseMatrix.cs | 40 +++++++++---------- .../LinearAlgebra/Complex/DiagonalMatrix.cs | 18 +++++++++ .../LinearAlgebra/Complex/SparseMatrix.cs | 39 +++++------------- .../LinearAlgebra/Complex32/DenseMatrix.cs | 40 +++++++++---------- .../LinearAlgebra/Complex32/DiagonalMatrix.cs | 18 +++++++++ .../LinearAlgebra/Complex32/SparseMatrix.cs | 39 +++++------------- .../LinearAlgebra/Double/DenseMatrix.cs | 40 +++++++++---------- .../LinearAlgebra/Double/DiagonalMatrix.cs | 18 +++++++++ .../LinearAlgebra/Double/SparseMatrix.cs | 39 +++++------------- .../LinearAlgebra/Single/DenseMatrix.cs | 40 +++++++++---------- .../LinearAlgebra/Single/DiagonalMatrix.cs | 18 +++++++++ .../LinearAlgebra/Single/SparseMatrix.cs | 39 +++++------------- .../Storage/DenseColumnMajorMatrixStorage.cs | 22 ++++++++-- .../Storage/DiagonalMatrixStorage.cs | 10 +++++ .../SparseCompressedRowMatrixStorage.cs | 27 +++++++++++++ 15 files changed, 248 insertions(+), 199 deletions(-) diff --git a/src/Numerics/LinearAlgebra/Complex/DenseMatrix.cs b/src/Numerics/LinearAlgebra/Complex/DenseMatrix.cs index d09ded08..28d36aa8 100644 --- a/src/Numerics/LinearAlgebra/Complex/DenseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Complex/DenseMatrix.cs @@ -138,27 +138,40 @@ namespace MathNet.Numerics.LinearAlgebra.Complex /// 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). /// This new matrix will be independent from the enumerable. - /// A new memory block will be allocated for storing the vector. + /// A new memory block will be allocated for storing the matrix. /// public static DenseMatrix OfColumnMajor(int rows, int columns, IEnumerable columnMajor) { return new DenseMatrix(DenseColumnMajorMatrixStorage.OfColumnMajorEnumerable(rows, columns, columnMajor)); } + /// + /// Create a new dense matrix and initialize each value using the provided init function. + /// + public static DenseMatrix Create(int rows, int columns, Func init) + { + return new DenseMatrix(DenseColumnMajorMatrixStorage.OfInit(rows, columns, init)); + } + + /// + /// Create a new dense matrix with values sampled from the provided random distribution. + /// + public static DenseMatrix CreateRandom(int rows, int columns, IContinuousDistribution distribution) + { + return new DenseMatrix(DenseColumnMajorMatrixStorage.OfInit(rows, columns, + (i, j) => new Complex(distribution.Sample(), distribution.Sample()))); + } + /// /// Create a new dense matrix with the given number of rows and columns. /// All cells of the matrix will be initialized to the provided value. /// Zero-length matrices are not supported. /// /// If the row or column count is less than one. - [Obsolete("Scheduled for removal in v3.0.")] + [Obsolete("Use DenseMatrix.Create instead. Scheduled for removal in v3.0.")] public DenseMatrix(int rows, int columns, Complex value) - : this(rows, columns) + : this(DenseColumnMajorMatrixStorage.OfInit(rows, columns, (i, j) => value)) { - for (var i = 0; i < _values.Length; i++) - { - _values[i] = value; - } } /// @@ -183,19 +196,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex { } - /// - /// Create a new dense matrix with values sampled from the provided random distribution. - /// - public static DenseMatrix CreateRandom(int rows, int columns, IContinuousDistribution distribution) - { - var storage = new DenseColumnMajorMatrixStorage(rows, columns); - for (var i = 0; i < storage.Data.Length; i++) - { - storage.Data[i] = new Complex(distribution.Sample(), distribution.Sample()); - } - return new DenseMatrix(storage); - } - /// /// Gets the matrix's data. /// diff --git a/src/Numerics/LinearAlgebra/Complex/DiagonalMatrix.cs b/src/Numerics/LinearAlgebra/Complex/DiagonalMatrix.cs index 5bbbd3f2..71e0a335 100644 --- a/src/Numerics/LinearAlgebra/Complex/DiagonalMatrix.cs +++ b/src/Numerics/LinearAlgebra/Complex/DiagonalMatrix.cs @@ -30,6 +30,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex { + using Distributions; using Generic; using Properties; using Storage; @@ -141,6 +142,23 @@ namespace MathNet.Numerics.LinearAlgebra.Complex return new DiagonalMatrix(DiagonalMatrixStorage.OfArray(array)); } + /// + /// Create a new diagonal matrix and initialize each diagonal value using the provided init function. + /// + public static DiagonalMatrix Create(int rows, int columns, Func init) + { + return new DiagonalMatrix(DiagonalMatrixStorage.OfInit(rows, columns, init)); + } + + /// + /// Create a new diagonal matrix with diagonal values sampled from the provided random distribution. + /// + public static DiagonalMatrix CreateRandom(int rows, int columns, IContinuousDistribution distribution) + { + return new DiagonalMatrix(DiagonalMatrixStorage.OfInit(rows, columns, + i => new Complex(distribution.Sample(), distribution.Sample()))); + } + /// /// Create a new diagonal matrix as a copy of the given two-dimensional array. /// This new matrix will be independent from the provided array. diff --git a/src/Numerics/LinearAlgebra/Complex/SparseMatrix.cs b/src/Numerics/LinearAlgebra/Complex/SparseMatrix.cs index 1a99d6ca..1a96c2fe 100644 --- a/src/Numerics/LinearAlgebra/Complex/SparseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Complex/SparseMatrix.cs @@ -136,43 +136,24 @@ namespace MathNet.Numerics.LinearAlgebra.Complex return new SparseMatrix(SparseCompressedRowMatrixStorage.OfColumnMajorList(rows, columns, columnMajor)); } + /// + /// Create a new sparse matrix and initialize each value using the provided init function. + /// + public static SparseMatrix Create(int rows, int columns, Func init) + { + return new SparseMatrix(SparseCompressedRowMatrixStorage.OfInit(rows, columns, init)); + } + /// /// Create a new sparse matrix with the given number of rows and columns. /// All cells of the matrix will be initialized to the provided value. /// Zero-length matrices are not supported. /// /// If the row or column count is less than one. - [Obsolete("Use a dense matrix instead. Scheduled for removal in v3.0.")] + [Obsolete("Use a dense matrix or SparseMatrix.Create instead. Scheduled for removal in v3.0.")] public SparseMatrix(int rows, int columns, Complex value) - : this(rows, columns) + : this(SparseCompressedRowMatrixStorage.OfInit(rows, columns, (i, j) => value)) { - if (value.IsZero()) - { - return; - } - - var rowPointers = _storage.RowPointers; - var valueCount = _storage.ValueCount = rows * columns; - var columnIndices = _storage.ColumnIndices = new int[valueCount]; - var values = _storage.Values = new Complex[valueCount]; - - for (int i = 0, j = 0; i < values.Length; i++, j++) - { - // Reset column position to "0" - if (j == columns) - { - j = 0; - } - - values[i] = value; - columnIndices[i] = j; - } - - // Set proper row pointers - for (var i = 0; i < rowPointers.Length; i++) - { - rowPointers[i] = ((i + 1) * columns) - columns; - } } /// diff --git a/src/Numerics/LinearAlgebra/Complex32/DenseMatrix.cs b/src/Numerics/LinearAlgebra/Complex32/DenseMatrix.cs index 74a7fec9..aa5e147a 100644 --- a/src/Numerics/LinearAlgebra/Complex32/DenseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Complex32/DenseMatrix.cs @@ -138,27 +138,40 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 /// 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). /// This new matrix will be independent from the enumerable. - /// A new memory block will be allocated for storing the vector. + /// A new memory block will be allocated for storing the matrix. /// public static DenseMatrix OfColumnMajor(int rows, int columns, IEnumerable columnMajor) { return new DenseMatrix(DenseColumnMajorMatrixStorage.OfColumnMajorEnumerable(rows, columns, columnMajor)); } + /// + /// Create a new dense matrix and initialize each value using the provided init function. + /// + public static DenseMatrix Create(int rows, int columns, Func init) + { + return new DenseMatrix(DenseColumnMajorMatrixStorage.OfInit(rows, columns, init)); + } + + /// + /// Create a new dense matrix with values sampled from the provided random distribution. + /// + public static DenseMatrix CreateRandom(int rows, int columns, IContinuousDistribution distribution) + { + return new DenseMatrix(DenseColumnMajorMatrixStorage.OfInit(rows, columns, + (i, j) => new Complex32((float) distribution.Sample(), (float) distribution.Sample()))); + } + /// /// Create a new dense matrix with the given number of rows and columns. /// All cells of the matrix will be initialized to the provided value. /// Zero-length matrices are not supported. /// /// If the row or column count is less than one. - [Obsolete("Scheduled for removal in v3.0.")] + [Obsolete("Use DenseMatrix.Create instead. Scheduled for removal in v3.0.")] public DenseMatrix(int rows, int columns, Complex32 value) - : this(rows, columns) + : this(DenseColumnMajorMatrixStorage.OfInit(rows, columns, (i, j) => value)) { - for (var i = 0; i < _values.Length; i++) - { - _values[i] = value; - } } /// @@ -183,19 +196,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 { } - /// - /// Create a new dense matrix with values sampled from the provided random distribution. - /// - public static DenseMatrix CreateRandom(int rows, int columns, IContinuousDistribution distribution) - { - var storage = new DenseColumnMajorMatrixStorage(rows, columns); - for (var i = 0; i < storage.Data.Length; i++) - { - storage.Data[i] = new Complex32((float)distribution.Sample(), (float)distribution.Sample()); - } - return new DenseMatrix(storage); - } - /// /// Gets the matrix's data. /// diff --git a/src/Numerics/LinearAlgebra/Complex32/DiagonalMatrix.cs b/src/Numerics/LinearAlgebra/Complex32/DiagonalMatrix.cs index ecf9d32d..6348a231 100644 --- a/src/Numerics/LinearAlgebra/Complex32/DiagonalMatrix.cs +++ b/src/Numerics/LinearAlgebra/Complex32/DiagonalMatrix.cs @@ -30,6 +30,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 { + using Distributions; using Generic; using Numerics; using Properties; @@ -141,6 +142,23 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 return new DiagonalMatrix(DiagonalMatrixStorage.OfArray(array)); } + /// + /// Create a new diagonal matrix and initialize each diagonal value using the provided init function. + /// + public static DiagonalMatrix Create(int rows, int columns, Func init) + { + return new DiagonalMatrix(DiagonalMatrixStorage.OfInit(rows, columns, init)); + } + + /// + /// Create a new diagonal matrix with diagonal values sampled from the provided random distribution. + /// + public static DiagonalMatrix CreateRandom(int rows, int columns, IContinuousDistribution distribution) + { + return new DiagonalMatrix(DiagonalMatrixStorage.OfInit(rows, columns, + i => new Complex32((float) distribution.Sample(), (float) distribution.Sample()))); + } + /// /// Create a new diagonal matrix as a copy of the given two-dimensional array. /// This new matrix will be independent from the provided array. diff --git a/src/Numerics/LinearAlgebra/Complex32/SparseMatrix.cs b/src/Numerics/LinearAlgebra/Complex32/SparseMatrix.cs index e74277c3..122e1a50 100644 --- a/src/Numerics/LinearAlgebra/Complex32/SparseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Complex32/SparseMatrix.cs @@ -136,43 +136,24 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 return new SparseMatrix(SparseCompressedRowMatrixStorage.OfColumnMajorList(rows, columns, columnMajor)); } + /// + /// Create a new sparse matrix and initialize each value using the provided init function. + /// + public static SparseMatrix Create(int rows, int columns, Func init) + { + return new SparseMatrix(SparseCompressedRowMatrixStorage.OfInit(rows, columns, init)); + } + /// /// Create a new sparse matrix with the given number of rows and columns. /// All cells of the matrix will be initialized to the provided value. /// Zero-length matrices are not supported. /// /// If the row or column count is less than one. - [Obsolete("Use a dense matrix instead. Scheduled for removal in v3.0.")] + [Obsolete("Use a dense matrix or SparseMatrix.Create instead. Scheduled for removal in v3.0.")] public SparseMatrix(int rows, int columns, Complex32 value) - : this(rows, columns) + : this(SparseCompressedRowMatrixStorage.OfInit(rows, columns, (i,j) => value)) { - if (value.IsZero()) - { - return; - } - - var rowPointers = _storage.RowPointers; - var valueCount = _storage.ValueCount = rows * columns; - var columnIndices = _storage.ColumnIndices = new int[valueCount]; - var values = _storage.Values = new Complex32[valueCount]; - - for (int i = 0, j = 0; i < values.Length; i++, j++) - { - // Reset column position to "0" - if (j == columns) - { - j = 0; - } - - values[i] = value; - columnIndices[i] = j; - } - - // Set proper row pointers - for (var i = 0; i < rowPointers.Length; i++) - { - rowPointers[i] = ((i + 1) * columns) - columns; - } } /// diff --git a/src/Numerics/LinearAlgebra/Double/DenseMatrix.cs b/src/Numerics/LinearAlgebra/Double/DenseMatrix.cs index dd7e7590..ee262973 100644 --- a/src/Numerics/LinearAlgebra/Double/DenseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Double/DenseMatrix.cs @@ -140,27 +140,40 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// 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). /// This new matrix will be independent from the enumerable. - /// A new memory block will be allocated for storing the vector. + /// A new memory block will be allocated for storing the matrix. /// public static DenseMatrix OfColumnMajor(int rows, int columns, IEnumerable columnMajor) { return new DenseMatrix(DenseColumnMajorMatrixStorage.OfColumnMajorEnumerable(rows, columns, columnMajor)); } + /// + /// Create a new dense matrix and initialize each value using the provided init function. + /// + public static DenseMatrix Create(int rows, int columns, Func init) + { + return new DenseMatrix(DenseColumnMajorMatrixStorage.OfInit(rows, columns, init)); + } + + /// + /// Create a new dense matrix with values sampled from the provided random distribution. + /// + public static DenseMatrix CreateRandom(int rows, int columns, IContinuousDistribution distribution) + { + return new DenseMatrix(DenseColumnMajorMatrixStorage.OfInit(rows, columns, + (i, j) => distribution.Sample())); + } + /// /// Create a new dense matrix with the given number of rows and columns. /// All cells of the matrix will be initialized to the provided value. /// Zero-length matrices are not supported. /// /// If the row or column count is less than one. - [Obsolete("Scheduled for removal in v3.0.")] + [Obsolete("Use DenseMatrix.Create instead. Scheduled for removal in v3.0.")] public DenseMatrix(int rows, int columns, double value) - : this(rows, columns) + : this(DenseColumnMajorMatrixStorage.OfInit(rows, columns, (i, j) => value)) { - for (var i = 0; i < _values.Length; i++) - { - _values[i] = value; - } } /// @@ -185,19 +198,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double { } - /// - /// Create a new dense matrix with values sampled from the provided random distribution. - /// - public static DenseMatrix CreateRandom(int rows, int columns, IContinuousDistribution distribution) - { - var storage = new DenseColumnMajorMatrixStorage(rows, columns); - for (var i = 0; i < storage.Data.Length; i++) - { - storage.Data[i] = distribution.Sample(); - } - return new DenseMatrix(storage); - } - /// /// Gets the matrix's data. /// diff --git a/src/Numerics/LinearAlgebra/Double/DiagonalMatrix.cs b/src/Numerics/LinearAlgebra/Double/DiagonalMatrix.cs index 312dc04c..e812322b 100644 --- a/src/Numerics/LinearAlgebra/Double/DiagonalMatrix.cs +++ b/src/Numerics/LinearAlgebra/Double/DiagonalMatrix.cs @@ -30,6 +30,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double { + using Distributions; using Generic; using Properties; using Storage; @@ -140,6 +141,23 @@ namespace MathNet.Numerics.LinearAlgebra.Double return new DiagonalMatrix(DiagonalMatrixStorage.OfArray(array)); } + /// + /// Create a new diagonal matrix and initialize each diagonal value using the provided init function. + /// + public static DiagonalMatrix Create(int rows, int columns, Func init) + { + return new DiagonalMatrix(DiagonalMatrixStorage.OfInit(rows, columns, init)); + } + + /// + /// Create a new diagonal matrix with diagonal values sampled from the provided random distribution. + /// + public static DiagonalMatrix CreateRandom(int rows, int columns, IContinuousDistribution distribution) + { + return new DiagonalMatrix(DiagonalMatrixStorage.OfInit(rows, columns, + i => distribution.Sample())); + } + /// /// Create a new diagonal matrix as a copy of the given two-dimensional array. /// This new matrix will be independent from the provided array. diff --git a/src/Numerics/LinearAlgebra/Double/SparseMatrix.cs b/src/Numerics/LinearAlgebra/Double/SparseMatrix.cs index 0ed4c50c..ca0e3792 100644 --- a/src/Numerics/LinearAlgebra/Double/SparseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Double/SparseMatrix.cs @@ -135,43 +135,24 @@ namespace MathNet.Numerics.LinearAlgebra.Double return new SparseMatrix(SparseCompressedRowMatrixStorage.OfColumnMajorList(rows, columns, columnMajor)); } + /// + /// Create a new sparse matrix and initialize each value using the provided init function. + /// + public static SparseMatrix Create(int rows, int columns, Func init) + { + return new SparseMatrix(SparseCompressedRowMatrixStorage.OfInit(rows, columns, init)); + } + /// /// Create a new sparse matrix with the given number of rows and columns. /// All cells of the matrix will be initialized to the provided value. /// Zero-length matrices are not supported. /// /// If the row or column count is less than one. - [Obsolete("Use a dense matrix instead. Scheduled for removal in v3.0.")] + [Obsolete("Use a dense matrix or SparseMatrix.Create instead. Scheduled for removal in v3.0.")] public SparseMatrix(int rows, int columns, double value) - : this(rows, columns) + : this(SparseCompressedRowMatrixStorage.OfInit(rows, columns, (i, j) => value)) { - if (value == 0.0) - { - return; - } - - var rowPointers = _storage.RowPointers; - var valueCount = _storage.ValueCount = rows * columns; - var columnIndices = _storage.ColumnIndices = new int[valueCount]; - var values = _storage.Values = new double[valueCount]; - - for (int i = 0, j = 0; i < values.Length; i++, j++) - { - // Reset column position to "0" - if (j == columns) - { - j = 0; - } - - values[i] = value; - columnIndices[i] = j; - } - - // Set proper row pointers - for (var i = 0; i < rowPointers.Length; i++) - { - rowPointers[i] = ((i + 1) * columns) - columns; - } } /// diff --git a/src/Numerics/LinearAlgebra/Single/DenseMatrix.cs b/src/Numerics/LinearAlgebra/Single/DenseMatrix.cs index 22dcb7ed..9a16110a 100644 --- a/src/Numerics/LinearAlgebra/Single/DenseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Single/DenseMatrix.cs @@ -138,27 +138,40 @@ namespace MathNet.Numerics.LinearAlgebra.Single /// 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). /// This new matrix will be independent from the enumerable. - /// A new memory block will be allocated for storing the vector. + /// A new memory block will be allocated for storing the matrix. /// public static DenseMatrix OfColumnMajor(int rows, int columns, IEnumerable columnMajor) { return new DenseMatrix(DenseColumnMajorMatrixStorage.OfColumnMajorEnumerable(rows, columns, columnMajor)); } + /// + /// Create a new dense matrix and initialize each value using the provided init function. + /// + public static DenseMatrix Create(int rows, int columns, Func init) + { + return new DenseMatrix(DenseColumnMajorMatrixStorage.OfInit(rows, columns, init)); + } + + /// + /// Create a new dense matrix with values sampled from the provided random distribution. + /// + public static DenseMatrix CreateRandom(int rows, int columns, IContinuousDistribution distribution) + { + return new DenseMatrix(DenseColumnMajorMatrixStorage.OfInit(rows, columns, + (i, j) => (float) distribution.Sample())); + } + /// /// Create a new dense matrix with the given number of rows and columns. /// All cells of the matrix will be initialized to the provided value. /// Zero-length matrices are not supported. /// /// If the row or column count is less than one. - [Obsolete("Scheduled for removal in v3.0.")] + [Obsolete("Use DenseMatrix.Create instead. Scheduled for removal in v3.0.")] public DenseMatrix(int rows, int columns, float value) - : this(rows, columns) + : this(DenseColumnMajorMatrixStorage.OfInit(rows, columns, (i, j) => value)) { - for (var i = 0; i < _values.Length; i++) - { - _values[i] = value; - } } /// @@ -183,19 +196,6 @@ namespace MathNet.Numerics.LinearAlgebra.Single { } - /// - /// Create a new dense matrix with values sampled from the provided random distribution. - /// - public static DenseMatrix CreateRandom(int rows, int columns, IContinuousDistribution distribution) - { - var storage = new DenseColumnMajorMatrixStorage(rows, columns); - for (var i = 0; i < storage.Data.Length; i++) - { - storage.Data[i] = (float)distribution.Sample(); - } - return new DenseMatrix(storage); - } - /// /// Gets the matrix's data. /// diff --git a/src/Numerics/LinearAlgebra/Single/DiagonalMatrix.cs b/src/Numerics/LinearAlgebra/Single/DiagonalMatrix.cs index c5e6ad5e..46ea9455 100644 --- a/src/Numerics/LinearAlgebra/Single/DiagonalMatrix.cs +++ b/src/Numerics/LinearAlgebra/Single/DiagonalMatrix.cs @@ -30,6 +30,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single { + using Distributions; using Generic; using Properties; using Storage; @@ -140,6 +141,23 @@ namespace MathNet.Numerics.LinearAlgebra.Single return new DiagonalMatrix(DiagonalMatrixStorage.OfArray(array)); } + /// + /// Create a new diagonal matrix and initialize each diagonal value using the provided init function. + /// + public static DiagonalMatrix Create(int rows, int columns, Func init) + { + return new DiagonalMatrix(DiagonalMatrixStorage.OfInit(rows, columns, init)); + } + + /// + /// Create a new diagonal matrix with diagonal values sampled from the provided random distribution. + /// + public static DiagonalMatrix CreateRandom(int rows, int columns, IContinuousDistribution distribution) + { + return new DiagonalMatrix(DiagonalMatrixStorage.OfInit(rows, columns, + i => (float) distribution.Sample())); + } + /// /// Create a new diagonal matrix as a copy of the given two-dimensional array. /// This new matrix will be independent from the provided array. diff --git a/src/Numerics/LinearAlgebra/Single/SparseMatrix.cs b/src/Numerics/LinearAlgebra/Single/SparseMatrix.cs index 6fdba1f4..f075724c 100644 --- a/src/Numerics/LinearAlgebra/Single/SparseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Single/SparseMatrix.cs @@ -135,43 +135,24 @@ namespace MathNet.Numerics.LinearAlgebra.Single return new SparseMatrix(SparseCompressedRowMatrixStorage.OfColumnMajorList(rows, columns, columnMajor)); } + /// + /// Create a new sparse matrix and initialize each value using the provided init function. + /// + public static SparseMatrix Create(int rows, int columns, Func init) + { + return new SparseMatrix(SparseCompressedRowMatrixStorage.OfInit(rows, columns, init)); + } + /// /// Create a new sparse matrix with the given number of rows and columns. /// All cells of the matrix will be initialized to the provided value. /// Zero-length matrices are not supported. /// /// If the row or column count is less than one. - [Obsolete("Use a dense matrix instead. Scheduled for removal in v3.0.")] + [Obsolete("Use a dense matrix or SparseMatrix.Create instead. Scheduled for removal in v3.0.")] public SparseMatrix(int rows, int columns, float value) - : this(rows, columns) + : this(SparseCompressedRowMatrixStorage.OfInit(rows, columns, (i, j) => value)) { - if (value == 0.0) - { - return; - } - - var rowPointers = _storage.RowPointers; - var valueCount = _storage.ValueCount = rows * columns; - var columnIndices = _storage.ColumnIndices = new int[valueCount]; - var values = _storage.Values = new float[valueCount]; - - for (int i = 0, j = 0; i < values.Length; i++, j++) - { - // Reset column position to "0" - if (j == columns) - { - j = 0; - } - - values[i] = value; - columnIndices[i] = j; - } - - // Set proper row pointers - for (var i = 0; i < rowPointers.Length; i++) - { - rowPointers[i] = ((i + 1) * columns) - columns; - } } /// diff --git a/src/Numerics/LinearAlgebra/Storage/DenseColumnMajorMatrixStorage.cs b/src/Numerics/LinearAlgebra/Storage/DenseColumnMajorMatrixStorage.cs index 74e0784e..10ab5982 100644 --- a/src/Numerics/LinearAlgebra/Storage/DenseColumnMajorMatrixStorage.cs +++ b/src/Numerics/LinearAlgebra/Storage/DenseColumnMajorMatrixStorage.cs @@ -111,11 +111,27 @@ namespace MathNet.Numerics.LinearAlgebra.Storage public static DenseColumnMajorMatrixStorage OfArray(T[,] array) { var storage = new DenseColumnMajorMatrixStorage(array.GetLength(0), array.GetLength(1)); - for (var i = 0; i < storage.RowCount; i++) + int index = 0; + for (var j = 0; j < storage.ColumnCount; j++) { - for (var j = 0; j < storage.ColumnCount; j++) + for (var i = 0; i < storage.RowCount; i++) { - storage.Data[(j * storage.RowCount) + i] = array[i, j]; + storage.Data[index++] = array[i, j]; + } + } + return storage; + } + + public static DenseColumnMajorMatrixStorage OfInit(int rows, int columns, Func init) + { + var storage = new DenseColumnMajorMatrixStorage(rows, columns); + int index = 0; + for (var j = 0; j < storage.ColumnCount; j++) + { + for (var i = 0; i < storage.RowCount; i++) + { + + storage.Data[index++] = init(i, j); } } return storage; diff --git a/src/Numerics/LinearAlgebra/Storage/DiagonalMatrixStorage.cs b/src/Numerics/LinearAlgebra/Storage/DiagonalMatrixStorage.cs index 4980fc15..70a293f5 100644 --- a/src/Numerics/LinearAlgebra/Storage/DiagonalMatrixStorage.cs +++ b/src/Numerics/LinearAlgebra/Storage/DiagonalMatrixStorage.cs @@ -199,6 +199,16 @@ namespace MathNet.Numerics.LinearAlgebra.Storage return storage; } + public static DiagonalMatrixStorage OfInit(int rows, int columns, Func init) + { + var storage = new DiagonalMatrixStorage(rows, columns); + for (var i = 0; i < storage.Data.Length; i++) + { + storage.Data[i] = init(i); + } + 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 8dd33fe5..e13710c1 100644 --- a/src/Numerics/LinearAlgebra/Storage/SparseCompressedRowMatrixStorage.cs +++ b/src/Numerics/LinearAlgebra/Storage/SparseCompressedRowMatrixStorage.cs @@ -401,6 +401,33 @@ namespace MathNet.Numerics.LinearAlgebra.Storage return storage; } + public static SparseCompressedRowMatrixStorage OfInit(int rows, int columns, Func init) + { + var storage = new SparseCompressedRowMatrixStorage(rows, columns); + var rowPointers = storage.RowPointers; + var columnIndices = new List(); + var values = new List(); + + for (int row = 0; row < rows; row++) + { + rowPointers[row] = values.Count; + for (int col = 0; col < columns; col++) + { + var item = init(row, col); + if (!Zero.Equals(item)) + { + values.Add(item); + columnIndices.Add(col); + } + } + } + + 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)