From 5fbb3e3607b2e78cff115fdd3a61851e1d912162 Mon Sep 17 00:00:00 2001 From: Christoph Ruegg Date: Sat, 2 Feb 2013 19:47:37 +0100 Subject: [PATCH] Cosmetics: Matrix class structure (no code changes) --- src/Numerics/LinearAlgebra/Generic/Matrix.cs | 699 +++++++++---------- 1 file changed, 335 insertions(+), 364 deletions(-) diff --git a/src/Numerics/LinearAlgebra/Generic/Matrix.cs b/src/Numerics/LinearAlgebra/Generic/Matrix.cs index 876f5332..4f65922a 100644 --- a/src/Numerics/LinearAlgebra/Generic/Matrix.cs +++ b/src/Numerics/LinearAlgebra/Generic/Matrix.cs @@ -35,8 +35,6 @@ namespace MathNet.Numerics.LinearAlgebra.Generic using Numerics; using Properties; using Storage; - using Threading; - /// /// Defines the base class for Matrix classes. @@ -290,6 +288,19 @@ namespace MathNet.Numerics.LinearAlgebra.Generic return result; } +#if !PORTABLE + /// + /// Creates a new object that is a copy of the current instance. + /// + /// + /// A new object that is a copy of this instance. + /// + object ICloneable.Clone() + { + return Clone(); + } +#endif + /// /// Copies the elements of this matrix to the given matrix. /// @@ -339,17 +350,6 @@ namespace MathNet.Numerics.LinearAlgebra.Generic /// public abstract Vector CreateVector(int size, bool fullyMutable = false); - /// - /// Returns a that represents this instance. - /// - /// - /// A that represents this instance. - /// - public override string ToString() - { - return ToString(null); - } - /// /// Copies a row into an Vector. /// @@ -400,7 +400,7 @@ namespace MathNet.Numerics.LinearAlgebra.Generic /// or greater than or equal to the number of rows. /// is negative, /// or greater than or equal to the number of columns. - /// (columnIndex + length) >= Columns. + /// (columnIndex + length) >= Columns. /// If is not positive. public Vector Row(int rowIndex, int columnIndex, int length) { @@ -418,10 +418,10 @@ namespace MathNet.Numerics.LinearAlgebra.Generic /// The Vector to copy the column into. /// If the result Vector is . /// If is negative, - /// or greater than or equal to the number of columns. + /// or greater than or equal to the number of columns. /// If is negative, - /// or greater than or equal to the number of rows. - /// If + + /// 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. @@ -486,7 +486,7 @@ namespace MathNet.Numerics.LinearAlgebra.Generic /// is negative, /// or greater than or equal to the number of rows. /// (rowIndex + length) >= Rows. - /// + /// /// If is not positive. public Vector Column(int columnIndex, int rowIndex, int length) { @@ -504,10 +504,10 @@ namespace MathNet.Numerics.LinearAlgebra.Generic /// The Vector to copy the column into. /// If the result Vector is . /// If is negative, - /// or greater than or equal to the number of columns. + /// or greater than or equal to the number of columns. /// If is negative, - /// or greater than or equal to the number of rows. - /// If + + /// 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. @@ -521,10 +521,29 @@ namespace MathNet.Numerics.LinearAlgebra.Generic Storage.CopySubColumnTo(result.Storage, columnIndex, rowIndex, 0, length); } + /// + /// Returns a new matrix containing the upper triangle of this matrix. + /// + /// The upper triangle of this matrix. + public virtual Matrix UpperTriangle() + { + var ret = CreateMatrix(RowCount, ColumnCount); + + for (var row = 0; row < RowCount; row++) + { + for (var column = row; column < ColumnCount; column++) + { + ret.At(row, column, At(row, column)); + } + } + + return ret; + } + /// /// Returns a new matrix containing the lower triangle of this matrix. /// - /// The lower triangle of this matrix. + /// The lower triangle of this matrix. public virtual Matrix LowerTriangle() { var ret = CreateMatrix(RowCount, ColumnCount); @@ -567,25 +586,6 @@ namespace MathNet.Numerics.LinearAlgebra.Generic } } - /// - /// Returns a new matrix containing the upper triangle of this matrix. - /// - /// The upper triangle of this matrix. - public virtual Matrix UpperTriangle() - { - var ret = CreateMatrix(RowCount, ColumnCount); - - for (var row = 0; row < RowCount; row++) - { - for (var column = row; column < ColumnCount; column++) - { - ret.At(row, column, At(row, column)); - } - } - - return ret; - } - /// /// Puts the upper triangle of this matrix into the result matrix. /// @@ -623,10 +623,10 @@ namespace MathNet.Numerics.LinearAlgebra.Generic /// The requested sub-matrix. /// If: is /// negative, or greater than or equal to the number of rows. - /// is negative, or greater than or equal to the number + /// is negative, or greater than or equal to the number /// of columns. /// (columnIndex + columnLength) >= Columns - /// (rowIndex + rowLength) >= Rows + /// (rowIndex + rowLength) >= Rows /// If or /// is not positive. public virtual Matrix SubMatrix(int rowIndex, int rowCount, int columnIndex, int columnCount) @@ -636,105 +636,6 @@ namespace MathNet.Numerics.LinearAlgebra.Generic return target; } - /// - /// Returns an that enumerates over the matrix columns. - /// - /// An that enumerates over the matrix columns - /// - public virtual IEnumerable>> ColumnEnumerator() - { - for (var i = 0; i < ColumnCount; i++) - { - yield return new Tuple>(i, Column(i)); - } - } - - /// - /// Returns an that enumerates the requested matrix columns. - /// - /// The column to start enumerating over. - /// The number of columns to enumerating over. - /// An that enumerates over requested matrix columns. - /// - /// If: - /// is negative, - /// or greater than or equal to the number of columns. - /// (index + length) >= Columns. - /// - /// If is not positive. - public virtual IEnumerable>> ColumnEnumerator(int index, int length) - { - if (index >= ColumnCount || index < 0) - { - throw new ArgumentOutOfRangeException("index"); - } - - if (index + length > ColumnCount) - { - throw new ArgumentOutOfRangeException("length"); - } - - if (length < 1) - { - throw new ArgumentException(Resources.ArgumentMustBePositive, "length"); - } - - var maxIndex = index + length; - for (var i = index; i < maxIndex; i++) - { - yield return new Tuple>(i, Column(i)); - } - } - - /// - /// Returns an that enumerates the requested matrix rows. - /// - /// The row to start enumerating over. - /// The number of rows to enumerating over. - /// An that enumerates over requested matrix rows. - /// - /// If: - /// is negative, - /// or greater than or equal to the number of rows. - /// (index + length) >= Rows. - /// If is not positive. - public virtual IEnumerable>> RowEnumerator(int index, int length) - { - if (index >= RowCount || index < 0) - { - throw new ArgumentOutOfRangeException("index"); - } - - if (index + length > RowCount) - { - throw new ArgumentOutOfRangeException("length"); - } - - if (length < 1) - { - throw new ArgumentException(Resources.ArgumentMustBePositive, "length"); - } - - var maxi = index + length; - for (var i = index; i < maxi; i++) - { - yield return new Tuple>(i, Row(i)); - } - } - - /// - /// Returns an that enumerates over the matrix rows. - /// - /// An that enumerates over the matrix rows - /// - public virtual IEnumerable>> RowEnumerator() - { - for (var i = 0; i < RowCount; i++) - { - yield return new Tuple>(i, Row(i)); - } - } - /// /// Returns the elements of the diagonal in a Vector. /// @@ -896,7 +797,7 @@ namespace MathNet.Numerics.LinearAlgebra.Generic /// /// The column to copy the values to. /// The array to copy the values from. - /// If is . + /// If is . /// If is less than zero, /// or greater than or equal to the number of columns. /// If the size of does not @@ -931,7 +832,7 @@ namespace MathNet.Numerics.LinearAlgebra.Generic /// /// The column to copy the values to. /// The vector to copy the values from. - /// If is . + /// If is . /// If is less than zero, /// or greater than or equal to the number of columns. /// If the size of does not @@ -1007,7 +908,7 @@ namespace MathNet.Numerics.LinearAlgebra.Generic /// /// The row to copy the values to. /// The vector to copy the values from. - /// If is . + /// If is . /// If is less than zero, /// or greater than or equal to the number of rows. /// If the size of does not @@ -1040,7 +941,7 @@ namespace MathNet.Numerics.LinearAlgebra.Generic /// /// The row to copy the values to. /// The array to copy the values from. - /// If is . + /// If is . /// If is less than zero, /// or greater than or equal to the number of rows. /// If the size of does not @@ -1078,10 +979,10 @@ namespace MathNet.Numerics.LinearAlgebra.Generic /// The sub-matrix to copy from. /// If: is /// negative, or greater than or equal to the number of rows. - /// is negative, or greater than or equal to the number + /// is negative, or greater than or equal to the number /// of columns. /// (columnIndex + columnLength) >= Columns - /// (rowIndex + rowLength) >= Rows + /// (rowIndex + rowLength) >= Rows /// If is /// the size of is not at least x . /// If or @@ -1101,7 +1002,7 @@ namespace MathNet.Numerics.LinearAlgebra.Generic /// /// The vector to copy the values from. The length of the vector should be /// Min(Rows, Columns). - /// If is . + /// If is . /// If the length of does not /// equal Min(Rows, Columns). /// For non-square matrices, the elements of are copied to @@ -1131,7 +1032,7 @@ namespace MathNet.Numerics.LinearAlgebra.Generic /// /// The array to copy the values from. The length of the vector should be /// Min(Rows, Columns). - /// If is . + /// If is . /// If the length of does not /// equal Min(Rows, Columns). /// For non-square matrices, the elements of are copied to @@ -1157,221 +1058,71 @@ namespace MathNet.Numerics.LinearAlgebra.Generic } /// - /// Returns this matrix as a multidimensional array. + /// Returns the transpose of this matrix. /// - /// A multidimensional containing the values of this matrix. - public T[,] ToArray() + /// The transpose of this matrix. + public virtual Matrix Transpose() { - return Storage.ToArray(); - } + var ret = CreateMatrix(ColumnCount, RowCount); + for (var j = 0; j < ColumnCount; j++) + { + for (var i = 0; i < RowCount; i++) + { + ret.At(j, i, At(i, j)); + } + } - /// - /// Returns the matrix's elements as an array with the data laid out column-wise. - /// - ///
-        /// 1, 2, 3
-        /// 4, 5, 6  will be returned as  1, 4, 7, 2, 5, 8, 3, 6, 9
-        /// 7, 8, 9
-        /// 
- /// An array containing the matrix's elements. - public T[] ToColumnWiseArray() - { - return Storage.ToColumnMajorArray(); + return ret; } /// - /// Returns the matrix's elements as an array with the data laid row-wise. + /// Returns the conjugate transpose of this matrix. /// - ///
-        /// 1, 2, 3
-        /// 4, 5, 6  will be returned as  1, 2, 3, 4, 5, 6, 7, 8, 9
-        /// 7, 8, 9
-        /// 
- /// An array containing the matrix's elements. - public T[] ToRowWiseArray() - { - return Storage.ToRowMajorArray(); - } - - #region Implemented Interfaces - -#if !PORTABLE - - #region ICloneable + /// The conjugate transpose of this matrix. + public abstract Matrix ConjugateTranspose(); /// - /// Creates a new object that is a copy of the current instance. + /// Permute the rows of a matrix according to a permutation. /// - /// - /// A new object that is a copy of this instance. - /// - object ICloneable.Clone() + /// The row permutation to apply to this matrix. + public virtual void PermuteRows(Permutation p) { - return Clone(); - } - - #endregion + if (p.Dimension != RowCount) + { + throw new ArgumentException(Resources.ArgumentArraysSameLength, "p"); + } -#endif + // Get a sequence of inversions from the permutation. + var inv = p.ToInversions(); - #region IEquatable> + for (var i = 0; i < inv.Length; i++) + { + if (inv[i] != i) + { + var q = inv[i]; + for (var j = 0; j < ColumnCount; j++) + { + var temp = At(q, j); + At(q, j, At(i, j)); + At(i, j, temp); + } + } + } + } /// - /// Indicates whether the current object is equal to another object of the same type. + /// Permute the columns of a matrix according to a permutation. /// - /// - /// An object to compare with this object. - /// - /// - /// true if the current object is equal to the parameter; otherwise, false. - /// - public bool Equals(Matrix other) + /// The column permutation to apply to this matrix. + public virtual void PermuteColumns(Permutation p) { - if (other == null) + if (p.Dimension != ColumnCount) { - return false; + throw new ArgumentException(Resources.ArgumentArraysSameLength, "p"); } - return Storage.Equals(other.Storage); - } - - #endregion - - #region IFormattable - - /// - /// Returns a that represents this instance. - /// - /// - /// The format to use. - /// - /// - /// The format provider to use. - /// - /// - /// A that represents this instance. - /// - public virtual string ToString(string format, IFormatProvider formatProvider = null) - { - var stringBuilder = new StringBuilder(); - for (var row = 0; row < RowCount; row++) - { - for (var column = 0; column < ColumnCount; column++) - { - stringBuilder.Append(At(row, column).ToString(format, formatProvider)); - if (column != ColumnCount - 1) - { - stringBuilder.Append(formatProvider.GetTextInfo().ListSeparator); - } - } - - if (row != RowCount - 1) - { - stringBuilder.Append(Environment.NewLine); - } - } - - return stringBuilder.ToString(); - } - - #endregion - - #endregion - - #region System.Object overrides - - /// - /// Determines whether the specified is equal to this instance. - /// - /// The to compare with this instance. - /// - /// true if the specified is equal to this instance; otherwise, false. - /// - public override bool Equals(object obj) - { - var other = obj as Matrix; - return other != null && Storage.Equals(other.Storage); - } - - /// - /// Returns a hash code for this instance. - /// - /// - /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. - /// - public override int GetHashCode() - { - return Storage.GetHashCode(); - } - - #endregion - - /// - /// Returns the transpose of this matrix. - /// - /// The transpose of this matrix. - public virtual Matrix Transpose() - { - var ret = CreateMatrix(ColumnCount, RowCount); - for (var j = 0; j < ColumnCount; j++) - { - for (var i = 0; i < RowCount; i++) - { - ret.At(j, i, At(i, j)); - } - } - - return ret; - } - - /// - /// Returns the conjugate transpose of this matrix. - /// - /// The conjugate transpose of this matrix. - public abstract Matrix ConjugateTranspose(); - - /// - /// Permute the rows of a matrix according to a permutation. - /// - /// The row permutation to apply to this matrix. - public virtual void PermuteRows(Permutation p) - { - if (p.Dimension != RowCount) - { - throw new ArgumentException(Resources.ArgumentArraysSameLength, "p"); - } - - // Get a sequence of inversions from the permutation. - var inv = p.ToInversions(); - - for (var i = 0; i < inv.Length; i++) - { - if (inv[i] != i) - { - var q = inv[i]; - for (var j = 0; j < ColumnCount; j++) - { - var temp = At(q, j); - At(q, j, At(i, j)); - At(i, j, temp); - } - } - } - } - - /// - /// Permute the columns of a matrix according to a permutation. - /// - /// The column permutation to apply to this matrix. - public virtual void PermuteColumns(Permutation p) - { - if (p.Dimension != ColumnCount) - { - throw new ArgumentException(Resources.ArgumentArraysSameLength, "p"); - } - - // Get a sequence of inversions from the permutation. - var inv = p.ToInversions(); + // Get a sequence of inversions from the permutation. + var inv = p.ToInversions(); for (var i = 0; i < inv.Length; i++) { @@ -1501,7 +1252,7 @@ namespace MathNet.Numerics.LinearAlgebra.Generic } /// - /// Diagonally stacks his matrix on top of the given matrix. The new matrix is a M-by-N matrix, + /// 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. /// @@ -1555,8 +1306,8 @@ namespace MathNet.Numerics.LinearAlgebra.Generic public abstract T L1Norm(); /// Calculates the L2 norm. - /// The L2 norm of the matrix. - /// For sparse matrices, the L2 norm is computed using a dense implementation of singular value decomposition. + /// The L2 norm of the matrix. + /// For sparse matrices, the L2 norm is computed using a dense implementation of singular value decomposition. /// In a later release, it will be replaced with a sparse implementation. public virtual T L2Norm() { @@ -1568,24 +1319,9 @@ namespace MathNet.Numerics.LinearAlgebra.Generic public abstract T FrobeniusNorm(); /// Calculates the infinity norm of this matrix. - /// The infinity norm of this matrix. + /// The infinity norm of this matrix. public abstract T InfinityNorm(); - /// - /// Iterates throw each element in the matrix (row-wise). - /// - /// The value at the current iteration along with its position (row, column, value). - public virtual IEnumerable> IndexedEnumerator() - { - for (var row = 0; row < RowCount; row++) - { - for (var column = 0; column < ColumnCount; column++) - { - yield return new Tuple(row, column, At(row, column)); - } - } - } - /// /// Gets a value indicating whether this matrix is symmetric. /// @@ -1612,5 +1348,240 @@ namespace MathNet.Numerics.LinearAlgebra.Generic return true; } } + + /// + /// Returns an that enumerates over the matrix columns. + /// + /// An that enumerates over the matrix columns + /// + public virtual IEnumerable>> ColumnEnumerator() + { + for (var i = 0; i < ColumnCount; i++) + { + yield return new Tuple>(i, Column(i)); + } + } + + /// + /// Returns an that enumerates the requested matrix columns. + /// + /// The column to start enumerating over. + /// The number of columns to enumerating over. + /// An that enumerates over requested matrix columns. + /// + /// If: + /// is negative, + /// or greater than or equal to the number of columns. + /// (index + length) >= Columns. + /// + /// If is not positive. + public virtual IEnumerable>> ColumnEnumerator(int index, int length) + { + if (index >= ColumnCount || index < 0) + { + throw new ArgumentOutOfRangeException("index"); + } + + if (index + length > ColumnCount) + { + throw new ArgumentOutOfRangeException("length"); + } + + if (length < 1) + { + throw new ArgumentException(Resources.ArgumentMustBePositive, "length"); + } + + var maxIndex = index + length; + for (var i = index; i < maxIndex; i++) + { + yield return new Tuple>(i, Column(i)); + } + } + + /// + /// Returns an that enumerates the requested matrix rows. + /// + /// The row to start enumerating over. + /// The number of rows to enumerating over. + /// An that enumerates over requested matrix rows. + /// + /// If: + /// is negative, + /// or greater than or equal to the number of rows. + /// (index + length) >= Rows. + /// If is not positive. + public virtual IEnumerable>> RowEnumerator(int index, int length) + { + if (index >= RowCount || index < 0) + { + throw new ArgumentOutOfRangeException("index"); + } + + if (index + length > RowCount) + { + throw new ArgumentOutOfRangeException("length"); + } + + if (length < 1) + { + throw new ArgumentException(Resources.ArgumentMustBePositive, "length"); + } + + var maxi = index + length; + for (var i = index; i < maxi; i++) + { + yield return new Tuple>(i, Row(i)); + } + } + + /// + /// Returns an that enumerates over the matrix rows. + /// + /// An that enumerates over the matrix rows + /// + public virtual IEnumerable>> RowEnumerator() + { + for (var i = 0; i < RowCount; i++) + { + yield return new Tuple>(i, Row(i)); + } + } + + /// + /// Iterates throw each element in the matrix (row-wise). + /// + /// The value at the current iteration along with its position (row, column, value). + public virtual IEnumerable> IndexedEnumerator() + { + for (var row = 0; row < RowCount; row++) + { + for (var column = 0; column < ColumnCount; column++) + { + yield return new Tuple(row, column, At(row, column)); + } + } + } + + /// + /// Returns this matrix as a multidimensional array. + /// + /// A multidimensional containing the values of this matrix. + public T[,] ToArray() + { + return Storage.ToArray(); + } + + /// + /// Returns the matrix's elements as an array with the data laid out column-wise. + /// + ///
+        /// 1, 2, 3
+        /// 4, 5, 6  will be returned as  1, 4, 7, 2, 5, 8, 3, 6, 9
+        /// 7, 8, 9
+        /// 
+ /// An array containing the matrix's elements. + public T[] ToColumnWiseArray() + { + return Storage.ToColumnMajorArray(); + } + + /// + /// Returns the matrix's elements as an array with the data laid row-wise. + /// + ///
+        /// 1, 2, 3
+        /// 4, 5, 6  will be returned as  1, 2, 3, 4, 5, 6, 7, 8, 9
+        /// 7, 8, 9
+        /// 
+ /// An array containing the matrix's elements. + public T[] ToRowWiseArray() + { + return Storage.ToRowMajorArray(); + } + + /// + /// Returns a that represents this instance. + /// + /// + /// A that represents this instance. + /// + public override string ToString() + { + return ToString(null); + } + + /// + /// Returns a that represents this instance. + /// + /// + /// The format to use. + /// + /// + /// The format provider to use. + /// + /// + /// A that represents this instance. + /// + public virtual string ToString(string format, IFormatProvider formatProvider = null) + { + var stringBuilder = new StringBuilder(); + for (var row = 0; row < RowCount; row++) + { + for (var column = 0; column < ColumnCount; column++) + { + stringBuilder.Append(At(row, column).ToString(format, formatProvider)); + if (column != ColumnCount - 1) + { + stringBuilder.Append(formatProvider.GetTextInfo().ListSeparator); + } + } + + if (row != RowCount - 1) + { + stringBuilder.Append(Environment.NewLine); + } + } + + return stringBuilder.ToString(); + } + + /// + /// Returns a hash code for this instance. + /// + /// + /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. + /// + public override int GetHashCode() + { + return Storage.GetHashCode(); + } + + /// + /// Indicates whether the current object is equal to another object of the same type. + /// + /// + /// An object to compare with this object. + /// + /// + /// true if the current object is equal to the parameter; otherwise, false. + /// + public bool Equals(Matrix other) + { + return other != null && Storage.Equals(other.Storage); + } + + /// + /// Determines whether the specified is equal to this instance. + /// + /// The to compare with this instance. + /// + /// true if the specified is equal to this instance; otherwise, false. + /// + public override bool Equals(object obj) + { + var other = obj as Matrix; + return other != null && Storage.Equals(other.Storage); + } } }