numexpr 2.12.1__tar.gz → 2.13.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. {numexpr-2.12.1 → numexpr-2.13.0}/ADDFUNCS.rst +3 -3
  2. {numexpr-2.12.1 → numexpr-2.13.0}/ANNOUNCE.rst +5 -3
  3. {numexpr-2.12.1 → numexpr-2.13.0}/AUTHORS.txt +3 -0
  4. {numexpr-2.12.1 → numexpr-2.13.0}/PKG-INFO +1 -1
  5. {numexpr-2.12.1 → numexpr-2.13.0}/RELEASE_NOTES.rst +17 -1
  6. numexpr-2.13.0/VERSION +1 -0
  7. numexpr-2.13.0/numexpr/bespoke_functions.hpp +294 -0
  8. {numexpr-2.12.1 → numexpr-2.13.0}/numexpr/complex_functions.hpp +39 -0
  9. {numexpr-2.12.1 → numexpr-2.13.0}/numexpr/expressions.py +26 -13
  10. {numexpr-2.12.1 → numexpr-2.13.0}/numexpr/functions.hpp +56 -3
  11. {numexpr-2.12.1 → numexpr-2.13.0}/numexpr/interp_body.cpp +30 -0
  12. {numexpr-2.12.1 → numexpr-2.13.0}/numexpr/interpreter.cpp +49 -145
  13. {numexpr-2.12.1 → numexpr-2.13.0}/numexpr/interpreter.hpp +12 -0
  14. {numexpr-2.12.1 → numexpr-2.13.0}/numexpr/module.cpp +4 -0
  15. {numexpr-2.12.1 → numexpr-2.13.0}/numexpr/msvc_function_stubs.hpp +47 -0
  16. {numexpr-2.12.1 → numexpr-2.13.0}/numexpr/necompiler.py +10 -0
  17. {numexpr-2.12.1 → numexpr-2.13.0}/numexpr/numexpr_config.hpp +14 -9
  18. numexpr-2.13.0/numexpr/opcodes.hpp +214 -0
  19. {numexpr-2.12.1 → numexpr-2.13.0}/numexpr/tests/test_numexpr.py +72 -15
  20. {numexpr-2.12.1 → numexpr-2.13.0}/numexpr/version.py +2 -2
  21. {numexpr-2.12.1 → numexpr-2.13.0}/numexpr.egg-info/PKG-INFO +1 -1
  22. {numexpr-2.12.1 → numexpr-2.13.0}/numexpr.egg-info/SOURCES.txt +1 -0
  23. numexpr-2.12.1/VERSION +0 -1
  24. numexpr-2.12.1/numexpr/opcodes.hpp +0 -193
  25. {numexpr-2.12.1 → numexpr-2.13.0}/LICENSE.txt +0 -0
  26. {numexpr-2.12.1 → numexpr-2.13.0}/LICENSES/cpuinfo.txt +0 -0
  27. {numexpr-2.12.1 → numexpr-2.13.0}/MANIFEST.in +0 -0
  28. {numexpr-2.12.1 → numexpr-2.13.0}/README.rst +0 -0
  29. {numexpr-2.12.1 → numexpr-2.13.0}/bench/boolean_timing.py +0 -0
  30. {numexpr-2.12.1 → numexpr-2.13.0}/bench/free_threading.py +0 -0
  31. {numexpr-2.12.1 → numexpr-2.13.0}/bench/issue-36.py +0 -0
  32. {numexpr-2.12.1 → numexpr-2.13.0}/bench/issue-47.py +0 -0
  33. {numexpr-2.12.1 → numexpr-2.13.0}/bench/large_array_vs_numpy.py +0 -0
  34. {numexpr-2.12.1 → numexpr-2.13.0}/bench/multidim.py +0 -0
  35. {numexpr-2.12.1 → numexpr-2.13.0}/bench/poly.py +0 -0
  36. {numexpr-2.12.1 → numexpr-2.13.0}/bench/timing.py +0 -0
  37. {numexpr-2.12.1 → numexpr-2.13.0}/bench/unaligned-simple.py +0 -0
  38. {numexpr-2.12.1 → numexpr-2.13.0}/bench/varying-expr.py +0 -0
  39. {numexpr-2.12.1 → numexpr-2.13.0}/bench/vml_timing.py +0 -0
  40. {numexpr-2.12.1 → numexpr-2.13.0}/bench/vml_timing2.py +0 -0
  41. {numexpr-2.12.1 → numexpr-2.13.0}/bench/vml_timing3.py +0 -0
  42. {numexpr-2.12.1 → numexpr-2.13.0}/numexpr/__init__.py +0 -0
  43. {numexpr-2.12.1 → numexpr-2.13.0}/numexpr/cpuinfo.py +0 -0
  44. {numexpr-2.12.1 → numexpr-2.13.0}/numexpr/missing_posix_functions.hpp +0 -0
  45. {numexpr-2.12.1 → numexpr-2.13.0}/numexpr/module.hpp +0 -0
  46. {numexpr-2.12.1 → numexpr-2.13.0}/numexpr/numexpr_object.cpp +0 -0
  47. {numexpr-2.12.1 → numexpr-2.13.0}/numexpr/numexpr_object.hpp +0 -0
  48. {numexpr-2.12.1 → numexpr-2.13.0}/numexpr/str-two-way.hpp +0 -0
  49. {numexpr-2.12.1 → numexpr-2.13.0}/numexpr/tests/__init__.py +0 -0
  50. {numexpr-2.12.1 → numexpr-2.13.0}/numexpr/tests/conftest.py +0 -0
  51. {numexpr-2.12.1 → numexpr-2.13.0}/numexpr/utils.py +0 -0
  52. {numexpr-2.12.1 → numexpr-2.13.0}/numexpr/win32/pthread.c +0 -0
  53. {numexpr-2.12.1 → numexpr-2.13.0}/numexpr/win32/pthread.h +0 -0
  54. {numexpr-2.12.1 → numexpr-2.13.0}/numexpr/win32/stdint.h +0 -0
  55. {numexpr-2.12.1 → numexpr-2.13.0}/numexpr.egg-info/dependency_links.txt +0 -0
  56. {numexpr-2.12.1 → numexpr-2.13.0}/numexpr.egg-info/requires.txt +0 -0
  57. {numexpr-2.12.1 → numexpr-2.13.0}/numexpr.egg-info/top_level.txt +0 -0
  58. {numexpr-2.12.1 → numexpr-2.13.0}/pyproject.toml +0 -0
  59. {numexpr-2.12.1 → numexpr-2.13.0}/requirements.txt +0 -0
  60. {numexpr-2.12.1 → numexpr-2.13.0}/setup.cfg +0 -0
  61. {numexpr-2.12.1 → numexpr-2.13.0}/setup.py +0 -0
  62. {numexpr-2.12.1 → numexpr-2.13.0}/site.cfg.example +0 -0
