36 #ifndef VIGRA_MATHUTIL_HXX 
   37 #define VIGRA_MATHUTIL_HXX 
   40 # pragma warning (disable: 4996) // hypot/_hypot confusion 
   49 #include "sized_int.hxx" 
   50 #include "numerictraits.hxx" 
   51 #include "algorithm.hxx" 
   90 #    define M_PI     3.14159265358979323846 
   94 #    define M_2_PI   0.63661977236758134308 
   98 #    define M_PI_2   1.57079632679489661923 
  102 #    define M_PI_4   0.78539816339744830962 
  106 #    define M_SQRT2  1.41421356237309504880 
  110 #    define M_E      2.71828182845904523536 
  113 #ifndef M_EULER_GAMMA 
  114 #    define M_EULER_GAMMA  0.5772156649015329 
  126 using VIGRA_CSTD::pow;
 
  138 #define VIGRA_DEFINE_UNSIGNED_ABS(T) \ 
  139     inline T abs(T t) { return t; } 
  141 VIGRA_DEFINE_UNSIGNED_ABS(
bool)
 
  142 VIGRA_DEFINE_UNSIGNED_ABS(
unsigned char)
 
  143 VIGRA_DEFINE_UNSIGNED_ABS(
unsigned short)
 
  144 VIGRA_DEFINE_UNSIGNED_ABS(
unsigned int)
 
  145 VIGRA_DEFINE_UNSIGNED_ABS(
unsigned long)
 
  146 VIGRA_DEFINE_UNSIGNED_ABS(
unsigned long long)
 
  148 #undef VIGRA_DEFINE_UNSIGNED_ABS 
  150 #define VIGRA_DEFINE_MISSING_ABS(T) \ 
  151     inline T abs(T t) { return t < 0 ? static_cast<T>(-t) : t; } 
  153 VIGRA_DEFINE_MISSING_ABS(
signed char)
 
  154 VIGRA_DEFINE_MISSING_ABS(
signed short)
 
  156 #if defined(_MSC_VER) && _MSC_VER < 1600 
  157 VIGRA_DEFINE_MISSING_ABS(
signed long long)
 
  160 #undef VIGRA_DEFINE_MISSING_ABS 
  170 template <
class REAL>
 
  171 inline bool isinf(REAL v)
 
  173     return _finite(v) == 0 && _isnan(v) == 0;
 
  176 template <
class REAL>
 
  177 inline bool isnan(REAL v)
 
  179     return _isnan(v) != 0;
 
  182 template <
class REAL>
 
  183 inline bool isfinite(REAL v)
 
  185     return _finite(v) != 0;
 
  193 #define VIGRA_DEFINE_SCALAR_DOT(T) \ 
  194     inline NumericTraits<T>::Promote dot(T l, T r) { return l*r; } 
  196 VIGRA_DEFINE_SCALAR_DOT(
unsigned char)
 
  197 VIGRA_DEFINE_SCALAR_DOT(
unsigned short)
 
  198 VIGRA_DEFINE_SCALAR_DOT(
unsigned int)
 
  199 VIGRA_DEFINE_SCALAR_DOT(
unsigned long)
 
  200 VIGRA_DEFINE_SCALAR_DOT(
unsigned long long)
 
  201 VIGRA_DEFINE_SCALAR_DOT(
signed char)
 
  202 VIGRA_DEFINE_SCALAR_DOT(
signed short)
 
  203 VIGRA_DEFINE_SCALAR_DOT(
signed int)
 
  204 VIGRA_DEFINE_SCALAR_DOT(
signed long)
 
  205 VIGRA_DEFINE_SCALAR_DOT(
signed long long)
 
  206 VIGRA_DEFINE_SCALAR_DOT(
float)
 
  207 VIGRA_DEFINE_SCALAR_DOT(
double)
 
  208 VIGRA_DEFINE_SCALAR_DOT(
long double)
 
  210 #undef VIGRA_DEFINE_SCALAR_DOT 
  216 inline float pow(
float v, 
double e)
 
  218     return std::pow(v, (
float)e);
 
  221 inline long double pow(
long double v, 
double e)
 
  223     return std::pow(v, (
long double)e);
 
  234 #ifdef DOXYGEN // only for documentation 
  238 inline float round(
float t)
 
  245 inline double round(
double t)
 
  252 inline long double round(
long double t)
 
  271                 ? (
long long)(t + 0.5)
 
  272                 : (
long long)(t - 0.5);
 
  280     return x && !(x & (x - 1));
 
  332     static Int32 table[64];
 
  336 Int32 IntLog2<T>::table[64] = {
 
  337          -1,  0,  -1,  15,  -1,  1,  28,  -1,  16,  -1,  -1,  -1,  2,  21,
 
  338          29,  -1,  -1,  -1,  19,  17,  10,  -1,  12,  -1,  -1,  3,  -1,  6,
 
  339          -1,  22,  30,  -1,  14,  -1,  27,  -1,  -1,  -1,  20,  -1,  18,  9,
 
  340          11,  -1,  5,  -1,  -1,  13,  26,  -1,  -1,  8,  -1,  4,  -1,  25,
 
  341          -1,  7,  24,  -1,  23,  -1,  31,  -1};
 
  370     return detail::IntLog2<Int32>::table[x >> 26];
 
  382 typename NumericTraits<T>::Promote 
