40 #ifndef __has_c2_function_hh
41 #define __has_c2_function_hh 1
46 #define _USE_MATH_DEFINES
47 #define c2_isnan _isnan
48 #define c2_isfinite _finite
50 #define c2_isnan std::isnan
51 #define c2_isfinite std::isfinite
72 virtual const char*
what()
const throw() {
return info.c_str(); }
85 template <
typename float_type>
class c2_ptr;
151 "c2_function.hh 490 2012-04-10 19:05:40Z marcus ";
164 std::ostringstream outstr;
165 outstr <<
"attempt to delete an object with non-zero ownership in class";
166 outstr <<
typeid(*this).name() << std::endl;
180 float_type *yprime2)
const =0 ;
195 float_type *yprime2)
const
230 float_type
find_root(float_type lower_bracket, float_type upper_bracket,
233 float_type *final_yprime=0,
234 float_type *final_yprime2=0 ) const ;
267 std::vector<float_type> *partials = 0,
268 float_type abs_tol=1
e-12,
269 float_type rel_tol=1e-12,
270 int derivs=2,
bool adapt=
true,
271 bool extrapolate=true)
305 float_type
integral(float_type amin, float_type amax,
306 std::vector<float_type> *partials = 0,
307 float_type abs_tol=1e-12, float_type rel_tol=1e-12,
308 int derivs=2,
bool adapt=true,
bool extrapolate=true)
383 float_type amin, float_type amax,
384 float_type abs_tol=1e-12, float_type rel_tol=1e-12,
385 int derivs=2, std::vector<float_type> *
xvals=0,
386 std::vector<float_type> *
yvals=0) const ;
435 std::vector<float_type> &grid)
const ;
440 size_t refinement)
const;
451 float_type
norm=1.0) const ;
453 float_type amin, float_type amax,
510 std::ostringstream outstr;
511 outstr <<
"attempt to release ownership of an unowned function in class ";
512 outstr <<
typeid(*this).name() << std::endl;
533 fXMin(-std::numeric_limits<float_type>::
max()),
649 float_type
x, float_type *yprime,
650 float_type *yprime2)
const
653 throw c2_exception(
"c2_classic_function called with null function");
654 if(yprime) *yprime=0;
655 if(yprime2) *yprime2=0;
662 const float_type (*
func)(float_type);
721 if(
func)
func->release_ownership_for_return();
767 float_type *yprime2)
const
768 {
return get().value_with_derivatives(
x, yprime, yprime2); }
835 template <
typename float_type,
template <
typename>
class c2_class >
851 inline c2_class<float_type> &
get()
const
853 return *
static_cast<c2_class<float_type> *
>
861 {
return static_cast<c2_class<float_type> *
>(
864 operator c2_class<float_type>&()
const {
return get(); }
889 func.set_function(f);
895 float_type
x, float_type *yprime,
896 float_type *yprime2)
const
899 throw c2_exception(
"c2_plugin_function_p called uninitialized");
900 return func->value_with_derivatives(
x, yprime, yprime2);
909 std::vector<float_type> &grid)
const
912 throw c2_exception(
"c2_plugin_function_p called uninitialized");
915 else func->get_sampling_grid(amin, amax, grid);
937 {
return this->
func.get(); }
944 float_type
x, float_type *yprime,
945 float_type *yprime2)
const
948 throw c2_exception(
"attempt to evaluate a c2_binary_function stub");
960 float_type
x, float_type *yprime,
961 float_type *yprime2),
975 float_type
x, float_type *yprime, float_type *yprime2)
983 float_type
x, float_type *yprime, float_type *yprime2);
1006 float_type
x, float_type *yprime,
1007 float_type *yprime2)
const
1009 float_type
y=this->
func->value_with_derivatives(
x, yprime, yprime2);
1010 if(yprime) (*yprime)*=
yscale;
1011 if(yprime2) (*yprime2)*=
yscale;
1043 float_type
x, float_type *yprime,
1044 float_type *yprime2)
const
1047 y=this->
func->value_with_derivatives(
x, &
yp, &
ypp);
1051 if(yprime) *yprime=
yp;
1052 if(yprime2) *yprime2=
ypp;
1077 float_type
x, float_type *yprime,
1078 float_type *yprime2)
1081 if(yprime || yprime2) {
1082 float_type yp0, ypp0, yp1, ypp1;
1085 if(yprime) *yprime=yp1*yp0;
1086 if(yprime2) *yprime2=ypp0*yp1+yp0*yp0*ypp1;
1095 template <
typename float_type=
double>
class c2_sum_p
1110 float_type
x, float_type *yprime,
1111 float_type *yprime2)
1114 if(yprime || yprime2) {
1115 float_type yp0, ypp0, yp1, ypp1;
1118 if(yprime) *yprime=yp0+yp1;
1119 if(yprime2) *yprime2=ypp0+ypp1;
1128 template <
typename float_type=
double>
class c2_diff_p
1143 float_type
x, float_type *yprime,
1144 float_type *yprime2)
1147 if(yprime || yprime2) {
1148 float_type yp0, ypp0, yp1, ypp1;
1151 if(yprime) *yprime=yp0-yp1;
1152 if(yprime2) *yprime2=ypp0-ypp1;
1165 template <
typename float_type=
double>
class c2_product_p
1180 float_type
x, float_type *yprime,
1181 float_type *yprime2)
1184 if(yprime || yprime2) {
1185 float_type yp0, ypp0, yp1, ypp1;
1188 if(yprime) *yprime=y1*yp0+y0*yp1;
1189 if(yprime2) *yprime2=ypp0*y1+2.0*yp0*yp1+ypp1*y0;
1202 template <
typename float_type=
double>
class c2_ratio_p
1217 float_type
x, float_type *yprime,
1218 float_type *yprime2)
1221 if(yprime || yprime2) {
1222 float_type yp0, ypp0, yp1, ypp1;
1225 if(yprime) *yprime=(yp0*y1-y0*yp1)/(y1*y1);
1226 if(yprime2) *yprime2=(y1*y1*ypp0+y0*(2*yp1*yp1-y1*ypp1)-2*y1*yp0*yp1)
1246 float_type, float_type *yprime,
1247 float_type *yprime2)
const
1248 {
if(yprime) *yprime=0;
if(yprime2) *yprime2=0;
return value; }
1265 float_type (*xin)(float_type),
1266 float_type (*xinp)(float_type),
1267 float_type (*xinpp)(float_type),
1268 float_type (*xout)(float_type)
1293 float_type (*
const pIn)(float_type);
1299 float_type (*
const pOut)(float_type);
1302 virtual float_type
fIn(float_type
x)
const {
return pIn(x); }
1308 virtual float_type
fOut(float_type
x)
const {
return pOut(x); }
1313 throw c2_exception(
"use of improperly constructed axis transform");
1316 static float_type
ident(float_type
x) {
return x; }
1318 static float_type
one(float_type) {
return 1; }
1320 static float_type
zero(float_type) {
return 0; }
1322 static float_type
recip(float_type
x) {
return 1.0/
x; }
1377 template <
typename float_type>
1386 isIdentity(!(xx.fTransformed || yy.fTransformed)),
X(xx),
Y(yy) { }
1391 float_type
y, float_type yp0, float_type ypp0,
1392 float_type *yprime, float_type *yprime2)
const;
1551 const std::vector<float_type> &
x,
1552 const std::vector<float_type> &
f,
1553 bool lowerSlopeNatural, float_type lowerSlope,
1554 bool upperSlopeNatural, float_type upperSlope,
bool splined=
true
1573 std::vector<std::pair<float_type, float_type> > &
data,
1574 bool lowerSlopeNatural, float_type lowerSlope,
1575 bool upperSlopeNatural, float_type upperSlope,
bool splined=
true
1614 float_type amin, float_type amax,
1615 float_type abs_tol, float_type rel_tol,
1616 bool lowerSlopeNatural, float_type lowerSlope,
1617 bool upperSlopeNatural, float_type upperSlope
1645 const std::vector<float_type> &bincenters,
1650 const std::vector<float_type> &bins,
1651 const std::vector<float_type> &binheights,
1656 float_type
x, float_type *yprime,
1657 float_type *yprime2)
const ;
1667 std::vector<float_type> &
yvals)
const ;
1670 std::vector<float_type> &
xvals,
1671 std::vector<float_type> &
yvals,
1672 std::vector<float_type> &y2vals)
const
1673 { xvals=
X; yvals=
F; y2vals=
y2; }
1707 bool lowerSlopeNatural, float_type lowerSlope,
1708 bool upperSlopeNatural, float_type upperSlope
1711 static bool comp_pair(std::pair<float_type,float_type>
const &i,
1712 std::pair<float_type,float_type>
const &j)
1713 {
return i.first<j.first;}
1808 float_type
x, float_type *yprime,
1809 float_type *yprime2)
const
1810 { float_type q=std::sin(
x);
1811 if(yprime) *yprime=std::cos(
x);
1812 if(yprime2) *yprime2=-q;
1816 std::vector<float_type> &grid)
const;
1830 float_type
x, float_type *yprime,
1831 float_type *yprime2)
const
1832 { float_type q=std::cos(
x);
1833 if(yprime) *yprime=-std::sin(
x);
1834 if(yprime2) *yprime2=-q;
1849 float_type
x, float_type *yprime,
1850 float_type *yprime2)
const
1852 float_type
c=std::cos(
x), ss=std::sin(
x);
1854 float_type yp=1/(c*
c);
1855 if(yprime) { *yprime=yp; }
1856 if(yprime2){*yprime2=2*t*yp; }
1872 float_type
x, float_type *yprime,
1873 float_type *yprime2)
const
1874 {
if(yprime) *yprime=1.0/
x;
1875 if(yprime2) *yprime2=-1.0/(
x*
x);
1876 return std::log(
x); }
1890 float_type
x, float_type *yprime,
1891 float_type *yprime2)
const
1892 { float_type q=std::exp(
x);
1893 if(yprime) *yprime=q;
1894 if(yprime2) *yprime2=q;
1909 float_type
x, float_type *yprime,
1910 float_type *yprime2)
const
1911 { float_type q=std::sqrt(
x);
1912 if(yprime) *yprime=0.5/q;
1913 if(yprime2) *yprime2=-0.25/(
x*q);
1928 float_type
x, float_type *yprime,
1929 float_type *yprime2)
const
1933 if(yprime) *yprime=-y*q;
1934 if(yprime2) *yprime2=2*y*q*q;
1955 float_type
x, float_type *yprime,
1956 float_type *yprime2)
const
1957 {
if(yprime) *yprime=1.0;
if(yprime2) *yprime2=0;
return x; }
1984 void reset(float_type x0, float_type y0, float_type slope)
1987 float_type
x, float_type *yprime,
1988 float_type *yprime2)
const
1989 {
if(yprime) *yprime=
m;
1990 if(yprime2) *yprime2=0;
2022 float_type xcoef, float_type x2coef) :
2029 void reset(float_type x0, float_type y0, float_type xcoef,
2032 float_type
x, float_type *yprime,
2033 float_type *yprime2)
const
2035 if(yprime) *yprime=2*
a*dx+
b;
2036 if(yprime2) *yprime2=2*
a;
2070 float_type
x, float_type *yprime,
2071 float_type *yprime2)
const
2072 { float_type q=
a*std::pow(
x,
b-2);
2073 if(yprime) *yprime=
b*q*
x;
2074 if(yprime2) *yprime2=
b*(
b-1)*q;
2107 float_type
x, float_type *yprime,
2108 float_type *yprime2)
const ;
2185 const std::vector<float_type> binheights,
2186 bool normalize=
false,
2187 bool inverse_function=
false,
bool drop_zeros=
true);
2229 bool auto_center, float_type
y1);
2246 float_type x0, float_type y0, float_type yp0, float_type ypp0,
2247 float_type x2, float_type
y2, float_type yp2, float_type ypp2,
2248 bool auto_center, float_type y1);
2260 bool auto_center, float_type y1);
2265 float_type
x, float_type *yprime,
2266 float_type *yprime2)
const ;
2272 bool auto_center, float_type y1);
2310 float_type
x, float_type *yprime,
2311 float_type *yprime2)
const ;
2331 #include "c2_function.icc"