public void SquareMatrixStochasticEigensystem() { // this is a simplifed form of a Markov matrix that arose in the Monopoly problem // and failed to converge int n = 12; // originally failed for n=12 due to lack of 2x2 detection at top // now tested for n up to 40, but n=14 appears to still be a problem, // probably due to a six-times degenerate eigenvalue SquareMatrix R = new SquareMatrix(n); for (int c = 0; c < n; c++) { R[(c + 2) % n, c] = 1.0 / 36.0; R[(c + 3) % n, c] = 2.0 / 36.0; R[(c + 4) % n, c] = 3.0 / 36.0; R[(c + 5) % n, c] = 4.0 / 36.0; R[(c + 6) % n, c] = 5.0 / 36.0; R[(c + 7) % n, c] = 6.0 / 36.0; R[(c + 8) % n, c] = 5.0 / 36.0; R[(c + 9) % n, c] = 4.0 / 36.0; R[(c + 10) % n, c] = 3.0 / 36.0; R[(c + 11) % n, c] = 2.0 / 36.0; R[(c + 12) % n, c] = 1.0 / 36.0; } //Complex[] v = R.Eigenvalues(); ComplexEigendecomposition E = R.Eigendecomposition(); for (int i = 0; i < E.Dimension; i++) { Assert.IsTrue(TestUtilities.IsNearlyEigenpair(R, E.Eigenpairs[i].Eigenvector, E.Eigenpairs[i].Eigenvalue)); } }
public void CompanionMatrixEigenvalues() { SquareMatrix CM = new SquareMatrix(3); CM[0, 2] = -1.0; CM[1, 0] = 1.0; CM[1, 2] = -3.0; CM[2, 1] = 1.0; CM[2, 2] = -3.0; ComplexEigendecomposition EM = CM.Eigendecomposition(); for (int d = 2; d <= 8; d++) { Console.WriteLine(d); SquareMatrix C = new SquareMatrix(d); for (int r = 1; r < d; r++) { C[r, r - 1] = 1.0; } for (int r = 0; r < d; r++) { C[r, d - 1] = -AdvancedIntegerMath.BinomialCoefficient(d, r); } ComplexEigendecomposition e = C.Eigendecomposition(); } }
public void SquareUnitMatrixEigensystem() { int d = 3; SquareMatrix I = UnitMatrix.OfDimension(d).ToSquareMatrix(); ComplexEigendecomposition E = I.Eigendecomposition(); Assert.IsTrue(E.Dimension == d); for (int i = 0; i < d; i++) { Complex val = E.Eigenpairs[i].Eigenvalue; Assert.IsTrue(val == 1.0); ComplexColumnVector vec = E.Eigenpairs[i].Eigenvector; for (int j = 0; j < d; j++) { if (i == j) { Assert.IsTrue(vec[j] == 1.0); } else { Assert.IsTrue(vec[j] == 0.0); } } } }
public static void EigenvaluesAndEigenvectors() { SymmetricMatrix H = new SymmetricMatrix(3); for (int r = 0; r < H.Dimension; r++) { for (int c = 0; c <= r; c++) { H[r, c] = 1.0 / (r + c + 1); } } RealEigendecomposition ed = H.Eigendecomposition(); SquareMatrix V = ed.TransformMatrix; PrintMatrix("V^T V", V.Transpose * V); PrintMatrix("V D V^T", V * ed.DiagonalizedMatrix * V.Transpose); foreach (RealEigenpair pair in ed.Eigenpairs) { Console.WriteLine($"Eigenvalue {pair.Eigenvalue}"); PrintMatrix("Hv", H * pair.Eigenvector); PrintMatrix("ev", pair.Eigenvalue * pair.Eigenvector); } ed.Eigenpairs.Sort(OrderBy.MagnitudeDescending); Console.WriteLine($"Largest eigenvalue {ed.Eigenpairs[0].Eigenvalue}"); ed.Eigenpairs.Sort(OrderBy.ValueAscending); Console.WriteLine($"Least eigenvalue {ed.Eigenpairs[0].Eigenvalue}"); double[] eigenvalues = H.Eigenvalues(); double sum = 0.0; double product = 1.0; foreach (double eigenvalue in eigenvalues) { sum += eigenvalue; product *= eigenvalue; } Console.WriteLine($"sum(e) = {sum}, tr(H) = {H.Trace()}"); Console.WriteLine($"prod(e) = {product}, det(H) = {H.CholeskyDecomposition().Determinant()}"); SquareMatrix G1 = new SquareMatrix(4); G1[0, 3] = 1.0; G1[1, 2] = 1.0; G1[2, 1] = -1.0; G1[3, 0] = -1.0; ComplexEigendecomposition ced = G1.Eigendecomposition(); foreach (ComplexEigenpair pair in ced.Eigenpairs) { Console.WriteLine(pair.Eigenvalue); } }
public void DegenerateEigenvalues() { double[,] source = new double[, ] { { 1, 0, 1 }, { 0, 2, 0 }, { 1, 0, 1 } }; SquareMatrix A = new SquareMatrix(source); ComplexEigendecomposition e = A.Eigendecomposition(); foreach (ComplexEigenpair pair in e.Eigenpairs) { TestUtilities.IsNearlyEigenpair(A, pair.Eigenvector, pair.Eigenvalue); } }
public void Bug8021() { // User presented a matrix with a large number (138) of zero eigenvalues. // QR algorithm got tripped up on high degeneracy, but eigenvalues could // be revealed before QR by simple index permutation. Added code to isolate // these "cheap" eigenvalues before starting QR algorithm. int n = 276; SquareMatrix A = new SquareMatrix(n); using (System.IO.StreamReader reader = System.IO.File.OpenText(@"Bug8021.csv")) { int r = 0; while (!reader.EndOfStream) { string line = reader.ReadLine(); string[] cells = line.Split(','); for (int c = 0; c < cells.Length; c++) { string cell = cells[c]; double value = Double.Parse(cell); A[r, c] = value; } r++; } } ComplexEigendecomposition S = A.Eigendecomposition(); foreach (ComplexEigenpair pair in S.Eigenpairs) { TestUtilities.IsNearlyEigenpair(A, pair.Eigenvector, pair.Eigenvalue); } Complex[] eigenvalues = A.Eigenvalues(); double trace = A.Trace(); Complex sum = 0.0; for (int i = 0; i < eigenvalues.Length; i++) { sum += eigenvalues[i]; } TestUtilities.IsNearlyEqual(trace, sum); }
public void SquareMatrixDifficultEigensystem() { // This matrix requires > 30 iterations to converge, looses more accuracy than it should. // This example throws a NonConvergenceException without the ad hoc shift but works once the ad hoc shift is included. SquareMatrix M = new SquareMatrix(4); M[0, 1] = 2; M[0, 3] = -1; M[1, 0] = 1; M[2, 1] = 1; M[3, 2] = 1; // The eigenvalues of this matrix are -1, -1, 1, 1. // There are only two distinct eigenvectors: (1, -1, 1, -1) with eigenvalue -1, and (1, 1, 1, 1) with eigenvalue 1. ComplexEigendecomposition E = M.Eigendecomposition(); foreach (ComplexEigenpair pair in E.Eigenpairs) { Assert.IsTrue(TestUtilities.IsNearlyEigenpair(M, pair.Eigenvector, pair.Eigenvalue)); } }
public void Bug7208() { // this matrix has two eigenpairs with the same eigenvalue but distinct eigenvectors // we would report the same eigenvector for both, making the matrix of eigenvectors // non-invertible int n = 4; SquareMatrix matrix = new SquareMatrix(n + 1); double d = (3 + 2 * Math.Cos(2 * Math.PI / n)); double w = (64 * n) / (40 - d * d) - n; double w1 = w / (w + n); double w2 = 1 / (w + n); matrix[0, 0] = w1; for (int i = 1; i < n; i++) { matrix[0, i + 1] = w2; matrix[i + 1, 0] = 3.0 / 8; matrix[i + 1, i + 1] = 3.0 / 8; matrix[i, i + 1] = 1.0 / 8; matrix[i + 1, i] = 1.0 / 8; } matrix[0, 1] = w2; matrix[1, 0] = 3.0 / 8; matrix[1, 1] = 3.0 / 8; matrix[1, n] = 1.0 / 8; matrix[n, 1] = 1.0 / 8; ComplexEigendecomposition ces = matrix.Eigendecomposition(); SquareMatrix V = new SquareMatrix(n + 1); for (int i = 0; i < n + 1; i++) { for (int j = 0; j < n + 1; j++) { V[i, j] = ces.Eigenpairs[i].Eigenvector[j].Re; } } SquareMatrix inv = V.Inverse(); }
public void SquareRandomMatrixEigenvalues() { for (int d = 1; d <= 67; d = d + 11) { SquareMatrix M = CreateSquareRandomMatrix(d, d); double tr = M.Trace(); DateTime start = DateTime.Now; ComplexEigendecomposition E = M.Eigendecomposition(); DateTime finish = DateTime.Now; Console.WriteLine("d={0} t={1} ms", d, (finish - start).Milliseconds); Assert.IsTrue(E.Dimension == d); Complex[] es = new Complex[d]; for (int i = 0; i < d; i++) { es[i] = E.Eigenpairs[i].Eigenvalue; ComplexColumnVector v = E.Eigenpairs[i].Eigenvector; Assert.IsTrue(TestUtilities.IsNearlyEigenpair(M, v, es[i])); } Assert.IsTrue(TestUtilities.IsSumNearlyEqual(es, tr)); } }
public void SquareVandermondeMatrixEigenvalues() { for (int d = 1; d <= 8; d++) { SquareMatrix H = CreateVandermondeMatrix(d); double tr = H.Trace(); ComplexEigendecomposition E = H.Eigendecomposition(); double sum = 0.0; foreach (ComplexEigenpair pair in E.Eigenpairs) { double e = pair.Eigenvalue.Re; sum += e; ComplexColumnVector vc = pair.Eigenvector; ColumnVector v = new ColumnVector(d); for (int j = 0; j < d; j++) { v[j] = vc[j].Re; } Assert.IsTrue(TestUtilities.IsNearlyEigenpair(H, v, e)); } Assert.IsTrue(TestUtilities.IsNearlyEqual(tr, sum)); } }