sq(T t)
 
  389 template <
class V, 
unsigned>
 
  392     static V call(
const V & x, 
const V & y) { 
return x * y; }
 
  395 struct cond_mult<V, 0>
 
  397     static V call(
const V &, 
const V & y) { 
return y; }
 
  400 template <
class V, 
unsigned n>
 
  403     static V call(
const V & x)
 
  406             ? cond_mult<V, n & 1>::call(x, power_static<V, n / 2>::call(x * x))
 
  411 struct power_static<V, 0>
 
  413     static V call(
const V & )
 
  426 template <
unsigned n, 
class V>
 
  429     return detail::power_static<V, n>::call(x);
 
  438     static UInt32 sqq_table[];
 
  443 UInt32 IntSquareRoot<T>::sqq_table[] = {
 
  444            0,  16,  22,  27,  32,  35,  39,  42,  45,  48,  50,  53,  55,  57,
 
  445           59,  61,  64,  65,  67,  69,  71,  73,  75,  76,  78,  80,  81,  83,
 
  446           84,  86,  87,  89,  90,  91,  93,  94,  96,  97,  98,  99, 101, 102,
 
  447          103, 104, 106, 107, 108, 109, 110, 112, 113, 114, 115, 116, 117, 118,
 
  448          119, 120, 121, 122, 123, 124, 125, 126, 128, 128, 129, 130, 131, 132,
 
  449          133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 144, 145,
 
  450          146, 147, 148, 149, 150, 150, 151, 152, 153, 154, 155, 155, 156, 157,
 
  451          158, 159, 160, 160, 161, 162, 163, 163, 164, 165, 166, 167, 167, 168,
 
  452          169, 170, 170, 171, 172, 173, 173, 174, 175, 176, 176, 177, 178, 178,
 
  453          179, 180, 181, 181, 182, 183, 183, 184, 185, 185, 186, 187, 187, 188,
 
  454          189, 189, 190, 191, 192, 192, 193, 193, 194, 195, 195, 196, 197, 197,
 
  455          198, 199, 199, 200, 201, 201, 202, 203, 203, 204, 204, 205, 206, 206,
 
  456          207, 208, 208, 209, 209, 210, 211, 211, 212, 212, 213, 214, 214, 215,
 
  457          215, 216, 217, 217, 218, 218, 219, 219, 220, 221, 221, 222, 222, 223,
 
  458          224, 224, 225, 225, 226, 226, 227, 227, 228, 229, 229, 230, 230, 231,
 
  459          231, 232, 232, 233, 234, 234, 235, 235, 236, 236, 237, 237, 238, 238,
 
  460          239, 240, 240, 241, 241, 242, 242, 243, 243, 244, 244, 245, 245, 246,
 
  461          246, 247, 247, 248, 248, 249, 249, 250, 250, 251, 251, 252, 252, 253,
 
  472                 if (x >= 0x40000000) {
 
  475                     xn = sqq_table[x>>24] << 8;
 
  477                     xn = sqq_table[x>>22] << 7;
 
  480                     xn = sqq_table[x>>20] << 6;
 
  482                     xn = sqq_table[x>>18] << 5;
 
  486                     xn = sqq_table[x>>16] << 4;
 
  488                     xn = sqq_table[x>>14] << 3;
 
  491                     xn = sqq_table[x>>12] << 2;
 
  493                     xn = sqq_table[x>>10] << 1;
 
  501                     xn = (sqq_table[x>>8] >> 0) + 1;
 
  503                     xn = (sqq_table[x>>6] >> 1) + 1;
 
  506                     xn = (sqq_table[x>>4] >> 2) + 1;
 
  508                     xn = (sqq_table[x>>2] >> 3) + 1;
 
  512             return sqq_table[x] >> 4;
 
  516     xn = (xn + 1 + x / xn) / 2;
 
  518     xn = (xn + 1 + x / xn) / 2;
 
  541         throw std::domain_error(
"sqrti(Int32): negative argument.");
 
  542     return (
Int32)detail::IntSquareRoot<UInt32>::exec((
UInt32)v);
 
  554     return detail::IntSquareRoot<UInt32>::exec(v);
 
  557 #ifdef VIGRA_NO_HYPOT 
  566 inline double hypot(
double a, 
double b)
 
  568     double absa = VIGRA_CSTD::fabs(a), absb = VIGRA_CSTD::fabs(b);
 
  593     return t > NumericTraits<T>::zero()
 
  594                ? NumericTraits<T>::one()
 
  595                : t < NumericTraits<T>::zero()
 
  596                     ? -NumericTraits<T>::one()
 
  597                     : NumericTraits<T>::zero();
 
  610     return t > NumericTraits<T>::zero()
 
  612                : t < NumericTraits<T>::zero()
 
  624 template <
class T1, 
class T2>
 
  627     return t2 >= NumericTraits<T2>::zero()
 
  633 #ifdef DOXYGEN // only for documentation 
  648 #define VIGRA_DEFINE_ODD_EVEN(T) \ 
  649     inline bool even(T t) { return (t&1) == 0; } \ 
  650     inline bool odd(T t)  { return (t&1) == 1; } 
  652 VIGRA_DEFINE_ODD_EVEN(
char)
 
  653 VIGRA_DEFINE_ODD_EVEN(
short)
 
  654 VIGRA_DEFINE_ODD_EVEN(
int)
 
  655 VIGRA_DEFINE_ODD_EVEN(
long)
 
  656 VIGRA_DEFINE_ODD_EVEN(
long long)
 
  657 VIGRA_DEFINE_ODD_EVEN(
unsigned char)
 
  658 VIGRA_DEFINE_ODD_EVEN(
unsigned short)
 
  659 VIGRA_DEFINE_ODD_EVEN(
unsigned int)
 
  660 VIGRA_DEFINE_ODD_EVEN(
unsigned long)
 
  661 VIGRA_DEFINE_ODD_EVEN(
unsigned long long)
 
  663 #undef VIGRA_DEFINE_ODD_EVEN 
  665 #define VIGRA_DEFINE_NORM(T) \ 
  666     inline NormTraits<T>::SquaredNormType squaredNorm(T t) { return sq(t); } \ 
  667     inline NormTraits<T>::NormType norm(T t) { return abs(t); } 
  669 VIGRA_DEFINE_NORM(
bool)
 
  670 VIGRA_DEFINE_NORM(
signed char)
 
  671 VIGRA_DEFINE_NORM(
unsigned char)
 
  672 VIGRA_DEFINE_NORM(
short)
 
  673 VIGRA_DEFINE_NORM(
unsigned short)
 
  674 VIGRA_DEFINE_NORM(
int)
 
  675 VIGRA_DEFINE_NORM(
unsigned int)
 
  676 VIGRA_DEFINE_NORM(
long)
 
  677 VIGRA_DEFINE_NORM(
unsigned long)
 
  678 VIGRA_DEFINE_NORM(
long long)
 
  679 VIGRA_DEFINE_NORM(
unsigned long long)
 
  680 VIGRA_DEFINE_NORM(
float)
 
  681 VIGRA_DEFINE_NORM(
double)
 
  682 VIGRA_DEFINE_NORM(
long double)
 
  684 #undef VIGRA_DEFINE_NORM 
  687 inline typename NormTraits<std::complex<T> >::SquaredNormType
 
  690     return sq(t.real()) + 
sq(t.imag());
 
  693 #ifdef DOXYGEN // only for documentation 
  703 NormTraits<T>::SquaredNormType 
squaredNorm(T 
const & t);
 
  716 inline typename NormTraits<T>::NormType
 
  719     typedef typename NormTraits<T>::SquaredNormType SNT;
 
  720     return sqrt(
static_cast<typename SquareRootTraits<SNT>::SquareRootArgument
>(
squaredNorm(t)));
 
  736     double d  = 
hypot(a00 - a11, 2.0*a01);
 
  737     *r0 = 
static_cast<T
>(0.5*(a00 + a11 + d));
 
  738     *r1 = 
static_cast<T
>(0.5*(a00 + a11 - d));
 
  755                              T * r0, T * r1, T * r2)
 
  757     double inv3 = 1.0 / 3.0, root3 = 
std::sqrt(3.0);
 
  759     double c0 = a00*a11*a22 + 2.0*a01*a02*a12 - a00*a12*a12 - a11*a02*a02 - a22*a01*a01;
 
  760     double c1 = a00*a11 - a01*a01 + a00*a22 - a02*a02 + a11*a22 - a12*a12;
 
  761     double c2 = a00 + a11 + a22;
 
  762     double c2Div3 = c2*inv3;
 
  763     double aDiv3 = (c1 - c2*c2Div3)*inv3;
 
  766     double mbDiv2 = 0.5*(c0 + c2Div3*(2.0*c2Div3*c2Div3 - c1));
 
  767     double q = mbDiv2*mbDiv2 + aDiv3*aDiv3*aDiv3;
 
  774     *r0 = 
static_cast<T
>(c2Div3 + 2.0*magnitude*cs);
 
  775     *r1 = 
static_cast<T
>(c2Div3 - magnitude*(cs + root3*sn));
 
  776     *r2 = 
static_cast<T
>(c2Div3 - magnitude*(cs - root3*sn));
 
  788 T ellipticRD(T x, T y, T z)
 
  790     double f = 1.0, s = 0.0, X, Y, Z, m;
 
  793         m = (x + y + 3.0*z) / 5.0;
 
  797         if(std::max(std::max(VIGRA_CSTD::fabs(X), VIGRA_CSTD::fabs(Y)), VIGRA_CSTD::fabs(Z)) < 0.01)
 
  809     double d = a - 6.0*b;
 
  810     double e = d + 2.0*c;
 
  811     return 3.0*s + f*(1.0+d*(-3.0/14.0+d*9.0/88.0-Z*e*4.5/26.0)
 
  812                       +Z*(e/6.0+Z*(-c*9.0/22.0+a*Z*3.0/26.0))) / VIGRA_CSTD::pow(m,1.5);
 
  816 T ellipticRF(T x, T y, T z)
 
  821         m = (x + y + z) / 3.0;
 
  825         if(std::max(std::max(VIGRA_CSTD::fabs(X), VIGRA_CSTD::fabs(Y)), VIGRA_CSTD::fabs(Z)) < 0.01)
 
  832     double d = X*Y - 
sq(Z);
 
  859     return s*detail::ellipticRF(c2, 1.0 - 
sq(k*s), 1.0);
 
  884     return s*(detail::ellipticRF(c2, 1.0-k, 1.0) - k/3.0*detail::ellipticRD(c2, 1.0-k, 1.0));
 
  887 #if defined(_MSC_VER) && _MSC_VER < 1800 
  894     double t = 1.0/(1.0+0.5*VIGRA_CSTD::fabs(x));
 
  895     double ans = t*
VIGRA_CSTD::exp(-x*x-1.26551223+t*(1.00002368+t*(0.37409196+
 
  896                                     t*(0.09678418+t*(-0.18628806+t*(0.27886807+
 
  897                                     t*(-1.13520398+t*(1.48851587+t*(-0.82215223+
 
  898                                     t*0.17087277)))))))));
 
  922 inline double erf(
double x)
 
  924     return detail::erfImpl(x);
 
  938     double a = degreesOfFreedom + noncentrality;
 
  939     double b = (a + noncentrality) / 
sq(a);
 
  940     double t = (VIGRA_CSTD::pow((
double)arg / a, 1.0/3.0) - (1.0 - 2.0 / 9.0 * b)) / 
VIGRA_CSTD::sqrt(2.0 / 9.0 * b);
 
  945 void noncentralChi2OneIteration(T arg, T & lans, T & dans, T & pans, 
unsigned int & j)
 
  955         dans = dans * arg / j;
 
  962 std::pair<double, double> 
noncentralChi2CDF(
unsigned int degreesOfFreedom, T noncentrality, T arg, T eps)
 
  964     vigra_precondition(noncentrality >= 0.0 && arg >= 0.0 && eps > 0.0,
 
  965         "noncentralChi2P(): parameters must be positive.");
 
  966     if (arg == 0.0 && degreesOfFreedom > 0)
 
  967         return std::make_pair(0.0, 0.0);
 
  970     double b1 = 0.5 * noncentrality,
 
  973            lnrtpi2 = 0.22579135264473,
 
  974            probability, density, lans, dans, pans, 
sum, am, hold;
 
  975     unsigned int maxit = 500,
 
  977     if(degreesOfFreedom % 2)
 
  993     if(degreesOfFreedom == 0)
 
  996         degreesOfFreedom = 2;
 
  998         sum = 1.0 / ao - 1.0 - am;
 
 1000         probability = 1.0 + am * pans;
 
 1005         degreesOfFreedom = degreesOfFreedom - 1;
 
 1007         sum = 1.0 / ao - 1.0;
 
 1008         while(i < degreesOfFreedom)
 
 1009             detail::noncentralChi2OneIteration(arg, lans, dans, pans, i);
 
 1010         degreesOfFreedom = degreesOfFreedom + 1;
 
 1015     for(++m; m<maxit; ++m)
 
 1018         detail::noncentralChi2OneIteration(arg, lans, dans, pans, degreesOfFreedom);
 
 1020         density = density + am * dans;
 
 1022         probability = probability + hold;
 
 1023         if((pans * sum < eps2) && (hold < eps2))
 
 1027         vigra_fail(
"noncentralChi2P(): no convergence.");
 
 1028     return std::make_pair(0.5 * ao * density, std::min(1.0, std::max(0.0, ao * probability)));
 
 1042 inline double chi2(
unsigned int degreesOfFreedom, 
double arg, 
double accuracy = 1e-7)
 
 1057 inline double chi2CDF(
unsigned int degreesOfFreedom, 
double arg, 
double accuracy = 1e-7)
 
 1074               double noncentrality, 
double arg, 
double accuracy = 1e-7)
 
 1092               double noncentrality, 
