public void CalcResult(NMInitialParams ip)
        {
            double fMax  = float.MinValue;
            int    index = -1;

            for (int i = 0; i < arrF.Length; i++)
            {
                if (arrF[i] > fMax)
                {
                    fMax  = arrF[i];
                    index = i;
                }
            }

            int n = arrF.Length - 1;

            arrXRes = new double[n];
            for (int i = 0; i < n; i++)
            {
                for (int j = 0; j < matrX.Length; j++)
                {
                    if (j == index)
                    {
                        continue;
                    }
                    arrXRes[i] += matrX[j][i];
                }
                arrXRes[i] /= (matrX.Length - 1);
            }
            fRes = ip.GetFuncValue(arrXRes);
        }
 public void CalcFuncAndResult(NMInitialParams ip)
 {
     arrF = new double[matrX.Length];
     for (int i = 0; i < arrF.Length; i++)
     {
         arrF[i] = ip.GetFuncValue(matrX[i]);
     }
     CalcResult(ip);
 }
        public IIteration DoIteration(IIteration prevIter)
        {
            it = (NMIteration)prevIter;
            for (int i = 0; i < it.matrX.Length; i++)
            {
                if (it.matrX[i].Length + 1 != it.matrX.Length)
                {
                    throw new Exception();
                }
            }
            int n = it.matrX[0].Length;

            it.arrF = new double[n + 1];
            for (int i = 0; i < n + 1; i++)
            {
                it.arrF[i] = ip.GetFuncValue(it.matrX[i]);
            }
            it.fg = it.fh = float.MinValue;
            it.fl = float.MaxValue;
            for (int i = 0; i < n + 1; i++)
            {
                if (it.arrF[i] > it.fh)
                {
                    it.fh = it.arrF[i];
                    it.h  = i;
                }
                if (it.arrF[i] > it.fg && it.arrF[i] < it.fh)
                {
                    it.fg = it.arrF[i];
                    it.g  = i;
                }
                if (it.arrF[i] < it.fl)
                {
                    it.fl = it.arrF[i];
                    it.l  = i;
                }
            }

            // центр
            it.arrX0 = new double[n];
            for (int i = 0; i < n; i++)
            {
                for (int j = 0; j < n + 1; j++)
                {
                    if (j == it.h)
                    {
                        continue;
                    }
                    it.arrX0[i] += it.matrX[j][i];
                }
                it.arrX0[i] /= n;
            }
            it.f0 = ip.GetFuncValue(it.arrX0);

            // отражение
            it.arrXr = new double[n];
            for (int i = 0; i < n; i++)
            {
                it.arrXr[i] = (1 + ip.alpha) * it.arrX0[i] - ip.alpha * it.matrX[it.h][i];
            }
            it.fr = ip.GetFuncValue(it.arrXr);

            if (it.fr < it.fl)
            {
                // растяжение
                it.arrXe = new double[n];
                for (int i = 0; i < n; i++)
                {
                    it.arrXe[i] = ip.gamma * it.arrXr[i] + (1 - ip.gamma) * it.arrX0[i];
                }
                it.fe = ip.GetFuncValue(it.arrXe);

                if (it.fe < it.fl)
                {
                    it.matrX[it.h] = (double[])it.arrXe.Clone();
                    it.CalcResult(ip);
                    if (!CheckIsDone())
                    {
                        return(new NMIteration(it.matrX));
                    }
                    else
                    {
                        return(null);
                    }
                }

                it.matrX[it.h] = (double[])it.arrXr.Clone();
                it.CalcResult(ip);
                if (!CheckIsDone())
                {
                    return(new NMIteration(it.matrX));
                }
                else
                {
                    return(null);
                }
            }

            if (it.fr <= it.fg)
            {
                it.matrX[it.h] = (double[])it.arrXr.Clone();
                it.CalcResult(ip);
                if (!CheckIsDone())
                {
                    return(new NMIteration(it.matrX));
                }
                else
                {
                    return(null);
                }
            }

            if (it.fr <= it.fh)
            {
                it.matrX[it.h] = (double[])it.arrXr.Clone();
            }

            // сжатие
            it.arrXc = new double[n];
            for (int i = 0; i < it.arrXc.Length; i++)
            {
                it.arrXc[i] = ip.beta * it.matrX[it.h][i] + (1 - ip.beta) * it.arrX0[i];
            }
            it.fc = ip.GetFuncValue(it.arrXc);

            if (it.fc > it.fh)
            {
                for (int i = 0; i < n + 1; i++)
                {
                    for (int j = 0; j < n; j++)
                    {
                        it.matrX[i][j] = 0.5 * (it.matrX[i][j] + it.matrX[it.l][j]);
                    }
                }
                it.CalcResult(ip);
                if (!CheckIsDone())
                {
                    return(new NMIteration(it.matrX));
                }
                else
                {
                    return(null);
                }
            }

            it.matrX[it.h] = (double[])it.arrXc.Clone();
            it.CalcResult(ip);
            if (!CheckIsDone())
            {
                return(new NMIteration(it.matrX));
            }
            else
            {
                return(null);
            }
        }