Browse Source

LA: slightly reworked EVD unit tests

provider
Christoph Ruegg 13 years ago
parent
commit
04d36411d5
  1. 8
      src/Numerics/LinearAlgebra/Factorization/Evd.cs
  2. 155
      src/UnitTests/AssertHelpers.cs
  3. 374
      src/UnitTests/LinearAlgebraTests/Complex/Factorization/EvdTests.cs
  4. 195
      src/UnitTests/LinearAlgebraTests/Complex/Factorization/UserEvdTests.cs
  5. 371
      src/UnitTests/LinearAlgebraTests/Complex32/Factorization/EvdTests.cs
  6. 185
      src/UnitTests/LinearAlgebraTests/Complex32/Factorization/UserEvdTests.cs
  7. 373
      src/UnitTests/LinearAlgebraTests/Double/Factorization/EvdTests.cs
  8. 195
      src/UnitTests/LinearAlgebraTests/Double/Factorization/UserEvdTests.cs
  9. 361
      src/UnitTests/LinearAlgebraTests/Single/Factorization/EvdTests.cs
  10. 195
      src/UnitTests/LinearAlgebraTests/Single/Factorization/UserEvdTests.cs

8
src/Numerics/LinearAlgebra/Factorization/Evd.cs

@ -103,7 +103,7 @@ namespace MathNet.Numerics.LinearAlgebra.Factorization
public Matrix<T> D { get; private set; }
/// <summary>
/// Solves a system of linear equations, <b>AX = B</b>, with A SVD factorized.
/// Solves a system of linear equations, <b>AX = B</b>, with A EVD factorized.
/// </summary>
/// <param name="input">The right hand side <see cref="Matrix{T}"/>, <b>B</b>.</param>
/// <returns>The left hand side <see cref="Matrix{T}"/>, <b>X</b>.</returns>
@ -115,14 +115,14 @@ namespace MathNet.Numerics.LinearAlgebra.Factorization
}
/// <summary>
/// Solves a system of linear equations, <b>AX = B</b>, with A SVD factorized.
/// Solves a system of linear equations, <b>AX = B</b>, with A EVD factorized.
/// </summary>
/// <param name="input">The right hand side <see cref="Matrix{T}"/>, <b>B</b>.</param>
/// <param name="result">The left hand side <see cref="Matrix{T}"/>, <b>X</b>.</param>
public abstract void Solve(Matrix<T> input, Matrix<T> result);
/// <summary>
/// Solves a system of linear equations, <b>Ax = b</b>, with A SVD factorized.
/// Solves a system of linear equations, <b>Ax = b</b>, with A EVD factorized.
/// </summary>
/// <param name="input">The right hand side vector, <b>b</b>.</param>
/// <returns>The left hand side <see cref="Vector{T}"/>, <b>x</b>.</returns>
@ -134,7 +134,7 @@ namespace MathNet.Numerics.LinearAlgebra.Factorization
}
/// <summary>
/// Solves a system of linear equations, <b>Ax = b</b>, with A SVD factorized.
/// Solves a system of linear equations, <b>Ax = b</b>, with A EVD factorized.
/// </summary>
/// <param name="input">The right hand side vector, <b>b</b>.</param>
/// <param name="result">The left hand side <see cref="Matrix{T}"/>, <b>x</b>.</param>

155
src/UnitTests/AssertHelpers.cs

@ -25,6 +25,7 @@
// </copyright>
using System.Collections.Generic;
using MathNet.Numerics.LinearAlgebra;
using NUnit.Framework;
namespace MathNet.Numerics.UnitTests
@ -38,7 +39,7 @@ namespace MathNet.Numerics.UnitTests
/// <summary>
/// A class which includes some assertion helper methods particularly for numerical code.
/// </summary>
internal class AssertHelpers
internal static class AssertHelpers
{
public static void AlmostEqual(Complex expected, Complex actual)
{
@ -269,5 +270,157 @@ namespace MathNet.Numerics.UnitTests
}
}
}
public static void AlmostEqual(Matrix<double> expected, Matrix<double> actual, int decimalPlaces)
{
if (expected.ColumnCount != actual.ColumnCount || expected.RowCount != actual.RowCount)
{
Assert.Fail("Matrix dimensions mismatch. Expected: {0}; Actual: {1}", expected.ToTypeString(), actual.ToTypeString());
}
for (var i = 0; i < expected.RowCount; i++)
{
for (var j = 0; j < expected.ColumnCount; j++)
{
if (!actual.At(i, j).AlmostEqual(expected.At(i, j), decimalPlaces))
{
Assert.Fail("Not equal within {0} places. Expected:{1}; Actual:{2}", decimalPlaces, expected.At(i, j), actual.At(i, j));
}
}
}
}
public static void AlmostEqual(Matrix<float> expected, Matrix<float> actual, int decimalPlaces)
{
if (expected.ColumnCount != actual.ColumnCount || expected.RowCount != actual.RowCount)
{
Assert.Fail("Matrix dimensions mismatch. Expected: {0}; Actual: {1}", expected.ToTypeString(), actual.ToTypeString());
}
for (var i = 0; i < expected.RowCount; i++)
{
for (var j = 0; j < expected.ColumnCount; j++)
{
if (!actual.At(i, j).AlmostEqual(expected.At(i, j), decimalPlaces))
{
Assert.Fail("Not equal within {0} places. Expected:{1}; Actual:{2}", decimalPlaces, expected.At(i, j), actual.At(i, j));
}
}
}
}
public static void AlmostEqual(Matrix<Complex> expected, Matrix<Complex> actual, int decimalPlaces)
{
if (expected.ColumnCount != actual.ColumnCount || expected.RowCount != actual.RowCount)
{
Assert.Fail("Matrix dimensions mismatch. Expected: {0}; Actual: {1}", expected.ToTypeString(), actual.ToTypeString());
}
for (var i = 0; i < expected.RowCount; i++)
{
for (var j = 0; j < expected.ColumnCount; j++)
{
if (!actual.At(i, j).AlmostEqual(expected.At(i, j), decimalPlaces))
{
Assert.Fail("Not equal within {0} places. Expected:{1}; Actual:{2}", decimalPlaces, expected.At(i, j), actual.At(i, j));
}
}
}
}
public static void AlmostEqual(Matrix<Complex32> expected, Matrix<Complex32> actual, int decimalPlaces)
{
if (expected.ColumnCount != actual.ColumnCount || expected.RowCount != actual.RowCount)
{
Assert.Fail("Matrix dimensions mismatch. Expected: {0}; Actual: {1}", expected.ToTypeString(), actual.ToTypeString());
}
for (var i = 0; i < expected.RowCount; i++)
{
for (var j = 0; j < expected.ColumnCount; j++)
{
if (!actual.At(i, j).AlmostEqual(expected.At(i, j), decimalPlaces))
{
Assert.Fail("Not equal within {0} places. Expected:{1}; Actual:{2}", decimalPlaces, expected.At(i, j), actual.At(i, j));
}
}
}
}
public static void AlmostEqualRelative(Matrix<double> expected, Matrix<double> actual, int decimalPlaces)
{
if (expected.ColumnCount != actual.ColumnCount || expected.RowCount != actual.RowCount)
{
Assert.Fail("Matrix dimensions mismatch. Expected: {0}; Actual: {1}", expected.ToTypeString(), actual.ToTypeString());
}
for (var i = 0; i < expected.RowCount; i++)
{
for (var j = 0; j < expected.ColumnCount; j++)
{
if (!actual.At(i, j).AlmostEqualRelative(expected.At(i, j), decimalPlaces))
{
Assert.Fail("Not equal within {0} relative places. Expected:{1}; Actual:{2}", decimalPlaces, expected.At(i, j), actual.At(i, j));
}
}
}
}
public static void AlmostEqualRelative(Matrix<float> expected, Matrix<float> actual, int decimalPlaces)
{
if (expected.ColumnCount != actual.ColumnCount || expected.RowCount != actual.RowCount)
{
Assert.Fail("Matrix dimensions mismatch. Expected: {0}; Actual: {1}", expected.ToTypeString(), actual.ToTypeString());
}
for (var i = 0; i < expected.RowCount; i++)
{
for (var j = 0; j < expected.ColumnCount; j++)
{
if (!actual.At(i, j).AlmostEqualRelative(expected.At(i, j), decimalPlaces))
{
Assert.Fail("Not equal within {0} relative places. Expected:{1}; Actual:{2}", decimalPlaces, expected.At(i, j), actual.At(i, j));
}
}
}
}
public static void AlmostEqualRelative(Matrix<Complex> expected, Matrix<Complex> actual, int decimalPlaces)
{
if (expected.ColumnCount != actual.ColumnCount || expected.RowCount != actual.RowCount)
{
Assert.Fail("Matrix dimensions mismatch. Expected: {0}; Actual: {1}", expected.ToTypeString(), actual.ToTypeString());
}
for (var i = 0; i < expected.RowCount; i++)
{
for (var j = 0; j < expected.ColumnCount; j++)
{
if (!actual.At(i, j).AlmostEqualRelative(expected.At(i, j), decimalPlaces))
{
Assert.Fail("Not equal within {0} relative places. Expected:{1}; Actual:{2}", decimalPlaces, expected.At(i, j), actual.At(i, j));
}
}
}
}
public static void AlmostEqualRelative(Matrix<Complex32> expected, Matrix<Complex32> actual, int decimalPlaces)
{
if (expected.ColumnCount != actual.ColumnCount || expected.RowCount != actual.RowCount)
{
Assert.Fail("Matrix dimensions mismatch. Expected: {0}; Actual: {1}", expected.ToTypeString(), actual.ToTypeString());
}
for (var i = 0; i < expected.RowCount; i++)
{
for (var j = 0; j < expected.ColumnCount; j++)
{
if (!actual.At(i, j).AlmostEqualRelative(expected.At(i, j), decimalPlaces))
{
Assert.Fail("Not equal within {0} relative places. Expected:{1}; Actual:{2}", decimalPlaces, expected.At(i, j), actual.At(i, j));
}
}
}
}
}
}

374
src/UnitTests/LinearAlgebraTests/Complex/Factorization/EvdTests.cs