@@ -54,7 +54,7 @@ Example:
54
54
  #define FUNC_FF(...)
55
55
  #endif
56
56
  ...
57
- FUNC_FF(FUNC_MYFUNC_FF, "myfunc_ff", myfuncf, myfuncf2, vfMyfunc)
57
+ FUNC_FF(FUNC_MYFUNC_FF, "myfunc_ff", myfuncf, myfuncf2, vsMyfunc)
58
58
  FUNC_FF(FUNC_FF_LAST, NULL, NULL, NULL, NULL)
59
59
  #ifdef ELIDE_FUNC_FF
60
60
  #undef ELIDE_FUNC_FF
@@ -171,7 +171,7 @@ Add clauses to generate the FUNC_CODES from the ``functions.hpp`` header, making
171
171
  };
172
172
  #endif
173
173
 
174
- Some functions (e.g. ``fmod``, ``isnan``) are not available in MKL, and so must be hard-coded here as well:
174
+ Some functions (e.g. ``fmod``, ``isnan``) are not available in MKL, and so must be hard-coded in ``bespoke_functions.hpp`` as well:
175
175
 
176
176
  .. code-block:: cpp
177
177
 
@@ -186,7 +186,7 @@ Some functions (e.g. ``fmod``, ``isnan``) are not available in MKL, and so must
186
186
  };
187
187
  #endif
188
188
 
189
- The complex case is slightlñy different (see other examples in the same file).
189
+ The complex case is slightly different (see other examples in the same file).
190
190
 
191
191
  Add case handling to the ``check_program`` function
192
192
 
@@ -1,11 +1,13 @@
1
1
  =========================
2
- Announcing NumExpr 2.12.1
2
+ Announcing NumExpr 2.13.0
3
3
  =========================
4
4
 
5
5
  Hi everyone,
6
6
 
