From 36fe86a1f502db6b889915fd4de5e47565e861e8 Mon Sep 17 00:00:00 2001 From: Alexander Karatarakis Date: Sat, 24 Nov 2012 19:05:55 +0200 Subject: [PATCH] Add SymmetricMatrixTests Signed-off-by: Alexander Karatarakis --- .../Double/SymmetricMatrixTests.Arithmetic.cs | 191 ++++++++++++++++++ .../Double/SymmetricMatrixTests.cs | 123 +++++++++++ src/UnitTests/UnitTests.csproj | 2 + 3 files changed, 316 insertions(+) create mode 100644 src/UnitTests/LinearAlgebraTests/Double/SymmetricMatrixTests.Arithmetic.cs create mode 100644 src/UnitTests/LinearAlgebraTests/Double/SymmetricMatrixTests.cs diff --git a/src/UnitTests/LinearAlgebraTests/Double/SymmetricMatrixTests.Arithmetic.cs b/src/UnitTests/LinearAlgebraTests/Double/SymmetricMatrixTests.Arithmetic.cs new file mode 100644 index 00000000..cb7accb7 --- /dev/null +++ b/src/UnitTests/LinearAlgebraTests/Double/SymmetricMatrixTests.Arithmetic.cs @@ -0,0 +1,191 @@ +// +// Math.NET Numerics, part of the Math.NET Project +// http://numerics.mathdotnet.com +// http://github.com/mathnet/mathnet-numerics +// http://mathnetnumerics.codeplex.com +// Copyright (c) 2009-2010 Math.NET +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double +{ + using System.Collections.Generic; + using LinearAlgebra.Double; + using NUnit.Framework; + + /// + /// Abstract class with the common set of matrix tests for symmetric matrices + /// + public abstract partial class SymmetricMatrixTests + { + /// + /// Setup test matrices. + /// Singular and Square matrices are overridden here with symmetric ones so that calls to base methods work as intended. + /// Additional NonSymmetric matrices are defined for some tests. + /// + [SetUp] + public override void SetupMatrices() + { + TestData2D = new Dictionary + { + { "Singular3x3", new[,] { { 1.0, 2.0, 3.0 }, { 2.0, 0.0, 0.0 }, { 3.0, 0.0, 0.0 } } }, + { "Square3x3", new[,] { { -1.1, 2.0, 3.0 }, { 2.0, 1.1, 0.0 }, { 3.0, 0.0, 6.6 } } }, + { "Square4x4", new[,] { { 1.1, 2.0, -3.0, 4.4 }, { 2.0, 5.0, -6.0, 7.0 }, { -3.0, -6.0, 8.0, 9.0 }, { 4.4, 7.0, 9.0, 10.0 } } }, + { "Singular4x4", new[,] { { 1.0, 2.0, 0.0, 4.0 }, { 2.0, 5.0, 0.0, 7.0 }, { 0.0, 0.0, 0.0, 0.0 }, { 4.0, 7.0, 0.0, 10.0 } } }, + { "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 } } }, + { "NonSymmetric3x3", new[,] { { -1.1, -2.2, -3.3 }, { 0.0, 1.1, 2.2 }, { -4.4, 5.5, 6.6 } } }, + { "NonSymmetric4x4", new[,] { { -1.1, -2.2, -3.3, -4.4 }, { 0.0, 1.1, 2.2, 3.3 }, { 1.0, 2.1, 6.2, 4.3 }, { -4.4, 5.5, 6.6, -7.7 } } }, + { "IndexTester4x4", new double[,] { { 0, 1, 3, 6 }, { 1, 2, 4, 7 }, { 3, 4, 5, 8 }, { 6, 7, 8, 9 } } } + }; + + TestMatrices = new Dictionary(); + + foreach (var name in TestData2D.Keys) + { + TestMatrices.Add(name, CreateMatrix(TestData2D[name])); + } + } + + /// + /// Can add a non-symmetric matrix to this symmetric matrix. + /// + /// Matrix A name. + /// Matrix B name. + [Test, Sequential] + public void CanAddNonSymmetricMatrix([Values("Square3x3", "Square4x4")] string mtxA, [Values("NonSymmetric3x3", "NonSymmetric4x4")] string mtxB) + { + var matrixA = TestMatrices[mtxA]; + var matrixB = TestMatrices[mtxB]; + + var matrix = matrixA.Clone(); + matrix = matrix.Add(matrixB); + + for (var i = 0; i < matrix.RowCount; i++) + { + for (var j = 0; j < matrix.ColumnCount; j++) + { + Assert.AreEqual(matrix[i, j], matrixA[i, j] + matrixB[i, j]); + } + } + } + + /// + /// Can subtract a non-symmetric matrix from this symmetric matrix. + /// + /// Matrix A name. + /// Matrix B name. + [Test, Sequential] + public void CanSubtractNonSymmetricMatrix([Values("Square3x3", "Square4x4")] string mtxA, [Values("NonSymmetric3x3", "NonSymmetric4x4")] string mtxB) + { + var matrixA = TestMatrices[mtxA]; + var matrixB = TestMatrices[mtxB]; + + var matrix = matrixA.Clone(); + matrix = matrix.Subtract(matrixB); + for (var i = 0; i < matrix.RowCount; i++) + { + for (var j = 0; j < matrix.ColumnCount; j++) + { + Assert.AreEqual(matrix[i, j], matrixA[i, j] - matrixB[i, j]); + } + } + } + + /// + /// Can compute Frobenius norm. + /// + public override void CanComputeFrobeniusNorm() + { + var matrix = TestMatrices["Square3x3"]; + var denseMatrix = new DenseMatrix(TestData2D["Square3x3"]); + AssertHelpers.AlmostEqual(denseMatrix.FrobeniusNorm(), matrix.FrobeniusNorm(), 14); + + matrix = TestMatrices["Wide2x3"]; + denseMatrix = new DenseMatrix(TestData2D["Wide2x3"]); + AssertHelpers.AlmostEqual(denseMatrix.FrobeniusNorm(), matrix.FrobeniusNorm(), 14); + + matrix = TestMatrices["Tall3x2"]; + denseMatrix = new DenseMatrix(TestData2D["Tall3x2"]); + AssertHelpers.AlmostEqual(denseMatrix.FrobeniusNorm(), matrix.FrobeniusNorm(), 14); + } + + + + /// + /// Can compute Infinity norm. + /// + public override void CanComputeInfinityNorm() + { + var matrix = TestMatrices["Square3x3"]; + var denseMatrix = new DenseMatrix(TestData2D["Square3x3"]); + AssertHelpers.AlmostEqual(denseMatrix.InfinityNorm(), matrix.InfinityNorm(), 14); + + matrix = TestMatrices["Wide2x3"]; + denseMatrix = new DenseMatrix(TestData2D["Wide2x3"]); + AssertHelpers.AlmostEqual(denseMatrix.InfinityNorm(), matrix.InfinityNorm(), 14); + + matrix = TestMatrices["Tall3x2"]; + denseMatrix = new DenseMatrix(TestData2D["Tall3x2"]); + AssertHelpers.AlmostEqual(denseMatrix.InfinityNorm(), matrix.InfinityNorm(), 14); + } + + + + /// + /// Can compute L1 norm. + /// + public override void CanComputeL1Norm() + { + var matrix = TestMatrices["Square3x3"]; + var denseMatrix = new DenseMatrix(TestData2D["Square3x3"]); + AssertHelpers.AlmostEqual(denseMatrix.L1Norm(), matrix.L1Norm(), 14); + + matrix = TestMatrices["Wide2x3"]; + denseMatrix = new DenseMatrix(TestData2D["Wide2x3"]); + AssertHelpers.AlmostEqual(denseMatrix.L1Norm(), matrix.L1Norm(), 14); + + matrix = TestMatrices["Tall3x2"]; + denseMatrix = new DenseMatrix(TestData2D["Tall3x2"]); + AssertHelpers.AlmostEqual(denseMatrix.L1Norm(), matrix.L1Norm(), 14); + } + + + + /// + /// Can compute L2 norm. + /// + public override void CanComputeL2Norm() + { + var matrix = TestMatrices["Square3x3"]; + var denseMatrix = new DenseMatrix(TestData2D["Square3x3"]); + AssertHelpers.AlmostEqual(denseMatrix.L2Norm(), matrix.L2Norm(), 14); + + matrix = TestMatrices["Wide2x3"]; + denseMatrix = new DenseMatrix(TestData2D["Wide2x3"]); + AssertHelpers.AlmostEqual(denseMatrix.L2Norm(), matrix.L2Norm(), 14); + + matrix = TestMatrices["Tall3x2"]; + denseMatrix = new DenseMatrix(TestData2D["Tall3x2"]); + AssertHelpers.AlmostEqual(denseMatrix.L2Norm(), matrix.L2Norm(), 14); + } + } +} \ No newline at end of file diff --git a/src/UnitTests/LinearAlgebraTests/Double/SymmetricMatrixTests.cs b/src/UnitTests/LinearAlgebraTests/Double/SymmetricMatrixTests.cs new file mode 100644 index 00000000..d95359f0 --- /dev/null +++ b/src/UnitTests/LinearAlgebraTests/Double/SymmetricMatrixTests.cs @@ -0,0 +1,123 @@ +// +// Math.NET Numerics, part of the Math.NET Project +// http://numerics.mathdotnet.com +// http://github.com/mathnet/mathnet-numerics +// http://mathnetnumerics.codeplex.com +// Copyright (c) 2009-2010 Math.NET +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double +{ + using MathNet.Numerics.LinearAlgebra.Double; + using NUnit.Framework; + + /// + /// Abstract class with the common set of matrix tests for symmetric matrices. + /// + public abstract partial class SymmetricMatrixTests : MatrixTests + { + /// + /// Can check if a matrix is symmetric. + /// + [Test] + public override void CanCheckIfMatrixIsSymmetric() + { + var matrix = TestMatrices["Square3x3"]; + Assert.IsTrue(matrix.IsSymmetric); + + matrix = TestMatrices["NonSymmetric3x3"]; + Assert.IsFalse(matrix.IsSymmetric); + } + + /// + /// Can check if a [,] array is symmetric. + /// + [Test] + public void CanCheckIfArrayIsSymmetric() + { + Assert.IsTrue(SymmetricMatrix.CheckIfSymmetric(TestData2D["Square3x3"])); + Assert.IsFalse(SymmetricMatrix.CheckIfSymmetric(TestData2D["NonSymmetric3x3"])); + } + + /// + /// Test whether the index enumerator returns the correct values. + /// + [Test] + public void CanUseIndexedEnumerator() + { + var matrix = TestMatrices["Singular3x3"]; + var enumerator = matrix.IndexedEnumerator().GetEnumerator(); + enumerator.MoveNext(); + var item = enumerator.Current; + Assert.AreEqual(0, item.Item1); + Assert.AreEqual(0, item.Item2); + Assert.AreEqual(1.0, item.Item3); + + enumerator.MoveNext(); + item = enumerator.Current; + Assert.AreEqual(0, item.Item1); + Assert.AreEqual(1, item.Item2); + Assert.AreEqual(2.0, item.Item3); + + enumerator.MoveNext(); + item = enumerator.Current; + Assert.AreEqual(0, item.Item1); + Assert.AreEqual(2, item.Item2); + Assert.AreEqual(3.0, item.Item3); + + enumerator.MoveNext(); + item = enumerator.Current; + Assert.AreEqual(1, item.Item1); + Assert.AreEqual(0, item.Item2); + Assert.AreEqual(2.0, item.Item3); + + enumerator.MoveNext(); + item = enumerator.Current; + Assert.AreEqual(1, item.Item1); + Assert.AreEqual(1, item.Item2); + Assert.AreEqual(0.0, item.Item3); + + enumerator.MoveNext(); + item = enumerator.Current; + Assert.AreEqual(1, item.Item1); + Assert.AreEqual(2, item.Item2); + Assert.AreEqual(0.0, item.Item3); + + enumerator.MoveNext(); + item = enumerator.Current; + Assert.AreEqual(2, item.Item1); + Assert.AreEqual(0, item.Item2); + Assert.AreEqual(3.0, item.Item3); + + enumerator.MoveNext(); + item = enumerator.Current; + Assert.AreEqual(2, item.Item1); + Assert.AreEqual(1, item.Item2); + Assert.AreEqual(0.0, item.Item3); + + enumerator.MoveNext(); + item = enumerator.Current; + Assert.AreEqual(2, item.Item1); + Assert.AreEqual(2, item.Item2); + Assert.AreEqual(0.0, item.Item3); + } + } +} \ No newline at end of file diff --git a/src/UnitTests/UnitTests.csproj b/src/UnitTests/UnitTests.csproj index 6ca40e38..9a71e1b5 100644 --- a/src/UnitTests/UnitTests.csproj +++ b/src/UnitTests/UnitTests.csproj @@ -568,6 +568,8 @@ Code + + Code