@ -3,7 +3,9 @@
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
// Copyright (c) 2009-2010 Math.NET
//
// Copyright (c) 2009-2014 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
@ -12,8 +14,10 @@
// 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
@ -42,26 +46,19 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization
[TestFixture, Category("LAFactorization")]
public class EvdTests
{
/// <summary>
/// Can factorize identity matrix.
/// </summary>
/// <param name="order">Matrix order.</param>
[TestCase(1)]
[TestCase(10)]
[TestCase(100)]
public void CanFactorizeIdentity(int order)
[Test]
public void CanFactorizeIdentityMatrix([Values(1, 10, 100)] int order)
{
var matrixI = DenseMatrix.CreateIdentity(order);
var factorEvd = matrixI.Evd();
var matrix = Matrix<Complex>.Build.DenseIdentity(order);
var factorEvd = matrix.Evd();
var eigenValues = factorEvd.EigenValues;
var eigenVectors = factorEvd.EigenVectors;
var d = factorEvd.D;
Assert.AreEqual(matrixI.RowCount, eigenVectors.RowCount);
Assert.AreEqual(matrixI.RowCount, eigenVectors.ColumnCount);
Assert.AreEqual(matrixI.ColumnCount, d.RowCount);
Assert.AreEqual(matrixI.ColumnCount, d.ColumnCount);
Assert.AreEqual(matrix.RowCount, eigenVectors.RowCount);
Assert.AreEqual(matrix.RowCount, eigenVectors.ColumnCount);
Assert.AreEqual(matrix.ColumnCount, d.RowCount);
Assert.AreEqual(matrix.ColumnCount, d.ColumnCount);
for (var i = 0; i < eigenValues.Count; i++)
{
@ -69,126 +66,75 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization
}
}
/// <summary>
/// Can factorize a random square matrix.
/// </summary>
/// <param name="order">Matrix order.</param>
[TestCase(1)]
[TestCase(2)]
[TestCase(5)]
[TestCase(10)]
[TestCase(50)]
[TestCase(100)]
public void CanFactorizeRandomMatrix(int order)
[Test]
public void CanFactorizeRandomSquareMatrix([Values(1, 2, 5, 10, 50, 100)] int order)
{
var matrixA = Matrix<Complex>.Build.Random(order, order, 1);
var factorEvd = matrixA.Evd();
var eigenVectors = factorEvd.EigenVectors;
Assert.AreEqual(order, eigenVectors.RowCount);
Assert.AreEqual(order, eigenVectors.ColumnCount);
Assert.AreEqual(order, factorEvd.D.RowCount);
Assert.AreEqual(order, factorEvd.D.ColumnCount);
// Make sure the A*V = λ*V
var matrixAv = matrixA * eigenVectors;
var matrixLv = eigenVectors * factorEvd.D;
for (var i = 0; i < matrixAv.RowCount; i++)
{
for (var j = 0; j < matrixAv.ColumnCount; j++)
{
AssertHelpers.AlmostEqualRelative(matrixAv[i, j], matrixLv[i, j], 7);
}
}
var A = Matrix<Complex>.Build.Random(order, order, 1);
var factorEvd = A.Evd();
var V = factorEvd.EigenVectors;
var λ = factorEvd.D;
Assert.AreEqual(order, V.RowCount);
Assert.AreEqual(order, V.ColumnCount);
Assert.AreEqual(order, λ.RowCount);
Assert.AreEqual(order, λ.ColumnCount);
// Verify A*V = λ*V
var Av = A * V;
var Lv = V * λ;
AssertHelpers.AlmostEqual(Av, Lv, 10);
AssertHelpers.AlmostEqualRelative(Av, Lv, 8);
}
/// <summary>
/// Can factorize a symmetric random square matrix.
/// </summary> <param name="order">Matrix order.</param>
[Test]
[TestCase(1)]
[TestCase(2)]
[TestCase(5)]
[TestCase(10)]
[TestCase(50)]
[TestCase(100)]
public void CanFactorizeRandomSymmetricMatrix(int order)
public void CanFactorizeRandomSymmetricMatrix([Values(1, 2, 5, 10, 50, 100)] int order)
{
var matrixA = Matrix<Complex>.Build.RandomPositiveDefinite(order, 1);
MatrixHelpers.ForceConjugateSymmetric(matrixA);
var factorEvd = matrixA.Evd();
var eigenVectors = factorEvd.EigenVectors;
var d = factorEvd.D;
Assert.AreEqual(order, eigenVectors.RowCount);
Assert.AreEqual(order, eigenVectors.ColumnCount);
Assert.AreEqual(order, d.RowCount);
Assert.AreEqual(order, d.ColumnCount);
// Make sure the A = V*λ*VT
var matrix = eigenVectors * d * eigenVectors.ConjugateTranspose();
for (var i = 0; i < matrix.RowCount; i++)
{
for (var j = 0; j < matrix.ColumnCount; j++)
{
AssertHelpers.AlmostEqualRelative(matrix[i, j], matrixA[i, j], 7);
}
}
var A = Matrix<Complex>.Build.RandomPositiveDefinite(order, 1);
MatrixHelpers.ForceConjugateSymmetric(A);
var factorEvd = A.Evd();
var V = factorEvd.EigenVectors;
var λ = factorEvd.D;
Assert.AreEqual(order, V.RowCount);
Assert.AreEqual(order, V.ColumnCount);
Assert.AreEqual(order, λ.RowCount);
Assert.AreEqual(order, λ.ColumnCount);
// Verify A = V*λ*VT
var matrix = V*λ*V.ConjugateTranspose();
AssertHelpers.AlmostEqual(matrix, A, 10);
AssertHelpers.AlmostEqualRelative(matrix, A, 10);
}
/// <summary>
/// Can check rank of square matrix.
/// </summary>
/// <param name="order">Matrix order.</param>
[TestCase(10)]
[TestCase(50)]
[TestCase(100)]
public void CanCheckRankSquare(int order)
[Test]
public void CanCheckRankSquare([Values(10, 50, 100)] int order)
{
var matrixA = Matrix<Complex>.Build.Random(order, order, 1);
var factorEvd = matrixA.Evd();
Assert.AreEqual(factorEvd.Rank, order);
var A = Matrix<Complex>.Build.Random(order, order, 1);
Assert.AreEqual(A.Evd().Rank, order);
}
/// <summary>
/// Can check rank of square singular matrix.
/// </summary>
/// <param name="order">Matrix order.</param>
[TestCase(10)]
[TestCase(50)]
[TestCase(100)]
public void CanCheckRankOfSquareSingular(int order)
[Test]
public void CanCheckRankOfSquareSingular([Values(10, 50, 100)] int order)
{
var matrixA = new DenseMatrix(order, order);
matrixA[0, 0] = 1;
matrixA[order - 1, order - 1] = 1;
var A = new DenseMatrix(order, order);
A[0, 0] = 1;
A[order - 1, order - 1] = 1;
for (var i = 1; i < order - 1; i++)
{
matrixA[i, i - 1] = 1;
matrixA[i, i + 1] = 1;
matrixA[i - 1, i] = 1;
matrixA[i + 1, i] = 1;
A[i, i - 1] = 1;
A[i, i + 1] = 1;
A[i - 1, i] = 1;
A[i + 1, i] = 1;
}
var factorEvd = matrixA.Evd();
var factorEvd = A.Evd();
Assert.AreEqual(factorEvd.Determinant, Complex.Zero);
Assert.AreEqual(factorEvd.Rank, order - 1);
}
/// <summary>
/// Identity determinant is one.
/// </summary>
/// <param name="order">Matrix order.</param>
[TestCase(1)]
[TestCase(10)]
[TestCase(100)]
public void IdentityDeterminantIsOne(int order)
[Test]
public void IdentityDeterminantIsOne([Values(1, 10, 100)] int order)
{
var matrixI = DenseMatrix.CreateIdentity(order);
var factorEvd = matrixI.Evd();
@ -200,40 +146,26 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization
/// </summary>
/// <param name="order">Matrix order.</param>
[Test]
[TestCase(1)]
[TestCase(2)]
[TestCase(5)]
[TestCase(10)]
[TestCase(50)]
[TestCase(100)]
public void CanSolveForRandomVectorAndSymmetricMatrix(int order)
public void CanSolveForRandomVectorAndSymmetricMatrix([Values(1, 2, 5, 10, 50, 100)] int order)
{
var matrixA = Matrix<Complex>.Build.RandomPositiveDefinite(order, 1);
MatrixHelpers.ForceConjugateSymmetric(matrixA);
var matrixACopy = matrixA.Clone();
var factorEvd = matrixA.Evd();
var A = Matrix<Complex>.Build.RandomPositiveDefinite(order, 1);
MatrixHelpers.ForceConjugateSymmetric(A);
var ACopy = A.Clone();
var evd = A.Evd();
var vectorb = Vector<Complex>.Build.Random(order, 1);
var resultx = factorEvd.Solve(vectorb);
var b = Vector<Complex>.Build.Random(order, 2);
var bCopy = b.Clone();
Assert.AreEqual(matrixA.ColumnCount, resultx.Count);
var x = evd.Solve(b);
var matrixBReconstruct = matrixA * resultx;
var bReconstruct = A * x;
// Check the reconstruction.
for (var i = 0; i < vectorb.Count; i++)
{
AssertHelpers.AlmostEqual(vectorb[i], matrixBReconstruct[i], 10);
}
AssertHelpers.ListAlmostEqual(b, bReconstruct, 9);
// Make sure A didn't change.
for (var i = 0; i < matrixA.RowCount; i++)
{
for (var j = 0; j < matrixA.ColumnCount; j++)
{
Assert.AreEqual(matrixACopy[i, j], matrixA[i, j]);
}
}
// Make sure A/B didn't change.
AssertHelpers.AlmostEqual(ACopy, A, 14);
AssertHelpers.ListAlmostEqual(bCopy, b, 14);
}
/// <summary>
@ -241,47 +173,33 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization
/// </summary>
/// <param name="order">Matrix order.</param>
[Test]
[TestCase(1)]
[TestCase(2)]
[TestCase(5)]
[TestCase(10)]
[TestCase(50)]
[TestCase(100)]
public void CanSolveForRandomMatrixAndSymmetricMatrix(int order)
public void CanSolveForRandomMatrixAndSymmetricMatrix([Values(1, 2, 5, 10, 50, 100)] int order)
{
var matrixA = Matrix<Complex>.Build.RandomPositiveDefinite(order, 1);
MatrixHelpers.ForceConjugateSymmetric(matrixA);
var matrixACopy = matrixA.Clone();
var factorEvd = matrixA.Evd();
var matrixB = Matrix<Complex>.Build.Random(order, order, 1);
var matrixX = factorEvd.Solve(matrixB);
var A = Matrix<Complex>.Build.RandomPositiveDefinite(order, 1);
MatrixHelpers.ForceConjugateSymmetric(A);
var ACopy = A.Clone();
var evd = A.Evd();
var B = Matrix<Complex>.Build.Random(order, order, 2);
var BCopy = B.Clone();
var X = evd.Solve(B);
// The solution X row dimension is equal to the column dimension of A
Assert.AreEqual(matrixA.ColumnCount, matrixX.RowCount);
Assert.AreEqual(A.ColumnCount, X.RowCount);
// The solution X has the same number of columns as B
Assert.AreEqual(matrixB.ColumnCount, matrixX.ColumnCount);
Assert.AreEqual(B.ColumnCount, X.ColumnCount);
var matrixBReconstruct = matrixA * matrixX;
var BReconstruct = A * X;
// Check the reconstruction.
for (var i = 0; i < matrixB.RowCount; i++)
{
for (var j = 0; j < matrixB.ColumnCount; j++)
{
AssertHelpers.AlmostEqual(matrixB[i, j], matrixBReconstruct[i, j], 10);
}
}
AssertHelpers.AlmostEqual(B, BReconstruct, 9);
// Make sure A didn't change.
for (var i = 0; i < matrixA.RowCount; i++)
{
for (var j = 0; j < matrixA.ColumnCount; j++)
{
Assert.AreEqual(matrixACopy[i, j], matrixA[i, j]);
}
}
// Make sure A/B didn't change.
AssertHelpers.AlmostEqual(ACopy, A, 14);
AssertHelpers.AlmostEqual(BCopy, B, 14);
}
/// <summary>
@ -289,45 +207,27 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization
/// </summary>
/// <param name="order">Matrix order.</param>
[Test]
[TestCase(1)]
[TestCase(2)]
[TestCase(5)]
[TestCase(10)]
[TestCase(50)]
[TestCase(100)]
public void CanSolveForRandomVectorAndSymmetricMatrixWhenResultVectorGiven(int order)
public void CanSolveForRandomVectorAndSymmetricMatrixWhenResultVectorGiven([Values(1, 2, 5, 10, 50, 100)] int order)
{
var matrixA = Matrix<Complex>.Build.RandomPositiveDefinite(order, 1);
MatrixHelpers.ForceConjugateSymmetric(matrixA);
var matrixACopy = matrixA.Clone();
var factorEvd = matrixA.Evd();
var vectorb = Vector<Complex>.Build.Random(order, 1);
var vectorbCopy = vectorb.Clone();
var resultx = new DenseVector(order);
factorEvd.Solve(vectorb, resultx);
var A = Matrix<Complex>.Build.RandomPositiveDefinite(order, 1);
MatrixHelpers.ForceConjugateSymmetric(A);
var ACopy = A.Clone();
var evd = A.Evd();
var matrixBReconstruct = matrixA * resultx;
var b = Vector<Complex>.Build.Random(order, 2);
var bCopy = b.Clone();
// Check the reconstruction.
for (var i = 0; i < vectorb.Count; i++)
{
AssertHelpers.AlmostEqual(vectorb[i], matrixBReconstruct[i], 10);
}
var x = new DenseVector(order);
evd.Solve(b, x);
// Make sure A didn't change.
for (var i = 0; i < matrixA.RowCount; i++)
{
for (var j = 0; j < matrixA.ColumnCount; j++)
{
Assert.AreEqual(matrixACopy[i, j], matrixA[i, j]);
}
}
var bReconstruct = A * x;
// Make sure b didn't change.
for (var i = 0; i < vectorb.Count; i++)
{
Assert.AreEqual(vectorbCopy[i], vectorb[i]);
}
// Check the reconstruction.
AssertHelpers.ListAlmostEqual(b, bReconstruct, 9);
// Make sure A/B didn't change.
AssertHelpers.AlmostEqual(ACopy, A, 14);
AssertHelpers.ListAlmostEqual(bCopy, b, 14);
}
/// <summary>
@ -335,59 +235,33 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization
/// </summary>
/// <param name="order">Matrix order.</param>
[Test]
[TestCase(1)]
[TestCase(2)]
[TestCase(5)]
[TestCase(10)]
[TestCase(50)]
[TestCase(100)]
public void CanSolveForRandomMatrixAndSymmetricMatrixWhenResultMatrixGiven(int order)
public void CanSolveForRandomMatrixAndSymmetricMatrixWhenResultMatrixGiven([Values(1, 2, 5, 10, 50, 100)] int order)
{
var matrixA = Matrix<Complex>.Build.RandomPositiveDefinite(order, 1);
MatrixHelpers.ForceConjugateSymmetric(matrixA);
var matrixACopy = matrixA.Clone();
var factorEvd = matrixA.Evd();
var A = Matrix<Complex>.Build.RandomPositiveDefinite(order, 1);
MatrixHelpers.ForceConjugateSymmetric(A);
var ACopy = A.Clone();
var evd = A.Evd();
var matrixB = Matrix<Complex>.Build.Random(order, order, 1);
var matrixBCopy = matrixB.Clone();
var B = Matrix<Complex>.Build.Random(order, order, 2);
var BCopy = B.Clone();
var matrixX = new DenseMatrix(order, order);
factorEvd.Solve(matrixB, matrixX);
var X = new DenseMatrix(order, order);
evd.Solve(B, X);
// The solution X row dimension is equal to the column dimension of A
Assert.AreEqual(matrixA.ColumnCount, matrixX.RowCount);
Assert.AreEqual(A.ColumnCount, X.RowCount);
// The solution X has the same number of columns as B
Assert.AreEqual(matrixB.ColumnCount, matrixX.ColumnCount);
Assert.AreEqual(B.ColumnCount, X.ColumnCount);
var matrixBReconstruct = matrixA * matrixX;
var BReconstruct = A * X;
// Check the reconstruction.
for (var i = 0; i < matrixB.RowCount; i++)
{
for (var j = 0; j < matrixB.ColumnCount; j++)
{
AssertHelpers.AlmostEqual(matrixB[i, j], matrixBReconstruct[i, j], 10);
}
}
// Make sure A didn't change.
for (var i = 0; i < matrixA.RowCount; i++)
{
for (var j = 0; j < matrixA.ColumnCount; j++)
{
Assert.AreEqual(matrixACopy[i, j], matrixA[i, j]);
}
}
AssertHelpers.AlmostEqual(B, BReconstruct, 9);
// Make sure B didn't change.
for (var i = 0; i < matrixB.RowCount; i++)
{
for (var j = 0; j < matrixB.ColumnCount; j++)
{
Assert.AreEqual(matrixBCopy[i, j], matrixB[i, j]);
}
}
// Make sure A/B didn't change.
AssertHelpers.AlmostEqual(ACopy, A, 14);
AssertHelpers.AlmostEqual(BCopy, B, 14);
}
}
}

195
src/UnitTests/LinearAlgebraTests/Complex/Factorization/UserEvdTests.cs

