summaryrefslogtreecommitdiff
path: root/numpy
diff options
context:
space:
mode:
Diffstat (limited to 'numpy')
-rw-r--r--numpy/core/include/numpy/ufuncobject.h5
-rw-r--r--numpy/core/setup.py105
-rw-r--r--numpy/core/src/_isnan.c46
-rw-r--r--numpy/core/src/_signbit.c2
-rw-r--r--numpy/core/src/math_c99.inc.src264
-rw-r--r--numpy/core/src/umathmodule.c.src635
-rw-r--r--numpy/distutils/command/config.py68
7 files changed, 444 insertions, 681 deletions
diff --git a/numpy/core/include/numpy/ufuncobject.h b/numpy/core/include/numpy/ufuncobject.h
index 91f37f99c..96934b820 100644
--- a/numpy/core/include/numpy/ufuncobject.h
+++ b/numpy/core/include/numpy/ufuncobject.h
@@ -263,11 +263,6 @@ typedef struct _loop1d_info {
| ((SW_INVALID & fpstatus) ? UFUNC_FPE_INVALID : 0); \
}
-#define isnan(x) (_isnan((double)(x)))
-#define isinf(x) ((_fpclass((double)(x)) == _FPCLASS_PINF) || \
- (_fpclass((double)(x)) == _FPCLASS_NINF))
-#define isfinite(x) (_finite((double) x))
-
/* Solaris --------------------------------------------------------*/
/* --------ignoring SunOS ieee_flags approach, someone else can
** deal with that! */
diff --git a/numpy/core/setup.py b/numpy/core/setup.py
index cd15d793e..9e3847cbf 100644
--- a/numpy/core/setup.py
+++ b/numpy/core/setup.py
@@ -5,20 +5,6 @@ from os.path import join
from numpy.distutils import log
from distutils.dep_util import newer
-FUNCTIONS_TO_CHECK = [
- ('expl', 'HAVE_LONGDOUBLE_FUNCS'),
- ('expf', 'HAVE_FLOAT_FUNCS'),
- ('log1p', 'HAVE_LOG1P'),
- ('expm1', 'HAVE_EXPM1'),
- ('asinh', 'HAVE_INVERSE_HYPERBOLIC'),
- ('atanhf', 'HAVE_INVERSE_HYPERBOLIC_FLOAT'),
- ('atanhl', 'HAVE_INVERSE_HYPERBOLIC_LONGDOUBLE'),
- ('isnan', 'HAVE_ISNAN'),
- ('isinf', 'HAVE_ISINF'),
- ('rint', 'HAVE_RINT'),
- ('trunc', 'HAVE_TRUNC'),
- ]
-
def is_npy_no_signal():
"""Return True if the NPY_NO_SIGNAL symbol must be defined in configuration
header."""
@@ -49,6 +35,75 @@ def is_npy_no_smp():
nosmp = 0
return nosmp == 1
+def check_math_capabilities(config, moredefs, mathlibs):
+ def check_func(func_name):
+ return config.check_func(func_name, libraries=mathlibs,
+ decl=True, call=True)
+
+ def check_funcs_once(funcs_name):
+ decl = dict([(f, True) for f in funcs_name])
+ st = config.check_funcs_once(funcs_name, libraries=mathlibs,
+ decl=decl, call=decl)
+ if st:
+ moredefs.extend([name_to_defsymb(f) for f in funcs_name])
+ return st
+
+ def check_funcs(funcs_name):
+ # Use check_funcs_once first, and if it does not work, test func per
+ # func. Return success only if all the functions are available
+ if not check_funcs_once(funcs_name):
+ # Global check failed, check func per func
+ for f in funcs_name:
+ if check_func(f):
+ moredefs.append(name_to_defsymb(f))
+ return 0
+ else:
+ return 1
+
+ def name_to_defsymb(name):
+ return "HAVE_%s" % name.upper()
+
+ #use_msvc = config.check_decl("_MSC_VER")
+
+ # Mandatory functions: if not found, fail the build
+ mandatory_funcs = ["sin", "cos", "tan", "sinh", "cosh", "tanh", "fabs",
+ "floor", "ceil", "sqrt", "log10", "log", "exp", "asin",
+ "acos", "atan", "fmod", 'modf', 'frexp', 'ldexp']
+
+ if not check_funcs_once(mandatory_funcs):
+ raise SystemError("One of the required function to build numpy is not"
+ " available (the list is %s)." % str(mandatory_funcs))
+
+ # Standard functions which may not be available and for which we have a
+ # replacement implementation
+ # XXX: we do not test for hypot because python checks for it (HAVE_HYPOT in
+ # python.h... I wish they would clean their public headers someday)
+ optional_stdfuncs = ["expm1", "log1p", "acosh", "asinh", "atanh",
+ "rint", "trunc"]
+
+ check_funcs(optional_stdfuncs)
+
+ # C99 functions: float and long double versions
+ c99_funcs = ["sin", "cos", "tan", "sinh", "cosh", "tanh", "fabs", "floor",
+ "ceil", "rint", "trunc", "sqrt", "log10", "log", "exp",
+ "expm1", "asin", "acos", "atan", "asinh", "acosh", "atanh",
+ "hypot", "atan2", "pow", "fmod", "modf", 'frexp', 'ldexp']
+
+ for prec in ['l', 'f']:
+ fns = [f + prec for f in c99_funcs]
+ check_funcs(fns)
+
+ # Normally, isnan and isinf are macro (C99), but some platforms only have
+ # func, or both func and macro version. Check for macro only, and define
+ # replacement ones if not found.
+ # Note: including Python.h is necessary because it modifies some math.h
+ # definitions
+ for f in ["isnan", "isinf", "signbit", "isfinite"]:
+ st = config.check_decl(f, headers = ["Python.h", "math.h"])
+ if st:
+ moredefs.append(name_to_defsymb("decl_%s" % f))
+
+
def configuration(parent_package='',top_path=None):
from numpy.distutils.misc_util import Configuration,dot_join
from numpy.distutils.system_info import get_info, default_lib_dirs
@@ -106,14 +161,7 @@ def configuration(parent_package='',top_path=None):
ext.libraries.extend(mathlibs)
moredefs.append(('MATHLIB',','.join(mathlibs)))
- def check_func(func_name):
- return config_cmd.check_func(func_name,
- libraries=mathlibs, decl=False,
- headers=['math.h'])
-
- for func_name, defsymbol in FUNCTIONS_TO_CHECK:
- if check_func(func_name):
- moredefs.append(defsymbol)
+ check_math_capabilities(config_cmd, moredefs, mathlibs)
if is_npy_no_signal():
moredefs.append('__NPY_PRIVATE_NO_SIGNAL')
@@ -136,6 +184,17 @@ def configuration(parent_package='',top_path=None):
target_f.write('#define %s\n' % (d))
else:
target_f.write('#define %s %s\n' % (d[0],d[1]))
+
+ # Keep those for backward compatibility for now
+ target_f.write("""
+#ifdef HAVE_EXPL
+#define HAVE_LONGDOUBLE_FUNCS
+#endif
+
+#ifdef HAVE_EXPF
+#define HAVE_FLOAT_FUNCS
+#endif
+""")
target_f.close()
print 'File:',target
target_f = open(target)
@@ -264,7 +323,6 @@ def configuration(parent_package='',top_path=None):
join('src','scalartypes.inc.src'),
join('src','arraytypes.inc.src'),
join('src','_signbit.c'),
- join('src','_isnan.c'),
join('src','ucsnarrow.c'),
join('include','numpy','*object.h'),
'include/numpy/fenv/fenv.c',
@@ -298,6 +356,7 @@ def configuration(parent_package='',top_path=None):
generate_ufunc_api,
join('src','scalartypes.inc.src'),
join('src','arraytypes.inc.src'),
+ join('src','math_c99.inc.src'),
],
depends = [join('src','ufuncobject.c'),
generate_umath_py,
diff --git a/numpy/core/src/_isnan.c b/numpy/core/src/_isnan.c
deleted file mode 100644
index bff6e0a49..000000000
--- a/numpy/core/src/_isnan.c
+++ /dev/null
@@ -1,46 +0,0 @@
-/* Adapted from cephes */
-
-static int
-isnan(double x)
-{
- union
- {
- double d;
- unsigned short s[4];
- unsigned int i[2];
- } u;
-
- u.d = x;
-
-#if SIZEOF_INT == 4
-
-#ifdef WORDS_BIGENDIAN /* defined in pyconfig.h */
- if( ((u.i[0] & 0x7ff00000) == 0x7ff00000)
- && (((u.i[0] & 0x000fffff) != 0) || (u.i[1] != 0)))
- return 1;
-#else
- if( ((u.i[1] & 0x7ff00000) == 0x7ff00000)
- && (((u.i[1] & 0x000fffff) != 0) || (u.i[0] != 0)))
- return 1;
-#endif
-
-#else /* SIZEOF_INT != 4 */
-
-#ifdef WORDS_BIGENDIAN
- if( (u.s[0] & 0x7ff0) == 0x7ff0)
- {
- if( ((u.s[0] & 0x000f) | u.s[1] | u.s[2] | u.s[3]) != 0 )
- return 1;
- }
-#else
- if( (u.s[3] & 0x7ff0) == 0x7ff0)
- {
- if( ((u.s[3] & 0x000f) | u.s[2] | u.s[1] | u.s[0]) != 0 )
- return 1;
- }
-#endif
-
-#endif /* SIZEOF_INT */
-
- return 0;
-}
diff --git a/numpy/core/src/_signbit.c b/numpy/core/src/_signbit.c
index 2be3649fd..3074c2716 100644
--- a/numpy/core/src/_signbit.c
+++ b/numpy/core/src/_signbit.c
@@ -1,7 +1,7 @@
/* Adapted from cephes */
static int
-signbit(double x)
+signbit_d(double x)
{
union
{
diff --git a/numpy/core/src/math_c99.inc.src b/numpy/core/src/math_c99.inc.src
new file mode 100644
index 000000000..14399f699
--- /dev/null
+++ b/numpy/core/src/math_c99.inc.src
@@ -0,0 +1,264 @@
+/*
+ * vim:syntax=c
+ * A small module to implement missing C99 math capabilities required by numpy
+ *
+ * Please keep this independant of python !
+ */
+
+/*
+ *****************************************************************************
+ ** BASIC MATH FUNCTIONS **
+ *****************************************************************************
+ */
+
+/* Original code by Konrad Hinsen. */
+#ifndef HAVE_EXPM1
+double expm1(double x)
+{
+ double u = exp(x);
+ if (u == 1.0) {
+ return x;
+ } else if (u-1.0 == -1.0) {
+ return -1;
+ } else {
+ return (u-1.0) * x/log(u);
+ }
+}
+#endif
+
+#ifndef HAVE_LOG1P
+double log1p(double x)
+{
+ double u = 1. + x;
+ if (u == 1.0) {
+ return x;
+ } else {
+ return log(u) * x / (u-1.);
+ }
+}
+#endif
+
+#ifndef HAVE_HYPOT
+double hypot(double x, double y)
+{
+ double yx;
+
+ x = fabs(x);
+ y = fabs(y);
+ if (x < y) {
+ double temp = x;
+ x = y;
+ y = temp;
+ }
+ if (x == 0.)
+ return 0.;
+ else {
+ yx = y/x;
+ return x*sqrt(1.+yx*yx);
+ }
+}
+#endif
+
+#ifndef HAVE_ACOSH
+double acosh(double x)
+{
+ return 2*log(sqrt((x+1.0)/2)+sqrt((x-1.0)/2));
+}
+#endif
+
+#ifndef HAVE_ASINH
+double asinh(double xx)
+{
+ double x, d;
+ int sign;
+ if (xx < 0.0) {
+ sign = -1;
+ x = -xx;
+ }
+ else {
+ sign = 1;
+ x = xx;
+ }
+ if (x > 1e8) {
+ d = x;
+ } else {
+ d = sqrt(x*x + 1);
+ }
+ return sign*log1p(x*(1.0 + x/(d+1)));
+}
+#endif
+
+#ifndef HAVE_ATANH
+static double atanh(double x)
+{
+ return 0.5*log1p(2.0*x/(1.0-x));
+}
+#endif
+
+#ifndef HAVE_RINT
+double rint(double x)
+{
+ double y, r;
+
+ y = floor(x);
+ r = x - y;
+
+ if (r > 0.5) goto rndup;
+
+ /* Round to nearest even */
+ if (r==0.5) {
+ r = y - 2.0*floor(0.5*y);
+ if (r==1.0) {
+ rndup:
+ y+=1.0;
+ }
+ }
+ return y;
+}
+#endif
+
+#ifndef HAVE_TRUNC
+double trunc(double x)
+{
+ if (x < 0) {
+ return ceil(x);
+ }
+ else {
+ return floor(x);
+ }
+
+}
+#endif
+
+/*
+ *****************************************************************************
+ ** IEEE 754 FPU HANDLING **
+ *****************************************************************************
+ */
+#if !defined(HAVE_DECL_ISNAN)
+ # define isnan(x) ((x) != (x))
+#endif
+
+/* VS 2003 with /Ox optimizes (x)-(x) to 0, which is not IEEE compliant. So we
+ * force (x) + (-x), which seems to work. */
+#if !defined(HAVE_DECL_ISFINITE)
+ # define isfinite(x) !isnan((x) + (-x))
+#endif
+
+#if !defined(HAVE_DECL_ISINF)
+#define isinf(x) (!isfinite(x) && !isnan(x))
+#endif
+
+#if !defined(HAVE_DECL_SIGNBIT)
+ #include "_signbit.c"
+ # define signbit(x) \
+ (sizeof (x) == sizeof (long double) ? signbit_ld (x) \
+ : sizeof (x) == sizeof (double) ? signbit_d (x) \
+ : signbit_f (x))
+
+static int signbit_f (float x)
+{
+ return signbit_d((double)x);
+}
+
+static int signbit_ld (long double x)
+{
+ return signbit_d((double)x);
+}
+#endif
+
+/*
+ * if C99 extensions not available then define dummy functions that use the
+ * double versions for
+ *
+ * sin, cos, tan
+ * sinh, cosh, tanh,
+ * fabs, floor, ceil, rint, trunc
+ * sqrt, log10, log, exp, expm1
+ * asin, acos, atan,
+ * asinh, acosh, atanh
+ *
+ * hypot, atan2, pow, fmod, modf
+ *
+ * We assume the above are always available in their double versions.
+ *
+ * NOTE: some facilities may be available as macro only instead of functions.
+ * For simplicity, we define our own functions and undef the macros. We could
+ * instead test for the macro, but I am lazy to do that for now.
+ */
+
+/*
+ * One value argument function
+ */
+
+/**begin repeat
+
+ #kind=(sin,cos,tan,sinh,cosh,tanh,fabs,floor,ceil,rint,trunc,sqrt,log10,log,exp,expm1,asin,acos,atan,asinh,acosh,atanh,log1p)*2#
+ #KIND=(SIN,COS,TAN,SINH,COSH,TANH,FABS,FLOOR,CEIL,RINT,TRUNC,SQRT,LOG10,LOG,EXP,EXPM1,ASIN,ACOS,ATAN,ASINH,ACOSH,ATANH,LOG1P)*2#
+ #typ=longdouble*23, float*23#
+ #c=l*23,f*23#
+ #C=L*23,F*23#
+ #TYPE=LONGDOUBLE*23, FLOAT*23#
+*/
+
+#ifndef HAVE_@KIND@@C@
+#ifdef @kind@@c@
+#undef @kind@@c@
+#endif
+@typ@ @kind@@c@(@typ@ x)
+{
+ return (@typ@) @kind@((double)x);
+}
+#endif
+/**end repeat**/
+
+/*
+ * Two values arguments function
+ */
+
+/**begin repeat
+
+ #kind=(atan2,hypot,pow,fmod)*2#
+ #KIND=(ATAN2,HYPOT,POW,FMOD)*2#
+ #typ=longdouble*4, float*4#
+ #c=l*4,f*4#
+ #C=L*4,F*4#
+ #TYPE=LONGDOUBLE*4,FLOAT*4#
+*/
+#ifndef HAVE_@KIND@@C@
+#ifdef @kind@@c@
+#undef @kind@@c@
+#endif
+@typ@ @kind@@c@(@typ@ x, @typ@ y)
+{
+ return (@typ@) @kind@((double)x, (double) y);
+}
+#endif
+/**end repeat**/
+
+/*
+ * One value - one pointer argument function
+ */
+
+/**begin repeat
+ #kind=modf*2#
+ #KIND=MODF*2#
+ #c=l,f#
+ #C=L,F#
+ #typ=longdouble, float#
+ #TYPE=LONGDOUBLE, FLOAT#
+*/
+#ifndef HAVE_@KIND@@C@
+#ifdef modf@c@
+#undef modf@c@
+#endif
+@typ@ modf@c@(@typ@ x, @typ@ *iptr)
+{
+ double nx, niptr, y;
+ nx = (double) x;
+ y = modf(nx, &niptr);
+ *iptr = (@typ@) niptr;
+ return (@typ@) y;
+}
+#endif
+/**end repeat**/
diff --git a/numpy/core/src/umathmodule.c.src b/numpy/core/src/umathmodule.c.src
index 77675c441..4d7734cca 100644
--- a/numpy/core/src/umathmodule.c.src
+++ b/numpy/core/src/umathmodule.c.src
@@ -1,6 +1,10 @@
/* -*- c -*- */
/*
+ * vim:syntax=c
+ */
+
+/*
*****************************************************************************
** INCLUDES **
*****************************************************************************
@@ -13,435 +17,10 @@
#include "config.h"
#include <math.h>
-/*
- *****************************************************************************
- ** BASIC MATH FUNCTIONS **
- *****************************************************************************
- */
-
-/* A whole slew of basic math functions are provided originally
- by Konrad Hinsen. */
-
-#if !defined(__STDC__) && !defined(_MSC_VER)
-extern double fmod (double, double);
-extern double frexp (double, int *);
-extern double ldexp (double, int);
-extern double modf (double, double *);
-#endif
#ifndef M_PI
#define M_PI 3.14159265358979323846264338328
#endif
-
-
-#if defined(DISTUTILS_USE_SDK)
-/* win32 on AMD64 build architecture */
-/* See also http://projects.scipy.org/scipy/numpy/ticket/164 */
-#ifndef HAVE_FABSF
-#ifdef fabsf
-#undef fabsf
-#endif
-static float fabsf(float x)
-{
- return (float)fabs((double)(x));
-}
-#endif
-#ifndef HAVE_HYPOTF
-static float hypotf(float x, float y)
-{
- return (float)hypot((double)(x), (double)(y));
-}
-#endif
-#ifndef HAVE_RINTF
-#ifndef HAVE_RINT
-static double rint (double x);
-#endif
-static float rintf(float x)
-{
- return (float)rint((double)(x));
-}
-#endif
-#ifndef HAVE_FREXPF
-static float frexpf(float x, int * i)
-{
- return (float)frexp((double)(x), i);
-}
-#endif
-#ifndef HAVE_LDEXPF
-static float ldexpf(float x, int i)
-{
- return (float)ldexp((double)(x), i);
-}
-#endif
-#define tanhf nc_tanhf
-#endif
-
-#ifndef HAVE_INVERSE_HYPERBOLIC
-static double acosh(double x)
-{
- return 2*log(sqrt((x+1.0)/2)+sqrt((x-1.0)/2));
-}
-
-double log1p(double);
-static double asinh(double xx)
-{
- double x, d;
- int sign;
- if (xx < 0.0) {
- sign = -1;
- x = -xx;
- }
- else {
- sign = 1;
- x = xx;
- }
- if (x > 1e8) {
- d = x;
- } else {
- d = sqrt(x*x + 1);
- }
- return sign*log1p(x*(1.0 + x/(d+1)));
-}
-
-static double atanh(double x)
-{
- return 0.5*log1p(2.0*x/(1.0-x));
-}
-#endif
-
-#if !defined(HAVE_INVERSE_HYPERBOLIC_FLOAT)
-#ifdef HAVE_FLOAT_FUNCS
-#ifdef log1pf
-#undef log1pf
-#endif
-#ifdef logf
-#undef logf
-#endif
-#ifdef sqrtf
-#undef sqrtf
-#endif
-float log1pf(float);
-#ifdef DISTUTILS_USE_SDK
-DL_IMPORT(float) logf(float);
-DL_IMPORT(float) sqrtf(float);
-#else
-/* should these be extern?: */
-float logf(float);
-float sqrtf(float);
-#endif
-#ifdef acoshf
-#undef acoshf
-#endif
-static float acoshf(float x)
-{
- return 2*logf(sqrtf((x+1)/2)+sqrtf((x-1)/2));
-}
-
-#ifdef asinhf
-#undef asinhf
-#endif
-static float asinhf(float xx)
-{
- float x, d;
- int sign;
- if (xx < 0) {
- sign = -1;
- x = -xx;
- }
- else {
- sign = 1;
- x = xx;
- }
- if (x > 1e5) {
- d = x;
- } else {
- d = sqrtf(x*x + 1);
- }
- return sign*log1pf(x*(1 + x/(d+1)));
-}
-
-#ifdef atanhf
-#undef atanhf
-#endif
-static float atanhf(float x)
-{
- return log1pf(2*x/(1-x))/2;
-}
-#else
-#ifdef acoshf
-#undef acoshf
-#endif
-static float acoshf(float x)
-{
- return (float)acosh((double)(x));
-}
-
-#ifdef asinhf
-#undef asinhf
-#endif
-static float asinhf(float x)
-{
- return (float)asinh((double)(x));
-}
-
-#ifdef atanhf
-#undef atanhf
-#endif
-static float atanhf(float x)
-{
- return (float)atanh((double)(x));
-}
-#endif
-#endif
-
-
-#if !defined(HAVE_INVERSE_HYPERBOLIC_LONGDOUBLE)
-#ifdef HAVE_LONGDOUBLE_FUNCS
-#ifdef logl
-#undef logl
-#endif
-#ifdef sqrtl
-#undef sqrtl
-#endif
-#ifdef log1pl
-#undef log1pl
-#endif
-longdouble logl(longdouble);
-longdouble sqrtl(longdouble);
-longdouble log1pl(longdouble);
-#ifdef acoshl
-#undef acoshl
-#endif
-static longdouble acoshl(longdouble x)
-{
- return 2*logl(sqrtl((x+1.0)/2)+sqrtl((x-1.0)/2));
-}
-
-#ifdef asinhl
-#undef asinhl
-#endif
-static longdouble asinhl(longdouble xx)
-{
- longdouble x, d;
- int sign;
- if (xx < 0.0) {
- sign = -1;
- x = -xx;
- }
- else {
- sign = 1;
- x = xx;
- }
- if (x > 1e17) {
- d = x;
- } else {
- d = sqrtl(x*x + 1);
- }
- return sign*log1pl(x*(1.0 + x/(d+1)));
-}
-
-#ifdef atanhl
-#undef atanhl
-#endif
-static longdouble atanhl(longdouble x)
-{
- return 0.5*log1pl(2.0*x/(1.0-x));
-}
-
-#else
-
-#ifdef acoshl
-#undef acoshl
-#endif
-static longdouble acoshl(longdouble x)
-{
- return (longdouble)acosh((double)(x));
-}
-
-#ifdef asinhl
-#undef asinhl
-#endif
-static longdouble asinhl(longdouble x)
-{
- return (longdouble)asinh((double)(x));
-}
-
-#ifdef atanhl
-#undef atanhl
-#endif
-static longdouble atanhl(longdouble x)
-{
- return (longdouble)atanh((double)(x));
-}
-
-#endif
-#endif
-
-
-#ifdef HAVE_HYPOT
-#if !defined(NeXT) && !defined(_MSC_VER)
-extern double hypot(double, double);
-#endif
-#else
-static double hypot(double x, double y)
-{
- double yx;
-
- x = fabs(x);
- y = fabs(y);
- if (x < y) {
- double temp = x;
- x = y;
- y = temp;
- }
- if (x == 0.)
- return 0.;
- else {
- yx = y/x;
- return x*sqrt(1.+yx*yx);
- }
-}
-#endif
-
-#ifndef HAVE_RINT
-/* needs cleanup */
-static double
-rint(double x)
-{
- double y, r;
-
- y = floor(x);
- r = x - y;
-
- if (r > 0.5) goto rndup;
-
- /* Round to nearest even */
- if (r==0.5) {
- r = y - 2.0*floor(0.5*y);
- if (r==1.0) {
- rndup:
- y+=1.0;
- }
- }
- return y;
-}
-#endif
-
-/*
- * Comment out trunc definition until build problems are fixed.
- */
-/*
-#ifndef HAVE_TRUNC
-static double
-trunc(double x)
-{
- if (x < 0) {
- return ceil(x);
- }
- else {
- return floor(x);
- }
-
-}
-#endif
-*/
-
-
-
-
-/* Define isnan, isinf, isfinite, signbit if needed */
-/* Use fpclassify if possible */
-/* isnan, isinf --
- these will use macros and then fpclassify if available before
- defaulting to a dumb convert-to-double version...
-
- isfinite -- define a macro if not already available
- signbit -- if macro available use it, otherwise define a function
- and a dumb convert-to-double version for other types.
-*/
-
-#if defined(fpclassify)
-
-#if !defined(isnan)
-#define isnan(x) (fpclassify(x) == FP_NAN)
-#endif
-#if !defined(isinf)
-#define isinf(x) (fpclassify(x) == FP_INFINITE)
-#endif
-
-#else /* check to see if already have a function like this */
-
-#if !defined(HAVE_ISNAN)
-
-#if !defined(isnan)
-#include "_isnan.c"
-#endif
-#endif /* HAVE_ISNAN */
-
-#if !defined(HAVE_ISINF)
-#if !defined(isinf)
-#define isinf(x) (!isnan((x)) && isnan((x)-(x)))
-#endif
-#endif /* HAVE_ISINF */
-
-#endif /* defined(fpclassify) */
-
-
-/* Define signbit if needed */
-#if !defined(signbit)
-#include "_signbit.c"
-#endif
-
-/* Now defined the extended type macros */
-
-#if !defined(isnan)
-
-#if !defined(HAVE_LONGDOUBLE_FUNCS) || !defined(HAVE_ISNAN)
-#define isnanl(x) isnan((double)(x))
-#endif
-
-#if !defined(HAVE_FLOAT_FUNCS) || !defined(HAVE_ISNAN)
-#define isnanf(x) isnan((double)(x))
-#endif
-
-#else /* !defined(isnan) */
-
-#define isnanl(x) isnan((x))
-#define isnanf(x) isnan((x))
-
-#endif /* !defined(isnan) */
-
-
-#if !defined(isinf)
-
-#if !defined(HAVE_LONGDOUBLE_FUNCS) || !defined(HAVE_ISINF)
-#define isinfl(x) (!isnanl((x)) && isnanl((x)-(x)))
-#endif
-
-#if !defined(HAVE_FLOAT_FUNCS) || !defined(HAVE_ISINF)
-#define isinff(x) (!isnanf((x)) && isnanf((x)-(x)))
-#endif
-
-#else /* !defined(isinf) */
-
-#define isinfl(x) isinf((x))
-#define isinff(x) isinf((x))
-
-#endif /* !defined(isinf) */
-
-
-#if !defined(signbit)
-#define signbitl(x) ((longdouble) signbit((double)(x)))
-#define signbitf(x) ((float) signbit((double) (x)))
-#else
-#define signbitl(x) signbit((x))
-#define signbitf(x) signbit((x))
-#endif
-
-#if !defined(isfinite)
-#define isfinite(x) (!(isinf((x)) || isnan((x))))
-#endif
-#define isfinitef(x) (!(isinff((x)) || isnanf((x))))
-#define isfinitel(x) (!(isinfl((x)) || isnanl((x))))
+#include "math_c99.inc"
float degreesf(float x) {
return x * (float)(180.0/M_PI);
@@ -463,168 +42,6 @@ longdouble radiansl(longdouble x) {
return x * (M_PI/180.0L);
}
-/* First, the C functions that do the real work */
-
-/* if C99 extensions not available then define dummy functions that use the
- double versions for
-
- sin, cos, tan
- sinh, cosh, tanh,
- fabs, floor, ceil, fmod, sqrt, log10, log, exp, fabs
- asin, acos, atan,
- asinh, acosh, atanh
-
- hypot, atan2, pow
-*/
-
-/**begin repeat
-
- #kind=(sin,cos,tan,sinh,cosh,tanh,fabs,floor,ceil,sqrt,log10,log,exp,asin,acos,atan,rint)*2#
- #typ=longdouble*17, float*17#
- #c=l*17,f*17#
- #TYPE=LONGDOUBLE*17, FLOAT*17#
-*/
-
-#ifndef HAVE_@TYPE@_FUNCS
-#ifdef @kind@@c@
-#undef @kind@@c@
-#endif
-@typ@ @kind@@c@(@typ@ x) {
- return (@typ@) @kind@((double)x);
-}
-#endif
-/**end repeat**/
-
-/**begin repeat
-
- #kind=(atan2,hypot,pow,fmod)*2#
- #typ=longdouble*4, float*4#
- #c=l*4,f*4#
- #TYPE=LONGDOUBLE*4,FLOAT*4#
-*/
-#ifndef HAVE_@TYPE@_FUNCS
-#ifdef @kind@@c@
-#undef @kind@@c@
-#endif
-@typ@ @kind@@c@(@typ@ x, @typ@ y) {
- return (@typ@) @kind@((double)x, (double) y);
-}
-#endif
-/**end repeat**/
-
-/**begin repeat
- #kind=modf*2#
- #typ=longdouble, float#
- #c=l,f#
- #TYPE=LONGDOUBLE, FLOAT#
-*/
-#ifndef HAVE_@TYPE@_FUNCS
-#ifdef modf@c@
-#undef modf@c@
-#endif
-@typ@ modf@c@(@typ@ x, @typ@ *iptr) {
- double nx, niptr, y;
- nx = (double) x;
- y = modf(nx, &niptr);
- *iptr = (@typ@) niptr;
- return (@typ@) y;
-}
-#endif
-/**end repeat**/
-
-
-
-#ifndef HAVE_LOG1P
-double log1p(double x)
-{
- double u = 1. + x;
- if (u == 1.0) {
- return x;
- } else {
- return log(u) * x / (u-1.);
- }
-}
-#endif
-
-#if !defined(HAVE_LOG1P) || !defined(HAVE_LONGDOUBLE_FUNCS)
-#ifdef log1pl
-#undef log1pl
-#endif
-longdouble log1pl(longdouble x)
-{
- longdouble u = 1. + x;
- if (u == 1.0) {
- return x;
- } else {
- return logl(u) * x / (u-1.);
- }
-}
-#endif
-
-#if !defined(HAVE_LOG1P) || !defined(HAVE_FLOAT_FUNCS)
-#ifdef log1pf
-#undef log1pf
-#endif
-float log1pf(float x)
-{
- float u = 1 + x;
- if (u == 1) {
- return x;
- } else {
- return logf(u) * x / (u-1);
- }
-}
-#endif
-
-#ifndef HAVE_EXPM1
-static double expm1(double x)
-{
- double u = exp(x);
- if (u == 1.0) {
- return x;
- } else if (u-1.0 == -1.0) {
- return -1;
- } else {
- return (u-1.0) * x/log(u);
- }
-}
-#endif
-
-#if !defined(HAVE_EXPM1) || !defined(HAVE_LONGDOUBLE_FUNCS)
-#ifdef expml1
-#undef expml1
-#endif
-static longdouble expm1l(longdouble x)
-{
- longdouble u = expl(x);
- if (u == 1.0) {
- return x;
- } else if (u-1.0 == -1.0) {
- return -1;
- } else {
- return (u-1.0) * x/logl(u);
- }
-}
-#endif
-
-#if !defined(HAVE_EXPM1) || !defined(HAVE_FLOAT_FUNCS)
-#ifdef expm1f
-#undef expm1f
-#endif
-static float expm1f(float x)
-{
- float u = expf(x);
- if (u == 1) {
- return x;
- } else if (u-1 == -1) {
- return -1;
- } else {
- return (u-1) * x/logf(u);
- }
-}
-#endif
-
-
/*
*****************************************************************************
** COMPLEX FUNCTIONS **
@@ -2047,7 +1464,6 @@ static void
#kind=isnan*3, isinf*3, isfinite*3, signbit*3#
#TYPE=(FLOAT, DOUBLE, LONGDOUBLE)*4#
#typ=(float, double, longdouble)*4#
- #c=(f,,l)*4#
*/
static void
@TYPE@_@kind@(char **args, intp *dimensions, intp *steps, void *func)
@@ -2056,7 +1472,7 @@ static void
intp is=steps[0], os=steps[1], n=dimensions[0];
char *ip=args[0], *op=args[1];
for(i=0; i<n; i++, ip+=is, op+=os) {
- *((Bool *)op) = (Bool) (@kind@@c@(*((@typ@ *)ip)) != 0);
+ *((Bool *)op) = (Bool) (@kind@(*((@typ@ *)ip)) != 0);
}
}
/**end repeat**/
@@ -2066,7 +1482,6 @@ static void
#kind=isnan*3, isinf*3, isfinite*3#
#TYPE=(CFLOAT, CDOUBLE, CLONGDOUBLE)*3#
#typ=(float, double, longdouble)*3#
- #c=(f,,l)*3#
#OP=||*6,&&*3#
*/
static void
@@ -2076,8 +1491,8 @@ static void
intp is=steps[0], os=steps[1], n=dimensions[0];
char *ip=args[0], *op=args[1];
for(i=0; i<n; i++, ip+=is, op+=os) {
- *((Bool *)op) = @kind@@c@(((@typ@ *)ip)[0]) @OP@ \
- @kind@@c@(((@typ@ *)ip)[1]);
+ *((Bool *)op) = @kind@(((@typ@ *)ip)[0]) @OP@ \
+ @kind@(((@typ@ *)ip)[1]);
}
}
/**end repeat**/
@@ -2108,13 +1523,13 @@ static void
}
/**end repeat**/
-#define HAVE_DOUBLE_FUNCS
/**begin repeat
#TYPE=FLOAT, DOUBLE, LONGDOUBLE#
#typ=float, double, longdouble#
#c=f,,l#
+ #C=F,,L#
*/
-#ifdef HAVE_@TYPE@_FUNCS
+#ifdef HAVE_FREXP@C@
static void
@TYPE@_frexp(char **args, intp *dimensions, intp *steps, void *func)
{
@@ -2130,7 +1545,9 @@ static void
*((int *) op2) = y2;
}
}
+#endif
+#ifdef HAVE_LDEXP@C@
static void
@TYPE@_ldexp(char **args, intp *dimensions, intp *steps, void *func)
{
@@ -2148,47 +1565,46 @@ static void
}
#endif
/**end repeat**/
-#undef HAVE_DOUBLE_FUNCS
static PyUFuncGenericFunction frexp_functions[] = {
-#ifdef HAVE_FLOAT_FUNCS
+#ifdef HAVE_FREXPF
FLOAT_frexp,
#endif
DOUBLE_frexp
-#ifdef HAVE_LONGDOUBLE_FUNCS
+#ifdef HAVE_FREXPL
,LONGDOUBLE_frexp
#endif
};
static void * blank3_data[] = { (void *)NULL, (void *)NULL, (void *)NULL};
static char frexp_signatures[] = {
-#ifdef HAVE_FLOAT_FUNCS
+#ifdef HAVE_FREXPF
PyArray_FLOAT, PyArray_FLOAT, PyArray_INT,
#endif
PyArray_DOUBLE, PyArray_DOUBLE, PyArray_INT
-#ifdef HAVE_LONGDOUBLE_FUNCS
+#ifdef HAVE_FREXPL
,PyArray_LONGDOUBLE, PyArray_LONGDOUBLE, PyArray_INT
#endif
};
static PyUFuncGenericFunction ldexp_functions[] = {
-#ifdef HAVE_FLOAT_FUNCS
+#ifdef HAVE_LDEXPF
FLOAT_ldexp,
#endif
DOUBLE_ldexp
-#ifdef HAVE_LONGDOUBLE_FUNCS
+#ifdef HAVE_LDEXPL
,LONGDOUBLE_ldexp
#endif
};
static char ldexp_signatures[] = {
-#ifdef HAVE_FLOAT_FUNCS
+#ifdef HAVE_LDEXPF
PyArray_FLOAT, PyArray_INT, PyArray_FLOAT,
#endif
PyArray_DOUBLE, PyArray_INT, PyArray_DOUBLE
-#ifdef HAVE_LONGDOUBLE_FUNCS
+#ifdef HAVE_LDEXPL
,PyArray_LONGDOUBLE, PyArray_INT, PyArray_LONGDOUBLE
#endif
};
@@ -2241,10 +1657,10 @@ InitOtherOperators(PyObject *dictionary) {
PyObject *f;
int num=1;
-#ifdef HAVE_LONGDOUBLE_FUNCS
+#ifdef HAVE_FREXPL
num += 1;
#endif
-#ifdef HAVE_FLOAT_FUNCS
+#ifdef HAVE_FREXPF
num += 1;
#endif
f = PyUFunc_FromFuncAndData(frexp_functions, blank3_data,
@@ -2255,6 +1671,13 @@ InitOtherOperators(PyObject *dictionary) {
PyDict_SetItemString(dictionary, "frexp", f);
Py_DECREF(f);
+ num = 1;
+#ifdef HAVE_LDEXPL
+ num += 1;
+#endif
+#ifdef HAVE_LDEXPF
+ num += 1;
+#endif
f = PyUFunc_FromFuncAndData(ldexp_functions, blank3_data, ldexp_signatures, num,
2, 1, PyUFunc_None, "ldexp",
"Compute y = x1 * 2**x2.",0);
diff --git a/numpy/distutils/command/config.py b/numpy/distutils/command/config.py
index ce42a36e0..5170bfcb0 100644
--- a/numpy/distutils/command/config.py
+++ b/numpy/distutils/command/config.py
@@ -126,6 +126,13 @@ int main()
body = []
if decl:
body.append("int %s ();" % func)
+ # Handle MSVC intrisincs: force MS compiler to make a function call.
+ # Useful to test for some functions when built with optimization on, to
+ # avoid build error because the intrisinc and our 'fake' test
+ # declaration do not match.
+ body.append("#ifdef _MSC_VER")
+ body.append("#pragma function(%s)" % func)
+ body.append("#endif")
body.append("int main (void) {")
if call:
if call_args is None:
@@ -140,6 +147,67 @@ int main()
return self.try_link(body, headers, include_dirs,
libraries, library_dirs)
+ def check_funcs_once(self, funcs,
+ headers=None, include_dirs=None,
+ libraries=None, library_dirs=None,
+ decl=False, call=False, call_args=None):
+ """Check a list of functions at once.
+
+ This is useful to speed up things, since all the functions in the funcs
+ list will be put in one compilation unit.
+
+ Arguments
+ ---------
+
+ funcs: seq
+ list of functions to test
+ include_dirs : seq
+ list of header paths
+ libraries : seq
+ list of libraries to link the code snippet to
+ libraru_dirs : seq
+ list of library paths
+ decl : dict
+ for every (key, value), the declaration in the value will be
+ used for function in key. If a function is not in the
+ dictionay, no declaration will be used.
+ call : dict
+ for every item (f, value), if the value is True, a call will be
+ done to the function f"""
+ self._check_compiler()
+ body = []
+ if decl:
+ for f, v in decl.items():
+ if v:
+ body.append("int %s ();" % f)
+
+ # Handle MS intrinsics. See check_func for more info.
+ body.append("#ifdef _MSC_VER")
+ for func in funcs:
+ body.append("#pragma function(%s)" % func)
+ body.append("#endif")
+
+ body.append("int main (void) {")
+ if call:
+ for f in funcs:
+ if call.has_key(f) and call[f]:
+ if not (call_args and call_args.has_key(f) and call_args[f]):
+ args = ''
+ else:
+ args = call_args[f]
+ body.append(" %s(%s);" % (f, args))
+ else:
+ body.append(" %s;" % f)
+ else:
+ for f in funcs:
+ body.append(" %s;" % f)
+ body.append(" return 0;")
+ body.append("}")
+ body = '\n'.join(body) + "\n"
+
+ return self.try_link(body, headers, include_dirs,
+ libraries, library_dirs)
+
def get_output(self, body, headers=None, include_dirs=None,
libraries=None, library_dirs=None,
lang="c"):