Sort all includes in src/gromacs
[alexxy/gromacs.git] / src / gromacs / math / utilities.c
index e96a6de07b4a3273c688013136d00900688bbd3f..03b7134427da15d9a9509925dacebdf899ed1c9a 100644 (file)
  * To help us fund GROMACS development, we humbly ask that you cite
  * the research papers on the package. Check out http://www.gromacs.org.
  */
-#include "gromacs/math/utilities.h"
+#include "gmxpre.h"
 
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
+#include "utilities.h"
 
-#include <math.h>
+#include "config.h"
+
+#include <assert.h>
 #include <limits.h>
+#include <math.h>
+
 #ifdef HAVE__FINITE
 #include <float.h>
 #endif
@@ -59,11 +61,11 @@ real cuberoot(real x)
 {
     if (x < 0)
     {
-        return (-pow(-x, 1.0/DIM));
+        return (-pow(-x, 1.0/3.0));
     }
     else
     {
-        return (pow(x, 1.0/DIM));
+        return (pow(x, 1.0/3.0));
     }
 }
 
@@ -95,20 +97,6 @@ real sign(real x, real y)
  * ====================================================
  */
 
-#if ( (defined SIZEOF_INT && SIZEOF_INT == 4) || (SIZEOF_INT_MAX == 2147483647) )
-typedef int erf_int32_t;
-typedef unsigned int erf_u_int32_t;
-#elif (LONG_MAX == 2147483647L)
-typedef long erf_int32_t;
-typedef unsigned long erf_u_int32_t;
-#elif (SHRT_MAX == 2147483647)
-typedef short erf_int32_t;
-typedef unsigned short erf_u_int32_t;
-#else
-#  error ERROR: No 32 bit wide integer type found!
-#endif
-
-
 static const double
     tiny        = 1e-300,
     half        =  5.00000000000000000000e-01, /* 0x3FE00000, 0x00000000 */
@@ -186,8 +174,8 @@ static const double
 
 double gmx_erfd(double x)
 {
-
-    erf_int32_t hx, ix, i;
+#ifdef GMX_FLOAT_FORMAT_IEEE754
+    gmx_int32_t hx, ix, i;
     double      R, S, P, Q, s, y, z, r;
 
     union
@@ -199,9 +187,7 @@ double gmx_erfd(double x)
 
     conv.d = x;
 
-    /* In release-4-6 and later branches, only the test for
-     * GMX_IEEE754_BIG_ENDIAN_WORD_ORDER will be required. */
-#if defined(IEEE754_BIG_ENDIAN_WORD_ORDER) || defined(GMX_IEEE754_BIG_ENDIAN_WORD_ORDER)
+#ifdef GMX_IEEE754_BIG_ENDIAN_WORD_ORDER
     hx = conv.i[0];
 #else
     hx = conv.i[1];
@@ -211,7 +197,7 @@ double gmx_erfd(double x)
     if (ix >= 0x7ff00000)
     {
         /* erf(nan)=nan */
-        i = ((erf_u_int32_t)hx>>31)<<1;
+        i = ((gmx_uint32_t)hx>>31)<<1;
         return (double)(1-i)+one/x; /* erf(+-inf)=+-1 */
     }
 
@@ -277,9 +263,7 @@ double gmx_erfd(double x)
 
     conv.d = x;
 
-    /* In release-4-6 and later branches, only the test for
-     * GMX_IEEE754_BIG_ENDIAN_WORD_ORDER will be required. */
-#if defined(IEEE754_BIG_ENDIAN_WORD_ORDER) || defined(GMX_IEEE754_BIG_ENDIAN_WORD_ORDER)
+#ifdef GMX_IEEE754_BIG_ENDIAN_WORD_ORDER
     conv.i[1] = 0;
 #else
     conv.i[0] = 0;
@@ -296,12 +280,17 @@ double gmx_erfd(double x)
     {
         return r/x-one;
     }
+#else
+    /* No IEEE754 information. We need to trust that the OS provides erf(). */
+    return erf(x);
+#endif
 }
 
 
 double gmx_erfcd(double x)
 {
-    erf_int32_t hx, ix;
+#ifdef GMX_FLOAT_FORMAT_IEEE754
+    gmx_int32_t hx, ix;
     double      R, S, P, Q, s, y, z, r;
 
     union
@@ -313,9 +302,7 @@ double gmx_erfcd(double x)
 
     conv.d = x;
 
-    /* In release-4-6 and later branches, only the test for
-     * GMX_IEEE754_BIG_ENDIAN_WORD_ORDER will be required. */
-#if defined(IEEE754_BIG_ENDIAN_WORD_ORDER) || defined(GMX_IEEE754_BIG_ENDIAN_WORD_ORDER)
+#ifdef GMX_IEEE754_BIG_ENDIAN_WORD_ORDER
     hx = conv.i[0];
 #else
     hx = conv.i[1];
@@ -326,7 +313,7 @@ double gmx_erfcd(double x)
     {
         /* erfc(nan)=nan */
         /* erfc(+-inf)=0,2 */
-        return (double)(((erf_u_int32_t)hx>>31)<<1)+one/x;
+        return (double)(((gmx_uint32_t)hx>>31)<<1)+one/x;
     }
 
     if (ix < 0x3feb0000)
@@ -393,9 +380,7 @@ double gmx_erfcd(double x)
 
         conv.d = x;
 
-        /* In release-4-6 and later branches, only the test for
-         * GMX_IEEE754_BIG_ENDIAN_WORD_ORDER will be required. */
-#if defined(IEEE754_BIG_ENDIAN_WORD_ORDER) || defined(GMX_IEEE754_BIG_ENDIAN_WORD_ORDER)
+#ifdef GMX_IEEE754_BIG_ENDIAN_WORD_ORDER
         conv.i[1] = 0;
 #else
         conv.i[0] = 0;
@@ -425,6 +410,10 @@ double gmx_erfcd(double x)
             return two-tiny;
         }
     }