@ -198,187 +198,122 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex.Factorization
/// Can solve a system of linear equations for a random vector and symmetric matrix (Ax=b).
/// </summary>
/// <param name="order">Matrix order.</param>
[TestCase(1)]
[TestCase(2)]
[TestCase(5)]
[TestCase(10)]
[TestCase(50)]
[TestCase(100)]
public void CanSolveForRandomVectorAndSymmetricMatrix(int order)
[Test]
public void CanSolveForRandomVectorAndSymmetricMatrix([Values(1, 2, 5, 10, 50, 100)] int order)
{
var matrixA = new UserDefinedMatrix(Matrix<Complex>.Build.RandomPositiveDefinite(order, 1).ToArray());
var matrixACopy = matrixA.Clone();
var factorEvd = matrixA.Evd();
var A = new UserDefinedMatrix(Matrix<Complex>.Build.RandomPositiveDefinite(order, 1).ToArray());
MatrixHelpers.ForceConjugateSymmetric(A);
var ACopy = A.Clone();
var evd = A.Evd();
var vectorb = new UserDefinedVector(Vector<Complex>.Build.Random(order, 1).ToArray());
var resultx = factorEvd.Solve(vectorb);
var b = new UserDefinedVector(Vector<Complex>.Build.Random(order, 1).ToArray());
var bCopy = b.Clone();
Assert.AreEqual(matrixA.ColumnCount, resultx.Count);
var x = evd.Solve(b);
var matrixBReconstruct = matrixA * resultx;
var bReconstruct = A * x;
// Check the reconstruction.
for (var i = 0; i < vectorb.Count; i++)
{
AssertHelpers.AlmostEqual(vectorb[i], matrixBReconstruct[i], 10);
}
AssertHelpers.AlmostEqual(b, bReconstruct, 9);
// Make sure A didn't change.
for (var i = 0; i < matrixA.RowCount; i++)
{
for (var j = 0; j < matrixA.ColumnCount; j++)
{
Assert.AreEqual(matrixACopy[i, j], matrixA[i, j]);
}
}
// Make sure A/B didn't change.
AssertHelpers.AlmostEqual(ACopy, A, 14);
AssertHelpers.AlmostEqual(bCopy, b, 14);
}
/// <summary>
/// Can solve a system of linear equations for a random matrix and symmetric matrix (AX=B).
/// </summary>
/// <param name="order">Matrix order.</param>
[TestCase(1)]
[TestCase(2)]
[TestCase(5)]
[TestCase(10)]
[TestCase(50)]
[TestCase(100)]
public void CanSolveForRandomMatrixAndSymmetricMatrix(int order)
[Test]
public void CanSolveForRandomMatrixAndSymmetricMatrix([Values(1, 2, 5, 10, 50, 100)] int order)
{
var matrixA = new UserDefinedMatrix(Matrix<Complex>.Build.RandomPositiveDefinite(order, 1).ToArray());
var matrixACopy = matrixA.Clone();
var factorEvd = matrixA.Evd();
var A = new UserDefinedMatrix(Matrix<Complex>.Build.RandomPositiveDefinite(order, 1).ToArray());
MatrixHelpers.ForceConjugateSymmetric(A);
var ACopy = A.Clone();
var evd = A.Evd();
var B = new UserDefinedMatrix(Matrix<Complex>.Build.Random(order, order, 1).ToArray());
var BCopy = B.Clone();
var matrixB = new UserDefinedMatrix(Matrix<Complex>.Build.Random(order, order, 1).ToArray());
var matrixX = factorEvd.Solve(matrixB);
var X = evd.Solve(B);
// The solution X row dimension is equal to the column dimension of A
Assert.AreEqual(matrixA.ColumnCount, matrixX.RowCount);
Assert.AreEqual(A.ColumnCount, X.RowCount);
// The solution X has the same number of columns as B
Assert.AreEqual(matrixB.ColumnCount, matrixX.ColumnCount);
Assert.AreEqual(B.ColumnCount, X.ColumnCount);
var matrixBReconstruct = matrixA * matrixX;
var BReconstruct = A * X;
// Check the reconstruction.
for (var i = 0; i < matrixB.RowCount; i++)
{
for (var j = 0; j < matrixB.ColumnCount; j++)
{
AssertHelpers.AlmostEqual(matrixB[i, j], matrixBReconstruct[i, j], 10);
}
}
AssertHelpers.AlmostEqual(B, BReconstruct, 9);
// Make sure A didn't change.
for (var i = 0; i < matrixA.RowCount; i++)
{
for (var j = 0; j < matrixA.ColumnCount; j++)
{
Assert.AreEqual(matrixACopy[i, j], matrixA[i, j]);
}
}
// Make sure A/B didn't change.
AssertHelpers.AlmostEqual(ACopy, A, 14);
AssertHelpers.AlmostEqual(BCopy, B, 14);
}
/// <summary>
/// Can solve a system of linear equations for a random vector and symmetric matrix (Ax=b) into a result matrix.
/// </summary>
/// <param name="order">Matrix order.</param>
[TestCase(1)]
[TestCase(2)]
[TestCase(5)]
[TestCase(10)]
[TestCase(50)]
[TestCase(100)]
public void CanSolveForRandomVectorAndSymmetricMatrixWhenResultVectorGiven(int order)
[Test]
public void CanSolveForRandomVectorAndSymmetricMatrixWhenResultVectorGiven([Values(1, 2, 5, 10, 50, 100)] int order)
{
var matrixA = new UserDefinedMatrix(Matrix<Complex>.Build.RandomPositiveDefinite(order, 1).ToArray());
var matrixACopy = matrixA.Clone();
var factorEvd = matrixA.Evd();
var vectorb = new UserDefinedVector(Vector<Complex>.Build.Random(order, 1).ToArray());
var vectorbCopy = vectorb.Clone();
var resultx = new UserDefinedVector(order);
factorEvd.Solve(vectorb, resultx);
var A = new UserDefinedMatrix(Matrix<Complex>.Build.RandomPositiveDefinite(order, 1).ToArray());
MatrixHelpers.ForceConjugateSymmetric(A);
var ACopy = A.Clone();
var evd = A.Evd();
var matrixBReconstruct = matrixA * resultx;
var b = new UserDefinedVector(Vector<Complex>.Build.Random(order, 1).ToArray());
var bCopy = b.Clone();
// Check the reconstruction.
for (var i = 0; i < vectorb.Count; i++)
{
AssertHelpers.AlmostEqual(vectorb[i], matrixBReconstruct[i], 10);
}
var x = new UserDefinedVector(order);
evd.Solve(b, x);
// Make sure A didn't change.
for (var i = 0; i < matrixA.RowCount; i++)
{
for (var j = 0; j < matrixA.ColumnCount; j++)
{
Assert.AreEqual(matrixACopy[i, j], matrixA[i, j]);
}
}
var bReconstruct = A * x;
// Make sure b didn't change.
for (var i = 0; i < vectorb.Count; i++)
{
Assert.AreEqual(vectorbCopy[i], vectorb[i]);
}
// Check the reconstruction.
AssertHelpers.AlmostEqual(b, bReconstruct, 9);
// Make sure A/B didn't change.
AssertHelpers.AlmostEqual(ACopy, A, 14);
AssertHelpers.AlmostEqual(bCopy, b, 14);
}
/// <summary>
/// Can solve a system of linear equations for a random matrix and symmetric matrix (AX=B) into result matrix.
/// </summary>
/// <param name="order">Matrix order.</param>
[TestCase(1)]
[TestCase(2)]
[TestCase(5)]
[TestCase(10)]
[TestCase(50)]
[TestCase(100)]
public void CanSolveForRandomMatrixAndSymmetricMatrixWhenResultMatrixGiven(int order)
[Test]
public void CanSolveForRandomMatrixAndSymmetricMatrixWhenResultMatrixGiven([Values(1, 2, 5, 10, 50, 100)] int order)
{
var matrixA = new UserDefinedMatrix(Matrix<Complex>.Build.RandomPositiveDefinite(order, 1).ToArray());
var matrixACopy = matrixA.Clone();
var factorEvd = matrixA.Evd();
var A = new UserDefinedMatrix(Matrix<Complex>.Build.RandomPositiveDefinite(order, 1).ToArray());
MatrixHelpers.ForceConjugateSymmetric(A);
var ACopy = A.Clone();
var evd = A.Evd();
var matrixB = new UserDefinedMatrix(Matrix<Complex>.Build.Random(order, order, 1).ToArray());
var matrixBCopy = matrixB.Clone();
var B = new UserDefinedMatrix(Matrix<Complex>.Build.Random(order, order, 1).ToArray());
var BCopy = B.Clone();
var matrixX = new UserDefinedMatrix(order, order);
factorEvd.Solve(matrixB, matrixX);
var X = new UserDefinedMatrix(order, order);
evd.Solve(B, X);
// The solution X row dimension is equal to the column dimension of A
Assert.AreEqual(matrixA.ColumnCount, matrixX.RowCount);
Assert.AreEqual(A.ColumnCount, X.RowCount);
// The solution X has the same number of columns as B
Assert.AreEqual(matrixB.ColumnCount, matrixX.ColumnCount);
Assert.AreEqual(B.ColumnCount, X.ColumnCount);
var matrixBReconstruct = matrixA * matrixX;
var BReconstruct = A * X;
// Check the reconstruction.
for (var i = 0; i < matrixB.RowCount; i++)
{
for (var j = 0; j < matrixB.ColumnCount; j++)
{
AssertHelpers.AlmostEqual(matrixB[i, j], matrixBReconstruct[i, j], 10);
}
}
AssertHelpers.AlmostEqual(B, BReconstruct, 9);
// Make sure A didn't change.
for (var i = 0; i < matrixA.RowCount; i++)
{
for (var j = 0; j < matrixA.ColumnCount; j++)
{
Assert.AreEqual(matrixACopy[i, j], matrixA[i, j]);
}
}
// Make sure B didn't change.
for (var i = 0; i < matrixB.RowCount; i++)
{
for (var j = 0; j < matrixB.ColumnCount; j++)
{
Assert.AreEqual(matrixBCopy[i, j], matrixB[i, j]);
}
}
// Make sure A/B didn't change.
AssertHelpers.AlmostEqual(ACopy, A, 14);
AssertHelpers.AlmostEqual(BCopy, B, 14);
}
}
}

371
src/UnitTests/LinearAlgebraTests/Complex32/Factorization/EvdTests.cs

