diff options
-rw-r--r-- | numpy/core/SConscript | 15 | ||||
-rw-r--r-- | numpy/core/code_generators/generate_umath.py | 2 | ||||
-rw-r--r-- | numpy/core/include/numpy/ndarrayobject.h | 67 | ||||
-rw-r--r-- | numpy/core/include/numpy/npy_common.h | 74 | ||||
-rw-r--r-- | numpy/core/include/numpy/npy_math.h | 217 | ||||
-rw-r--r-- | numpy/core/include/numpy/numpyconfig.h.in | 5 | ||||
-rw-r--r-- | numpy/core/setup.py | 291 | ||||
-rw-r--r-- | numpy/core/src/_signbit.c | 4 | ||||
-rw-r--r-- | numpy/core/src/multiarraymodule.c | 7 | ||||
-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.c | 8 | ||||
-rw-r--r-- | numpy/core/src/umath_funcs.inc.src | 165 | ||||
-rw-r--r-- | numpy/core/src/umath_loops.inc.src | 12 | ||||
-rw-r--r-- | numpy/core/src/umathmodule.c.src | 7 | ||||
-rw-r--r-- | numpy/distutils/command/build_clib.py | 6 | ||||
-rw-r--r-- | numpy/distutils/command/config.py | 82 |
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, |