diff --git a/src/Numerics/LinearAlgebra/Matrix.cs b/src/Numerics/LinearAlgebra/Matrix.cs index d420c968..c2f422fd 100644 --- a/src/Numerics/LinearAlgebra/Matrix.cs +++ b/src/Numerics/LinearAlgebra/Matrix.cs @@ -649,19 +649,9 @@ namespace MathNet.Numerics.LinearAlgebra } var result = Build.SameAs(this, RowCount, ColumnCount + 1); - - for (var i = 0; i < columnIndex; i++) - { - result.SetColumn(i, Column(i)); - } - + Storage.CopySubMatrixTo(result.Storage, 0, 0, RowCount, 0, 0, columnIndex, skipClearing: true); result.SetColumn(columnIndex, column); - - for (var i = columnIndex + 1; i < ColumnCount + 1; i++) - { - result.SetColumn(i, Column(i - 1)); - } - + Storage.CopySubMatrixTo(result.Storage, 0, 0, RowCount, columnIndex, columnIndex + 1, ColumnCount - columnIndex, skipClearing: true); return result; } @@ -756,19 +746,9 @@ namespace MathNet.Numerics.LinearAlgebra } var result = Build.SameAs(this, RowCount + 1, ColumnCount); - - for (var i = 0; i < rowIndex; i++) - { - result.SetRow(i, Row(i)); - } - + Storage.CopySubMatrixTo(result.Storage, 0, 0, rowIndex, 0, 0, ColumnCount, skipClearing: true); result.SetRow(rowIndex, row); - - for (var i = rowIndex + 1; i < RowCount + 1; i++) - { - result.SetRow(i, Row(i - 1)); - } - + Storage.CopySubMatrixTo(result.Storage, rowIndex, rowIndex+1, RowCount - rowIndex, 0, 0, ColumnCount, skipClearing: true); return result; } diff --git a/src/Numerics/LinearAlgebra/Storage/MatrixStorage.cs b/src/Numerics/LinearAlgebra/Storage/MatrixStorage.cs index 45cdeb85..754e7514 100644 --- a/src/Numerics/LinearAlgebra/Storage/MatrixStorage.cs +++ b/src/Numerics/LinearAlgebra/Storage/MatrixStorage.cs @@ -270,6 +270,11 @@ namespace MathNet.Numerics.LinearAlgebra.Storage throw new ArgumentNullException("target"); } + if (rowCount == 0 || columnCount == 0) + { + return; + } + if (ReferenceEquals(this, target)) { throw new NotSupportedException(); @@ -319,6 +324,11 @@ namespace MathNet.Numerics.LinearAlgebra.Storage throw new ArgumentNullException("target"); } + if (columnCount == 0) + { + return; + } + ValidateSubRowRange(target, rowIndex, sourceColumnIndex, targetColumnIndex, columnCount); CopySubRowToUnchecked(target, rowIndex, sourceColumnIndex, targetColumnIndex, columnCount, skipClearing); } @@ -355,6 +365,11 @@ namespace MathNet.Numerics.LinearAlgebra.Storage throw new ArgumentNullException("target"); } + if (rowCount == 0) + { + return; + } + ValidateSubColumnRange(target, columnIndex, sourceRowIndex, targetRowIndex, rowCount); CopySubColumnToUnchecked(target, columnIndex, sourceRowIndex, targetRowIndex, rowCount, skipClearing); } diff --git a/src/UnitTests/LinearAlgebraTests/MatrixStructureTheory.Access.cs b/src/UnitTests/LinearAlgebraTests/MatrixStructureTheory.Access.cs index 6c57a374..5cfe957b 100644 --- a/src/UnitTests/LinearAlgebraTests/MatrixStructureTheory.Access.cs +++ b/src/UnitTests/LinearAlgebraTests/MatrixStructureTheory.Access.cs @@ -656,14 +656,14 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests Assert.That(() => m.SetSubMatrix(0, 1, 0, 1, default(Matrix)), Throws.InstanceOf()); Assert.That(() => m.SetSubMatrix(-1, 1, 0, 1, Matrix.Build.Dense(1, 1)), Throws.InstanceOf()); Assert.That(() => m.SetSubMatrix(matrix.RowCount, 1, 0, 1, Matrix.Build.Dense(1, 1)), Throws.InstanceOf()); - Assert.That(() => m.SetSubMatrix(0, 0, 0, 1, Matrix.Build.Dense(1, 1)), Throws.InstanceOf()); Assert.That(() => m.SetSubMatrix(0, 1, -1, 1, Matrix.Build.Dense(1, 1)), Throws.InstanceOf()); Assert.That(() => m.SetSubMatrix(0, 1, matrix.ColumnCount, 1, Matrix.Build.Dense(1, 1)), Throws.InstanceOf()); - Assert.That(() => m.SetSubMatrix(0, 1, 0, 0, Matrix.Build.Dense(1, 1)), Throws.InstanceOf()); // Usually invalid, but not for SetSubMatrix (since size is explicitly provided) Assert.That(() => m.SetSubMatrix(0, 1, 0, 1, Matrix.Build.Dense(1, 2)), Throws.Nothing); Assert.That(() => m.SetSubMatrix(0, 1, 0, 1, Matrix.Build.Dense(2, 1)), Throws.Nothing); + Assert.That(() => m.SetSubMatrix(0, 0, 0, 1, Matrix.Build.Dense(1, 1)), Throws.Nothing); + Assert.That(() => m.SetSubMatrix(0, 1, 0, 0, Matrix.Build.Dense(1, 1)), Throws.Nothing); } } }