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 PZMath_permutation(PZMath_permutation p)
 {
     size = p.Size;
     data = new PZMath_vector(size);
     for (int i = 0; i < size; i ++)
         data[i] = p[i];
 }
        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 expb_df(PZMath_vector x, object param, PZMath_matrix J)
        {
            int n = (param as TestNonlinearLeastSquareFitParam).n;
            double[] sigma = (param as TestNonlinearLeastSquareFitParam).sigma;

            double A = x[0];
            double lambda = x[1];

            int i;
            for (i = 0; i < n; i++)
            {
                // Jacobian matrix J(i, j) = dfi / dxj
                // where fi = (Yi - yi) / sigma[i]
                //		 Yi = A * exp(-lambda * i) + b
                // and the xj are the parameters (A, lambda, b)

                double t = (double)i;
                double s = sigma[i];
                double e = System.Math.Exp(-lambda * t);
                J[i, 0] = e / s;
                J[i, 1] = -t * A * e / s;
                J[i, 2] = 1 / s;
            }

            return PZMath_errno.PZMath_SUCCESS;
        }
Exemple #5
0
        public static int BidiagDecomp(PZMath_matrix A, PZMath_vector tau_U, PZMath_vector tau_V)
        {
            if (A.RowCount < A.ColumnCount)
                PZMath_errno.ERROR ("PZMath_linalg::BidiagDecomp(), bidiagonal decomposition requires M>=N", PZMath_errno.PZMath_EBADLEN);
            else if (tau_U.Size != A.ColumnCount)
                PZMath_errno.ERROR ("PZMath_linalg::BidiagDecomp(),size of tau_U must be N", PZMath_errno.PZMath_EBADLEN);
            else if (tau_V.Size + 1 != A.ColumnCount)
                PZMath_errno.ERROR ("PZMath_linalg::BidiagDecomp(),size of tau_V must be (N - 1)", PZMath_errno.PZMath_EBADLEN);
            else
            {
                int M = A.RowCount;
                int N = A.ColumnCount;
                int i;

                for (i = 0 ; i < N; i++)
                {
                    /* Apply Householder transformation to current column */

                {
                    PZMath_vector c = A.Column(i);
                    PZMath_vector v = c.SubVector(i, M - i);
                    double tau_i = PZMath_linalg.HouseholderTransform(v);

                    /* Apply the transformation to the remaining columns */

                    if (i + 1 < N)
                    {
                        PZMath_matrix m = A.Submatrix(i, i + 1, M - i, N - (i + 1));
                        PZMath_linalg.HouseholderHM(tau_i, v, m);
                    }

                    tau_U[i] = tau_i;

                }

                    /* Apply Householder transformation to current row */

                    if (i + 1 < N)
                    {
                        PZMath_vector r = A.Row(i);
                        PZMath_vector v = r.SubVector(i + 1, N - (i + 1));
                        double tau_i = PZMath_linalg.HouseholderTransform (v);

                        /* Apply the transformation to the remaining rows */

                        if (i + 1 < M)
                        {
                            PZMath_matrix m = A.Submatrix(i+1, i+1, M - (i+1), N - (i+1));
                            PZMath_linalg.HouseholderMH(tau_i, v, m);
                        }

                        tau_V[i] = tau_i;
                    }
                }
            }

            return PZMath_errno.PZMath_SUCCESS;
        }
Exemple #6
0
 public static double Dasum(PZMath_vector X)
 {
     double r = 0.0;
     int i;
     int N = X.Size;
     for (i = 0; i < N; i++)
         r += System.Math.Abs(X[i]);
     return r;
 }
 public int Alloc(PZMath_multifit_fdfsolver_type T, int n, int p)
 {
     x = new PZMath_vector(p);
     f = new PZMath_vector(n);
     J = new PZMath_matrix(n, p);
     dx = new PZMath_vector(p);
     type = T;
     state = new lmder_state_t();
     return (this.type.alloc) (this.state, n, p);
 }
