/** \file pow_model.hpp \brief combing two model by power operation \author Junhua Gu */ #ifndef POW_MODEL_H_ #define POW_MODEL_H_ #define OPT_HEADER #include <core/fitter.hpp> #include <core/opt_traits.hpp> #include <cmath> namespace opt_utilities { template <typename Ty,typename Tx,typename Tp,typename Tstr> class pow_model :public model<Ty,Tx,Tp,Tstr> { private: model<Ty,Tx,Tp,Tstr>* do_clone()const { return new pow_model<Ty,Tx,Tp,Tstr>(*this); } private: pow_model() { } const char* do_get_type_name()const { return "combine two models by power operation"; } private: model<Ty,Tx,Tp,Tstr>* pm1; typename element_type_trait<Tp>::element_type idx; public: pow_model(const model<Ty,Tx,Tp,Tstr>& m1, const typename element_type_trait<Tp>::element_type& index) :pm1(m1.clone()),idx(index) { int np1=m1.get_num_params(); for(int i=0;i<np1;++i) { param_info<Tp,Tstr> p(m1.get_param_info(i)); //param_info<Tp,Tstr> p1(p.get_name(),p.get_value()); this->push_param_info(p); } } pow_model(const pow_model& rhs) :pm1(NULL),idx(0) { int np1(0); if(rhs.pm1) { pm1=rhs.pm1->clone(); np1=rhs.pm1->get_num_params(); for(int i=0;i<np1;++i) { param_info<Tp,Tstr> p(rhs.pm1->get_param_info(i)); param_info<Tp,Tstr> p1(p.get_name()+"1",p.get_value()); this->push_param_info(p1); } } idx=rhs.idx; } pow_model& operator=(const pow_model& rhs) { if(this==&rhs) { return *this; } if(!pm1) { //delete pm1; pm1->destroy(); } int np1(0); if(rhs.pm1) { pm1=rhs.pm1->clone(); np1=rhs.pm1->get_num_params(); for(int i=0;i<np1;++i) { param_info<Tp,Tstr> p(rhs.pm1->get_param_info(i)); // param_info<Tp,Tstr> p1(p.get_name()+"1",p.get_value()); this->push_param_info(p); } } idx=rhs.idx; return *this; } ~pow_model() { if(!pm1) { //delete pm1; pm1->destroy(); } } public: Ty do_eval(const Tx& x,const Tp& param) { if(!pm1) { throw opt_exception("incomplete model!"); } return std::pow(pm1->eval(x,param),idx); } }; template <typename Ty,typename Tx,typename Tp,typename Tstr> pow_model<Ty,Tx,Tp,Tstr> pow(const model<Ty,Tx,Tp,Tstr>& m1, const typename element_type_trait<Tp>:: element_type& idx) { return pow_model<Ty,Tx,Tp,Tstr>(m1,idx); } } #endif //EOF