7
- NumExpr 2.12.1 allows isnan/isfinite/isinf functions to be used with complex.
8
- Also, OneAPI MKL has been fixed. Thanks to Luke Shaw for these contributions.
7
+ NumExpr 2.13.0 introduced a bunch of new features including new
8
+ bitwise operators (&, |, ^, ~), floor division (//). It also adds
9
+ many new functions (like hypot, log2, maximum, minimum, nextafter...).
10
+ Thanks to Luke Shaw for these contributions.
9
11
 
10
12
  Project documentation is available at:
11
13
 
@@ -29,3 +29,6 @@ since 2016 to 2023.
29
29
 
30
30
  Teng Liu fixed many bugs, and in particular, contributed valuable fixes
31
31
  to the new regex sanitizer for expressions.
32
+
33
+ Luke Shaw contributed a bunch of new functions, and expanded the amount
34
+ of opcodes from 128 to 256.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: numexpr
3
- Version: 2.12.1
3
+ Version: 2.13.0
4
4
  Summary: Fast numerical expression evaluator for NumPy
5
5
  Author-email: "David M. Cooke, Francesc Alted, and others" <blosc@blosc.org>
6
6
  Maintainer-email: Blosc Development Team <blosc@blosc.org>
@@ -1,7 +1,23 @@
1
1
  =====================================
2
- Release notes for NumExpr 2.12 series
2
+ Release notes for NumExpr 2.13 series
3
3
  =====================================
4
4
 
5
+
6
+ Changes from 2.12.1 to 2.13.0
7
+ -----------------------------
8
+
9
+ * New functionality has been added:
10
+ * Bitwise operators (and, or, not, xor): `&, |, ~, ^`
11
+ * New binary arithmetic operator for floor division: `//`
12
+ * New functions: `signbit`, `hypot`, `copysign`, `nextafter`, `maximum`,
13
+ `minimum`, `log2`, `trunc`, `round` and `sign`.
14
+ * Also enables integer outputs for integer inputs for
15
+ `abs`, `fmod`, `copy`, `ones_like`, `sign` and `round`.
16
+
17
+ Thanks to Luke Shaw for the contributions.
18
+
19
+ * New wheels for Python 3.14 and 3.14t are provided.
20
+
5
21
  Changes from 2.12.0 to 2.12.1
6
22
  -----------------------------
7
23
 
numexpr-2.13.0/VERSION ADDED
@@ -0,0 +1 @@
1
+ 2.13.0
@@ -0,0 +1,294 @@
1
+ #include <numpy/npy_cpu.h>
2
+ #include <math.h>
3
+ #include <string.h>
4
+ #include <assert.h>
5
+ #include <vector>
6
+ #include "numexpr_config.hpp" // isnan definitions
7
+
8
+ // Generic sign function
9
+ inline int signi(int x) {return (0 < x) - (x < 0);}
10
+ inline long signl(long x) {return (0 < x) - (x < 0);}
11
+ inline double sign(double x){
12
+ // Floats: -1.0, 0.0, +1.0, NaN stays NaN
13
+ if (isnand(x)) {return NAN;}
14
+ if (x > 0) {return 1;}
15
+ if (x < 0) {return -1;}
16
+ return 0; // handles +0.0 and -0.0
17
+ }
18
+ inline float signf(float x){
19
+ // Floats: -1.0, 0.0, +1.0, NaN stays NaN
20
+ if (isnanf_(x)) {return NAN;}
21
+ if (x > 0) {return 1;}
22
+ if (x < 0) {return -1;}
23
+ return 0; // handles +0.0 and -0.0
24
+ }
25
+
26
+ // round function for ints
27
+ inline int rinti(int x) {return x;}
28
+ inline long rintl(long x) {return x;}
29
+ // abs function for ints
30
+ inline int fabsi(int x) {return x<0 ? -x: x;}
31
+ inline long fabsl(long x) {return x<0 ? -x: x;}
32
+ // fmod function for ints
33
+ // TODO: Have to add FUNC_III, FUNC_LLL signatures to functions.hpp to enable these
34
+ // inline int fmodi(int x, int y) {return (int)fmodf((float)x, (float)y);}
35
+ // inline long fmodl(long x, long y) {return (long)fmodf((long)x, (long)y);}
36
+
37
+ #ifdef USE_VML
38
+ static void viRint(MKL_INT n, const int* x, int* dest)
39
+ {
40
+ memcpy(dest, x, n * sizeof(int)); // just copy x1 which is already int
41
+ };
42
+
43
+ static void vlRint(MKL_INT n, const long* x, long* dest)
44
+ {
45
+ memcpy(dest, x, n * sizeof(long)); // just copy x1 which is already int
46
+ };
47
+
48
+ static void viFabs(MKL_INT n, const int* x, int* dest)
49
+ {
50
+ MKL_INT j;
51
+ for (j=0; j<n; j++) {
52
+ dest[j] = x[j] < 0 ? -x[j]: x[j];
53
+ };
54
+ };
55
+
56
+ static void vlFabs(MKL_INT n, const long* x, long* dest)
57
+ {
58
+ MKL_INT j;
59
+ for (j=0; j<n; j++) {
60
+ dest[j] = x[j] < 0 ? -x[j]: x[j];
61
+ };
62
+ };
63
+
64
+ /* Fake vsConj function just for casting purposes inside numexpr */
65
+ static void vsConj(MKL_INT n, const float* x1, float* dest)
66
+ {
67
+ MKL_INT j;
68
+ for (j=0; j<n; j++) {
69
+ dest[j] = x1[j];
70
+ };
71
+ };
72
+
73
+ /* fmod not available in VML */
74
+ static void vsfmod(MKL_INT n, const float* x1, const float* x2, float* dest)
75
+ {
76
+ MKL_INT j;
77
+ for(j=0; j < n; j++) {
78
+ dest[j] = fmodf(x1[j], x2[j]);
79
+ };
80
+ }
81
+ static void vdfmod(MKL_INT n, const double* x1, const double* x2, double* dest)
82
+ {
83
+ MKL_INT j;
84
+ for(j=0; j < n; j++) {
85
+ dest[j] = fmod(x1[j], x2[j]);
86
+ };
87
+ };
88
+ // TODO: Have to add FUNC_III, FUNC_LLL signatures to functions.hpp
89
+ // static void vifmod(MKL_INT n, const int* x1, const int* x2, int* dest)
90
+ // {
91
+ // MKL_INT j;
92
+ // for(j=0; j < n; j++) {
93
+ // dest[j] = fmodi(x1[j], x2[j]);
94
+ // };
95
+ // };
96
+ // static void vlfmod(MKL_INT n, const long* x1, const long* x2, long* dest)
97
+ // {
98
+ // MKL_INT j;
99
+ // for(j=0; j < n; j++) {
100
+ // dest[j] = fmodl(x1[j], x2[j]);
101
+ // };
102
+ // };
103
+
104
+ /* no isnan, isfinite, isinf or signbit in VML */
105
+ static void vsIsfinite(MKL_INT n, const float* x1, bool* dest)
106
+ {
107
+ MKL_INT j;
108
+ for (j=0; j<n; j++) {
109
+ dest[j] = isfinitef_(x1[j]);
110
+ };
111
+ };
112
+ static void vsIsinf(MKL_INT n, const float* x1, bool* dest)
113
+ {
114
+ MKL_INT j;
115
+ for (j=0; j<n; j++) {
116
+ dest[j] = isinff_(x1[j]);
117
+ };
118
+ };
119
+ static void vsIsnan(MKL_INT n, const float* x1, bool* dest)
120
+ {
121
+ MKL_INT j;
122
+ for (j=0; j<n; j++) {
123
+ dest[j] = isnanf_(x1[j]);
124
+ };
125
+ };
126
+ static void vsSignBit(MKL_INT n, const float* x1, bool* dest)
127
+ {
128
+ MKL_INT j;
129
+ for (j=0; j<n; j++) {
130
+ dest[j] = signbitf(x1[j]);
131
+ };
132
+ };
133
+
134
+ /* no isnan, isfinite, isinf, signbit in VML */
135
+ static void vdIsfinite(MKL_INT n, const double* x1, bool* dest)
136
+ {
137
+ MKL_INT j;
138
+ for (j=0; j<n; j++) {
139
+ dest[j] = isfinited(x1[j]);
140
+ };
141
+ };
142
+ static void vdIsinf(MKL_INT n, const double* x1, bool* dest)
143
+ {
144
+ MKL_INT j;
145
+ for (j=0; j<n; j++) {
146
+ dest[j] = isinfd(x1[j]);
147
+ };
148
+ };
149
+ static void vdIsnan(MKL_INT n, const double* x1, bool* dest)
150
+ {
151
+ MKL_INT j;
152
+ for (j=0; j<n; j++) {
153
+ dest[j] = isnand(x1[j]);
154
+ };
155
+ };
156
+ static void vdSignBit(MKL_INT n, const double* x1, bool* dest)
157
+ {
158
+ MKL_INT j;
159
+ for (j=0; j<n; j++) {
160
+ dest[j] = signbit(x1[j]);
161
+ };
162
+ };
163
+
164
+ /* no isnan, isfinite or isinf in VML */
165
+ static void vzIsfinite(MKL_INT n, const MKL_Complex16* x1, bool* dest)
166
+ {
167
+ MKL_INT j;
168
+ for (j=0; j<n; j++) {
169
+ dest[j] = isfinited(x1[j].real) && isfinited(x1[j].imag);
170
+ };
171
+ };
172
+ static void vzIsinf(MKL_INT n, const MKL_Complex16* x1, bool* dest)
173
+ {
174
+ MKL_INT j;
175
+ for (j=0; j<n; j++) {
176
+ dest[j] = isinfd(x1[j].real) || isinfd(x1[j].imag);
177
+ };
178
+ };
179
+ static void vzIsnan(MKL_INT n, const MKL_Complex16* x1, bool* dest)
180
+ {
181
+ MKL_INT j;
182
+ for (j=0; j<n; j++) {
183
+ dest[j] = isnand(x1[j].real) || isnand(x1[j].imag);
184
+ };
185
+ };
186
+
187
+ /* Fake vdConj function just for casting purposes inside numexpr */
188
+ static void vdConj(MKL_INT n, const double* x1, double* dest)
189
+ {
190
+ MKL_INT j;
191
+ for (j=0; j<n; j++) {
192
+ dest[j] = x1[j];
193
+ };
194
+ };
195
+
196
+ /* various functions not available in VML */
197
+ static void vzExpm1(MKL_INT n, const MKL_Complex16* x1, MKL_Complex16* dest)
198
+ {
199
+ MKL_INT j;
200
+ vzExp(n, x1, dest);
201
+ for (j=0; j<n; j++) {
202
+ dest[j].real -= 1.0;
203
+ };
204
+ };
205
+
206
+ static void vzLog1p(MKL_INT n, const MKL_Complex16* x1, MKL_Complex16* dest)
207
+ {
208
+ MKL_INT j;
209
+ for (j=0; j<n; j++) {
210
+ dest[j].real = x1[j].real + 1;
211
+ dest[j].imag = x1[j].imag;
212
+ };
213
+ vzLn(n, dest, dest);
214
+ };
215
+
216
+ static void vzLog2(MKL_INT n, const MKL_Complex16* x1, MKL_Complex16* dest)
217
+ {
218
+ MKL_INT j;
219
+ vzLn(n, x1, dest);
220
+ for (j=0; j<n; j++) {
221
+ dest[j].real = dest[j].real * M_LOG2_E;
222
+ dest[j].imag = dest[j].imag * M_LOG2_E;
223
+ };
224
+ };
225
+
226
+ static void vzRint(MKL_INT n, const MKL_Complex16* x1, MKL_Complex16* dest)
227
+ {
228
+ MKL_INT j;
229
+ for (j=0; j<n; j++) {
230
+ dest[j].real = rint(x1[j].real);
231
+ dest[j].imag = rint(x1[j].imag);
232
+ };
233
+ };
234
+
235
+ /* Use this instead of native vzAbs in VML as it seems to work badly */
236
+ static void vzAbs_(MKL_INT n, const MKL_Complex16* x1, MKL_Complex16* dest)
237
+ {
238
+ MKL_INT j;
239
+ for (j=0; j<n; j++) {
240
+ dest[j].real = sqrt(x1[j].real*x1[j].real + x1[j].imag*x1[j].imag);
241
+ dest[j].imag = 0;
242
+ };
243
+ };
244
+
245
+ /*sign functions*/
246
+ static void vsSign(MKL_INT n, const float* x1, float* dest)
247
+ {
248
+ MKL_INT j;
249
+ for(j=0; j < n; j++) {
250
+ dest[j] = signf(x1[j]);
251
+ };
252
+ };
253
+ static void vdSign(MKL_INT n, const double* x1, double* dest)
254
+ {
255
+ MKL_INT j;
256
+ for(j=0; j < n; j++) {
257
+ dest[j] = sign(x1[j]);
258
+ };
259
+ };
260
+ static void viSign(MKL_INT n, const int* x1, int* dest)
261
+ {
262
+ MKL_INT j;
263
+ for(j=0; j < n; j++) {
264
+ dest[j] = signi(x1[j]);
265
+ };
266
+ };
267
+ static void vlSign(MKL_INT n, const long* x1, long* dest)
268
+ {
269
+ MKL_INT j;
270
+ for(j=0; j < n; j++) {
271
+ dest[j] = signl(x1[j]);
272
+ };
273
+ };
274
+ static void vzSign(MKL_INT n, const MKL_Complex16* x1, MKL_Complex16* dest)
275
+ {
276
+ MKL_INT j;
277
+ double mag;
278
+ for(j=0; j < n; j++) {
279
+ mag = sqrt(x1[j].real*x1[j].real + x1[j].imag*x1[j].imag);
280
+ if (isnand(mag)) {
281
+ dest[j].real = NAN;
282
+ dest[j].imag = NAN;
283
+ }
284
+ else if (mag == 0) {
285
+ dest[j].real = 0;
286
+ dest[j].imag = 0;
287
+ }
288
+ else {
289
+ dest[j].real = x1[j].real / mag;
290
+ dest[j].imag = x1[j].imag / mag;
291
+ }
292
+ };
293
+ };
294
+ #endif
@@ -11,6 +11,7 @@
11
11
  **********************************************************************/
12
12
 
13
13
  // Replace npy_cdouble with std::complex<double>
14
+ #include <math.h> // NAN
14
15
  #include <complex>
15
16
 
16
17
  /* constants */
@@ -347,6 +348,8 @@ nc_cosh(std::complex<double> *x, std::complex<double> *r)
347
348
 
348
349
 
349
350
  #define M_LOG10_E 0.434294481903251827651128918916605082294397
351
+ #define M_LOG2_E 1.44269504088896340735992468100189213742664
352
+
350
353
 
351
354
  static void
352
355
  nc_log10(std::complex<double> *x, std::complex<double> *r)
@@ -357,6 +360,15 @@ nc_log10(std::complex<double> *x, std::complex<double> *r)
357
360
  return;
358
361
  }