+#else
+    /* No IEEE754 information. We need to trust that the OS provides erfc(). */
+    return erfc(x);
+#endif
 }
 
 
@@ -507,7 +496,7 @@ static const float
 typedef union
 {
     float         value;
-    erf_u_int32_t word;
+    gmx_uint32_t  word;
 } ieee_float_shape_type;
 
 #define GET_FLOAT_WORD(i, d)                 \
@@ -528,7 +517,7 @@ typedef union
 
 float gmx_erff(float x)
 {
-    erf_int32_t hx, ix, i;
+    gmx_int32_t hx, ix, i;
     float       R, S, P, Q, s, y, z, r;
 
     union
@@ -545,7 +534,7 @@ float gmx_erff(float x)
     if (ix >= 0x7f800000)
     {
         /* erf(nan)=nan */
-        i = ((erf_u_int32_t)hx>>31)<<1;
+        i = ((gmx_uint32_t)hx>>31)<<1;
         return (float)(1-i)+onef/x; /* erf(+-inf)=+-1 */
     }
 
@@ -626,7 +615,7 @@ float gmx_erff(float x)
 
 float gmx_erfcf(float x)
 {
-    erf_int32_t hx, ix;
+    gmx_int32_t hx, ix;
     float       R, S, P, Q, s, y, z, r;
 
     union
@@ -644,7 +633,7 @@ float gmx_erfcf(float x)
     {
         /* erfc(nan)=nan */
         /* erfc(+-inf)=0,2 */
-        return (float)(((erf_u_int32_t)hx>>31)<<1)+onef/x;
+        return (float)(((gmx_uint32_t)hx>>31)<<1)+onef/x;
     }
 
     if (ix < 0x3f580000)
@@ -737,9 +726,7 @@ float gmx_erfcf(float x)
 
 gmx_bool gmx_isfinite(real gmx_unused x)
 {
-    gmx_bool returnval = TRUE;
-    /* If no suitable function was found, assume the value is
-     * finite. */
+    gmx_bool returnval;
 
 #ifdef HAVE__FINITE
     returnval = _finite(x);
@@ -747,13 +734,16 @@ gmx_bool gmx_isfinite(real gmx_unused x)
     returnval = isfinite(x);
 #elif defined HAVE__ISFINITE
     returnval = _isfinite(x);
+#else
+    /* If no suitable function was found, assume the value is
+     * finite. */
+    returnval = TRUE;
 #endif
     return returnval;
 }
 
 gmx_bool gmx_isnan(real x)
 {
-    /* cppcheck-suppress duplicateExpression */
     return x != x;
 }
 
@@ -779,12 +769,45 @@ gmx_numzero(double a)
     return gmx_within_tol(a, 0.0, GMX_REAL_MIN/GMX_REAL_EPS);
 }
 
-real
-gmx_log2(real x)
+unsigned int
+gmx_log2i(unsigned int n)
 {
-    const real iclog2 = 1.0/log( 2.0 );
+    assert(n != 0); /* behavior differs for 0 */
+#if defined(__INTEL_COMPILER)
+    return _bit_scan_reverse(n);
+#elif defined(__GNUC__) && UINT_MAX == 4294967295U /*also for clang*/
+    return __builtin_clz(n) ^ 31U;                 /* xor gets optimized out */
+#elif defined(_MSC_VER) && _MSC_VER >= 1400
+    {
+        unsigned long i;
+        _BitScanReverse(&i, n);
+        return i;
+    }
+#elif defined(__xlC__)
+    return 31 - __cntlz4(n);
+#else
+    /* http://graphics.stanford.edu/~seander/bithacks.html#IntegerLogLookup */
+#define LT(n) n, n, n, n, n, n, n, n, n, n, n, n, n, n, n, n
+    static const char     LogTable256[256] = {
+        -1, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3,
+        LT(4), LT(5), LT(5), LT(6), LT(6), LT(6), LT(6),
+        LT(7), LT(7), LT(7), LT(7), LT(7), LT(7), LT(7), LT(7)
+    };
+#undef LT
+
+    unsigned int r;     /* r will be lg(n) */
+    unsigned int t, tt; /* temporaries */
 
-    return log( x ) * iclog2;
+    if ((tt = n >> 16) != 0)
+    {
+        r = ((t = tt >> 8) != 0) ? 24 + LogTable256[t] : 16 + LogTable256[tt];
+    }
+    else
+    {
+        r = ((t = n >> 8) != 0) ? 8 + LogTable256[t] : LogTable256[n];
+    }
+    return r;
+#endif
 }
 
 gmx_bool