From ca8c2846cacee049f8a28db4ae9a6ba18693f91d Mon Sep 17 00:00:00 2001 From: Christoph Ruegg Date: Fri, 4 Apr 2014 15:26:37 +0200 Subject: [PATCH] LA: matrix RemoveRow/RemoveColumn #207 #45 --- .../LinearAlgebra/Complex/DiagonalMatrix.cs | 74 ------------------- .../LinearAlgebra/Complex32/DiagonalMatrix.cs | 74 ------------------- .../LinearAlgebra/Double/DiagonalMatrix.cs | 74 ------------------- .../LinearAlgebra/Matrix.Arithmetic.cs | 1 + src/Numerics/LinearAlgebra/Matrix.cs | 46 +++++++++++- .../LinearAlgebra/Single/DiagonalMatrix.cs | 74 ------------------- .../LinearAlgebra/Vector.Arithmetic.cs | 1 + .../MatrixStructureTheory.Reform.cs | 51 +++++++++++++ 8 files changed, 95 insertions(+), 300 deletions(-) diff --git a/src/Numerics/LinearAlgebra/Complex/DiagonalMatrix.cs b/src/Numerics/LinearAlgebra/Complex/DiagonalMatrix.cs index 355c6c05..e2dde4d6 100644 --- a/src/Numerics/LinearAlgebra/Complex/DiagonalMatrix.cs +++ b/src/Numerics/LinearAlgebra/Complex/DiagonalMatrix.cs @@ -930,80 +930,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex return target; } - /// - /// Creates a new and inserts the given column at the given index. - /// - /// The index of where to insert the column. - /// The column to insert. - /// A new with the inserted column. - /// If is < zero or > the number of columns. - /// If the size of != the number of rows. - public override Matrix InsertColumn(int columnIndex, Vector column) - { - if (columnIndex < 0 || columnIndex > ColumnCount) - { - throw new ArgumentOutOfRangeException("columnIndex"); - } - - if (column.Count != RowCount) - { - throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension, "column"); - } - - var result = new SparseMatrix(RowCount, ColumnCount + 1); - - for (var i = 0; i < columnIndex; i++) - { - result.SetColumn(i, Column(i)); - } - - result.SetColumn(columnIndex, column); - - for (var i = columnIndex + 1; i < ColumnCount + 1; i++) - { - result.SetColumn(i, Column(i - 1)); - } - - return result; - } - - /// - /// Creates a new and inserts the given row at the given index. - /// - /// The index of where to insert the row. - /// The row to insert. - /// A new with the inserted column. - /// If is < zero or > the number of rows. - /// If the size of != the number of columns. - public override Matrix InsertRow(int rowIndex, Vector row) - { - if (rowIndex < 0 || rowIndex > RowCount) - { - throw new ArgumentOutOfRangeException("rowIndex"); - } - - if (row.Count != ColumnCount) - { - throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension, "row"); - } - - var result = new SparseMatrix(RowCount + 1, ColumnCount); - - for (var i = 0; i < rowIndex; i++) - { - result.At(i, i, At(i, i)); - } - - result.SetRow(rowIndex, row); - - for (var i = rowIndex + 1; i < result.RowCount; i++) - { - result.At(i, i - 1, At(i - 1, i - 1)); - } - - return result; - } - /// /// Permute the columns of a matrix according to a permutation. /// diff --git a/src/Numerics/LinearAlgebra/Complex32/DiagonalMatrix.cs b/src/Numerics/LinearAlgebra/Complex32/DiagonalMatrix.cs index 4db5dd61..f9258d60 100644 --- a/src/Numerics/LinearAlgebra/Complex32/DiagonalMatrix.cs +++ b/src/Numerics/LinearAlgebra/Complex32/DiagonalMatrix.cs @@ -924,80 +924,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 return target; } - /// - /// Creates a new and inserts the given column at the given index. - /// - /// The index of where to insert the column. - /// The column to insert. - /// A new with the inserted column. - /// If is < zero or > the number of columns. - /// If the size of != the number of rows. - public override Matrix InsertColumn(int columnIndex, Vector column) - { - if (columnIndex < 0 || columnIndex > ColumnCount) - { - throw new ArgumentOutOfRangeException("columnIndex"); - } - - if (column.Count != RowCount) - { - throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension, "column"); - } - - var result = new SparseMatrix(RowCount, ColumnCount + 1); - - for (var i = 0; i < columnIndex; i++) - { - result.SetColumn(i, Column(i)); - } - - result.SetColumn(columnIndex, column); - - for (var i = columnIndex + 1; i < ColumnCount + 1; i++) - { - result.SetColumn(i, Column(i - 1)); - } - - return result; - } - - /// - /// Creates a new and inserts the given row at the given index. - /// - /// The index of where to insert the row. - /// The row to insert. - /// A new with the inserted column. - /// If is < zero or > the number of rows. - /// If the size of != the number of columns. - public override Matrix InsertRow(int rowIndex, Vector row) - { - if (rowIndex < 0 || rowIndex > RowCount) - { - throw new ArgumentOutOfRangeException("rowIndex"); - } - - if (row.Count != ColumnCount) - { - throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension, "row"); - } - - var result = new SparseMatrix(RowCount + 1, ColumnCount); - - for (var i = 0; i < rowIndex; i++) - { - result.At(i, i, At(i, i)); - } - - result.SetRow(rowIndex, row); - - for (var i = rowIndex + 1; i < result.RowCount; i++) - { - result.At(i, i - 1, At(i - 1, i - 1)); - } - - return result; - } - /// /// Permute the columns of a matrix according to a permutation. /// diff --git a/src/Numerics/LinearAlgebra/Double/DiagonalMatrix.cs b/src/Numerics/LinearAlgebra/Double/DiagonalMatrix.cs index ced251a6..ccfede32 100644 --- a/src/Numerics/LinearAlgebra/Double/DiagonalMatrix.cs +++ b/src/Numerics/LinearAlgebra/Double/DiagonalMatrix.cs @@ -774,80 +774,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double return target; } - /// - /// Creates a new and inserts the given column at the given index. - /// - /// The index of where to insert the column. - /// The column to insert. - /// A new with the inserted column. - /// If is < zero or > the number of columns. - /// If the size of != the number of rows. - public override Matrix InsertColumn(int columnIndex, Vector column) - { - if (columnIndex < 0 || columnIndex > ColumnCount) - { - throw new ArgumentOutOfRangeException("columnIndex"); - } - - if (column.Count != RowCount) - { - throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension, "column"); - } - - var result = new SparseMatrix(RowCount, ColumnCount + 1); - - for (var i = 0; i < columnIndex; i++) - { - result.SetColumn(i, Column(i)); - } - - result.SetColumn(columnIndex, column); - - for (var i = columnIndex + 1; i < ColumnCount + 1; i++) - { - result.SetColumn(i, Column(i - 1)); - } - - return result; - } - - /// - /// Creates a new and inserts the given row at the given index. - /// - /// The index of where to insert the row. - /// The row to insert. - /// A new with the inserted column. - /// If is < zero or > the number of rows. - /// If the size of != the number of columns. - public override Matrix InsertRow(int rowIndex, Vector row) - { - if (rowIndex < 0 || rowIndex > RowCount) - { - throw new ArgumentOutOfRangeException("rowIndex"); - } - - if (row.Count != ColumnCount) - { - throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension, "row"); - } - - var result = new SparseMatrix(RowCount + 1, ColumnCount); - - for (var i = 0; i < rowIndex; i++) - { - result.At(i, i, At(i, i)); - } - - result.SetRow(rowIndex, row); - - for (var i = rowIndex + 1; i < result.RowCount; i++) - { - result.At(i, i - 1, At(i - 1, i - 1)); - } - - return result; - } - /// /// Permute the columns of a matrix according to a permutation. /// diff --git a/src/Numerics/LinearAlgebra/Matrix.Arithmetic.cs b/src/Numerics/LinearAlgebra/Matrix.Arithmetic.cs index 1eeacb99..afe767a8 100644 --- a/src/Numerics/LinearAlgebra/Matrix.Arithmetic.cs +++ b/src/Numerics/LinearAlgebra/Matrix.Arithmetic.cs @@ -1380,6 +1380,7 @@ namespace MathNet.Numerics.LinearAlgebra /// Pointwise raise this matrix to an exponent. /// /// The exponent to raise this matrix values to. + /// The matrix to store the result into. /// If this matrix and are not the same size. public void PointwisePower(T exponent, Matrix result) { diff --git a/src/Numerics/LinearAlgebra/Matrix.cs b/src/Numerics/LinearAlgebra/Matrix.cs index c2f422fd..245973f0 100644 --- a/src/Numerics/LinearAlgebra/Matrix.cs +++ b/src/Numerics/LinearAlgebra/Matrix.cs @@ -631,7 +631,7 @@ namespace MathNet.Numerics.LinearAlgebra /// If is . /// If is < zero or > the number of columns. /// If the size of != the number of rows. - public virtual Matrix InsertColumn(int columnIndex, Vector column) + public Matrix InsertColumn(int columnIndex, Vector column) { if (column == null) { @@ -648,13 +648,32 @@ namespace MathNet.Numerics.LinearAlgebra throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension, "column"); } - var result = Build.SameAs(this, RowCount, ColumnCount + 1); + var result = Build.SameAs(this, RowCount, ColumnCount + 1, fullyMutable: true); Storage.CopySubMatrixTo(result.Storage, 0, 0, RowCount, 0, 0, columnIndex, skipClearing: true); result.SetColumn(columnIndex, column); Storage.CopySubMatrixTo(result.Storage, 0, 0, RowCount, columnIndex, columnIndex + 1, ColumnCount - columnIndex, skipClearing: true); return result; } + /// + /// Creates a new matrix with the given column removed. + /// + /// The index of the column to remove. + /// A new matrix without the chosen column. + /// If is < zero or > the number of columns. + public Matrix RemoveColumn(int columnIndex) + { + if (columnIndex < 0 || columnIndex > ColumnCount) + { + throw new ArgumentOutOfRangeException("columnIndex"); + } + + var result = Build.SameAs(this, RowCount, ColumnCount - 1, fullyMutable: true); + Storage.CopySubMatrixTo(result.Storage, 0, 0, RowCount, 0, 0, columnIndex, skipClearing: true); + Storage.CopySubMatrixTo(result.Storage, 0, 0, RowCount, columnIndex + 1, columnIndex, ColumnCount - columnIndex - 1, skipClearing: true); + return result; + } + /// /// Copies the values of the given Vector to the specified column. /// @@ -728,7 +747,7 @@ namespace MathNet.Numerics.LinearAlgebra /// If is . /// If is < zero or > the number of rows. /// If the size of != the number of columns. - public virtual Matrix InsertRow(int rowIndex, Vector row) + public Matrix InsertRow(int rowIndex, Vector row) { if (row == null) { @@ -745,13 +764,32 @@ namespace MathNet.Numerics.LinearAlgebra throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension, "row"); } - var result = Build.SameAs(this, RowCount + 1, ColumnCount); + var result = Build.SameAs(this, RowCount + 1, ColumnCount, fullyMutable: true); Storage.CopySubMatrixTo(result.Storage, 0, 0, rowIndex, 0, 0, ColumnCount, skipClearing: true); result.SetRow(rowIndex, row); Storage.CopySubMatrixTo(result.Storage, rowIndex, rowIndex+1, RowCount - rowIndex, 0, 0, ColumnCount, skipClearing: true); return result; } + /// + /// Creates a new matrix with the given row removed. + /// + /// The index of the row to remove. + /// A new matrix without the chosen row. + /// If is < zero or > the number of rows. + public Matrix RemoveRow(int rowIndex) + { + if (rowIndex < 0 || rowIndex > ColumnCount) + { + throw new ArgumentOutOfRangeException("rowIndex"); + } + + var result = Build.SameAs(this, RowCount - 1, ColumnCount, fullyMutable: true); + Storage.CopySubMatrixTo(result.Storage, 0, 0, rowIndex, 0, 0, ColumnCount, skipClearing: true); + Storage.CopySubMatrixTo(result.Storage, rowIndex + 1, rowIndex, RowCount - rowIndex - 1, 0, 0, ColumnCount, skipClearing: true); + return result; + } + /// /// Copies the values of the given Vector to the specified row. /// diff --git a/src/Numerics/LinearAlgebra/Single/DiagonalMatrix.cs b/src/Numerics/LinearAlgebra/Single/DiagonalMatrix.cs index 88a4fe33..38836a16 100644 --- a/src/Numerics/LinearAlgebra/Single/DiagonalMatrix.cs +++ b/src/Numerics/LinearAlgebra/Single/DiagonalMatrix.cs @@ -774,80 +774,6 @@ namespace MathNet.Numerics.LinearAlgebra.Single return target; } - /// - /// Creates a new and inserts the given column at the given index. - /// - /// The index of where to insert the column. - /// The column to insert. - /// A new with the inserted column. - /// If is < zero or > the number of columns. - /// If the size of != the number of rows. - public override Matrix InsertColumn(int columnIndex, Vector column) - { - if (columnIndex < 0 || columnIndex > ColumnCount) - { - throw new ArgumentOutOfRangeException("columnIndex"); - } - - if (column.Count != RowCount) - { - throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension, "column"); - } - - var result = new SparseMatrix(RowCount, ColumnCount + 1); - - for (var i = 0; i < columnIndex; i++) - { - result.SetColumn(i, Column(i)); - } - - result.SetColumn(columnIndex, column); - - for (var i = columnIndex + 1; i < ColumnCount + 1; i++) - { - result.SetColumn(i, Column(i - 1)); - } - - return result; - } - - /// - /// Creates a new and inserts the given row at the given index. - /// - /// The index of where to insert the row. - /// The row to insert. - /// A new with the inserted column. - /// If is < zero or > the number of rows. - /// If the size of != the number of columns. - public override Matrix InsertRow(int rowIndex, Vector row) - { - if (rowIndex < 0 || rowIndex > RowCount) - { - throw new ArgumentOutOfRangeException("rowIndex"); - } - - if (row.Count != ColumnCount) - { - throw new ArgumentException(Resources.ArgumentMatrixSameRowDimension, "row"); - } - - var result = new SparseMatrix(RowCount + 1, ColumnCount); - - for (var i = 0; i < rowIndex; i++) - { - result.At(i, i, At(i, i)); - } - - result.SetRow(rowIndex, row); - - for (var i = rowIndex + 1; i < result.RowCount; i++) - { - result.At(i, i - 1, At(i - 1, i - 1)); - } - - return result; - } - /// /// Permute the columns of a matrix according to a permutation. /// diff --git a/src/Numerics/LinearAlgebra/Vector.Arithmetic.cs b/src/Numerics/LinearAlgebra/Vector.Arithmetic.cs index 2ed73596..ae42c104 100644 --- a/src/Numerics/LinearAlgebra/Vector.Arithmetic.cs +++ b/src/Numerics/LinearAlgebra/Vector.Arithmetic.cs @@ -796,6 +796,7 @@ namespace MathNet.Numerics.LinearAlgebra /// Pointwise raise this vector to an exponent and store the result into the result vector. /// /// The exponent to raise this vector values to. + /// The matrix to store the result into. /// If this vector and are not the same size. public void PointwisePower(T exponent, Vector result) { diff --git a/src/UnitTests/LinearAlgebraTests/MatrixStructureTheory.Reform.cs b/src/UnitTests/LinearAlgebraTests/MatrixStructureTheory.Reform.cs index 76a90ea1..dd123a96 100644 --- a/src/UnitTests/LinearAlgebraTests/MatrixStructureTheory.Reform.cs +++ b/src/UnitTests/LinearAlgebraTests/MatrixStructureTheory.Reform.cs @@ -131,6 +131,31 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests Assert.That(() => matrix.InsertRow(0, Vector.Build.Dense(matrix.ColumnCount + 1)), Throws.ArgumentException); } + [Theory] + public void CanRemoveRow(Matrix matrix) + { + var row = Vector.Build.Random(matrix.ColumnCount, 0); + for (var position = 0; position < matrix.RowCount; position++) + { + var result = matrix.RemoveRow(position); + Assert.That(result.RowCount, Is.EqualTo(matrix.RowCount - 1)); + for (int ir = 0, im = 0; ir < result.RowCount; ir++, im++) + { + if (ir == position) + { + im++; + } + for (var j = 0; j < result.ColumnCount; j++) + { + Assert.That(result[ir, j], Is.EqualTo(matrix[im, j]), "A({0},{1}) for {2}", ir, j, matrix.GetType().FullName); + } + } + } + + Assert.That(() => matrix.RemoveRow(-1), Throws.InstanceOf()); + Assert.That(() => matrix.RemoveRow(matrix.RowCount + 1), Throws.InstanceOf()); + } + [Theory] public void CanInsertColumn(Matrix matrix) { @@ -167,6 +192,32 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests Assert.That(() => matrix.InsertColumn(0, Vector.Build.Dense(matrix.RowCount + 1)), Throws.ArgumentException); } + [Theory] + public void CanRemoveColumn(Matrix matrix) + { + var column = Vector.Build.Random(matrix.RowCount, 0); + for (var position = 0; position < matrix.ColumnCount; position++) + { + var result = matrix.RemoveColumn(position); + Assert.That(result.ColumnCount, Is.EqualTo(matrix.ColumnCount - 1)); + for (int jr = 0, jm = 0; jr < result.ColumnCount; jr++, jm++) + { + if (jr == position) + { + jm++; + } + for (var i = 0; i < result.RowCount; i++) + { + Assert.That(result[i, jr], Is.EqualTo(matrix[i, jm])); + } + } + } + + // Invalid + Assert.That(() => matrix.RemoveColumn(-1), Throws.InstanceOf()); + Assert.That(() => matrix.RemoveColumn(matrix.ColumnCount + 1), Throws.InstanceOf()); + } + [Theory] public void CanAppend(Matrix left, Matrix right) {