359
362
 
363
+ static void
364
+ nc_log2(std::complex<double> *x, std::complex<double> *r)
365
+ {
366
+ nc_log(x, r);
367
+ r->real(r->real() * M_LOG2_E);
368
+ r->imag(r->imag() * M_LOG2_E);
369
+ return;
370
+ }
371
+
360
372
  static void
361
373
  nc_sin(std::complex<double> *x, std::complex<double> *r)
362
374
  {
@@ -424,6 +436,13 @@ nc_abs(std::complex<double> *x, std::complex<double> *r)
424
436
  r->imag(0);
425
437
  }
426
438
 
439
+ static void
440
+ nc_rint(std::complex<double> *x, std::complex<double> *r)
441
+ {
442
+ r->real(rint(x->real()));
443
+ r->imag(rint(x->imag()));
444
+ }
445
+
427
446
  static bool
428
447
  nc_isinf(std::complex<double> *x)
429
448
  {
@@ -453,4 +472,24 @@ nc_isfinite(std::complex<double> *x)
453
472
  br = isfinited(xr);
454
473
  return bi && br;
455
474
  }
475
+
476
+ static void
477
+ nc_sign(std::complex<double> *x, std::complex<double> *r)
478
+ {
479
+ if (nc_isnan(x)){
480
+ r->real(NAN);
481
+ r->imag(NAN);
482
+ }
483
+ std::complex<double> mag;
484
+ nc_abs(x, &mag);
485
+ if (mag.real() == 0){
486
+ r->real(0);
487
+ r->imag(0);
488
+ }
489
+ else{
490
+ r->real(x->real()/mag.real());
491
+ r->imag(x->imag()/mag.real());
492
+ }
493
+ }
494
+
456
495
  #endif // NUMEXPR_COMPLEX_FUNCTIONS_HPP