Exemple #8
0
 // copy constructor
 public PZMath_vector(PZMath_vector v)
 {
     size = v.Size;
     offset = v.offset;
     stride = v.stride;
     length = v.length;
     data = new double [length];
     Array.Copy(v.data, data, length);
     _mean = v._mean;
     _stddev = v._stddev;
 }
        static double my_f(PZMath_vector v, object parms)
        {
            double x, y;
            double dp1 = (parms as TestMultiminNMSimplexParms).dp1;
            double dp2 = (parms as TestMultiminNMSimplexParms).dp2;

            x = v[0];
            y = v[1];

            return 10.0 * (x - dp1) * (x - dp1) + 20.0 * (y - dp2) * (y - dp2) + 30.0;
        }
        /// <summary>
        /// N(mu, sigma)
        /// </summary>
        /// <param name="l">lower bound</param>
        /// <param name="u">upper bound</param>
        public MultivariateNormalDistribution(PZMath_vector m, PZMath_matrix s)
        {
            dimension = m.Size;
            mu = new PZMath_vector(dimension);
            mu.MemCopyFrom(m);

            sigma = new PZMath_matrix(dimension, dimension);
            sigma.MemCopyFrom(s);

            if (dimension != sigma.RowCount || dimension != sigma.ColumnCount)
                throw new ApplicationException("MultivariateNormalDistribution::MultivariateNormalDistribution(), mu and sigma in different dimension!");

            Init();
        }
Exemple #11
0
 // vector sum, i.e. Y = aX + Y
 public static int Daxpy(double alpha, PZMath_vector X, PZMath_vector Y)
 {
     if (X.Size == Y.Size)
     {
         for (int i = 0; i < X.Size; i ++)
             Y[i] = alpha * X[i] + Y[i];
         return PZMath_errno.PZMath_SUCCESS;
     }
     else
     {
         PZMath_errno.ERROR("invalid length", PZMath_errno.PZMath_EBADLEN);
     }
     return 0;
 }
Exemple #12
0
 // scalar product of vector X and Y, i.e. (X ^ T)  Y = Sum(X[i] * Y[i]);
 // out result
 public static int Ddot(PZMath_vector X, PZMath_vector Y, out double result)
 {
     result = 0.0;
     if (X.Size == Y.Size)
     {
         for (int i = 0; i < X.Size; i ++)
             result += X[i] * Y[i];
         return PZMath_errno.PZMath_SUCCESS;
     }
     else
     {
         PZMath_errno.ERROR("invalid length", PZMath_errno.PZMath_EBADLEN);
     }
     return 0;
 }
        /// <summary>
        /// sigma is a diagonal matrix
        /// </summary>
        /// <param name="m"></param>
        /// <param name="diag"></param>
        public MultivariateNormalDistribution(PZMath_vector m, PZMath_vector diag)
        {
            if (m.Size != diag.Size)
                throw new ApplicationException("MultivariateNormalDistribution::MultivariateNormalDistribution(), mu and sigma in different dimension!");
            dimension = m.Size;

            mu = new PZMath_vector(dimension);
            mu.MemCopyFrom(m);

            sigma = new PZMath_matrix(dimension, dimension);
            for (int i = 0; i < dimension; i ++)
                sigma[i, i] = diag[i];

            Init();
        }