@ -3,7 +3,9 @@
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
// Copyright (c) 2009-2010 Math.NET
//
// Copyright (c) 2009-2014 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
@ -12,8 +14,10 @@
// 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
@ -44,149 +48,94 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization
[TestFixture, Category("LAFactorization")]
public class EvdTests
{
/// <summary>
/// Can factorize identity matrix.
/// </summary>
/// <param name="order">Matrix order.</param>
[TestCase(1)]
[TestCase(10)]
[TestCase(100)]
public void CanFactorizeIdentity(int order)
[Test]
public void CanFactorizeIdentityMatrix([Values(1, 10, 100)] int order)
{
var matrixI = DenseMatrix.CreateIdentity(order);
var factorEvd = matrixI.Evd();
var matrix = Matrix<Complex32>.Build.DenseIdentity(order);
var factorEvd = matrix.Evd();
var eigenValues = factorEvd.EigenValues;
var eigenVectors = factorEvd.EigenVectors;
var d = factorEvd.D;
Assert.AreEqual(matrixI.RowCount, eigenVectors.RowCount);
Assert.AreEqual(matrixI.RowCount, eigenVectors.ColumnCount);
Assert.AreEqual(matrixI.ColumnCount, d.RowCount);
Assert.AreEqual(matrixI.ColumnCount, d.ColumnCount);
Assert.AreEqual(matrix.RowCount, eigenVectors.RowCount);
Assert.AreEqual(matrix.RowCount, eigenVectors.ColumnCount);
Assert.AreEqual(matrix.ColumnCount, d.RowCount);
Assert.AreEqual(matrix.ColumnCount, d.ColumnCount);
for (var i = 0; i < factorEvd.EigenValues.Count; i++)
for (var i = 0; i < eigenValues.Count; i++)
{
Assert.AreEqual(Complex.One, eigenValues[i]);
}
}
/// <summary>
/// Can factorize a random square matrix.
/// </summary>
/// <param name="order">Matrix order.</param>
[TestCase(1)]
[TestCase(2)]
[TestCase(5)]
[TestCase(10)]
[TestCase(50)]
[TestCase(100)]
public void CanFactorizeRandomMatrix(int order)
[Test]
public void CanFactorizeRandomSquareMatrix([Values(1, 2, 5, 10, 50, 100)] int order)
{
var matrixA = Matrix<Complex32>.Build.Random(order, order, 1);
var factorEvd = matrixA.Evd();
var eigenVectors = factorEvd.EigenVectors;
var d = factorEvd.D;
Assert.AreEqual(order, eigenVectors.RowCount);
Assert.AreEqual(order, eigenVectors.ColumnCount);
Assert.AreEqual(order, d.RowCount);
Assert.AreEqual(order, d.ColumnCount);
// Make sure the A*V = λ*V
var matrixAv = matrixA * eigenVectors;
var matrixLv = eigenVectors * factorEvd.D;
for (var i = 0; i < matrixAv.RowCount; i++)
{
for (var j = 0; j < matrixAv.ColumnCount; j++)
{
Assert.AreEqual(matrixAv[i, j].Real, matrixLv[i, j].Real, 1e-3f);
Assert.AreEqual(matrixAv[i, j].Imaginary, matrixLv[i, j].Imaginary, 1e-3f);
}
}
var A = Matrix<Complex32>.Build.Random(order, order, 1);
var factorEvd = A.Evd();
var V = factorEvd.EigenVectors;
var λ = factorEvd.D;
Assert.AreEqual(order, V.RowCount);
Assert.AreEqual(order, V.ColumnCount);
Assert.AreEqual(order, λ.RowCount);
Assert.AreEqual(order, λ.ColumnCount);
// Verify A*V = λ*V
var Av = A * V;
var Lv = V * λ;
AssertHelpers.AlmostEqual(Av, Lv, 4);
}
/// <summary>
/// Can factorize a symmetric random square matrix.
/// </summary> <param name="order">Matrix order.</param>
[Test]
public void CanFactorizeRandomSymmetricMatrix([Values(1, 2, 5, 10)] int order)
public void CanFactorizeRandomSymmetricMatrix([Values(1, 2, 5, 10, 50, 100)] int order)
{
var matrixA = Matrix<Complex32>.Build.RandomPositiveDefinite(order, 1);
MatrixHelpers.ForceConjugateSymmetric(matrixA);
var factorEvd = matrixA.Evd();
var eigenVectors = factorEvd.EigenVectors;
var d = factorEvd.D;
Assert.AreEqual(order, eigenVectors.RowCount);
Assert.AreEqual(order, eigenVectors.ColumnCount);
Assert.AreEqual(order, d.RowCount);
Assert.AreEqual(order, d.ColumnCount);
// Make sure the A = V*λ*VT
var matrix = eigenVectors * d * eigenVectors.ConjugateTranspose();
for (var i = 0; i < matrix.RowCount; i++)
{
for (var j = 0; j < matrix.ColumnCount; j++)
{
AssertHelpers.AlmostEqual(matrix[i, j], matrixA[i, j], 3);
}
}
var A = Matrix<Complex32>.Build.RandomPositiveDefinite(order, 1);
MatrixHelpers.ForceConjugateSymmetric(A);
var factorEvd = A.Evd();
var V = factorEvd.EigenVectors;
var λ = factorEvd.D;
Assert.AreEqual(order, V.RowCount);
Assert.AreEqual(order, V.ColumnCount);
Assert.AreEqual(order, λ.RowCount);
Assert.AreEqual(order, λ.ColumnCount);
// Verify A = V*λ*VT
var matrix = V*λ*V.ConjugateTranspose();
AssertHelpers.AlmostEqual(matrix, A, 3);
AssertHelpers.AlmostEqualRelative(matrix, A, 1);
}
/// <summary>
/// Can check rank of square matrix.
/// </summary>
/// <param name="order">Matrix order.</param>
[TestCase(10)]
[TestCase(50)]
[TestCase(100)]
public void CanCheckRankSquare(int order)
[Test]
public void CanCheckRankSquare([Values(10, 50, 100)] int order)
{
var matrixA = Matrix<Complex32>.Build.Random(order, order, 1);
var factorEvd = matrixA.Evd();
Assert.AreEqual(factorEvd.Rank, order);
var A = Matrix<Complex32>.Build.Random(order, order, 1);
Assert.AreEqual(A.Evd().Rank, order);
}
/// <summary>
/// Can check rank of square singular matrix.
/// </summary>
/// <param name="order">Matrix order.</param>
[TestCase(10)]
[TestCase(50)]
[TestCase(100)]
public void CanCheckRankOfSquareSingular(int order)
[Test]
public void CanCheckRankOfSquareSingular([Values(10, 50, 100)] int order)
{
var matrixA = new DenseMatrix(order, order);
matrixA[0, 0] = 1;
matrixA[order - 1, order - 1] = 1;
var A = new DenseMatrix(order, order);
A[0, 0] = 1;
A[order - 1, order - 1] = 1;
for (var i = 1; i < order - 1; i++)
{
matrixA[i, i - 1] = 1;
matrixA[i, i + 1] = 1;
matrixA[i - 1, i] = 1;
matrixA[i + 1, i] = 1;
A[i, i - 1] = 1;
A[i, i + 1] = 1;
A[i - 1, i] = 1;
A[i + 1, i] = 1;
}
var factorEvd = matrixA.Evd();
var factorEvd = A.Evd();
Assert.AreEqual(factorEvd.Determinant, Complex32.Zero);
Assert.AreEqual(factorEvd.Rank, order - 1);
}
/// <summary>
/// Identity determinant is one.
/// </summary>
/// <param name="order">Matrix order.</param>
[TestCase(1)]
[TestCase(10)]
[TestCase(100)]
public void IdentityDeterminantIsOne(int order)
[Test]
public void IdentityDeterminantIsOne([Values(1, 10, 100)] int order)
{
var matrixI = DenseMatrix.CreateIdentity(order);
var factorEvd = matrixI.Evd();
@ -198,40 +147,26 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization
/// </summary>
/// <param name="order">Matrix order.</param>
[Test]
[TestCase(1)]
[TestCase(2)]
[TestCase(5)]
[TestCase(10)]
[TestCase(50)]
public void CanSolveForRandomVectorAndSymmetricMatrix(int order)
public void CanSolveForRandomVectorAndSymmetricMatrix([Values(1, 2, 5, 10, 50, 100)] int order)
{
var matrixA = Matrix<Complex32>.Build.RandomPositiveDefinite(order, 1);
MatrixHelpers.ForceConjugateSymmetric(matrixA);
var matrixACopy = matrixA.Clone();
var factorEvd = matrixA.Evd();
var A = Matrix<Complex32>.Build.RandomPositiveDefinite(order, 1);
MatrixHelpers.ForceConjugateSymmetric(A);
var ACopy = A.Clone();
var evd = A.Evd();
var vectorb = Vector<Complex32>.Build.Random(order, 1);
var resultx = factorEvd.Solve(vectorb);
var b = Vector<Complex32>.Build.Random(order, 2);
var bCopy = b.Clone();
Assert.AreEqual(matrixA.ColumnCount, resultx.Count);
var x = evd.Solve(b);
var matrixBReconstruct = matrixA * resultx;
var bReconstruct = A * x;
// Check the reconstruction.
for (var i = 0; i < vectorb.Count; i++)
{
Assert.AreEqual(vectorb[i].Real, matrixBReconstruct[i].Real, 1e-2f);
Assert.AreEqual(vectorb[i].Imaginary, matrixBReconstruct[i].Imaginary, 1e-2f);
}
AssertHelpers.ListAlmostEqual(b, bReconstruct, 2);
// Make sure A didn't change.
for (var i = 0; i < matrixA.RowCount; i++)
{
for (var j = 0; j < matrixA.ColumnCount; j++)
{
Assert.AreEqual(matrixACopy[i, j], matrixA[i, j]);
}
}
// Make sure A/B didn't change.
AssertHelpers.AlmostEqual(ACopy, A, 14);
AssertHelpers.ListAlmostEqual(bCopy, b, 14);
}
/// <summary>
@ -239,47 +174,32 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization
/// </summary>
/// <param name="order">Matrix order.</param>
[Test]
[TestCase(1)]
[TestCase(2)]
[TestCase(5)]
[TestCase(10)]
[TestCase(50)]
public void CanSolveForRandomMatrixAndSymmetricMatrix(int order)
public void CanSolveForRandomMatrixAndSymmetricMatrix([Values(1, 2, 5, 10, 50, 100)] int order)
{
var matrixA = Matrix<Complex32>.Build.RandomPositiveDefinite(order, 1);
MatrixHelpers.ForceConjugateSymmetric(matrixA);
var matrixACopy = matrixA.Clone();
var factorEvd = matrixA.Evd();
var A = Matrix<Complex32>.Build.RandomPositiveDefinite(order, 1);
MatrixHelpers.ForceConjugateSymmetric(A);
var ACopy = A.Clone();
var evd = A.Evd();
var B = Matrix<Complex32>.Build.Random(order, order, 2);
var BCopy = B.Clone();
var matrixB = Matrix<Complex32>.Build.Random(order, order, 1);
var matrixX = factorEvd.Solve(matrixB);
var X = evd.Solve(B);
// The solution X row dimension is equal to the column dimension of A
Assert.AreEqual(matrixA.ColumnCount, matrixX.RowCount);
Assert.AreEqual(A.ColumnCount, X.RowCount);
// The solution X has the same number of columns as B
Assert.AreEqual(matrixB.ColumnCount, matrixX.ColumnCount);
Assert.AreEqual(B.ColumnCount, X.ColumnCount);
var matrixBReconstruct = matrixA * matrixX;
var BReconstruct = A * X;
// Check the reconstruction.
for (var i = 0; i < matrixB.RowCount; i++)
{
for (var j = 0; j < matrixB.ColumnCount; j++)
{
Assert.AreEqual(matrixB[i, j].Real, matrixBReconstruct[i, j].Real, 1e-2f);
Assert.AreEqual(matrixB[i, j].Imaginary, matrixBReconstruct[i, j].Imaginary, 1e-2f);
}
}
AssertHelpers.AlmostEqual(B, BReconstruct, 1);
// Make sure A didn't change.
for (var i = 0; i < matrixA.RowCount; i++)
{
for (var j = 0; j < matrixA.ColumnCount; j++)
{
Assert.AreEqual(matrixACopy[i, j], matrixA[i, j]);
}
}
// Make sure A/B didn't change.
AssertHelpers.AlmostEqual(ACopy, A, 14);
AssertHelpers.AlmostEqual(BCopy, B, 14);
}
/// <summary>
@ -287,45 +207,27 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization
/// </summary>
/// <param name="order">Matrix order.</param>
[Test]
[TestCase(1)]
[TestCase(2)]
[TestCase(5)]
[TestCase(10)]
[TestCase(50)]
public void CanSolveForRandomVectorAndSymmetricMatrixWhenResultVectorGiven(int order)
public void CanSolveForRandomVectorAndSymmetricMatrixWhenResultVectorGiven([Values(1, 2, 5, 10, 50, 100)] int order)
{
var matrixA = Matrix<Complex32>.Build.RandomPositiveDefinite(order, 1);
MatrixHelpers.ForceConjugateSymmetric(matrixA);
var matrixACopy = matrixA.Clone();
var factorEvd = matrixA.Evd();
var vectorb = Vector<Complex32>.Build.Random(order, 1);
var vectorbCopy = vectorb.Clone();
var resultx = new DenseVector(order);
factorEvd.Solve(vectorb, resultx);
var A = Matrix<Complex32>.Build.RandomPositiveDefinite(order, 1);
MatrixHelpers.ForceConjugateSymmetric(A);
var ACopy = A.Clone();
var evd = A.Evd();
var matrixBReconstruct = matrixA * resultx;
var b = Vector<Complex32>.Build.Random(order, 2);
var bCopy = b.Clone();
// Check the reconstruction.
for (var i = 0; i < vectorb.Count; i++)
{
Assert.AreEqual(vectorb[i].Real, matrixBReconstruct[i].Real, 1e-2f);
Assert.AreEqual(vectorb[i].Imaginary, matrixBReconstruct[i].Imaginary, 1e-2f);
}
var x = new DenseVector(order);
evd.Solve(b, x);
// Make sure A didn't change.
for (var i = 0; i < matrixA.RowCount; i++)
{
for (var j = 0; j < matrixA.ColumnCount; j++)
{
Assert.AreEqual(matrixACopy[i, j], matrixA[i, j]);
}
}
var bReconstruct = A * x;
// Make sure b didn't change.
for (var i = 0; i < vectorb.Count; i++)
{
Assert.AreEqual(vectorbCopy[i], vectorb[i]);
}
// Check the reconstruction.
AssertHelpers.ListAlmostEqual(b, bReconstruct, 2);
// Make sure A/B didn't change.
AssertHelpers.AlmostEqual(ACopy, A, 14);
AssertHelpers.ListAlmostEqual(bCopy, b, 14);
}
/// <summary>
@ -333,60 +235,33 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization
/// </summary>
/// <param name="order">Matrix order.</param>
[Test]
[TestCase(1)]
[TestCase(2)]
[TestCase(5)]
[TestCase(10)]
[TestCase(50)]
[TestCase(100)]
public void CanSolveForRandomMatrixAndSymmetricMatrixWhenResultMatrixGiven(int order)
public void CanSolveForRandomMatrixAndSymmetricMatrixWhenResultMatrixGiven([Values(1, 2, 5, 10, 50, 100)] int order)
{
var matrixA = Matrix<Complex32>.Build.RandomPositiveDefinite(order, 1);
MatrixHelpers.ForceConjugateSymmetric(matrixA);
var matrixACopy = matrixA.Clone();
var factorEvd = matrixA.Evd();
var A = Matrix<Complex32>.Build.RandomPositiveDefinite(order, 1);
MatrixHelpers.ForceConjugateSymmetric(A);
var ACopy = A.Clone();
var evd = A.Evd();
var matrixB = Matrix<Complex32>.Build.Random(order, order, 1);
var matrixBCopy = matrixB.Clone();
var B = Matrix<Complex32>.Build.Random(order, order, 2);
var BCopy = B.Clone();
var matrixX = new DenseMatrix(order, order);
factorEvd.Solve(matrixB, matrixX);
var X = new DenseMatrix(order, order);
evd.Solve(B, X);
// The solution X row dimension is equal to the column dimension of A
Assert.AreEqual(matrixA.ColumnCount, matrixX.RowCount);
Assert.AreEqual(A.ColumnCount, X.RowCount);
// The solution X has the same number of columns as B
Assert.AreEqual(matrixB.ColumnCount, matrixX.ColumnCount);
Assert.AreEqual(B.ColumnCount, X.ColumnCount);
var matrixBReconstruct = matrixA * matrixX;
var BReconstruct = A * X;
// Check the reconstruction.
for (var i = 0; i < matrixB.RowCount; i++)
{
for (var j = 0; j < matrixB.ColumnCount; j++)
{
Assert.AreEqual(matrixB[i, j].Real, matrixBReconstruct[i, j].Real, 1e-1f);
Assert.AreEqual(matrixB[i, j].Imaginary, matrixBReconstruct[i, j].Imaginary, 1e-1f);
}
}
// Make sure A didn't change.
for (var i = 0; i < matrixA.RowCount; i++)
{
for (var j = 0; j < matrixA.ColumnCount; j++)
{
Assert.AreEqual(matrixACopy[i, j], matrixA[i, j]);
}
}
AssertHelpers.AlmostEqual(B, BReconstruct, 1);
// Make sure B didn't change.
for (var i = 0; i < matrixB.RowCount; i++)
{
for (var j = 0; j < matrixB.ColumnCount; j++)
{
Assert.AreEqual(matrixBCopy[i, j], matrixB[i, j]);
}
}
// Make sure A/B didn't change.
AssertHelpers.AlmostEqual(ACopy, A, 14);
AssertHelpers.AlmostEqual(BCopy, B, 14);
}
}
}

185
src/UnitTests/LinearAlgebraTests/Complex32/Factorization/UserEvdTests.cs