@@ -186,11 +186,12 @@ def func(func, minkind=None, maxkind=None):
186
186
  return ConstantNode(func(*[x.value for x in args]))
187
187
  kind = commonKind(args)
188
188
  if kind in ('int', 'long'):
189
- # Exception for following NumPy casting rules
190
- #FIXME: this is not always desirable. The following
191
- # functions which return ints (for int inputs) on numpy
192
- # but not on numexpr: copy, abs, fmod, ones_like
193
- kind = 'double'
189
+ if func.__name__ not in ('copy', 'abs', 'ones_like', 'round', 'sign'):
190
+ # except for these special functions (which return ints for int inputs in NumPy)
191
+ # just do a cast to double
192
+ # FIXME: 'fmod' outputs ints for NumPy when inputs are ints, but need to
193
+ # add new function signatures FUNC_LLL FUNC_III to support this
194
+ kind = 'double'
194
195
  else:
195
196
  # Apply regular casting rules
196
197
  if minkind and kind_rank.index(minkind) > kind_rank.index(kind):
@@ -348,16 +349,26 @@ functions = {
348
349
 
349
350
  'fmod': func(numpy.fmod, 'float'),
350
351
  'arctan2': func(numpy.arctan2, 'float'),
352
+ 'hypot': func(numpy.hypot, 'double'),
353
+ 'nextafter': func(numpy.nextafter, 'double'),
354
+ 'copysign': func(numpy.copysign, 'double'),
355
+ 'maximum': func(numpy.maximum, 'double'),
356
+ 'minimum': func(numpy.minimum, 'double'),
357
+
351
358
 
352
359
  'log': func(numpy.log, 'float'),
353
360
  'log1p': func(numpy.log1p, 'float'),
354
361
  'log10': func(numpy.log10, 'float'),
362
+ 'log2': func(numpy.log2, 'float'),
355
363
  'exp': func(numpy.exp, 'float'),
356
364
  'expm1': func(numpy.expm1, 'float'),
357
365
 
358
366
  'abs': func(numpy.absolute, 'float'),
359
367
  'ceil': func(numpy.ceil, 'float', 'double'),
360
368
  'floor': func(numpy.floor, 'float', 'double'),
369
+ 'round': func(numpy.round, 'double'),
370
+ 'trunc': func(numpy.trunc, 'double'),
371
+ 'sign': func(numpy.sign, 'double'),
361
372
 
362
373
  'where': where_func,
363
374
 
@@ -366,9 +377,10 @@ functions = {
366
377
  'complex': func(complex, 'complex'),
367
378
  'conj': func(numpy.conj, 'complex'),
368
379
 
369
- 'isnan': func(numpy.isnan, 'bool'),
370
- 'isfinite': func(numpy.isfinite, 'bool'),
371
- 'isinf': func(numpy.isinf, 'bool'),
380
+ 'isnan': func(numpy.isnan, 'double'),
381
+ 'isfinite': func(numpy.isfinite, 'double'),
382
+ 'isinf': func(numpy.isinf, 'double'),
383
+ 'signbit': func(numpy.signbit, 'double'),
372
384
 
373
385
  'sum': gen_reduce_axis_func('sum'),
374
386
  'prod': gen_reduce_axis_func('prod'),
@@ -441,6 +453,7 @@ class ExpressionNode():
441
453
  __mul__ = __rmul__ = binop('mul')
442
454
  __truediv__ = truediv_op
443
455
  __rtruediv__ = rtruediv_op
456
+ __floordiv__ = binop("floordiv")
444
457
  __pow__ = pow_op
445
458
  __rpow__ = binop('pow', reversed=True)
446
459
  __mod__ = binop('mod')
@@ -451,10 +464,10 @@ class ExpressionNode():
451
464
  __rshift__ = binop('rshift')
452
465
  __rrshift__ = binop('rshift', reversed=True)
453
466
 
454
- # boolean operations
455
-
456
- __and__ = binop('and', kind='bool')
457
- __or__ = binop('or', kind='bool')
467
+ # bitwise or logical operations
468
+ __and__ = binop('and')
469
+ __or__ = binop('or')
470
+ __xor__ = binop('xor')
458
471
 
459
472
  __gt__ = binop('gt', kind='bool')
460
473
  __ge__ = binop('ge', kind='bool')
@@ -525,6 +538,6 @@ class FuncNode(OpNode):
525
538
  def __init__(self, opcode=None, args=None, kind=None):
526
539
  if (kind is None) and (args is not None):
527
540
  kind = commonKind(args)
528
- if opcode in ("isnan", "isfinite", "isinf"): # bodge for boolean return functions
541
+ if opcode in ("isnan", "isfinite", "isinf", "signbit"): # bodge for boolean return functions
529
542
  kind = 'bool'
530
543
  OpNode.__init__(self, opcode, args, kind)
@@ -30,12 +30,17 @@ FUNC_FF(FUNC_ARCTANH_FF, "arctanh_ff", atanhf, atanhf2, vsAtanh)
30
30
  FUNC_FF(FUNC_LOG_FF, "log_ff", logf, logf2, vsLn)
31
31
  FUNC_FF(FUNC_LOG1P_FF, "log1p_ff", log1pf, log1pf2, vsLog1p)
32
32
  FUNC_FF(FUNC_LOG10_FF, "log10_ff", log10f, log10f2, vsLog10)
33
+ FUNC_FF(FUNC_LOG2_FF, "log2_ff", log2f, log2f2, vsLog2)
33
34
  FUNC_FF(FUNC_EXP_FF, "exp_ff", expf, expf2, vsExp)
34
35
  FUNC_FF(FUNC_EXPM1_FF, "expm1_ff", expm1f, expm1f2, vsExpm1)
35
36
  FUNC_FF(FUNC_ABS_FF, "absolute_ff", fabsf, fabsf2, vsAbs)
36
37
  FUNC_FF(FUNC_CONJ_FF, "conjugate_ff",fconjf, fconjf2, vsConj)
37
38
  FUNC_FF(FUNC_CEIL_FF, "ceil_ff", ceilf, ceilf2, vsCeil)
38
39
  FUNC_FF(FUNC_FLOOR_FF, "floor_ff", floorf, floorf2, vsFloor)
40
+ FUNC_FF(FUNC_TRUNC_FF, "trunc_ff", truncf, truncf2, vsTrunc)
41
+ FUNC_FF(FUNC_SIGN_FF, "sign_ff", signf, signf2, vsSign)
42
+ //rint rounds to nearest even integer, matching NumPy (round doesn't)
43
+ FUNC_FF(FUNC_ROUND_FF, "round_ff", rintf, rintf2, vsRint)
39
44
  FUNC_FF(FUNC_FF_LAST, NULL, NULL, NULL, NULL)
40
45
  #ifdef ELIDE_FUNC_FF
41
46
  #undef ELIDE_FUNC_FF
@@ -48,6 +53,11 @@ FUNC_FF(FUNC_FF_LAST, NULL, NULL, NULL, NULL)
48
53
  #endif
49
54
  FUNC_FFF(FUNC_FMOD_FFF, "fmod_fff", fmodf, fmodf2, vsfmod)
50
55
  FUNC_FFF(FUNC_ARCTAN2_FFF, "arctan2_fff", atan2f, atan2f2, vsAtan2)
56
+ FUNC_FFF(FUNC_HYPOT_FFF, "hypot_fff", hypotf, hypotf2, vsHypot)
57
+ FUNC_FFF(FUNC_NEXTAFTER_FFF, "nextafter_fff", nextafterf, nextafterf2, vsNextAfter)
58
+ FUNC_FFF(FUNC_COPYSIGN_FFF, "copysign_fff", copysignf, copysignf2, vsCopySign)
59
+ FUNC_FFF(FUNC_MAXIMUM_FFF, "maximum_fff", fmaxf, fmaxf2, vsFmax)
60
+ FUNC_FFF(FUNC_MINIMUM_FFF, "minimum_fff", fminf, fminf2, vsFmin)
51
61
  FUNC_FFF(FUNC_FFF_LAST, NULL, NULL, NULL, NULL)
52
62
  #ifdef ELIDE_FUNC_FFF
53
63
  #undef ELIDE_FUNC_FFF
@@ -74,12 +84,17 @@ FUNC_DD(FUNC_ARCTANH_DD, "arctanh_dd", atanh, vdAtanh)
74
84
  FUNC_DD(FUNC_LOG_DD, "log_dd", log, vdLn)
75
85
  FUNC_DD(FUNC_LOG1P_DD, "log1p_dd", log1p, vdLog1p)
76
86
  FUNC_DD(FUNC_LOG10_DD, "log10_dd", log10, vdLog10)
87
+ FUNC_DD(FUNC_LOG2_DD, "log2_dd", log2, vdLog2)
77
88
  FUNC_DD(FUNC_EXP_DD, "exp_dd", exp, vdExp)
78
89
  FUNC_DD(FUNC_EXPM1_DD, "expm1_dd", expm1, vdExpm1)
79
90
  FUNC_DD(FUNC_ABS_DD, "absolute_dd", fabs, vdAbs)
80
91
  FUNC_DD(FUNC_CONJ_DD, "conjugate_dd",fconj, vdConj)
81
92
  FUNC_DD(FUNC_CEIL_DD, "ceil_dd", ceil, vdCeil)
82
93
  FUNC_DD(FUNC_FLOOR_DD, "floor_dd", floor, vdFloor)
94
+ FUNC_DD(FUNC_TRUNC_DD, "trunc_dd", trunc, vdTrunc)
95
+ FUNC_DD(FUNC_SIGN_DD, "sign_dd", sign, vdSign)
96
+ //rint rounds to nearest even integer, matching NumPy (round doesn't)
97
+ FUNC_DD(FUNC_ROUND_DD, "round_dd", rint, vdRint)
83
98
  FUNC_DD(FUNC_DD_LAST, NULL, NULL, NULL)
84
99
  #ifdef ELIDE_FUNC_DD
85
100
  #undef ELIDE_FUNC_DD
@@ -94,6 +109,7 @@ FUNC_DD(FUNC_DD_LAST, NULL, NULL, NULL)
94
109
  FUNC_BD(FUNC_ISNAN_BD, "isnan_bd", isnand, vdIsnan)
95
110
  FUNC_BD(FUNC_ISFINITE_BD, "isfinite_bd", isfinited, vdIsfinite)
96
111
  FUNC_BD(FUNC_ISINF_BD, "isinf_bd", isinfd, vdIsinf)
112
+ FUNC_BD(FUNC_SIGNBIT_BD, "signbit_bd", signbit, vdSignBit)
97
113
  FUNC_BD(FUNC_BD_LAST, NULL, NULL, NULL)
98
114
  #ifdef ELIDE_FUNC_BD
99
115
  #undef ELIDE_FUNC_BD
@@ -105,9 +121,10 @@ FUNC_BD(FUNC_BD_LAST, NULL, NULL, NULL)
105
121
  #define ELIDE_FUNC_BF
106
122
  #define FUNC_BF(...)
107
123
  #endif // use wrappers as there is name collision with isnanf in std
108
- FUNC_BF(FUNC_ISNAN_BF, "isnan_bf", isnanf_, isnanf2, vfIsnan)
109
- FUNC_BF(FUNC_ISFINITE_BF, "isfinite_bf", isfinitef_, isfinitef2, vfIsfinite)
110
- FUNC_BF(FUNC_ISINF_BF, "isinf_bf", isinff_, isinff2, vfIsinf)
124
+ FUNC_BF(FUNC_ISNAN_BF, "isnan_bf", isnanf_, isnanf2, vsIsnan)
125
+ FUNC_BF(FUNC_ISFINITE_BF, "isfinite_bf", isfinitef_, isfinitef2, vsIsfinite)
126
+ FUNC_BF(FUNC_ISINF_BF, "isinf_bf", isinff_, isinff2, vsIsinf)
127
+ FUNC_BF(FUNC_SIGNBIT_BF, "signbit_bf", signbitf, signbitf2, vsSignBit)
111
128
  FUNC_BF(FUNC_BF_LAST, NULL, NULL, NULL, NULL)
112
129
  #ifdef ELIDE_FUNC_BF
113
130
  #undef ELIDE_FUNC_BF
@@ -120,6 +137,11 @@ FUNC_BF(FUNC_BF_LAST, NULL, NULL, NULL, NULL)
120
137
  #endif
121
138
  FUNC_DDD(FUNC_FMOD_DDD, "fmod_ddd", fmod, vdfmod)
122
139
  FUNC_DDD(FUNC_ARCTAN2_DDD, "arctan2_ddd", atan2, vdAtan2)
140
+ FUNC_DDD(FUNC_HYPOT_DDD, "hypot_ddd", hypot, vdHypot)
141
+ FUNC_DDD(FUNC_NEXTAFTER_DDD, "nextafter_ddd", nextafter, vdNextAfter)
142
+ FUNC_DDD(FUNC_COPYSIGN_DDD, "copysign_ddd", copysign, vdCopySign)
143
+ FUNC_DDD(FUNC_MAXIMUM_DDD, "maximum_ddd", fmaxd, vdFmax)
144
+ FUNC_DDD(FUNC_MINIMUM_DDD, "minimum_ddd", fmind, vdFmin)
123
145
  FUNC_DDD(FUNC_DDD_LAST, NULL, NULL, NULL)
124
146
  #ifdef ELIDE_FUNC_DDD
125
147
  #undef ELIDE_FUNC_DDD
@@ -146,10 +168,14 @@ FUNC_CC(FUNC_ARCTANH_CC, "arctanh_cc", nc_atanh, vzAtanh)
146
168
  FUNC_CC(FUNC_LOG_CC, "log_cc", nc_log, vzLn)
147
169
  FUNC_CC(FUNC_LOG1P_CC, "log1p_cc", nc_log1p, vzLog1p)
148
170
  FUNC_CC(FUNC_LOG10_CC, "log10_cc", nc_log10, vzLog10)
171
+ FUNC_CC(FUNC_LOG2_CC, "log2_cc", nc_log2, vzLog2)
149
172
  FUNC_CC(FUNC_EXP_CC, "exp_cc", nc_exp, vzExp)
150
173
  FUNC_CC(FUNC_EXPM1_CC, "expm1_cc", nc_expm1, vzExpm1)
151
174
  FUNC_CC(FUNC_ABS_CC, "absolute_cc", nc_abs, vzAbs_)
152
175
  FUNC_CC(FUNC_CONJ_CC, "conjugate_cc",nc_conj, vzConj)
176
+ FUNC_CC(FUNC_SIGN_CC, "sign_cc", nc_sign, vzSign)
177
+ // rint rounds to nearest even integer, matches NumPy behaviour (round doesn't)
178
+ FUNC_CC(FUNC_ROUND_CC, "round_cc", nc_rint, vzRint)
153
179
  FUNC_CC(FUNC_CC_LAST, NULL, NULL, NULL)
154
180
  #ifdef ELIDE_FUNC_CC
155
181
  #undef ELIDE_FUNC_CC
@@ -180,3 +206,30 @@ FUNC_BC(FUNC_BC_LAST, NULL, NULL, NULL)
180
206
  #undef ELIDE_FUNC_BC
181
207
  #undef FUNC_BC
182
208
  #endif
209
+
210
+ // int -> int functions
211
+ #ifndef FUNC_II
212
+ #define ELIDE_FUNC_II
213
+ #define FUNC_II(...)
214
+ #endif
215
+ FUNC_II(FUNC_SIGN_II, "sign_ii", signi, viSign)
216
+ FUNC_II(FUNC_ROUND_II, "round_ii", rinti, viRint)
217
+ FUNC_II(FUNC_ABS_II, "absolute_ii", fabsi, viFabs)
218
+ FUNC_II(FUNC_II_LAST, NULL, NULL, NULL)
219
+ #ifdef ELIDE_FUNC_II
220
+ #undef ELIDE_FUNC_II
221
+ #undef FUNC_II
222
+ #endif
223
+
224
+ #ifndef FUNC_LL
225
+ #define ELIDE_FUNC_LL
226
+ #define FUNC_LL(...)
227
+ #endif
228
+ FUNC_LL(FUNC_SIGN_LL, "sign_ll", signl, vlSign)
229
+ FUNC_LL(FUNC_ROUND_LL, "round_ll", rintl, vlRint)
230
+ FUNC_LL(FUNC_ABS_LL, "absolute_ll", fabsl, vlFabs)
231
+ FUNC_LL(FUNC_LL_LAST, NULL, NULL, NULL)
232
+ #ifdef ELIDE_FUNC_LL
233
+ #undef ELIDE_FUNC_LL
234
+ #undef FUNC_LL
235
+ #endif