Exemple #14
0
        public static int BalanceColumns(PZMath_matrix A, PZMath_vector D)
        {
            int N = A.ColumnCount;
            int j;

            if (D.Size != N)
            {
                PZMath_errno.ERROR ("PZMath_linalg::BalanceColumns(), length of D must match second dimension of A", PZMath_errno.PZMath_EINVAL);
            }

            D.SetAll(1.0);

            for (j = 0; j < N; j++)
            {
                PZMath_vector A_j = A.Column(j);

                double s = PZMath_blas.Dasum (A_j);

                double f = 1.0;

                if (s == 0.0 || !PZMath_sys.Finite(s))
                {
                    D[j] = f;
                    continue;
                }

                while (s > 1.0)
                {
                    s /= 2.0;
                    f *= 2.0;
                }

                while (s < 0.5)
                {
                    s *= 2.0;
                    f /= 2.0;
                }

                D[j] = f;

                if (f != 1.0)
                    PZMath_blas.Dscal(1.0/f, A_j);
            }

            return PZMath_errno.PZMath_SUCCESS;
        }
        public static int expb_f(PZMath_vector x, object param, PZMath_vector f)
        {
            int n = (param as TestNonlinearLeastSquareFitParam).n;
            double[] y = (param as TestNonlinearLeastSquareFitParam).y;
            double[] sigma = (param as TestNonlinearLeastSquareFitParam).sigma;

            double A = x[0];
            double lambda = x[1];
            double b = x[2];

            int i;
            for (i = 0; i < n; i++)
            {
                // Model Yi = A * exp(-lambda * i) + b
                double t = (double)i;
                double Yi = A * System.Math.Exp(-lambda * t) + b;
                f[i] = (Yi - y[i]) / sigma[i];
            }
            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 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;
        }
Exemple #18
0
 // return the index of max element of X, in absolut magtitude
 public static int Idamax(PZMath_vector X)
 {
     double max = 0.0;
     double t;
     int index = 0;
     for (int i = 0; i < X.Size; i ++)
     {
         t = System.Math.Abs(X[i]);
         if (t > max)
         {
             max = t;
             index = i;
         }
     }
     return index;
 }
