#ifndef NUMDIFF_HPP #define NUMDIFF_HPP #include #include #include #include #include namespace opt_utilities { template class dfunc_obj :public func_obj { private: virtual pT do_diff(const pT& p)=0; public: pT diff(const pT& p) { return do_diff(p); } }; class underivable :public opt_exception { public: underivable() :opt_exception("underivable") {} }; template pT numdiff(func_obj& f,const pT& p) { rT ep=std::sqrt(std::numeric_limits::epsilon()); pT result; resize(result,get_size(p)); pT p2; resize(p2,get_size(p)); pT p1; resize(p1,get_size(p)); for(size_t i=0;i::element_type h= std::max(get_element(p,i),rT(1))*ep; set_element(p2,i,get_element(p,i)+h); set_element(p1,i,get_element(p,i)-h); rT v2=f(p2); rT v1=f(p1); set_element(result,i, (v2-v1)/h/2 ); set_element(p2,i,get_element(p,i)); set_element(p1,i,get_element(p,i)); } return result; } template pT diff(func_obj& f,const pT& p) { dfunc_obj* pdf=dynamic_cast*>(&f); if(pdf) { return pdf->diff(p); } return numdiff(f,p); } } #endif