/** \file bootstrap.hpp \brief A simple implement of bootstrap method for error estimation \autho Junhua Gu */ #ifndef BOOT_STRAP #define BOOT_STRAP #define OPT_HEADER #include #include #include #include #include #include #include #include using std::cerr; namespace opt_utilities { template inline Ty rand_norm(Ty y0,Ty y_err) { Ty y; do { y=(rand()/(Ty)RAND_MAX-(Ty).5)*(10*y_err)+y0; } while(rand()/(Ty)RAND_MAX>exp(-(y-y0)*(y-y0)/(y_err*y_err))); return y; } /** \brief using bootstrap method to estimate confidence interval \tparam Ty the return type of a model \tparam Tx the type of self-var \tparam Tp the type of model parameters \tparam Ts the type of statistic \tparam Tstr the type of string used */ template class bootstrap { private: public: typedef typename std::list::const_iterator param_iterator; public: std::list param_pool; default_data_set current_data_set; default_data_set origin_data_set; fitter* p_fitter; Tp origin_param; mutable bool bstop; public: /** default construct */ bootstrap() :p_fitter(NULL) {} /** destructure */ ~bootstrap() { reset(); } /** set a fitter \param pf the fitter, the confidence interval of which will be estimated */ void set_fitter(fitter& pf) { param_pool.clear(); p_fitter=&pf; origin_data_set=dynamic_cast&>(pf.get_data_set()); origin_param=pf.get_all_params(); } /** reset the estimation reload the data restore the parameters */ void reset() { if(p_fitter!=0) { p_fitter->load_data(origin_data_set); p_fitter->set_param_value(origin_param); } p_fitter=0; } /** resample n times \param n the times to sample */ void sample(int n) { bstop=false; if(p_fitter!=NULL) { for(int i=0;iload_data(origin_data_set); p_fitter->set_param_value(origin_param); } else { throw opt_exception("Fitter not_set"); } } void stop() { bstop=true; } /** get the param of i-th sampling \param i the order of parameter \return the parameter */ const Tp& get_param(int n)const { //return param_pool.at(i); int cnt=0; for(typename std::list::const_iterator i=param_pool.begin(); i!=param_pool.end();++i) { if(cnt==n) { return *i; } ++cnt; } throw opt_exception("excesses param_pool size"); return *param_pool.begin(); } typename std::list::const_iterator param_begin()const { return param_pool.begin(); } typename std::list::const_iterator param_end()const { return param_pool.end(); } int get_param_pool_size()const { return param_pool.size(); } private: Tp sample() { if(p_fitter==NULL) { throw fitter_not_set(); } current_data_set=default_data_set(); for(size_t i=0;i d; d=origin_data_set.get_data(i); d.set_y(rand_norm(d.get_y(),(d.get_y_upper_err()+d.get_y_lower_err())/2.)); current_data_set.add_data(d); } p_fitter->load_data(current_data_set); p_fitter->set_param_value(origin_param); param_pool.push_back(p_fitter->fit()); for(size_t i=0;i<(param_pool.back()).size();++i) { cerr<::element_type,typename element_type_trait::element_type> interval(const Tstr& param_name,double level) { if(p_fitter==NULL) { throw opt_exception("Fitter not_set"); } if(param_pool.empty()) { throw opt_exception("Bootstrap not done"); } //sample(); std::vector::element_type> _tmp; int order=p_fitter->get_param_order(param_name); for(typename std::list::iterator i=param_pool.begin(); i!=param_pool.end();++i) { _tmp.push_back((*i)[order]); } sort(_tmp.begin(),_tmp.end()); std::pair::element_type>::iterator, typename std::vector::element_type>::iterator> itv=equal_range(_tmp.begin(),_tmp.end(),origin_param[order]); int current_param_position=itv.second-_tmp.begin(); //std::cerr<<_tmp.size()<::element_type, typename element_type_trait::element_type>( _tmp.at((int)((1-level)*current_param_position)), _tmp.at((int)(current_param_position+level*(_tmp.size()-current_param_position))) ); } }; } #endif //EOF