Exemple #19
0
        public static int Dtrsv(CBLAS_UPLO Uplo, CBLAS_TRANSPOSE TransA, CBLAS_DIAG Diag, PZMath_matrix A, PZMath_vector x)
        {
            int M = A.RowCount;
            int N = A.ColumnCount;

            if (M != N)
            {
                PZMath_errno.ERROR("PZMath_blas::Dtrsv(), matrix must be square", PZMath_errno.PZMath_ENOTSQR);
            }
            else if (N != x.Size)
            {
                PZMath_errno.ERROR("PZMath_blas::Dtrsv(), invalid length", PZMath_errno.PZMath_EBADLEN);
            }

            bool nonunit = (Diag == CBLAS_DIAG.CblasNonUnit);
            int ix, jx;
            int i, j;
            CBLAS_TRANSPOSE Trans = (TransA != CBLAS_TRANSPOSE.CblasConjTrans) ? TransA : CBLAS_TRANSPOSE.CblasTrans;
            CBLAS_ORDER order = CBLAS_ORDER.CblasRowMajor;

            if (N == 0)
                return PZMath_errno.PZMath_SUCCESS;

            /* form  x := inv( A )*x */

            if ((order == CBLAS_ORDER.CblasRowMajor && Trans == CBLAS_TRANSPOSE.CblasNoTrans
                && Uplo == CBLAS_UPLO.CblasUpper)
                || (order == CBLAS_ORDER.CblasColMajor && Trans == CBLAS_TRANSPOSE.CblasTrans
                && Uplo == CBLAS_UPLO.CblasLower))
            {
                /* backsubstitution */
                ix = N - 1;
                if (nonunit)
                    x[ix] = x[ix] / A[N - 1, N - 1];
                ix--;

                for (i = N - 1; i > 0 && (i-- > 0); )
                {
                    double tmp = x[ix];
                    jx = ix + 1;
                    for (j = i + 1; j < N; j++)
                    {
                        double Aij = A[i, j];
                        tmp -= Aij * x[jx];
                        jx++;
                    }

                    if (nonunit)
                    {
                        x[ix] = tmp / A[i, i];
                    }
                    else
                    {
                        x[ix] = tmp;
                    }
                    ix--;
                }
            }
            else if ((order == CBLAS_ORDER.CblasRowMajor && Trans == CBLAS_TRANSPOSE.CblasNoTrans
                && Uplo == CBLAS_UPLO.CblasLower)
                       || (order == CBLAS_ORDER.CblasColMajor && Trans == CBLAS_TRANSPOSE.CblasTrans
                && Uplo == CBLAS_UPLO.CblasUpper))
            {
                /* forward substitution */
                ix = 0;
                if (nonunit)
                {
                    x[ix] = x[ix] / A[0, 0];
                }
                ix++;
                for (i = 1; i < N; i++)
                {
                    double tmp = x[ix];
                    jx = 0;
                    for (j = 0; j < i; j++)
                    {
                        double Aij = A[i, j];
                        tmp -= Aij * x[jx];
                        jx++;
                    }
                    if (nonunit)
                    {
                        x[ix] = tmp / A[i, i];
                    }
                    else
                    {
                        x[ix] = tmp;
                    }
                    ix++;
                }
            }
            else if ((order == CBLAS_ORDER.CblasRowMajor && Trans == CBLAS_TRANSPOSE.CblasTrans
                && Uplo == CBLAS_UPLO.CblasUpper)
                       || (order == CBLAS_ORDER.CblasColMajor && Trans == CBLAS_TRANSPOSE.CblasNoTrans
                && Uplo == CBLAS_UPLO.CblasLower))
            {

                /* form  x := inv( A' )*x */

                /* forward substitution */
                ix = 0;
                if (nonunit)
                {
                    x[ix] = x[ix] / A[0, 0];
                }
                ix++;
                for (i = 1; i < N; i++)
                {
                    double tmp = x[ix];
                    jx = 0;
                    for (j = 0; j < i; j++)
                    {
                        double Aji = A[j, i];
                        tmp -= Aji * x[jx];
                        jx++;
                    }
                    if (nonunit)
                    {
                        x[ix] = tmp / A[i, i];
                    }
                    else
                    {
                        x[ix] = tmp;
                    }
                    ix++;
                }
            }
            else if ((order == CBLAS_ORDER.CblasRowMajor && Trans == CBLAS_TRANSPOSE.CblasTrans
                && Uplo == CBLAS_UPLO.CblasLower)
                       || (order == CBLAS_ORDER.CblasColMajor && Trans == CBLAS_TRANSPOSE.CblasNoTrans
                && Uplo == CBLAS_UPLO.CblasUpper))
            {

                /* backsubstitution */
                ix = N - 1;
                if (nonunit)
                {
                    x[ix] = x[ix] / A[(N - 1), (N - 1)];
                }
                ix--;
                for (i = N - 1; i > 0 && (i-- > 0); )
                {
                    double tmp = x[ix];
                    jx = ix + 1;
                    for (j = i + 1; j < N; j++)
                    {
                        double Aji = A[j, i];
                        tmp -= Aji * x[jx];
                        jx++;
                    }
                    if (nonunit)
                    {
                        x[ix] = tmp / A[i, i];
                    }
                    else
                    {
                        x[ix] = tmp;
                    }
                    ix--;
                }
            }
            else
            {
                PZMath_errno.ERROR("PZMath_blas::Dtrsv(), unrecognized operation");
            }
            return PZMath_errno.PZMath_SUCCESS;
        }
Exemple #20
0
 // rescale X by the multicative factor alpha, X = alpha * X
 public static void Dscal(double alpha, PZMath_vector X)
 {
     for (int i = 0; i < X.Size; i ++)
         X[i] = alpha * X[i];
 }
Exemple #21
0
        // return Norm 2 of vector f i.e. Sqrt(Sum(f[i] ^ 2))
        public static double Dnrm2(PZMath_vector f)
        {
            double scale = 0.0;
            double ssq = 1.0;
            int i;

            if (f.Size <= 0 || f.stride <= 0)
            {
                return 0;
            }
            else if (f.size == 1)
            {
                return System.Math.Abs(f[0]);
            }

            for (i = 0; i < f.size; i++)
            {
                double x = f[i];

                if (x != 0.0)
                {
                    double ax = System.Math.Abs(x);

                    if (scale < ax)
                    {
                        ssq = 1.0 + ssq * (scale / ax) * (scale / ax);
                        scale = ax;
                    }
                    else
                    {
                        ssq += (ax / scale) * (ax / scale);
                    }
                }
            }

            return scale * System.Math.Sqrt(ssq);
        }
