Ejemplo n.º 1
0
        //method to calculate the root for a system of functions given an initial guess/vector
        //Gradient Descent with Fixed Alpha
        public double[] GradientAlpha(FunctionMatrix f, double[] x, double toler)
        {
            int counter = 0;
            int dim = x.GetLength(0);
            int r = f.Rows;

            double[,] Jmat = new double[r, dim];
            Matrix MJmat = new Matrix(Jmat);
            Vector VFg1 = new Vector(r);
            Vector Vz = new Vector(dim);
            Vector VFg3 = new Vector(r);
            Vector VFg2 = new Vector(r);
            Vector VFgc = new Vector(r);
            Vector VFgnew = new Vector(r);
            Vector Vxnew = new Vector(dim);

            double alpha2 = 0;
            double alpha3 = 0;
            double[] xold = x;
            double[] xnew = new double[dim];
            double g1 = 0;
            double g2 = 0;
            double g3 = 0;
            double gc = 0;
            double gnew = 0;
            double normz = 0;
            double h1 = 0;
            double h2 = 0;
            double h3 = 0;
            double ac = 0;

            do
            {
                VFg1 = f.EvaluateVector(xold);
                g1 = VFg1.Magnitude();

                //calculate the Jacobian
                Jmat = jacobi(f, xold, 0.001);
                //now update the Matrix object which represents the Jacobian
                for (int i = 0; i < r; i++)
                    for (int j = 0; j < dim; j++)
                        MJmat[i, j] = Jmat[i, j];

                Vz = 2 * (MJmat * VFg1);

                normz = Math.Sqrt(Vz.Magnitude());

                if (normz > toler)
                {
                    Vz = (1 / normz) * Vz;
                    alpha3 = 1;

                    VFg3 = f.EvaluateVector((double[])((Vector)xold - (alpha3 * Vz)));
                    g3 = VFg3.Magnitude();

                    while (Math.Abs(g3 - g1) > toler)
                    {
                        alpha3 = 0.5 * alpha3;

                        VFg3 = f.EvaluateVector((double[])((Vector)xold - (alpha3 * Vz)));
                        g3 = VFg3.Magnitude();
                        if (Math.Abs(alpha3) < 0.5 * toler)
                            break;
                    }

                    alpha2 = 0.5 * alpha3;
                    VFg2 = f.EvaluateVector((double[])((Vector)xold - (alpha2 * Vz)));
                    g2 = VFg2.Magnitude();

                    //perform interpolation
                    h1 = (g2 - g1) / alpha2;
                    h2 = (g3 - g2) / (alpha3 - alpha2);
                    h3 = (h2 - h1) / alpha3;
                    ac = 0.5 * (alpha2 - (h1 / h3));

                    VFgc = f.EvaluateVector((double[])((Vector)xold - (ac * Vz)));
                    gc = VFgc.Magnitude();

                    if (gc < g3)
                    {
                        Vxnew = ((Vector)xold) - (ac * Vz);
                        VFgnew = f.EvaluateVector((double[])Vxnew);
                        gnew = VFgnew.Magnitude();
                    }
                    else
                    {
                        Vxnew = ((Vector)xold) - (alpha3 * Vz);
                        VFgnew = f.EvaluateVector((double[])Vxnew);
                        gnew = VFgnew.Magnitude();
                    }

                    //test for convergence
                    if (Math.Abs(gnew - g1) < toler)
                        break;
                    else
                    {
                        xold = (double[])Vxnew;
                        counter++;
                    }

                    //end if
                }

            } while (counter < 100);

            return (double[])Vxnew;
            //end of method
        }
