public void Alloc(PZMath_multimin_fminimizer_type T, int n)
 {
     type = T;
     x = new PZMath_vector(n);
     state = new nmsimplex_state_t();
     T.alloc(state, n);
 }
        public static int ContractByBest(nmsimplex_state_t state, int best, PZMath_vector xc, 
            PZMath_multimin_function f)
        {
            /* Function contracts the simplex in respect to
               best valued corner. That is, all corners besides the
               best corner are moved. */

            /* the xc vector is simply work space here */

            PZMath_matrix x1 = state.x1;
            PZMath_vector y1 = state.y1;

            int  i, j;
            double newval;

            for (i = 0; i < x1.RowCount; i++)
            {
                if (i != best)
                {
                    for (j = 0; j < x1.ColumnCount; j++)
                    {
                        newval = 0.5 * (x1[i, j] + x1[best, j]);
                        x1[i, j] = newval;
                    }

                    /* evaluate function in the new point */

                    x1.CopyRow2(i, xc);
                    newval = f.FN_EVAL(xc);
                    y1[i] = newval;
                }
            }

            return PZMath_errno.PZMath_SUCCESS;
        }
        public static int CalcCenter(nmsimplex_state_t state, PZMath_vector mp)
        {
            /* calculates the center of the simplex to mp */

            PZMath_matrix x1 = state.x1;

            int i, j;
            double val;

            for (j = 0; j < x1.ColumnCount; j++)
            {
                val = 0.0;
                for (i = 0; i < x1.RowCount; i++)
                {
                    val += x1[i, j];
                }
                val /= x1.RowCount;
                mp[j] = val;
            }

            return PZMath_errno.PZMath_SUCCESS;
        }
        public static double Size(nmsimplex_state_t state)
        {
            /* calculates simplex size as average sum of length of vectors
               from simplex center to corner points:

               ( sum ( || y - y_middlepoint || ) ) / n
             */

            PZMath_vector s = state.ws1;
            PZMath_vector mp = state.ws2;
            PZMath_matrix x1 = state.x1;
            int i;
            double ss = 0.0;

            /* Calculate middle point */
            CalcCenter (state, mp);

            for (i = 0; i < x1.RowCount; i++)
            {

                x1.CopyRow2(i, s);
                PZMath_blas.Daxpy(-1.0, mp, s);
                ss += PZMath_blas.Dnrm2(s);
            }

            return ss / (double) (x1.RowCount);
        }
        public static double MoveCorner(double coeff, nmsimplex_state_t state, int corner, 
            PZMath_vector xc, PZMath_multimin_function f)
        {
            /* moves a simplex corner scaled by coeff (negative value represents
                mirroring by the middle point of the "other" corner points)
                and gives new corner in xc and function value at xc as a
                return value
            */

            PZMath_matrix x1 = state.x1;

            int i, j;
            double newval, mp;

            if (x1.RowCount < 2)
            {
                PZMath_errno.ERROR ("nmsimplex::MoveCorner(), simplex cannot have less than two corners!", PZMath_errno.PZMath_FAILURE);
            }

            for (j = 0; j < x1.ColumnCount; j++)
            {
                mp = 0.0;
                for (i = 0; i < x1.RowCount; i++)
                {
                    if (i != corner)
                    {
                        mp += (x1[i, j]);
                    }
                }
                mp /= (double) (x1.RowCount - 1);
                newval = mp - coeff * (mp - x1[corner, j]);
                xc[j] = newval;
            }

            newval = f.FN_EVAL(xc);

            return newval;
        }