summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--numpy/core/SConscript15
-rw-r--r--numpy/core/code_generators/generate_umath.py2
-rw-r--r--numpy/core/include/numpy/ndarrayobject.h67
-rw-r--r--numpy/core/include/numpy/npy_common.h74
-rw-r--r--numpy/core/include/numpy/npy_math.h217
-rw-r--r--numpy/core/include/numpy/numpyconfig.h.in5
-rw-r--r--numpy/core/setup.py291
-rw-r--r--numpy/core/src/_signbit.c4
-rw-r--r--numpy/core/src/multiarraymodule.c7
-rw-r--r--numpy/core/src/npy_math.c.src (renamed from numpy/core/src/umath_funcs_c99.inc.src)209
-rw-r--r--numpy/core/src/numpyos.c8
-rw-r--r--numpy/core/src/umath_funcs.inc.src165
-rw-r--r--numpy/core/src/umath_loops.inc.src12
-rw-r--r--numpy/core/src/umathmodule.c.src7
-rw-r--r--numpy/distutils/command/build_clib.py6
-rw-r--r--numpy/distutils/command/config.py82
16 files changed, 746 insertions, 425 deletions
diff --git a/numpy/core/SConscript b/numpy/core/SConscript
index b611c04c9..84f03366e 100644
--- a/numpy/core/SConscript
+++ b/numpy/core/SConscript
@@ -131,7 +131,7 @@ numpyconfig_sym.append(('MATHLIB', ','.join(mlib)))
#----------------------------------
# Function to check:
mfuncs = ('expl', 'expf', 'log1p', 'expm1', 'asinh', 'atanhf', 'atanhl',
- 'isnan', 'isinf', 'rint', 'trunc')
+ 'rint', 'trunc')
# Set value to 1 for each defined function (in math lib)
mfuncs_defined = dict([(f, 0) for f in mfuncs])
@@ -185,7 +185,11 @@ for f in ["isnan", "isinf", "signbit", "isfinite"]:
#include <Python.h>
#include <math.h>
"""
- config.CheckDeclaration(f, includes=includes)
+ st = config.CheckDeclaration(f, includes=includes)
+ if st:
+ numpyconfig_sym.append(('DEFINE_NPY_HAVE_DECL_%s' % f.upper(),
+ '#define NPY_HAVE_DECL_%s' % f.upper()))
+
#-------------------------------------------------------
# Define the function PyOS_ascii_strod if not available
@@ -256,7 +260,6 @@ env.Append(BUILDERS = {'GenerateMultiarrayApi' : array_api_gen_bld,
# Generate generated code
#------------------------
scalartypes_src = env.GenerateFromTemplate(pjoin('src', 'scalartypes.inc.src'))
-umath_funcs_c99_src = env.GenerateFromTemplate(pjoin('src', 'umath_funcs_c99.inc.src'))
umath_funcs_src = env.GenerateFromTemplate(pjoin('src', 'umath_funcs.inc.src'))
umath_loops_src = env.GenerateFromTemplate(pjoin('src', 'umath_loops.inc.src'))
arraytypes_src = env.GenerateFromTemplate(pjoin('src', 'arraytypes.inc.src'))
@@ -276,6 +279,12 @@ ufunc_api = env.GenerateUfuncApi('ufunc_api',
env.Prepend(CPPPATH = ['include', '.'])
+# npymath core lib
+npymath_src = env.GenerateFromTemplate(pjoin('src', 'npy_math.c.src'))
+env.DistutilsStaticExtLibrary("npymath", npymath_src)
+env.Prepend(LIBS=["npymath"])
+env.Prepend(LIBPATH=["."])
+
#-----------------
# Build multiarray
#-----------------
diff --git a/numpy/core/code_generators/generate_umath.py b/numpy/core/code_generators/generate_umath.py
index a34dcc540..c9c945513 100644
--- a/numpy/core/code_generators/generate_umath.py
+++ b/numpy/core/code_generators/generate_umath.py
@@ -37,7 +37,7 @@ class TypeDescription(object):
self.out = self.type * nout
assert len(self.out) == nout
-_fdata_map = dict(f='%sf', d='%s', g='%sl',
+_fdata_map = dict(f='npy_%sf', d='npy_%s', g='npy_%sl',
F='nc_%sf', D='nc_%s', G='nc_%sl')
def build_func_data(types, f):
func_data = []
diff --git a/numpy/core/include/numpy/ndarrayobject.h b/numpy/core/include/numpy/ndarrayobject.h
index d8d87a51d..f754959f9 100644
--- a/numpy/core/include/numpy/ndarrayobject.h
+++ b/numpy/core/include/numpy/ndarrayobject.h
@@ -56,72 +56,7 @@ extern "C" CONFUSE_EMACS
*/
#define NPY_FEATURE_VERSION 0x00000001
-/* Some platforms don't define bool, long long, or long double.
- Handle that here.
-*/
-
-#define NPY_BYTE_FMT "hhd"
-#define NPY_UBYTE_FMT "hhu"
-#define NPY_SHORT_FMT "hd"
-#define NPY_USHORT_FMT "hu"
-#define NPY_INT_FMT "d"
-#define NPY_UINT_FMT "u"
-#define NPY_LONG_FMT "ld"
-#define NPY_ULONG_FMT "lu"
-#define NPY_FLOAT_FMT "g"
-#define NPY_DOUBLE_FMT "g"
-
-#ifdef PY_LONG_LONG
-typedef PY_LONG_LONG npy_longlong;
-typedef unsigned PY_LONG_LONG npy_ulonglong;
-# ifdef _MSC_VER
-# define NPY_LONGLONG_FMT "I64d"
-# define NPY_ULONGLONG_FMT "I64u"
-# define NPY_LONGLONG_SUFFIX(x) (x##i64)
-# define NPY_ULONGLONG_SUFFIX(x) (x##Ui64)
-# else
- /* #define LONGLONG_FMT "lld" Another possible variant
- #define ULONGLONG_FMT "llu"
-
- #define LONGLONG_FMT "qd" -- BSD perhaps?
- #define ULONGLONG_FMT "qu"
- */
-# define NPY_LONGLONG_FMT "Ld"
-# define NPY_ULONGLONG_FMT "Lu"
-# define NPY_LONGLONG_SUFFIX(x) (x##LL)
-# define NPY_ULONGLONG_SUFFIX(x) (x##ULL)
-# endif
-#else
-typedef long npy_longlong;
-typedef unsigned long npy_ulonglong;
-# define NPY_LONGLONG_SUFFIX(x) (x##L)
-# define NPY_ULONGLONG_SUFFIX(x) (x##UL)
-#endif
-
-
-typedef unsigned char npy_bool;
-#define NPY_FALSE 0
-#define NPY_TRUE 1
-
-
-#if NPY_SIZEOF_LONGDOUBLE == NPY_SIZEOF_DOUBLE
- typedef double npy_longdouble;
- #define NPY_LONGDOUBLE_FMT "g"
-#else
- typedef long double npy_longdouble;
- #define NPY_LONGDOUBLE_FMT "Lg"
-#endif
-
-#ifndef Py_USING_UNICODE
-#error Must use Python with unicode enabled.
-#endif
-
-
-typedef signed char npy_byte;
-typedef unsigned char npy_ubyte;
-typedef unsigned short npy_ushort;
-typedef unsigned int npy_uint;
-typedef unsigned long npy_ulong;
+#include "npy_common.h"
/* These are for completeness */
typedef float npy_float;
diff --git a/numpy/core/include/numpy/npy_common.h b/numpy/core/include/numpy/npy_common.h
new file mode 100644
index 000000000..01f97f6ad
--- /dev/null
+++ b/numpy/core/include/numpy/npy_common.h
@@ -0,0 +1,74 @@
+#ifndef _NPY_COMMON_H_
+#define _NPY_COMMON_H_
+
+/* This is auto-generated */
+#include "numpyconfig.h"
+
+/* Some platforms don't define bool, long long, or long double.
+ Handle that here.
+*/
+
+#define NPY_BYTE_FMT "hhd"
+#define NPY_UBYTE_FMT "hhu"
+#define NPY_SHORT_FMT "hd"
+#define NPY_USHORT_FMT "hu"
+#define NPY_INT_FMT "d"
+#define NPY_UINT_FMT "u"
+#define NPY_LONG_FMT "ld"
+#define NPY_ULONG_FMT "lu"
+#define NPY_FLOAT_FMT "g"
+#define NPY_DOUBLE_FMT "g"
+
+#ifdef PY_LONG_LONG
+typedef PY_LONG_LONG npy_longlong;
+typedef unsigned PY_LONG_LONG npy_ulonglong;
+# ifdef _MSC_VER
+# define NPY_LONGLONG_FMT "I64d"
+# define NPY_ULONGLONG_FMT "I64u"
+# define NPY_LONGLONG_SUFFIX(x) (x##i64)
+# define NPY_ULONGLONG_SUFFIX(x) (x##Ui64)
+# else
+ /* #define LONGLONG_FMT "lld" Another possible variant
+ #define ULONGLONG_FMT "llu"
+
+ #define LONGLONG_FMT "qd" -- BSD perhaps?
+ #define ULONGLONG_FMT "qu"
+ */
+# define NPY_LONGLONG_FMT "Ld"
+# define NPY_ULONGLONG_FMT "Lu"
+# define NPY_LONGLONG_SUFFIX(x) (x##LL)
+# define NPY_ULONGLONG_SUFFIX(x) (x##ULL)
+# endif
+#else
+typedef long npy_longlong;
+typedef unsigned long npy_ulonglong;
+# define NPY_LONGLONG_SUFFIX(x) (x##L)
+# define NPY_ULONGLONG_SUFFIX(x) (x##UL)
+#endif
+
+
+typedef unsigned char npy_bool;
+#define NPY_FALSE 0
+#define NPY_TRUE 1
+
+
+#if NPY_SIZEOF_LONGDOUBLE == NPY_SIZEOF_DOUBLE
+ typedef double npy_longdouble;
+ #define NPY_LONGDOUBLE_FMT "g"
+#else
+ typedef long double npy_longdouble;
+ #define NPY_LONGDOUBLE_FMT "Lg"
+#endif
+
+#ifndef Py_USING_UNICODE
+#error Must use Python with unicode enabled.
+#endif
+
+
+typedef signed char npy_byte;
+typedef unsigned char npy_ubyte;
+typedef unsigned short npy_ushort;
+typedef unsigned int npy_uint;
+typedef unsigned long npy_ulong;
+
+#endif
diff --git a/numpy/core/include/numpy/npy_math.h b/numpy/core/include/numpy/npy_math.h
new file mode 100644
index 000000000..3f88d747b
--- /dev/null
+++ b/numpy/core/include/numpy/npy_math.h
@@ -0,0 +1,217 @@
+#ifndef __NPY_MATH_C99_H_
+#define __NPY_MATH_C99_H_
+
+#include <math.h>
+#include <numpy/npy_common.h>
+
+/*
+ * Useful constants
+ */
+#define NPY_E 2.7182818284590452353602874713526625 /* e */
+#define NPY_LOG2E 1.4426950408889634073599246810018921 /* log_2 e */
+#define NPY_LOG10E 0.4342944819032518276511289189166051 /* log_10 e */
+#define NPY_LOGE2 0.6931471805599453094172321214581766 /* log_e 2 */
+#define NPY_LOGE10 2.3025850929940456840179914546843642 /* log_e 10 */
+#define NPY_PI 3.1415926535897932384626433832795029 /* pi */
+#define NPY_PI_2 1.5707963267948966192313216916397514 /* pi/2 */
+#define NPY_PI_4 0.7853981633974483096156608458198757 /* pi/4 */
+#define NPY_1_PI 0.3183098861837906715377675267450287 /* 1/pi */
+#define NPY_2_PI 0.6366197723675813430755350534900574 /* 2/pi */
+
+#define NPY_Ef 2.7182818284590452353602874713526625F /* e */
+#define NPY_LOG2Ef 1.4426950408889634073599246810018921F /* log_2 e */
+#define NPY_LOG10Ef 0.4342944819032518276511289189166051F /* log_10 e */
+#define NPY_LOGE2f 0.6931471805599453094172321214581766F /* log_e 2 */
+#define NPY_LOGE10f 2.3025850929940456840179914546843642F /* log_e 10 */
+#define NPY_PIf 3.1415926535897932384626433832795029F /* pi */
+#define NPY_PI_2f 1.5707963267948966192313216916397514F /* pi/2 */
+#define NPY_PI_4f 0.7853981633974483096156608458198757F /* pi/4 */
+#define NPY_1_PIf 0.3183098861837906715377675267450287F /* 1/pi */
+#define NPY_2_PIf 0.6366197723675813430755350534900574F /* 2/pi */
+
+#define NPY_El 2.7182818284590452353602874713526625L /* e */
+#define NPY_LOG2El 1.4426950408889634073599246810018921L /* log_2 e */
+#define NPY_LOG10El 0.4342944819032518276511289189166051L /* log_10 e */
+#define NPY_LOGE2l 0.6931471805599453094172321214581766L /* log_e 2 */
+#define NPY_LOGE10l 2.3025850929940456840179914546843642L /* log_e 10 */
+#define NPY_PIl 3.1415926535897932384626433832795029L /* pi */
+#define NPY_PI_2l 1.5707963267948966192313216916397514L /* pi/2 */
+#define NPY_PI_4l 0.7853981633974483096156608458198757L /* pi/4 */
+#define NPY_1_PIl 0.3183098861837906715377675267450287L /* 1/pi */
+#define NPY_2_PIl 0.6366197723675813430755350534900574L /* 2/pi */
+
+/*
+ * C99 double math funcs
+ */
+double npy_sin(double x);
+double npy_cos(double x);
+double npy_tan(double x);
+double npy_sinh(double x);
+double npy_cosh(double x);
+double npy_tanh(double x);
+
+double npy_asin(double x);
+double npy_acos(double x);
+double npy_atan(double x);
+double npy_aexp(double x);
+double npy_alog(double x);
+double npy_asqrt(double x);
+double npy_afabs(double x);
+
+double npy_log(double x);
+double npy_log10(double x);
+double npy_exp(double x);
+double npy_sqrt(double x);
+
+double npy_fabs(double x);
+double npy_ceil(double x);
+double npy_fmod(double x, double y);
+double npy_floor(double x);
+
+double npy_expm1(double x);
+double npy_log1p(double x);
+double npy_hypot(double x, double y);
+double npy_acosh(double x);
+double npy_asinh(double xx);
+double npy_atanh(double x);
+double npy_rint(double x);
+double npy_trunc(double x);
+double npy_exp2(double x);
+double npy_log2(double x);
+
+double npy_atan2(double x, double y);
+double npy_pow(double x, double y);
+/*
+ * IEEE 754 fpu handling. Those are guaranteed to be macros
+ */
+#ifndef NPY_HAVE_DECL_ISNAN
+ #define npy_isnan(x) ((x) != (x))
+#else
+ #define npy_isnan(x) isnan((x))
+#endif
+
+#ifndef NPY_HAVE_DECL_ISFINITE
+ #define npy_isfinite(x) !npy_isnan((x) + (-x))
+#else
+ #define npy_isfinite(x) isfinite((x))
+#endif
+
+#ifndef NPY_HAVE_DECL_ISINF
+ #define npy_isinf(x) (!npy_isfinite(x) && !npy_isnan(x))
+#else
+ #define npy_isinf(x) isinf((x))
+#endif
+
+#ifndef NPY_HAVE_DECL_SIGNBIT
+ int _npy_signbit_f(float x);
+ int _npy_signbit(double x);
+ int _npy_signbit_ld(npy_longdouble x);
+ #define npy_signbit(x) \
+ (sizeof (x) == sizeof (long double) ? _npy_signbit_ld (x) \
+ : sizeof (x) == sizeof (double) ? _npy_signbit_d (x) \
+ : _npy_signbit_f (x))
+#else
+ #define npy_signbit(x) signbit((x))
+#endif
+
+/*
+ * float C99 math functions
+ */
+
+float npy_sinf(float x);
+float npy_cosf(float x);
+float npy_tanf(float x);
+float npy_sinhf(float x);
+float npy_coshf(float x);
+float npy_tanhf(float x);
+float npy_fabsf(float x);
+float npy_floorf(float x);
+float npy_ceilf(float x);
+float npy_rintf(float x);
+float npy_truncf(float x);
+float npy_sqrtf(float x);
+float npy_log10f(float x);
+float npy_logf(float x);
+float npy_expf(float x);
+float npy_expm1f(float x);
+float npy_asinf(float x);
+float npy_acosf(float x);
+float npy_atanf(float x);
+float npy_asinhf(float x);
+float npy_acoshf(float x);
+float npy_atanhf(float x);
+float npy_log1pf(float x);
+float npy_exp2f(float x);
+float npy_log2f(float x);
+
+float npy_atan2f(float x, float y);
+float npy_hypotf(float x, float y);
+float npy_powf(float x, float y);
+float npy_fmodf(float x, float y);
+
+float npy_modff(float x, float* y);
+
+/*
+ * float C99 math functions
+ */
+
+npy_longdouble npy_sinl(npy_longdouble x);
+npy_longdouble npy_cosl(npy_longdouble x);
+npy_longdouble npy_tanl(npy_longdouble x);
+npy_longdouble npy_sinhl(npy_longdouble x);
+npy_longdouble npy_coshl(npy_longdouble x);
+npy_longdouble npy_tanhl(npy_longdouble x);
+npy_longdouble npy_fabsl(npy_longdouble x);
+npy_longdouble npy_floorl(npy_longdouble x);
+npy_longdouble npy_ceill(npy_longdouble x);
+npy_longdouble npy_rintl(npy_longdouble x);
+npy_longdouble npy_truncl(npy_longdouble x);
+npy_longdouble npy_sqrtl(npy_longdouble x);
+npy_longdouble npy_log10l(npy_longdouble x);
+npy_longdouble npy_logl(npy_longdouble x);
+npy_longdouble npy_expl(npy_longdouble x);
+npy_longdouble npy_expm1l(npy_longdouble x);
+npy_longdouble npy_asinl(npy_longdouble x);
+npy_longdouble npy_acosl(npy_longdouble x);
+npy_longdouble npy_atanl(npy_longdouble x);
+npy_longdouble npy_asinhl(npy_longdouble x);
+npy_longdouble npy_acoshl(npy_longdouble x);
+npy_longdouble npy_atanhl(npy_longdouble x);
+npy_longdouble npy_log1pl(npy_longdouble x);
+npy_longdouble npy_exp2l(npy_longdouble x);
+npy_longdouble npy_log2l(npy_longdouble x);
+
+npy_longdouble npy_atan2l(npy_longdouble x, npy_longdouble y);
+npy_longdouble npy_hypotl(npy_longdouble x, npy_longdouble y);
+npy_longdouble npy_powl(npy_longdouble x, npy_longdouble y);
+npy_longdouble npy_fmodl(npy_longdouble x, npy_longdouble y);
+
+npy_longdouble npy_modfl(npy_longdouble x, npy_longdouble* y);
+
+/*
+ * Non standard functions
+ */
+double npy_deg2rad(double x);
+double npy_rad2deg(double x);
+double npy_logaddexp(double x, double y);
+double npy_logaddexp2(double x, double y);
+
+float npy_deg2radf(float x);
+float npy_rad2degf(float x);
+float npy_logaddexpf(float x, float y);
+float npy_logaddexp2f(float x, float y);
+
+npy_longdouble npy_deg2radl(npy_longdouble x);
+npy_longdouble npy_rad2degl(npy_longdouble x);
+npy_longdouble npy_logaddexpl(npy_longdouble x, npy_longdouble y);
+npy_longdouble npy_logaddexp2l(npy_longdouble x, npy_longdouble y);
+
+#define npy_degrees npy_rad2deg
+#define npy_degreesf npy_rad2degf
+#define npy_degreesl npy_rad2degl
+
+#define npy_radians npy_deg2rad
+#define npy_radiansf npy_deg2radf
+#define npy_radiansl npy_deg2radl
+
+#endif
diff --git a/numpy/core/include/numpy/numpyconfig.h.in b/numpy/core/include/numpy/numpyconfig.h.in
index bdebf7078..4dba4e11e 100644
--- a/numpy/core/include/numpy/numpyconfig.h.in
+++ b/numpy/core/include/numpy/numpyconfig.h.in
@@ -6,6 +6,11 @@
#define NPY_SIZEOF_LONGDOUBLE @SIZEOF_LONG_DOUBLE@
#define NPY_SIZEOF_PY_INTPTR_T @SIZEOF_PY_INTPTR_T@
+@DEFINE_NPY_HAVE_DECL_ISNAN@
+@DEFINE_NPY_HAVE_DECL_ISINF@
+@DEFINE_NPY_HAVE_DECL_ISFINITE@
+@DEFINE_NPY_HAVE_DECL_SIGNBIT@
+
@DEFINE_NPY_NO_SIGNAL@
#define NPY_NO_SMP @NPY_NO_SMP@
diff --git a/numpy/core/setup.py b/numpy/core/setup.py
index 791d926a0..7d50f61dd 100644
--- a/numpy/core/setup.py
+++ b/numpy/core/setup.py
@@ -4,6 +4,14 @@ import sys
from os.path import join
from numpy.distutils import log
from distutils.dep_util import newer
+from distutils.sysconfig import get_config_var
+
+def pythonlib_dir():
+ """return path where libpython* is."""
+ if sys.platform == 'win32':
+ return os.path.join(sys.prefix, "libs")
+ else:
+ return get_config_var('LIBDIR')
def is_npy_no_signal():
"""Return True if the NPY_NO_SIGNAL symbol must be defined in configuration
@@ -35,6 +43,22 @@ def is_npy_no_smp():
nosmp = 0
return nosmp == 1
+def win32_checks(deflist):
+ from numpy.distutils.misc_util import get_build_architecture
+ a = get_build_architecture()
+
+ # Distutils hack on AMD64 on windows
+ print 'BUILD_ARCHITECTURE: %r, os.name=%r, sys.platform=%r' % \
+ (a, os.name, sys.platform)
+ if a == 'AMD64':
+ deflist.append('DISTUTILS_USE_SDK')
+
+ # On win32, force long double format string to be 'g', not
+ # 'Lg', since the MS runtime does not support long double whose
+ # size is > sizeof(double)
+ if a =="Intel":
+ deflist.append('FORCE_NO_LONG_DOUBLE_FORMATTING')
+
def check_math_capabilities(config, moredefs, mathlibs):
def check_func(func_name):
return config.check_func(func_name, libraries=mathlibs,
@@ -112,6 +136,69 @@ def check_math_capabilities(config, moredefs, mathlibs):
if st:
moredefs.append(name_to_defsymb("decl_%s" % f))
+def check_types(config, ext, build_dir):
+ private_defines = []
+ public_defines = []
+
+ config_cmd = config.get_config_cmd()
+
+ # Check we have the python header (-dev* packages on Linux)
+ result = config_cmd.check_header('Python.h')
+ if not result:
+ raise SystemError(
+ "Cannot compiler 'Python.h'. Perhaps you need to "\
+ "install python-dev|python-devel.")
+
+ # Check basic types sizes
+ for type in ('short', 'int', 'long', 'float', 'double', 'long double'):
+ res = config_cmd.check_type_size(type)
+ if res >= 0:
+ private_defines.append(('SIZEOF_%s' % sym2def(type), '%d' % res))
+ else:
+ raise SystemError("Checking sizeof (%s) failed !" % type)
+
+ for type in ('Py_intptr_t',):
+ res = config_cmd.check_type_size(type, headers=["Python.h"],
+ library_dirs=[pythonlib_dir()])
+ if res >= 0:
+ private_defines.append(('SIZEOF_%s' % sym2def(type), '%d' % res))
+ else:
+ raise SystemError("Checking sizeof (%s) failed !" % type)
+
+ # We check declaration AND type because that's how distutils does it.
+ if config_cmd.check_decl('PY_LONG_LONG', headers=['Python.h']):
+ st = config_cmd.check_type_size('PY_LONG_LONG', headers=['Python.h'], library_dirs=[pythonlib_dir()])
+ assert not st == 0
+ private_defines.append(('SIZEOF_%s' % sym2def('PY_LONG_LONG'), '%d' % res))
+
+ if not config_cmd.check_decl('CHAR_BIT', headers=['Python.h']):
+ raise RuntimeError(
+ "Config wo CHAR_BIT is not supported"\
+ ", please contact the maintainers")
+
+ return private_defines, public_defines
+
+def sym2def(symbol):
+ define = symbol.replace(' ', '_')
+ return define.upper()
+
+def check_mathlib(config_cmd):
+ # Testing the C math library
+ mathlibs = []
+ tc = testcode_mathlib()
+ mathlibs_choices = [[],['m'],['cpml']]
+ mathlib = os.environ.get('MATHLIB')
+ if mathlib:
+ mathlibs_choices.insert(0,mathlib.split(','))
+ for libs in mathlibs_choices:
+ if config_cmd.try_run(tc,libraries=libs):
+ mathlibs = libs
+ break
+ else:
+ raise EnvironmentError("math library missing; rerun "
+ "setup.py after setting the "
+ "MATHLIB env variable")
+ return mathlibs
def configuration(parent_package='',top_path=None):
from numpy.distutils.misc_util import Configuration,dot_join
@@ -131,70 +218,31 @@ def configuration(parent_package='',top_path=None):
def generate_config_h(ext, build_dir):
target = join(build_dir,header_dir,'config.h')
- dir = os.path.dirname(target)
- if not os.path.exists(dir):
- os.makedirs(dir)
+ d = os.path.dirname(target)
+ if not os.path.exists(d):
+ os.makedirs(d)
if newer(__file__,target):
config_cmd = config.get_config_cmd()
log.info('Generating %s',target)
- tc = generate_testcode(target)
- from distutils import sysconfig
- python_include = sysconfig.get_python_inc()
- python_h = join(python_include, 'Python.h')
- if not os.path.isfile(python_h):
- raise SystemError,\
- "Non-existing %s. Perhaps you need to install"\
- " python-dev|python-devel." % (python_h)
- result = config_cmd.try_run(tc,include_dirs=[python_include],
- library_dirs = default_lib_dirs)
- if not result:
- raise SystemError,"Failed to test configuration. "\
- "See previous error messages for more information."
- moredefs = []
- #
- mathlibs = []
- tc = testcode_mathlib()
- mathlibs_choices = [[],['m'],['cpml']]
- mathlib = os.environ.get('MATHLIB')
- if mathlib:
- mathlibs_choices.insert(0,mathlib.split(','))
- for libs in mathlibs_choices:
- if config_cmd.try_run(tc,libraries=libs):
- mathlibs = libs
- break
- else:
- raise EnvironmentError("math library missing; rerun "
- "setup.py after setting the "
- "MATHLIB env variable")
- ext.libraries.extend(mathlibs)
+ # Check sizeof
+ moredefs, ignored = check_types(config, ext, build_dir)
+
+ # Check math library and C99 math funcs availability
+ mathlibs = check_mathlib(config_cmd)
moredefs.append(('MATHLIB',','.join(mathlibs)))
check_math_capabilities(config_cmd, moredefs, mathlibs)
+ # Signal check
if is_npy_no_signal():
moredefs.append('__NPY_PRIVATE_NO_SIGNAL')
+ # Windows checks
if sys.platform=='win32' or os.name=='nt':
- from numpy.distutils.misc_util import get_build_architecture
- a = get_build_architecture()
- print 'BUILD_ARCHITECTURE: %r, os.name=%r, sys.platform=%r' % (a, os.name, sys.platform)
- if a == 'AMD64':
- moredefs.append('DISTUTILS_USE_SDK')
-
- if sys.version[:3] < '2.4':
- if config_cmd.check_func('strtod', decl=False,
- headers=['stdlib.h']):
- moredefs.append(('PyOS_ascii_strtod', 'strtod'))
-
- if sys.platform == "win32":
- from numpy.distutils.misc_util import get_build_architecture
- # On win32, force long double format string to be 'g', not
- # 'Lg', since the MS runtime does not support long double whose
- # size is > sizeof(double)
- if get_build_architecture()=="Intel":
- moredefs.append('FORCE_NO_LONG_DOUBLE_FORMATTING')
+ win32_checks(moredefs)
+ # Generate the config.h file from moredefs
target_f = open(target,'a')
for d in moredefs:
if isinstance(d,str):
@@ -202,16 +250,6 @@ def configuration(parent_package='',top_path=None):
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)
@@ -229,7 +267,11 @@ def configuration(parent_package='',top_path=None):
mathlibs.extend(value.split(','))
target_f.close()
- ext.libraries.extend(mathlibs)
+ # Ugly: this can be called within a library and not an extension,
+ # in which case there is no libraries attributes (and none is
+ # needed).
+ if hasattr(ext, 'libraries'):
+ ext.libraries.extend(mathlibs)
incl_dir = os.path.dirname(target)
if incl_dir not in config.numpy_include_dirs:
@@ -240,34 +282,35 @@ def configuration(parent_package='',top_path=None):
def generate_numpyconfig_h(ext, build_dir):
"""Depends on config.h: generate_config_h has to be called before !"""
target = join(build_dir,header_dir,'numpyconfig.h')
- dir = os.path.dirname(target)
- if not os.path.exists(dir):
- os.makedirs(dir)
+ d = os.path.dirname(target)
+ if not os.path.exists(d):
+ os.makedirs(d)
if newer(__file__,target):
config_cmd = config.get_config_cmd()
log.info('Generating %s',target)
testcode = generate_numpyconfig_code(target)
- from distutils import sysconfig
- python_include = sysconfig.get_python_inc()
- python_h = join(python_include, 'Python.h')
- if not os.path.isfile(python_h):
- raise SystemError,\
- "Non-existing %s. Perhaps you need to install"\
- " python-dev|python-devel." % (python_h)
-
- config.numpy_include_dirs
result = config_cmd.try_run(testcode,
- include_dirs = [python_include] + \
- config.numpy_include_dirs,
- library_dirs = default_lib_dirs)
-
+ include_dirs=config.numpy_include_dirs,
+ library_dirs=default_lib_dirs)
if not result:
raise SystemError,"Failed to generate numpy configuration. "\
"See previous error messages for more information."
moredefs = []
+ # 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
+ # XXX: we check those twice... should decouple tests from
+ # config.h/numpyconfig.h to avoid this
+ for f in ["isnan", "isinf", "signbit", "isfinite"]:
+ st = config_cmd.check_decl(f, headers = ["Python.h", "math.h"])
+ if st:
+ moredefs.append('NPY_HAVE_DECL_%s' % f.upper())
+
# Check wether we can use inttypes (C99) formats
if config_cmd.check_decl('PRIdPTR', headers = ['inttypes.h']):
moredefs.append(('NPY_USE_C99_FORMATS', 1))
@@ -353,6 +396,23 @@ def configuration(parent_package='',top_path=None):
if sys.platform == 'cygwin':
config.add_data_dir('include/numpy/fenv')
+ config.add_extension('_sort',
+ sources=[join('src','_sortmodule.c.src'),
+ generate_config_h,
+ generate_numpyconfig_h,
+ generate_numpy_api,
+ ],
+ )
+
+ # npymath needs the config.h and numpyconfig.h files to be generated, but
+ # build_clib cannot handle generate_config_h and generate_numpyconfig_h
+ # (don't ask). Because clib are generated before extensions, we have to
+ # explicitly add an extension which has generate_config_h and
+ # generate_numpyconfig_h as sources *before* adding npymath.
+ config.add_library('npymath',
+ sources=[join('src', 'npy_math.c.src')],
+ depends=[])
+
config.add_extension('multiarray',
sources = [join('src','multiarraymodule.c'),
generate_config_h,
@@ -364,6 +424,7 @@ def configuration(parent_package='',top_path=None):
join('*.py')
],
depends = deps,
+ libraries=['npymath'],
)
config.add_extension('umath',
@@ -374,7 +435,6 @@ def configuration(parent_package='',top_path=None):
generate_ufunc_api,
join('src','scalartypes.inc.src'),
join('src','arraytypes.inc.src'),
- join('src','umath_funcs_c99.inc.src'),
join('src','umath_funcs.inc.src'),
join('src','umath_loops.inc.src'),
],
@@ -382,14 +442,7 @@ def configuration(parent_package='',top_path=None):
generate_umath_py,
join(codegen_dir,'generate_ufunc_api.py'),
]+deps,
- )
-
- config.add_extension('_sort',
- sources=[join('src','_sortmodule.c.src'),
- generate_config_h,
- generate_numpyconfig_h,
- generate_numpy_api,
- ],
+ libraries=['npymath'],
)
config.add_extension('scalarmath',
@@ -446,70 +499,6 @@ int main(int argc, char *argv[])
"""
import sys
-def generate_testcode(target):
- if sys.platform == 'win32':
- target = target.replace('\\','\\\\')
- testcode = [r'''
-#include <Python.h>
-#include <limits.h>
-#include <stdio.h>
-
-int main(int argc, char **argv)
-{
-
- FILE *fp;
-
- fp = fopen("'''+target+'''","w");
- ''']
-
- c_size_test = r'''
-#ifndef %(sz)s
- fprintf(fp,"#define %(sz)s %%d\n", sizeof(%(type)s));
-#else
- fprintf(fp,"/* #define %(sz)s %%d */\n", %(sz)s);
-#endif
-'''
- for sz, t in [('SIZEOF_SHORT', 'short'),
- ('SIZEOF_INT', 'int'),
- ('SIZEOF_LONG', 'long'),
- ('SIZEOF_FLOAT', 'float'),
- ('SIZEOF_DOUBLE', 'double'),
- ('SIZEOF_LONG_DOUBLE', 'long double'),
- ('SIZEOF_PY_INTPTR_T', 'Py_intptr_t'),
- ]:
- testcode.append(c_size_test % {'sz' : sz, 'type' : t})
-
- testcode.append('#ifdef PY_LONG_LONG')
- testcode.append(c_size_test % {'sz' : 'SIZEOF_LONG_LONG',
- 'type' : 'PY_LONG_LONG'})
- testcode.append(c_size_test % {'sz' : 'SIZEOF_PY_LONG_LONG',
- 'type' : 'PY_LONG_LONG'})
-
-
- testcode.append(r'''
-#else
- fprintf(fp, "/* PY_LONG_LONG not defined */\n");
-#endif
-#ifndef CHAR_BIT
- {
- unsigned char var = 2;
- int i=0;
- while (var >= 2) {
- var = var << 1;
- i++;
- }
- fprintf(fp,"#define CHAR_BIT %d\n", i+1);
- }
-#else
- fprintf(fp, "/* #define CHAR_BIT %d */\n", CHAR_BIT);
-#endif
- fclose(fp);
- return 0;
-}
-''')
- testcode = '\n'.join(testcode)
- return testcode
-
def generate_numpyconfig_code(target):
"""Return the source code as a string of the code to generate the
numpyconfig header file."""
diff --git a/numpy/core/src/_signbit.c b/numpy/core/src/_signbit.c
index 3074c2716..a2ad38162 100644
--- a/numpy/core/src/_signbit.c
+++ b/numpy/core/src/_signbit.c
@@ -1,7 +1,7 @@
/* Adapted from cephes */
-static int
-signbit_d(double x)
+int
+_npy_signbit_d(double x)
{
union
{
diff --git a/numpy/core/src/multiarraymodule.c b/numpy/core/src/multiarraymodule.c
index 1829f7b40..83c9ed40d 100644
--- a/numpy/core/src/multiarraymodule.c
+++ b/numpy/core/src/multiarraymodule.c
@@ -89,13 +89,6 @@ _arraydescr_fromobj(PyObject *obj)
}
/*
- * XXX: We include c99 compat math module here because it is needed for
- * numpyos.c (included by arrayobject). This is bad - we should separate
- * declaration/implementation and share this in a lib.
- */
-#include "umath_funcs_c99.inc"
-
-/*
* Including this file is the only way I know how to declare functions
* static in each file, and store the pointers from functions in both
* arrayobject.c and multiarraymodule.c for the C-API
diff --git a/numpy/core/src/umath_funcs_c99.inc.src b/numpy/core/src/npy_math.c.src
index e0bcdebee..21fc7d427 100644
--- a/numpy/core/src/umath_funcs_c99.inc.src
+++ b/numpy/core/src/npy_math.c.src
@@ -2,7 +2,8 @@
* vim:syntax=c
* A small module to implement missing C99 math capabilities required by numpy
*
- * Please keep this independant of python !
+ * Please keep this independant of python ! Only basic types (npy_longdouble)
+ * can be used, otherwise, pure C, without any use of Python facilities
*
* How to add a function to this section
* -------------------------------------
@@ -38,15 +39,14 @@
* Ok:
* #ifdef SYMBOL_DEFINED_WEIRD_PLATFORM
* double exp(double);
- * #endif
+ * #endif
*/
-/*
- *****************************************************************************
- ** DISTRO VOODOO **
- *****************************************************************************
- */
+#include <Python.h>
+#include <math.h>
+#include "config.h"
+#include "numpy/npy_math.h"
/*
*****************************************************************************
@@ -56,7 +56,7 @@
/* Original code by Konrad Hinsen. */
#ifndef HAVE_EXPM1
-double expm1(double x)
+static double expm1(double x)
{
double u = exp(x);
if (u == 1.0) {
@@ -70,7 +70,7 @@ double expm1(double x)
#endif
#ifndef HAVE_LOG1P
-double log1p(double x)
+static double log1p(double x)
{
double u = 1. + x;
if (u == 1.0) {
@@ -82,7 +82,7 @@ double log1p(double x)
#endif
#ifndef HAVE_HYPOT
-double hypot(double x, double y)
+static double hypot(double x, double y)
{
double yx;
@@ -103,14 +103,14 @@ double hypot(double x, double y)
#endif
#ifndef HAVE_ACOSH
-double acosh(double x)
+static 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)
+static double asinh(double xx)
{
double x, d;
int sign;
@@ -132,7 +132,7 @@ double asinh(double xx)
#endif
#ifndef HAVE_ATANH
-double atanh(double x)
+static double atanh(double x)
{
if (x > 0) {
return -0.5*log1p(-2.0*x/(1.0 + x));
@@ -144,7 +144,7 @@ double atanh(double x)
#endif
#ifndef HAVE_RINT
-double rint(double x)
+static double rint(double x)
{
double y, r;
@@ -166,7 +166,7 @@ double rint(double x)
#endif
#ifndef HAVE_TRUNC
-double trunc(double x)
+static double trunc(double x)
{
return x < 0 ? ceil(x) : floor(x);
}
@@ -174,7 +174,7 @@ double trunc(double x)
#ifndef HAVE_EXP2
#define LOG2 0.69314718055994530943
-double exp2(double x)
+static double exp2(double x)
{
return exp(LOG2*x);
}
@@ -183,7 +183,7 @@ double exp2(double x)
#ifndef HAVE_LOG2
#define INVLOG2 1.4426950408889634074
-double log2(double x)
+static double log2(double x)
{
return INVLOG2*log(x);
}
@@ -195,35 +195,17 @@ double log2(double x)
** 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))
+#include "_signbit.c"
-static int signbit_f (float x)
+int _npy_signbit_f (float x)
{
- return signbit_d((double)x);
+ return _npy_signbit_d((double)x);
}
-static int signbit_ld (long double x)
+int _npy_signbit_ld (long double x)
{
- return signbit_d((double)x);
+ return _npy_signbit_d((double)x);
}
#endif
@@ -248,8 +230,8 @@ static int signbit_ld (long double x)
*/
/**begin repeat
- * #type = longdouble, float#
- * #TYPE = LONGDOUBLE, FLOAT#
+ * #type = npy_longdouble, float#
+ * #TYPE = NPY_LONGDOUBLE, FLOAT#
* #c = l,f#
* #C = L,F#
*/
@@ -265,7 +247,7 @@ static int signbit_ld (long double x)
#undef @kind@@c@
#endif
#ifndef HAVE_@KIND@@C@
-@type@ @kind@@c@(@type@ x)
+static @type@ @kind@@c@(@type@ x)
{
return (@type@) @kind@((double)x);
}
@@ -281,7 +263,7 @@ static int signbit_ld (long double x)
#undef @kind@@c@
#endif
#ifndef HAVE_@KIND@@C@
-@type@ @kind@@c@(@type@ x, @type@ y)
+static @type@ @kind@@c@(@type@ x, @type@ y)
{
return (@type@) @kind@((double)x, (double) y);
}
@@ -292,7 +274,7 @@ static int signbit_ld (long double x)
#undef modf@c@
#endif
#ifndef HAVE_MODF@C@
-@type@ modf@c@(@type@ x, @type@ *iptr)
+static @type@ modf@c@(@type@ x, @type@ *iptr)
{
double niptr;
double y = modf((double)x, &niptr);
@@ -302,3 +284,140 @@ static int signbit_ld (long double x)
#endif
/**end repeat**/
+
+/*
+ * Useful constants in three precisions:
+ * XXX: those should really be in the header
+ */
+
+/**begin repeat
+ * #c = f, ,l#
+ * #C = F, ,L#
+ */
+#define NPY_E@c@ 2.7182818284590452353602874713526625@C@ /* e */
+#define NPY_LOG2E@c@ 1.4426950408889634073599246810018921@C@ /* log_2 e */
+#define NPY_LOG10E@c@ 0.4342944819032518276511289189166051@C@ /* log_10 e */
+#define NPY_LOGE2@c@ 0.6931471805599453094172321214581766@C@ /* log_e 2 */
+#define NPY_LOGE10@c@ 2.3025850929940456840179914546843642@C@ /* log_e 10 */
+#define NPY_PI@c@ 3.1415926535897932384626433832795029@C@ /* pi */
+#define NPY_PI_2@c@ 1.5707963267948966192313216916397514@C@ /* pi/2 */
+#define NPY_PI_4@c@ 0.7853981633974483096156608458198757@C@ /* pi/4 */
+#define NPY_1_PI@c@ 0.3183098861837906715377675267450287@C@ /* 1/pi */
+#define NPY_2_PI@c@ 0.6366197723675813430755350534900574@C@ /* 2/pi */
+/**end repeat**/
+
+/*
+ * Non standard functions
+ */
+
+/**begin repeat
+ * #type = float, double, npy_longdouble#
+ * #c = f, ,l#
+ * #C = F, ,L#
+ */
+
+#define LOGE2 NPY_LOGE2@c@
+#define LOG2E NPY_LOG2E@c@
+#define RAD2DEG (180.0@c@/NPY_PI@c@)
+#define DEG2RAD (NPY_PI@c@/180.0@c@)
+
+static @type@ rad2deg@c@(@type@ x)
+{
+ return x*RAD2DEG;
+}
+
+static @type@ deg2rad@c@(@type@ x)
+{
+ return x*DEG2RAD;
+}
+
+static @type@ log2_1p@c@(@type@ x)
+{
+ @type@ u = 1 + x;
+ if (u == 1) {
+ return LOG2E*x;
+ } else {
+ return npy_log2@c@(u) * x / (u - 1);
+ }
+}
+
+static @type@ exp2_1m@c@(@type@ x)
+{
+ @type@ u = exp@c@(x);
+ if (u == 1.0) {
+ return LOGE2*x;
+ } else if (u - 1 == -1) {
+ return -LOGE2;
+ } else {
+ return (u - 1) * x/npy_log2@c@(u);
+ }
+}
+
+static @type@ logaddexp@c@(@type@ x, @type@ y)
+{
+ const @type@ tmp = x - y;
+ if (tmp > 0) {
+ return x + npy_log1p@c@(npy_exp@c@(-tmp));
+ }
+ else {
+ return y + npy_log1p@c@(npy_exp@c@(tmp));
+ }
+}
+
+static @type@ logaddexp2@c@(@type@ x, @type@ y)
+{
+ const @type@ tmp = x - y;
+ if (tmp > 0) {
+ return x + log2_1p@c@(npy_exp2@c@(-tmp));
+ }
+ else {
+ return y + log2_1p@c@(npy_exp2@c@(tmp));
+ }
+}
+
+#define degrees@c@ rad2deg@c@
+#define radians@c@ deg2rad@c@
+
+#undef LOGE2
+#undef LOG2E
+#undef RAD2DEG
+#undef DEG2RAD
+
+/**end repeat**/
+
+/*
+ * Decorate all the functions: those are the public ones
+ */
+
+/**begin repeat
+ * #type = npy_longdouble,double,float#
+ * #c = l,,f#
+ */
+/**begin repeat1
+ * #kind = sin,cos,tan,sinh,cosh,tanh,fabs,floor,ceil,rint,trunc,sqrt,log10,
+ * log,exp,expm1,asin,acos,atan,asinh,acosh,atanh,log1p,exp2,log2,
+ * rad2deg,deg2rad,exp2_1m#
+ */
+
+@type@ npy_@kind@@c@(@type@ x)
+{
+ return @kind@@c@(x);
+}
+
+/**end repeat1**/
+
+/**begin repeat1
+ * #kind = atan2,hypot,pow,fmod,logaddexp,logaddexp2#
+ */
+@type@ npy_@kind@@c@(@type@ x, @type@ y)
+{
+ return @kind@@c@(x, y);
+}
+/**end repeat1**/
+
+@type@ npy_modf@c@(@type@ x, @type@ *iptr)
+{
+ return modf@c@(x, iptr);
+}
+
+/**end repeat**/
diff --git a/numpy/core/src/numpyos.c b/numpy/core/src/numpyos.c
index 5408851f9..ca7cdafe9 100644
--- a/numpy/core/src/numpyos.c
+++ b/numpy/core/src/numpyos.c
@@ -1,6 +1,8 @@
#include <locale.h>
#include <stdio.h>
+#include "numpy/npy_math.h"
+
/* From the C99 standard, section 7.19.6: The exponent always contains at least
two digits, and only as many more digits as necessary to represent the
exponent.
@@ -249,21 +251,21 @@ _fix_ascii_format(char* buf, size_t buflen, int decimal)
const char *format, \
type val, int decimal) \
{ \
- if (isfinite(val)) { \
+ if (npy_isfinite(val)) { \
if(_check_ascii_format(format)) { \
return NULL; \
} \
PyOS_snprintf(buffer, buf_size, format, (print_type)val); \
return _fix_ascii_format(buffer, buf_size, decimal); \
} \
- else if (isnan(val)){ \
+ else if (npy_isnan(val)){ \
if (buf_size < 4) { \
return NULL; \
} \
strcpy(buffer, "nan"); \
} \
else { \
- if (signbit(val)) { \
+ if (npy_signbit(val)) { \
if (buf_size < 5) { \
return NULL; \
} \
diff --git a/numpy/core/src/umath_funcs.inc.src b/numpy/core/src/umath_funcs.inc.src
index 1e5337afe..ef87bd10a 100644
--- a/numpy/core/src/umath_funcs.inc.src
+++ b/numpy/core/src/umath_funcs.inc.src
@@ -10,109 +10,6 @@
#define M_LOG10_E 0.434294481903251827651128918916605082294397
-/* Useful constants in three precisions.*/
-
-/**begin repeat
- * #c = f, ,l#
- * #C = F, ,L#
- */
-#define NPY_E@c@ 2.7182818284590452353602874713526625@C@ /* e */
-#define NPY_LOG2E@c@ 1.4426950408889634073599246810018921@C@ /* log_2 e */
-#define NPY_LOG10E@c@ 0.4342944819032518276511289189166051@C@ /* log_10 e */
-#define NPY_LOGE2@c@ 0.6931471805599453094172321214581766@C@ /* log_e 2 */
-#define NPY_LOGE10@c@ 2.3025850929940456840179914546843642@C@ /* log_e 10 */
-#define NPY_PI@c@ 3.1415926535897932384626433832795029@C@ /* pi */
-#define NPY_PI_2@c@ 1.5707963267948966192313216916397514@C@ /* pi/2 */
-#define NPY_PI_4@c@ 0.7853981633974483096156608458198757@C@ /* pi/4 */
-#define NPY_1_PI@c@ 0.3183098861837906715377675267450287@C@ /* 1/pi */
-#define NPY_2_PI@c@ 0.6366197723675813430755350534900574@C@ /* 2/pi */
-/**end repeat**/
-
-/*
- ******************************************************************************
- ** FLOAT FUNCTIONS **
- ******************************************************************************
- */
-
-/**begin repeat
- * #type = float, double, longdouble#
- * #c = f, ,l#
- * #C = F, ,L#
- */
-
-#define LOGE2 NPY_LOGE2@c@
-#define LOG2E NPY_LOG2E@c@
-#define RAD2DEG (180.0@c@/NPY_PI@c@)
-#define DEG2RAD (NPY_PI@c@/180.0@c@)
-
-static @type@
-rad2deg@c@(@type@ x) {
- return x*RAD2DEG;
-}
-
-static @type@
-deg2rad@c@(@type@ x) {
- return x*DEG2RAD;
-}
-
-static @type@
-log2_1p@c@(@type@ x)
-{
- @type@ u = 1 + x;
- if (u == 1) {
- return LOG2E*x;
- } else {
- return log2@c@(u) * x / (u - 1);
- }
-}
-
-static @type@
-exp2_1m@c@(@type@ x)
-{
- @type@ u = exp@c@(x);
- if (u == 1.0) {
- return LOGE2*x;
- } else if (u - 1 == -1) {
- return -LOGE2;
- } else {
- return (u - 1) * x/log2@c@(u);
- }
-}
-
-static @type@
-logaddexp@c@(@type@ x, @type@ y)
-{
- const @type@ tmp = x - y;
- if (tmp > 0) {
- return x + log1p@c@(exp@c@(-tmp));
- }
- else {
- return y + log1p@c@(exp@c@(tmp));
- }
-}
-
-static @type@
-logaddexp2@c@(@type@ x, @type@ y)
-{
- const @type@ tmp = x - y;
- if (tmp > 0) {
- return x + log2_1p@c@(exp2@c@(-tmp));
- }
- else {
- return y + log2_1p@c@(exp2@c@(tmp));
- }
-}
-
-#define degrees@c@ rad2deg@c@
-#define radians@c@ deg2rad@c@
-
-#undef LOGE2
-#undef LOG2E
-#undef RAD2DEG
-#undef DEG2RAD
-
-/**end repeat**/
-
/*
*****************************************************************************
** PYTHON OBJECT FUNCTIONS **
@@ -261,7 +158,7 @@ nc_sqrt@c@(c@typ@ *x, c@typ@ *r)
if (x->real == 0. && x->imag == 0.)
*r = *x;
else {
- s = sqrt@c@((fabs@c@(x->real) + hypot@c@(x->real,x->imag))/2);
+ s = npy_sqrt@c@((npy_fabs@c@(x->real) + npy_hypot@c@(x->real,x->imag))/2);
d = x->imag/(2*s);
if (x->real > 0) {
r->real = s;
@@ -282,43 +179,43 @@ nc_sqrt@c@(c@typ@ *x, c@typ@ *r)
static void
nc_rint@c@(c@typ@ *x, c@typ@ *r)
{
- r->real = rint@c@(x->real);
- r->imag = rint@c@(x->imag);
+ r->real = npy_rint@c@(x->real);
+ r->imag = npy_rint@c@(x->imag);
}
static void
nc_log@c@(c@typ@ *x, c@typ@ *r)
{
- @typ@ l = hypot@c@(x->real,x->imag);
- r->imag = atan2@c@(x->imag, x->real);
- r->real = log@c@(l);
+ @typ@ l = npy_hypot@c@(x->real,x->imag);
+ r->imag = npy_atan2@c@(x->imag, x->real);
+ r->real = npy_log@c@(l);
return;
}
static void
nc_log1p@c@(c@typ@ *x, c@typ@ *r)
{
- @typ@ l = hypot@c@(x->real + 1,x->imag);
- r->imag = atan2@c@(x->imag, x->real + 1);
- r->real = log@c@(l);
+ @typ@ l = npy_hypot@c@(x->real + 1,x->imag);
+ r->imag = npy_atan2@c@(x->imag, x->real + 1);
+ r->real = npy_log@c@(l);
return;
}
static void
nc_exp@c@(c@typ@ *x, c@typ@ *r)
{
- @typ@ a = exp@c@(x->real);
- r->real = a*cos@c@(x->imag);
- r->imag = a*sin@c@(x->imag);
+ @typ@ a = npy_exp@c@(x->real);
+ r->real = a*npy_cos@c@(x->imag);
+ r->imag = a*npy_sin@c@(x->imag);
return;
}
static void
nc_expm1@c@(c@typ@ *x, c@typ@ *r)
{
- @typ@ a = exp@c@(x->real);
- r->real = a*cos@c@(x->imag) - 1;
- r->imag = a*sin@c@(x->imag);
+ @typ@ a = npy_exp@c@(x->real);
+ r->real = a*npy_cos@c@(x->imag) - 1;
+ r->imag = a*npy_sin@c@(x->imag);
return;
}
@@ -483,8 +380,8 @@ static void
nc_cos@c@(c@typ@ *x, c@typ@ *r)
{
@typ@ xr=x->real, xi=x->imag;
- r->real = cos@c@(xr)*cosh@c@(xi);
- r->imag = -sin@c@(xr)*sinh@c@(xi);
+ r->real = npy_cos@c@(xr)*npy_cosh@c@(xi);
+ r->imag = -npy_sin@c@(xr)*npy_sinh@c@(xi);
return;
}
@@ -492,8 +389,8 @@ static void
nc_cosh@c@(c@typ@ *x, c@typ@ *r)
{
@typ@ xr=x->real, xi=x->imag;
- r->real = cos@c@(xi)*cosh@c@(xr);
- r->imag = sin@c@(xi)*sinh@c@(xr);
+ r->real = npy_cos@c@(xi)*npy_cosh@c@(xr);
+ r->imag = npy_sin@c@(xi)*npy_sinh@c@(xr);
return;
}
@@ -510,8 +407,8 @@ static void
nc_sin@c@(c@typ@ *x, c@typ@ *r)
{
@typ@ xr=x->real, xi=x->imag;
- r->real = sin@c@(xr)*cosh@c@(xi);
- r->imag = cos@c@(xr)*sinh@c@(xi);
+ r->real = npy_sin@c@(xr)*npy_cosh@c@(xi);
+ r->imag = npy_cos@c@(xr)*npy_sinh@c@(xi);
return;
}
@@ -519,8 +416,8 @@ static void
nc_sinh@c@(c@typ@ *x, c@typ@ *r)
{
@typ@ xr=x->real, xi=x->imag;
- r->real = cos@c@(xi)*sinh@c@(xr);
- r->imag = sin@c@(xi)*cosh@c@(xr);
+ r->real = npy_cos@c@(xi)*npy_sinh@c@(xr);
+ r->imag = npy_sin@c@(xi)*npy_cosh@c@(xr);
return;
}
@@ -531,10 +428,10 @@ nc_tan@c@(c@typ@ *x, c@typ@ *r)
@typ@ rs,is,rc,ic;
@typ@ d;
@typ@ xr=x->real, xi=x->imag;
- sr = sin@c@(xr);
- cr = cos@c@(xr);
- shi = sinh@c@(xi);
- chi = cosh@c@(xi);
+ sr = npy_sin@c@(xr);
+ cr = npy_cos@c@(xr);
+ shi = npy_sinh@c@(xi);
+ chi = npy_cosh@c@(xi);
rs = sr*chi;
is = cr*shi;
rc = cr*chi;
@@ -552,10 +449,10 @@ nc_tanh@c@(c@typ@ *x, c@typ@ *r)
@typ@ rs,is,rc,ic;
@typ@ d;
@typ@ xr=x->real, xi=x->imag;
- si = sin@c@(xi);
- ci = cos@c@(xi);
- shr = sinh@c@(xr);
- chr = cosh@c@(xr);
+ si = npy_sin@c@(xi);
+ ci = npy_cos@c@(xi);
+ shr = npy_sinh@c@(xr);
+ chr = npy_cosh@c@(xr);
rs = ci*shr;
is = si*chr;
rc = ci*chr;
diff --git a/numpy/core/src/umath_loops.inc.src b/numpy/core/src/umath_loops.inc.src
index c754cef1f..04a8fd55c 100644
--- a/numpy/core/src/umath_loops.inc.src
+++ b/numpy/core/src/umath_loops.inc.src
@@ -860,7 +860,7 @@ static void
/**begin repeat1
* #kind = isnan, isinf, isfinite, signbit#
- * #func = isnan, isinf, isfinite, signbit#
+ * #func = npy_isnan, npy_isinf, npy_isfinite, npy_signbit#
**/
static void
@TYPE@_@kind@(char **args, intp *dimensions, intp *steps, void *NPY_UNUSED(func))
@@ -883,7 +883,7 @@ static void
BINARY_LOOP {
const @type@ in1 = *(@type@ *)ip1;
const @type@ in2 = *(@type@ *)ip2;
- *((@type@ *)op1) = (in1 @OP@ in2 || isnan(in1)) ? in1 : in2;
+ *((@type@ *)op1) = (in1 @OP@ in2 || npy_isnan(in1)) ? in1 : in2;
}
}
/**end repeat1**/
@@ -899,7 +899,7 @@ static void
BINARY_LOOP {
const @type@ in1 = *(@type@ *)ip1;
const @type@ in2 = *(@type@ *)ip2;
- *((@type@ *)op1) = (in1 @OP@ in2 || isnan(in2)) ? in1 : in2;
+ *((@type@ *)op1) = (in1 @OP@ in2 || npy_isnan(in2)) ? in1 : in2;
}
}
/**end repeat1**/
@@ -1173,7 +1173,7 @@ C@TYPE@_logical_not(char **args, intp *dimensions, intp *steps, void *NPY_UNUSED
/**begin repeat1
* #kind = isnan, isinf, isfinite#
- * #func = isnan, isinf, isfinite#
+ * #func = npy_isnan, npy_isinf, npy_isfinite#
* #OP = ||, ||, &&#
**/
static void
@@ -1272,7 +1272,7 @@ C@TYPE@_@kind@(char **args, intp *dimensions, intp *steps, void *NPY_UNUSED(func
const @type@ in1i = ((@type@ *)ip1)[1];
const @type@ in2r = ((@type@ *)ip2)[0];
const @type@ in2i = ((@type@ *)ip2)[1];
- if (@OP@(in1r, in1i, in2r, in2i) || isnan(in1r) || isnan(in1i)) {
+ if (@OP@(in1r, in1i, in2r, in2i) || npy_isnan(in1r) || npy_isnan(in1i)) {
((@type@ *)op1)[0] = in1r;
((@type@ *)op1)[1] = in1i;
}
@@ -1296,7 +1296,7 @@ C@TYPE@_@kind@(char **args, intp *dimensions, intp *steps, void *func)
const @type@ in1i = ((@type@ *)ip1)[1];
const @type@ in2r = ((@type@ *)ip2)[0];
const @type@ in2i = ((@type@ *)ip2)[1];
- if (@OP@(in1r, in1i, in2r, in2i) || isnan(in2r) || isnan(in2i)) {
+ if (@OP@(in1r, in1i, in2r, in2i) || npy_isnan(in2r) || npy_isnan(in2i)) {
((@type@ *)op1)[0] = in1r;
((@type@ *)op1)[1] = in1i;
}
diff --git a/numpy/core/src/umathmodule.c.src b/numpy/core/src/umathmodule.c.src
index a5557042f..f0eb20f4a 100644
--- a/numpy/core/src/umathmodule.c.src
+++ b/numpy/core/src/umathmodule.c.src
@@ -23,18 +23,13 @@
#include "abstract.h"
#include "config.h"
-/*
- * Looks like some versions of Python.h do naughty things, so math.h needs
- * to come after.
- */
-#include <math.h>
+#include "numpy/npy_math.h"
/*
*****************************************************************************
** INCLUDE GENERATED CODE **
*****************************************************************************
*/
-#include "umath_funcs_c99.inc"
#include "umath_funcs.inc"
#include "umath_loops.inc"
#include "umath_ufunc_object.inc"
diff --git a/numpy/distutils/command/build_clib.py b/numpy/distutils/command/build_clib.py
index 645c6427a..92498132d 100644
--- a/numpy/distutils/command/build_clib.py
+++ b/numpy/distutils/command/build_clib.py
@@ -10,7 +10,8 @@ from distutils.errors import DistutilsSetupError, DistutilsError, \
from numpy.distutils import log
from distutils.dep_util import newer_group
from numpy.distutils.misc_util import filter_sources, has_f_sources,\
- has_cxx_sources, all_strings, get_lib_source_files, is_sequence
+ has_cxx_sources, all_strings, get_lib_source_files, is_sequence, \
+ get_numpy_include_dirs
# Fix Python distutils bug sf #1718574:
_l = old_build_clib.user_options
@@ -162,8 +163,11 @@ class build_clib(old_build_clib):
macros = build_info.get('macros')
include_dirs = build_info.get('include_dirs')
+ if include_dirs is None:
+ include_dirs = []
extra_postargs = build_info.get('extra_compiler_args') or []
+ include_dirs.extend(get_numpy_include_dirs())
# where compiled F90 module files are:
module_dirs = build_info.get('module_dirs') or []
module_build_dir = os.path.dirname(lib_file)
diff --git a/numpy/distutils/command/config.py b/numpy/distutils/command/config.py
index 39ea5f3b1..74f96e3b0 100644
--- a/numpy/distutils/command/config.py
+++ b/numpy/distutils/command/config.py
@@ -11,6 +11,7 @@ from distutils.command.config import config as old_config
from distutils.command.config import LANG_EXT
from distutils import log
from distutils.file_util import copy_file
+from distutils.ccompiler import CompileError, LinkError
import distutils
from numpy.distutils.exec_command import exec_command
from numpy.distutils.mingw32ccompiler import generate_manifest
@@ -143,6 +144,12 @@ class was %s
(body, headers, include_dirs,
libraries, library_dirs, lang))
+ def check_header(self, header, include_dirs=None, library_dirs=None, lang='c'):
+ self._check_compiler()
+ return self.try_compile(
+ "/* we need a dummy line to make distutils happy */",
+ [header], include_dirs)
+
def check_decl(self, symbol,
headers=None, include_dirs=None):
self._check_compiler()
@@ -158,6 +165,81 @@ int main()
return self.try_compile(body, headers, include_dirs)
+ def check_type_size(self, type_name, headers=None, include_dirs=None, library_dirs=None):
+ """Check size of a given type."""
+ # XXX: should also implement the cross-compiling version (using binary
+ # search + array indexing, see AC_CHECK_SIZEOF).
+ self._check_compiler()
+
+ # We declare the functions to avoid warnings with -Wstrict-prototypes
+ body = r"""
+typedef %(type)s _dist_type_sizeof_;
+
+static long int longval (void)
+{
+ return (long int) (sizeof (_dist_type_sizeof_));
+}
+static unsigned long int ulongval (void)
+{
+ return (long int) (sizeof (_dist_type_sizeof_));
+}
+
+#include <stdio.h>
+#include <stdlib.h>
+int
+main (void)
+{
+
+ if (((long int) (sizeof (_dist_type_sizeof_))) < 0) {
+ long int i = longval ();
+ if (i != ((long int) (sizeof (_dist_type_sizeof_))))
+ return 1;
+ printf("%%ld\n", i);
+ } else {
+ unsigned long int i = ulongval ();
+ if (i != ((long int) (sizeof (_dist_type_sizeof_))))
+ return 1;
+ printf("%%lu\n", i);
+ }
+
+ return 0;
+}
+""" % {'type': type_name}
+
+ # XXX: this should be refactored (same code as get_output)
+ exitcode, output = 255, ''
+ size = None
+ try:
+ src, obj, exe = self._link(body, headers, include_dirs,
+ [], library_dirs, 'c')
+ #exe = os.path.join('.', exe)
+ exitstatus, output = exec_command(exe, execute_in='.')
+ if hasattr(os, 'WEXITSTATUS'):
+ exitcode = os.WEXITSTATUS(exitstatus)
+ if os.WIFSIGNALED(exitstatus):
+ sig = os.WTERMSIG(exitstatus)
+ log.error('subprocess exited with signal %d' % (sig,))
+ if sig == signal.SIGINT:
+ # control-C
+ raise KeyboardInterrupt
+ else:
+ exitcode = exitstatus
+ log.info("success!")
+
+ try:
+ size = int(output)
+ except ValueError:
+ log.error("Unexpected output %s" % output)
+ log.info("failure")
+ except (CompileError, LinkError):
+ log.info("failure.")
+
+ self._clean()
+ if size is not None:
+ return size
+ else:
+ return -1
+
def check_func(self, func,
headers=None, include_dirs=None,
libraries=None, library_dirs=None,