41 #ifndef __has_c2_function_hh
42 #define __has_c2_function_hh 1
47 #define _USE_MATH_DEFINES
48 #define c2_isnan _isnan
49 #define c2_isfinite _finite
51 #define c2_isnan std::isnan
52 #define c2_isfinite std::isfinite
73 virtual const char*
what()
const throw() {
return info.c_str(); }
86 template <
typename float_type>
class c2_ptr;
98 template <
typename float_type>
class c2_fblock
143 "c2_function.hh 490 2012-04-10 19:05:40Z marcus ";
154 if(root_info)
delete root_info;
156 std::ostringstream outstr;
157 outstr <<
"attempt to delete an object with non-zero ownership in class ";
158 outstr <<
typeid(*this).name() << std::endl;
206 float_type
find_root(float_type lower_bracket, float_type upper_bracket, float_type start,
207 float_type
value,
int *error=0,
208 float_type *final_yprime=0, float_type *final_yprime2=0 )
const throw(
c2_exception) ;
228 float_type
partial_integrals(std::vector<float_type> xgrid, std::vector<float_type> *partials = 0,
229 float_type abs_tol=1
e-12, float_type rel_tol=1e-12,
int derivs=2,
bool adapt=true,
bool extrapolate=true)
230 const throw(c2_exception);
251 float_type
integral(float_type amin, float_type amax, std::vector<float_type> *partials = 0,
252 float_type abs_tol=1e-12, float_type rel_tol=1e-12,
int derivs=2,
bool adapt=true,
bool extrapolate=true)
253 const throw(c2_exception);
293 float_type abs_tol=1e-12, float_type rel_tol=1e-12,
294 int derivs=2, std::vector<float_type> *xvals=0, std::vector<float_type> *yvals=0)
const throw(c2_exception);
340 virtual void get_sampling_grid(float_type amin, float_type amax, std::vector<float_type> &grid)
const ;
371 const throw(c2_exception);
411 std::ostringstream outstr;
412 outstr <<
"attempt to release ownership of an unowned function in class ";
413 outstr <<
typeid(*this).name() << std::endl;
414 throw c2_exception(outstr.str().c_str());
434 fXMin(-std::numeric_limits<float_type>::max()),
435 fXMax(std::numeric_limits<float_type>::max()), root_info(0), owner_count(0)
468 float_type previous_estimate, abs_tol, step_sum;
470 size_t f0index, f2index;
478 struct c2_integrate_recur {
480 float_type abs_tol, rel_tol, eps_scale, extrap_coef, extrap2, dx_tolerance, abs_tol_min;
481 std::vector< recur_item > *rb_stack;
483 bool adapt, extrapolate, inited;
488 struct c2_sample_recur {
490 float_type abs_tol, rel_tol, dx_tolerance, abs_tol_min;
493 std::vector<float_type> *xvals, *yvals;
494 std::vector< recur_item > *rb_stack;
500 struct c2_root_info {
510 float_type integrate_step(
struct c2_integrate_recur &rb)
const throw(
c2_exception);
517 void sample_step(
struct c2_sample_recur &rb)
const throw(
c2_exception);
523 mutable struct c2_root_info *root_info;
525 mutable size_t owner_count;
544 if(!
func)
throw c2_exception(
"c2_classic_function called with null function");
545 if(yprime) *yprime=0;
546 if(yprime2) *yprime2=0;
553 const float_type (*
func)(float_type);
603 if(
func)
func->release_ownership_for_return();
646 {
return get().value_with_derivatives(
x, yprime, yprime2); }
750 operator c2_class<float_type>&()
const {
return get(); }
794 func.set_function(f);
801 if(!
func.valid())
throw c2_exception(
"c2_plugin_function_p called uninitialized");
802 return func->value_with_derivatives(
x, yprime, yprime2);
810 virtual void get_sampling_grid(float_type amin, float_type amax, std::vector<float_type> &grid)
const
812 if(!
func.valid())
throw c2_exception(
"c2_plugin_function_p called uninitialized");
814 else func->get_sampling_grid(amin, amax, grid);
839 {
return this->
func.get(); }
852 if(
stub)
throw c2_exception(
"attempt to evaluate a c2_binary_function stub");
867 float_type
x, float_type *yprime, float_type *yprime2),
881 float_type
x, float_type *yprime, float_type *yprime2)
886 float_type
x, float_type *yprime, float_type *yprime2);
917 float_type
y=this->
func->value_with_derivatives(
x, yprime, yprime2);
918 if(yprime) (*yprime)*=
yscale;
919 if(yprime2) (*yprime2)*=
yscale;
951 y=this->
func->value_with_derivatives(
x, &
yp, &
ypp);
955 if(yprime) *yprime=
yp;
956 if(yprime2) *yprime2=
ypp;
987 float_type
x, float_type *yprime, float_type *yprime2)
throw(
c2_exception)
990 if(yprime || yprime2) {
991 float_type yp0, ypp0, yp1, ypp1;
992 y0=
right.value_with_derivatives(
x, &yp0, &ypp0);
993 y1=
left.value_with_derivatives(y0, &yp1, &ypp1);
994 if(yprime) *yprime=yp1*yp0;
995 if(yprime2) *yprime2=ypp0*yp1+yp0*yp0*ypp1;
1018 float_type
x, float_type *yprime, float_type *yprime2)
throw(
c2_exception)
1021 if(yprime || yprime2) {
1022 float_type yp0, ypp0, yp1, ypp1;
1023 y0=
left.value_with_derivatives(
x, &yp0, &ypp0);
1024 y1=
right.value_with_derivatives(
x, &yp1, &ypp1);
1025 if(yprime) *yprime=yp0+yp1;
1026 if(yprime2) *yprime2=ypp0+ypp1;
1050 float_type
x, float_type *yprime, float_type *yprime2)
throw(
c2_exception)
1053 if(yprime || yprime2) {
1054 float_type yp0, ypp0, yp1, ypp1;
1055 y0=
left.value_with_derivatives(
x, &yp0, &ypp0);
1056 y1=
right.value_with_derivatives(
x, &yp1, &ypp1);
1057 if(yprime) *yprime=yp0-yp1;
1058 if(yprime2) *yprime2=ypp0-ypp1;
1082 float_type
x, float_type *yprime, float_type *yprime2)
throw(
c2_exception)
1085 if(yprime || yprime2) {
1086 float_type yp0, ypp0, yp1, ypp1;
1087 y0=
left.value_with_derivatives(
x, &yp0, &ypp0);
1088 y1=
right.value_with_derivatives(
x, &yp1, &ypp1);
1089 if(yprime) *yprime=y1*yp0+y0*yp1;
1090 if(yprime2) *yprime2=ypp0*y1+2.0*yp0*yp1+ypp1*y0;
1114 float_type
x, float_type *yprime, float_type *yprime2)
throw(
c2_exception)
1117 if(yprime || yprime2) {
1118 float_type yp0, ypp0, yp1, ypp1;
1119 y0=
left.value_with_derivatives(
x, &yp0, &ypp0);
1120 y1=
right.value_with_derivatives(
x, &yp1, &ypp1);
1121 if(yprime) *yprime=(yp0*y1-y0*yp1)/(y1*y1);
1122 if(yprime2) *yprime2=(y1*y1*ypp0+y0*(2*yp1*yp1-y1*ypp1)-2*y1*yp0*yp1)/(y1*y1*
y1);
1141 {
if(yprime) *yprime=0;
if(yprime2) *yprime2=0;
return value; }
1158 float_type (*xin)(float_type), float_type (*xinp)(float_type), float_type (*xinpp)(float_type), float_type (*xout)(float_type)
1178 float_type (*
const pIn)(float_type);
1184 float_type (*
const pOut)(float_type);
1187 virtual float_type
fIn(float_type
x)
const {
return pIn(x); }
1193 virtual float_type
fOut(float_type
x)
const {
return pOut(x); }
1199 static float_type
ident(float_type
x) {
return x; }
1201 static float_type
one(float_type) {
return 1; }
1203 static float_type
zero(float_type) {
return 0; }
1205 static float_type
recip(float_type
x) {
return 1.0/
x; }
1246 template <
typename float_type>
1254 isIdentity(!(xx.fTransformed || yy.fTransformed)),
X(xx),
Y(yy) { }
1265 virtual float_type
evaluate(float_type xraw,
1266 float_type
y, float_type yp0, float_type ypp0,
1267 float_type *yprime, float_type *yprime2)
const;
1402 bool lowerSlopeNatural, float_type lowerSlope,
1403 bool upperSlopeNatural, float_type upperSlope,
bool splined=
true
1415 std::vector<std::pair<float_type, float_type> > &
data,
1416 bool lowerSlopeNatural, float_type lowerSlope,
1417 bool upperSlopeNatural, float_type upperSlope,
bool splined=true
1418 ) throw(c2_exception);
1438 float_type amin, float_type amax, float_type abs_tol, float_type rel_tol,
1439 bool lowerSlopeNatural, float_type lowerSlope,
1440 bool upperSlopeNatural, float_type upperSlope
1441 ) throw(c2_exception);
1459 throw(c2_exception);
1479 const std::vector<float_type> &bins,
const std::vector<float_type> &binheights,
bool splined=true)
1480 throw(c2_exception);
1497 void get_data(std::vector<float_type> &xvals, std::vector<float_type> &yvals)
const throw() ;
1506 std::vector<float_type> &xvals,
1507 std::vector<float_type> &yvals,
1508 std::vector<float_type> &y2vals)
const
1509 { xvals=
X; yvals=
F; y2vals=
y2; }
1578 bool lowerSlopeNatural, float_type lowerSlope,
1579 bool upperSlopeNatural, float_type upperSlope
1583 static bool comp_pair(std::pair<float_type,float_type>
const &i, std::pair<float_type,float_type>
const &j) {
return i.first<j.first;}
1670 { float_type q=std::sin(
x);
if(yprime) *yprime=std::cos(
x);
if(yprime2) *yprime2=-q;
return q; }
1676 virtual void get_sampling_grid(float_type amin, float_type amax, std::vector<float_type> &grid)
const;
1689 { float_type q=std::cos(
x);
if(yprime) *yprime=-std::sin(
x);
if(yprime2) *yprime2=-q;
return q; }
1703 float_type
c=std::cos(
x), ss=std::sin(
x);
1705 float_type yp=1/(c*
c);
1706 if(yprime) *yprime=yp;
if(yprime2) *yprime2=2*t*yp;
1721 {
if(yprime) *yprime=1.0/
x;
if(yprime2) *yprime2=-1.0/(
x*
x);
return std::log(
x); }
1734 { float_type q=std::exp(
x);
if(yprime) *yprime=q;
if(yprime2) *yprime2=q;
return q; }
1747 { float_type q=std::sqrt(
x);
if(yprime) *yprime=0.5/q;
if(yprime2) *yprime2=-0.25/(
x*q);
return q; }
1762 float_type
y=rscale*q;
1763 if(yprime) *yprime=-y*q;
1764 if(yprime2) *yprime2=2*y*q*q;
1784 {
if(yprime) *yprime=1.0;
if(yprime2) *yprime2=0;
return x; }
1805 c2_function<float_type>(), xint(x0), intercept(y0), m(slope) {}
1810 void reset(float_type x0, float_type y0, float_type slope) { xint=x0; intercept=y0; m=slope; }
1812 {
if(yprime) *yprime=m;
if(yprime2) *yprime2=0;
return m*(
x-xint)+intercept; }
1815 float_type xint, intercept, m;
1841 c2_function<float_type>(), intercept(y0), center(x0), a(x2coef), b(xcoef) {}
1847 void reset(float_type x0, float_type y0, float_type xcoef, float_type x2coef) { intercept=y0; center=x0; a=x2coef; b=xcoef; }
1849 { float_type dx=
x-center;
if(yprime) *yprime=2*a*dx+b;
if(yprime2) *yprime2=2*a;
return a*dx*dx+b*dx+intercept; }
1852 float_type intercept, center, a, b;
1881 { float_type q=a*std::pow(
x,b-2);
if(yprime) *yprime=b*q*
x;
if(yprime2) *yprime2=b*(b-1)*q;
return q*x*
x; }
1976 accumulated_histogram(
const std::vector<float_type>binedges,
const std::vector<float_type> binheights,
1977 bool normalize=
false,
bool inverse_function=
false,
bool drop_zeros=
true);
2007 bool auto_center, float_type
y1);
2022 float_type x0, float_type y0, float_type yp0, float_type ypp0,
2023 float_type x2, float_type
y2, float_type yp2, float_type ypp2,
2024 bool auto_center, float_type y1);
2034 bool auto_center, float_type y1);
2044 bool auto_center, float_type y1);
2088 #include "c2_function.icc"