public void TwoByTwo_NonSymetric() { string strA = @"1 2 3 4"; Matrix3 A = new Matrix3(); A.Parse(strA); Assert.That(StandardMatrixTests.IsSymetric(A), Is.False); EigenvalueDecomposition EofA = new EigenvalueDecomposition(A); Matrix3 V = EofA.V; Matrix3 D = EofA.getD(); Assert.That(StandardMatrixTests.IsDiagonal(D), Is.True); //Block Diagonal which for 2x2 is diagonal // V*D * V.Inverse = A Matrix3 test = Matrix3.Mult(D, V.Inverted()); test = Matrix3.Mult(V, test); Assert.That(test.ToFloatArray(), Is.EqualTo(A.ToFloatArray()).Within(.0000001).Percent); // A.times(V) equals V.times(D) Assert.That(Matrix3.Mult(A, V).ToFloatArray(), Is.EqualTo(Matrix3.Mult(V, D).ToFloatArray()).Within(.0000001).Percent); }
private void TestDecomposition(Matrix3 A) { EigenvalueDecomposition EofA = new EigenvalueDecomposition(A); Matrix3 V = EofA.V; Matrix3 D = EofA.getD(); if (StandardMatrixTests.IsSymetric(A)) { // V is orthogonal V times V transpose is the identity Matrix3 test = Matrix3.Mult(D, Matrix3.Transpose(V)); test = Matrix3.Mult(V, test); Assert.That(Matrix3.Mult(V, Matrix3.Transpose(V)), Is.EqualTo(Matrix3.Identity).Within(.0000001)); Assert.That(test.ToFloatArray(), Is.EqualTo(A.ToFloatArray()).Within(.0000001)); } else { Assert.That((A * V).ToFloatArray(), Is.EqualTo((V * D).ToFloatArray()).Within(.0000001)); } }
public void Random_NByN_Symetric(int n) { Rectangular rand = new Rectangular(); Matrix3 A = rand.Randomfloat(n, n); A = A.Add(Matrix3.Transpose(A)); /// Any matrix added to its transpose will be symetric Assert.That(StandardMatrixTests.IsSymetric(A), Is.True); EigenvalueDecomposition EofA = new EigenvalueDecomposition(A); Matrix3 V = EofA.V; // V is orthogonal V times V transpose is the identity Assert.That(Matrix3.Mult(V, Matrix3.Transpose(V)).ToFloatArray(), Is.EqualTo(Matrix3.Identity.ToFloatArray()).Within(.0000001)); Matrix3 D = EofA.getD(); Matrix3 test = Matrix3.Mult(D, Matrix3.Transpose(V)); test = Matrix3.Mult(V, test); Assert.That(test.ToFloatArray(), Is.EqualTo(A.ToFloatArray()).Within(.0000001).Percent); }
public void TwoByTwo_Symetric() { string strA = @"2 1 1 2"; Matrix3 A = new Matrix3(); A.Parse(strA); string strExpectedD = @"1 0 0 3"; Matrix3 ExpectedD = new Matrix3(); ExpectedD.Parse(strExpectedD); string strExpectedV = @" -0.7071 0.7071 0.7071 0.7071"; Matrix3 ExpectedV = new Matrix3(); ExpectedV.Parse(strExpectedV); //This is the value that one will get from Matlab. The eigenvalue Decomposition returns //the following 0.7071 0.7071 // -0.7071 0.7071" // (Warning Proof ahead ) //The problem stems from the fact that the Eigenvalue decomposition is not entirely unique. // The A is decomposed such that A = V * D * V'; // Consider the diagonal matrix J such that all of its diagonal values are eiher 1 or -1. J*J = I. // (V *J) * D * (V * J)' = V * J * D * J' * V' using (AB)' = B'A' The transpose of the product is the transpose of the elements reversed. // V * J * D * J' * V' = V * J * D * J * V' as J is diagonal // V * J * D * J * V' = V * J * J * D * V' as J and D are diagonal. // V * J * J * D * V' = V * D * V' since J*J = I. // (Proof finished) // In practical terms this means that Assert.That(V, Is.EqualTo(ExpectedV) ); // is not a good test. and I will need to test if it is equivalent instead. Assert.That(StandardMatrixTests.IsSymetric(A), Is.True); EigenvalueDecomposition EofA = new EigenvalueDecomposition(A); float[] realEigenValues = EofA.EV; float[] imaginaryEigenValues = EofA.EV; Matrix3 V = EofA.V; Debug.WriteLine(V.ToString()); // Assert.That(V, Is.EqualTo(ExpectedV) ); Not enough uniqueness so does not work //TestEigenvalueVEquivalent(V, ExpectedV); // V is orthogonal V times V transpose is the identity Assert.That(Matrix3.Mult(V, Matrix3.Transpose(V)).ToFloatArray(), Is.EqualTo(Matrix3.Identity.ToFloatArray()).Within(.0000001)); Matrix3 D = EofA.getD(); Assert.That(StandardMatrixTests.IsDiagonal(D), Is.True); //Diagonal which for 2x2 is diagonal Assert.That(D.ToFloatArray(), Is.EqualTo(ExpectedD.ToFloatArray()).Within(10).Ulps); //V * D * V,transpose = A Matrix3 test = Matrix3.Mult(D, Matrix3.Transpose(V)); test = Matrix3.Mult(V, test); Assert.That(test.ToFloatArray(), Is.EqualTo(A.ToFloatArray()).Within(.0000001)); }