private static Point GeneralizedNewtonMethod(FunctionWrapper function, Point x0, double h0, double epsilon)
        {
            var g = function.Gradient(x0);

            if (!(g.Normalize() > epsilon))
            {
                return(x0);
            }
            double h;
            var    hessian         = function.Hess(x0);
            var    hessianInverted = hessian.InvertByJordanGauss();

            do
            {
                CountThisLoop();
                var x = x0;
                x0 = new Point(new double[x0.Length]);
                var w = new Vector(new double[x0.Length]);
                for (var i = 0; i < w.Length; i++)
                {
                    for (var j = 0; j < w.Length; j++)
                    {
                        w[i] += hessianInverted[i, j] * g[j];
                    }
                }
                h  = function.FindHForFastestDescent(x, w, h0, epsilon);
                x0 = x - h * w;
                g  = function.Gradient(x0);
            } while (g.Normalize() >= epsilon && Math.Abs(h) > Math.Sqrt(epsilon));
            return(x0);
        }
        private static Point NewtonMethod(FunctionWrapper function, Point x0, double epsilon)
        {
            var g = function.Gradient(x0);

            if (g.Normalize() > epsilon)
            {
                do
                {
                    CountThisLoop();
                    var x               = x0;
                    var hessian         = function.Hess(x0);
                    var hessianInverted = hessian.InvertByJordanGauss();
                    x0 = new Point(new double[x0.Length]);
                    var w = new Vector(new double[x0.Length]);
                    for (var i = 0; i < w.Length; i++)
                    {
                        for (var j = 0; j < w.Length; j++)
                        {
                            w[i] += hessianInverted[i, j] * g[j];
                        }
                    }
                    x0 = x - w;
                    g  = function.Gradient(x0);
                } while (g.Normalize() >= epsilon);
            }
            return(x0);
        }
        private static Point FastestDescent(FunctionWrapper function, Point x0, double h0, double epsilon)
        {
            var g = function.Gradient(x0);

            if (g.Normalize() > epsilon)
            {
                Point x;
                do
                {
                    CountThisLoop();
                    x = x0;
                    var h = function.FindHForFastestDescent(x, g, h0, epsilon);
                    x0 = x - h * g;
                    g  = function.Gradient(x0);
                } while (!((x - x0).Normalize() < epsilon || g.Normalize() < epsilon));
            }
            return(x0);
        }