From 722611725f48fa4b4e823ad4f59c3f369efcef0a Mon Sep 17 00:00:00 2001 From: Marcus Cuda Date: Mon, 27 Jun 2011 21:04:13 +0800 Subject: [PATCH] added methods to create matrices from a list of vectors. work items: 5691 --- src/Numerics/LinearAlgebra/Generic/Matrix.cs | 85 ++++++++++++++++++- .../LinearAlgebraTests/Complex/MatrixTests.cs | 66 ++++++++++++++ .../Complex32/MatrixTests.cs | 66 ++++++++++++++ .../Double/DenseMatrixTests.cs | 2 +- .../LinearAlgebraTests/Double/MatrixTests.cs | 66 ++++++++++++++ .../LinearAlgebraTests/Single/MatrixTests.cs | 66 ++++++++++++++ 6 files changed, 346 insertions(+), 5 deletions(-) diff --git a/src/Numerics/LinearAlgebra/Generic/Matrix.cs b/src/Numerics/LinearAlgebra/Generic/Matrix.cs index e2df0170..1f0322a5 100644 --- a/src/Numerics/LinearAlgebra/Generic/Matrix.cs +++ b/src/Numerics/LinearAlgebra/Generic/Matrix.cs @@ -44,9 +44,9 @@ namespace MathNet.Numerics.LinearAlgebra.Generic #if SILVERLIGHT IFormattable, IEquatable> #else - IFormattable, IEquatable>, ICloneable + IFormattable, IEquatable>, ICloneable #endif - where T : struct, IEquatable, IFormattable + where T : struct, IEquatable, IFormattable { /// /// Initializes a new instance of the Matrix class. @@ -110,6 +110,82 @@ namespace MathNet.Numerics.LinearAlgebra.Generic private set; } + /// + /// Constructs matrix from a list of column vectors. + /// + /// The vectors to construct the matrix from. + /// The matrix constructed from the list of column vectors. + /// Creates a matrix of size Max([i].Count) x .Count + public static Matrix CreateFromColumns(IList> columnVectors) + { + if (columnVectors == null) + { + throw new ArgumentNullException("columnVectors"); + } + + if (columnVectors.Count == 0) + { + throw new ArgumentOutOfRangeException("columnVectors"); + } + + var rows = columnVectors[0].Count; + var columns = columnVectors.Count; + + for (var column = 1; column < columns; column++) + { + rows = Math.Max(rows, columnVectors[column].Count); + } + + var matrix = columnVectors[0].CreateMatrix(rows, columns); + for (var j = 0; j < columns; j++) + { + for (var i = 0; i < columnVectors[j].Count; i++) + { + matrix.At(i, j, columnVectors[j][i]); + } + } + + return matrix; + } + + /// + /// Constructs matrix from a list of row vectors. + /// + /// The vectors to construct the matrix from. + /// The matrix constructed from the list of row vectors. + /// Creates a matrix of size Max(.Count) x [i].Count + public static Matrix CreateFromRows(IList> rowVectors) + { + if (rowVectors == null) + { + throw new ArgumentNullException("rowVectors"); + } + + if (rowVectors.Count == 0) + { + throw new ArgumentOutOfRangeException("rowVectors"); + } + + var rows = rowVectors.Count; + var columns = rowVectors[0].Count; + + for (var row = 1; row < rows; row++) + { + columns = Math.Max(columns, rowVectors[row].Count); + } + + var matrix = rowVectors[0].CreateMatrix(rows, columns); + for (var i = 0; i < rows; i++) + { + for (var j = 0; j < rowVectors[i].Count; j++) + { + matrix.At(i, j, rowVectors[i][j]); + } + } + + return matrix; + } + /// /// Gets or sets the value at the given row and column. /// @@ -473,7 +549,7 @@ namespace MathNet.Numerics.LinearAlgebra.Generic for (var row = 0; row < RowCount; row++) { - for (var column = 0; column <= row && column < ColumnCount; column++) + for (var column = 0; column <= row && column < ColumnCount; column++) { ret.At(row, column, At(row, column)); } @@ -733,7 +809,7 @@ namespace MathNet.Numerics.LinearAlgebra.Generic { diagonal[i] = At(i, i); } - + return diagonal; } @@ -1426,6 +1502,7 @@ namespace MathNet.Numerics.LinearAlgebra.Generic return BitConverter.ToInt32(BitConverter.GetBytes(hash), 4); } + #endregion /// diff --git a/src/UnitTests/LinearAlgebraTests/Complex/MatrixTests.cs b/src/UnitTests/LinearAlgebraTests/Complex/MatrixTests.cs index de188d39..a5abd476 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex/MatrixTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex/MatrixTests.cs @@ -1990,5 +1990,71 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex } } } + + /// + /// Test whether we can create a matrix from a list of column vectors. + /// + [Test] + public virtual void CanCreateMatrixFromColumns() + { + var column1 = CreateVector(new Complex[] { 1.0 }); + var column2 = CreateVector(new Complex[] { 1.0, 2.0, 3.0, 4.0 }); + var column3 = CreateVector(new Complex[] { 1.0, 2.0 }); + var columnVectors = new System.Collections.Generic.List> + { + column1, + column2, + column3 + }; + var matrix = Matrix.CreateFromColumns(columnVectors); + + Assert.AreEqual(matrix.RowCount, 4); + Assert.AreEqual(matrix.ColumnCount, 3); + Assert.AreEqual(1.0, matrix[0, 0].Real); + Assert.AreEqual(0.0, matrix[1, 0].Real); + Assert.AreEqual(0.0, matrix[2, 0].Real); + Assert.AreEqual(0.0, matrix[3, 0].Real); + Assert.AreEqual(1.0, matrix[0, 1].Real); + Assert.AreEqual(2.0, matrix[1, 1].Real); + Assert.AreEqual(3.0, matrix[2, 1].Real); + Assert.AreEqual(4.0, matrix[3, 1].Real); + Assert.AreEqual(1.0, matrix[0, 2].Real); + Assert.AreEqual(2.0, matrix[1, 2].Real); + Assert.AreEqual(0.0, matrix[2, 2].Real); + Assert.AreEqual(0.0, matrix[3, 2].Real); + } + + /// + /// Test whether we can create a matrix from a list of row vectors. + /// + [Test] + public virtual void CanCreateMatrixFromRows() + { + var row1 = CreateVector(new Complex[] { 1.0 }); + var row2 = CreateVector(new Complex[] { 1.0, 2.0, 3.0, 4.0 }); + var row3 = CreateVector(new Complex[] { 1.0, 2.0 }); + var rowVectors = new System.Collections.Generic.List> + { + row1, + row2, + row3 + }; + var matrix = Matrix.CreateFromRows(rowVectors); + + Assert.AreEqual(matrix.RowCount, 3); + Assert.AreEqual(matrix.ColumnCount, 4); + Assert.AreEqual(1.0, matrix[0, 0].Real); + Assert.AreEqual(0.0, matrix[0, 1].Real); + Assert.AreEqual(0.0, matrix[0, 2].Real); + Assert.AreEqual(0.0, matrix[0, 3].Real); + Assert.AreEqual(1.0, matrix[1, 0].Real); + Assert.AreEqual(2.0, matrix[1, 1].Real); + Assert.AreEqual(3.0, matrix[1, 2].Real); + Assert.AreEqual(4.0, matrix[1, 3].Real); + Assert.AreEqual(1.0, matrix[2, 0].Real); + Assert.AreEqual(2.0, matrix[2, 1].Real); + Assert.AreEqual(0.0, matrix[2, 2].Real); + Assert.AreEqual(0.0, matrix[2, 3].Real); + } } } diff --git a/src/UnitTests/LinearAlgebraTests/Complex32/MatrixTests.cs b/src/UnitTests/LinearAlgebraTests/Complex32/MatrixTests.cs index d628e6d2..59f831e8 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex32/MatrixTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex32/MatrixTests.cs @@ -1990,5 +1990,71 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32 } } } + + /// + /// Test whether we can create a matrix from a list of column vectors. + /// + [Test] + public virtual void CanCreateMatrixFromColumns() + { + var column1 = CreateVector(new Complex32[] { 1.0f }); + var column2 = CreateVector(new Complex32[] { 1.0f, 2.0f, 3.0f, 4.0f }); + var column3 = CreateVector(new Complex32[] { 1.0f, 2.0f }); + var columnVectors = new System.Collections.Generic.List> + { + column1, + column2, + column3 + }; + var matrix = Matrix.CreateFromColumns(columnVectors); + + Assert.AreEqual(matrix.RowCount, 4); + Assert.AreEqual(matrix.ColumnCount, 3); + Assert.AreEqual(1.0, matrix[0, 0].Real); + Assert.AreEqual(0.0, matrix[1, 0].Real); + Assert.AreEqual(0.0, matrix[2, 0].Real); + Assert.AreEqual(0.0, matrix[3, 0].Real); + Assert.AreEqual(1.0, matrix[0, 1].Real); + Assert.AreEqual(2.0, matrix[1, 1].Real); + Assert.AreEqual(3.0, matrix[2, 1].Real); + Assert.AreEqual(4.0, matrix[3, 1].Real); + Assert.AreEqual(1.0, matrix[0, 2].Real); + Assert.AreEqual(2.0, matrix[1, 2].Real); + Assert.AreEqual(0.0, matrix[2, 2].Real); + Assert.AreEqual(0.0, matrix[3, 2].Real); + } + + /// + /// Test whether we can create a matrix from a list of row vectors. + /// + [Test] + public virtual void CanCreateMatrixFromRows() + { + var row1 = CreateVector(new Complex32[] { 1.0f }); + var row2 = CreateVector(new Complex32[] { 1.0f, 2.0f, 3.0f, 4.0f }); + var row3 = CreateVector(new Complex32[] { 1.0f, 2.0f }); + var rowVectors = new System.Collections.Generic.List> + { + row1, + row2, + row3 + }; + var matrix = Matrix.CreateFromRows(rowVectors); + + Assert.AreEqual(matrix.RowCount, 3); + Assert.AreEqual(matrix.ColumnCount, 4); + Assert.AreEqual(1.0, matrix[0, 0].Real); + Assert.AreEqual(0.0, matrix[0, 1].Real); + Assert.AreEqual(0.0, matrix[0, 2].Real); + Assert.AreEqual(0.0, matrix[0, 3].Real); + Assert.AreEqual(1.0, matrix[1, 0].Real); + Assert.AreEqual(2.0, matrix[1, 1].Real); + Assert.AreEqual(3.0, matrix[1, 2].Real); + Assert.AreEqual(4.0, matrix[1, 3].Real); + Assert.AreEqual(1.0, matrix[2, 0].Real); + Assert.AreEqual(2.0, matrix[2, 1].Real); + Assert.AreEqual(0.0, matrix[2, 2].Real); + Assert.AreEqual(0.0, matrix[2, 3].Real); + } } } diff --git a/src/UnitTests/LinearAlgebraTests/Double/DenseMatrixTests.cs b/src/UnitTests/LinearAlgebraTests/Double/DenseMatrixTests.cs index 8b4acf3f..2b8acebc 100644 --- a/src/UnitTests/LinearAlgebraTests/Double/DenseMatrixTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Double/DenseMatrixTests.cs @@ -1,4 +1,4 @@ -// +//// // Math.NET Numerics, part of the Math.NET Project // http://numerics.mathdotnet.com // http://github.com/mathnet/mathnet-numerics diff --git a/src/UnitTests/LinearAlgebraTests/Double/MatrixTests.cs b/src/UnitTests/LinearAlgebraTests/Double/MatrixTests.cs index a006eb41..f942a87c 100644 --- a/src/UnitTests/LinearAlgebraTests/Double/MatrixTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Double/MatrixTests.cs @@ -1927,5 +1927,71 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double } } } + + /// + /// Test whether we can create a matrix from a list of column vectors. + /// + [Test] + public virtual void CanCreateMatrixFromColumns() + { + var column1 = CreateVector(new[] { 1.0 }); + var column2 = CreateVector(new[] { 1.0, 2.0, 3.0, 4.0 }); + var column3 = CreateVector(new[] { 1.0, 2.0 }); + var columnVectors = new System.Collections.Generic.List> + { + column1, + column2, + column3 + }; + var matrix = Matrix.CreateFromColumns(columnVectors); + + Assert.AreEqual(matrix.RowCount, 4); + Assert.AreEqual(matrix.ColumnCount, 3); + Assert.AreEqual(1.0, matrix[0, 0]); + Assert.AreEqual(0.0, matrix[1, 0]); + Assert.AreEqual(0.0, matrix[2, 0]); + Assert.AreEqual(0.0, matrix[3, 0]); + Assert.AreEqual(1.0, matrix[0, 1]); + Assert.AreEqual(2.0, matrix[1, 1]); + Assert.AreEqual(3.0, matrix[2, 1]); + Assert.AreEqual(4.0, matrix[3, 1]); + Assert.AreEqual(1.0, matrix[0, 2]); + Assert.AreEqual(2.0, matrix[1, 2]); + Assert.AreEqual(0.0, matrix[2, 2]); + Assert.AreEqual(0.0, matrix[3, 2]); + } + + /// + /// Test whether we can create a matrix from a list of row vectors. + /// + [Test] + public virtual void CanCreateMatrixFromRows() + { + var row1 = CreateVector(new[] { 1.0 }); + var row2 = CreateVector(new[] { 1.0, 2.0, 3.0, 4.0 }); + var row3 = CreateVector(new[] { 1.0, 2.0 }); + var rowVectors = new System.Collections.Generic.List> + { + row1, + row2, + row3 + }; + var matrix = Matrix.CreateFromRows(rowVectors); + + Assert.AreEqual(matrix.RowCount, 3); + Assert.AreEqual(matrix.ColumnCount, 4); + Assert.AreEqual(1.0, matrix[0, 0]); + Assert.AreEqual(0.0, matrix[0, 1]); + Assert.AreEqual(0.0, matrix[0, 2]); + Assert.AreEqual(0.0, matrix[0, 3]); + Assert.AreEqual(1.0, matrix[1, 0]); + Assert.AreEqual(2.0, matrix[1, 1]); + Assert.AreEqual(3.0, matrix[1, 2]); + Assert.AreEqual(4.0, matrix[1, 3]); + Assert.AreEqual(1.0, matrix[2, 0]); + Assert.AreEqual(2.0, matrix[2, 1]); + Assert.AreEqual(0.0, matrix[2, 2]); + Assert.AreEqual(0.0, matrix[2, 3]); + } } } diff --git a/src/UnitTests/LinearAlgebraTests/Single/MatrixTests.cs b/src/UnitTests/LinearAlgebraTests/Single/MatrixTests.cs index e6ae1c4e..6eb5e632 100644 --- a/src/UnitTests/LinearAlgebraTests/Single/MatrixTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Single/MatrixTests.cs @@ -1927,5 +1927,71 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single } } } + + /// + /// Test whether we can create a matrix from a list of column vectors. + /// + [Test] + public virtual void CanCreateMatrixFromColumns() + { + var column1 = CreateVector(new[] { 1.0f }); + var column2 = CreateVector(new[] { 1.0f, 2.0f, 3.0f, 4.0f }); + var column3 = CreateVector(new[] { 1.0f, 2.0f }); + var columnVectors = new System.Collections.Generic.List> + { + column1, + column2, + column3 + }; + var matrix = Matrix.CreateFromColumns(columnVectors); + + Assert.AreEqual(matrix.RowCount, 4); + Assert.AreEqual(matrix.ColumnCount, 3); + Assert.AreEqual(1.0, matrix[0, 0]); + Assert.AreEqual(0.0, matrix[1, 0]); + Assert.AreEqual(0.0, matrix[2, 0]); + Assert.AreEqual(0.0, matrix[3, 0]); + Assert.AreEqual(1.0, matrix[0, 1]); + Assert.AreEqual(2.0, matrix[1, 1]); + Assert.AreEqual(3.0, matrix[2, 1]); + Assert.AreEqual(4.0, matrix[3, 1]); + Assert.AreEqual(1.0, matrix[0, 2]); + Assert.AreEqual(2.0, matrix[1, 2]); + Assert.AreEqual(0.0, matrix[2, 2]); + Assert.AreEqual(0.0, matrix[3, 2]); + } + + /// + /// Test whether we can create a matrix from a list of row vectors. + /// + [Test] + public virtual void CanCreateMatrixFromRows() + { + var row1 = CreateVector(new[] { 1.0f }); + var row2 = CreateVector(new[] { 1.0f, 2.0f, 3.0f, 4.0f }); + var row3 = CreateVector(new[] { 1.0f, 2.0f }); + var rowVectors = new System.Collections.Generic.List> + { + row1, + row2, + row3 + }; + var matrix = Matrix.CreateFromRows(rowVectors); + + Assert.AreEqual(matrix.RowCount, 3); + Assert.AreEqual(matrix.ColumnCount, 4); + Assert.AreEqual(1.0, matrix[0, 0]); + Assert.AreEqual(0.0, matrix[0, 1]); + Assert.AreEqual(0.0, matrix[0, 2]); + Assert.AreEqual(0.0, matrix[0, 3]); + Assert.AreEqual(1.0, matrix[1, 0]); + Assert.AreEqual(2.0, matrix[1, 1]); + Assert.AreEqual(3.0, matrix[1, 2]); + Assert.AreEqual(4.0, matrix[1, 3]); + Assert.AreEqual(1.0, matrix[2, 0]); + Assert.AreEqual(2.0, matrix[2, 1]); + Assert.AreEqual(0.0, matrix[2, 2]); + Assert.AreEqual(0.0, matrix[2, 3]); + } } }