Esempio n. 1
0
    static void probC()
    {
        Write("Problem C:\n");
        var rand = new System.Random();
        int n    = 5 + rand.Next(3);

        matrix A = makeRandomMatrix(n, n);

        A.print("Make a random square matrix of random size: A = ");

        qr_givens decomp_givens = new qr_givens(A);
        qr_gs     decomp_gs     = new qr_gs(A);

        Write("\nDo the Givens decomposition and store the restult in the matrix G, which cotains the elements of the component R in the upper triangular part, and the angles for the Givens rotations in the relevant sub-diagonal entries. Compare with the R matrix found from the Gramm-Schmitt method:");
        decomp_givens.G.print("Givens G: ");
        decomp_gs.R.print("Gram-Schmitt R: ");
        Write("The upper triangular parts are the same.\n");

        vector b = makeRandomVector(n);

        b.print("\nMake a random vector b with the same size as A: b = ");

        Write("\nCompare using the Givens rotations to apply Q^(T) to b, and doing the explicit matrix multiplication with the Q matrix found by the Gramm-Schmitt method:\n");
        decomp_givens.applyQT(b).print("Givens: Q^(T)*b = ");
        (decomp_gs.Q.transpose() * b).print("GS: Q^(T)*b = ");

        vector x = decomp_givens.solve(b);

        x.print("\nSolution to A*x=b using Givens: ");
        (A * x - b).print("\nCheck solution satisfies A*x = b: A*x-b = ");

        Write("\nFind the inverse of A, and check that A^(-1)*A is the identity matrix:\n");
        decomp_givens.inverse().print("A^(-1)");
        (decomp_givens.inverse() * A).print("A^(-1)*A = ");
    }
Esempio n. 2
0
    // Wrapper method to find the lowest eigenvalues faster than the
    // highest, by going the other way in the application of A; that is
    // by solving A*v2 = v1 instead of applying A*v1 = v2.
    public static void iterations_lowest(
        matrix A,         // The input matrix
        matrix V,         // The n x m matrix to contain V
        matrix T          // The m x m matrix to contain the tridiagonal T matrix
        )
    {
        // We need to solve a number of equations like:
        // A*x = b
        // However, this can be simplified by first finding the QR
        // decomposition of A:
        qr_givens A_decomp = new qr_givens(A);
        // Here the "A_decomp" object will be saved in the closure of the
        // "applyA" anonymous function, and thereby the decomposition is
        // only calculated once.
        Func <vector, vector> applyA = (v) => {
            return(A_decomp.solve(v));
        };

        iterations(applyA, V, T);
    }
Esempio n. 3
0
    public static vector newton(
        Func <vector, vector> f, // Vector function to find root of
        vector x,                // The starting point
        double epsilon = 1e-3,   // The accuracy goal
        double dx      = 1e-7    // finite difference to be used for jacobian
        )
    {
        //Write("One call to newton()\n");
        vector root;

        vector f_x = f(x);

        // 1: Calculate Jacobian
        // Assume f has the same size as x?
        int    n = x.size;
        matrix J = new matrix(n, n);

        for (int k = 0; k < n; k++)
        {
            vector new_x = x.copy();
            new_x[k] += dx;
            vector diff_f = (f(new_x) - f_x) / dx;
            for (int i = 0; i < n; i++)
            {
                J[i, k] = diff_f[i];
            }
        }

        // 2: Find delta_x by solving J*delta_x=-f
        qr_givens Jsolver = new qr_givens(J);
        vector    delta_x = Jsolver.solve(-f_x);

        // 3: Find actual step by backtracking line search
        // This loop is hard to read, might have to change.
        double lambda = 1.0;

        while ((lambda >= 1.0 / 64) && (f(x + lambda * delta_x).norm() > (1 - lambda / 2) * f_x.norm()))
        {
            lambda /= 2;
        }
        x = x + lambda * delta_x;
        // Write($"f(x).norm = {f(x).norm()}\n");

        // 4: Check if we are under tolerance
        //	  a: If under tolerance: Return value
        //    b: If not under tolerance: Recursive call with new x
        if (delta_x.norm() < dx)
        {
            Error.Write("Step size {delta_x.norm()} is below finite diffrence dx\nStopping itterations and returning best found root...");
            root = x;
        }
        else if (f(x).norm() < epsilon)
        {
            root = x;
        }
        else
        {
            root = newton(f, x, epsilon, dx);
        }

        return(root);
    }