@ -197,181 +197,122 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex32.Factorization
/// Can solve a system of linear equations for a random vector and symmetric matrix (Ax=b).
/// </summary>
/// <param name="order">Matrix order.</param>
[Test, Ignore]
[Test]
public void CanSolveForRandomVectorAndSymmetricMatrix([Values(1, 2, 5, 10, 50, 100)] int order)
{
var matrixA = new UserDefinedMatrix(Matrix<Complex32>.Build.RandomPositiveDefinite(order, 1).ToArray());
var matrixACopy = matrixA.Clone();
var factorEvd = matrixA.Evd();
var A = new UserDefinedMatrix(Matrix<Complex32>.Build.RandomPositiveDefinite(order, 1).ToArray());
MatrixHelpers.ForceConjugateSymmetric(A);
var ACopy = A.Clone();
var evd = A.Evd();
var vectorb = new UserDefinedVector(Vector<Complex32>.Build.Random(order, 1).ToArray());
var resultx = factorEvd.Solve(vectorb);
var b = new UserDefinedVector(Vector<Complex32>.Build.Random(order, 1).ToArray());
var bCopy = b.Clone();
Assert.AreEqual(matrixA.ColumnCount, resultx.Count);
var x = evd.Solve(b);
var matrixBReconstruct = matrixA * resultx;
var bReconstruct = A * x;
// Check the reconstruction.
for (var i = 0; i < vectorb.Count; i++)
{
Assert.AreEqual(vectorb[i].Real, matrixBReconstruct[i].Real, 1e-3f);
Assert.AreEqual(vectorb[i].Imaginary, matrixBReconstruct[i].Imaginary, 1e-3f);
}
AssertHelpers.AlmostEqual(b, bReconstruct, 2);
// Make sure A didn't change.
for (var i = 0; i < matrixA.RowCount; i++)
{
for (var j = 0; j < matrixA.ColumnCount; j++)
{
Assert.AreEqual(matrixACopy[i, j], matrixA[i, j]);
}
}
// Make sure A/B didn't change.
AssertHelpers.AlmostEqual(ACopy, A, 14);
AssertHelpers.AlmostEqual(bCopy, b, 14);
}
/// <summary>
/// Can solve a system of linear equations for a random matrix and symmetric matrix (AX=B).
/// </summary>
/// <param name="order">Matrix order.</param>
[TestCase(1)]
[TestCase(2)]
[TestCase(5)]
[TestCase(10)]
[TestCase(50)]
[TestCase(100)]
public void CanSolveForRandomMatrixAndSymmetricMatrix(int order)
[Test]
public void CanSolveForRandomMatrixAndSymmetricMatrix([Values(1, 2, 5, 10, 50, 100)] int order)
{
var matrixA = new UserDefinedMatrix(Matrix<Complex32>.Build.RandomPositiveDefinite(order, 1).ToArray());
var matrixACopy = matrixA.Clone();
var factorEvd = matrixA.Evd();
var A = new UserDefinedMatrix(Matrix<Complex32>.Build.RandomPositiveDefinite(order, 1).ToArray());
MatrixHelpers.ForceConjugateSymmetric(A);
var ACopy = A.Clone();
var evd = A.Evd();
var B = new UserDefinedMatrix(Matrix<Complex32>.Build.Random(order, order, 1).ToArray());
var BCopy = B.Clone();
var matrixB = new UserDefinedMatrix(Matrix<Complex32>.Build.Random(order, order, 1).ToArray());
var matrixX = factorEvd.Solve(matrixB);
var X = evd.Solve(B);
// The solution X row dimension is equal to the column dimension of A
Assert.AreEqual(matrixA.ColumnCount, matrixX.RowCount);
Assert.AreEqual(A.ColumnCount, X.RowCount);
// The solution X has the same number of columns as B
Assert.AreEqual(matrixB.ColumnCount, matrixX.ColumnCount);
Assert.AreEqual(B.ColumnCount, X.ColumnCount);
var matrixBReconstruct = matrixA * matrixX;
var BReconstruct = A * X;
// Check the reconstruction.
for (var i = 0; i < matrixB.RowCount; i++)
{
for (var j = 0; j < matrixB.ColumnCount; j++)
{
Assert.AreEqual(matrixB[i, j].Real, matrixBReconstruct[i, j].Real, 1e-1f);
Assert.AreEqual(matrixB[i, j].Imaginary, matrixBReconstruct[i, j].Imaginary, 1e-1f);
}
}
AssertHelpers.AlmostEqual(B, BReconstruct, 1);
// Make sure A didn't change.
for (var i = 0; i < matrixA.RowCount; i++)
{
for (var j = 0; j < matrixA.ColumnCount; j++)
{
Assert.AreEqual(matrixACopy[i, j], matrixA[i, j]);
}
}
// Make sure A/B didn't change.
AssertHelpers.AlmostEqual(ACopy, A, 14);
AssertHelpers.AlmostEqual(BCopy, B, 14);
}
/// <summary>
/// Can solve a system of linear equations for a random vector and symmetric matrix (Ax=b) into a result matrix.
/// </summary>
/// <param name="order">Matrix order.</param>
[Test, Ignore]
[Test]
public void CanSolveForRandomVectorAndSymmetricMatrixWhenResultVectorGiven([Values(1, 2, 5, 10, 50, 100)] int order)
{
var matrixA = new UserDefinedMatrix(Matrix<Complex32>.Build.RandomPositiveDefinite(order, 1).ToArray());
var matrixACopy = matrixA.Clone();
var factorEvd = matrixA.Evd();
var vectorb = new UserDefinedVector(Vector<Complex32>.Build.Random(order, 1).ToArray());
var vectorbCopy = vectorb.Clone();
var resultx = new UserDefinedVector(order);
factorEvd.Solve(vectorb, resultx);
var A = new UserDefinedMatrix(Matrix<Complex32>.Build.RandomPositiveDefinite(order, 1).ToArray());
MatrixHelpers.ForceConjugateSymmetric(A);
var ACopy = A.Clone();
var evd = A.Evd();
var matrixBReconstruct = matrixA * resultx;
var b = new UserDefinedVector(Vector<Complex32>.Build.Random(order, 1).ToArray());
var bCopy = b.Clone();
// Check the reconstruction.
for (var i = 0; i < vectorb.Count; i++)
{
Assert.AreEqual(vectorb[i].Real, matrixBReconstruct[i].Real, 1e-3f);
Assert.AreEqual(vectorb[i].Imaginary, matrixBReconstruct[i].Imaginary, 1e-3f);
}
var x = new UserDefinedVector(order);
evd.Solve(b, x);
// Make sure A didn't change.
for (var i = 0; i < matrixA.RowCount; i++)
{
for (var j = 0; j < matrixA.ColumnCount; j++)
{
Assert.AreEqual(matrixACopy[i, j], matrixA[i, j]);
}
}
var bReconstruct = A * x;
// Make sure b didn't change.
for (var i = 0; i < vectorb.Count; i++)
{
Assert.AreEqual(vectorbCopy[i], vectorb[i]);
}
// Check the reconstruction.
AssertHelpers.AlmostEqual(b, bReconstruct, 2);
// Make sure A/B didn't change.
AssertHelpers.AlmostEqual(ACopy, A, 14);
AssertHelpers.AlmostEqual(bCopy, b, 14);
}
/// <summary>
/// Can solve a system of linear equations for a random matrix and symmetric matrix (AX=B) into result matrix.
/// </summary>
/// <param name="order">Matrix order.</param>
[TestCase(1)]
[TestCase(2)]
[TestCase(5)]
[TestCase(10)]
[TestCase(50)]
[TestCase(100)]
public void CanSolveForRandomMatrixAndSymmetricMatrixWhenResultMatrixGiven(int order)
[Test]
public void CanSolveForRandomMatrixAndSymmetricMatrixWhenResultMatrixGiven([Values(1, 2, 5, 10, 50, 100)] int order)
{
var matrixA = new UserDefinedMatrix(Matrix<Complex32>.Build.RandomPositiveDefinite(order, 1).ToArray());
var matrixACopy = matrixA.Clone();
var factorEvd = matrixA.Evd();
var A = new UserDefinedMatrix(Matrix<Complex32>.Build.RandomPositiveDefinite(order, 1).ToArray());
MatrixHelpers.ForceConjugateSymmetric(A);
var ACopy = A.Clone();
var evd = A.Evd();
var matrixB = new UserDefinedMatrix(Matrix<Complex32>.Build.Random(order, order, 1).ToArray());
var matrixBCopy = matrixB.Clone();
var B = new UserDefinedMatrix(Matrix<Complex32>.Build.Random(order, order, 1).ToArray());
var BCopy = B.Clone();
var matrixX = new UserDefinedMatrix(order, order);
factorEvd.Solve(matrixB, matrixX);
var X = new UserDefinedMatrix(order, order);
evd.Solve(B, X);
// The solution X row dimension is equal to the column dimension of A
Assert.AreEqual(matrixA.ColumnCount, matrixX.RowCount);
Assert.AreEqual(A.ColumnCount, X.RowCount);
// The solution X has the same number of columns as B
Assert.AreEqual(matrixB.ColumnCount, matrixX.ColumnCount);
Assert.AreEqual(B.ColumnCount, X.ColumnCount);
var matrixBReconstruct = matrixA * matrixX;
var BReconstruct = A * X;
// Check the reconstruction.
for (var i = 0; i < matrixB.RowCount; i++)
{
for (var j = 0; j < matrixB.ColumnCount; j++)
{
Assert.AreEqual(matrixB[i, j].Real, matrixBReconstruct[i, j].Real, 1e-1f);
Assert.AreEqual(matrixB[i, j].Imaginary, matrixBReconstruct[i, j].Imaginary, 1e-1f);
}
}
AssertHelpers.AlmostEqual(B, BReconstruct, 1);
// Make sure A didn't change.
for (var i = 0; i < matrixA.RowCount; i++)
{
for (var j = 0; j < matrixA.ColumnCount; j++)
{
Assert.AreEqual(matrixACopy[i, j], matrixA[i, j]);
}
}
// Make sure B didn't change.
for (var i = 0; i < matrixB.RowCount; i++)
{
for (var j = 0; j < matrixB.ColumnCount; j++)
{
Assert.AreEqual(matrixBCopy[i, j], matrixB[i, j]);
}
}
// Make sure A/B didn't change.
AssertHelpers.AlmostEqual(ACopy, A, 14);
AssertHelpers.AlmostEqual(BCopy, B, 14);
}
}
}

373
src/UnitTests/LinearAlgebraTests/Double/Factorization/EvdTests.cs

@ -3,7 +3,9 @@
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
// Copyright (c) 2009-2010 Math.NET
//
// Copyright (c) 2009-2014 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
@ -12,8 +14,10 @@
// 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
@ -42,26 +46,19 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization
[TestFixture, Category("LAFactorization")]
public class EvdTests
{
/// <summary>
/// Can factorize identity matrix.
/// </summary>
/// <param name="order">Matrix order.</param>
[TestCase(1)]
[TestCase(10)]
[TestCase(100)]
public void CanFactorizeIdentity(int order)
[Test]
public void CanFactorizeIdentityMatrix([Values(1, 10, 100)] int order)
{
var matrixI = Matrix<double>.Build.DenseIdentity(order);
var factorEvd = matrixI.Evd();
var matrix = Matrix<double>.Build.DenseIdentity(order);
var factorEvd = matrix.Evd();
var eigenValues = factorEvd.EigenValues;
var eigenVectors = factorEvd.EigenVectors;
var d = factorEvd.D;
Assert.AreEqual(matrixI.RowCount, eigenVectors.RowCount);
Assert.AreEqual(matrixI.RowCount, eigenVectors.ColumnCount);
Assert.AreEqual(matrixI.ColumnCount, d.RowCount);
Assert.AreEqual(matrixI.ColumnCount, d.ColumnCount);
Assert.AreEqual(matrix.RowCount, eigenVectors.RowCount);
Assert.AreEqual(matrix.RowCount, eigenVectors.ColumnCount);
Assert.AreEqual(matrix.ColumnCount, d.RowCount);
Assert.AreEqual(matrix.ColumnCount, d.ColumnCount);
for (var i = 0; i < eigenValues.Count; i++)
{
@ -69,127 +66,75 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization
}
}
/// <summary>
/// Can factorize a random square matrix.
/// </summary>
/// <param name="order">Matrix order.</param>
[TestCase(1)]
[TestCase(2)]
[TestCase(5)]
[TestCase(10)]
[TestCase(50)]
[TestCase(100)]
public void CanFactorizeRandomMatrix(int order)
[Test]
public void CanFactorizeRandomSquareMatrix([Values(1, 2, 5, 10, 50, 100)] int order)
{
var matrixA = Matrix<double>.Build.Random(order, order, 1);
var factorEvd = matrixA.Evd();
var eigenVectors = factorEvd.EigenVectors;
var d = factorEvd.D;
Assert.AreEqual(order, eigenVectors.RowCount);
Assert.AreEqual(order, eigenVectors.ColumnCount);
Assert.AreEqual(order, d.RowCount);
Assert.AreEqual(order, d.ColumnCount);
// Make sure the A*V = λ*V
var matrixAv = matrixA * eigenVectors;
var matrixLv = eigenVectors * factorEvd.D;
for (var i = 0; i < matrixAv.RowCount; i++)
{
for (var j = 0; j < matrixAv.ColumnCount; j++)
{
Assert.AreEqual(matrixAv[i, j], matrixLv[i, j], 1.0e-10);
}
}
var A = Matrix<double>.Build.Random(order, order, 1);
var factorEvd = A.Evd();
var V = factorEvd.EigenVectors;
var λ = factorEvd.D;
Assert.AreEqual(order, V.RowCount);
Assert.AreEqual(order, V.ColumnCount);
Assert.AreEqual(order, λ.RowCount);
Assert.AreEqual(order, λ.ColumnCount);
// Verify A*V = λ*V
var Av = A * V;
var Lv = V * λ;
AssertHelpers.AlmostEqual(Av, Lv, 10);
AssertHelpers.AlmostEqualRelative(Av, Lv, 8);
}
/// <summary>
/// Can factorize a symmetric random square matrix.
/// </summary>
/// <param name="order">Matrix order.</param>
[TestCase(1)]
[TestCase(2)]
[TestCase(5)]
[TestCase(10)]
[TestCase(50)]
[TestCase(100)]
public void CanFactorizeRandomSymmetricMatrix(int order)
[Test]
public void CanFactorizeRandomSymmetricMatrix([Values(1, 2, 5, 10, 50, 100)] int order)
{
var matrixA = Matrix<double>.Build.RandomPositiveDefinite(order, 1);
MatrixHelpers.ForceSymmetric(matrixA);
var factorEvd = matrixA.Evd();
var eigenVectors = factorEvd.EigenVectors;
var d = factorEvd.D;
var A = Matrix<double>.Build.RandomPositiveDefinite(order, 1);
MatrixHelpers.ForceSymmetric(A);
var factorEvd = A.Evd();
var V = factorEvd.EigenVectors;
var λ = factorEvd.D;
Assert.AreEqual(order, eigenVectors.RowCount);
Assert.AreEqual(order, eigenVectors.ColumnCount);
Assert.AreEqual(order, d.RowCount);
Assert.AreEqual(order, d.ColumnCount);
// Make sure the A = V*λ*VT
var matrix = eigenVectors * d * eigenVectors.Transpose();
for (var i = 0; i < matrix.RowCount; i++)
{
for (var j = 0; j < matrix.ColumnCount; j++)
{
Assert.AreEqual(matrix[i, j], matrixA[i, j], 1.0e-10);
}
}
Assert.AreEqual(order, V.RowCount);
Assert.AreEqual(order, V.ColumnCount);
Assert.AreEqual(order, λ.RowCount);
Assert.AreEqual(order, λ.ColumnCount);
// Verify A = V*λ*VT
var matrix = V * λ * V.Transpose();
AssertHelpers.AlmostEqual(matrix, A, 10);
AssertHelpers.AlmostEqualRelative(matrix, A, 10);
}
/// <summary>
/// Can check rank of square matrix.
/// </summary>
/// <param name="order">Matrix order.</param>
[TestCase(10)]
[TestCase(50)]
[TestCase(100)]
public void CanCheckRankSquare(int order)
[Test]
public void CanCheckRankSquare([Values(10, 50, 100)] int order)
{
var matrixA = Matrix<double>.Build.Random(order, order, 1);
var factorEvd = matrixA.Evd();
Assert.AreEqual(factorEvd.Rank, order);
var A = Matrix<double>.Build.Random(order, order, 1);
Assert.AreEqual(A.Evd().Rank, order);
}
/// <summary>
/// Can check rank of square singular matrix.
/// </summary>
/// <param name="order">Matrix order.</param>
[TestCase(10)]
[TestCase(50)]
[TestCase(100)]
public void CanCheckRankOfSquareSingular(int order)
[Test]
public void CanCheckRankOfSquareSingular([Values(10, 50, 100)] int order)
{
var matrixA = new DenseMatrix(order, order);
matrixA[0, 0] = 1;
matrixA[order - 1, order - 1] = 1;
var A = new DenseMatrix(order, order);
A[0, 0] = 1;
A[order - 1, order - 1] = 1;
for (var i = 1; i < order - 1; i++)
{
matrixA[i, i - 1] = 1;
matrixA[i, i + 1] = 1;
matrixA[i - 1, i] = 1;
matrixA[i + 1, i] = 1;
A[i, i - 1] = 1;
A[i, i + 1] = 1;
A[i - 1, i] = 1;
A[i + 1, i] = 1;
}
var factorEvd = matrixA.Evd();
var factorEvd = A.Evd();
Assert.AreEqual(factorEvd.Determinant, 0);
Assert.AreEqual(factorEvd.Rank, order - 1);
}
/// <summary>
/// Identity determinant is one.
/// </summary>
/// <param name="order">Matrix order.</param>
[TestCase(1)]
[TestCase(10)]
[TestCase(100)]
public void IdentityDeterminantIsOne(int order)
[Test]
public void IdentityDeterminantIsOne([Values(1, 10, 100)] int order)
{
var matrixI = Matrix<double>.Build.DenseIdentity(order);
var factorEvd = matrixI.Evd();
@ -201,40 +146,26 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization
/// </summary>
/// <param name="order">Matrix order.</param>
[Test]
[TestCase(1)]
[TestCase(2)]
[TestCase(5)]
[TestCase(10)]
[TestCase(50)]
[TestCase(100)]
public void CanSolveForRandomVectorAndSymmetricMatrix(int order)
public void CanSolveForRandomVectorAndSymmetricMatrix([Values(1, 2, 5, 10, 50, 100)] int order)
{
var matrixA = Matrix<double>.Build.RandomPositiveDefinite(order, 1);
MatrixHelpers.ForceSymmetric(matrixA);
var matrixACopy = matrixA.Clone();
var factorEvd = matrixA.Evd();
var A = Matrix<double>.Build.RandomPositiveDefinite(order, 1);
MatrixHelpers.ForceSymmetric(A);
var ACopy = A.Clone();
var evd = A.Evd();
var vectorb = Vector<double>.Build.Random(order, 1);
var resultx = factorEvd.Solve(vectorb);
var b = Vector<double>.Build.Random(order, 2);
var bCopy = b.Clone();
Assert.AreEqual(matrixA.ColumnCount, resultx.Count);
var x = evd.Solve(b);
var matrixBReconstruct = matrixA * resultx;
var bReconstruct = A * x;
// Check the reconstruction.
for (var i = 0; i < vectorb.Count; i++)
{
Assert.AreEqual(vectorb[i], matrixBReconstruct[i], 1e-9);
}
AssertHelpers.ListAlmostEqual(b, bReconstruct, 9);
// Make sure A didn't change.
for (var i = 0; i < matrixA.RowCount; i++)
{
for (var j = 0; j < matrixA.ColumnCount; j++)
{
Assert.AreEqual(matrixACopy[i, j], matrixA[i, j]);
}
}
// Make sure A/B didn't change.
AssertHelpers.AlmostEqual(ACopy, A, 14);
AssertHelpers.ListAlmostEqual(bCopy, b, 14);
}
//private
@ -243,48 +174,32 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization
/// </summary>
/// <param name="order">Matrix order.</param>
[Test]
[TestCase(1)]
[TestCase(2)]
[TestCase(5)]
[TestCase(10)]
[TestCase(50)]
[TestCase(100)]
public void CanSolveForRandomMatrixAndSymmetricMatrix(int order)
public void CanSolveForRandomMatrixAndSymmetricMatrix([Values(1, 2, 5, 10, 50, 100)] int order)
{
var matrixA = Matrix<double>.Build.RandomPositiveDefinite(order, 1);
MatrixHelpers.ForceSymmetric(matrixA);
var matrixACopy = matrixA.Clone();
var factorEvd = matrixA.Evd();
var A = Matrix<double>.Build.RandomPositiveDefinite(order, 1);
MatrixHelpers.ForceSymmetric(A);
var ACopy = A.Clone();
var evd = A.Evd();
var matrixB = Matrix<double>.Build.Random(order, order, 1);
var B = Matrix<double>.Build.Random(order, order, 2);
var BCopy = B.Clone();
var matrixX = factorEvd.Solve(matrixB);
var X = evd.Solve(B);
// The solution X row dimension is equal to the column dimension of A
Assert.AreEqual(matrixA.ColumnCount, matrixX.RowCount);
Assert.AreEqual(A.ColumnCount, X.RowCount);
// The solution X has the same number of columns as B
Assert.AreEqual(matrixB.ColumnCount, matrixX.ColumnCount);
Assert.AreEqual(B.ColumnCount, X.ColumnCount);
var matrixBReconstruct = matrixA * matrixX;
var BReconstruct = A * X;
// Check the reconstruction.
for (var i = 0; i < matrixB.RowCount; i++)
{
for (var j = 0; j < matrixB.ColumnCount; j++)
{
Assert.AreEqual(matrixB[i, j], matrixBReconstruct[i, j], 1e-9);
}
}
AssertHelpers.AlmostEqual(B, BReconstruct, 9);
// Make sure A didn't change.
for (var i = 0; i < matrixA.RowCount; i++)
{
for (var j = 0; j < matrixA.ColumnCount; j++)
{
Assert.AreEqual(matrixACopy[i, j], matrixA[i, j]);
}
}
// Make sure A/B didn't change.
AssertHelpers.AlmostEqual(ACopy, A, 14);
AssertHelpers.AlmostEqual(BCopy, B, 14);
}
/// <summary>
@ -292,45 +207,27 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization
/// </summary>
/// <param name="order">Matrix order.</param>
[Test]
[TestCase(1)]
[TestCase(2)]
[TestCase(5)]
[TestCase(10)]
[TestCase(50)]
[TestCase(100)]
public void CanSolveForRandomVectorAndSymmetricMatrixWhenResultVectorGiven(int order)
public void CanSolveForRandomVectorAndSymmetricMatrixWhenResultVectorGiven([Values(1, 2, 5, 10, 50, 100)] int order)
{
var matrixA = Matrix<double>.Build.RandomPositiveDefinite(order, 1);
MatrixHelpers.ForceSymmetric(matrixA);
var matrixACopy = matrixA.Clone();
var factorEvd = matrixA.Evd();
var vectorb = Vector<double>.Build.Random(order, 1);
var vectorbCopy = vectorb.Clone();
var resultx = new DenseVector(order);
factorEvd.Solve(vectorb, resultx);
var A = Matrix<double>.Build.RandomPositiveDefinite(order, 1);
MatrixHelpers.ForceSymmetric(A);
var ACopy = A.Clone();
var evd = A.Evd();
var matrixBReconstruct = matrixA * resultx;
var b = Vector<double>.Build.Random(order, 2);
var bCopy = b.Clone();
// Check the reconstruction.
for (var i = 0; i < vectorb.Count; i++)
{
Assert.AreEqual(vectorb[i], matrixBReconstruct[i], 1e-9);
}
var x = new DenseVector(order);
evd.Solve(b, x);
// Make sure A didn't change.
for (var i = 0; i < matrixA.RowCount; i++)
{
for (var j = 0; j < matrixA.ColumnCount; j++)
{
Assert.AreEqual(matrixACopy[i, j], matrixA[i, j]);
}
}
var bReconstruct = A * x;
// Make sure b didn't change.
for (var i = 0; i < vectorb.Count; i++)
{
Assert.AreEqual(vectorbCopy[i], vectorb[i]);
}
// Check the reconstruction.
AssertHelpers.ListAlmostEqual(b, bReconstruct, 9);
// Make sure A/B didn't change.
AssertHelpers.AlmostEqual(ACopy, A, 14);
AssertHelpers.ListAlmostEqual(bCopy, b, 14);
}
/// <summary>
@ -338,59 +235,33 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization
/// </summary>
/// <param name="order">Matrix order.</param>
[Test]
[TestCase(1)]
[TestCase(2)]
[TestCase(5)]
[TestCase(10)]
[TestCase(50)]
[TestCase(100)]
public void CanSolveForRandomMatrixAndSymmetricMatrixWhenResultMatrixGiven(int order)
public void CanSolveForRandomMatrixAndSymmetricMatrixWhenResultMatrixGiven([Values(1, 2, 5, 10, 50, 100)] int order)
{
var matrixA = Matrix<double>.Build.RandomPositiveDefinite(order, 1);
MatrixHelpers.ForceSymmetric(matrixA);
var matrixACopy = matrixA.Clone();
var factorEvd = matrixA.Evd();
var A = Matrix<double>.Build.RandomPositiveDefinite(order, 1);
MatrixHelpers.ForceSymmetric(A);
var ACopy = A.Clone();
var evd = A.Evd();
var matrixB = Matrix<double>.Build.Random(order, order, 1);
var matrixBCopy = matrixB.Clone();
var B = Matrix<double>.Build.Random(order, order, 2);
var BCopy = B.Clone();
var matrixX = new DenseMatrix(order, order);
factorEvd.Solve(matrixB, matrixX);
var X = new DenseMatrix(order, order);
evd.Solve(B, X);
// The solution X row dimension is equal to the column dimension of A
Assert.AreEqual(matrixA.ColumnCount, matrixX.RowCount);
Assert.AreEqual(A.ColumnCount, X.RowCount);
// The solution X has the same number of columns as B
Assert.AreEqual(matrixB.ColumnCount, matrixX.ColumnCount);
Assert.AreEqual(B.ColumnCount, X.ColumnCount);
var matrixBReconstruct = matrixA * matrixX;
var BReconstruct = A * X;
// Check the reconstruction.
for (var i = 0; i < matrixB.RowCount; i++)
{
for (var j = 0; j < matrixB.ColumnCount; j++)
{
Assert.AreEqual(matrixB[i, j], matrixBReconstruct[i, j], 1e-9);
}
}
// Make sure A didn't change.
for (var i = 0; i < matrixA.RowCount; i++)
{
for (var j = 0; j < matrixA.ColumnCount; j++)
{
Assert.AreEqual(matrixACopy[i, j], matrixA[i, j]);
}
}
AssertHelpers.AlmostEqual(B, BReconstruct, 9);
// Make sure B didn't change.
for (var i = 0; i < matrixB.RowCount; i++)
{
for (var j = 0; j < matrixB.ColumnCount; j++)
{
Assert.AreEqual(matrixBCopy[i, j], matrixB[i, j]);
}
}
// Make sure A/B didn't change.
AssertHelpers.AlmostEqual(ACopy, A, 14);
AssertHelpers.AlmostEqual(BCopy, B, 14);
}
}
}