double arg, 
double accuracy = 1e-7)
 
 1123     T tmp = NumericTraits<T>::one();
 
 1124     for(T f = l-m+1; f <= l+m; ++f)
 
 1141 template <
class REAL>
 
 1144     vigra_precondition(
abs(x) <= 1.0, 
"legendre(): x must be in [-1.0, 1.0].");
 
 1151         return legendre(l,m,x) * s / detail::facLM<REAL>(l,m);
 
 1156         REAL r = 
std::sqrt( (1.0-x) * (1.0+x) );
 
 1158         for (
int i=1; i<=m; i++)
 
 1167     REAL result_1 = x * (2.0 * m + 1.0) * result;
 
 1171     for(
unsigned int i = m+2; i <= l; ++i)
 
 1173         other = ( (2.0*i-1.0) * x * result_1 - (i+m-1.0)*result) / (i-m);
 
 1188 template <
class REAL>
 
 1203 template <
class REAL>
 
 1211     bool invert = 
false;
 
 1225         rem = NumericTraits<REAL>::one();
 
 1241 template <
class REAL>
 
 1249 template <
class REAL>
 
 1252     static REAL 
gamma(REAL x);
 
 1265 template <
class REAL>
 
 1266 double GammaImpl<REAL>::g[] = {
 
 1269    -0.6558780715202538,
 
 1270    -0.420026350340952e-1,
 
 1272    -0.421977345555443e-1,
 
 1273    -0.9621971527877e-2,
 
 1275    -0.11651675918591e-2,
 
 1276    -0.2152416741149e-3,
 
 1294 template <
class REAL>
 
 1295 double GammaImpl<REAL>::a[] = {
 
 1296     7.72156649015328655494e-02,
 
 1297     3.22467033424113591611e-01,
 
 1298     6.73523010531292681824e-02,
 
 1299     2.05808084325167332806e-02,
 
 1300     7.38555086081402883957e-03,
 
 1301     2.89051383673415629091e-03,
 
 1302     1.19270763183362067845e-03,
 
 1303     5.10069792153511336608e-04,
 
 1304     2.20862790713908385557e-04,
 
 1305     1.08011567247583939954e-04,
 
 1306     2.52144565451257326939e-05,
 
 1307     4.48640949618915160150e-05
 
 1310 template <
class REAL>
 
 1311 double GammaImpl<REAL>::t[] = {
 
 1312     4.83836122723810047042e-01,
 
 1313     -1.47587722994593911752e-01,
 
 1314     6.46249402391333854778e-02,
 
 1315     -3.27885410759859649565e-02,
 
 1316     1.79706750811820387126e-02,
 
 1317     -1.03142241298341437450e-02,
 
 1318     6.10053870246291332635e-03,
 
 1319     -3.68452016781138256760e-03,
 
 1320     2.25964780900612472250e-03,
 
 1321     -1.40346469989232843813e-03,
 
 1322     8.81081882437654011382e-04,
 
 1323     -5.38595305356740546715e-04,
 
 1324     3.15632070903625950361e-04,
 
 1325     -3.12754168375120860518e-04,
 
 1326     3.35529192635519073543e-04
 
 1329 template <
class REAL>
 
 1330 double GammaImpl<REAL>::u[] = {
 
 1331     -7.72156649015328655494e-02,
 
 1332     6.32827064025093366517e-01,
 
 1333     1.45492250137234768737e+00,
 
 1334     9.77717527963372745603e-01,
 
 1335     2.28963728064692451092e-01,
 
 1336     1.33810918536787660377e-02
 
 1339 template <
class REAL>
 
 1340 double GammaImpl<REAL>::v[] = {
 
 1342     2.45597793713041134822e+00,
 
 1343     2.12848976379893395361e+00,
 
 1344     7.69285150456672783825e-01,
 
 1345     1.04222645593369134254e-01,
 
 1346     3.21709242282423911810e-03
 
 1349 template <
class REAL>
 
 1350 double GammaImpl<REAL>::s[] = {
 
 1351     -7.72156649015328655494e-02,
 
 1352     2.14982415960608852501e-01,
 
 1353     3.25778796408930981787e-01,
 
 1354     1.46350472652464452805e-01,
 
 1355     2.66422703033638609560e-02,
 
 1356     1.84028451407337715652e-03,
 
 1357     3.19475326584100867617e-05
 
 1360 template <
class REAL>
 
 1361 double GammaImpl<REAL>::r[] = {
 
 1363     1.39200533467621045958e+00,
 
 1364     7.21935547567138069525e-01,
 
 1365     1.71933865632803078993e-01,
 
 1366     1.86459191715652901344e-02,
 
 1367     7.77942496381893596434e-04,
 
 1368     7.32668430744625636189e-06
 
 1371 template <
class REAL>
 
 1372 double GammaImpl<REAL>::w[] = {
 
 1373     4.18938533204672725052e-01,
 
 1374     8.33333333333329678849e-02,
 
 1375     -2.77777777728775536470e-03,
 
 1376     7.93650558643019558500e-04,
 
 1377     -5.95187557450339963135e-04,
 
 1378     8.36339918996282139126e-04,
 
 1379     -1.63092934096575273989e-03
 
 1382 template <
class REAL>
 
 1385     int i, k, m, ix = (int)x;
 
 1386     double ga = 0.0, gr = 0.0, r = 0.0, z = 0.0;
 
 1388     vigra_precondition(x <= 171.0,
 
 1389         "gamma(): argument cannot exceed 171.0.");
 
 1396             for (i=2; i<ix; ++i)
 
 1403             vigra_precondition(
false,
 
 1404                  "gamma(): gamma function is undefined for 0 and negative integers.");
 
 1414             for (k=1; k<=m; ++k)
 
 1425         for (k=23; k>=0; --k)
 
 1435                 ga = -M_PI/(x*ga*
sin_pi(x));
 
 1455 template <
class REAL>
 
 1458     vigra_precondition(x > 0.0,
 
 1459         "loggamma(): argument must be positive.");
 
 1461     vigra_precondition(x <= 1.0e307,
 
 1462         "loggamma(): argument must not exceed 1e307.");
 
 1466     if (x < 4.2351647362715017e-22)
 
 1470     else if ((x == 2.0) || (x == 1.0))
 
 1476         const double tc  =  1.46163214496836224576e+00;
 
 1477         const double tf  = -1.21486290535849611461e-01;
 
 1478         const double tt  = -3.63867699703950536541e-18;
 
 1486                 double p1 = a[0]+z*(a[2]+z*(a[4]+z*(a[6]+z*(a[8]+z*a[10]))));
 
 1487                 double p2 = z*(a[1]+z*(a[3]+z*(a[5]+z*(a[7]+z*(a[9]+z*a[11])))));
 
 1491             else if (x >= 0.23164)
 
 1493                 double y = x-(tc-1.0);
 
 1496                 double p1 = t[0]+w*(t[3]+w*(t[6]+w*(t[9] +w*t[12])));
 
 1497                 double p2 = t[1]+w*(t[4]+w*(t[7]+w*(t[10]+w*t[13])));
 
 1498                 double p3 = t[2]+w*(t[5]+w*(t[8]+w*(t[11]+w*t[14])));
 
 1499                 double p  = z*p1-(tt-w*(p2+y*p3));
 
 1505                 double p1 = y*(u[0]+y*(u[1]+y*(u[2]+y*(u[3]+y*(u[4]+y*u[5])))));
 
 1506                 double p2 = 1.0+y*(v[1]+y*(v[2]+y*(v[3]+y*(v[4]+y*v[5]))));
 
 1507                 res += (-0.5*y + p1/p2);
 
 1517                 double p1 = a[0]+z*(a[2]+z*(a[4]+z*(a[6]+z*(a[8]+z*a[10]))));
 
 1518                 double p2 = z*(a[1]+z*(a[3]+z*(a[5]+z*(a[7]+z*(a[9]+z*a[11])))));
 
 1522             else if(x >= 1.23164)
 
 1527                 double p1 = t[0]+w*(t[3]+w*(t[6]+w*(t[9] +w*t[12])));
 
 1528                 double p2 = t[1]+w*(t[4]+w*(t[7]+w*(t[10]+w*t[13])));
 
 1529                 double p3 = t[2]+w*(t[5]+w*(t[8]+w*(t[11]+w*t[14])));
 
 1530                 double p  = z*p1-(tt-w*(p2+y*p3));
 
 1536                 double p1 = y*(u[0]+y*(u[1]+y*(u[2]+y*(u[3]+y*(u[4]+y*u[5])))));
 
 1537                 double p2 = 1.0+y*(v[1]+y*(v[2]+y*(v[3]+y*(v[4]+y*v[5]))));
 
 1538                 res += (-0.5*y + p1/p2);
 
 1546         double p = y*(s[0]+y*(s[1]+y*(s[2]+y*(s[3]+y*(s[4]+y*(s[5]+y*s[6]))))));
 
 1547         double q = 1.0+y*(r[1]+y*(r[2]+y*(r[3]+y*(r[4]+y*(r[5]+y*r[6])))));
 
 1557     else if (x < 2.8823037615171174e+17)
 
 1562         double yy = w[0]+z*(w[1]+y*(w[2]+y*(w[3]+y*(w[4]+y*(w[5]+y*w[6])))));
 
 1563         res = (x-0.5)*(t-1.0)+yy;
 
 1614 FPT safeFloatDivision( FPT f1, FPT f2 )
 
 1616     return  f2 < NumericTraits<FPT>::one() && f1 > f2 * NumericTraits<FPT>::max()
 
 1617                 ? NumericTraits<FPT>::max()
 
 1618                 : (f2 > NumericTraits<FPT>::one() && f1 < f2 * NumericTraits<FPT>::smallestPositive()) ||
 
 1619                    f1 == NumericTraits<FPT>::zero()
 
 1620                      ? NumericTraits<FPT>::zero()
 
 1636 template <
class T1, 
class T2>
 
 1640     typedef typename PromoteTraits<T1, T2>::Promote T;
 
 1642         return VIGRA_CSTD::fabs(r) <= epsilon;
 
 1644         return VIGRA_CSTD::fabs(l) <= epsilon;
 
 1645     T diff = VIGRA_CSTD::fabs( l - r );
 
 1646     T d1   = detail::safeFloatDivision<T>( diff, VIGRA_CSTD::fabs( r ) );
 
 1647     T d2   = detail::safeFloatDivision<T>( diff, VIGRA_CSTD::fabs( l ) );
 
 1649     return (d1 <= epsilon && d2 <= epsilon);
 
 1652 template <
class T1, 
class T2>
 
 1655     typedef typename PromoteTraits<T1, T2>::Promote T;
 
 1670 template <
class T1, 
class T2>
 
 1677 template <
class T1, 
class T2>
 
 1680     typedef typename PromoteTraits<T1, T2>::Promote T;
 
 1695 template <
class T1, 
class T2>
 
 1702 template <
class T1, 
class T2>
 
 1705     typedef typename PromoteTraits<T1, T2>::Promote T;
 
 1711 #define VIGRA_MATH_FUNC_HELPER(TYPE) \ 
 1712     inline TYPE clipLower(const TYPE t){ \ 
 1713         return t < static_cast<TYPE>(0.0) ? static_cast<TYPE>(0.0) : t; \ 
 1715     inline TYPE clipLower(const TYPE t,const TYPE valLow){ \ 
 1716         return t < static_cast<TYPE>(valLow) ? static_cast<TYPE>(valLow) : t; \ 
 1718     inline TYPE clipUpper(const TYPE t,const TYPE valHigh){ \ 
 1719         return t > static_cast<TYPE>(valHigh) ? static_cast<TYPE>(valHigh) : t; \ 
 1721     inline TYPE clip(const TYPE t,const TYPE valLow, const TYPE valHigh){ \ 
 1724         else if(t>valHigh) \ 
 1729     inline TYPE sum(const TYPE t){ \ 
 1732     inline NumericTraits<TYPE>::RealPromote mean(const TYPE t){ \ 
 1735     inline TYPE isZero(const TYPE t){ \ 
 1736         return t==static_cast<TYPE>(0); \ 
 1738     inline NumericTraits<TYPE>::RealPromote sizeDividedSquaredNorm(const TYPE t){ \ 
 1739         return  squaredNorm(t); \ 
 1741     inline NumericTraits<TYPE>::RealPromote sizeDividedNorm(const TYPE t){ \ 
 1747 #pragma GCC diagnostic push 
 1748 #pragma GCC diagnostic ignored "-Wtype-limits" 
 1751 VIGRA_MATH_FUNC_HELPER(
unsigned char)
 
 1752 VIGRA_MATH_FUNC_HELPER(
unsigned short)
 
 1753 VIGRA_MATH_FUNC_HELPER(
unsigned int)
 
 1754 VIGRA_MATH_FUNC_HELPER(
unsigned long)
 
 1755 VIGRA_MATH_FUNC_HELPER(
unsigned long long)
 
 1756 VIGRA_MATH_FUNC_HELPER(
signed char)
 
 1757 VIGRA_MATH_FUNC_HELPER(
signed short)
 
 1758 VIGRA_MATH_FUNC_HELPER(
signed int)
 
 1759 VIGRA_MATH_FUNC_HELPER(
signed long)
 
 1760 VIGRA_MATH_FUNC_HELPER(
signed long long)
 
 1761 VIGRA_MATH_FUNC_HELPER(
float)
 
 1762 VIGRA_MATH_FUNC_HELPER(
double)
 
 1763 VIGRA_MATH_FUNC_HELPER(
long double)
 
 1766 #pragma GCC diagnostic pop 
 1769 #undef VIGRA_MATH_FUNC_HELPER 
double ellipticIntegralF(double x, double k)
The incomplete elliptic integral of the first kind. 
Definition: mathutil.hxx:855
REAL sin_pi(REAL x)
sin(pi*x). 
Definition: mathutil.hxx:1204
FixedPoint16< 2, OverflowHandling > atan2(FixedPoint16< IntBits, OverflowHandling > y, FixedPoint16< IntBits, OverflowHandling > x)
Arctangent. Accuracy better than 1/3 degree (9 significant bits). 
Definition: fixedpoint.hxx:1654
R arg(const FFTWComplex< R > &a)
phase 
Definition: fftw3.hxx:1009
Int32 roundi(FixedPoint16< IntBits, OverflowHandling > v)
rounding to the nearest integer. 
Definition: fixedpoint.hxx:1775
linalg::TemporaryMatrix< T > sin(MultiArrayView< 2, T, C > const &v)
void symmetric3x3Eigenvalues(T a00, T a01, T a02, T a11, T a12, T a22, T *r0, T *r1, T *r2)
Compute the eigenvalues of a 3x3 real symmetric matrix. 
Definition: mathutil.hxx:754
linalg::TemporaryMatrix< T > exp(MultiArrayView< 2, T, C > const &v)
bool isPower2(UInt32 x)
Determine whether x is a power of 2 Bit twiddle from https://graphics.stanford.edu/~seander/bithacks...
Definition: mathutil.hxx:278
FFTWComplex< R >::SquaredNormType squaredNorm(const FFTWComplex< R > &a)
squared norm (= squared magnitude) 
Definition: fftw3.hxx:1044
V power(const V &x)
Exponentiation to a positive integer power by squaring. 
Definition: mathutil.hxx:427
int round(FixedPoint< IntBits, FracBits > v)
rounding to the nearest integer. 
Definition: fixedpoint.hxx:683
REAL legendre(unsigned int l, int m, REAL x)
Associated Legendre polynomial. 
Definition: mathutil.hxx:1142
int signi(T t)
The integer sign function. 
Definition: mathutil.hxx:608
bool greaterEqualAtTolerance(T1 l, T2 r, typename PromoteTraits< T1, T2 >::Promote epsilon)
Tolerance based floating-point greater-or-equal. 
Definition: mathutil.hxx:1697
FixedPoint16< IntBits, OverflowHandling > hypot(FixedPoint16< IntBits, OverflowHandling > v1, FixedPoint16< IntBits, OverflowHandling > v2)
Length of hypotenuse. 
Definition: fixedpoint.hxx:1640
bool odd(int t)
Check if an integer is odd. 
REAL cos_pi(REAL x)
cos(pi*x). 
Definition: mathutil.hxx:1242
double noncentralChi2(unsigned int degreesOfFreedom, double noncentrality, double arg, double accuracy=1e-7)
Non-central chi square distribution. 
Definition: mathutil.hxx:1073
FFTWComplex< R >::NormType norm(const FFTWComplex< R > &a)
norm (= magnitude) 
Definition: fftw3.hxx:1037
double noncentralChi2CDFApprox(unsigned int degreesOfFreedom, double noncentrality, double arg)
Cumulative non-central chi square distribution (approximate). 
Definition: mathutil.hxx:1111
Int32 log2i(UInt32 x)
Compute the base-2 logarithm of an integer. 
Definition: mathutil.hxx:361
NumericTraits< T >::Promote sq(T t)
The square function. 
Definition: mathutil.hxx:382
double noncentralChi2CDF(unsigned int degreesOfFreedom, double noncentrality, double arg, double accuracy=1e-7)
Cumulative non-central chi square distribution. 
Definition: mathutil.hxx:1091
NumericTraits< V >::Promote sum(TinyVectorBase< V, SIZE, D1, D2 > const &l)
sum of the vector's elements 
Definition: tinyvector.hxx:2073
detail::SelectIntegerType< 32, detail::SignedIntTypes >::type Int32
32-bit signed int 
Definition: sized_int.hxx:175
void symmetric2x2Eigenvalues(T a00, T a01, T a11, T *r0, T *r1)
Compute the eigenvalues of a 2x2 real symmetric matrix. 
Definition: mathutil.hxx:734
bool even(int t)
Check if an integer is even. 
double chi2CDF(unsigned int degreesOfFreedom, double arg, double accuracy=1e-7)
Cumulative chi square distribution. 
Definition: mathutil.hxx:1057
double gamma(double x)
The gamma function. 
Definition: mathutil.hxx:1587
bool closeAtTolerance(T1 l, T2 r, typename PromoteTraits< T1, T2 >::Promote epsilon)
Tolerance based floating-point equality. 
Definition: mathutil.hxx:1638
linalg::TemporaryMatrix< T > log(MultiArrayView< 2, T, C > const &v)
double loggamma(double x)
The natural logarithm of the gamma function. 
Definition: mathutil.hxx:1603
detail::SelectIntegerType< 32, detail::UnsignedIntTypes >::type UInt32
32-bit unsigned int 
Definition: sized_int.hxx:183
FFTWComplex< R >::NormType abs(const FFTWComplex< R > &a)
absolute value (= magnitude) 
Definition: fftw3.hxx:1002
Int32 sqrti(Int32 v)
Signed integer square root. 
Definition: mathutil.hxx:538
UInt32 floorPower2(UInt32 x)
Round down to the nearest power of 2. 
Definition: mathutil.hxx:317
double chi2(unsigned int degreesOfFreedom, double arg, double accuracy=1e-7)
Chi square distribution. 
Definition: mathutil.hxx:1042
UInt32 ceilPower2(UInt32 x)
Round up to the nearest power of 2. 
Definition: mathutil.hxx:294
int ceil(FixedPoint< IntBits, FracBits > v)
rounding up. 
Definition: fixedpoint.hxx:675
linalg::TemporaryMatrix< T > cos(MultiArrayView< 2, T, C > const &v)
bool lessEqualAtTolerance(T1 l, T2 r, typename PromoteTraits< T1, T2 >::Promote epsilon)
Tolerance based floating-point less-or-equal. 
Definition: mathutil.hxx:1672
T sign(T t)
The sign function. 
Definition: mathutil.hxx:591
int floor(FixedPoint< IntBits, FracBits > v)
rounding down. 
Definition: fixedpoint.hxx:667
double ellipticIntegralE(double x, double k)
The incomplete elliptic integral of the second kind. 
Definition: mathutil.hxx:879
SquareRootTraits< FixedPoint< IntBits, FracBits > >::SquareRootResult sqrt(FixedPoint< IntBits, FracBits > v)
square root. 
Definition: fixedpoint.hxx:616