Ejemplo n.º 2
0
        //method to calculate the root for a system of functions given an initial guess/vector
        public double[] newtonraphson(FunctionMatrix f, double[] x, double toler)
        {
            int maxiter = 1000;
            double err = 10000000;
            int counter = 0;
            int dim = x.GetLength(0);
            int r = f.Rows;
            double[] xn = new double[dim];
            //populating vector xn
            for (int i = 0; i < dim; i++)
                xn[i] = x[i];
            double[] xnp1 = new double[dim];

            while ((counter < maxiter) && (err > toler))
            {
                Vector Fn = f.EvaluateVector(xn);
                //converting to Vector Objects
                Vector Vxn = new Vector(xn);

                //Need to calculate the Jacobi and convert it to a matrix
                double[,] j = jacobi(f, xn, 0.001);
                double[,] jinv = s.find_inverse(j, j.GetLength(0));
                Matrix Jinv = new Matrix(jinv);

                //this is just F(xn)/F'(xn)
                Vector tmp = Jinv * Fn;

                //xnp1 = xn - F(xn)/F'(xn)
                Vector Vxnp1 = Vxn - tmp;

                //what is the size of the err i.e. xnp1-xn
                Vector Diff = Vxnp1 - Vxn;
                err = Diff.maxNorm();
                double[] t = new double[dim];

                xnp1 = (double[])Vxnp1;
                xn = xnp1;
                counter++;
            }

            return xn;
            //end of method
        }
Ejemplo n.º 3
0
        //method to calculate the root for a system of functions given an initial guess/vector
        public double[] BroydenShermanMorrison(FunctionMatrix f, double[] x, double toler)
        {
            double err = 10000000;
            int counter = 0;
            int dim = x.GetLength(0);
            int r = f.Rows;
            double[] xn = new double[dim];
            //populating vector xn
            for (int i = 0; i < dim; i++)
                xn[i] = x[i];
            double[] xnp1 = new double[dim];

            //first iteration i.e. use Newton Raphson for one iteration, the Inverse of the Jacobi will be used as the Ainv for Broyden
            Vector Fn = f.EvaluateVector(xn);
            Vector Vxn = new Vector(xn);
            //Need to calculate the Jacobi and convert it to a matrix
            double[,] j = jacobi(f, xn, 0.001);
            double[,] jinv = s.find_inverse(j, j.GetLength(0));
            Matrix Jinv = new Matrix(jinv);
            //this is just F(xn)/F'(xn)
            Vector tmp = Jinv * Fn;
            //xnp1 = xn - F(xn)/F'(xn)
            Vector Vxnp1 = Vxn - tmp;
            //what is the size of the err i.e. xnp1-xn
            Vector Vdeltax = Vxnp1 - Vxn;
            err = Vdeltax.maxNorm();
            xnp1 = (double[])Vxnp1;

            Vector placeholder = new Vector(1);

            //we'll use these later
            Vector VFnold = f.EvaluateVector(xn);
            Vector VFnew = f.EvaluateVector(xnp1);
            Vector VdeltaF = VFnew - VFnold;
            double[,] Aold = new double[dim, dim];
            double[,] Anew = new double[dim, dim];

            //now we'll start on the Broyden iteration element
            if (err < toler)
                return xn;
            else
            {
                while ((err > toler) && (counter < 1000))
                {
                    if (counter == 0)
                    {
                        Aold = jinv;
                        Anew = BroydenAinv(Aold, (double[])Vdeltax, (double[])VdeltaF);
                    }
                    else
                    {
                        Anew = BroydenAinv(Aold, (double[])Vdeltax, (double[])VdeltaF);
                    }
                    //now update all the variables
                    Vxnp1 = Vxn - placeholder.dot(new Matrix(Anew), VFnew);
                    Vdeltax = Vxnp1 - Vxn;
                    err = Vdeltax.maxNorm();
                    Aold = Anew;
                    VFnold = f.EvaluateVector((double[])Vxn);
                    VFnew = f.EvaluateVector((double[])Vxnp1);
                    VdeltaF = VFnew - VFnold;
                    Vxn = Vxnp1;
                    xn = (double[])Vxn;
                    counter++;
                }
                return xn;
            }
            //end of method
        }