//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 }
//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 }
//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 }