public static void Main(string[] args) { int n = 5; //size of real symmetric matrix matrix A = new matrix(n, n); var rnd = new Random(1); for (int i = 0; i < n; i++) /* Construction of a random vector */ { for (int j = 0; j < n; j++) { A[i, j] = (rnd.NextDouble() * 10); A[j, i] = A[i, j]; /* We make sure that the matrix is symmetric */ } } A.print("Random symmetric matrix, A:"); matrix V = new matrix(n, n); vector e = new vector(n); matrix B = A.copy(); /* We make a copy of A */ int sweeps = jacobi.cyclic(A, e, V); /* We use the jacobi matlib for the implementation of the cyclic sweeps: public static int cyclic(matrix A, vector e, matrix V=null){...} */ WriteLine($"\nNumber of sweeps: {sweeps}"); matrix D = (V.T * B * V); // D.print("\nEigenvalue-decomposition, V^T*A*V (should be diagonal):"); D.printfloat("\nEigenvalue-decomposition, V^T*A*V (should be diagonal):"); /* using my print2 to get 0's instead of values with e.g. "e-16"*/ e.print("\nEigenvalues:\n"); }
static void Main() { int n = 5; //size of real symmetric matrix matrix A = new matrix(n, n); var rnd = new Random(1); for (int i = 0; i < n; i++) /* Construction of a random vector */ { for (int j = 0; j < n; j++) { A[i, j] = (rnd.NextDouble() * 10); A[j, i] = A[i, j]; /* We make sure that the matrix is symmetric */ } } A.printfloat("Random symmetric matrix, A:"); matrix V = new matrix(n, n); matrix V2 = new matrix(n, n); vector e = new vector(n); vector e2 = new vector(n); // matrix B=A.copy(); matrix B2 = A.copy(); int rotations = jacobi.classic2(A, e, V); /* We use the jacobi matlib for the implementation of the cyclic sweeps: public static int cyclic(matrix A, vector e, matrix V=null){...} */ WriteLine($"\nNumber of rotations: {rotations}"); // matrix D=(V.T*B*V); // D.printfloat("\nClassic: Eigenvalue-decomposition, V^T*A*V (should be diagonal):"); int sweeps = jacobi.cyclic(B2, e2, V2); WriteLine($"Number of sweeps: {sweeps}"); // matrix D2=(V2.T*B*V2); // D2.printfloat("\nCyclic: Eigenvalue-decomposition, V^T*A*V (should be diagonal):"); // var rnd = new Random(1); // int n = 4; // matrix v_c = new matrix(n,n); // matrix v_classic = new matrix(n,n); // vector e_classic = new vector(n); // var A_c = new matrix(n,n); // for(int i=0;i<n;i++){ // for(int j=i;j<n;j++){ // A_c[i,j]=2*(rnd.NextDouble()-0.5); // A_c[j,i]=A_c[i,j]; // } // } // matrix B=A_c.copy(); // var A_classic = A_c.copy(); // int rotations = classic(A_classic,e_classic,v_classic); // A_classic.printfloat("A classic transformed"); // // e_classic.print("Eigenvalues calculated with classic:"); // // v_classic.print("Eigenvectors calculated with classic:"); // var VTAV=v_classic.T*B*v_classic; // VTAV.printfloat("V^T*A*V:"); }
static public int classic(matrix B, vector e, matrix V = null) { /* Jacobi diagonalization. Upper triangle of A is destroyed. * e and V accumulate eigenvalues and eigenvectors */ matrix A = B.copy(); bool changed; int rotations = 0, n = A.size1; for (int i = 0; i < n; i++) { e[i] = A[i, i]; } for (int i = 0; i < n; i++) { V[i, i] = 1.0; for (int j = i + 1; j < n; j++) { V[i, j] = 0; V[j, i] = 0; } } do { rotations++; changed = false; WriteLine($"{A[0,0]} {A[0,1]} {A[0,2]} {A[0,3]} {A[0,4]}"); for (int p = 0; p < n - 1; p++) { WriteLine($"p: {p}"); int q = p + 1; double max = Abs(A[p, q]); for (int j = p + 2; j < n; j++) { WriteLine($"A0: {A[0,0]} {A[0,1]} {A[0,2]} {A[0,3]} {A[0,4]}"); if (max <= Abs(A[p, j])) { max = Abs(A[p, j]); q = j; // WriteLine($"max:({p},{q}), A[p,q]: {A[p,q]} A[1,4]: {A[1,4]}"); } } // WriteLine($"q: {q}"); double app = e[p]; double aqq = e[q]; double apq = A[p, q]; double phi = 0.5 * Atan2(2 * apq, aqq - app); double c = Cos(phi), s = Sin(phi); double app1 = c * c * app - 2 * s * c * apq + s * s * aqq; double aqq1 = s * s * app + 2 * s * c * apq + c * c * aqq; if (app1 != app || aqq1 != aqq) { changed = true; e[p] = app1; e[q] = aqq1; A[p, q] = 0.0; for (int i = 0; i < p; i++) { double aip = A[i, p]; double aiq = A[i, q]; A[i, p] = c * aip - s * aiq; A[i, q] = c * aiq + s * aip; } for (int i = p + 1; i < q; i++) { double api = A[p, i]; double aiq = A[i, q]; A[p, i] = c * api - s * aiq; A[i, q] = c * aiq + s * api; } for (int i = q + 1; i < n; i++) { double api = A[p, i]; double aqi = A[q, i]; A[p, i] = c * api - s * aqi; A[q, i] = c * aqi + s * api; } if (V != null) { for (int i = 0; i < n; i++) { double vip = V[i, p]; double viq = V[i, q]; V[i, p] = c * vip - s * viq; V[i, q] = c * viq + s * vip; } } } A.printfloat("After rotation:"); } }while(changed); return(rotations); }