/** Method:  Try steffensen acceleration (if error, return -1)
         * f -  function
         * x - independent variable
         * min - min value of the interval
         * max -  max value of the interval
         * val -  value to add (0 if pure root search)
         * iterations - number of iterations */
        internal double TrySteffensenAcceleration(function f, derivative d, double x, double val, double iterations)
        {
            double gx     = f(x) - val;
            int    i      = 0;
            double xi     = -1;
            double xiMin1 = -1;
            double xiMin2 = -1;

            while (Math.Abs(gx) > epsilon)
            {
                if (d(x) == 0)
                {
                    return(0);
                }
                if (i < 4 || i % 2 == 0 || xi - 2 * xiMin1 + xiMin2 == 0)
                {
                    x = x - gx / d(x);
                }
                else
                {
                    x = GetAitkenIteration(xiMin2, xiMin1, xi);
                }
                gx     = f(x) - val;
                xiMin2 = xiMin1;
                xiMin1 = xi;
                xi     = x;
                i++;
                if (i > maxIterations)
                {
                    throw new Exception("Exceed maximun iterations");
                }
            }
            iterations = i;
            return(x);
        }
Exemplo n.º 2
0
 //Расчёт значения производной в точке
 public double GetDerivative(derivative function, int k, uint round = 0)
 {
     if (round != 0)
     {
         return(Math.Round(function(points[0, k], points[1, k]), (int)round));
     }
     else
     {
         return(function(points[0, k], points[1, k]));
     }
 }
        /** Method:  Bisection root search numerical method
         * f -  function
         * d -  first derivative
         * min - min value of the interval
         * max -  max value of the interval
         * val -  value to add (0 if pure root search)
         * eps - epsilon for solution validation
         * maxIt - maximum of iterations */
        internal double MonotoneBisection(function f, derivative d, double min, double max, double val, double eps, ref int it, int maxIt)
        {
            double dMin = d(min);
            double dMax = d(max);

            if (dMin * dMax < 0)
            {
                throw new ArgumentException("This method is only for monotone intervals");
            }
            return(MonotoneBisectionRec(f, min, max, val, (dMin > 0), eps, ref it, maxIt));
        }
        /** Method:
         * Metodo Steffenson, que es una forma mas rapida de encontrar una raiz o cero de una función
         * Si va es cero entonces encuantra la raiz de la funcion
         * si no, encuentra la inversa de la función
         * f -  function
         * d -  first derivative
         * x -  independent variable
         * val - Valor para el cual se desea buscar la inversa de la función */
        internal double SteffensenAcceleration(function f, derivative d, double x, double val)
        {
            double gxAnt = double.MaxValue;

            epsilon = 0.005;
            double gx     = f(x) - val;
            int    i      = 0;
            double xi     = -1;
            double xiMin1 = -1;
            double xiMin2 = -1;

            while (Math.Abs(gx) > epsilon)
            {
                if (d(x) == 0)
                {
                    return(0);
                }
                if (i < 4 || i % 2 == 0 || xi - 2 * xiMin1 + xiMin2 == 0)
                {
                    x = x - gx / d(x);
                }
                else
                {
                    x = GetAitkenIteration(xiMin2, xiMin1, xi);
                }
                gx = f(x) - val;
                if (Math.Abs(gx) > Math.Abs(gxAnt))
                {
                    return(xi);
                }
                gxAnt  = gx;
                xiMin2 = xiMin1;
                xiMin1 = xi;
                xi     = x;
                i++;
                if (i > maxIterations)
                {
                    return(0);
                }
            }
            iterations = i;
            return(x);
        }
        /** Method:
         * Metodo Newton Raphson para encontrar una raiz o cero de una función</para>
         * Si val es cero entonces encuantra la raiz de la funcion,
         * si no, encuentra la inversa de la función
         * f -  function
         * d -  first derivative
         * x -  independent variable
         * val - Valor para el cual se desea buscar la inversa de la función */
        internal double NewtonRaphson(function f, derivative d, double x, double val)
        {
            int    i  = 0;
            double gx = f(x) - val;

            while (Math.Abs(gx) > epsilon)
            {
                if (d(x) == 0)
                {
                    return(0);
                }
                x  = x - gx / d(x);
                gx = f(x) - val;
                i++;
                if (i > maxIterations)
                {
                    throw new Exception("Exceed the maximun iterations");
                }
            }
            return(x);
        }
        /** Method:
         * Metodo Newton Raphson para encontrar una raiz o cero de una función
         * Si val es cero entonces encuantra la raiz de la funcion
         * si no, encuentra la inversa de la función <paramref name="f"/> en val
         * f -  function
         * d -  first derivative
         * d2 -  second derivative
         * min - min value of the interval
         * max -  max value of the interval
         * val -  value to add (0 if pure root search)
         * eps - epsilon for solution validation
         * maxIt - maximum of iterations */
        internal double NewtonRaphsonOneRoot(function f, derivative d, derivative2 d2, double min, double max, double val)
        {
            if ((f(min) - val) * f(max) - val > 0)
            {
                throw new ArgumentException("No zero between these values");
            }
            double nr = 0;
            double x;
            int    i = 0;

            while (nr == 0)
            {
                x  = GetFourierValue(f, d2, min, max, val);
                nr = NewtonRaphson(f, d, x, val);
                if (i > maxIterations)
                {
                    throw new Exception("Exceed the maximun iterations");
                }
                i++;
            }
            return(nr);
        }
        /** Method:
         * Metodo Steffenson, que es una forma mas rapida de encontrar una raiz o cero de una función
         * Si val es cero entonces encuantra la raiz de la funcion
         * si no, encuentra la inversa de la función
         * f -  function
         * d -  first derivative
         * d2 -  second derivative
         * min - min value of the interval
         * max -  max value of the interval
         * val -  value to add (0 if pure root search)
         * maxIterations -  maximum of iterations */
        internal double SteffensenAccOneRoot(function f, derivative d, derivative2 d2, double min, double max, double val, int maxIterations)
        {
            if ((f(min) - val) * f(max) - val > 0)
            {
                throw new Exception("No zero between these values");
            }
            double st = 0;
            double x;
            int    i = 0;

            while (st == 0)
            {
                x  = GetFourierValue(f, d2, min, max, val);
                st = SteffensenAcceleration(f, d, x, val);
                i++;
                if (i > maxIterations)
                {
                    throw new Exception("Exceed maximun iterations");
                }
            }
            //Console.WriteLine("val = " + val + " , st = " + st + " , it = " + i);
            return(st);
        }
