⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 optimize.h

📁 使用R语言的马尔科夫链蒙特卡洛模拟(MCMC)源代码程序。
💻 H
📖 第 1 页 / 共 3 页
字号:
    T alpha_last = (T) 0.0;    T alpha_cur = (T) 1.0;    T alpha_max = (T) 10.0;    T c1 = (T) 1e-4;    T c2 = (T) 0.5;    unsigned int max_iter = 50;    T fgradalpha0 = gradfdifls(fun, (T) 0, theta, p);    for (unsigned int i = 0; i < max_iter; ++i) {      T phi_cur = fun(theta + alpha_cur * p);      T phi_last = fun(theta + alpha_last * p);           if ((phi_cur > (fun(theta) + c1 * alpha_cur * fgradalpha0))          || ((phi_cur >= phi_last) && (i > 0))) {        T alphastar = zoom(fun, alpha_last, alpha_cur, theta, p);        return alphastar;      }      T fgradalpha_cur = gradfdifls(fun, alpha_cur, theta, p);      if (std::fabs(fgradalpha_cur) <= -1 * c2 * fgradalpha0)        return alpha_cur;      if ( fgradalpha_cur >= (T) 0.0) {        T alphastar = zoom(fun, alpha_cur, alpha_last, theta, p);        return alphastar;      }            alpha_last = alpha_cur;      // runif stuff below is probably not correc KQ 12/08/2006      // I think it should work now DBP 01/02/2007      alpha_cur = runif() * (alpha_max - alpha_cur) + alpha_cur;    }    return 0.001;  }   /*! \brief Find minimum of a function once bracketed.    *    * This function finds the minimum of a function, once bracketed.    *    * \param fun The function to minimize.  This function should take    * one Matrix (vector) argument of type T and return a single value    * of type T.    * \param alpha_lo The lower bracket.    * \param alpha_hi The upper bracket.    * \param theta A column vector of parameter values that anchor the    * 1-dimensional function.    * \param p A direction vector that creates the 1-dimensional    *    * \see linesearch1(FUNCTOR fun, const Matrix<T,PO1,PS1>& theta, const Matrix<T,PO2,PS2>& p)    * \see linesearch2(FUNCTOR fun, const Matrix<T,PO1,PS1>& theta, const Matrix<T,PO2,PS2>& p, rng<RNGTYPE>& runif)    * \see BFGS(FUNCTOR fun, const Matrix<T,PO,PS>& theta, rng<RNGTYPE>& runif, unsigned int maxit, T tolerance, bool trace = false)    *    * \throw scythe_dimension_error (Level 1)    *    * \note    * Users will typically wish to implement \a fun in terms of a    * functor.  Using a functor provides a generic way in which to    * evaluate functions with more than one parameter.  Furthermore,    * although one can pass a function pointer to this routine,    * the compiler cannot inline and fully optimize code    * referenced by function pointers.    *     */  template <typename T, matrix_order PO1, matrix_style PS1,            matrix_order PO2, matrix_style PS2, typename FUNCTOR>  T zoom (FUNCTOR fun, T alpha_lo, T alpha_hi,          const Matrix<T,PO1,PS1>& theta, const Matrix<T,PO2,PS2>& p)  {    SCYTHE_CHECK_10(! theta.isColVector(), scythe_dimension_error,        "Theta not column vector");    SCYTHE_CHECK_10(! p.isColVector(), scythe_dimension_error,        "p not column vector");    T alpha_j = (alpha_lo + alpha_hi) / 2.0;    T phi_0 = fun(theta);    T c1 = (T) 1e-4;    T c2 = (T) 0.5;    T fgrad0 = gradfdifls(fun, (T) 0, theta, p);    unsigned int count = 0;    unsigned int maxit = 20;    while(count < maxit) {      T phi_j = fun(theta + alpha_j * p);      T phi_lo = fun(theta + alpha_lo * p);           if ((phi_j > (phi_0 + c1 * alpha_j * fgrad0))          || (phi_j >= phi_lo)){        alpha_hi = alpha_j;      } else {        T fgradj = gradfdifls(fun, alpha_j, theta, p);        if (std::fabs(fgradj) <= -1 * c2 * fgrad0){           return alpha_j;        }        if ( fgradj * (alpha_hi - alpha_lo) >= 0){          alpha_hi = alpha_lo;        }        alpha_lo = alpha_j;      }      ++count;    }       return alpha_j;  }   /*! \brief Find function minimum using the BFGS algorithm.    *    * Numerically find the minimum of a function using the BFGS    * algorithm.    *    * \param fun The function to minimize.  This function should take    * one Matrix (vector) argument of type T and return a single value    * of type T.    * \param theta A column vector of parameter values that anchor the    * 1-dimensional function.    * \param runif A random uniform number generator function object    * (an object that returns a random uniform variate on (0,1) when    * its () operator is invoked).    * \param maxit The maximum number of iterations.    * \param tolerance The convergence tolerance.    * \param trace Boolean value determining whether BFGS should print     *              to stdout (defaults to false).    *    * \see linesearch1(FUNCTOR fun, const Matrix<T,PO1,PS1>& theta, const Matrix<T,PO2,PS2>& p)    * \see linesearch2(FUNCTOR fun, const Matrix<T,PO1,PS1>& theta, const Matrix<T,PO2,PS2>& p, rng<RNGTYPE>& runif)    * \see zoom(FUNCTOR fun, T alpha_lo, T alpha_hi, const Matrix<T,PO1,PS1>& theta, const Matrix<T,PO2,PS2>& p)    *    * \throw scythe_dimension_error (Level 1)    * \throw scythe_convergence_error (Level 0)    *    * \note    * Users will typically wish to implement \a fun in terms of a    * functor.  Using a functor provides a generic way in which to    * evaluate functions with more than one parameter.  Furthermore,    * although one can pass a function pointer to this routine,    * the compiler cannot inline and fully optimize code    * referenced by function pointers.    */  // there were 2 versions of linesearch1-- the latter was what we  // had been calling linesearch2  template <matrix_order RO, matrix_style RS, typename T,             matrix_order PO, matrix_style PS,            typename FUNCTOR, typename RNGTYPE>  Matrix<T,RO,RS>  BFGS (FUNCTOR fun, const Matrix<T,PO,PS>& theta, rng<RNGTYPE>& runif,         unsigned int maxit, T tolerance, bool trace = false)  {    SCYTHE_CHECK_10(! theta.isColVector(), scythe_dimension_error,        "Theta not column vector");    unsigned int n = theta.size();    // H is initial inverse hessian    Matrix<T,RO> H = inv(hesscdif(fun, theta));    // gradient at starting values    Matrix<T,RO> fgrad = gradfdif(fun, theta);    Matrix<T,RO> thetamin = theta;    Matrix<T,RO> fgrad_new = fgrad;    Matrix<T,RO> I = eye<T,RO>(n);     Matrix<T,RO> s;    Matrix<T,RO> y;    unsigned int count = 0;    while( (t(fgrad_new)*fgrad_new)[0] > tolerance) {      Matrix<T> p = -1.0 * H * fgrad;      //std::cout << "initial H * fgrad = " << H * fgrad << "\n";      //std::cout << "initial p = " << p << "\n";      T alpha = linesearch2(fun, thetamin, p, runif);      //T alpha = linesearch1(fun, thetamin, p);      //std::cout << "after linesearch p = " << p << "\n";      Matrix<T> thetamin_new = thetamin + alpha * p;      fgrad_new = gradfdif(fun, thetamin_new);      s = thetamin_new - thetamin;      y = fgrad_new - fgrad;      T rho = 1.0 / (t(y) * s)[0];      H = (I - rho * s * t(y)) * H *(I - rho * y * t(s))        + rho * s * t(s);      thetamin = thetamin_new;      fgrad = fgrad_new;      ++count;      if (trace){	std::cout << "BFGS iteration = " << count << std::endl;	std::cout << "thetamin = " << (t(thetamin)) ;	std::cout << "gradient = " << (t(fgrad)) ;	std::cout << "t(gradient) * gradient = " << 	  (t(fgrad) * fgrad) ;	std::cout << "function value = " << fun(thetamin) << 	  std::endl << std::endl;      }      //std::cout << "Hessian = " << hesscdif(fun, theta) << "\n";      //std::cout << "H = " << H << "\n";      //std::cout << "alpha = " << alpha << std::endl;      //std::cout << "p = " << p << "\n";      //std::cout << "-1 * H * fgrad = " << -1.0 * H * fgrad << "\n";      SCYTHE_CHECK(count > maxit, scythe_convergence_error,          "Failed to converge.  Try better starting values");    }       return thetamin;  }  // Default template  template <typename T, matrix_order O, matrix_style S,            typename FUNCTOR, typename RNGTYPE>  Matrix<T,O,Concrete>  BFGS (FUNCTOR fun, const Matrix<T,O,S>& theta, rng<RNGTYPE>& runif,        unsigned int maxit, T tolerance, bool trace = false)  {    return BFGS<O,Concrete> (fun, theta, runif, maxit, tolerance, trace);  }    /* Solves a system of n nonlinear equations in n unknowns of the form   * fun(thetastar) = 0 for thetastar given the function, starting    * value theta, max number of iterations, and tolerance.   * Uses Broyden's method.   */   /*! \brief Solve a system of nonlinear equations.    *    * Solves a system of n nonlinear equations in n unknowns of the form    * \f$fun(\theta^*) = 0\f$ for \f$\theta^*\f$.    *    * \param fun The function to solve.  The function should both take    * and return a Matrix of type T.    * \param theta A column vector of parameter values at which to    * start the solve procedure.    * \param maxit The maximum number of iterations.    * \param tolerance The convergence tolerance.    *    * \throw scythe_dimension_error (Level 1)    * \throw scythe_convergence_error (Level 1)    *    * \note    * Users will typically wish to implement \a fun in terms of a    * functor.  Using a functor provides a generic way in which to    * evaluate functions with more than one parameter.  Furthermore,    * although one can pass a function pointer to this routine,    * the compiler cannot inline and fully optimize code    * referenced by function pointers.    */  template <matrix_order RO, matrix_style RS, typename T,            matrix_order PO, matrix_style PS, typename FUNCTOR>  Matrix<T,RO,RS>  nls_broyden(FUNCTOR fun, const Matrix<T,PO,PS>& theta,              unsigned int maxit = 5000, T tolerance = 1e-6)  {    SCYTHE_CHECK_10(! theta.isColVector(), scythe_dimension_error,        "Theta not column vector");    Matrix<T,RO> thetastar = theta;    Matrix<T,RO> B = jacfdif(fun, thetastar);    Matrix<T,RO> fthetastar;    Matrix<T,RO> p;    Matrix<T,RO> thetastar_new;    Matrix<T,RO> fthetastar_new;    Matrix<T,RO> s;    Matrix<T,RO> y;    for (unsigned int i = 0; i < maxit; ++i) {      fthetastar = fun(thetastar);      p = lu_solve(B, -1 * fthetastar);      T alpha = (T) 1.0;      thetastar_new = thetastar + alpha*p;      fthetastar_new = fun(thetastar_new);      s = thetastar_new - thetastar;      y = fthetastar_new - fthetastar;      B = B + ((y - B * s) * t(s)) / (t(s) * s);      thetastar = thetastar_new;      if (max(fabs(fthetastar_new)) < tolerance)        return thetastar;    }     SCYTHE_THROW_10(scythe_convergence_error,  "Failed to converge.  Try better starting values or increase maxit");    return thetastar;  }  // default template  template <typename T, matrix_order O, matrix_style S,            typename FUNCTOR>  Matrix<T,O,Concrete>  nls_broyden (FUNCTOR fun, const Matrix<T,O,S>& theta,               unsigned int maxit = 5000, T tolerance = 1e-6)  {    return nls_broyden<O,Concrete>(fun, theta, maxit, tolerance);  }} // namespace scythe#endif /* SCYTHE_OPTIMIZE_H */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -