/** \file add_model.hpp \brief proxy class representing the sum of two models \author Junhua Gu */ #ifndef ADD_MODEL_H_ #define ADD_MODEL_H_ #define OPT_HEADER #include #include namespace opt_utilities { template class add_model :public model { private: model* do_clone()const { return new add_model(*this); } private: add_model() { } private: model* pm1; model* pm2; public: add_model(const model& m1, const model& m2) :pm1(m1.clone()),pm2(m2.clone()) { int np1=m1.get_num_params(); int np2=m2.get_num_params(); for(int i=0;i p(m1.get_param_info(i)); param_info p1(p.get_name()+"1",p.get_value()); this->push_param_info(p1); } for(int i=0;i p(m2.get_param_info(i)); param_info p2(p.get_name()+"2",p.get_value()); this->push_param_info(p2); } } add_model(const add_model& rhs) :pm1(NULL),pm2(NULL) { int np1(0),np2(0); if(rhs.pm1) { pm1=rhs.pm1->clone(); np1=rhs.pm1->get_num_params(); for(int i=0;i p(rhs.pm1->get_param_info(i)); param_info p1(p.get_name()+"1",p.get_value()); this->push_param_info(p1); } } if(rhs.pm2) { pm2=rhs.pm2->clone(); np2=rhs.pm2->get_num_params(); for(int i=0;i p(rhs.pm2->get_param_info(i)); param_info p2(p.get_name()+"2",p.get_value()); this->push_param_info(p2); } } } add_model& operator=(const add_model& rhs) { if(this==&rhs) { return *this; } if(!pm1) { //delete pm1; pm1->destroy(); } if(!pm2) { //delete pm2; pm2->destroy(); } int np1(0),np2(0); if(rhs.pm1) { pm1=rhs.pm1->clone(); np1=rhs.pm1->get_num_params(); for(int i=0;i p(rhs.pm1->get_param_info(i)); param_info p1(p.get_name()+"1",p.get_value()); this->push_param_info(p1); } } if(rhs.pm2) { pm2=rhs.pm2->clone(); np2=rhs.pm2->get_num_params(); for(int i=0;i p(rhs.pm2->get_param_info(i)); param_info p2(p.get_name()+"2",p.get_value()); this->push_param_info(p2); } } return *this; } ~add_model() { if(!pm1) { //delete pm1; pm1->destroy(); } if(!pm2) { //delete pm2; pm2->destroy(); } } public: const char* do_get_type_name()const { return "add model"; } public: Ty do_eval(const Tx& x,const Tp& param) { if(!pm1) { throw opt_exception("incomplete model!"); } if(!pm2) { throw opt_exception("incomplete model!"); } Tp p1(pm1->get_num_params()); Tp p2(pm2->get_num_params()); int i=0; int j=0; for(i=0;iget_num_params();++i,++j) { set_element(p1,i,get_element(param,j)); } for(i=0;iget_num_params();++i,++j) { set_element(p2,i,get_element(param,j)); } return pm1->eval(x,p1)+pm2->eval(x,p2); } }; template add_model operator+(const model& m1, const model& m2) { return add_model(m1,m2); } } #endif //EOF