private static Point CoordinateDescent(FunctionWrapper function, Point x0, double h0, double epsilon)
        {
            var h = new Vector(new double[x0.Length]);

            for (var i = 0; i < h.Length; i++)
            {
                h[i] = h0;
            }
            var   xInt = x0.Clone();
            Point xExt;

            do
            {
                xExt = xInt.Clone();
                for (var i = 0; i < xInt.Length; i++)
                {
                    Program.CountThisLoop();
                    var x  = xInt.Clone();
                    var y1 = x.Clone();
                    y1[i] += 3 * epsilon;
                    var y2 = x.Clone();
                    y2[i] -= 3 * epsilon;
                    var f1 = function.Eval(y1);
                    var f2 = function.Eval(y2);
                    var z  = Math.Sign(f2 - f1);
                    h[i]    = function.FindHForCoordinateDescent(xInt.Clone(), z, i, h[i], epsilon);
                    xInt[i] = x[i] + h[i] * z;
                }
            } while ((xInt - xExt).Normalize() >= epsilon);
            return(xInt);
        }
        private void методПокоординатногоСпускуМетодомЗейделяГаусаToolStripMenuItem_Click(object sender, EventArgs e)
        {
            FunctionWrapper.Function firstFunction =
                x => 40 * Math.Pow(x[0], 2) + 20 * x[0] * x[1] + 30 * Math.Pow(x[1], 2) - 10 * x[0] + x[1];

            var firstCounter         = new FunctionCallsCounter(firstFunction);
            var x0ForFirstFunction   = new Point(0, 2);
            var firstFunctionWrapper = new FunctionWrapper(firstCounter.GetFunction(),
                                                           x => new Vector(80 * x[0] + 20 * x[1] - 10, 20 * x[0] + 60 * x[1] + 1));
            var epsilon = Convert.ToDouble(comboBox1.Text);
            var res     = CoordinateDescent(firstFunctionWrapper, x0ForFirstFunction, h0, epsilon);

            textBox1.Text = res.ToString();
            textBox2.Text = firstFunctionWrapper.Eval(res).ToString();
            textBox3.Text = firstCounter.Count.ToString();
            textBox4.Text = _loopCounter.ToString();
        }
        private void методНайшвидшогоСпускуToolStripMenuItem_Click_1(object sender, EventArgs e)
        {
            //функцiя Розенброка
            FunctionWrapper.Function RozenbrocksFunction =
                x => 100 * Math.Pow(x[1] - Math.Pow(x[0], 2), 2) + Math.Pow(1 - x[0], 2);
            var rozenblocksCounter         = new FunctionCallsCounter(RozenbrocksFunction);
            var rozenblocksFunctionWrapper = new FunctionWrapper(rozenblocksCounter.GetFunction(),
                                                                 x => new Vector(400 * Math.Pow(x[0], 3) - 400 * x[0] * x[1] + 2 * x[0] - 2,
                                                                                 200 * x[1] - 200 * Math.Pow(x[0], 2)));
            var x0ForRozenboksFunction = new Point(0, 0);
            var epsilon = Convert.ToDouble(comboBox1.Text);

            rozenblocksCounter.Count = 0;
            _loopCounter             = 0;
            var res = FastestDescent(rozenblocksFunctionWrapper, x0ForRozenboksFunction, h0, epsilon);

            textBox1.Text = res.ToString();
            textBox2.Text = rozenblocksFunctionWrapper.Eval(res).ToString();
            textBox3.Text = rozenblocksCounter.Count.ToString();
            textBox4.Text = _loopCounter.ToString();
        }
        private void узагальненийМетодНьютонаДляПошукуДругоїФункціїToolStripMenuItem_Click(object sender, EventArgs e)
        {
            FunctionWrapper.Function secondFunction =
                x =>
                Math.Pow(x[0], 4) + 3 * Math.Pow(x[1], 4) +
                Math.Sqrt(2 * Math.Pow(x[0], 2) + Math.Pow(x[1], 2) + 1) -
                4 * x[0] + 6 * x[1];
            var secondCounter         = new FunctionCallsCounter(secondFunction);
            var secondFunctionWrapper = new FunctionWrapper(secondCounter.GetFunction(),
                                                            x =>
                                                            new Vector(4 * Math.Pow(x[0], 3) + 2 * x[0] / Math.Sqrt(2 * Math.Pow(x[0], 2) + x[1] + 1) - 4,
                                                                       x[1] / Math.Sqrt(2 * Math.Pow(x[0], 2) + Math.Pow(x[1], 2) + 1) + 12 * Math.Pow(x[1], 3) + 6),
                                                            x => new SquareMatrix(new double[2][]
            {
                new double[2]
                {
                    2 * (6 * Math.Pow(x[0], 2) * Math.Pow(2 * Math.Pow(x[0], 2) + x[1] + 1, 1.5) + x[1] + 1) /
                    Math.Pow(2 * Math.Pow(x[0], 2) + x[1] + 1, 1.5),
                    -(x[0] / Math.Pow(Math.Pow(x[0], 2) + x[1] + 1, 1.5))
                },
                new double[2]
                {
                    -(2 * x[0] * x[1] / Math.Pow(2 * Math.Pow(x[0], 2) + Math.Pow(x[1], 2) + 1, 1.5)),
                    (2 * Math.Pow(x[0], 2) + 1) / Math.Pow(2 * Math.Pow(x[0], 2) + Math.Pow(x[1], 2) + 1, 1.5) +
                    36 * Math.Pow(x[1], 2)
                }
            }));
            var x0ForSecondFunction = new Point(1, 1);

            secondCounter.Count = 0;
            _loopCounter        = 0;
            var epsilon = Convert.ToDouble(comboBox1.Text);
            var res     = GeneralizedNewtonMethod(secondFunctionWrapper, x0ForSecondFunction, h0, epsilon);

            textBox1.Text = res.ToString();
            textBox2.Text = secondFunctionWrapper.Eval(res).ToString();
            textBox3.Text = secondCounter.Count.ToString();
            textBox4.Text = _loopCounter.ToString();
        }