/** \file conjugate_gradient.hpp \brief conjugate gradient optimization method \author Junhua Gu */ #ifndef CONJUGATE_GRADIENT #define CONJUGATE_GRADIENT #define OPT_HEADER #include //#include #include #include #include #include "../linmin/linmin.hpp" #include #include #include namespace opt_utilities { /** \brief Impliment of an optimization method \tparam rT return type of the object function \tparam pT parameter type of the object function */ template class conjugate_gradient :public opt_method { public: typedef pT array1d_type; typedef rT T; private: func_obj* p_fo; optimizer* p_optimizer; volatile bool bstop; const char* do_get_type_name()const { return "conjugate gradient"; } private: array1d_type start_point; array1d_type end_point; private: rT threshold; private: rT func(const pT& x) { assert(p_fo!=0); return p_fo->eval(x); } private: public: conjugate_gradient() :threshold(1e-4) {} virtual ~conjugate_gradient() { }; conjugate_gradient(const conjugate_gradient& rhs) :opt_method(rhs),p_fo(rhs.p_fo),p_optimizer(rhs.p_optimizer), start_point(rhs.start_point), end_point(rhs.end_point), threshold(rhs.threshold) { } conjugate_gradient& operator=(const conjugate_gradient& rhs) { threshold=rhs.threshold; p_fo=rhs.p_fo; p_optimizer=rhs.p_optimizer; start_point=rhs.start_point; end_point=rhs.end_point; threshold=rhs.threshold; } opt_method* do_clone()const { return new conjugate_gradient(*this); } void do_set_start_point(const array1d_type& p) { resize(start_point,get_size(p)); opt_eq(start_point,p); } array1d_type do_get_start_point()const { return start_point; } void do_set_lower_limit(const array1d_type& p) {} void do_set_upper_limit(const array1d_type& p) {} void do_set_precision(rT t) { threshold=t; } rT do_get_precision()const { return threshold; } void do_set_optimizer(optimizer& o) { p_optimizer=&o; p_fo=p_optimizer->ptr_func_obj(); } pT do_optimize() { bstop=false; opt_eq(end_point,start_point); pT xn; opt_eq(xn,start_point); pT Delta_Xn1(gradient(*p_fo,start_point)); for(size_t i=0;i