195
src/UnitTests/LinearAlgebraTests/Double/Factorization/UserEvdTests.cs

@ -198,187 +198,122 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Factorization
/// Can solve a system of linear equations for a random vector and symmetric matrix (Ax=b).
/// </summary>
/// <param name="order">Matrix order.</param>
[TestCase(1)]
[TestCase(2)]
[TestCase(5)]
[TestCase(10)]
[TestCase(50)]
[TestCase(100)]
public void CanSolveForRandomVectorAndSymmetricMatrix(int order)
[Test]
public void CanSolveForRandomVectorAndSymmetricMatrix([Values(1, 2, 5, 10, 50, 100)] int order)
{
var matrixA = new UserDefinedMatrix(Matrix<double>.Build.RandomPositiveDefinite(order, 1).ToArray());
var matrixACopy = matrixA.Clone();
var factorEvd = matrixA.Evd();
var A = new UserDefinedMatrix(Matrix<double>.Build.RandomPositiveDefinite(order, 1).ToArray());
MatrixHelpers.ForceSymmetric(A);
var ACopy = A.Clone();
var evd = A.Evd();
var vectorb = new UserDefinedVector(Vector<double>.Build.Random(order, 1).ToArray());
var resultx = factorEvd.Solve(vectorb);
var b = new UserDefinedVector(Vector<double>.Build.Random(order, 1).ToArray());
var bCopy = b.Clone();
Assert.AreEqual(matrixA.ColumnCount, resultx.Count);
var x = evd.Solve(b);
var matrixBReconstruct = matrixA * resultx;
var bReconstruct = A * x;
// Check the reconstruction.
for (var i = 0; i < vectorb.Count; i++)
{
Assert.AreEqual(vectorb[i], matrixBReconstruct[i], 1e-9);
}
AssertHelpers.AlmostEqual(b, bReconstruct, 9);
// Make sure A didn't change.
for (var i = 0; i < matrixA.RowCount; i++)
{
for (var j = 0; j < matrixA.ColumnCount; j++)
{
Assert.AreEqual(matrixACopy[i, j], matrixA[i, j]);
}
}
// Make sure A/B didn't change.
AssertHelpers.AlmostEqual(ACopy, A, 14);
AssertHelpers.AlmostEqual(bCopy, b, 14);
}
/// <summary>
/// Can solve a system of linear equations for a random matrix and symmetric matrix (AX=B).
/// </summary>
/// <param name="order">Matrix order.</param>
[TestCase(1)]
[TestCase(2)]
[TestCase(5)]
[TestCase(10)]
[TestCase(50)]
[TestCase(100)]
public void CanSolveForRandomMatrixAndSymmetricMatrix(int order)
[Test]
public void CanSolveForRandomMatrixAndSymmetricMatrix([Values(1, 2, 5, 10, 50, 100)] int order)
{
var matrixA = new UserDefinedMatrix(Matrix<double>.Build.RandomPositiveDefinite(order, 1).ToArray());
var matrixACopy = matrixA.Clone();
var factorEvd = matrixA.Evd();
var A = new UserDefinedMatrix(Matrix<double>.Build.RandomPositiveDefinite(order, 1).ToArray());
MatrixHelpers.ForceSymmetric(A);
var ACopy = A.Clone();
var evd = A.Evd();
var B = new UserDefinedMatrix(Matrix<double>.Build.Random(order, order, 1).ToArray());
var BCopy = B.Clone();
var matrixB = new UserDefinedMatrix(Matrix<double>.Build.Random(order, order, 1).ToArray());
var matrixX = factorEvd.Solve(matrixB);
var X = evd.Solve(B);
// The solution X row dimension is equal to the column dimension of A
Assert.AreEqual(matrixA.ColumnCount, matrixX.RowCount);
Assert.AreEqual(A.ColumnCount, X.RowCount);
// The solution X has the same number of columns as B
Assert.AreEqual(matrixB.ColumnCount, matrixX.ColumnCount);
Assert.AreEqual(B.ColumnCount, X.ColumnCount);
var matrixBReconstruct = matrixA * matrixX;
var BReconstruct = A * X;
// Check the reconstruction.
for (var i = 0; i < matrixB.RowCount; i++)
{
for (var j = 0; j < matrixB.ColumnCount; j++)
{
Assert.AreEqual(matrixB[i, j], matrixBReconstruct[i, j], 1e-9);
}
}
AssertHelpers.AlmostEqual(B, BReconstruct, 8);
// Make sure A didn't change.
for (var i = 0; i < matrixA.RowCount; i++)
{
for (var j = 0; j < matrixA.ColumnCount; j++)
{
Assert.AreEqual(matrixACopy[i, j], matrixA[i, j]);
}
}
// Make sure A/B didn't change.
AssertHelpers.AlmostEqual(ACopy, A, 14);
AssertHelpers.AlmostEqual(BCopy, B, 14);
}
/// <summary>
/// Can solve a system of linear equations for a random vector and symmetric matrix (Ax=b) into a result matrix.
/// </summary>
/// <param name="order">Matrix order.</param>
[TestCase(1)]
[TestCase(2)]
[TestCase(5)]
[TestCase(10)]
[TestCase(50)]
[TestCase(100)]
public void CanSolveForRandomVectorAndSymmetricMatrixWhenResultVectorGiven(int order)
[Test]
public void CanSolveForRandomVectorAndSymmetricMatrixWhenResultVectorGiven([Values(1, 2, 5, 10, 50, 100)] int order)
{
var matrixA = new UserDefinedMatrix(Matrix<double>.Build.RandomPositiveDefinite(order, 1).ToArray());
var matrixACopy = matrixA.Clone();
var factorEvd = matrixA.Evd();
var vectorb = new UserDefinedVector(Vector<double>.Build.Random(order, 1).ToArray());
var vectorbCopy = vectorb.Clone();
var resultx = new UserDefinedVector(order);
factorEvd.Solve(vectorb, resultx);
var A = new UserDefinedMatrix(Matrix<double>.Build.RandomPositiveDefinite(order, 1).ToArray());
MatrixHelpers.ForceSymmetric(A);
var ACopy = A.Clone();
var evd = A.Evd();
var matrixBReconstruct = matrixA * resultx;
var b = new UserDefinedVector(Vector<double>.Build.Random(order, 1).ToArray());
var bCopy = b.Clone();
// Check the reconstruction.
for (var i = 0; i < vectorb.Count; i++)
{
Assert.AreEqual(vectorb[i], matrixBReconstruct[i], 1e-9);
}
var x = new UserDefinedVector(order);
evd.Solve(b, x);
// Make sure A didn't change.
for (var i = 0; i < matrixA.RowCount; i++)
{
for (var j = 0; j < matrixA.ColumnCount; j++)
{
Assert.AreEqual(matrixACopy[i, j], matrixA[i, j]);
}
}
var bReconstruct = A * x;
// Make sure b didn't change.
for (var i = 0; i < vectorb.Count; i++)
{
Assert.AreEqual(vectorbCopy[i], vectorb[i]);
}
// Check the reconstruction.
AssertHelpers.AlmostEqual(b, bReconstruct, 9);
// Make sure A/B didn't change.
AssertHelpers.AlmostEqual(ACopy, A, 14);
AssertHelpers.AlmostEqual(bCopy, b, 14);
}
/// <summary>
/// Can solve a system of linear equations for a random matrix and symmetric matrix (AX=B) into result matrix.
/// </summary>
/// <param name="order">Matrix order.</param>
[TestCase(1)]
[TestCase(2)]
[TestCase(5)]
[TestCase(10)]
[TestCase(50)]
[TestCase(100)]
public void CanSolveForRandomMatrixAndSymmetricMatrixWhenResultMatrixGiven(int order)
[Test]
public void CanSolveForRandomMatrixAndSymmetricMatrixWhenResultMatrixGiven([Values(1, 2, 5, 10, 50, 100)] int order)
{
var matrixA = new UserDefinedMatrix(Matrix<double>.Build.RandomPositiveDefinite(order, 1).ToArray());
var matrixACopy = matrixA.Clone();
var factorEvd = matrixA.Evd();
var A = new UserDefinedMatrix(Matrix<double>.Build.RandomPositiveDefinite(order, 1).ToArray());
MatrixHelpers.ForceSymmetric(A);
var ACopy = A.Clone();
var evd = A.Evd();
var matrixB = new UserDefinedMatrix(Matrix<double>.Build.Random(order, order, 1).ToArray());
var matrixBCopy = matrixB.Clone();
var B = new UserDefinedMatrix(Matrix<double>.Build.Random(order, order, 1).ToArray());
var BCopy = B.Clone();
var matrixX = new UserDefinedMatrix(order, order);
factorEvd.Solve(matrixB, matrixX);
var X = new UserDefinedMatrix(order, order);
evd.Solve(B, X);
// The solution X row dimension is equal to the column dimension of A
Assert.AreEqual(matrixA.ColumnCount, matrixX.RowCount);
Assert.AreEqual(A.ColumnCount, X.RowCount);
// The solution X has the same number of columns as B
Assert.AreEqual(matrixB.ColumnCount, matrixX.ColumnCount);
Assert.AreEqual(B.ColumnCount, X.ColumnCount);
var matrixBReconstruct = matrixA * matrixX;
var BReconstruct = A * X;
// Check the reconstruction.
for (var i = 0; i < matrixB.RowCount; i++)
{
for (var j = 0; j < matrixB.ColumnCount; j++)
{
Assert.AreEqual(matrixB[i, j], matrixBReconstruct[i, j], 1e-9);
}
}
AssertHelpers.AlmostEqual(B, BReconstruct, 8);
// Make sure A didn't change.
for (var i = 0; i < matrixA.RowCount; i++)
{
for (var j = 0; j < matrixA.ColumnCount; j++)
{
Assert.AreEqual(matrixACopy[i, j], matrixA[i, j]);
}
}
// Make sure B didn't change.
for (var i = 0; i < matrixB.RowCount; i++)
{
for (var j = 0; j < matrixB.ColumnCount; j++)
{
Assert.AreEqual(matrixBCopy[i, j], matrixB[i, j]);
}
}
// Make sure A/B didn't change.
AssertHelpers.AlmostEqual(ACopy, A, 14);
AssertHelpers.AlmostEqual(BCopy, B, 14);
}
}
}

