Esempio n. 1
0
    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);
    }
Esempio n. 2
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));
    }
Esempio n. 3
0
    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);
    }
Esempio n. 4
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);
    }
Esempio n. 5
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);
    }