/** \file lbfgs_method.hpp \brief large bfgs method, used to perform large scale optimization \author Junhua Gu */ #ifndef LBFGS_METHOD #define LBFGS_METHOD #define OPT_HEADER #include //#include #include #include #include #include "../linmin/linmin.hpp" #include #include #include #include #include #include #include "lbfgs.h" #include "lbfgs.cpp" /* * */ #include using std::cerr; using std::endl; namespace opt_utilities { template lbfgsfloatval_t lbfgs_adapter( void *instance, const lbfgsfloatval_t *x, lbfgsfloatval_t *g, const int n, const lbfgsfloatval_t step ) { pT px; resize(px,n); for(int i=0;i*)instance)->eval(px); pT grad(gradient(*static_cast*>(instance),px)); for(int i=0;i class lbfgs_method :public opt_method { public: typedef pT array1d_type; typedef rT T; private: func_obj* p_fo; optimizer* p_optimizer; //typedef blitz::Array array2d_type; 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); } const char* do_get_type_name()const { return "large scale bfgs"; } public: lbfgs_method() :threshold(1e-4) {} virtual ~lbfgs_method() { }; lbfgs_method(const lbfgs_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) { } lbfgs_method& operator=(const lbfgs_method& rhs) { threshold=rhs.threshold; p_fo=rhs.p_fo; p_optimizer=rhs.p_optimizer; opt_eq(start_point,rhs.start_point); opt_eq(end_point,rhs.end_point); } opt_method* do_clone()const { return new lbfgs_method(*this); } void do_set_start_point(const array1d_type& p) { start_point.resize(get_size(p)); opt_eq(start_point,p); } array1d_type do_get_start_point()const { return start_point; } 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() { lbfgs_parameter_t param; lbfgs_parameter_init(¶m); param.ftol=threshold; std::vector buffer(get_size(start_point)); for(int i=0;i,0,p_fo,¶m); for(int i=0;i