361
src/UnitTests/LinearAlgebraTests/Single/Factorization/EvdTests.cs

@ -3,7 +3,9 @@
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
// Copyright (c) 2009-2010 Math.NET
//
// Copyright (c) 2009-2014 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
@ -12,8 +14,10 @@
// 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
@ -42,26 +46,19 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization
[TestFixture, Category("LAFactorization")]
public class EvdTests
{
/// <summary>
/// Can factorize identity matrix.
/// </summary>
/// <param name="order">Matrix order.</param>
[TestCase(1)]
[TestCase(10)]
[TestCase(100)]
public void CanFactorizeIdentity(int order)
[Test]
public void CanFactorizeIdentityMatrix([Values(1, 10, 100)] int order)
{
var matrixI = DenseMatrix.CreateIdentity(order);
var factorEvd = matrixI.Evd();
var matrix = Matrix<float>.Build.DenseIdentity(order);
var factorEvd = matrix.Evd();
var eigenValues = factorEvd.EigenValues;
var eigenVectors = factorEvd.EigenVectors;
var d = factorEvd.D;
Assert.AreEqual(matrixI.RowCount, eigenVectors.RowCount);
Assert.AreEqual(matrixI.RowCount, eigenVectors.ColumnCount);
Assert.AreEqual(matrixI.ColumnCount, d.RowCount);
Assert.AreEqual(matrixI.ColumnCount, d.ColumnCount);
Assert.AreEqual(matrix.RowCount, eigenVectors.RowCount);
Assert.AreEqual(matrix.RowCount, eigenVectors.ColumnCount);
Assert.AreEqual(matrix.ColumnCount, d.RowCount);
Assert.AreEqual(matrix.ColumnCount, d.ColumnCount);
for (var i = 0; i < eigenValues.Count; i++)
{
@ -69,116 +66,73 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization
}
}
/// <summary>
/// Can factorize a random square matrix.
/// </summary>
/// <param name="order">Matrix order.</param>
[Test]
public void CanFactorizeRandomMatrix([Values(1, 2, 5, 10, 50, 100)] int order)
public void CanFactorizeRandomSquareMatrix([Values(1, 2, 5, 10, 50, 100)] int order)
{
var matrixA = Matrix<float>.Build.Random(order, order, 1);
var factorEvd = matrixA.Evd();
var eigenVectors = factorEvd.EigenVectors;
var d = factorEvd.D;
Assert.AreEqual(order, eigenVectors.RowCount);
Assert.AreEqual(order, eigenVectors.ColumnCount);
Assert.AreEqual(order, d.RowCount);
Assert.AreEqual(order, d.ColumnCount);
// Make sure the A*V = λ*V
var matrixAv = matrixA * eigenVectors;
var matrixLv = eigenVectors * d;
for (var i = 0; i < matrixAv.RowCount; i++)
{
for (var j = 0; j < matrixAv.ColumnCount; j++)
{
Assert.AreEqual(matrixAv[i, j], matrixLv[i, j], 1e-3);
}
}
var A = Matrix<float>.Build.Random(order, order, 1);
var factorEvd = A.Evd();
var V = factorEvd.EigenVectors;
var λ = factorEvd.D;
Assert.AreEqual(order, V.RowCount);
Assert.AreEqual(order, V.ColumnCount);
Assert.AreEqual(order, λ.RowCount);
Assert.AreEqual(order, λ.ColumnCount);
// Verify A*V = λ*V
var Av = A * V;
var Lv = V * λ;
AssertHelpers.AlmostEqual(Av, Lv, 4);
}
/// <summary>
/// Can factorize a symmetric random square matrix.
/// </summary>
/// <param name="order">Matrix order.</param>
[Test]
public void CanFactorizeRandomSymmetricMatrix([Values(1, 2, 5, 10, 50)] int order)
public void CanFactorizeRandomSymmetricMatrix([Values(1, 2, 5, 10, 50, 100)] int order)
{
var matrixA = Matrix<float>.Build.RandomPositiveDefinite(order, 1);
MatrixHelpers.ForceSymmetric(matrixA);
var factorEvd = matrixA.Evd();
var eigenVectors = factorEvd.EigenVectors;
var d = factorEvd.D;
Assert.AreEqual(order, eigenVectors.RowCount);
Assert.AreEqual(order, eigenVectors.ColumnCount);
Assert.AreEqual(order, d.RowCount);
Assert.AreEqual(order, d.ColumnCount);
// Make sure the A = V*λ*VT
var matrix = eigenVectors * d * eigenVectors.Transpose();
for (var i = 0; i < matrix.RowCount; i++)
{
for (var j = 0; j < matrix.ColumnCount; j++)
{
Assert.AreEqual(matrix[i, j], matrixA[i, j], 1e-3);
}
}
var A = Matrix<float>.Build.RandomPositiveDefinite(order, 1);
MatrixHelpers.ForceSymmetric(A);
var factorEvd = A.Evd();
var V = factorEvd.EigenVectors;
var λ = factorEvd.D;
Assert.AreEqual(order, V.RowCount);
Assert.AreEqual(order, V.ColumnCount);
Assert.AreEqual(order, λ.RowCount);
Assert.AreEqual(order, λ.ColumnCount);
// Verify A = V*λ*VT
var matrix = V * λ * V.Transpose();
AssertHelpers.AlmostEqual(matrix, A, 3);
AssertHelpers.AlmostEqualRelative(matrix, A, 1);
}
/// <summary>
/// Can check rank of square matrix.
/// </summary>
/// <param name="order">Matrix order.</param>
[TestCase(10)]
[TestCase(50)]
[TestCase(100)]
public void CanCheckRankSquare(int order)
[Test]
public void CanCheckRankSquare([Values(10, 50, 100)] int order)
{
var matrixA = Matrix<float>.Build.Random(order, order, 1);
var factorEvd = matrixA.Evd();
Assert.AreEqual(factorEvd.Rank, order);
var A = Matrix<float>.Build.Random(order, order, 1);
Assert.AreEqual(A.Evd().Rank, order);
}
/// <summary>
/// Can check rank of square singular matrix.
/// </summary>
/// <param name="order">Matrix order.</param>
[TestCase(10)]
[TestCase(50)]
[TestCase(100)]
public void CanCheckRankOfSquareSingular(int order)
[Test]
public void CanCheckRankOfSquareSingular([Values(10, 50, 100)] int order)
{
var matrixA = new DenseMatrix(order, order);
matrixA[0, 0] = 1;
matrixA[order - 1, order - 1] = 1;
var A = new DenseMatrix(order, order);
A[0, 0] = 1;
A[order - 1, order - 1] = 1;
for (var i = 1; i < order - 1; i++)
{
matrixA[i, i - 1] = 1;
matrixA[i, i + 1] = 1;
matrixA[i - 1, i] = 1;
matrixA[i + 1, i] = 1;
A[i, i - 1] = 1;
A[i, i + 1] = 1;
A[i - 1, i] = 1;
A[i + 1, i] = 1;
}
var factorEvd = matrixA.Evd();
var factorEvd = A.Evd();
Assert.AreEqual(factorEvd.Determinant, 0);
Assert.AreEqual(factorEvd.Rank, order - 1);
}
/// <summary>
/// Identity determinant is one.
/// </summary>
/// <param name="order">Matrix order.</param>
[TestCase(1)]
[TestCase(10)]
[TestCase(100)]
public void IdentityDeterminantIsOne(int order)
[Test]
public void IdentityDeterminantIsOne([Values(1, 10, 100)] int order)
{
var matrixI = DenseMatrix.CreateIdentity(order);
var factorEvd = matrixI.Evd();
@ -190,40 +144,26 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization
/// </summary>
/// <param name="order">Matrix order.</param>
[Test]
[TestCase(1)]
[TestCase(2)]
[TestCase(5)]
[TestCase(10)]
[TestCase(50)]
[TestCase(100)]
public void CanSolveForRandomVectorAndSymmetricMatrix(int order)
public void CanSolveForRandomVectorAndSymmetricMatrix([Values(1, 2, 5, 10, 50, 100)] int order)
{
var matrixA = Matrix<float>.Build.RandomPositiveDefinite(order, 1);
MatrixHelpers.ForceSymmetric(matrixA);
var matrixACopy = matrixA.Clone();
var factorEvd = matrixA.Evd();
var A = Matrix<float>.Build.RandomPositiveDefinite(order, 1);
MatrixHelpers.ForceSymmetric(A);
var ACopy = A.Clone();
var evd = A.Evd();
var vectorb = Vector<float>.Build.Random(order, 1);
var resultx = factorEvd.Solve(vectorb);
var b = Vector<float>.Build.Random(order, 2);
var bCopy = b.Clone();
Assert.AreEqual(matrixA.ColumnCount, resultx.Count);
var x = evd.Solve(b);
var matrixBReconstruct = matrixA * resultx;
var bReconstruct = A * x;
// Check the reconstruction.
for (var i = 0; i < vectorb.Count; i++)
{
Assert.AreEqual(vectorb[i], matrixBReconstruct[i], 1e-1);
}
AssertHelpers.ListAlmostEqual(b, bReconstruct, 0);
// Make sure A didn't change.
for (var i = 0; i < matrixA.RowCount; i++)
{
for (var j = 0; j < matrixA.ColumnCount; j++)
{
Assert.AreEqual(matrixACopy[i, j], matrixA[i, j]);
}
}
// Make sure A/B didn't change.
AssertHelpers.AlmostEqual(ACopy, A, 14);
AssertHelpers.ListAlmostEqual(bCopy, b, 14);
}
/// <summary>
@ -231,47 +171,32 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization
/// </summary>
/// <param name="order">Matrix order.</param>
[Test]
[TestCase(1)]
[TestCase(2)]
[TestCase(5)]
[TestCase(10)]
[TestCase(50)]
[TestCase(100)]
public void CanSolveForRandomMatrixAndSymmetricMatrix(int order)
public void CanSolveForRandomMatrixAndSymmetricMatrix([Values(1, 2, 5, 10, 50, 100)] int order)
{
var matrixA = Matrix<float>.Build.RandomPositiveDefinite(order, 1);
MatrixHelpers.ForceSymmetric(matrixA);
var matrixACopy = matrixA.Clone();
var factorEvd = matrixA.Evd();
var A = Matrix<float>.Build.RandomPositiveDefinite(order, 1);
MatrixHelpers.ForceSymmetric(A);
var ACopy = A.Clone();
var evd = A.Evd();
var B = Matrix<float>.Build.Random(order, order, 2);
var BCopy = B.Clone();
var matrixB = Matrix<float>.Build.Random(order, order, 1);
var matrixX = factorEvd.Solve(matrixB);
var X = evd.Solve(B);
// The solution X row dimension is equal to the column dimension of A
Assert.AreEqual(matrixA.ColumnCount, matrixX.RowCount);
Assert.AreEqual(A.ColumnCount, X.RowCount);
// The solution X has the same number of columns as B
Assert.AreEqual(matrixB.ColumnCount, matrixX.ColumnCount);
Assert.AreEqual(B.ColumnCount, X.ColumnCount);
var matrixBReconstruct = matrixA * matrixX;
var BReconstruct = A * X;
// Check the reconstruction.
for (var i = 0; i < matrixB.RowCount; i++)
{
for (var j = 0; j < matrixB.ColumnCount; j++)
{
Assert.AreEqual(matrixB[i, j], matrixBReconstruct[i, j], 1);
}
}
AssertHelpers.AlmostEqual(B, BReconstruct, 0);
// Make sure A didn't change.
for (var i = 0; i < matrixA.RowCount; i++)
{
for (var j = 0; j < matrixA.ColumnCount; j++)
{
Assert.AreEqual(matrixACopy[i, j], matrixA[i, j]);
}
}
// Make sure A/B didn't change.
AssertHelpers.AlmostEqual(ACopy, A, 14);
AssertHelpers.AlmostEqual(BCopy, B, 14);
}
/// <summary>
@ -279,45 +204,27 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization
/// </summary>
/// <param name="order">Matrix order.</param>
[Test]
[TestCase(1)]
[TestCase(2)]
[TestCase(5)]
[TestCase(10)]
[TestCase(50)]
[TestCase(100)]
public void CanSolveForRandomVectorAndSymmetricMatrixWhenResultVectorGiven(int order)
public void CanSolveForRandomVectorAndSymmetricMatrixWhenResultVectorGiven([Values(1, 2, 5, 10, 50, 100)] int order)
{
var matrixA = Matrix<float>.Build.RandomPositiveDefinite(order, 1);
MatrixHelpers.ForceSymmetric(matrixA);
var matrixACopy = matrixA.Clone();
var factorEvd = matrixA.Evd();
var vectorb = Vector<float>.Build.Random(order, 1);
var vectorbCopy = vectorb.Clone();
var resultx = new DenseVector(order);
factorEvd.Solve(vectorb, resultx);
var A = Matrix<float>.Build.RandomPositiveDefinite(order, 1);
MatrixHelpers.ForceSymmetric(A);
var ACopy = A.Clone();
var evd = A.Evd();
var matrixBReconstruct = matrixA * resultx;
var b = Vector<float>.Build.Random(order, 2);
var bCopy = b.Clone();
// Check the reconstruction.
for (var i = 0; i < vectorb.Count; i++)
{
Assert.AreEqual(vectorb[i], matrixBReconstruct[i], 1e-1);
}
var x = new DenseVector(order);
evd.Solve(b, x);
// Make sure A didn't change.
for (var i = 0; i < matrixA.RowCount; i++)
{
for (var j = 0; j < matrixA.ColumnCount; j++)
{
Assert.AreEqual(matrixACopy[i, j], matrixA[i, j]);
}
}
var bReconstruct = A * x;
// Make sure b didn't change.
for (var i = 0; i < vectorb.Count; i++)
{
Assert.AreEqual(vectorbCopy[i], vectorb[i]);
}
// Check the reconstruction.
AssertHelpers.ListAlmostEqual(b, bReconstruct, 0);
// Make sure A/B didn't change.
AssertHelpers.AlmostEqual(ACopy, A, 14);
AssertHelpers.ListAlmostEqual(bCopy, b, 14);
}
/// <summary>
@ -325,59 +232,33 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization
/// </summary>
/// <param name="order">Matrix order.</param>
[Test]
[TestCase(1)]
[TestCase(2)]
[TestCase(5)]
[TestCase(10)]
[TestCase(50)]
[TestCase(100)]
public void CanSolveForRandomMatrixAndSymmetricMatrixWhenResultMatrixGiven(int order)
public void CanSolveForRandomMatrixAndSymmetricMatrixWhenResultMatrixGiven([Values(1, 2, 5, 10, 50, 100)] int order)
{
var matrixA = Matrix<float>.Build.RandomPositiveDefinite(order, 1);
MatrixHelpers.ForceSymmetric(matrixA);
var matrixACopy = matrixA.Clone();
var factorEvd = matrixA.Evd();
var A = Matrix<float>.Build.RandomPositiveDefinite(order, 1);
MatrixHelpers.ForceSymmetric(A);
var ACopy = A.Clone();
var evd = A.Evd();
var matrixB = Matrix<float>.Build.Random(order, order, 1);
var matrixBCopy = matrixB.Clone();
var B = Matrix<float>.Build.Random(order, order, 2);
var BCopy = B.Clone();
var matrixX = new DenseMatrix(order, order);
factorEvd.Solve(matrixB, matrixX);
var X = new DenseMatrix(order, order);
evd.Solve(B, X);
// The solution X row dimension is equal to the column dimension of A
Assert.AreEqual(matrixA.ColumnCount, matrixX.RowCount);
Assert.AreEqual(A.ColumnCount, X.RowCount);
// The solution X has the same number of columns as B
Assert.AreEqual(matrixB.ColumnCount, matrixX.ColumnCount);
Assert.AreEqual(B.ColumnCount, X.ColumnCount);
var matrixBReconstruct = matrixA * matrixX;
var BReconstruct = A * X;
// Check the reconstruction.
for (var i = 0; i < matrixB.RowCount; i++)
{
for (var j = 0; j < matrixB.ColumnCount; j++)
{
Assert.AreEqual(matrixB[i, j], matrixBReconstruct[i, j], 1);
}
}
// Make sure A didn't change.
for (var i = 0; i < matrixA.RowCount; i++)
{
for (var j = 0; j < matrixA.ColumnCount; j++)
{
Assert.AreEqual(matrixACopy[i, j], matrixA[i, j]);
}
}
AssertHelpers.AlmostEqual(B, BReconstruct, 0);
// Make sure B didn't change.
for (var i = 0; i < matrixB.RowCount; i++)
{
for (var j = 0; j < matrixB.ColumnCount; j++)
{
Assert.AreEqual(matrixBCopy[i, j], matrixB[i, j]);
}
}
// Make sure A/B didn't change.
AssertHelpers.AlmostEqual(ACopy, A, 14);
AssertHelpers.AlmostEqual(BCopy, B, 14);
}
}
}

