public void KnownEigenvalues() { // This example is presented in http://people.inf.ethz.ch/arbenz/ewp/Lnotes/chapter3.pdf // It has eigenvalues 1 \pm 2i, 3, 4, 5 \pm 6i double[,] souce = new double[, ] { { 7, 3, 4, -11, -9, -2 }, { -6, 4, -5, 7, 1, 12 }, { -1, -9, 2, 2, 9, 1 }, { -8, 0, -1, 5, 0, 8 }, { -4, 3, -5, 7, 2, 10 }, { 6, 1, 4, -11, -7, -1 } }; SquareMatrix A = new SquareMatrix(6); for (int r = 0; r < souce.GetLength(0); r++) { for (int c = 0; c < souce.GetLength(1); c++) { A[r, c] = souce[r, c]; } } Complex[] eigenvalues = A.Eigenvalues(); foreach (Complex eigenvalue in eigenvalues) { Console.WriteLine(eigenvalue); } }
public void CirculantEigenvalues() { int n = 50; double[] x = new double[n]; for (int i = 0; i < x.Length; i++) { x[i] = 1.0 / (i + 1); } SquareMatrix A = CreateCirculantMatrix(x); Complex[] u = RootsOfUnity(n); Complex[] v = new Complex[n]; for (int i = 0; i < v.Length; i++) { for (int j = 0; j < n; j++) { v[i] += x[j] * u[(i * (n - j)) % n]; } } Complex[][] w = new Complex[n][]; for (int i = 0; i < n; i++) { w[i] = new Complex[n]; for (int j = 0; j < n; j++) { w[i][j] = u[i * j % n]; } } Complex[] e = A.Eigenvalues(); }
public void CirculantEigenvalues() { // See https://en.wikipedia.org/wiki/Circulant_matrix // Definition is C_{ij} = c_{|i - j|} for any n-vector c. // jth eigenvector known to be (1, \omega_j, \omega_j^2, \cdots, \omega_j^{n-1}) where \omega_j = \exp(2 \pi i j / n) are nth roots of unity // jth eigenvalue known to be c_0 + c_{n-1} \omega_j + c_{n-2} \omega_j^2 + \cdots + c_1 \omega_j^{n-1} int n = 12; double[] x = new double[n]; for (int i = 0; i < x.Length; i++) { x[i] = 1.0 / (i + 1); } SquareMatrix A = CreateCirculantMatrix(x); Complex[] u = RootsOfUnity(n); Complex[] v = new Complex[n]; for (int i = 0; i < v.Length; i++) { for (int j = 0; j < n; j++) { v[i] += x[j] * u[(i * (n - j)) % n]; } } Complex[][] w = new Complex[n][]; for (int i = 0; i < n; i++) { w[i] = new Complex[n]; for (int j = 0; j < n; j++) { w[i][j] = u[i * j % n]; } } Complex[] eValues = A.Eigenvalues(); Complex eProduct = 1.0; foreach (Complex eValue in eValues) { eProduct *= eValue; } // v and eValues should be equal. By inspection they are, // but how to verify this given floating point jitter? // Verify that eigenvalue product equals determinant. SquareQRDecomposition QR = A.QRDecomposition(); double det = QR.Determinant(); Assert.IsTrue(TestUtilities.IsNearlyEqual(eProduct, det)); }
public void CirculantEigenvalues() { int n = 12; double[] x = new double[n]; for (int i = 0; i < x.Length; i++) { x[i] = 1.0 / (i + 1); } SquareMatrix A = CreateCirculantMatrix(x); Complex[] u = RootsOfUnity(n); Complex[] v = new Complex[n]; for (int i = 0; i < v.Length; i++) { for (int j = 0; j < n; j++) { v[i] += x[j] * u[(i * (n - j)) % n]; } } Complex[][] w = new Complex[n][]; for (int i = 0; i < n; i++) { w[i] = new Complex[n]; for (int j = 0; j < n; j++) { w[i][j] = u[i * j % n]; } } Complex[] eValues = A.Eigenvalues(); Complex eProduct = 1.0; foreach (Complex eValue in eValues) { eProduct *= eValue; } // v and eValues should be equal. By inspection they are, // but how to verify this given floating point jitter? // Verify that eigenvalue product equals determinant. SquareQRDecomposition QR = A.QRDecomposition(); double det = QR.Determinant(); Assert.IsTrue(TestUtilities.IsNearlyEqual(eProduct, det)); }
public void Bug5504() { // this eigenvalue non-convergence is solved by an ad hoc shift // these "cyclic matrices" are good examples of situations that are difficult for the QR algorithm for (int d = 2; d <= 8; d++) { Console.WriteLine(d); SquareMatrix C = CyclicMatrix(d); Complex[] lambdas = C.Eigenvalues(); foreach (Complex lambda in lambdas) { Console.WriteLine("{0} ({1} {2})", lambda, ComplexMath.Abs(lambda), ComplexMath.Arg(lambda)); Assert.IsTrue(TestUtilities.IsNearlyEqual(ComplexMath.Abs(lambda), 1.0)); } } }
public void DifficultEigenvalue() { // This is from a paper describing difficult eigenvalue problems. // https://www.mathworks.com/company/newsletters/news_notes/pdf/sum95cleve.pdf SquareMatrix A = new SquareMatrix(4); A[0, 0] = 0.0; A[0, 1] = 2.0; A[0, 2] = 0.0; A[0, 3] = -1.0; A[1, 0] = 1.0; A[1, 1] = 0.0; A[1, 2] = 0.0; A[1, 3] = 0.0; A[2, 0] = 0.0; A[2, 1] = 1.0; A[2, 2] = 0.0; A[2, 3] = 0.0; A[3, 0] = 0.0; A[3, 1] = 0.0; A[3, 2] = 1.0; A[3, 3] = 0.0; Complex[] zs = A.Eigenvalues(); foreach (Complex z in zs) { Console.WriteLine("{0} ({1} {2})", z, ComplexMath.Abs(z), ComplexMath.Arg(z)); } }
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 TimedEigenvalues() { int n = 200; Random rng = new Random(1); SquareMatrix A = new SquareMatrix(n); for (int r = 0; r < n; r++) { for (int c = 0; c < n; c++) { A[r, c] = rng.NextDouble(); } } Stopwatch s = Stopwatch.StartNew(); Complex[] eigenvalues = A.Eigenvalues(); s.Stop(); Console.WriteLine(s.ElapsedMilliseconds); }