Exemple #22
0
        // These functions compute the matrix-vector product and sum
        // y = \alpha op(A) x + \beta y,
        // where op(A) = A, A^T, A^H for method =
        // 0 - CblasNoTrans,
        // 1 - CblasTrans
        public static int Dgemv(int method, double alpha, PZMath_matrix A, PZMath_vector X, double beta, PZMath_vector Y)
        {
            int M = A.RowCount;
            int N = A.ColumnCount;

            if ((method == 0 && N == X.Size && M == Y.Size)
                || (method == 1 && M == X.Size && N == Y.Size))
            {
                if (method == 0)
                    // no trans
                {
                    for (int i = 0; i < M; i ++)
                        // each element of Y
                    {
                        double temp = 0;
                        for (int j = 0; j < N; j ++)
                            // each element of A
                            temp += A[i, j] * X[j];
                        Y[i] = alpha * temp + beta * Y[i];
                    }
                }
                else
                    // trans
                {
                    for (int i = 0; i < N; i ++)
                        // each element of Y
                    {
                        double temp = 0;
                        for (int j = 0; j < M; j ++)
                            // each element of A
                            temp += A[j, i] * X[j];
                        Y[i] = alpha * temp + beta * Y[i];
                    }
                }
                return PZMath_errno.PZMath_SUCCESS;
            }
            else
            {
                PZMath_errno.ERROR ("PZMath_blas::Dgemv(), invalid length", PZMath_errno.PZMath_EBADLEN);
                return 0;
            }
        }
        public static void TestNonlinearLeastSquareFit()
        {
            PZMath_multifit_fdfsolver_type T = new PZMath_multifit_fdfsolver_type();
            PZMath_multifit_fdfsolver s = new PZMath_multifit_fdfsolver();

            int N = 40;
            int status;
            int i, iter = 0;

            int n = N;
            int p = 3;

            PZMath_matrix covar = new PZMath_matrix(p, p);

            double[] y = new double[N];
            double[] sigma = new double[N];
            double h = 1e-2; // step-size
            TestNonlinearLeastSquareFitParam d = new TestNonlinearLeastSquareFitParam(n, p, y, sigma, h);
            PZMath_multifit_function_fdf f = new PZMath_multifit_function_fdf();

            double[] x_init = new double[3];
            x_init[0] = 1.0;
            x_init[1] = 0.0;
            x_init[2] = 0.0;
            PZMath_vector x = new PZMath_vector(x_init);

            f.f = new multifit_delegate_f(TestPZMathMultifit.expb_f);
            f.df = new multifit_delegate_df(TestPZMathMultifit.expb_df);
            f.fdf = new multifit_delegate_fdf(TestPZMathMultifit.expb_fdf);
            f.n = n;
            f.p = p;
            f.parms = d;

            ParkMillerNormal r = new ParkMillerNormal();
            // this is the data to be fiitted
            for (i = 0; i < n; i++)
            {
                double t = i;
                double tt = System.Math.Exp(-0.1 * t);
                d.y[i] = 1.0 + 5 * System.Math.Exp(-0.1 * t);// + r.NextVariate();
                d.sigma[i] = 0.1;
                System.Diagnostics.Debug.WriteLine("data: " + i + " " + d.y[i] + " " + d.sigma[i]);
            }

            T.Init("PZMath_multifit_fdfsolver_lmsder");
            s.Alloc(T, n, p);
            s.Init(f, x);

            s.PrintState(iter);

            do
            {
                iter++;
                status = s.Iterate();
                System.Diagnostics.Debug.WriteLine("status = " + status);

                //printf ("status = %s \n", gsl_strerror(status));

                s.PrintState(iter);

                if (status > 0)
                    break;

                status = s.TestDelta(s.dx, s.x, 1e-4, 1e-4);
            }
            while (status == PZMath_errno.PZMath_CONTINUE && iter < 500);

            s.Covar(0.0, covar);
            covar.DebugWriteLine();

            System.Console.WriteLine("A = " + s.FIT(0) + " +/- " + s.ERR(0, covar));
            System.Console.WriteLine("lambda = " + s.FIT(1) + " +/- " + s.ERR(1, covar));
            System.Console.WriteLine("b = " + s.FIT(2) + " +/- " + s.ERR(2, covar));

            double chi = s.Chi();
            System.Console.WriteLine("chisq/dof = " + (System.Math.Pow(chi, 2.0) / (double)(n - p)));
            System.Console.WriteLine("state = " + status);

            //printf ("status = %s \n", gsl_strerror(status));
        }
 public double FN_EVAL(PZMath_vector x)
 {
     return f(x, parms);
 }