195
src/UnitTests/LinearAlgebraTests/Single/Factorization/UserEvdTests.cs

@ -193,187 +193,122 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single.Factorization
/// Can solve a system of linear equations for a random vector and symmetric matrix (Ax=b).
/// </summary>
/// <param name="order">Matrix order.</param>
[TestCase(1)]
[TestCase(2)]
[TestCase(5)]
[TestCase(10)]
[TestCase(50)]
[TestCase(100)]
public void CanSolveForRandomVectorAndSymmetricMatrix(int order)
[Test]
public void CanSolveForRandomVectorAndSymmetricMatrix([Values(1, 2, 5, 10, 50, 100)] int order)
{
var matrixA = new UserDefinedMatrix(Matrix<float>.Build.RandomPositiveDefinite(order, 1).ToArray());
var matrixACopy = matrixA.Clone();
var factorEvd = matrixA.Evd();
var A = new UserDefinedMatrix(Matrix<float>.Build.RandomPositiveDefinite(order, 1).ToArray());
MatrixHelpers.ForceSymmetric(A);
var ACopy = A.Clone();
var evd = A.Evd();
var vectorb = new UserDefinedVector(Vector<float>.Build.Random(order, 1).ToArray());
var resultx = factorEvd.Solve(vectorb);
var b = new UserDefinedVector(Vector<float>.Build.Random(order, 1).ToArray());
var bCopy = b.Clone();
Assert.AreEqual(matrixA.ColumnCount, resultx.Count);
var x = evd.Solve(b);
var matrixBReconstruct = matrixA * resultx;
var bReconstruct = A * x;
// Check the reconstruction.
for (var i = 0; i < vectorb.Count; i++)
{
Assert.AreEqual(vectorb[i], matrixBReconstruct[i], 1e-1);
}
AssertHelpers.AlmostEqual(b, bReconstruct, 0);
// Make sure A didn't change.
for (var i = 0; i < matrixA.RowCount; i++)
{
for (var j = 0; j < matrixA.ColumnCount; j++)
{
Assert.AreEqual(matrixACopy[i, j], matrixA[i, j]);
}
}
// Make sure A/B didn't change.
AssertHelpers.AlmostEqual(ACopy, A, 14);
AssertHelpers.AlmostEqual(bCopy, b, 14);
}
/// <summary>
/// Can solve a system of linear equations for a random matrix and symmetric matrix (AX=B).
/// </summary>
/// <param name="order">Matrix order.</param>
[TestCase(1)]
[TestCase(2)]
[TestCase(5)]
[TestCase(10)]
[TestCase(50)]
[TestCase(100)]
public void CanSolveForRandomMatrixAndSymmetricMatrix(int order)
[Test]
public void CanSolveForRandomMatrixAndSymmetricMatrix([Values(1, 2, 5, 10, 50, 100)] int order)
{
var matrixA = new UserDefinedMatrix(Matrix<float>.Build.RandomPositiveDefinite(order, 1).ToArray());
var matrixACopy = matrixA.Clone();
var factorEvd = matrixA.Evd();
var A = new UserDefinedMatrix(Matrix<float>.Build.RandomPositiveDefinite(order, 1).ToArray());
MatrixHelpers.ForceSymmetric(A);
var ACopy = A.Clone();
var evd = A.Evd();
var B = new UserDefinedMatrix(Matrix<float>.Build.Random(order, order, 1).ToArray());
var BCopy = B.Clone();
var matrixB = new UserDefinedMatrix(Matrix<float>.Build.Random(order, order, 1).ToArray());
var matrixX = factorEvd.Solve(matrixB);
var X = evd.Solve(B);
// The solution X row dimension is equal to the column dimension of A
Assert.AreEqual(matrixA.ColumnCount, matrixX.RowCount);
Assert.AreEqual(A.ColumnCount, X.RowCount);
// The solution X has the same number of columns as B
Assert.AreEqual(matrixB.ColumnCount, matrixX.ColumnCount);
Assert.AreEqual(B.ColumnCount, X.ColumnCount);
var matrixBReconstruct = matrixA * matrixX;
var BReconstruct = A * X;
// Check the reconstruction.
for (var i = 0; i < matrixB.RowCount; i++)
{
for (var j = 0; j < matrixB.ColumnCount; j++)
{
Assert.AreEqual(matrixB[i, j], matrixBReconstruct[i, j], 1);
}
}
AssertHelpers.AlmostEqual(B, BReconstruct, 0);
// Make sure A didn't change.
for (var i = 0; i < matrixA.RowCount; i++)
{
for (var j = 0; j < matrixA.ColumnCount; j++)
{
Assert.AreEqual(matrixACopy[i, j], matrixA[i, j]);
}
}
// Make sure A/B didn't change.
AssertHelpers.AlmostEqual(ACopy, A, 14);
AssertHelpers.AlmostEqual(BCopy, B, 14);
}
/// <summary>
/// Can solve a system of linear equations for a random vector and symmetric matrix (Ax=b) into a result matrix.
/// </summary>
/// <param name="order">Matrix order.</param>
[TestCase(1)]
[TestCase(2)]
[TestCase(5)]
[TestCase(10)]
[TestCase(50)]
[TestCase(100)]
public void CanSolveForRandomVectorAndSymmetricMatrixWhenResultVectorGiven(int order)
[Test]
public void CanSolveForRandomVectorAndSymmetricMatrixWhenResultVectorGiven([Values(1, 2, 5, 10, 50, 100)] int order)
{
var matrixA = new UserDefinedMatrix(Matrix<float>.Build.RandomPositiveDefinite(order, 1).ToArray());
var matrixACopy = matrixA.Clone();
var factorEvd = matrixA.Evd();
var vectorb = new UserDefinedVector(Vector<float>.Build.Random(order, 1).ToArray());
var vectorbCopy = vectorb.Clone();
var resultx = new UserDefinedVector(order);
factorEvd.Solve(vectorb, resultx);
var A = new UserDefinedMatrix(Matrix<float>.Build.RandomPositiveDefinite(order, 1).ToArray());
MatrixHelpers.ForceSymmetric(A);
var ACopy = A.Clone();
var evd = A.Evd();
var matrixBReconstruct = matrixA * resultx;
var b = new UserDefinedVector(Vector<float>.Build.Random(order, 1).ToArray());
var bCopy = b.Clone();
// Check the reconstruction.
for (var i = 0; i < vectorb.Count; i++)
{
Assert.AreEqual(vectorb[i], matrixBReconstruct[i], 1e-1);
}
var x = new UserDefinedVector(order);
evd.Solve(b, x);
// Make sure A didn't change.
for (var i = 0; i < matrixA.RowCount; i++)
{
for (var j = 0; j < matrixA.ColumnCount; j++)
{
Assert.AreEqual(matrixACopy[i, j], matrixA[i, j]);
}
}
var bReconstruct = A * x;
// Make sure b didn't change.
for (var i = 0; i < vectorb.Count; i++)
{
Assert.AreEqual(vectorbCopy[i], vectorb[i]);
}
// Check the reconstruction.
AssertHelpers.AlmostEqual(b, bReconstruct, 0);
// Make sure A/B didn't change.
AssertHelpers.AlmostEqual(ACopy, A, 14);
AssertHelpers.AlmostEqual(bCopy, b, 14);
}
/// <summary>
/// Can solve a system of linear equations for a random matrix and symmetric matrix (AX=B) into result matrix.
/// </summary>
/// <param name="order">Matrix order.</param>
[TestCase(1)]
[TestCase(2)]
[TestCase(5)]
[TestCase(10)]
[TestCase(50)]
[TestCase(100)]
public void CanSolveForRandomMatrixAndSymmetricMatrixWhenResultMatrixGiven(int order)
[Test]
public void CanSolveForRandomMatrixAndSymmetricMatrixWhenResultMatrixGiven([Values(1, 2, 5, 10, 50, 100)] int order)
{
var matrixA = new UserDefinedMatrix(Matrix<float>.Build.RandomPositiveDefinite(order, 1).ToArray());
var matrixACopy = matrixA.Clone();
var factorEvd = matrixA.Evd();
var A = new UserDefinedMatrix(Matrix<float>.Build.RandomPositiveDefinite(order, 1).ToArray());
MatrixHelpers.ForceSymmetric(A);
var ACopy = A.Clone();
var evd = A.Evd();
var matrixB = new UserDefinedMatrix(Matrix<float>.Build.Random(order, order, 1).ToArray());
var matrixBCopy = matrixB.Clone();
var B = new UserDefinedMatrix(Matrix<float>.Build.Random(order, order, 1).ToArray());
var BCopy = B.Clone();
var matrixX = new UserDefinedMatrix(order, order);
factorEvd.Solve(matrixB, matrixX);
var X = new UserDefinedMatrix(order, order);
evd.Solve(B, X);
// The solution X row dimension is equal to the column dimension of A
Assert.AreEqual(matrixA.ColumnCount, matrixX.RowCount);
Assert.AreEqual(A.ColumnCount, X.RowCount);
// The solution X has the same number of columns as B
Assert.AreEqual(matrixB.ColumnCount, matrixX.ColumnCount);
Assert.AreEqual(B.ColumnCount, X.ColumnCount);
var matrixBReconstruct = matrixA * matrixX;
var BReconstruct = A * X;
// Check the reconstruction.
for (var i = 0; i < matrixB.RowCount; i++)
{
for (var j = 0; j < matrixB.ColumnCount; j++)
{
Assert.AreEqual(matrixB[i, j], matrixBReconstruct[i, j], 1);
}
}
AssertHelpers.AlmostEqual(B, BReconstruct, 0);
// Make sure A didn't change.
for (var i = 0; i < matrixA.RowCount; i++)
{
for (var j = 0; j < matrixA.ColumnCount; j++)
{
Assert.AreEqual(matrixACopy[i, j], matrixA[i, j]);
}
}
// Make sure B didn't change.
for (var i = 0; i < matrixB.RowCount; i++)
{
for (var j = 0; j < matrixB.ColumnCount; j++)
{
Assert.AreEqual(matrixBCopy[i, j], matrixB[i, j]);
}
}
// Make sure A/B didn't change.
AssertHelpers.AlmostEqual(ACopy, A, 14);
AssertHelpers.AlmostEqual(BCopy, B, 14);
}
}
}

Loading…
Cancel
Save