Exemplo n.º 8
0
        static void Main(string[] args)
        {
            Func <double, double, double> func = (x1, x2) => (100 * Math.Pow(x1, 2) + Math.Pow(x2, 2));

            derivative[] masDerivatives = new derivative[2];
            masDerivatives[0] = ((x1, x2) => (200 * x1));
            masDerivatives[1] = ((x1, x2) => (2 * x2));

            secondDerivative[,] masSecondDerivatives = new secondDerivative[2, 2];
            masSecondDerivatives[0, 0] = ((x1, x2) => (200));
            masSecondDerivatives[0, 1] = ((x1, x2) => (0));
            masSecondDerivatives[1, 0] = ((x1, x2) => (0));
            masSecondDerivatives[1, 1] = ((x1, x2) => (2));

            double[,] points = new double[2, 12];
            points[0, 0]     = 0; points[1, 0] = 1;
            Gradient gradient1 = new Gradient(points, 0.1, 0.15, 10, 0.5, 3, masDerivatives, masSecondDerivatives, 3, func);
            Gradient gradient2 = new Gradient(points, 0.1, 0.15, 10, 0.5, 3, masDerivatives, masSecondDerivatives, 3, func);
            Gradient gradient3 = new Gradient(points, 0.1, 0.15, 10, 0.5, 3, masDerivatives, masSecondDerivatives, 3, func);

            //gradient1.RegisterHandler(func);
            //gradient2.RegisterHandler(func);
            //gradient3.RegisterHandler(func);
            Console.WriteLine("Метод Ньютона: ");
            Console.WriteLine();
            gradient1.SearchMinNyuton();
            Console.WriteLine();
            Console.WriteLine();
            Console.WriteLine("Метод сопряжённых градиентов: ");
            Console.WriteLine();
            gradient2.SearchMinConjugateGradients();
            Console.WriteLine();
            Console.WriteLine();
            Console.WriteLine("Метод наискорейшего градиентного спуска: ");
            Console.WriteLine();
            gradient3.SearchMinFast();
        }
 //Расчёт значения производной в точке
 public double GetDerivative(derivative function, int k)
 {
     return(function(points[0, k], points[1, k]));
 }