diff --git a/src/Numerics/LinearAlgebra/Complex/DiagonalMatrix.cs b/src/Numerics/LinearAlgebra/Complex/DiagonalMatrix.cs index 46f9c0ce..b6464ebc 100644 --- a/src/Numerics/LinearAlgebra/Complex/DiagonalMatrix.cs +++ b/src/Numerics/LinearAlgebra/Complex/DiagonalMatrix.cs @@ -684,118 +684,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex return ret; } - /// - /// Copies the requested column elements into the given vector. - /// - /// The column to copy elements from. - /// The row to start copying from. - /// The number of elements to copy. - /// The to copy the column into. - /// If the result is . - /// If is negative, - /// or greater than or equal to the number of columns. - /// If is negative, - /// or greater than or equal to the number of rows. - /// If + - /// is greater than or equal to the number of rows. - /// If is not positive. - /// If result.Count < length. - public override void Column(int columnIndex, int rowIndex, int length, Vector result) - { - if (result == null) - { - throw new ArgumentNullException("result"); - } - - if (columnIndex >= ColumnCount || columnIndex < 0) - { - throw new ArgumentOutOfRangeException("columnIndex"); - } - - if (rowIndex >= RowCount || rowIndex < 0) - { - throw new ArgumentOutOfRangeException("rowIndex"); - } - - if (rowIndex + length > RowCount) - { - throw new ArgumentOutOfRangeException("length"); - } - - if (length < 1) - { - throw new ArgumentOutOfRangeException("length", Resources.ArgumentMustBePositive); - } - - if (result.Count < length) - { - throw new ArgumentOutOfRangeException("result", Resources.ArgumentVectorsSameLength); - } - - // Clear the result and copy the diagonal entry. - result.Clear(); - if (columnIndex >= rowIndex && columnIndex < rowIndex + length && columnIndex < _data.Length) - { - result[columnIndex - rowIndex] = _data[columnIndex]; - } - } - - /// - /// Copies the requested row elements into a new . - /// - /// The row to copy elements from. - /// The column to start copying from. - /// The number of elements to copy. - /// The to copy the column into. - /// If the result is . - /// If is negative, - /// or greater than or equal to the number of columns. - /// If is negative, - /// or greater than or equal to the number of rows. - /// If + - /// is greater than or equal to the number of rows. - /// If is not positive. - /// If result.Count < length. - public override void Row(int rowIndex, int columnIndex, int length, Vector result) - { - if (result == null) - { - throw new ArgumentNullException("result"); - } - - if (rowIndex >= RowCount || rowIndex < 0) - { - throw new ArgumentOutOfRangeException("rowIndex"); - } - - if (columnIndex >= ColumnCount || columnIndex < 0) - { - throw new ArgumentOutOfRangeException("columnIndex"); - } - - if (columnIndex + length > ColumnCount) - { - throw new ArgumentOutOfRangeException("length"); - } - - if (length < 1) - { - throw new ArgumentOutOfRangeException("length", Resources.ArgumentMustBePositive); - } - - if (result.Count < length) - { - throw new ArgumentOutOfRangeException("result", Resources.ArgumentVectorsSameLength); - } - - // Clear the result and copy the diagonal entry. - result.Clear(); - if (rowIndex >= columnIndex && rowIndex < columnIndex + length && rowIndex < _data.Length) - { - result[rowIndex - columnIndex] = _data[rowIndex]; - } - } - /// Calculates the L1 norm. /// The L1 norm of the matrix. public override Complex L1Norm() diff --git a/src/Numerics/LinearAlgebra/Complex/SparseMatrix.cs b/src/Numerics/LinearAlgebra/Complex/SparseMatrix.cs index 63c5e87f..c08b2619 100644 --- a/src/Numerics/LinearAlgebra/Complex/SparseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Complex/SparseMatrix.cs @@ -612,78 +612,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex return norm; } - /// - /// Copies the requested row elements into a new . - /// - /// The row to copy elements from. - /// The column to start copying from. - /// The number of elements to copy. - /// The to copy the column into. - /// If the result is . - /// If is negative, - /// or greater than or equal to the number of columns. - /// If is negative, - /// or greater than or equal to the number of rows. - /// If + - /// is greater than or equal to the number of rows. - /// If is not positive. - /// If result.Count < length. - public override void Row(int rowIndex, int columnIndex, int length, Vector result) - { - if (result == null) - { - throw new ArgumentNullException("result"); - } - - if (rowIndex >= RowCount || rowIndex < 0) - { - throw new ArgumentOutOfRangeException("rowIndex"); - } - - if (columnIndex >= ColumnCount || columnIndex < 0) - { - throw new ArgumentOutOfRangeException("columnIndex"); - } - - if (columnIndex + length > ColumnCount) - { - throw new ArgumentOutOfRangeException("length"); - } - - if (length < 1) - { - throw new ArgumentOutOfRangeException("length", Resources.ArgumentMustBePositive); - } - - if (result.Count < length) - { - throw new ArgumentOutOfRangeException("result", Resources.ArgumentVectorsSameLength); - } - - var rowPointers = _storage.RowPointers; - var values = _storage.Values; - var valueCount = _storage.ValueCount; - - // Determine bounds in columnIndices array where this item should be searched (using rowIndex) - var startIndex = rowPointers[rowIndex]; - var endIndex = rowIndex < rowPointers.Length - 1 ? rowPointers[rowIndex + 1] : valueCount; - - if (startIndex == endIndex) - { - result.Clear(); - } - else - { - // If there are non-zero elements use base class implementation - for (int i = columnIndex, j = 0; i < columnIndex + length; i++, j++) - { - // Copy code from At(row, column) to avoid unnecessary lock - var index = _storage.FindItem(rowIndex, i); - result[j] = index >= 0 ? values[index] : Complex.Zero; - } - } - } - #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/DiagonalMatrix.cs b/src/Numerics/LinearAlgebra/Complex32/DiagonalMatrix.cs index f95ceda3..9086d4d8 100644 --- a/src/Numerics/LinearAlgebra/Complex32/DiagonalMatrix.cs +++ b/src/Numerics/LinearAlgebra/Complex32/DiagonalMatrix.cs @@ -684,118 +684,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 return ret; } - /// - /// Copies the requested column elements into the given vector. - /// - /// The column to copy elements from. - /// The row to start copying from. - /// The number of elements to copy. - /// The to copy the column into. - /// If the result is . - /// If is negative, - /// or greater than or equal to the number of columns. - /// If is negative, - /// or greater than or equal to the number of rows. - /// If + - /// is greater than or equal to the number of rows. - /// If is not positive. - /// If result.Count < length. - public override void Column(int columnIndex, int rowIndex, int length, Vector result) - { - if (result == null) - { - throw new ArgumentNullException("result"); - } - - if (columnIndex >= ColumnCount || columnIndex < 0) - { - throw new ArgumentOutOfRangeException("columnIndex"); - } - - if (rowIndex >= RowCount || rowIndex < 0) - { - throw new ArgumentOutOfRangeException("rowIndex"); - } - - if (rowIndex + length > RowCount) - { - throw new ArgumentOutOfRangeException("length"); - } - - if (length < 1) - { - throw new ArgumentOutOfRangeException("length", Resources.ArgumentMustBePositive); - } - - if (result.Count < length) - { - throw new ArgumentOutOfRangeException("result", Resources.ArgumentVectorsSameLength); - } - - // Clear the result and copy the diagonal entry. - result.Clear(); - if (columnIndex >= rowIndex && columnIndex < rowIndex + length && columnIndex < _data.Length) - { - result[columnIndex - rowIndex] = _data[columnIndex]; - } - } - - /// - /// Copies the requested row elements into a new . - /// - /// The row to copy elements from. - /// The column to start copying from. - /// The number of elements to copy. - /// The to copy the column into. - /// If the result is . - /// If is negative, - /// or greater than or equal to the number of columns. - /// If is negative, - /// or greater than or equal to the number of rows. - /// If + - /// is greater than or equal to the number of rows. - /// If is not positive. - /// If result.Count < length. - public override void Row(int rowIndex, int columnIndex, int length, Vector result) - { - if (result == null) - { - throw new ArgumentNullException("result"); - } - - if (rowIndex >= RowCount || rowIndex < 0) - { - throw new ArgumentOutOfRangeException("rowIndex"); - } - - if (columnIndex >= ColumnCount || columnIndex < 0) - { - throw new ArgumentOutOfRangeException("columnIndex"); - } - - if (columnIndex + length > ColumnCount) - { - throw new ArgumentOutOfRangeException("length"); - } - - if (length < 1) - { - throw new ArgumentOutOfRangeException("length", Resources.ArgumentMustBePositive); - } - - if (result.Count < length) - { - throw new ArgumentOutOfRangeException("result", Resources.ArgumentVectorsSameLength); - } - - // Clear the result and copy the diagonal entry. - result.Clear(); - if (rowIndex >= columnIndex && rowIndex < columnIndex + length && rowIndex < _data.Length) - { - result[rowIndex - columnIndex] = _data[rowIndex]; - } - } - /// Calculates the L1 norm. /// The L1 norm of the matrix. public override Complex32 L1Norm() diff --git a/src/Numerics/LinearAlgebra/Complex32/SparseMatrix.cs b/src/Numerics/LinearAlgebra/Complex32/SparseMatrix.cs index 2e672c06..30297893 100644 --- a/src/Numerics/LinearAlgebra/Complex32/SparseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Complex32/SparseMatrix.cs @@ -612,78 +612,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 return norm; } - /// - /// Copies the requested row elements into a new . - /// - /// The row to copy elements from. - /// The column to start copying from. - /// The number of elements to copy. - /// The to copy the column into. - /// If the result is . - /// If is negative, - /// or greater than or equal to the number of columns. - /// If is negative, - /// or greater than or equal to the number of rows. - /// If + - /// is greater than or equal to the number of rows. - /// If is not positive. - /// If result.Count < length. - public override void Row(int rowIndex, int columnIndex, int length, Vector result) - { - if (result == null) - { - throw new ArgumentNullException("result"); - } - - if (rowIndex >= RowCount || rowIndex < 0) - { - throw new ArgumentOutOfRangeException("rowIndex"); - } - - if (columnIndex >= ColumnCount || columnIndex < 0) - { - throw new ArgumentOutOfRangeException("columnIndex"); - } - - if (columnIndex + length > ColumnCount) - { - throw new ArgumentOutOfRangeException("length"); - } - - if (length < 1) - { - throw new ArgumentOutOfRangeException("length", Resources.ArgumentMustBePositive); - } - - if (result.Count < length) - { - throw new ArgumentOutOfRangeException("result", Resources.ArgumentVectorsSameLength); - } - - var rowPointers = _storage.RowPointers; - var values = _storage.Values; - var valueCount = _storage.ValueCount; - - // Determine bounds in columnIndices array where this item should be searched (using rowIndex) - var startIndex = rowPointers[rowIndex]; - var endIndex = rowIndex < rowPointers.Length - 1 ? rowPointers[rowIndex + 1] : valueCount; - - if (startIndex == endIndex) - { - result.Clear(); - } - else - { - // If there are non-zero elements use base class implementation - for (int i = columnIndex, j = 0; i < columnIndex + length; i++, j++) - { - // Copy code from At(row, column) to avoid unnecessary lock - var index = _storage.FindItem(rowIndex, i); - result[j] = index >= 0 ? values[index] : Complex32.Zero; - } - } - } - #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/DiagonalMatrix.cs b/src/Numerics/LinearAlgebra/Double/DiagonalMatrix.cs index 6b916612..0131e9ef 100644 --- a/src/Numerics/LinearAlgebra/Double/DiagonalMatrix.cs +++ b/src/Numerics/LinearAlgebra/Double/DiagonalMatrix.cs @@ -678,118 +678,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double return ret; } - /// - /// Copies the requested column elements into the given vector. - /// - /// The column to copy elements from. - /// The row to start copying from. - /// The number of elements to copy. - /// The to copy the column into. - /// If the result is . - /// If is negative, - /// or greater than or equal to the number of columns. - /// If is negative, - /// or greater than or equal to the number of rows. - /// If + - /// is greater than or equal to the number of rows. - /// If is not positive. - /// If result.Count < length. - public override void Column(int columnIndex, int rowIndex, int length, Vector result) - { - if (result == null) - { - throw new ArgumentNullException("result"); - } - - if (columnIndex >= ColumnCount || columnIndex < 0) - { - throw new ArgumentOutOfRangeException("columnIndex"); - } - - if (rowIndex >= RowCount || rowIndex < 0) - { - throw new ArgumentOutOfRangeException("rowIndex"); - } - - if (rowIndex + length > RowCount) - { - throw new ArgumentOutOfRangeException("length"); - } - - if (length < 1) - { - throw new ArgumentOutOfRangeException("length", Resources.ArgumentMustBePositive); - } - - if (result.Count < length) - { - throw new ArgumentOutOfRangeException("result", Resources.ArgumentVectorsSameLength); - } - - // Clear the result and copy the diagonal entry. - result.Clear(); - if (columnIndex >= rowIndex && columnIndex < rowIndex + length && columnIndex < _data.Length) - { - result[columnIndex - rowIndex] = _data[columnIndex]; - } - } - - /// - /// Copies the requested row elements into a new . - /// - /// The row to copy elements from. - /// The column to start copying from. - /// The number of elements to copy. - /// The to copy the column into. - /// If the result is . - /// If is negative, - /// or greater than or equal to the number of columns. - /// If is negative, - /// or greater than or equal to the number of rows. - /// If + - /// is greater than or equal to the number of rows. - /// If is not positive. - /// If result.Count < length. - public override void Row(int rowIndex, int columnIndex, int length, Vector result) - { - if (result == null) - { - throw new ArgumentNullException("result"); - } - - if (rowIndex >= RowCount || rowIndex < 0) - { - throw new ArgumentOutOfRangeException("rowIndex"); - } - - if (columnIndex >= ColumnCount || columnIndex < 0) - { - throw new ArgumentOutOfRangeException("columnIndex"); - } - - if (columnIndex + length > ColumnCount) - { - throw new ArgumentOutOfRangeException("length"); - } - - if (length < 1) - { - throw new ArgumentOutOfRangeException("length", Resources.ArgumentMustBePositive); - } - - if (result.Count < length) - { - throw new ArgumentOutOfRangeException("result", Resources.ArgumentVectorsSameLength); - } - - // Clear the result and copy the diagonal entry. - result.Clear(); - if (rowIndex >= columnIndex && rowIndex < columnIndex + length && rowIndex < _data.Length) - { - result[rowIndex - columnIndex] = _data[rowIndex]; - } - } - /// Calculates the L1 norm. /// The L1 norm of the matrix. public override double L1Norm() diff --git a/src/Numerics/LinearAlgebra/Double/SparseMatrix.cs b/src/Numerics/LinearAlgebra/Double/SparseMatrix.cs index 42eca740..c890f2dd 100644 --- a/src/Numerics/LinearAlgebra/Double/SparseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Double/SparseMatrix.cs @@ -610,78 +610,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double return norm; } - /// - /// Copies the requested row elements into a new . - /// - /// The row to copy elements from. - /// The column to start copying from. - /// The number of elements to copy. - /// The to copy the column into. - /// If the result is . - /// If is negative, - /// or greater than or equal to the number of columns. - /// If is negative, - /// or greater than or equal to the number of rows. - /// If + - /// is greater than or equal to the number of rows. - /// If is not positive. - /// If result.Count < length. - public override void Row(int rowIndex, int columnIndex, int length, Vector result) - { - if (result == null) - { - throw new ArgumentNullException("result"); - } - - if (rowIndex >= RowCount || rowIndex < 0) - { - throw new ArgumentOutOfRangeException("rowIndex"); - } - - if (columnIndex >= ColumnCount || columnIndex < 0) - { - throw new ArgumentOutOfRangeException("columnIndex"); - } - - if (columnIndex + length > ColumnCount) - { - throw new ArgumentOutOfRangeException("length"); - } - - if (length < 1) - { - throw new ArgumentOutOfRangeException("length", Resources.ArgumentMustBePositive); - } - - if (result.Count < length) - { - throw new ArgumentOutOfRangeException("result", Resources.ArgumentVectorsSameLength); - } - - var rowPointers = _storage.RowPointers; - var values = _storage.Values; - var valueCount = _storage.ValueCount; - - // Determine bounds in columnIndices array where this item should be searched (using rowIndex) - var startIndex = rowPointers[rowIndex]; - var endIndex = rowIndex < rowPointers.Length - 1 ? rowPointers[rowIndex + 1] : valueCount; - - if (startIndex == endIndex) - { - result.Clear(); - } - else - { - // If there are non-zero elements use base class implementation - for (int i = columnIndex, j = 0; i < columnIndex + length; i++, j++) - { - // Copy code from At(row, column) to avoid unnecessary lock - var index = _storage.FindItem(rowIndex, i); - result[j] = index >= 0 ? values[index] : 0d; - } - } - } - #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 4305f742..a6e9db82 100644 --- a/src/Numerics/LinearAlgebra/Generic/Matrix.cs +++ b/src/Numerics/LinearAlgebra/Generic/Matrix.cs @@ -283,7 +283,7 @@ namespace MathNet.Numerics.LinearAlgebra.Generic /// /// A clone of the instance. /// - public virtual Matrix Clone() + public Matrix Clone() { var result = CreateMatrix(RowCount, ColumnCount); Storage.CopyToUnchecked(result.Storage, skipClearing: true); @@ -357,10 +357,15 @@ namespace MathNet.Numerics.LinearAlgebra.Generic /// A Vector containing the copied elements. /// If is negative, /// or greater than or equal to the number of rows. - public virtual Vector Row(int index) + public Vector Row(int index) { + if (index >= RowCount || index < 0) + { + throw new ArgumentOutOfRangeException("index"); + } + var ret = CreateVector(ColumnCount); - Row(index, 0, ColumnCount, ret); + Storage.CopySubRowToUnchecked(ret.Storage, index, 0, 0, ColumnCount); return ret; } @@ -373,9 +378,14 @@ namespace MathNet.Numerics.LinearAlgebra.Generic /// If is negative, /// or greater than or equal to the number of rows. /// If this.Columns != result.Count. - public virtual void Row(int index, Vector result) + public void Row(int index, Vector result) { - Row(index, 0, ColumnCount, result); + if (result == null) + { + throw new ArgumentNullException("result"); + } + + Storage.CopySubRowTo(result.Storage, index, 0, 0, ColumnCount); } /// @@ -392,10 +402,10 @@ namespace MathNet.Numerics.LinearAlgebra.Generic /// or greater than or equal to the number of columns. /// (columnIndex + length) >= Columns. /// If is not positive. - public virtual Vector Row(int rowIndex, int columnIndex, int length) + public Vector Row(int rowIndex, int columnIndex, int length) { var ret = CreateVector(length); - Row(rowIndex, columnIndex, length, ret); + Storage.CopySubRowTo(ret.Storage, rowIndex, columnIndex, 0, length); return ret; } @@ -415,42 +425,14 @@ namespace MathNet.Numerics.LinearAlgebra.Generic /// is greater than or equal to the number of rows. /// If is not positive. /// If result.Count < length. - public virtual void Row(int rowIndex, int columnIndex, int length, Vector result) + public void Row(int rowIndex, int columnIndex, int length, Vector result) { if (result == null) { throw new ArgumentNullException("result"); } - if (rowIndex >= RowCount || rowIndex < 0) - { - throw new ArgumentOutOfRangeException("rowIndex"); - } - - if (columnIndex >= ColumnCount || columnIndex < 0) - { - throw new ArgumentOutOfRangeException("columnIndex"); - } - - if (columnIndex + length > ColumnCount) - { - throw new ArgumentOutOfRangeException("length"); - } - - if (length < 1) - { - throw new ArgumentOutOfRangeException("length", Resources.ArgumentMustBePositive); - } - - if (result.Count < length) - { - throw new ArgumentOutOfRangeException("result", Resources.ArgumentVectorsSameLength); - } - - for (int i = columnIndex, j = 0; i < columnIndex + length; i++, j++) - { - result[j] = At(rowIndex, i); - } + Storage.CopySubRowTo(result.Storage, rowIndex, columnIndex, 0, length); } /// @@ -460,11 +442,16 @@ namespace MathNet.Numerics.LinearAlgebra.Generic /// A Vector containing the copied elements. /// If is negative, /// or greater than or equal to the number of columns. - public virtual Vector Column(int index) + public Vector Column(int index) { - var result = CreateVector(RowCount); - Column(index, 0, RowCount, result); - return result; + if (index >= ColumnCount || index < 0) + { + throw new ArgumentOutOfRangeException("index"); + } + + var ret = CreateVector(RowCount); + Storage.CopySubColumnToUnchecked(ret.Storage, index, 0, 0, RowCount); + return ret; } /// @@ -476,9 +463,14 @@ namespace MathNet.Numerics.LinearAlgebra.Generic /// If is negative, /// or greater than or equal to the number of columns. /// If this.Rows != result.Count. - public virtual void Column(int index, Vector result) + public void Column(int index, Vector result) { - Column(index, 0, RowCount, result); + if (result == null) + { + throw new ArgumentNullException("result"); + } + + Storage.CopySubColumnTo(result.Storage, index, 0, 0, RowCount); } /// @@ -496,11 +488,11 @@ namespace MathNet.Numerics.LinearAlgebra.Generic /// (rowIndex + length) >= Rows. /// /// If is not positive. - public virtual Vector Column(int columnIndex, int rowIndex, int length) + public Vector Column(int columnIndex, int rowIndex, int length) { - var result = CreateVector(length); - Column(columnIndex, rowIndex, length, result); - return result; + var ret = CreateVector(length); + Storage.CopySubColumnTo(ret.Storage, columnIndex, rowIndex, 0, length); + return ret; } /// @@ -519,42 +511,14 @@ namespace MathNet.Numerics.LinearAlgebra.Generic /// is greater than or equal to the number of rows. /// If is not positive. /// If result.Count < length. - public virtual void Column(int columnIndex, int rowIndex, int length, Vector result) + public void Column(int columnIndex, int rowIndex, int length, Vector result) { if (result == null) { throw new ArgumentNullException("result"); } - if (columnIndex >= ColumnCount || columnIndex < 0) - { - throw new ArgumentOutOfRangeException("columnIndex"); - } - - if (rowIndex >= RowCount || rowIndex < 0) - { - throw new ArgumentOutOfRangeException("rowIndex"); - } - - if (rowIndex + length > RowCount) - { - throw new ArgumentOutOfRangeException("length"); - } - - if (length < 1) - { - throw new ArgumentOutOfRangeException("length", Resources.ArgumentMustBePositive); - } - - if (result.Count < length) - { - throw new ArgumentOutOfRangeException("result", Resources.ArgumentVectorsSameLength); - } - - for (int i = rowIndex, j = 0; i < rowIndex + length; i++, j++) - { - result[j] = At(i, columnIndex); - } + Storage.CopySubColumnTo(result.Storage, columnIndex, rowIndex, 0, length); } /// diff --git a/src/Numerics/LinearAlgebra/Single/DiagonalMatrix.cs b/src/Numerics/LinearAlgebra/Single/DiagonalMatrix.cs index 9fb8ca13..940a9d34 100644 --- a/src/Numerics/LinearAlgebra/Single/DiagonalMatrix.cs +++ b/src/Numerics/LinearAlgebra/Single/DiagonalMatrix.cs @@ -678,118 +678,6 @@ namespace MathNet.Numerics.LinearAlgebra.Single return ret; } - /// - /// Copies the requested column elements into the given vector. - /// - /// The column to copy elements from. - /// The row to start copying from. - /// The number of elements to copy. - /// The to copy the column into. - /// If the result is . - /// If is negative, - /// or greater than or equal to the number of columns. - /// If is negative, - /// or greater than or equal to the number of rows. - /// If + - /// is greater than or equal to the number of rows. - /// If is not positive. - /// If result.Count < length. - public override void Column(int columnIndex, int rowIndex, int length, Vector result) - { - if (result == null) - { - throw new ArgumentNullException("result"); - } - - if (columnIndex >= ColumnCount || columnIndex < 0) - { - throw new ArgumentOutOfRangeException("columnIndex"); - } - - if (rowIndex >= RowCount || rowIndex < 0) - { - throw new ArgumentOutOfRangeException("rowIndex"); - } - - if (rowIndex + length > RowCount) - { - throw new ArgumentOutOfRangeException("length"); - } - - if (length < 1) - { - throw new ArgumentOutOfRangeException("length", Resources.ArgumentMustBePositive); - } - - if (result.Count < length) - { - throw new ArgumentOutOfRangeException("result", Resources.ArgumentVectorsSameLength); - } - - // Clear the result and copy the diagonal entry. - result.Clear(); - if (columnIndex >= rowIndex && columnIndex < rowIndex + length && columnIndex < _data.Length) - { - result[columnIndex - rowIndex] = _data[columnIndex]; - } - } - - /// - /// Copies the requested row elements into a new . - /// - /// The row to copy elements from. - /// The column to start copying from. - /// The number of elements to copy. - /// The to copy the column into. - /// If the result is . - /// If is negative, - /// or greater than or equal to the number of columns. - /// If is negative, - /// or greater than or equal to the number of rows. - /// If + - /// is greater than or equal to the number of rows. - /// If is not positive. - /// If result.Count < length. - public override void Row(int rowIndex, int columnIndex, int length, Vector result) - { - if (result == null) - { - throw new ArgumentNullException("result"); - } - - if (rowIndex >= RowCount || rowIndex < 0) - { - throw new ArgumentOutOfRangeException("rowIndex"); - } - - if (columnIndex >= ColumnCount || columnIndex < 0) - { - throw new ArgumentOutOfRangeException("columnIndex"); - } - - if (columnIndex + length > ColumnCount) - { - throw new ArgumentOutOfRangeException("length"); - } - - if (length < 1) - { - throw new ArgumentOutOfRangeException("length", Resources.ArgumentMustBePositive); - } - - if (result.Count < length) - { - throw new ArgumentOutOfRangeException("result", Resources.ArgumentVectorsSameLength); - } - - // Clear the result and copy the diagonal entry. - result.Clear(); - if (rowIndex >= columnIndex && rowIndex < columnIndex + length && rowIndex < _data.Length) - { - result[rowIndex - columnIndex] = _data[rowIndex]; - } - } - /// Calculates the L1 norm. /// The L1 norm of the matrix. public override float L1Norm() diff --git a/src/Numerics/LinearAlgebra/Single/SparseMatrix.cs b/src/Numerics/LinearAlgebra/Single/SparseMatrix.cs index b9039618..824df4d1 100644 --- a/src/Numerics/LinearAlgebra/Single/SparseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Single/SparseMatrix.cs @@ -610,78 +610,6 @@ namespace MathNet.Numerics.LinearAlgebra.Single return norm; } - /// - /// Copies the requested row elements into a new . - /// - /// The row to copy elements from. - /// The column to start copying from. - /// The number of elements to copy. - /// The to copy the column into. - /// If the result is . - /// If is negative, - /// or greater than or equal to the number of columns. - /// If is negative, - /// or greater than or equal to the number of rows. - /// If + - /// is greater than or equal to the number of rows. - /// If is not positive. - /// If result.Count < length. - public override void Row(int rowIndex, int columnIndex, int length, Vector result) - { - if (result == null) - { - throw new ArgumentNullException("result"); - } - - if (rowIndex >= RowCount || rowIndex < 0) - { - throw new ArgumentOutOfRangeException("rowIndex"); - } - - if (columnIndex >= ColumnCount || columnIndex < 0) - { - throw new ArgumentOutOfRangeException("columnIndex"); - } - - if (columnIndex + length > ColumnCount) - { - throw new ArgumentOutOfRangeException("length"); - } - - if (length < 1) - { - throw new ArgumentOutOfRangeException("length", Resources.ArgumentMustBePositive); - } - - if (result.Count < length) - { - throw new ArgumentOutOfRangeException("result", Resources.ArgumentVectorsSameLength); - } - - var rowPointers = _storage.RowPointers; - var values = _storage.Values; - var valueCount = _storage.ValueCount; - - // Determine bounds in columnIndices array where this item should be searched (using rowIndex) - var startIndex = rowPointers[rowIndex]; - var endIndex = rowIndex < rowPointers.Length - 1 ? rowPointers[rowIndex + 1] : valueCount; - - if (startIndex == endIndex) - { - result.Clear(); - } - else - { - // If there are non-zero elements use base class implementation - for (int i = columnIndex, j = 0; i < columnIndex + length; i++, j++) - { - // Copy code from At(row, column) to avoid unnecessary lock - var index = _storage.FindItem(rowIndex, i); - result[j] = index >= 0 ? values[index] : 0f; - } - } - } - #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/DenseColumnMajorMatrixStorage.cs b/src/Numerics/LinearAlgebra/Storage/DenseColumnMajorMatrixStorage.cs index 4bd4f658..fc1f4dce 100644 --- a/src/Numerics/LinearAlgebra/Storage/DenseColumnMajorMatrixStorage.cs +++ b/src/Numerics/LinearAlgebra/Storage/DenseColumnMajorMatrixStorage.cs @@ -121,5 +121,53 @@ namespace MathNet.Numerics.LinearAlgebra.Storage Array.Copy(Data, j*RowCount + sourceRowIndex, target.Data, jj*target.RowCount + targetRowIndex, rowCount); } } + + internal override void CopySubRowToUnchecked(VectorStorage target, int rowIndex, int sourceColumnIndex, int targetColumnIndex, int columnCount, bool skipClearing = false) + { + var denseTarget = target as DenseVectorStorage; + if (denseTarget != null) + { + CopySubRowToUnchecked(denseTarget, rowIndex, sourceColumnIndex, targetColumnIndex, columnCount); + return; + } + + // FALL BACK + + for (int j = sourceColumnIndex, jj = targetColumnIndex; j < sourceColumnIndex + columnCount; j++, jj++) + { + target.At(jj, Data[(j * RowCount) + rowIndex]); + } + } + + void CopySubRowToUnchecked(DenseVectorStorage target, int rowIndex, int sourceColumnIndex, int targetColumnIndex, int columnCount, bool skipClearing = false) + { + for (int j = 0; j target, int columnIndex, int sourceRowIndex, int targetRowIndex, int rowCount, bool skipClearing = false) + { + var denseTarget = target as DenseVectorStorage; + if (denseTarget != null) + { + CopySubColumnToUnchecked(denseTarget, columnIndex, sourceRowIndex, targetRowIndex, rowCount); + return; + } + + // FALL BACK + + var offset = columnIndex * RowCount; + for (int i = sourceRowIndex, ii = targetRowIndex; i < sourceRowIndex + rowCount; i++, ii++) + { + target.At(ii, Data[offset + i]); + } + } + + void CopySubColumnToUnchecked(DenseVectorStorage target, int columnIndex, int sourceRowIndex, int targetRowIndex, int rowCount, bool skipClearing = false) + { + Array.Copy(Data, columnIndex*RowCount + sourceRowIndex, target.Data, targetRowIndex, rowCount); + } } } diff --git a/src/Numerics/LinearAlgebra/Storage/DiagonalMatrixStorage.cs b/src/Numerics/LinearAlgebra/Storage/DiagonalMatrixStorage.cs index 78a19d23..0d2132e0 100644 --- a/src/Numerics/LinearAlgebra/Storage/DiagonalMatrixStorage.cs +++ b/src/Numerics/LinearAlgebra/Storage/DiagonalMatrixStorage.cs @@ -355,5 +355,35 @@ namespace MathNet.Numerics.LinearAlgebra.Storage // else: all zero, nop } + + internal override void CopySubRowToUnchecked(VectorStorage target, int rowIndex, + int sourceColumnIndex, int targetColumnIndex, int columnCount, + bool skipClearing = false) + { + if (!skipClearing) + { + target.Clear(targetColumnIndex, columnCount); + } + + if (rowIndex >= sourceColumnIndex && rowIndex < sourceColumnIndex + columnCount && rowIndex < Data.Length) + { + target.At(rowIndex - sourceColumnIndex + targetColumnIndex, Data[rowIndex]); + } + } + + internal override void CopySubColumnToUnchecked(VectorStorage target, int columnIndex, + int sourceRowIndex, int targetRowIndex, int rowCount, + bool skipClearing = false) + { + if (!skipClearing) + { + target.Clear(targetRowIndex, rowCount); + } + + if (columnIndex >= sourceRowIndex && columnIndex < sourceRowIndex + rowCount && columnIndex < Data.Length) + { + target.At(columnIndex - sourceRowIndex + targetRowIndex, Data[columnIndex]); + } + } } } diff --git a/src/Numerics/LinearAlgebra/Storage/MatrixStorage.Validation.cs b/src/Numerics/LinearAlgebra/Storage/MatrixStorage.Validation.cs index 1d962b4b..437e7753 100644 --- a/src/Numerics/LinearAlgebra/Storage/MatrixStorage.Validation.cs +++ b/src/Numerics/LinearAlgebra/Storage/MatrixStorage.Validation.cs @@ -3,10 +3,10 @@ using MathNet.Numerics.Properties; namespace MathNet.Numerics.LinearAlgebra.Storage { - // ReSharper disable UnusedParameter.Global + // ReSharper disable UnusedParameter.Local public partial class MatrixStorage { - protected void ValidateRange(int row, int column) + void ValidateRange(int row, int column) { if (row < 0 || row >= RowCount) { @@ -19,7 +19,7 @@ namespace MathNet.Numerics.LinearAlgebra.Storage } } - protected void ValidateSubMatrixRange(MatrixStorage target, + void ValidateSubMatrixRange(MatrixStorage target, int sourceRowIndex, int targetRowIndex, int rowCount, int sourceColumnIndex, int targetColumnIndex, int columnCount) { @@ -83,6 +83,82 @@ namespace MathNet.Numerics.LinearAlgebra.Storage throw new ArgumentOutOfRangeException("columnCount"); } } + + void ValidateSubRowRange(VectorStorage target, int rowIndex, + int sourceColumnIndex, int targetColumnIndex, int columnCount) + { + if (columnCount < 1) + { + throw new ArgumentOutOfRangeException("columnCount", Resources.ArgumentMustBePositive); + } + + // Verify Source + + if (rowIndex >= RowCount || rowIndex < 0) + { + throw new ArgumentOutOfRangeException("rowIndex"); + } + + if (sourceColumnIndex >= ColumnCount || sourceColumnIndex < 0) + { + throw new ArgumentOutOfRangeException("sourceColumnIndex"); + } + + if (sourceColumnIndex + columnCount > ColumnCount) + { + throw new ArgumentOutOfRangeException("columnCount"); + } + + // Verify Target + + if (targetColumnIndex >= target.Length || targetColumnIndex < 0) + { + throw new ArgumentOutOfRangeException("targetColumnIndex"); + } + + if (targetColumnIndex + columnCount > target.Length) + { + throw new ArgumentOutOfRangeException("columnCount"); + } + } + + void ValidateSubColumnRange(VectorStorage target, int columnIndex, + int sourceRowIndex, int targetRowIndex, int rowCount) + { + if (rowCount < 1) + { + throw new ArgumentOutOfRangeException("rowCount", Resources.ArgumentMustBePositive); + } + + // Verify Source + + if (columnIndex >= ColumnCount || columnIndex < 0) + { + throw new ArgumentOutOfRangeException("columnIndex"); + } + + if (sourceRowIndex >= RowCount || sourceRowIndex < 0) + { + throw new ArgumentOutOfRangeException("sourceRowIndex"); + } + + if (sourceRowIndex + rowCount > RowCount) + { + throw new ArgumentOutOfRangeException("rowCount"); + } + + // Verify Target + + if (targetRowIndex >= target.Length || targetRowIndex < 0) + { + throw new ArgumentOutOfRangeException("targetRowIndex"); + } + + if (targetRowIndex + rowCount > target.Length) + { + throw new ArgumentOutOfRangeException("rowCount"); + } + } } - // ReSharper restore UnusedParameter.Global + // ReSharper restore UnusedParameter.Local } diff --git a/src/Numerics/LinearAlgebra/Storage/MatrixStorage.cs b/src/Numerics/LinearAlgebra/Storage/MatrixStorage.cs index b5ce7f2d..138df142 100644 --- a/src/Numerics/LinearAlgebra/Storage/MatrixStorage.cs +++ b/src/Numerics/LinearAlgebra/Storage/MatrixStorage.cs @@ -263,5 +263,53 @@ namespace MathNet.Numerics.LinearAlgebra.Storage } } } + + public void CopySubRowTo(VectorStorage target, int rowIndex, + int sourceColumnIndex, int targetColumnIndex, int columnCount, + bool skipClearing = false) + { + if (target == null) + { + throw new ArgumentNullException("target"); + } + + ValidateSubRowRange(target, rowIndex, sourceColumnIndex, targetColumnIndex, columnCount); + + CopySubRowToUnchecked(target, rowIndex, sourceColumnIndex, targetColumnIndex, columnCount, skipClearing); + } + + internal virtual void CopySubRowToUnchecked(VectorStorage target, int rowIndex, + int sourceColumnIndex, int targetColumnIndex, int columnCount, + bool skipClearing = false) + { + for (int j = sourceColumnIndex, jj = targetColumnIndex; j < sourceColumnIndex + columnCount; j++, jj++) + { + target.At(jj, At(rowIndex, j)); + } + } + + public void CopySubColumnTo(VectorStorage target, int columnIndex, + int sourceRowIndex, int targetRowIndex, int rowCount, + bool skipClearing = false) + { + if (target == null) + { + throw new ArgumentNullException("target"); + } + + ValidateSubColumnRange(target, columnIndex, sourceRowIndex, targetRowIndex, rowCount); + + CopySubColumnToUnchecked(target, columnIndex, sourceRowIndex, targetRowIndex, rowCount, skipClearing); + } + + internal virtual void CopySubColumnToUnchecked(VectorStorage target, int columnIndex, + int sourceRowIndex, int targetRowIndex, int rowCount, + bool skipClearing = false) + { + for (int i = sourceRowIndex, ii = targetRowIndex; i < sourceRowIndex + rowCount; i++, ii++) + { + target.At(ii, At(i, columnIndex)); + } + } } } diff --git a/src/Numerics/LinearAlgebra/Storage/SparseCompressedRowMatrixStorage.cs b/src/Numerics/LinearAlgebra/Storage/SparseCompressedRowMatrixStorage.cs index d0fa9599..fce72d20 100644 --- a/src/Numerics/LinearAlgebra/Storage/SparseCompressedRowMatrixStorage.cs +++ b/src/Numerics/LinearAlgebra/Storage/SparseCompressedRowMatrixStorage.cs @@ -432,15 +432,6 @@ namespace MathNet.Numerics.LinearAlgebra.Storage // FALL BACK - if (ReferenceEquals(this, target)) - { - throw new NotSupportedException(); - } - - ValidateSubMatrixRange(target, - sourceRowIndex, targetRowIndex, rowCount, - sourceColumnIndex, targetColumnIndex, columnCount); - if (!skipClearing) { target.Clear(targetRowIndex, rowCount, targetColumnIndex, columnCount); @@ -468,15 +459,6 @@ namespace MathNet.Numerics.LinearAlgebra.Storage 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; @@ -542,5 +524,31 @@ namespace MathNet.Numerics.LinearAlgebra.Storage } } } + + internal override void CopySubRowToUnchecked(VectorStorage target, int rowIndex, + int sourceColumnIndex, int targetColumnIndex, int columnCount, + bool skipClearing = false) + { + if (!skipClearing) + { + target.Clear(targetColumnIndex, columnCount); + } + + // Determine bounds in columnIndices array where this item should be searched (using rowIndex) + var startIndex = RowPointers[rowIndex]; + var endIndex = rowIndex < RowPointers.Length - 1 ? RowPointers[rowIndex + 1] : ValueCount; + + if (startIndex == endIndex) + { + return; + } + + // If there are non-zero elements use base class implementation + for (int i = sourceColumnIndex, j = 0; i < sourceColumnIndex + columnCount; i++, j++) + { + var index = FindItem(rowIndex, i); + target.At(j, index >= 0 ? Values[index] : _zero); + } + } } }