diff --git a/src/Numerics/LinearAlgebra/Complex/DenseMatrix.cs b/src/Numerics/LinearAlgebra/Complex/DenseMatrix.cs index 57f10f58..e1afd250 100644 --- a/src/Numerics/LinearAlgebra/Complex/DenseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Complex/DenseMatrix.cs @@ -172,16 +172,13 @@ namespace MathNet.Numerics.LinearAlgebra.Complex /// /// Creates a DenseMatrix for the given number of rows and columns. /// - /// - /// The number of rows. - /// - /// - /// The number of columns. - /// + /// The number of rows. + /// The number of columns. + /// True if all fields must be mutable (e.g. not a diagonal matrix). /// /// A DenseMatrix with the given dimensions. /// - public override Matrix CreateMatrix(int numberOfRows, int numberOfColumns) + public override Matrix CreateMatrix(int numberOfRows, int numberOfColumns, bool fullyMutable = false) { return new DenseMatrix(numberOfRows, numberOfColumns); } @@ -190,10 +187,11 @@ namespace MathNet.Numerics.LinearAlgebra.Complex /// Creates a with a the given dimension. /// /// The size of the vector. + /// True if all fields must be mutable. /// /// A with the given dimension. /// - public override Vector CreateVector(int size) + public override Vector CreateVector(int size, bool fullyMutable = false) { return new DenseVector(size); } diff --git a/src/Numerics/LinearAlgebra/Complex/DiagonalMatrix.cs b/src/Numerics/LinearAlgebra/Complex/DiagonalMatrix.cs index 214a5a87..805720e7 100644 --- a/src/Numerics/LinearAlgebra/Complex/DiagonalMatrix.cs +++ b/src/Numerics/LinearAlgebra/Complex/DiagonalMatrix.cs @@ -163,18 +163,17 @@ namespace MathNet.Numerics.LinearAlgebra.Complex /// /// Creates a DiagonalMatrix for the given number of rows and columns. /// - /// - /// The number of rows. - /// - /// - /// The number of columns. - /// + /// The number of rows. + /// The number of columns. + /// True if all fields must be mutable (e.g. not a diagonal matrix). /// /// A DiagonalMatrix with the given dimensions. /// - public override Matrix CreateMatrix(int numberOfRows, int numberOfColumns) + public override Matrix CreateMatrix(int numberOfRows, int numberOfColumns, bool fullyMutable = false) { - return new DiagonalMatrix(numberOfRows, numberOfColumns); + return fullyMutable + ? (Matrix) new SparseMatrix(numberOfRows, numberOfColumns) + : new DiagonalMatrix(numberOfRows, numberOfColumns); } /// @@ -184,7 +183,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex /// /// A with the given dimension. /// - public override Vector CreateVector(int size) + public override Vector CreateVector(int size, bool fullyMutable = false) { return new SparseVector(size); } @@ -1136,204 +1135,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex return result; } - /// - /// Stacks this matrix on top of the given matrix and places the result into the result . - /// - /// The matrix to stack this matrix upon. - /// The combined . - /// If lower is . - /// If upper.Columns != lower.Columns. - public override Matrix Stack(Matrix lower) - { - if (lower == null) - { - throw new ArgumentNullException("lower"); - } - - if (lower.ColumnCount != ColumnCount) - { - throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension, "lower"); - } - - var result = new SparseMatrix(RowCount + lower.RowCount, ColumnCount); - Stack(lower, result); - return result; - } - - /// - /// Stacks this matrix on top of the given matrix and places the result into the result . - /// - /// The matrix to stack this matrix upon. - /// The combined . - /// If lower is . - /// If upper.Columns != lower.Columns. - public override void Stack(Matrix lower, Matrix result) - { - if (lower == null) - { - throw new ArgumentNullException("lower"); - } - - if (lower.ColumnCount != ColumnCount) - { - throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension, "lower"); - } - - if (result == null) - { - throw new ArgumentNullException("result"); - } - - if (result.RowCount != (RowCount + lower.RowCount) || result.ColumnCount != ColumnCount) - { - throw DimensionsDontMatch(this, result, "result"); - } - - // Clear the result matrix - result.Clear(); - - // Copy the diagonal part into the result matrix. - for (var i = 0; i < _data.Length; i++) - { - result.At(i, i, _data[i]); - } - - // Copy the lower matrix into the result matrix. - for (var i = 0; i < lower.RowCount; i++) - { - for (var j = 0; j < lower.ColumnCount; j++) - { - result.At(i + RowCount, j, lower.At(i, j)); - } - } - } - - /// - /// Concatenates this matrix with the given matrix. - /// - /// The matrix to concatenate. - /// The combined . - public override Matrix Append(Matrix right) - { - if (right == null) - { - throw new ArgumentNullException("right"); - } - - if (right.RowCount != RowCount) - { - throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension); - } - - var result = new SparseMatrix(RowCount, ColumnCount + right.ColumnCount); - Append(right, result); - return result; - } - - /// - /// Concatenates this matrix with the given matrix and places the result into the result . - /// - /// The matrix to concatenate. - /// The combined . - public override void Append(Matrix right, Matrix result) - { - if (right == null) - { - throw new ArgumentNullException("right"); - } - - if (right.RowCount != RowCount) - { - throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension); - } - - if (result == null) - { - throw new ArgumentNullException("result"); - } - - if (result.ColumnCount != (ColumnCount + right.ColumnCount) || result.RowCount != RowCount) - { - throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension); - } - - // Clear the result matrix - result.Clear(); - - // Copy the diagonal part into the result matrix. - for (var i = 0; i < _data.Length; i++) - { - result.At(i, i, _data[i]); - } - - // Copy the lower matrix into the result matrix. - for (var i = 0; i < right.RowCount; i++) - { - for (var j = 0; j < right.ColumnCount; j++) - { - result.At(i, j + RowCount, right.At(i, j)); - } - } - } - - /// - /// Diagonally stacks his matrix on top of the given matrix. The new matrix is a M-by-N matrix, - /// where M = this.Rows + lower.Rows and N = this.Columns + lower.Columns. - /// The values of off the off diagonal matrices/blocks are set to zero. - /// - /// The lower, right matrix. - /// If lower is . - /// the combined matrix - public override Matrix DiagonalStack(Matrix lower) - { - if (lower == null) - { - throw new ArgumentNullException("lower"); - } - - var result = new SparseMatrix(RowCount + lower.RowCount, ColumnCount + lower.ColumnCount); - DiagonalStack(lower, result); - return result; - } - - /// - /// Diagonally stacks his matrix on top of the given matrix and places the combined matrix into the result matrix. - /// - /// The lower, right matrix. - /// The combined matrix - /// If lower is . - /// If the result matrix is . - /// If the result matrix's dimensions are not (this.Rows + lower.rows) x (this.Columns + lower.Columns). - public override void DiagonalStack(Matrix lower, Matrix result) - { - if (lower == null) - { - throw new ArgumentNullException("lower"); - } - - if (result == null) - { - throw new ArgumentNullException("result"); - } - - if (result.RowCount != RowCount + lower.RowCount || result.ColumnCount != ColumnCount + lower.ColumnCount) - { - throw DimensionsDontMatch(this, result, "result"); - } - - // Clear the result matrix - result.Clear(); - - // Copy the diagonal part into the result matrix. - for (var i = 0; i < _data.Length; i++) - { - result.At(i, i, _data[i]); - } - - // Copy the lower matrix into the result matrix. - result.SetSubMatrix(RowCount, lower.RowCount, ColumnCount, lower.ColumnCount, lower); - } - /// /// Permute the columns of a matrix according to a permutation. /// diff --git a/src/Numerics/LinearAlgebra/Complex/SparseMatrix.cs b/src/Numerics/LinearAlgebra/Complex/SparseMatrix.cs index 6e7275a2..50d30bc6 100644 --- a/src/Numerics/LinearAlgebra/Complex/SparseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Complex/SparseMatrix.cs @@ -190,16 +190,13 @@ namespace MathNet.Numerics.LinearAlgebra.Complex /// /// Creates a SparseMatrix for the given number of rows and columns. /// - /// - /// The number of rows. - /// - /// - /// The number of columns. - /// + /// The number of rows. + /// The number of columns. + /// True if all fields must be mutable (e.g. not a diagonal matrix). /// /// A SparseMatrix with the given dimensions. /// - public override Matrix CreateMatrix(int numberOfRows, int numberOfColumns) + public override Matrix CreateMatrix(int numberOfRows, int numberOfColumns, bool fullyMutable = false) { return new SparseMatrix(numberOfRows, numberOfColumns); } @@ -208,10 +205,11 @@ namespace MathNet.Numerics.LinearAlgebra.Complex /// Creates a with a the given dimension. /// /// The size of the vector. + /// True if all fields must be mutable. /// /// A with the given dimension. /// - public override Vector CreateVector(int size) + public override Vector CreateVector(int size, bool fullyMutable = false) { return new SparseVector(size); } @@ -690,56 +688,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex } } - /// - /// Diagonally stacks this matrix on top of the given matrix and places the combined matrix into the result matrix. - /// - /// The lower, right matrix. - /// The combined matrix - /// If lower is . - /// If the result matrix is . - /// If the result matrix's dimensions are not (Rows + lower.rows) x (Columns + lower.Columns). - public override void DiagonalStack(Matrix lower, Matrix result) - { - var lowerSparseMatrix = lower as SparseMatrix; - var resultSparseMatrix = result as SparseMatrix; - - if ((lowerSparseMatrix == null) || (resultSparseMatrix == null)) - { - base.DiagonalStack(lower, result); - } - else - { - var resultStorage = resultSparseMatrix.Raw; - var lowerStorage = lowerSparseMatrix.Raw; - - if (resultSparseMatrix.RowCount != RowCount + lowerSparseMatrix.RowCount || resultSparseMatrix.ColumnCount != ColumnCount + lowerSparseMatrix.ColumnCount) - { - throw DimensionsDontMatch(this, resultSparseMatrix, lowerSparseMatrix); - } - - resultStorage.ValueCount = _storage.ValueCount + lowerStorage.ValueCount; - resultStorage.Values = new Complex[resultStorage.ValueCount]; - resultStorage.ColumnIndices = new int[resultStorage.ValueCount]; - - Array.Copy(_storage.Values, 0, resultStorage.Values, 0, _storage.ValueCount); - Array.Copy(lowerStorage.Values, 0, resultStorage.Values, _storage.ValueCount, lowerStorage.ValueCount); - - Array.Copy(_storage.ColumnIndices, 0, resultStorage.ColumnIndices, 0, _storage.ValueCount); - Array.Copy(_storage.RowPointers, 0, resultStorage.RowPointers, 0, RowCount); - - // Copy and adjust lower column indices and rowIndex - for (int i = _storage.ValueCount, j = 0; i < resultStorage.ValueCount; i++, j++) - { - resultStorage.ColumnIndices[i] = lowerStorage.ColumnIndices[j] + ColumnCount; - } - - for (int i = RowCount, j = 0; i < resultStorage.RowCount; i++, j++) - { - resultStorage.RowPointers[i] = lowerStorage.RowPointers[j] + _storage.ValueCount; - } - } - } - #region Static constructors for special matrices. /// /// Initializes a square with all zero's except for ones on the diagonal. diff --git a/src/Numerics/LinearAlgebra/Complex32/DenseMatrix.cs b/src/Numerics/LinearAlgebra/Complex32/DenseMatrix.cs index 8fe6314f..614f4cd8 100644 --- a/src/Numerics/LinearAlgebra/Complex32/DenseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Complex32/DenseMatrix.cs @@ -172,16 +172,13 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 /// /// Creates a DenseMatrix for the given number of rows and columns. /// - /// - /// The number of rows. - /// - /// - /// The number of columns. - /// + /// The number of rows. + /// The number of columns. + /// True if all fields must be mutable (e.g. not a diagonal matrix). /// /// A DenseMatrix with the given dimensions. /// - public override Matrix CreateMatrix(int numberOfRows, int numberOfColumns) + public override Matrix CreateMatrix(int numberOfRows, int numberOfColumns, bool fullyMutable = false) { return new DenseMatrix(numberOfRows, numberOfColumns); } @@ -190,10 +187,11 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 /// Creates a with a the given dimension. /// /// The size of the vector. + /// True if all fields must be mutable. /// /// A with the given dimension. /// - public override Vector CreateVector(int size) + public override Vector CreateVector(int size, bool fullyMutable = false) { return new DenseVector(size); } diff --git a/src/Numerics/LinearAlgebra/Complex32/DiagonalMatrix.cs b/src/Numerics/LinearAlgebra/Complex32/DiagonalMatrix.cs index 400d3f50..4c511431 100644 --- a/src/Numerics/LinearAlgebra/Complex32/DiagonalMatrix.cs +++ b/src/Numerics/LinearAlgebra/Complex32/DiagonalMatrix.cs @@ -163,18 +163,17 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 /// /// Creates a DiagonalMatrix for the given number of rows and columns. /// - /// - /// The number of rows. - /// - /// - /// The number of columns. - /// + /// The number of rows. + /// The number of columns. + /// True if all fields must be mutable (e.g. not a diagonal matrix). /// /// A DiagonalMatrix with the given dimensions. /// - public override Matrix CreateMatrix(int numberOfRows, int numberOfColumns) + public override Matrix CreateMatrix(int numberOfRows, int numberOfColumns, bool fullyMutable = false) { - return new DiagonalMatrix(numberOfRows, numberOfColumns); + return fullyMutable + ? (Matrix) new SparseMatrix(numberOfRows, numberOfColumns) + : new DiagonalMatrix(numberOfRows, numberOfColumns); } /// @@ -184,7 +183,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 /// /// A with the given dimension. /// - public override Vector CreateVector(int size) + public override Vector CreateVector(int size, bool fullyMutable = false) { return new SparseVector(size); } @@ -1136,204 +1135,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 return result; } - /// - /// Stacks this matrix on top of the given matrix and places the result into the result . - /// - /// The matrix to stack this matrix upon. - /// The combined . - /// If lower is . - /// If upper.Columns != lower.Columns. - public override Matrix Stack(Matrix lower) - { - if (lower == null) - { - throw new ArgumentNullException("lower"); - } - - if (lower.ColumnCount != ColumnCount) - { - throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension, "lower"); - } - - var result = new SparseMatrix(RowCount + lower.RowCount, ColumnCount); - Stack(lower, result); - return result; - } - - /// - /// Stacks this matrix on top of the given matrix and places the result into the result . - /// - /// The matrix to stack this matrix upon. - /// The combined . - /// If lower is . - /// If upper.Columns != lower.Columns. - public override void Stack(Matrix lower, Matrix result) - { - if (lower == null) - { - throw new ArgumentNullException("lower"); - } - - if (lower.ColumnCount != ColumnCount) - { - throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension, "lower"); - } - - if (result == null) - { - throw new ArgumentNullException("result"); - } - - if (result.RowCount != (RowCount + lower.RowCount) || result.ColumnCount != ColumnCount) - { - throw DimensionsDontMatch(this, lower, result); - } - - // Clear the result matrix - result.Clear(); - - // Copy the diagonal part into the result matrix. - for (var i = 0; i < _data.Length; i++) - { - result.At(i, i, _data[i]); - } - - // Copy the lower matrix into the result matrix. - for (var i = 0; i < lower.RowCount; i++) - { - for (var j = 0; j < lower.ColumnCount; j++) - { - result.At(i + RowCount, j, lower.At(i, j)); - } - } - } - - /// - /// Concatenates this matrix with the given matrix. - /// - /// The matrix to concatenate. - /// The combined . - public override Matrix Append(Matrix right) - { - if (right == null) - { - throw new ArgumentNullException("right"); - } - - if (right.RowCount != RowCount) - { - throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension); - } - - var result = new SparseMatrix(RowCount, ColumnCount + right.ColumnCount); - Append(right, result); - return result; - } - - /// - /// Concatenates this matrix with the given matrix and places the result into the result . - /// - /// The matrix to concatenate. - /// The combined . - public override void Append(Matrix right, Matrix result) - { - if (right == null) - { - throw new ArgumentNullException("right"); - } - - if (right.RowCount != RowCount) - { - throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension); - } - - if (result == null) - { - throw new ArgumentNullException("result"); - } - - if (result.ColumnCount != (ColumnCount + right.ColumnCount) || result.RowCount != RowCount) - { - throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension); - } - - // Clear the result matrix - result.Clear(); - - // Copy the diagonal part into the result matrix. - for (var i = 0; i < _data.Length; i++) - { - result.At(i, i, _data[i]); - } - - // Copy the lower matrix into the result matrix. - for (var i = 0; i < right.RowCount; i++) - { - for (var j = 0; j < right.ColumnCount; j++) - { - result.At(i, j + RowCount, right.At(i, j)); - } - } - } - - /// - /// Diagonally stacks his matrix on top of the given matrix. The new matrix is a M-by-N matrix, - /// where M = this.Rows + lower.Rows and N = this.Columns + lower.Columns. - /// The values of off the off diagonal matrices/blocks are set to zero. - /// - /// The lower, right matrix. - /// If lower is . - /// the combined matrix - public override Matrix DiagonalStack(Matrix lower) - { - if (lower == null) - { - throw new ArgumentNullException("lower"); - } - - var result = new SparseMatrix(RowCount + lower.RowCount, ColumnCount + lower.ColumnCount); - DiagonalStack(lower, result); - return result; - } - - /// - /// Diagonally stacks his matrix on top of the given matrix and places the combined matrix into the result matrix. - /// - /// The lower, right matrix. - /// The combined matrix - /// If lower is . - /// If the result matrix is . - /// If the result matrix's dimensions are not (this.Rows + lower.rows) x (this.Columns + lower.Columns). - public override void DiagonalStack(Matrix lower, Matrix result) - { - if (lower == null) - { - throw new ArgumentNullException("lower"); - } - - if (result == null) - { - throw new ArgumentNullException("result"); - } - - if (result.RowCount != RowCount + lower.RowCount || result.ColumnCount != ColumnCount + lower.ColumnCount) - { - throw DimensionsDontMatch(this, lower, result); - } - - // Clear the result matrix - result.Clear(); - - // Copy the diagonal part into the result matrix. - for (var i = 0; i < _data.Length; i++) - { - result.At(i, i, _data[i]); - } - - // Copy the lower matrix into the result matrix. - result.SetSubMatrix(RowCount, lower.RowCount, ColumnCount, lower.ColumnCount, lower); - } - /// /// Permute the columns of a matrix according to a permutation. /// diff --git a/src/Numerics/LinearAlgebra/Complex32/SparseMatrix.cs b/src/Numerics/LinearAlgebra/Complex32/SparseMatrix.cs index 8164cb4b..f780d53a 100644 --- a/src/Numerics/LinearAlgebra/Complex32/SparseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Complex32/SparseMatrix.cs @@ -190,16 +190,13 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 /// /// Creates a SparseMatrix for the given number of rows and columns. /// - /// - /// The number of rows. - /// - /// - /// The number of columns. - /// + /// The number of rows. + /// The number of columns. + /// True if all fields must be mutable (e.g. not a diagonal matrix). /// /// A SparseMatrix with the given dimensions. /// - public override Matrix CreateMatrix(int numberOfRows, int numberOfColumns) + public override Matrix CreateMatrix(int numberOfRows, int numberOfColumns, bool fullyMutable = false) { return new SparseMatrix(numberOfRows, numberOfColumns); } @@ -208,10 +205,11 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 /// Creates a with a the given dimension. /// /// The size of the vector. + /// True if all fields must be mutable. /// /// A with the given dimension. /// - public override Vector CreateVector(int size) + public override Vector CreateVector(int size, bool fullyMutable = false) { return new SparseVector(size); } @@ -690,56 +688,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 } } - /// - /// Diagonally stacks this matrix on top of the given matrix and places the combined matrix into the result matrix. - /// - /// The lower, right matrix. - /// The combined matrix - /// If lower is . - /// If the result matrix is . - /// If the result matrix's dimensions are not (Rows + lower.rows) x (Columns + lower.Columns). - public override void DiagonalStack(Matrix lower, Matrix result) - { - var lowerSparseMatrix = lower as SparseMatrix; - var resultSparseMatrix = result as SparseMatrix; - - if ((lowerSparseMatrix == null) || (resultSparseMatrix == null)) - { - base.DiagonalStack(lower, result); - } - else - { - var resultStorage = resultSparseMatrix.Raw; - var lowerStorage = lowerSparseMatrix.Raw; - - if (resultSparseMatrix.RowCount != RowCount + lowerSparseMatrix.RowCount || resultSparseMatrix.ColumnCount != ColumnCount + lowerSparseMatrix.ColumnCount) - { - throw DimensionsDontMatch(this, resultSparseMatrix, lowerSparseMatrix); - } - - resultStorage.ValueCount = _storage.ValueCount + lowerStorage.ValueCount; - resultStorage.Values = new Complex32[resultStorage.ValueCount]; - resultStorage.ColumnIndices = new int[resultStorage.ValueCount]; - - Array.Copy(_storage.Values, 0, resultStorage.Values, 0, _storage.ValueCount); - Array.Copy(lowerStorage.Values, 0, resultStorage.Values, _storage.ValueCount, lowerStorage.ValueCount); - - Array.Copy(_storage.ColumnIndices, 0, resultStorage.ColumnIndices, 0, _storage.ValueCount); - Array.Copy(_storage.RowPointers, 0, resultStorage.RowPointers, 0, RowCount); - - // Copy and adjust lower column indices and rowIndex - for (int i = _storage.ValueCount, j = 0; i < resultStorage.ValueCount; i++, j++) - { - resultStorage.ColumnIndices[i] = lowerStorage.ColumnIndices[j] + ColumnCount; - } - - for (int i = RowCount, j = 0; i < resultStorage.RowCount; i++, j++) - { - resultStorage.RowPointers[i] = lowerStorage.RowPointers[j] + _storage.ValueCount; - } - } - } - #region Static constructors for special matrices. /// /// Initializes a square with all zero's except for ones on the diagonal. diff --git a/src/Numerics/LinearAlgebra/Double/DenseMatrix.cs b/src/Numerics/LinearAlgebra/Double/DenseMatrix.cs index 16756af5..50007cd9 100644 --- a/src/Numerics/LinearAlgebra/Double/DenseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Double/DenseMatrix.cs @@ -172,16 +172,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// /// Creates a DenseMatrix for the given number of rows and columns. /// - /// - /// The number of rows. - /// - /// - /// The number of columns. - /// + /// The number of rows. + /// The number of columns. + /// True if all fields must be mutable (e.g. not a diagonal matrix). /// /// A DenseMatrix with the given dimensions. /// - public override Matrix CreateMatrix(int numberOfRows, int numberOfColumns) + public override Matrix CreateMatrix(int numberOfRows, int numberOfColumns, bool fullyMutable = false) { return new DenseMatrix(numberOfRows, numberOfColumns); } @@ -190,10 +187,11 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// Creates a with a the given dimension. /// /// The size of the vector. + /// True if all fields must be mutable. /// /// A with the given dimension. /// - public override Vector CreateVector(int size) + public override Vector CreateVector(int size, bool fullyMutable = false) { return new DenseVector(size); } diff --git a/src/Numerics/LinearAlgebra/Double/DiagonalMatrix.cs b/src/Numerics/LinearAlgebra/Double/DiagonalMatrix.cs index 4ef3b400..c0da0aa4 100644 --- a/src/Numerics/LinearAlgebra/Double/DiagonalMatrix.cs +++ b/src/Numerics/LinearAlgebra/Double/DiagonalMatrix.cs @@ -162,18 +162,17 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// /// Creates a DiagonalMatrix for the given number of rows and columns. /// - /// - /// The number of rows. - /// - /// - /// The number of columns. - /// + /// The number of rows. + /// The number of columns. + /// True if all fields must be mutable (e.g. not a diagonal matrix). /// /// A DiagonalMatrix with the given dimensions. /// - public override Matrix CreateMatrix(int numberOfRows, int numberOfColumns) + public override Matrix CreateMatrix(int numberOfRows, int numberOfColumns, bool fullyMutable = false) { - return new DiagonalMatrix(numberOfRows, numberOfColumns); + return fullyMutable + ? (Matrix) new SparseMatrix(numberOfRows, numberOfColumns) + : new DiagonalMatrix(numberOfRows, numberOfColumns); } /// @@ -183,7 +182,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// /// A with the given dimension. /// - public override Vector CreateVector(int size) + public override Vector CreateVector(int size, bool fullyMutable = false) { return new SparseVector(size); } @@ -1130,204 +1129,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double return result; } - /// - /// Stacks this matrix on top of the given matrix and places the result into the result . - /// - /// The matrix to stack this matrix upon. - /// The combined . - /// If lower is . - /// If upper.Columns != lower.Columns. - public override Matrix Stack(Matrix lower) - { - if (lower == null) - { - throw new ArgumentNullException("lower"); - } - - if (lower.ColumnCount != ColumnCount) - { - throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension, "lower"); - } - - var result = new SparseMatrix(RowCount + lower.RowCount, ColumnCount); - Stack(lower, result); - return result; - } - - /// - /// Stacks this matrix on top of the given matrix and places the result into the result . - /// - /// The matrix to stack this matrix upon. - /// The combined . - /// If lower is . - /// If upper.Columns != lower.Columns. - public override void Stack(Matrix lower, Matrix result) - { - if (lower == null) - { - throw new ArgumentNullException("lower"); - } - - if (lower.ColumnCount != ColumnCount) - { - throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension, "lower"); - } - - if (result == null) - { - throw new ArgumentNullException("result"); - } - - if (result.RowCount != (RowCount + lower.RowCount) || result.ColumnCount != ColumnCount) - { - throw DimensionsDontMatch(this, lower, result); - } - - // Clear the result matrix - result.Clear(); - - // Copy the diagonal part into the result matrix. - for (var i = 0; i < _data.Length; i++) - { - result.At(i, i, _data[i]); - } - - // Copy the lower matrix into the result matrix. - for (var i = 0; i < lower.RowCount; i++) - { - for (var j = 0; j < lower.ColumnCount; j++) - { - result.At(i + RowCount, j, lower.At(i, j)); - } - } - } - - /// - /// Concatenates this matrix with the given matrix. - /// - /// The matrix to concatenate. - /// The combined . - public override Matrix Append(Matrix right) - { - if (right == null) - { - throw new ArgumentNullException("right"); - } - - if (right.RowCount != RowCount) - { - throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension); - } - - var result = new SparseMatrix(RowCount, ColumnCount + right.ColumnCount); - Append(right, result); - return result; - } - - /// - /// Concatenates this matrix with the given matrix and places the result into the result . - /// - /// The matrix to concatenate. - /// The combined . - public override void Append(Matrix right, Matrix result) - { - if (right == null) - { - throw new ArgumentNullException("right"); - } - - if (right.RowCount != RowCount) - { - throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension); - } - - if (result == null) - { - throw new ArgumentNullException("result"); - } - - if (result.ColumnCount != (ColumnCount + right.ColumnCount) || result.RowCount != RowCount) - { - throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension); - } - - // Clear the result matrix - result.Clear(); - - // Copy the diagonal part into the result matrix. - for (var i = 0; i < _data.Length; i++) - { - result.At(i, i, _data[i]); - } - - // Copy the lower matrix into the result matrix. - for (var i = 0; i < right.RowCount; i++) - { - for (var j = 0; j < right.ColumnCount; j++) - { - result.At(i, j + RowCount, right.At(i, j)); - } - } - } - - /// - /// Diagonally stacks his matrix on top of the given matrix. The new matrix is a M-by-N matrix, - /// where M = this.Rows + lower.Rows and N = this.Columns + lower.Columns. - /// The values of off the off diagonal matrices/blocks are set to zero. - /// - /// The lower, right matrix. - /// If lower is . - /// the combined matrix - public override Matrix DiagonalStack(Matrix lower) - { - if (lower == null) - { - throw new ArgumentNullException("lower"); - } - - var result = new SparseMatrix(RowCount + lower.RowCount, ColumnCount + lower.ColumnCount); - DiagonalStack(lower, result); - return result; - } - - /// - /// Diagonally stacks his matrix on top of the given matrix and places the combined matrix into the result matrix. - /// - /// The lower, right matrix. - /// The combined matrix - /// If lower is . - /// If the result matrix is . - /// If the result matrix's dimensions are not (this.Rows + lower.rows) x (this.Columns + lower.Columns). - public override void DiagonalStack(Matrix lower, Matrix result) - { - if (lower == null) - { - throw new ArgumentNullException("lower"); - } - - if (result == null) - { - throw new ArgumentNullException("result"); - } - - if (result.RowCount != RowCount + lower.RowCount || result.ColumnCount != ColumnCount + lower.ColumnCount) - { - throw DimensionsDontMatch(this, lower, result); - } - - // Clear the result matrix - result.Clear(); - - // Copy the diagonal part into the result matrix. - for (var i = 0; i < _data.Length; i++) - { - result.At(i, i, _data[i]); - } - - // Copy the lower matrix into the result matrix. - result.SetSubMatrix(RowCount, lower.RowCount, ColumnCount, lower.ColumnCount, lower); - } - /// /// Permute the columns of a matrix according to a permutation. /// diff --git a/src/Numerics/LinearAlgebra/Double/SparseMatrix.cs b/src/Numerics/LinearAlgebra/Double/SparseMatrix.cs index 8b9cf66a..e8cbbc09 100644 --- a/src/Numerics/LinearAlgebra/Double/SparseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Double/SparseMatrix.cs @@ -189,16 +189,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// /// Creates a SparseMatrix for the given number of rows and columns. /// - /// - /// The number of rows. - /// - /// - /// The number of columns. - /// + /// The number of rows. + /// The number of columns. + /// True if all fields must be mutable (e.g. not a diagonal matrix). /// /// A SparseMatrix with the given dimensions. /// - public override Matrix CreateMatrix(int numberOfRows, int numberOfColumns) + public override Matrix CreateMatrix(int numberOfRows, int numberOfColumns, bool fullyMutable = false) { return new SparseMatrix(numberOfRows, numberOfColumns); } @@ -207,10 +204,11 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// Creates a with a the given dimension. /// /// The size of the vector. + /// True if all fields must be mutable. /// /// A with the given dimension. /// - public override Vector CreateVector(int size) + public override Vector CreateVector(int size, bool fullyMutable = false) { return new SparseVector(size); } @@ -688,56 +686,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double } } - /// - /// Diagonally stacks this matrix on top of the given matrix and places the combined matrix into the result matrix. - /// - /// The lower, right matrix. - /// The combined matrix - /// If lower is . - /// If the result matrix is . - /// If the result matrix's dimensions are not (Rows + lower.rows) x (Columns + lower.Columns). - public override void DiagonalStack(Matrix lower, Matrix result) - { - var lowerSparseMatrix = lower as SparseMatrix; - var resultSparseMatrix = result as SparseMatrix; - - if ((lowerSparseMatrix == null) || (resultSparseMatrix == null)) - { - base.DiagonalStack(lower, result); - } - else - { - var resultStorage = resultSparseMatrix.Raw; - var lowerStorage = lowerSparseMatrix.Raw; - - if (resultStorage.RowCount != RowCount + lowerStorage.RowCount || resultStorage.ColumnCount != ColumnCount + lowerSparseMatrix.ColumnCount) - { - throw DimensionsDontMatch(this, lowerSparseMatrix, resultSparseMatrix); - } - - resultStorage.ValueCount = _storage.ValueCount + lowerStorage.ValueCount; - resultStorage.Values = new double[resultStorage.ValueCount]; - resultStorage.ColumnIndices = new int[resultStorage.ValueCount]; - - Array.Copy(_storage.Values, 0, resultStorage.Values, 0, _storage.ValueCount); - Array.Copy(lowerStorage.Values, 0, resultStorage.Values, _storage.ValueCount, lowerStorage.ValueCount); - - Array.Copy(_storage.ColumnIndices, 0, resultStorage.ColumnIndices, 0, _storage.ValueCount); - Array.Copy(_storage.RowPointers, 0, resultStorage.RowPointers, 0, RowCount); - - // Copy and adjust lower column indices and rowIndex - for (int i = _storage.ValueCount, j = 0; i < resultStorage.ValueCount; i++, j++) - { - resultStorage.ColumnIndices[i] = lowerStorage.ColumnIndices[j] + ColumnCount; - } - - for (int i = RowCount, j = 0; i < resultStorage.RowCount; i++, j++) - { - resultStorage.RowPointers[i] = lowerStorage.RowPointers[j] + _storage.ValueCount; - } - } - } - #region Static constructors for special matrices. /// /// Initializes a square with all zero's except for ones on the diagonal. diff --git a/src/Numerics/LinearAlgebra/Generic/Matrix.cs b/src/Numerics/LinearAlgebra/Generic/Matrix.cs index 0c230c1a..d95d2f76 100644 --- a/src/Numerics/LinearAlgebra/Generic/Matrix.cs +++ b/src/Numerics/LinearAlgebra/Generic/Matrix.cs @@ -261,31 +261,29 @@ namespace MathNet.Numerics.LinearAlgebra.Generic /// /// Creates a Matrix for the given number of rows and columns. /// - /// - /// The number of rows. - /// - /// - /// The number of columns. - /// + /// The number of rows. + /// The number of columns. + /// True if all fields must be mutable (e.g. not a diagonal matrix). /// /// A Matrix with the given dimensions. /// /// /// Creates a matrix of the same matrix type as the current matrix. /// - public abstract Matrix CreateMatrix(int numberOfRows, int numberOfColumns); + public abstract Matrix CreateMatrix(int numberOfRows, int numberOfColumns, bool fullyMutable = false); /// /// Creates a Vector with a the given dimension. /// /// The size of the vector. + /// True if all fields must be mutable. /// /// A Vector with the given dimension. /// /// /// Creates a vector of the same type as the current matrix. /// - public abstract Vector CreateVector(int size); + public abstract Vector CreateVector(int size, bool fullyMutable = false); /// /// Returns a that represents this instance. @@ -1070,7 +1068,7 @@ namespace MathNet.Numerics.LinearAlgebra.Generic /// the size of is not at least x . /// If or /// is not positive. - public virtual void SetSubMatrix(int rowIndex, int rowCount, int columnIndex, int columnCount, Matrix subMatrix) + public void SetSubMatrix(int rowIndex, int rowCount, int columnIndex, int columnCount, Matrix subMatrix) { if (subMatrix == null) { @@ -1409,7 +1407,7 @@ namespace MathNet.Numerics.LinearAlgebra.Generic /// /// The matrix to concatenate. /// The combined matrix. - public virtual Matrix Append(Matrix right) + public Matrix Append(Matrix right) { if (right == null) { @@ -1421,8 +1419,9 @@ namespace MathNet.Numerics.LinearAlgebra.Generic throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension); } - var result = CreateMatrix(RowCount, ColumnCount + right.ColumnCount); - Append(right, result); + var result = CreateMatrix(RowCount, ColumnCount + right.ColumnCount, fullyMutable: true); + Storage.CopySubMatrixTo(result.Storage, 0, 0, RowCount, 0, 0, ColumnCount, skipClearing: true); + right.Storage.CopySubMatrixTo(result.Storage, 0, 0, right.RowCount, 0, ColumnCount, right.ColumnCount, skipClearing: true); return result; } @@ -1431,7 +1430,7 @@ namespace MathNet.Numerics.LinearAlgebra.Generic /// /// The matrix to concatenate. /// The combined matrix. - public virtual void Append(Matrix right, Matrix result) + public void Append(Matrix right, Matrix result) { if (right == null) { @@ -1453,8 +1452,8 @@ namespace MathNet.Numerics.LinearAlgebra.Generic throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension); } - result.SetSubMatrix(0, RowCount, 0, ColumnCount, this); - result.SetSubMatrix(0, right.RowCount, ColumnCount, right.ColumnCount, right); + Storage.CopySubMatrixTo(result.Storage, 0, 0, RowCount, 0, 0, ColumnCount); + right.Storage.CopySubMatrixTo(result.Storage, 0, 0, right.RowCount, 0, ColumnCount, right.ColumnCount); } /// @@ -1464,7 +1463,7 @@ namespace MathNet.Numerics.LinearAlgebra.Generic /// The combined matrix. /// If lower is . /// If upper.Columns != lower.Columns. - public virtual Matrix Stack(Matrix lower) + public Matrix Stack(Matrix lower) { if (lower == null) { @@ -1476,8 +1475,9 @@ namespace MathNet.Numerics.LinearAlgebra.Generic throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension, "lower"); } - var result = CreateMatrix(RowCount + lower.RowCount, ColumnCount); - Stack(lower, result); + var result = CreateMatrix(RowCount + lower.RowCount, ColumnCount, fullyMutable: true); + Storage.CopySubMatrixTo(result.Storage, 0, 0, RowCount, 0, 0, ColumnCount, skipClearing: true); + lower.Storage.CopySubMatrixTo(result.Storage, 0, RowCount, lower.RowCount, 0, 0, lower.ColumnCount, skipClearing: true); return result; } @@ -1488,7 +1488,7 @@ namespace MathNet.Numerics.LinearAlgebra.Generic /// The combined matrix. /// If lower is . /// If upper.Columns != lower.Columns. - public virtual void Stack(Matrix lower, Matrix result) + public void Stack(Matrix lower, Matrix result) { if (lower == null) { @@ -1510,8 +1510,8 @@ namespace MathNet.Numerics.LinearAlgebra.Generic throw DimensionsDontMatch(this, result, "result"); } - result.SetSubMatrix(0, RowCount, 0, ColumnCount, this); - result.SetSubMatrix(RowCount, lower.RowCount, 0, lower.ColumnCount, lower); + Storage.CopySubMatrixTo(result.Storage, 0, 0, RowCount, 0, 0, ColumnCount); + lower.Storage.CopySubMatrixTo(result.Storage, 0, RowCount, lower.RowCount, 0, 0, lower.ColumnCount); } /// @@ -1522,15 +1522,16 @@ namespace MathNet.Numerics.LinearAlgebra.Generic /// The lower, right matrix. /// If lower is . /// the combined matrix - public virtual Matrix DiagonalStack(Matrix lower) + public Matrix DiagonalStack(Matrix lower) { if (lower == null) { throw new ArgumentNullException("lower"); } - var result = CreateMatrix(RowCount + lower.RowCount, ColumnCount + lower.ColumnCount); - DiagonalStack(lower, result); + var result = CreateMatrix(RowCount + lower.RowCount, ColumnCount + lower.ColumnCount, fullyMutable: true); + Storage.CopySubMatrixTo(result.Storage, 0, 0, RowCount, 0, 0, ColumnCount); + lower.Storage.CopySubMatrixTo(result.Storage, 0, RowCount, lower.RowCount, 0, ColumnCount, lower.ColumnCount); return result; } @@ -1542,7 +1543,7 @@ namespace MathNet.Numerics.LinearAlgebra.Generic /// If lower is . /// If the result matrix is . /// If the result matrix's dimensions are not (this.Rows + lower.rows) x (this.Columns + lower.Columns). - public virtual void DiagonalStack(Matrix lower, Matrix result) + public void DiagonalStack(Matrix lower, Matrix result) { if (lower == null) { @@ -1559,8 +1560,8 @@ namespace MathNet.Numerics.LinearAlgebra.Generic throw DimensionsDontMatch(this, result, "result"); } - result.SetSubMatrix(0, RowCount, 0, ColumnCount, this); - result.SetSubMatrix(RowCount, lower.RowCount, ColumnCount, lower.ColumnCount, lower); + Storage.CopySubMatrixTo(result.Storage, 0, 0, RowCount, 0, 0, ColumnCount); + lower.Storage.CopySubMatrixTo(result.Storage, 0, RowCount, lower.RowCount, 0, ColumnCount, lower.ColumnCount); } /// Calculates the L1 norm. diff --git a/src/Numerics/LinearAlgebra/Single/DenseMatrix.cs b/src/Numerics/LinearAlgebra/Single/DenseMatrix.cs index 2e4c9463..b2b46989 100644 --- a/src/Numerics/LinearAlgebra/Single/DenseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Single/DenseMatrix.cs @@ -172,16 +172,13 @@ namespace MathNet.Numerics.LinearAlgebra.Single /// /// Creates a DenseMatrix for the given number of rows and columns. /// - /// - /// The number of rows. - /// - /// - /// The number of columns. - /// + /// The number of rows. + /// The number of columns. + /// True if all fields must be mutable (e.g. not a diagonal matrix). /// /// A DenseMatrix with the given dimensions. /// - public override Matrix CreateMatrix(int numberOfRows, int numberOfColumns) + public override Matrix CreateMatrix(int numberOfRows, int numberOfColumns, bool fullyMutable = false) { return new DenseMatrix(numberOfRows, numberOfColumns); } @@ -190,10 +187,11 @@ namespace MathNet.Numerics.LinearAlgebra.Single /// Creates a with a the given dimension. /// /// The size of the vector. + /// True if all fields must be mutable. /// /// A with the given dimension. /// - public override Vector CreateVector(int size) + public override Vector CreateVector(int size, bool fullyMutable = false) { return new DenseVector(size); } diff --git a/src/Numerics/LinearAlgebra/Single/DiagonalMatrix.cs b/src/Numerics/LinearAlgebra/Single/DiagonalMatrix.cs index aa15c269..0ea96a27 100644 --- a/src/Numerics/LinearAlgebra/Single/DiagonalMatrix.cs +++ b/src/Numerics/LinearAlgebra/Single/DiagonalMatrix.cs @@ -162,18 +162,17 @@ namespace MathNet.Numerics.LinearAlgebra.Single /// /// Creates a DiagonalMatrix for the given number of rows and columns. /// - /// - /// The number of rows. - /// - /// - /// The number of columns. - /// + /// The number of rows. + /// The number of columns. + /// True if all fields must be mutable (e.g. not a diagonal matrix). /// /// A DiagonalMatrix with the given dimensions. /// - public override Matrix CreateMatrix(int numberOfRows, int numberOfColumns) + public override Matrix CreateMatrix(int numberOfRows, int numberOfColumns, bool fullyMutable = false) { - return new DiagonalMatrix(numberOfRows, numberOfColumns); + return fullyMutable + ? (Matrix) new SparseMatrix(numberOfRows, numberOfColumns) + : new DiagonalMatrix(numberOfRows, numberOfColumns); } /// @@ -183,7 +182,7 @@ namespace MathNet.Numerics.LinearAlgebra.Single /// /// A with the given dimension. /// - public override Vector CreateVector(int size) + public override Vector CreateVector(int size, bool fullyMutable = false) { return new SparseVector(size); } @@ -1130,204 +1129,6 @@ namespace MathNet.Numerics.LinearAlgebra.Single return result; } - /// - /// Stacks this matrix on top of the given matrix and places the result into the result . - /// - /// The matrix to stack this matrix upon. - /// The combined . - /// If lower is . - /// If upper.Columns != lower.Columns. - public override Matrix Stack(Matrix lower) - { - if (lower == null) - { - throw new ArgumentNullException("lower"); - } - - if (lower.ColumnCount != ColumnCount) - { - throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension, "lower"); - } - - var result = new SparseMatrix(RowCount + lower.RowCount, ColumnCount); - Stack(lower, result); - return result; - } - - /// - /// Stacks this matrix on top of the given matrix and places the result into the result . - /// - /// The matrix to stack this matrix upon. - /// The combined . - /// If lower is . - /// If upper.Columns != lower.Columns. - public override void Stack(Matrix lower, Matrix result) - { - if (lower == null) - { - throw new ArgumentNullException("lower"); - } - - if (lower.ColumnCount != ColumnCount) - { - throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension, "lower"); - } - - if (result == null) - { - throw new ArgumentNullException("result"); - } - - if (result.RowCount != (RowCount + lower.RowCount) || result.ColumnCount != ColumnCount) - { - throw DimensionsDontMatch(this, lower, result); - } - - // Clear the result matrix - result.Clear(); - - // Copy the diagonal part into the result matrix. - for (var i = 0; i < _data.Length; i++) - { - result.At(i, i, _data[i]); - } - - // Copy the lower matrix into the result matrix. - for (var i = 0; i < lower.RowCount; i++) - { - for (var j = 0; j < lower.ColumnCount; j++) - { - result.At(i + RowCount, j, lower.At(i, j)); - } - } - } - - /// - /// Concatenates this matrix with the given matrix. - /// - /// The matrix to concatenate. - /// The combined . - public override Matrix Append(Matrix right) - { - if (right == null) - { - throw new ArgumentNullException("right"); - } - - if (right.RowCount != RowCount) - { - throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension); - } - - var result = new SparseMatrix(RowCount, ColumnCount + right.ColumnCount); - Append(right, result); - return result; - } - - /// - /// Concatenates this matrix with the given matrix and places the result into the result . - /// - /// The matrix to concatenate. - /// The combined . - public override void Append(Matrix right, Matrix result) - { - if (right == null) - { - throw new ArgumentNullException("right"); - } - - if (right.RowCount != RowCount) - { - throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension); - } - - if (result == null) - { - throw new ArgumentNullException("result"); - } - - if (result.ColumnCount != (ColumnCount + right.ColumnCount) || result.RowCount != RowCount) - { - throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension); - } - - // Clear the result matrix - result.Clear(); - - // Copy the diagonal part into the result matrix. - for (var i = 0; i < _data.Length; i++) - { - result.At(i, i, _data[i]); - } - - // Copy the lower matrix into the result matrix. - for (var i = 0; i < right.RowCount; i++) - { - for (var j = 0; j < right.ColumnCount; j++) - { - result.At(i, j + RowCount, right.At(i, j)); - } - } - } - - /// - /// Diagonally stacks his matrix on top of the given matrix. The new matrix is a M-by-N matrix, - /// where M = this.Rows + lower.Rows and N = this.Columns + lower.Columns. - /// The values of off the off diagonal matrices/blocks are set to zero. - /// - /// The lower, right matrix. - /// If lower is . - /// the combined matrix - public override Matrix DiagonalStack(Matrix lower) - { - if (lower == null) - { - throw new ArgumentNullException("lower"); - } - - var result = new SparseMatrix(RowCount + lower.RowCount, ColumnCount + lower.ColumnCount); - DiagonalStack(lower, result); - return result; - } - - /// - /// Diagonally stacks his matrix on top of the given matrix and places the combined matrix into the result matrix. - /// - /// The lower, right matrix. - /// The combined matrix - /// If lower is . - /// If the result matrix is . - /// If the result matrix's dimensions are not (this.Rows + lower.rows) x (this.Columns + lower.Columns). - public override void DiagonalStack(Matrix lower, Matrix result) - { - if (lower == null) - { - throw new ArgumentNullException("lower"); - } - - if (result == null) - { - throw new ArgumentNullException("result"); - } - - if (result.RowCount != RowCount + lower.RowCount || result.ColumnCount != ColumnCount + lower.ColumnCount) - { - throw DimensionsDontMatch(this, lower, result); - } - - // Clear the result matrix - result.Clear(); - - // Copy the diagonal part into the result matrix. - for (var i = 0; i < _data.Length; i++) - { - result.At(i, i, _data[i]); - } - - // Copy the lower matrix into the result matrix. - result.SetSubMatrix(RowCount, lower.RowCount, ColumnCount, lower.ColumnCount, lower); - } - /// /// Permute the columns of a matrix according to a permutation. /// diff --git a/src/Numerics/LinearAlgebra/Single/SparseMatrix.cs b/src/Numerics/LinearAlgebra/Single/SparseMatrix.cs index 4f1d6b5a..f72424e2 100644 --- a/src/Numerics/LinearAlgebra/Single/SparseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Single/SparseMatrix.cs @@ -189,16 +189,13 @@ namespace MathNet.Numerics.LinearAlgebra.Single /// /// Creates a SparseMatrix for the given number of rows and columns. /// - /// - /// The number of rows. - /// - /// - /// The number of columns. - /// + /// The number of rows. + /// The number of columns. + /// True if all fields must be mutable (e.g. not a diagonal matrix). /// /// A SparseMatrix with the given dimensions. /// - public override Matrix CreateMatrix(int numberOfRows, int numberOfColumns) + public override Matrix CreateMatrix(int numberOfRows, int numberOfColumns, bool fullyMutable = false) { return new SparseMatrix(numberOfRows, numberOfColumns); } @@ -207,10 +204,11 @@ namespace MathNet.Numerics.LinearAlgebra.Single /// Creates a with a the given dimension. /// /// The size of the vector. + /// True if all fields must be mutable. /// /// A with the given dimension. /// - public override Vector CreateVector(int size) + public override Vector CreateVector(int size, bool fullyMutable = false) { return new SparseVector(size); } @@ -688,56 +686,6 @@ namespace MathNet.Numerics.LinearAlgebra.Single } } - /// - /// Diagonally stacks this matrix on top of the given matrix and places the combined matrix into the result matrix. - /// - /// The lower, right matrix. - /// The combined matrix - /// If lower is . - /// If the result matrix is . - /// If the result matrix's dimensions are not (Rows + lower.rows) x (Columns + lower.Columns). - public override void DiagonalStack(Matrix lower, Matrix result) - { - var lowerSparseMatrix = lower as SparseMatrix; - var resultSparseMatrix = result as SparseMatrix; - - if ((lowerSparseMatrix == null) || (resultSparseMatrix == null)) - { - base.DiagonalStack(lower, result); - } - else - { - var resultStorage = resultSparseMatrix.Raw; - var lowerStorage = lowerSparseMatrix.Raw; - - if (resultStorage.RowCount != RowCount + lowerStorage.RowCount || resultStorage.ColumnCount != ColumnCount + lowerSparseMatrix.ColumnCount) - { - throw DimensionsDontMatch(this, lowerSparseMatrix, resultSparseMatrix); - } - - resultStorage.ValueCount = _storage.ValueCount + lowerStorage.ValueCount; - resultStorage.Values = new float[resultStorage.ValueCount]; - resultStorage.ColumnIndices = new int[resultStorage.ValueCount]; - - Array.Copy(_storage.Values, 0, resultStorage.Values, 0, _storage.ValueCount); - Array.Copy(lowerStorage.Values, 0, resultStorage.Values, _storage.ValueCount, lowerStorage.ValueCount); - - Array.Copy(_storage.ColumnIndices, 0, resultStorage.ColumnIndices, 0, _storage.ValueCount); - Array.Copy(_storage.RowPointers, 0, resultStorage.RowPointers, 0, RowCount); - - // Copy and adjust lower column indices and rowIndex - for (int i = _storage.ValueCount, j = 0; i < resultStorage.ValueCount; i++, j++) - { - resultStorage.ColumnIndices[i] = lowerStorage.ColumnIndices[j] + ColumnCount; - } - - for (int i = RowCount, j = 0; i < resultStorage.RowCount; i++, j++) - { - resultStorage.RowPointers[i] = lowerStorage.RowPointers[j] + _storage.ValueCount; - } - } - } - #region Static constructors for special matrices. /// /// Initializes a square with all zero's except for ones on the diagonal. diff --git a/src/Numerics/LinearAlgebra/Storage/DiagonalMatrixStorage.cs b/src/Numerics/LinearAlgebra/Storage/DiagonalMatrixStorage.cs index cdd1f753..f4c9b46a 100644 --- a/src/Numerics/LinearAlgebra/Storage/DiagonalMatrixStorage.cs +++ b/src/Numerics/LinearAlgebra/Storage/DiagonalMatrixStorage.cs @@ -201,7 +201,7 @@ namespace MathNet.Numerics.LinearAlgebra.Storage Array.Copy(Data, 0, target.Data, 0, Data.Length); } - void CopyTo(SparseCompressedRowMatrixStorage target, bool skipClearing = false) + void CopyTo(SparseCompressedRowMatrixStorage target, bool skipClearing) { if (target == null) { @@ -225,7 +225,7 @@ namespace MathNet.Numerics.LinearAlgebra.Storage } } - void CopyTo(DenseColumnMajorMatrixStorage target, bool skipClearing = false) + void CopyTo(DenseColumnMajorMatrixStorage target, bool skipClearing) { if (target == null) { @@ -321,7 +321,7 @@ namespace MathNet.Numerics.LinearAlgebra.Storage void CopySubMatrixTo(DenseColumnMajorMatrixStorage target, int sourceRowIndex, int targetRowIndex, int rowCount, int sourceColumnIndex, int targetColumnIndex, int columnCount, - bool skipClearing = false) + bool skipClearing) { if (target == null) { @@ -381,7 +381,7 @@ namespace MathNet.Numerics.LinearAlgebra.Storage void CopySubMatrixTo(SparseCompressedRowMatrixStorage target, int sourceRowIndex, int targetRowIndex, int rowCount, int sourceColumnIndex, int targetColumnIndex, int columnCount, - bool skipClearing = false) + bool skipClearing) { if (target == null) { diff --git a/src/Numerics/LinearAlgebra/Storage/SparseCompressedRowMatrixStorage.cs b/src/Numerics/LinearAlgebra/Storage/SparseCompressedRowMatrixStorage.cs index ee0bbea2..a0cc2832 100644 --- a/src/Numerics/LinearAlgebra/Storage/SparseCompressedRowMatrixStorage.cs +++ b/src/Numerics/LinearAlgebra/Storage/SparseCompressedRowMatrixStorage.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using MathNet.Numerics.Properties; namespace MathNet.Numerics.LinearAlgebra.Storage @@ -362,11 +363,6 @@ namespace MathNet.Numerics.LinearAlgebra.Storage 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); @@ -385,13 +381,8 @@ namespace MathNet.Numerics.LinearAlgebra.Storage } } - void CopyTo(DenseColumnMajorMatrixStorage target, bool skipClearing = false) + void CopyTo(DenseColumnMajorMatrixStorage target, bool skipClearing) { - 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); @@ -427,6 +418,18 @@ namespace MathNet.Numerics.LinearAlgebra.Storage throw new ArgumentNullException("target"); } + var sparseTarget = target as SparseCompressedRowMatrixStorage; + if (sparseTarget != null) + { + CopySubMatrixTo(sparseTarget, + sourceRowIndex, targetRowIndex, rowCount, + sourceColumnIndex, targetColumnIndex, columnCount, + skipClearing); + return; + } + + // FALL BACK + if (ReferenceEquals(this, target)) { throw new NotSupportedException(); @@ -436,8 +439,86 @@ namespace MathNet.Numerics.LinearAlgebra.Storage sourceRowIndex, targetRowIndex, rowCount, sourceColumnIndex, targetColumnIndex, columnCount); - // NOTE: potential for more efficient implementation (specialized on target storage schema) - // (this would then essentially be the fallback implementation) + if (!skipClearing) + { + target.Clear(targetRowIndex, rowCount, targetColumnIndex, columnCount); + } + + for (int i = sourceRowIndex, row = 0; i < sourceRowIndex + rowCount; i++, row++) + { + var startIndex = RowPointers[i]; + var endIndex = i < RowPointers.Length - 1 ? RowPointers[i + 1] : ValueCount; + + for (int j = startIndex; j < endIndex; j++) + { + // check if the column index is in the range + if ((ColumnIndices[j] >= sourceColumnIndex) && (ColumnIndices[j] < sourceColumnIndex + columnCount)) + { + var column = ColumnIndices[j] - sourceColumnIndex; + target.At(targetRowIndex + row, targetColumnIndex + column, Values[j]); + } + } + } + } + + void CopySubMatrixTo(SparseCompressedRowMatrixStorage target, + int sourceRowIndex, int targetRowIndex, int rowCount, + int sourceColumnIndex, int targetColumnIndex, int columnCount, + bool skipClearing) + { + if (ReferenceEquals(this, target)) + { + throw new NotSupportedException(); + } + + ValidateSubMatrixRange(target, + sourceRowIndex, targetRowIndex, rowCount, + sourceColumnIndex, targetColumnIndex, columnCount); + + var rowOffset = targetRowIndex - sourceRowIndex; + var columnOffset = targetColumnIndex - sourceColumnIndex; + + // special case for empty target - much faster + if (target.ValueCount == 0) + { + // note: ValueCount is maximum resulting ValueCount (just using max to avoid internal copying) + // resulting arrays will likely be smaller - unless all values fit in the chosen range. + var values = new List(ValueCount); + var columnIndices = new List(ValueCount); + var rowPointers = target.RowPointers; + + for (int i = sourceRowIndex, row = 0; i < sourceRowIndex + rowCount; i++, row++) + { + rowPointers[i + rowOffset] = values.Count; + + var startIndex = RowPointers[i]; + var endIndex = i < RowPointers.Length - 1 ? RowPointers[i + 1] : ValueCount; + + // note: we might be able to replace this loop with Array.Copy (perf) + for (int j = startIndex; j < endIndex; j++) + { + // check if the column index is in the range + if ((ColumnIndices[j] >= sourceColumnIndex) && (ColumnIndices[j] < sourceColumnIndex + columnCount)) + { + values.Add(Values[j]); + columnIndices.Add(ColumnIndices[j] + columnOffset); + } + } + } + + for(int i=targetRowIndex + rowCount; iThe number of rows. /// The number of columns. /// A matrix with the given dimensions. - public override Matrix CreateMatrix(int numberOfRows, int numberOfColumns) + public override Matrix CreateMatrix(int numberOfRows, int numberOfColumns, bool fullyMutable = false) { return new UserDefinedMatrix(numberOfRows, numberOfColumns); } @@ -109,7 +109,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex /// /// The size of the vector. /// A vector with the given dimension. - public override Vector CreateVector(int size) + public override Vector CreateVector(int size, bool fullyMutable = false) { return new UserDefinedVector(size); } diff --git a/src/UnitTests/LinearAlgebraTests/Complex32/UserDefinedMatrix.cs b/src/UnitTests/LinearAlgebraTests/Complex32/UserDefinedMatrix.cs index 6f181705..f3ac48cd 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex32/UserDefinedMatrix.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex32/UserDefinedMatrix.cs @@ -99,7 +99,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32 /// The number of rows. /// The number of columns. /// A matrix with the given dimensions. - public override Matrix CreateMatrix(int numberOfRows, int numberOfColumns) + public override Matrix CreateMatrix(int numberOfRows, int numberOfColumns, bool fullyMutable = false) { return new UserDefinedMatrix(numberOfRows, numberOfColumns); } @@ -109,7 +109,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32 /// /// The size of the vector. /// A vector with the given dimension. - public override Vector CreateVector(int size) + public override Vector CreateVector(int size, bool fullyMutable = false) { return new UserDefinedVector(size); } diff --git a/src/UnitTests/LinearAlgebraTests/Double/UserDefinedMatrix.cs b/src/UnitTests/LinearAlgebraTests/Double/UserDefinedMatrix.cs index 902d6aeb..b93b4c43 100644 --- a/src/UnitTests/LinearAlgebraTests/Double/UserDefinedMatrix.cs +++ b/src/UnitTests/LinearAlgebraTests/Double/UserDefinedMatrix.cs @@ -98,7 +98,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double /// The number of rows. /// The number of columns. /// A matrix with the given dimensions. - public override Matrix CreateMatrix(int numberOfRows, int numberOfColumns) + public override Matrix CreateMatrix(int numberOfRows, int numberOfColumns, bool fullyMutable = false) { return new UserDefinedMatrix(numberOfRows, numberOfColumns); } @@ -108,7 +108,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double /// /// The size of the vector. /// A vector with the given dimension. - public override Vector CreateVector(int size) + public override Vector CreateVector(int size, bool fullyMutable = false) { return new UserDefinedVector(size); } diff --git a/src/UnitTests/LinearAlgebraTests/Single/UserDefinedMatrix.cs b/src/UnitTests/LinearAlgebraTests/Single/UserDefinedMatrix.cs index 0679607f..583ae21b 100644 --- a/src/UnitTests/LinearAlgebraTests/Single/UserDefinedMatrix.cs +++ b/src/UnitTests/LinearAlgebraTests/Single/UserDefinedMatrix.cs @@ -98,7 +98,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single /// The number of rows. /// The number of columns. /// A matrix with the given dimensions. - public override Matrix CreateMatrix(int numberOfRows, int numberOfColumns) + public override Matrix CreateMatrix(int numberOfRows, int numberOfColumns, bool fullyMutable = false) { return new UserDefinedMatrix(numberOfRows, numberOfColumns); } @@ -108,7 +108,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single /// /// The size of the vector. /// A vector with the given dimension. - public override Vector CreateVector(int size) + public override Vector CreateVector(int size, bool fullyMutable = false) { return new UserDefinedVector(size); }