static void Main(string[] args) { /* Compare the time it takes to diagonalize a matrix * of size n by different methods: * Cyclic jacobi, value-by-value and v-b-v * for both highest and lowest eig val. */ Stopwatch sw = new Stopwatch(); foreach (string arg in args) { int n = Int32.Parse(arg); // Generate symmetric nxn matrix A matrix A = randomMatrix(n, n); restoreUpperTriang(A); // Cyclic jacobi matrix V = new matrix(n, n); vector e = new vector(n); sw.Start(); int sweeps = Jacobi.cyclic(A, V, e); sw.Stop(); double cyclic = sw.Elapsed.Ticks / 10000.0; sw.Reset(); // Value-by-value full V = new matrix(n, n); e = new vector(n); sw.Start(); vector eigVals = Jacobi.lowestK(A, V, e, n); sw.Stop(); double VBVfull = sw.Elapsed.Ticks / 10000.0; sw.Reset(); // Value-by-value 1 V = new matrix(n, n); e = new vector(n); sw.Start(); eigVals = Jacobi.lowestK(A, V, e, 1); sw.Stop(); double VBVlow = sw.Elapsed.Ticks / 10000.0; sw.Reset(); // Value-by-value 1, highest first V = new matrix(n, n); e = new vector(n); sw.Start(); eigVals = Jacobi.highestK(A, V, e, 1); sw.Stop(); double VBVhigh = sw.Elapsed.Ticks / 10000.0; sw.Reset(); // size of matrix and time in ms WriteLine($"{n} {cyclic} {VBVfull} {VBVlow} {VBVhigh}"); } }
static void Main() { int n = 6; WriteLine($"Generate symmetric {n}x{n} matrix A"); matrix A = randomMatrix(n, n); restoreUpperTriang(A); A.print("A: "); matrix V = new matrix(n, n); vector e = new vector(n); int sweeps; // Cyclic sweeps = Jacobi.cyclic(A, V, e); WriteLine($"Cyclic Jacobi done in {sweeps} sweeps"); e.print("Cyclic eigenvalues: "); // Lowest k restoreUpperTriang(A); V = new matrix(n, n); e = new vector(n); int k = n / 3; vector v = Jacobi.lowestK(A, V, e, k); v.print($"Lowest {k} values:"); A.print($"Test that {k} rows are cleared"); // Highest k restoreUpperTriang(A); V = new matrix(n, n); e = new vector(n); k = n / 3; v = Jacobi.highestK(A, V, e, k); v.print($"Highest {k} values:"); A.print($"Test that {k} rows are cleared"); restoreUpperTriang(A); V = new matrix(n, n); e = new vector(n); int rots = Jacobi.classic(A, V, e); e.print($"Classical done! rotations: {rots}"); A.print($"Test that all rows are cleared"); }
static int Main() { // Generate matrix A int n = 12; WriteLine("Creating random 7x7 matrix, A..."); matrix A = randomMatrix(n, n); // Make A symmetric restoreUpperTriang(A); matrix V = new matrix(n, n); vector e = new vector(n); // Vector of eigenvalues A.print("A:"); WriteLine("Calculating eigenvalues..."); (int sweeps, int rots) = Jacobi.cyclic(A, V, e); WriteLine($"Calculation done! Number of sweeps: {sweeps}"); V.print("Eigenvectors"); matrix D = new matrix(n, n); for (int i = 0; i < n; i++) { D[i, i] = e[i]; } D.print("Diagonal composition, D:"); restoreUpperTriang(A); // Restore A matrix test = V.transpose() * A * V; test.print("Test that V^T * A * V = D"); matrix test2 = V * D * V.transpose(); test2.print("Test that V * D * V^T = A"); WriteLine("Test first eigenvalue and vector:"); vector eigvec = A * V[0]; vector eigval = D[0, 0] * V[0]; eigvec.print("A * V[0] : "); eigval.print("D[0,0] * V[0] : "); // Calculate numerically Quantum particle in a box WriteLine("--- Calculate numerically QM particle in a box ---"); // Generate H int N = 23; // Number of numerical steps double s = 1.0 / (N + 1); matrix H = new matrix(N, N); for (int i = 0; i < N - 1; i++) { H[i, i] = -2; H[i, i + 1] = 1; H[i + 1, i] = 1; } H[N - 1, N - 1] = -2; H.print("H, before scaling"); H = -1 / s / s * H; // Diagonalize H using jacobi matrix boxV = new matrix(N, N); vector boxE = new vector(N); (int hsweeps, int hrots) = Jacobi.cyclic(H, boxV, boxE); // Test that WriteLine("Calculation done: Checking that energies are correct"); WriteLine("E_n \t Calculation \t Exact"); for (int k = 0; k < N / 3; k++) { double exact = PI * PI * (k + 1) * (k + 1); double calc = boxE[k]; WriteLine($"E_{k} \t {calc.ToString("N5")} \t {exact.ToString("N5")}"); } // Scaling factor a double a = Sqrt(2) / boxV[N / 2, 0]; WriteLine($"a: {a}"); // Generate plotting data to plot with using (StreamWriter sw = new StreamWriter("data-A.txt")){ // Plot the first 3 wave funcs // Format: x \t psi0 \t psi_n ... sw.WriteLine($"0 \t 0 \t 0 \t 0 \t 0 \t 0"); for (int i = 0; i < N; i++) { sw.Write($"{(i+1.0)/(N+1)} "); for (int k = 0; k < 5; k++) { sw.Write($"\t {a*boxV[i,k]} "); } sw.Write("\n"); } sw.WriteLine($"1 \t 0 \t 0 \t 0 \t 0 \t 0"); } return(0); }