From 2dd9bb7555fffcbfd547b6b3a6ea5575ab88d78e Mon Sep 17 00:00:00 2001 From: Marcus Cuda Date: Sat, 22 Jan 2011 22:17:22 +0800 Subject: [PATCH] added a IsSymmetric property to the matrix interface and an optimized version for sparse matrices. work item: 5653 --- src/MathNet.Numerics.5.1.ReSharper | 5 +- .../LinearAlgebra/Complex/DiagonalMatrix.cs | 11 ++ .../LinearAlgebra/Complex/SparseMatrix.cs | 65 +++++++++++ .../LinearAlgebra/Complex32/DiagonalMatrix.cs | 11 ++ .../LinearAlgebra/Complex32/SparseMatrix.cs | 102 +++++++++++++++--- .../LinearAlgebra/Double/DiagonalMatrix.cs | 11 ++ .../LinearAlgebra/Double/SparseMatrix.cs | 65 +++++++++++ src/Numerics/LinearAlgebra/Generic/Matrix.cs | 32 ++++++ .../LinearAlgebra/Single/DiagonalMatrix.cs | 11 ++ .../LinearAlgebra/Single/SparseMatrix.cs | 65 +++++++++++ .../Complex/DiagonalMatrixTests.cs | 10 ++ .../Complex/MatrixLoader.cs | 1 + .../LinearAlgebraTests/Complex/MatrixTests.cs | 13 +++ .../Complex32/DiagonalMatrixTests.cs | 11 ++ .../Complex32/MatrixLoader.cs | 3 +- .../Complex32/MatrixTests.cs | 13 +++ .../Double/DiagonalMatrixTests.cs | 10 ++ .../LinearAlgebraTests/Double/MatrixLoader.cs | 1 + .../LinearAlgebraTests/Double/MatrixTests.cs | 13 +++ .../Single/DiagonalMatrixTests.cs | 10 ++ .../LinearAlgebraTests/Single/MatrixLoader.cs | 1 + .../LinearAlgebraTests/Single/MatrixTests.cs | 13 +++ 22 files changed, 459 insertions(+), 18 deletions(-) diff --git a/src/MathNet.Numerics.5.1.ReSharper b/src/MathNet.Numerics.5.1.ReSharper index 3d89754c..eacc79ba 100644 --- a/src/MathNet.Numerics.5.1.ReSharper +++ b/src/MathNet.Numerics.5.1.ReSharper @@ -75,7 +75,10 @@ Datatset Doesnt cosecant Ulps -Matlab +Matlab +&lt +&gt +Wikipedia diff --git a/src/Numerics/LinearAlgebra/Complex/DiagonalMatrix.cs b/src/Numerics/LinearAlgebra/Complex/DiagonalMatrix.cs index a52a0c63..9f58d067 100644 --- a/src/Numerics/LinearAlgebra/Complex/DiagonalMatrix.cs +++ b/src/Numerics/LinearAlgebra/Complex/DiagonalMatrix.cs @@ -1537,6 +1537,17 @@ namespace MathNet.Numerics.LinearAlgebra.Complex throw new InvalidOperationException("Permutations in diagonal matrix are not allowed"); } + /// + /// Gets a value indicating whether this matrix is symmetric. + /// + public override bool IsSymmetric + { + get + { + return true; + } + } + #region Static constructors for special matrices. /// diff --git a/src/Numerics/LinearAlgebra/Complex/SparseMatrix.cs b/src/Numerics/LinearAlgebra/Complex/SparseMatrix.cs index ded2c932..34467dc8 100644 --- a/src/Numerics/LinearAlgebra/Complex/SparseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Complex/SparseMatrix.cs @@ -1503,6 +1503,71 @@ namespace MathNet.Numerics.LinearAlgebra.Complex } } } + + /// + /// Gets a value indicating whether this matrix is symmetric. + /// + public override bool IsSymmetric + { + get + { + if (RowCount != ColumnCount) + { + return false; + } + + // todo: we might be able to speed this up by caching one half of the matrix + for (var row = 0; row < RowCount - 1; row++) + { + var start = _rowIndex[row]; + var end = _rowIndex[row + 1]; + + if (start == end) + { + continue; + } + + if (!CheckIfOppositesAreEqual(start, end, row)) + { + return false; + } + } + + var lastRow = _rowIndex.Length - 1; + + if (_rowIndex[lastRow] < NonZerosCount) + { + if (!CheckIfOppositesAreEqual(_rowIndex[lastRow], NonZerosCount, lastRow)) + { + return false; + } + } + + return true; + } + } + + /// + /// Checks if opposites in a range are equal. + /// + /// The start of the range. + /// The end of the range. + /// The row the row to check. + /// If the values are equal or not. + private bool CheckIfOppositesAreEqual(int start, int end, int row) + { + for (var index = start; index < end; index++) + { + var column = _columnIndices[index]; + var opposite = At(column, row); + if (!_nonZeroValues[index].Equals(opposite)) + { + return false; + } + } + + return true; + } } } diff --git a/src/Numerics/LinearAlgebra/Complex32/DiagonalMatrix.cs b/src/Numerics/LinearAlgebra/Complex32/DiagonalMatrix.cs index 46c6f130..d765e2c8 100644 --- a/src/Numerics/LinearAlgebra/Complex32/DiagonalMatrix.cs +++ b/src/Numerics/LinearAlgebra/Complex32/DiagonalMatrix.cs @@ -1542,6 +1542,17 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 throw new InvalidOperationException("Permutations in diagonal matrix are not allowed"); } + /// + /// Gets a value indicating whether this matrix is symmetric. + /// + public override bool IsSymmetric + { + get + { + return true; + } + } + #region Static constructors for special matrices. /// diff --git a/src/Numerics/LinearAlgebra/Complex32/SparseMatrix.cs b/src/Numerics/LinearAlgebra/Complex32/SparseMatrix.cs index 94b00ef3..d776b26b 100644 --- a/src/Numerics/LinearAlgebra/Complex32/SparseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Complex32/SparseMatrix.cs @@ -41,7 +41,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 /// A Matrix class with sparse storage. The underlying storage scheme is 3-array compressed-sparse-row (CSR) Format. /// Wikipedia - CSR. /// - public class SparseMatrix : Matrix + public class SparseMatrix : Matrix { /// /// The array containing the row indices of the existing rows. Element "j" of the array gives the index of the @@ -54,7 +54,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 /// array using the row-major storage mapping described in a compressed sparse row (CSR) format. /// private Complex32[] _nonZeroValues = new Complex32[0]; - + /// /// Gets the number of non zero elements in the matrix. /// @@ -64,7 +64,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 get; private set; } - + /// /// An array containing the column indices of the non-zero values. Element "I" of the array /// is the number of the column in matrix that contains the I-th value in the array. @@ -80,11 +80,12 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 /// /// The number of columns. /// - public SparseMatrix(int rows, int columns) : base(rows, columns) + public SparseMatrix(int rows, int columns) + : base(rows, columns) { _rowIndex = new int[rows]; } - + /// /// Initializes a new instance of the class. This matrix is square with a given size. /// @@ -92,7 +93,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 /// /// If is less than one. /// - public SparseMatrix(int order) : this(order, order) + public SparseMatrix(int order) + : this(order, order) { } @@ -106,7 +108,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 /// The number of columns. /// /// The value which we assign to each element of the matrix. - public SparseMatrix(int rows, int columns, Complex32 value) : this(rows, columns) + public SparseMatrix(int rows, int columns, Complex32 value) + : this(rows, columns) { if (value == 0.0f) { @@ -128,7 +131,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 _nonZeroValues[i] = value; _columnIndices[i] = j; } - + // Set proper row pointers for (var i = 0; i < _rowIndex.Length; i++) { @@ -144,7 +147,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 /// The one dimensional array to create this matrix from. This array should store the matrix in column-major order. see: http://en.wikipedia.org/wiki/Column-major_order /// If length is less than * . /// - public SparseMatrix(int rows, int columns, Complex32[] array) : this(rows, columns) + public SparseMatrix(int rows, int columns, Complex32[] array) + : this(rows, columns) { if (rows * columns > array.Length) { @@ -164,7 +168,8 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 /// Initializes a new instance of the class from a 2D array. /// /// The 2D array to create this matrix from. - public SparseMatrix(Complex32[,] array) : this(array.GetLength(0), array.GetLength(1)) + public SparseMatrix(Complex32[,] array) + : this(array.GetLength(0), array.GetLength(1)) { var rows = array.GetLength(0); var columns = array.GetLength(1); @@ -708,7 +713,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 _nonZeroValues[i - 1] = _nonZeroValues[i]; _columnIndices[i - 1] = _columnIndices[i]; } - + // Decrease value in Row for (var i = row + 1; i < _rowIndex.Length; i++) { @@ -725,7 +730,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 Array.Resize(ref _columnIndices, NonZerosCount); } } - + /// /// Find item Index in nonZeroValues array /// @@ -740,7 +745,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 var endIndex = row < _rowIndex.Length - 1 ? _rowIndex[row + 1] : NonZerosCount; return Array.BinarySearch(_columnIndices, startIndex, endIndex - startIndex, column); } - + /// /// Calculates the amount with which to grow the storage array's if they need to be /// increased in size. @@ -820,7 +825,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 Array.Copy(_rowIndex, sparseTarget._rowIndex, RowCount); } } - + /// /// Returns a hash code for this instance. /// @@ -1038,7 +1043,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 resultSparseMatrix.NonZerosCount = NonZerosCount + lowerSparseMatrix.NonZerosCount; resultSparseMatrix._nonZeroValues = new Complex32[resultSparseMatrix.NonZerosCount]; resultSparseMatrix._columnIndices = new int[resultSparseMatrix.NonZerosCount]; - + Array.Copy(_nonZeroValues, 0, resultSparseMatrix._nonZeroValues, 0, NonZerosCount); Array.Copy(lowerSparseMatrix._nonZeroValues, 0, resultSparseMatrix._nonZeroValues, NonZerosCount, lowerSparseMatrix.NonZerosCount); @@ -1313,7 +1318,7 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 { // Multiply row of matrix A on column of matrix B other.Column(column, columnVector); - + var sum = Complex32.Zero; for (var index = startIndex; index < endIndex; index++) { @@ -1499,5 +1504,70 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 } } } + + /// + /// Gets a value indicating whether this matrix is symmetric. + /// + public override bool IsSymmetric + { + get + { + if (RowCount != ColumnCount) + { + return false; + } + + // todo: we might be able to speed this up by caching one half of the matrix + for (var row = 0; row < RowCount - 1; row++) + { + var start = _rowIndex[row]; + var end = _rowIndex[row + 1]; + + if (start == end) + { + continue; + } + + if (!CheckIfOppositesAreEqual(start, end, row)) + { + return false; + } + } + + var lastRow = _rowIndex.Length - 1; + + if (_rowIndex[lastRow] < NonZerosCount) + { + if (!CheckIfOppositesAreEqual(_rowIndex[lastRow], NonZerosCount, lastRow)) + { + return false; + } + } + + return true; + } + } + + /// + /// Checks if opposites in a range are equal. + /// + /// The start of the range. + /// The end of the range. + /// The row the row to check. + /// If the values are equal or not. + private bool CheckIfOppositesAreEqual(int start, int end, int row) + { + for (var index = start; index < end; index++) + { + var column = _columnIndices[index]; + var opposite = At(column, row); + if (!_nonZeroValues[index].Equals(opposite)) + { + return false; + } + } + + return true; + } } } diff --git a/src/Numerics/LinearAlgebra/Double/DiagonalMatrix.cs b/src/Numerics/LinearAlgebra/Double/DiagonalMatrix.cs index a4ab2317..47a86955 100644 --- a/src/Numerics/LinearAlgebra/Double/DiagonalMatrix.cs +++ b/src/Numerics/LinearAlgebra/Double/DiagonalMatrix.cs @@ -1536,6 +1536,17 @@ namespace MathNet.Numerics.LinearAlgebra.Double throw new InvalidOperationException("Permutations in diagonal matrix are not allowed"); } + /// + /// Gets a value indicating whether this matrix is symmetric. + /// + public override bool IsSymmetric + { + get + { + return true; + } + } + #region Static constructors for special matrices. /// diff --git a/src/Numerics/LinearAlgebra/Double/SparseMatrix.cs b/src/Numerics/LinearAlgebra/Double/SparseMatrix.cs index a9bc40ff..a7c7a502 100644 --- a/src/Numerics/LinearAlgebra/Double/SparseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Double/SparseMatrix.cs @@ -1515,5 +1515,70 @@ namespace MathNet.Numerics.LinearAlgebra.Double } } } + + /// + /// Gets a value indicating whether this matrix is symmetric. + /// + public override bool IsSymmetric + { + get + { + if (RowCount != ColumnCount) + { + return false; + } + + // todo: we might be able to speed this up by caching one half of the matrix + for (var row = 0; row < RowCount - 1; row++) + { + var start = _rowIndex[row]; + var end = _rowIndex[row + 1]; + + if (start == end) + { + continue; + } + + if (!CheckIfOppositesAreEqual(start, end, row)) + { + return false; + } + } + + var lastRow = _rowIndex.Length - 1; + + if (_rowIndex[lastRow] < NonZerosCount) + { + if (!CheckIfOppositesAreEqual(_rowIndex[lastRow], NonZerosCount, lastRow)) + { + return false; + } + } + + return true; + } + } + + /// + /// Checks if opposites in a range are equal. + /// + /// The start of the range. + /// The end of the range. + /// The row the row to check. + /// If the values are equal or not. + private bool CheckIfOppositesAreEqual(int start, int end, int row) + { + for (var index = start; index < end; index++) + { + var column = _columnIndices[index]; + var opposite = At(column, row); + if (!_nonZeroValues[index].Equals(opposite)) + { + return false; + } + } + + return true; + } } } diff --git a/src/Numerics/LinearAlgebra/Generic/Matrix.cs b/src/Numerics/LinearAlgebra/Generic/Matrix.cs index b573951d..1fe4e14c 100644 --- a/src/Numerics/LinearAlgebra/Generic/Matrix.cs +++ b/src/Numerics/LinearAlgebra/Generic/Matrix.cs @@ -1773,5 +1773,37 @@ namespace MathNet.Numerics.LinearAlgebra.Generic } } } + + /// + /// Gets a value indicating whether this matrix is symmetric. + /// + public virtual bool IsSymmetric + { + get + { + if (RowCount != ColumnCount) + { + return false; + } + + for (var row = 1; row < RowCount; row++) + { + for (var column = 0; column < ColumnCount; column++) + { + if (column >= row) + { + continue; + } + + if (!At(row, column).Equals(At(column, row))) + { + return false; + } + } + } + + return true; + } + } } } diff --git a/src/Numerics/LinearAlgebra/Single/DiagonalMatrix.cs b/src/Numerics/LinearAlgebra/Single/DiagonalMatrix.cs index 29ae7424..72c93ae6 100644 --- a/src/Numerics/LinearAlgebra/Single/DiagonalMatrix.cs +++ b/src/Numerics/LinearAlgebra/Single/DiagonalMatrix.cs @@ -1536,6 +1536,17 @@ namespace MathNet.Numerics.LinearAlgebra.Single throw new InvalidOperationException("Permutations in diagonal matrix are not allowed"); } + /// + /// Gets a value indicating whether this matrix is symmetric. + /// + public override bool IsSymmetric + { + get + { + return true; + } + } + #region Static constructors for special matrices. /// diff --git a/src/Numerics/LinearAlgebra/Single/SparseMatrix.cs b/src/Numerics/LinearAlgebra/Single/SparseMatrix.cs index cfaedaea..5eadb4e3 100644 --- a/src/Numerics/LinearAlgebra/Single/SparseMatrix.cs +++ b/src/Numerics/LinearAlgebra/Single/SparseMatrix.cs @@ -1498,5 +1498,70 @@ namespace MathNet.Numerics.LinearAlgebra.Single } } } + + /// + /// Gets a value indicating whether this matrix is symmetric. + /// + public override bool IsSymmetric + { + get + { + if (RowCount != ColumnCount) + { + return false; + } + + // todo: we might be able to speed this up by caching one half of the matrix + for (var row = 0; row < RowCount - 1; row++) + { + var start = _rowIndex[row]; + var end = _rowIndex[row + 1]; + + if (start == end) + { + continue; + } + + if (!CheckIfOppositesAreEqual(start, end, row)) + { + return false; + } + } + + var lastRow = _rowIndex.Length - 1; + + if (_rowIndex[lastRow] < NonZerosCount) + { + if (!CheckIfOppositesAreEqual(_rowIndex[lastRow], NonZerosCount, lastRow)) + { + return false; + } + } + + return true; + } + } + + /// + /// Checks if opposites in a range are equal. + /// + /// The start of the range. + /// The end of the range. + /// The row the row to check. + /// If the values are equal or not. + private bool CheckIfOppositesAreEqual(int start, int end, int row) + { + for (var index = start; index < end; index++) + { + var column = _columnIndices[index]; + var opposite = At(column, row); + if (!_nonZeroValues[index].Equals(opposite)) + { + return false; + } + } + + return true; + } } } diff --git a/src/UnitTests/LinearAlgebraTests/Complex/DiagonalMatrixTests.cs b/src/UnitTests/LinearAlgebraTests/Complex/DiagonalMatrixTests.cs index acca934a..d414ce10 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex/DiagonalMatrixTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex/DiagonalMatrixTests.cs @@ -582,5 +582,15 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex Assert.AreEqual(2, item.Item2); Assert.AreEqual(new Complex(3.0, 1.0), item.Item3); } + + /// + /// Can check if a matrix is symmetric. + /// + [Test] + public override void CanCheckIfMatrixIsSymmetric() + { + var matrix = TestMatrices["Square3x3"]; + Assert.IsTrue(matrix.IsSymmetric); + } } } diff --git a/src/UnitTests/LinearAlgebraTests/Complex/MatrixLoader.cs b/src/UnitTests/LinearAlgebraTests/Complex/MatrixLoader.cs index cac795db..48b27c68 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex/MatrixLoader.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex/MatrixLoader.cs @@ -101,6 +101,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex { "Singular4x4", new[,] { { new Complex(-1.1, 1), new Complex(-2.2, 1), new Complex(-3.3, 1), new Complex(-4.4, 1) }, { new Complex(-1.1, 1), new Complex(-2.2, 1), new Complex(-3.3, 1), new Complex(-4.4, 1) }, { new Complex(-1.1, 1), new Complex(-2.2, 1), new Complex(-3.3, 1), new Complex(-4.4, 1) }, { new Complex(-1.1, 1), new Complex(-2.2, 1), new Complex(-3.3, 1), new Complex(-4.4, 1) } } }, { "Tall3x2", new[,] { { new Complex(-1.1, 1), new Complex(-2.2, 1) }, { Complex.Zero, new Complex(1.1, 1) }, { new Complex(-4.4, 1), new Complex(5.5, 1) } } }, { "Wide2x3", new[,] { { new Complex(-1.1, 1), new Complex(-2.2, 1), new Complex(-3.3, 1) }, { Complex.Zero, new Complex(1.1, 1), new Complex(2.2, 1) } } }, + { "Symmetric3x3", new[,] { { Complex.One, 2.0, 3.0 }, { 2.0, 2.0, 0.0 }, { 3.0, 0.0, 3.0 } } } }; TestMatrices = new Dictionary(); diff --git a/src/UnitTests/LinearAlgebraTests/Complex/MatrixTests.cs b/src/UnitTests/LinearAlgebraTests/Complex/MatrixTests.cs index 19031f3f..3c8fc9e1 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex/MatrixTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex/MatrixTests.cs @@ -1851,5 +1851,18 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex Assert.AreEqual(2, item.Item2); Assert.AreEqual(new Complex(2.0, 1.0), item.Item3); } + + /// + /// Can check if a matrix is symmetric. + /// + [Test] + public virtual void CanCheckIfMatrixIsSymmetric() + { + var matrix = TestMatrices["Symmetric3x3"]; + Assert.IsTrue(matrix.IsSymmetric); + + matrix = TestMatrices["Square3x3"]; + Assert.IsFalse(matrix.IsSymmetric); + } } } diff --git a/src/UnitTests/LinearAlgebraTests/Complex32/DiagonalMatrixTests.cs b/src/UnitTests/LinearAlgebraTests/Complex32/DiagonalMatrixTests.cs index 450beaa6..e333c3d9 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex32/DiagonalMatrixTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex32/DiagonalMatrixTests.cs @@ -582,5 +582,16 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32 Assert.AreEqual(2, item.Item2); Assert.AreEqual(new Complex32(3.0f, 1.0f), item.Item3); } + + /// + /// Can check if a matrix is symmetric. + /// + [Test] + public override void CanCheckIfMatrixIsSymmetric() + { + var matrix = TestMatrices["Square3x3"]; + Assert.IsTrue(matrix.IsSymmetric); + } + } } diff --git a/src/UnitTests/LinearAlgebraTests/Complex32/MatrixLoader.cs b/src/UnitTests/LinearAlgebraTests/Complex32/MatrixLoader.cs index a631ddd2..ff031c31 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex32/MatrixLoader.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex32/MatrixLoader.cs @@ -100,7 +100,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32 { "Square4x4", new[,] { { new Complex32(-1.1f, 1), new Complex32(-2.2f, 1), new Complex32(-3.3f, 1), new Complex32(-4.4f, 1) }, { Complex32.Zero, new Complex32(1.1f, 1), new Complex32(2.2f, 1), new Complex32(3.3f, 1) }, { new Complex32(1.0f, 1), new Complex32(2.1f, 1), new Complex32(6.2f, 1), new Complex32(4.3f, 1) }, { new Complex32(-4.4f, 1), new Complex32(5.5f, 1), new Complex32(6.6f, 1), new Complex32(-7.7f, 1) } } }, { "Singular4x4", new[,] { { new Complex32(-1.1f, 1), new Complex32(-2.2f, 1), new Complex32(-3.3f, 1), new Complex32(-4.4f, 1) }, { new Complex32(-1.1f, 1), new Complex32(-2.2f, 1), new Complex32(-3.3f, 1), new Complex32(-4.4f, 1) }, { new Complex32(-1.1f, 1), new Complex32(-2.2f, 1), new Complex32(-3.3f, 1), new Complex32(-4.4f, 1) }, { new Complex32(-1.1f, 1), new Complex32(-2.2f, 1), new Complex32(-3.3f, 1), new Complex32(-4.4f, 1) } } }, { "Tall3x2", new[,] { { new Complex32(-1.1f, 1), new Complex32(-2.2f, 1) }, { Complex32.Zero, new Complex32(1.1f, 1) }, { new Complex32(-4.4f, 1), new Complex32(5.5f, 1) } } }, - { "Wide2x3", new[,] { { new Complex32(-1.1f, 1), new Complex32(-2.2f, 1), new Complex32(-3.3f, 1) }, { Complex32.Zero, new Complex32(1.1f, 1), new Complex32(2.2f, 1) } } }, + { "Wide2x3", new[,] { { new Complex32(-1.1f, 1), new Complex32(-2.2f, 1), new Complex32(-3.3f, 1) }, { Complex32.Zero, new Complex32(1.1f, 1), new Complex32(2.2f, 1) } } }, + { "Symmetric3x3", new[,] { { Complex32.One, 2.0f, 3.0f }, { 2.0f, 2.0f, 0.0f }, { 3.0f, 0.0f, 3.0f } } } }; TestMatrices = new Dictionary(); diff --git a/src/UnitTests/LinearAlgebraTests/Complex32/MatrixTests.cs b/src/UnitTests/LinearAlgebraTests/Complex32/MatrixTests.cs index 1be67a4f..a8c863d1 100644 --- a/src/UnitTests/LinearAlgebraTests/Complex32/MatrixTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Complex32/MatrixTests.cs @@ -1851,5 +1851,18 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32 Assert.AreEqual(2, item.Item2); Assert.AreEqual(new Complex32(2.0f, 1.0f), item.Item3); } + + /// + /// Can check if a matrix is symmetric. + /// + [Test] + public virtual void CanCheckIfMatrixIsSymmetric() + { + var matrix = TestMatrices["Symmetric3x3"]; + Assert.IsTrue(matrix.IsSymmetric); + + matrix = TestMatrices["Square3x3"]; + Assert.IsFalse(matrix.IsSymmetric); + } } } diff --git a/src/UnitTests/LinearAlgebraTests/Double/DiagonalMatrixTests.cs b/src/UnitTests/LinearAlgebraTests/Double/DiagonalMatrixTests.cs index dd6a47c9..94294fae 100644 --- a/src/UnitTests/LinearAlgebraTests/Double/DiagonalMatrixTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Double/DiagonalMatrixTests.cs @@ -582,5 +582,15 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double Assert.AreEqual(2, item.Item2); Assert.AreEqual(3.0, item.Item3); } + + /// + /// Can check if a matrix is symmetric. + /// + [Test] + public override void CanCheckIfMatrixIsSymmetric() + { + var matrix = TestMatrices["Square3x3"]; + Assert.IsTrue(matrix.IsSymmetric); + } } } diff --git a/src/UnitTests/LinearAlgebraTests/Double/MatrixLoader.cs b/src/UnitTests/LinearAlgebraTests/Double/MatrixLoader.cs index 6ed7d029..542888f8 100644 --- a/src/UnitTests/LinearAlgebraTests/Double/MatrixLoader.cs +++ b/src/UnitTests/LinearAlgebraTests/Double/MatrixLoader.cs @@ -100,6 +100,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double { "Singular4x4", new[,] { { -1.1, -2.2, -3.3, -4.4 }, { -1.1, -2.2, -3.3, -4.4 }, { -1.1, -2.2, -3.3, -4.4 }, { -1.1, -2.2, -3.3, -4.4 } } }, { "Tall3x2", new[,] { { -1.1, -2.2 }, { 0.0, 1.1 }, { -4.4, 5.5 } } }, { "Wide2x3", new[,] { { -1.1, -2.2, -3.3 }, { 0.0, 1.1, 2.2 } } }, + { "Symmetric3x3", new[,] { { 1.0, 2.0, 3.0 }, { 2.0, 2.0, 0.0 }, { 3.0, 0.0, 3.0 } } } }; TestMatrices = new Dictionary(); diff --git a/src/UnitTests/LinearAlgebraTests/Double/MatrixTests.cs b/src/UnitTests/LinearAlgebraTests/Double/MatrixTests.cs index bc81a4e9..60c27cd4 100644 --- a/src/UnitTests/LinearAlgebraTests/Double/MatrixTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Double/MatrixTests.cs @@ -1792,5 +1792,18 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double Assert.AreEqual(2, item.Item2); Assert.AreEqual(2.0, item.Item3); } + + /// + /// Can check if a matrix is symmetric. + /// + [Test] + public virtual void CanCheckIfMatrixIsSymmetric() + { + var matrix = TestMatrices["Symmetric3x3"]; + Assert.IsTrue(matrix.IsSymmetric); + + matrix = TestMatrices["Square3x3"]; + Assert.IsFalse(matrix.IsSymmetric); + } } } diff --git a/src/UnitTests/LinearAlgebraTests/Single/DiagonalMatrixTests.cs b/src/UnitTests/LinearAlgebraTests/Single/DiagonalMatrixTests.cs index 582454d2..19952524 100644 --- a/src/UnitTests/LinearAlgebraTests/Single/DiagonalMatrixTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Single/DiagonalMatrixTests.cs @@ -581,5 +581,15 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single Assert.AreEqual(2, item.Item2); Assert.AreEqual(3.0f, item.Item3); } + + /// + /// Can check if a matrix is symmetric. + /// + [Test] + public override void CanCheckIfMatrixIsSymmetric() + { + var matrix = TestMatrices["Square3x3"]; + Assert.IsTrue(matrix.IsSymmetric); + } } } diff --git a/src/UnitTests/LinearAlgebraTests/Single/MatrixLoader.cs b/src/UnitTests/LinearAlgebraTests/Single/MatrixLoader.cs index 0d04c543..751281c0 100644 --- a/src/UnitTests/LinearAlgebraTests/Single/MatrixLoader.cs +++ b/src/UnitTests/LinearAlgebraTests/Single/MatrixLoader.cs @@ -100,6 +100,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single { "Singular4x4", new[,] { { -1.1f, -2.2f, -3.3f, -4.4f }, { -1.1f, -2.2f, -3.3f, -4.4f }, { -1.1f, -2.2f, -3.3f, -4.4f }, { -1.1f, -2.2f, -3.3f, -4.4f } } }, { "Tall3x2", new[,] { { -1.1f, -2.2f }, { 0.0f, 1.1f }, { -4.4f, 5.5f } } }, { "Wide2x3", new[,] { { -1.1f, -2.2f, -3.3f }, { 0.0f, 1.1f, 2.2f } } }, + { "Symmetric3x3", new[,] { { 1.0f, 2.0f, 3.0f }, { 2.0f, 2.0f, 0.0f }, { 3.0f, 0.0f, 3.0f } } } }; TestMatrices = new Dictionary(); diff --git a/src/UnitTests/LinearAlgebraTests/Single/MatrixTests.cs b/src/UnitTests/LinearAlgebraTests/Single/MatrixTests.cs index fee7e769..8701f005 100644 --- a/src/UnitTests/LinearAlgebraTests/Single/MatrixTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Single/MatrixTests.cs @@ -1792,5 +1792,18 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single Assert.AreEqual(2, item.Item2); Assert.AreEqual(2.0f, item.Item3); } + + /// + /// Can check if a matrix is symmetric. + /// + [Test] + public virtual void CanCheckIfMatrixIsSymmetric() + { + var matrix = TestMatrices["Symmetric3x3"]; + Assert.IsTrue(matrix.IsSymmetric); + + matrix = TestMatrices["Square3x3"]; + Assert.IsFalse(matrix.IsSymmetric); + } } }