From 4e6cebbb431222a5d8fa3bc62d5de44c93c8a93e Mon Sep 17 00:00:00 2001 From: astrojhgu Date: Sat, 22 Aug 2009 09:40:53 +0000 Subject: git-svn-id: file:///home/svn/opt_utilities@48 ed2142bd-67ad-457f-ba7c-d818d4011675 --- core/fitter.hpp | 296 +++++++++++++++++++++++++++++++++++++++++++------ core/freeze_param.hpp | 47 +++++++- core/num_diff.hpp | 31 ++++++ core/opt_exception.hpp | 43 +++++++ core/opt_traits.hpp | 61 ++++++++-- core/optimizer.hpp | 3 + 6 files changed, 434 insertions(+), 47 deletions(-) (limited to 'core') diff --git a/core/fitter.hpp b/core/fitter.hpp index 87e316e..2dff97b 100644 --- a/core/fitter.hpp +++ b/core/fitter.hpp @@ -897,6 +897,7 @@ namespace opt_utilities return do_eval(x,reform_param(p)); } + private: virtual Ty do_eval(const Tx& x,const Tp& p)=0; private: @@ -908,21 +909,35 @@ namespace opt_utilities }; - + /** + class to perform the model fitting + \tparam Ty the type of the model return type + \tparam Tx the type of the model self-var + \tparam Tp the type of the model param + \tparam Ts statistic type + \tparam Tstr the type of string used + */ template class fitter { - public: + private: model* p_model; statistic* p_statistic; data_set* p_data_set; optimizer optengine; public: + + /** + default construct function + */ fitter() :p_model(0),p_statistic(0),p_data_set(0),optengine() {} + /** + copy construct function + */ fitter(const fitter& rhs) :p_model(0),p_statistic(0),p_data_set(0),optengine() { @@ -942,6 +957,10 @@ namespace opt_utilities optengine=rhs.optengine; } + + /** + assignment operator + */ fitter& operator=(const fitter& rhs) { if(this==&rhs) @@ -964,6 +983,10 @@ namespace opt_utilities return *this; } + + /** + destruct function + */ virtual ~fitter() { if(p_model!=0) @@ -984,6 +1007,9 @@ namespace opt_utilities } + /** + evaluate the model + */ Ty eval_model(const Tx& x,const Tp& p) { if(p_model==0) @@ -1004,6 +1030,11 @@ namespace opt_utilities public: + + /** + set the model + \param m model to be used + */ void set_model(const model& m) { if(p_model!=0) @@ -1015,12 +1046,12 @@ namespace opt_utilities //p_model=&m; // current_param.resize(m.get_num_params()); } - /* - void set(const model& m) - { - set_model(m); - } - */ + + + /** + set the statistic (e.g., chi square, least square c-statistic etc.) + \param s statistic to be used + */ void set_statistic(const statistic& s) { if(p_statistic!=0) @@ -1032,13 +1063,11 @@ namespace opt_utilities //p_statistic=&s; p_statistic->set_fitter(*this); } - /* - void set(const statistic& s) - { - set_statistic(s); - } - */ + /** + set parameter modifier + \param pm parameter modifier to be used + */ void set_param_modifier(const param_modifier& pm) { if(p_model==0) @@ -1048,6 +1077,9 @@ namespace opt_utilities p_model->set_param_modifier(pm); } + /** + clear the param modifier + */ void set_param_modifier() { if(p_model==0) @@ -1057,6 +1089,11 @@ namespace opt_utilities p_model->set_param_modifier(); } + + /** + Get the inner kept param modifier + \return the reference of param_modifier + */ param_modifier& get_param_modifier() { if(p_model==0) @@ -1066,6 +1103,11 @@ namespace opt_utilities return p_model->get_param_modifier(); } + /** + report the status of a parameter + \param s the name of a parameter + \return string used to describe the parameter + */ Tstr report_param_status(const Tstr& s)const { if(p_model==0) @@ -1075,11 +1117,9 @@ namespace opt_utilities return p_model->report_param_status(s); } - /* - void set(const param_modifier& pm) - { - set_param_modifier(pm); - } + /** + load the data set + \param da a data set */ void load_data(const data_set& da) { @@ -1095,6 +1135,11 @@ namespace opt_utilities } } + + /** + get the data set that have been loaded + \return the const reference of inner data_set + */ const data_set& get_data_set()const { if(p_data_set==0) @@ -1104,6 +1149,10 @@ namespace opt_utilities return *(this->p_data_set); } + /** + Get the model used + \return the reference of model used + */ model& get_model() { if(p_model==0) @@ -1113,6 +1162,10 @@ namespace opt_utilities return *(this->p_model); } + /** + Get the statistic used + \return the reference of the statistic used + */ statistic& get_statistic() { if(p_statistic==0) @@ -1121,7 +1174,11 @@ namespace opt_utilities } return *(this->p_statistic); } - + + /** + Get the optimization method that used + \return the reference of the opt_method + */ opt_method& get_method() { return optengine.method(); @@ -1129,6 +1186,11 @@ namespace opt_utilities public: + /** + set the value of a parameter + \param pname the name of the parameter + \param v the value of the parameter + */ void set_param_value(const Tstr& pname, const typename element_type_trait::element_type& v) { @@ -1139,6 +1201,11 @@ namespace opt_utilities p_model->set_param_value(pname,v); } + /** + set the lower limit of a parameter + \param pname the name of the parameter + \param v the lower limit of the parameter + */ void set_param_lower_limit(const Tstr& pname, const typename element_type_trait::element_type& v) { @@ -1149,6 +1216,11 @@ namespace opt_utilities p_model->set_param_lower_limit(pname,v); } + /** + set the upper limit of a parameter + \param pname the name of the parameter + \param v the upper limit of the parameter + */ void set_param_upper_limit(const Tstr& pname, const typename element_type_trait::element_type& v) { @@ -1160,6 +1232,11 @@ namespace opt_utilities } + /** + set the values of all parameters + \param param the vector containing the value of all parameters + */ + void set_param_value(const Tp& param) { if(p_model==0) @@ -1169,6 +1246,10 @@ namespace opt_utilities p_model->set_param_value(param); } + /** + set the lower limits of all parameters + \param param the vector containing the lower limits of all parameters + */ void set_param_lower_limit(const Tp& param) { if(p_model==0) @@ -1178,6 +1259,10 @@ namespace opt_utilities p_model->set_param_lower_limit(param); } + /** + set the upper limits of all parameters + \param param the vector containing the upper limits of all parameters + */ void set_param_upper_limit(const Tp& param) { if(p_model==0) @@ -1187,6 +1272,12 @@ namespace opt_utilities p_model->set_param_upper_limit(param); } + + /** + get the parameter value + \param pname the name of the parameter + \return the value of the parameter + */ typename element_type_trait::element_type get_param_value(const Tstr& pname)const { if(p_model==0) @@ -1196,6 +1287,11 @@ namespace opt_utilities return p_model->get_param_info(pname).get_value(); } + /** + get the lower limit of a parameter + \param pname the name of a parameter + \return the lower limit of a parameter + */ typename element_type_trait::element_type get_param_lower_limit(const Tstr& pname)const { if(p_model==0) @@ -1205,6 +1301,11 @@ namespace opt_utilities return p_model->get_param_info(pname).get_lower_limit(); } + /** + get the upper limit of a parameter + \param pname the name of a parameter + \return the upper limit of a parameter + */ typename element_type_trait::element_type get_param_upper_limit(const Tstr& pname)const { if(p_model==0) @@ -1215,7 +1316,11 @@ namespace opt_utilities } - + /** + get the param_info of a parameter + \param pname the name of the parameter + \return the const reference of a param_info object + */ const param_info& get_param_info(const Tstr& pname)const { if(p_model==0) @@ -1224,7 +1329,12 @@ namespace opt_utilities } return p_model->get_param_info(pname); } - + + /** + get the param_info of a parameter by its order + \param n the order of the parameter + \return the const reference of a param_info object + */ const param_info& get_param_info(size_t n)const { if(p_model==0) @@ -1234,6 +1344,11 @@ namespace opt_utilities return p_model->get_param_info(n); } + /** + get the order of a parameter by its name + \param pname the name of the parameter + \return the order of the parameter + */ size_t get_param_order(const Tstr& pname)const { if(p_model==0) @@ -1243,6 +1358,10 @@ namespace opt_utilities return p_model->get_param_order(pname); } + /** + get the number of parameters + \return the number of parameters + */ size_t get_num_params()const { if(p_model==0) @@ -1252,6 +1371,10 @@ namespace opt_utilities return p_model->get_num_params(); } + /** + get all params + \return the vector containing the values of all parameters + */ Tp get_all_params()const { if(p_model==0) @@ -1262,22 +1385,29 @@ namespace opt_utilities return p_model->get_all_params(); } + /** + set the optimization method used to perform the model fitting + \param pm the opt_method to be used + */ void set_method(const opt_method& pm) { //assert(p_optimizer!=0); optengine.set_opt_method(pm); } - /* - void set(const opt_method& pm) - { - set_method(pm); - } - */ + + /** + set the precision + \param y the precision + */ void set_precision(typename element_type_trait::element_type y) { optengine.set_precision(y); } + + /** + perform the fitting + */ Tp fit() { // assert(p_model!=0); @@ -1345,11 +1475,20 @@ namespace opt_utilities }; + + /** + virtual class representing a statistic + \tparam Ty the type of the model return type + \tparam Tx the type of the model self-var + \tparam Tp the type of the model param + \tparam Ts statistic type + \tparam Tstr the type of string used + */ template class statistic :public func_obj { - public: + private: fitter* p_fitter; private: @@ -1361,23 +1500,40 @@ namespace opt_utilities } public: + /** + clone the existing object + \return the clone of self + */ statistic* clone()const { return this->do_clone(); } + /** + destroy the cloned object + */ void destroy() { return do_destroy(); } + + /** + default construct + */ statistic() :p_fitter(0) {} + /** + copy construct + */ statistic(const statistic& rhs) :p_fitter(rhs.p_fitter) {} + /** + assignment operator + */ statistic& operator=(const statistic& rhs) { if(this==&rhs) @@ -1388,14 +1544,27 @@ namespace opt_utilities return *this; } + + /** + destructure function + */ virtual ~statistic() {} + /** + set the fitter + \param pfitter the fitter to be linked + */ virtual void set_fitter(fitter& pfitter) { p_fitter=&pfitter; } + + /** + get the attached fitter + \return the const reference of the fitter object + */ virtual const fitter& get_fitter()const { if(p_fitter==0) @@ -1405,6 +1574,12 @@ namespace opt_utilities return *p_fitter; } + /** + evaluating the model + \param x the self-var + \param p the parameter + \return the evaluated model value + */ Ty eval_model(const Tx& x,const Tp& p) { if(p_fitter==0) @@ -1414,7 +1589,10 @@ namespace opt_utilities return p_fitter->eval_model(x,p); } - + /** + get the data_set object managed by the fitter object + \return the const reference of the data_set object + */ const data_set& get_data_set()const { if(p_fitter==0) @@ -1426,41 +1604,71 @@ namespace opt_utilities }; + + /** + Used to modify the parameter, e.g., freezing, bind + \tparam Ty the type of the model return type + \tparam Tx the type of the model self-var + \tparam Tp the type of the model param + \tparam Tstr the type of string used + */ template class param_modifier { private: model* p_model; public: + /** + constructing full parameter list from the free parameters + */ Tp reform(const Tp& p)const { return do_reform(p); } + + /** + constructing the free parameter from the full parameters + */ Tp deform(const Tp& p)const { return do_deform(p); } + /** + return the clone of self + \return the clone of self + */ param_modifier* clone()const { return do_clone(); } - + + /** + destroy the cloned object + */ void destroy() { do_destroy(); } public: - + /** + the default construct function + */ param_modifier() :p_model(0) {} + /** + copy construct function + */ param_modifier(const param_modifier& rhs) :p_model(rhs.p_model) {} + /** + assignment operator + */ param_modifier& operator=(const param_modifier& rhs) { if(this==&rhs) @@ -1472,12 +1680,21 @@ namespace opt_utilities } public: + + /** + Attach the fitter object + \param pf the fitter to be attached + */ void set_model(model& pf) { p_model=&pf; update(); } + /** + get the model attached + \return the const reference of the model + */ const model& get_model()const { if(p_model==0) @@ -1488,17 +1705,27 @@ namespace opt_utilities return *(this->p_model); } + /** + calculate the number of free parameters + */ size_t get_num_free_params()const { return do_get_num_free_params(); } + /** + report the status of parameters + \param pname parameter name + \return the string used to describe the parameter + */ Tstr report_param_status(const Tstr& name)const { return do_report_param_status(name); } - + /** + destruct function + */ virtual ~param_modifier(){} private: virtual Tp do_reform(const Tp& p)const=0; @@ -1515,9 +1742,6 @@ namespace opt_utilities } }; - - - } diff --git a/core/freeze_param.hpp b/core/freeze_param.hpp index 31541c1..4f7cc8c 100644 --- a/core/freeze_param.hpp +++ b/core/freeze_param.hpp @@ -1,3 +1,7 @@ +/** + \file freeze_param.hpp +*/ + #ifndef FREEZE_PARAM_HPP #define FREEZE_PARAM_HPP #include "fitter.hpp" @@ -6,6 +10,13 @@ namespace opt_utilities { + /** + freeze a set of parameter in model fitting + \tparam Ty the return type of a model + \tparam Tx the type of the self-var + \tparam Tp the type of the model parameter + \tparam Tstr the type of string used + */ template class freeze_param :public param_modifier @@ -16,11 +27,17 @@ namespace opt_utilities size_t num_free; public: + /** + the default construct function + */ freeze_param() { - } - + + /** + construct function + \param name the name of the parameter to be frozen + */ freeze_param(const Tstr& name) { param_names.insert(name); @@ -33,7 +50,10 @@ namespace opt_utilities } - + /** + update the parameter information + should be called by the library, rather than the user + */ void update() { param_num.clear(); @@ -133,6 +153,12 @@ namespace opt_utilities } public: + + /** + plus operator, used to combine a list of freeze_param objects + \param fp another freeze_param object + \return the combined freeze_param object + */ freeze_param operator+(const freeze_param& fp)const { freeze_param result(*this); @@ -145,6 +171,10 @@ namespace opt_utilities return result; } + /** + += operator + like the plus operator + */ freeze_param& operator+=(const freeze_param& fp) { //param_names.insert(param_names.end(), @@ -167,6 +197,12 @@ namespace opt_utilities return *this; } + + /** + un-freeze a parameter to a list of pre-frozen parameter list + \param fp the parameter to be un-frozen + \return the reference to the operated freeze_param object + */ freeze_param& operator-=(const freeze_param& fp) { //param_names.insert(param_names.end(), @@ -191,6 +227,11 @@ namespace opt_utilities }; + /** + help function to create a freeze_param object + \param name the name to be frozen + \return the created freeze_param object + */ template freeze_param freeze(const Tstr& name) { diff --git a/core/num_diff.hpp b/core/num_diff.hpp index f9cf520..a6d9659 100644 --- a/core/num_diff.hpp +++ b/core/num_diff.hpp @@ -1,3 +1,8 @@ +/** + \file num_diff.hpp + */ + + #ifndef NUMDIFF_HPP #define NUMDIFF_HPP @@ -9,6 +14,12 @@ namespace opt_utilities { + + /** + differentiable function + \tparam rT the return type + \tparam the parameter type + */ template class dfunc_obj :public func_obj @@ -17,12 +28,22 @@ namespace opt_utilities virtual pT do_diff(const pT& p)=0; public: + /** + calculate the differentiation + \param p the self-var + \return the gradient at p + */ pT diff(const pT& p) { return do_diff(p); } }; + + /** + When trying to diff an object function, when it is not differentiable, + this exception will be thrown. + */ class underivable :public opt_exception { @@ -32,6 +53,9 @@ namespace opt_utilities {} }; + /** + calculate the numerical differential of a func_obj + */ template pT numdiff(func_obj& f,const pT& p) { @@ -68,6 +92,13 @@ namespace opt_utilities return result; } + + /** + Help function to calculate the gradient of an objection function + func_obj, whether it is differentiable or not. If it is differentiable, + the gradient will be calculated by calling the diff member in the func_obj, + or a numerical calculation will be performed. + */ template pT diff(func_obj& f,const pT& p) { diff --git a/core/opt_exception.hpp b/core/opt_exception.hpp index 65e4470..4413da7 100644 --- a/core/opt_exception.hpp +++ b/core/opt_exception.hpp @@ -1,9 +1,16 @@ +/** + \file opt_exception.hpp +*/ + #ifndef OPT_EXCEPTION #define OPT_EXCEPTION #include #include namespace opt_utilities { + /** + the root class of exception used in opt_utilities + */ class opt_exception :public std::exception { @@ -26,6 +33,10 @@ namespace opt_utilities } }; + /** + When objection is not defined in optimizer, and optimizion is performing, + this exception will be thrown + */ class target_function_undefined :public opt_exception { @@ -35,6 +46,10 @@ namespace opt_utilities {} }; + /** + When the opt_method is not defined before the optimization is performing, + this exception will be thrown. + */ class opt_method_undefined :public opt_exception { @@ -44,6 +59,10 @@ namespace opt_utilities {} }; + /** + When fitter is not attached in a model, statistic, and other objects, + this exception will be thrown. + */ class fitter_unset :public opt_exception { @@ -53,6 +72,11 @@ namespace opt_utilities {} }; + + /** + When the model is not set before the model fitting, + this exception will be thrown. + */ class model_undefined :public opt_exception { @@ -62,6 +86,11 @@ namespace opt_utilities {} }; + + /** + When the data set is not loaded before the model fitting, + this exception will be thrown. + */ class data_unloaded :public opt_exception { @@ -72,6 +101,10 @@ namespace opt_utilities }; + /** + When the statistic is not set before the model fitting, + this exception will be thrown. + */ class statistic_undefined :public opt_exception { @@ -81,6 +114,11 @@ namespace opt_utilities {} }; + + /** + If a parameter is not found by the name or other information, + this exception will be thrown. + */ class param_not_found :public opt_exception { @@ -90,6 +128,11 @@ namespace opt_utilities {} }; + + /** + If param_modifier is not defined, and the user tries to get the + param_modifer, this exception will be thrown. + */ class param_modifier_undefined :public opt_exception { diff --git a/core/opt_traits.hpp b/core/opt_traits.hpp index b8426e0..7c2638a 100644 --- a/core/opt_traits.hpp +++ b/core/opt_traits.hpp @@ -1,22 +1,41 @@ +/** + \file opt_traits.hpp + */ + #ifndef ARRAY_OPERATION #define ARRAY_OPERATION #include namespace opt_utilities { - /////////Useful function/////////////////////////////////// + /** + Get the size of an array object + \param x the array object + \return the size of the array object + */ template inline size_t get_size(const T& x) { return x.size(); } + /** + Trait class, in which the types of elements in an array are defined + \tparam the type of the array object + */ template class element_type_trait { public: + /** + Default definition of element_type + */ typedef typename T::value_type element_type; }; + + /** + The return type trait of some certain data types. + */ template class return_type_trait { @@ -26,6 +45,14 @@ namespace opt_utilities typedef const T& const_reference_type; }; + + /** + Help function to get the i-th element from an array + \tparam T the type of the array object + \param x the array object + \param i the order of the element + \return the fetched element value, const reference + */ template inline typename return_type_trait::element_type>:: @@ -33,14 +60,16 @@ namespace opt_utilities { return x[i]; } - /* - template - inline typename element_type_trait::element_type& get_element(T& x,size_t i) - { - return x[i]; - } - */ + + /** + set ths i-th element by a given value + \tparam T the type of the array object + \tparam Tx the type of the element + \param x the array object + \param i the order of the element + \param v the value of the element to be set + */ template inline void set_element(T& x,size_t i, const TX& v) @@ -48,12 +77,28 @@ namespace opt_utilities x[i]=v; } + + /** + resize an array object + \tparam T the type of the array + \param x the array object + \param s the new size + */ template inline void resize(T& x,size_t s) { x.resize(s); } + + /** + Assignment operator of two array objects + \tparam Tl the type of left-hand array + \tparam Tr the type of right-hand array + \param lhs the left-hand array + \param rhs the right-hand array + \return the reference of the left-hand array + */ template inline Tl& opt_eq(Tl& lhs,const Tr& rhs) { diff --git a/core/optimizer.hpp b/core/optimizer.hpp index 7492bab..2381da0 100644 --- a/core/optimizer.hpp +++ b/core/optimizer.hpp @@ -17,6 +17,9 @@ using namespace std; #endif +/** + The root namespace of the opt_utilities library + */ namespace opt_utilities { /////////Forward declare/////////////////////////////////// -- cgit v1.2.2