Exemple #25
0
 //This function copies the elements of the i-th row of the matrix m
 // into the vector v.
 // The length of the vector must be the same as the length of the row.
 public void CopyRow2(int indexRow, PZMath_vector v)
 {
     if (indexRow < 0 || indexRow > row)
     {
         PZMath_errno.ERROR("PZMath_matrix::GetRow(), Index Out Of Range", PZMath_errno.PZMath_EFAILED);
     }
     if (v.size != col)
         PZMath_errno.ERROR("PZMath_matrix::GetRow(), vector does not match the row");
     for (int i = 0; i < col; i ++)
         v[i] = this[indexRow, i];
 }
 public static int expb_fdf(PZMath_vector x, object param, PZMath_vector f, PZMath_matrix J)
 {
     expb_f(x, param, f);
     expb_df(x, param, J);
     return PZMath_errno.PZMath_SUCCESS;
 }
        public static int Iterate(object vstate, PZMath_multimin_function f,
            PZMath_vector x, out double size, out double fval)
        {
            /* Simplex iteration tries to minimize function f value */
            /* Includes corrections from Ivo Alxneit <*****@*****.**> */

            /* xc and xc2 vectors store tried corner point coordinates */

            PZMath_vector xc = (vstate as nmsimplex_state_t).ws1;
            PZMath_vector xc2 = (vstate as nmsimplex_state_t).ws2;
            PZMath_vector y1 = (vstate as nmsimplex_state_t).y1;
            PZMath_matrix x1 = (vstate as nmsimplex_state_t).x1;

            int n = y1.size;
            int i;
            int hi = 0, s_hi = 0, lo = 0;
            double dhi, ds_hi, dlo;
            int status;
            double val, val2;

            /* get index of highest, second highest and lowest point */

            dhi = ds_hi = dlo = y1[0];

            for (i = 1; i < n; i++)
            {
                val = y1[i];
                if (val < dlo)
                {
                    dlo = val;
                    lo = i;
                }
                else if (val > dhi)
                {
                    ds_hi = dhi;
                    s_hi = hi;
                    dhi = val;
                    hi = i;
                }
                else if (val > ds_hi)
                {
                    ds_hi = val;
                    s_hi = i;
                }
            }

            /* reflect the highest value */
            val = MoveCorner (-1.0, vstate as nmsimplex_state_t, hi, xc, f);

            if (val < y1[lo])
            {

                /* reflected point becomes lowest point, try expansion */
                val2 = MoveCorner (-2.0, vstate as nmsimplex_state_t, hi, xc2, f);

                if (val2 < y1[lo])
                {
                    x1.SetRow(hi, xc2);
                    y1[hi] = val2;
                }
                else
                {
                    x1.SetRow(hi, xc);
                    y1[hi] = val;
                }
            }

                /* reflection does not improve things enough */

            else if (val > y1[s_hi])
            {
                if (val <= y1[hi])
                {

                    /* if trial point is better than highest point, replace
                       highest point */
                    x1.SetRow(hi, xc);
                    y1[hi] = val;
                }

                /* try one dimensional contraction */
                val2 = MoveCorner (0.5, vstate as nmsimplex_state_t, hi, xc2, f);

                if (val2 <= y1[hi])
                {
                    x1.SetRow(hi, xc2);
                    y1[hi] = val2;
                }

                else
                {

                    /* contract the whole simplex in respect to the best point */
                    status = ContractByBest (vstate as nmsimplex_state_t, lo, xc, f);
                    if (status != 0)
                    {
                        PZMath_errno.ERROR("nmsimplex::Iterate(), nmsimplex_contract_by_best failed", PZMath_errno.PZMath_FAILURE);
                    }
                }
            }
            else
            {

                /* trial point is better than second highest point.
                   Replace highest point by it */

                x1.SetRow(hi, xc);
                y1[hi] = val;
            }

            /* return lowest point of simplex as x */

            lo = y1.MinIndex();
            x1.CopyRow2(lo, x);
            fval = y1[lo];

            /* Update simplex size */

            size = Size (vstate as nmsimplex_state_t);

            return PZMath_errno.PZMath_SUCCESS;
        }
 public int Init(PZMath_multimin_function f, PZMath_vector x, PZMath_vector step_size)
 {
     this.f = f;
     this.x.MemCopyFrom(x);
     return type.init(state, this.f, this.x, out this.size, step_size);
 }
        // fit data from y = exp(x), x :[0 : 2]
        public static void TestLinearLeastSquareFit()
        {
            int i, n;
            n = 19;

            // -- prepare model parameters
            double xi, yi, chisq;
            PZMath_matrix X, cov;
            PZMath_vector y, w, c;

            X = new PZMath_matrix(n, 3);
            y = new PZMath_vector(n);
            w = new PZMath_vector(n);

            c = new PZMath_vector(3);
            cov = new PZMath_matrix(3, 3);

            // -- data to be fitted
            //PZMath_random_ParkMiller_Normal r = new PZMath_random_ParkMiller_Normal();
            for (i = 0; i < n; i++)
            {
                xi = 0.1 + 0.1 * i;
                yi = System.Math.Exp(xi);	// f(x)
                System.Console.WriteLine(xi + " " + yi);

                X[i, 0] = 1.0;
                X[i, 1] = xi;
                X[i, 2] = xi * xi;
                y[i] = yi;
                w[i] = 1.0;
            }
            PZMath_multifit_linear l = new PZMath_multifit_linear();
            l.Alloc(n, 3);
            l.Wlinear(X, w, y, c, cov, out chisq);

            System.Console.WriteLine("# best fit: Y = " + c[0] + " + " + c[1] + " X + " + c[2] + " X ^ 2");
            System.Console.WriteLine("# covariance matrix:");
            cov.ScreenWriteLine();
            System.Console.WriteLine("# chisq = " + chisq);
        }
        public static int Init(object vstate, PZMath_multimin_function f, PZMath_vector x, 
            out double size, PZMath_vector step_size)
        {
            int i;
            double val;
            PZMath_vector xtemp = (vstate as nmsimplex_state_t).ws1;

            /* first point is the original x0 */
            val = f.FN_EVAL(x);

            (vstate as nmsimplex_state_t).x1.SetRow(0, x);
            (vstate as nmsimplex_state_t).y1[0] = val;

            /* following points are initialized to x0 + step_size */

            for (i = 0; i < x.size; i++)
            {
                xtemp.MemCopyFrom(x);
                val = xtemp[i] + step_size[i];
                xtemp[i] = val;
                val = f.FN_EVAL(xtemp);
                (vstate as nmsimplex_state_t).x1.SetRow(i + 1, xtemp);
                (vstate as nmsimplex_state_t).y1[i + 1] = val;
            }

            /* Initialize simplex size */
            size = Size (vstate as nmsimplex_state_t);

            return PZMath_errno.PZMath_SUCCESS;
        }