public static int Main() { int dim = 30; double tau = 1e-6; double eps = 1e-6; int updates = 999; // If updates=999, no Rayleigh updates are performed int n_max = 999; var rnd = new Random(); int i = rnd.Next(dim); matrix A = misc.gen_matrix(dim); matrix Ac = A.copy(); matrix I = new matrix(A.size1, A.size1); I.set_identity(); var jacobi = new jacobi_diagonalization(A); vector e = jacobi.get_eigenvalues(); vector v_0 = misc.gen_vector(dim); // The below code monitors the error as function of iterations to investigate convergence for different deviations double e_0; double[] deviations = new double[3] { 1.01, 1.02, 1.03 }; double[] deviations2 = new double[3] { 1.05, 1.075, 1.10 }; for (int j = 0; j < deviations.Length; j++) { e_0 = e[i] * deviations[j]; power_method.generate_convergences(j, ref Ac, ref I, e_0, v_0, e[i], tau, eps, n_max, updates); } for (int j = 0; j < deviations.Length; j++) { e_0 = e[i] * deviations[j]; power_method.generate_convergences(j + deviations.Length, ref Ac, ref I, e_0, v_0, e[i], tau, eps, n_max, -1); } for (int j = 0; j < deviations2.Length; j++) { e_0 = e[i] * deviations2[j]; power_method.generate_convergences(j + 2 * deviations.Length, ref Ac, ref I, e_0, v_0, e[i], tau, eps, n_max, updates); } for (int j = 0; j < deviations2.Length; j++) { e_0 = e[i] * deviations2[j]; power_method.generate_convergences(j + 3 * deviations2.Length, ref Ac, ref I, e_0, v_0, e[i], tau, eps, n_max, -1); } return(0); }
public static Tuple <vector, matrix> box(int n) { double s = 1.0 / (n + 1); matrix H = new matrix(n, n); for (int i = 0; i < n - 1; i++) { matrix.set(H, i, i, -2); matrix.set(H, i, i + 1, 1); matrix.set(H, i + 1, i, 1); } matrix.set(H, n - 1, n - 1, -2); H = -1 / s / s * H; var res = new jacobi_diagonalization(H); vector e = res.get_eigenvalues(); matrix V = res.get_eigenvectors(); return(new Tuple <vector, matrix>(e, V)); }
public static int Main() { int dim = 30; double tau = 1e-6; double eps = 1e-6; int updates = 999; int n_max = 999; // If updates=999, no Rayleigh updates are performed var rnd = new Random(); int i = rnd.Next(dim - 1); double deviation = 1.05; matrix A = misc.gen_matrix(dim); matrix Ac = A.copy(); var jacobi = new jacobi_diagonalization(A); vector e = jacobi.get_eigenvalues(); matrix V = jacobi.get_eigenvectors(); double s_0 = e[i] * deviation; double s_1 = e[i] * deviation; vector v_0 = misc.gen_vector(dim); // Random vector vector v_1 = V[i] / V[i].norm(); // Jacobi eigenvector for (int j = 0; j < v_1.size; j++) { v_1[j] = v_1[j] * deviation; } double n_0 = power_method.inverse_iteration(Ac, ref s_0, ref v_0, tau, eps, n_max, updates); // Random double n_1 = power_method.inverse_iteration(Ac, ref s_1, ref v_1, tau, eps, n_max, updates); // Jacobi var outfile = new System.IO.StreamWriter($"../test_out.txt", append: false); outfile.WriteLine($"--------------------------------------------"); outfile.WriteLine($"Inverse iteration method (Jacobi comparison)"); outfile.WriteLine($"--------------------------------------------"); outfile.WriteLine($"Matrix dimension: {dim}"); outfile.WriteLine($"Random eigenvalue index: {i}"); outfile.WriteLine($"Maximum iterations: {n_max}\n"); outfile.WriteLine($"Jacobi eigenvalues:"); outfile.WriteLine($"e_(i-1): {e[i-1]}"); outfile.WriteLine($"e_(i): {e[i]}"); outfile.WriteLine($"e_(i+1): {e[i+1]}\n"); outfile.WriteLine($"Inverse iteration method:\n"); outfile.WriteLine($"Initial deviation: {deviation}"); outfile.WriteLine($"Initial eigenvalue: {e[i]*deviation}"); outfile.WriteLine($"Absolute accuracy: {tau}"); outfile.WriteLine($"Relative accuracy: {eps}\n"); outfile.WriteLine($"Inverse iteration method with random initial eigenvector:"); outfile.WriteLine($"Algorithm result: {s_0}"); outfile.WriteLine($"v^(T)*A*v: {v_0.dot(Ac*v_0)}"); outfile.WriteLine($"Iterations: {n_0}"); outfile.WriteLine($"Errors compared to Jacobi eigenvalues:"); outfile.WriteLine($"Abs(e_(i-1) - s): {Abs(e[i-1]-s_0)}"); outfile.WriteLine($"Abs(e_(i) - s): {Abs(e[i]-s_0)}"); outfile.WriteLine($"Abs(e_(i+1) - s): {Abs(e[i+1]-s_0)}\n"); outfile.WriteLine($"Inverse iteration method with deviated Jacobi eigenvector:"); outfile.WriteLine($"Algorithm result: {s_1}"); outfile.WriteLine($"v^(T)*A*v: {v_1.dot(Ac*v_1)}"); outfile.WriteLine($"Iterations: {n_1}"); outfile.WriteLine($"Errors compared to Jacobi eigenvalues:"); outfile.WriteLine($"Abs(e_(i-1) - s): {Abs(e[i-1]-s_1)}"); outfile.WriteLine($"Abs(e_(i) - s): {Abs(e[i]-s_1)}"); outfile.WriteLine($"Abs(e_(i+1) - s): {Abs(e[i+1]-s_1)}\n"); outfile.Close(); return(0); }
public static int Main() { // 1) Amount of operations scaling matrix A; int nmax = 100; Stopwatch time = new Stopwatch(); var diag_scale = new System.IO.StreamWriter("./plot_files/diag_scale.txt", append: false); for (int n = 20; n < nmax; n += 1) { A = misc.gen_matrix(n); time.Reset(); time.Start(); var res = new jacobi_diagonalization(A); time.Stop(); diag_scale.WriteLine($"{Log(n)} {Log(time.ElapsedMilliseconds)}"); } diag_scale.Close(); // Linear fit to logarithmic data to verify n^3 dependence List <double[]> data = misc.load_data("./plot_files/diag_scale.txt"); double[] x = data[0]; double[] y = data[1]; double[] dy = new double[y.Length]; // Allocate array for y errors for (int i = 0; i < dy.Length; i++) { dy[i] = 1e-3; } // Logarithmic y errors Func <double, double>[] F = new Func <double, double>[] { s => 1, s => s }; // Array of fitting functions var fit = new lsq_qr(x, y, dy, F); // Variable storing instance of least square class vector c = fit.get_c(); // Retrieve expansion coefficients of fitting functions double a = c[0]; double b = c[1]; var fit_data = new System.IO.StreamWriter("./plot_files/fit_data.txt", append: false); for (double n = x[0]; n < x[x.Length - 1]; n += 0.1) { fit_data.WriteLine($"{n} {a + b*n}"); } fit_data.Close(); // 2) Demonstration of value-by-value method int dim = 10; int eigenvalues = 5; A = misc.gen_matrix(dim); matrix Ac = A.copy(); matrix Acc = A.copy(); var A_res = new jacobi_diagonalization(A, "cyclic"); var Ac_res = new jacobi_diagonalization(Ac, "value", "min", eigenvalues); var Acc_res = new jacobi_diagonalization(Acc, "value", "max", eigenvalues); var outfile = new System.IO.StreamWriter("../out_B.txt", append: false); outfile.WriteLine($"---------------------------------"); outfile.WriteLine($"Scaling of matrix diagonalization"); outfile.WriteLine($"---------------------------------"); outfile.WriteLine($"To demonstrate the O(n^3) scaling of the matrix diagonalization procedure, a linear fit is applied to the logaritmic (n,t) data."); outfile.WriteLine($"Fit result:"); outfile.WriteLine($"log(t) = {a} + {b}*log(n)"); outfile.WriteLine($"Thus, the scaling must be O(n^3) since the slope is approximately equal to 3.\n"); outfile.WriteLine($"-----------------------------------------------"); outfile.WriteLine($"Jacobi diagonalization eigenvalue-by-eigenvalue"); outfile.WriteLine($"-----------------------------------------------"); outfile.WriteLine($"Test of eigenvalue-by-eigenvalue routine:"); outfile.WriteLine($"A random symmetric matrix A of dimension {dim}x{dim} is generated. Rotation angle should be changed into 0.5*arctan2(-2*Apq, App-Aqq) to achieve largest eigenvalue.\n"); outfile.WriteLine($"{eigenvalues} lowest eigenvalues of A:"); vector lowest_eigenvalues = Ac_res.get_eigenvalues(); for (int ir = 0; ir < lowest_eigenvalues.size; ir++) { outfile.Write("{0,10:g3} ", lowest_eigenvalues[ir]); } outfile.WriteLine("\n"); outfile.WriteLine($"{eigenvalues} highest eigenvalues of A:"); vector highest_eigenvalues = Acc_res.get_eigenvalues(); for (int ir = 0; ir < highest_eigenvalues.size; ir++) { outfile.Write("{0,10:g3} ", highest_eigenvalues[ir]); } outfile.WriteLine("\n"); outfile.WriteLine($"Eigenvalues of A for comparison:"); vector all_eigenvalues = A_res.get_eigenvalues(); for (int ir = 0; ir < all_eigenvalues.size; ir++) { outfile.Write("{0,10:g3} ", all_eigenvalues[ir]); } outfile.WriteLine("\n"); outfile.WriteLine($"Comparison of the two diagonalization routines in terms of number of rotations:"); dim = 50; A = misc.gen_matrix(dim); Ac = A.copy(); Acc = A.copy(); A_res = new jacobi_diagonalization(A, "cyclic"); Ac_res = new jacobi_diagonalization(Ac, "value", "min", 1); Acc_res = new jacobi_diagonalization(Acc, "value", "min", dim); outfile.WriteLine($"Another random symmetric matrix A of dimension {dim}x{dim} is generated.\n"); outfile.WriteLine($"Cyclic method:"); outfile.WriteLine($"Lowest eigenvalue: {A_res.get_eigenvalues()[0]}"); outfile.WriteLine($"Amount of rotations (full diagonalization): {A_res.get_rotations()}\n"); outfile.WriteLine($"Eigenvalue-by-eigenvalue method:"); outfile.WriteLine($"Lowest eigenvalue: {Ac_res.get_eigenvalues()[0]}"); outfile.WriteLine($"Amount of rotations (lowest eigenvalue): {Ac_res.get_rotations()}"); outfile.WriteLine($"Amount of rotations (full diagonalization): {Acc_res.get_rotations()}\n"); outfile.WriteLine($"Thus, the eigenvalue-by-eigenvalue method is suitable for calculuating only the lowest eigenvalues of a matrix whereas the cyclic sweep method is faster for full diagonalization.\n"); outfile.Close(); return(0); }
public static int Main() { // A: Jacobi diagonalization with cyclic sweeps and quantum particle in a box matrix A = misc.gen_matrix(5); // Generate random symmetric matrix A matrix Ac = A.copy(); var res = new jacobi_diagonalization(A); // Create an instance of jacobi diagonalization for matrix A vector e = res.get_eigenvalues(); // Retrieve eigenvalues matrix V = res.get_eigenvectors(); // Retrieves eigenvectors matrix D = new matrix(A.size1, A.size1); // Create D matrix for (int i = 0; i < A.size1; i++) { D[i][i] = e[i]; } matrix VTAV = V * Ac * V.transpose(); Tuple <vector, matrix> boxres = box(20); var outfile = new System.IO.StreamWriter("../out_A.txt", append: false); outfile.WriteLine($"-----------------------------------------"); outfile.WriteLine($"Jacobi diagonalization with cyclic sweeps"); outfile.WriteLine($"-----------------------------------------"); outfile.WriteLine("Random real symmetric matrix A:"); for (int ir = 0; ir < Ac.size1; ir++) { for (int ic = 0; ic < Ac.size2; ic++) { outfile.Write("{0,10:g3} ", Ac[ir, ic]); } outfile.WriteLine(""); } outfile.WriteLine(""); outfile.WriteLine("Eigenvalues of A:"); for (int ir = 0; ir < e.size; ir++) { outfile.Write("{0,10:g3} ", e[ir]); } outfile.WriteLine(""); outfile.WriteLine(""); outfile.WriteLine("Eigenvectors of A (matrix V):"); for (int ir = 0; ir < V.size1; ir++) { for (int ic = 0; ic < V.size2; ic++) { outfile.Write("{0,10:g3} ", V[ir, ic]); } outfile.WriteLine(""); } outfile.WriteLine(""); outfile.WriteLine("V*A*V^T:"); for (int ir = 0; ir < VTAV.size1; ir++) { for (int ic = 0; ic < VTAV.size2; ic++) { outfile.Write("{0,10:g3} ", VTAV[ir, ic]); } outfile.WriteLine(""); } outfile.WriteLine(""); outfile.WriteLine("Matrix D:"); for (int ir = 0; ir < D.size1; ir++) { for (int ic = 0; ic < D.size2; ic++) { outfile.Write("{0,10:g3} ", D[ir, ic]); } outfile.WriteLine(""); } outfile.WriteLine(""); outfile.WriteLine($"-----------------------------------------"); outfile.WriteLine($"Quantum particle in a box"); outfile.WriteLine($"-----------------------------------------"); int n = 20; outfile.WriteLine("Eigenvalues of the Hamiltonian (k, calculated, exact, error):"); for (int k = 0; k < n / 3; k++) { double exact = PI * PI * (k + 1) * (k + 1); double calculated = boxres.Item1[k]; outfile.WriteLine($"{k} {calculated} {exact} {exact-calculated}"); } for (int k = 0; k < 3; k++) { var eigenvectors = new System.IO.StreamWriter($"./plot_files/eigenvectors{k}.txt", append: false); eigenvectors.WriteLine($"{0} {0} {0}"); for (int i = 0; i < n; i++) { eigenvectors.WriteLine($"{(i+1.0)/(n+1)} {boxres.Item2[k,i]} {Psi(k+1,(i+1.0)/(n+1))}"); } eigenvectors.WriteLine($"{1} {0} {0}"); eigenvectors.Close(); } outfile.Close(); return(0); }