numexpr 2.12.1__tar.gz → 2.13.1__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 (63) hide show
  1. {numexpr-2.12.1 → numexpr-2.13.1}/ADDFUNCS.rst +3 -3
  2. {numexpr-2.12.1 → numexpr-2.13.1}/ANNOUNCE.rst +15 -11
  3. {numexpr-2.12.1 → numexpr-2.13.1}/AUTHORS.txt +3 -0
  4. {numexpr-2.12.1 → numexpr-2.13.1}/PKG-INFO +1 -1
  5. {numexpr-2.12.1 → numexpr-2.13.1}/RELEASE_NOTES.rst +21 -1
  6. numexpr-2.13.1/VERSION +1 -0
  7. numexpr-2.13.1/numexpr/bespoke_functions.hpp +339 -0
  8. {numexpr-2.12.1 → numexpr-2.13.1}/numexpr/complex_functions.hpp +39 -0
  9. {numexpr-2.12.1 → numexpr-2.13.1}/numexpr/expressions.py +29 -13
  10. {numexpr-2.12.1 → numexpr-2.13.1}/numexpr/functions.hpp +56 -3
  11. {numexpr-2.12.1 → numexpr-2.13.1}/numexpr/interp_body.cpp +30 -0
  12. {numexpr-2.12.1 → numexpr-2.13.1}/numexpr/interpreter.cpp +49 -145
  13. {numexpr-2.12.1 → numexpr-2.13.1}/numexpr/interpreter.hpp +12 -0
  14. {numexpr-2.12.1 → numexpr-2.13.1}/numexpr/module.cpp +4 -0
  15. numexpr-2.13.1/numexpr/msvc_function_stubs.hpp +231 -0
  16. {numexpr-2.12.1 → numexpr-2.13.1}/numexpr/necompiler.py +10 -0
  17. {numexpr-2.12.1 → numexpr-2.13.1}/numexpr/numexpr_config.hpp +17 -8
  18. numexpr-2.13.1/numexpr/opcodes.hpp +214 -0
  19. {numexpr-2.12.1 → numexpr-2.13.1}/numexpr/tests/test_numexpr.py +87 -15
  20. {numexpr-2.12.1 → numexpr-2.13.1}/numexpr/version.py +2 -2
  21. {numexpr-2.12.1 → numexpr-2.13.1}/numexpr.egg-info/PKG-INFO +1 -1
  22. {numexpr-2.12.1 → numexpr-2.13.1}/numexpr.egg-info/SOURCES.txt +1 -0
  23. numexpr-2.12.1/VERSION +0 -1
  24. numexpr-2.12.1/numexpr/msvc_function_stubs.hpp +0 -174
  25. numexpr-2.12.1/numexpr/opcodes.hpp +0 -193
  26. {numexpr-2.12.1 → numexpr-2.13.1}/LICENSE.txt +0 -0
  27. {numexpr-2.12.1 → numexpr-2.13.1}/LICENSES/cpuinfo.txt +0 -0
  28. {numexpr-2.12.1 → numexpr-2.13.1}/MANIFEST.in +0 -0
  29. {numexpr-2.12.1 → numexpr-2.13.1}/README.rst +0 -0
  30. {numexpr-2.12.1 → numexpr-2.13.1}/bench/boolean_timing.py +0 -0
  31. {numexpr-2.12.1 → numexpr-2.13.1}/bench/free_threading.py +0 -0
  32. {numexpr-2.12.1 → numexpr-2.13.1}/bench/issue-36.py +0 -0
  33. {numexpr-2.12.1 → numexpr-2.13.1}/bench/issue-47.py +0 -0
  34. {numexpr-2.12.1 → numexpr-2.13.1}/bench/large_array_vs_numpy.py +0 -0
  35. {numexpr-2.12.1 → numexpr-2.13.1}/bench/multidim.py +0 -0
  36. {numexpr-2.12.1 → numexpr-2.13.1}/bench/poly.py +0 -0
  37. {numexpr-2.12.1 → numexpr-2.13.1}/bench/timing.py +0 -0
  38. {numexpr-2.12.1 → numexpr-2.13.1}/bench/unaligned-simple.py +0 -0
  39. {numexpr-2.12.1 → numexpr-2.13.1}/bench/varying-expr.py +0 -0
  40. {numexpr-2.12.1 → numexpr-2.13.1}/bench/vml_timing.py +0 -0
  41. {numexpr-2.12.1 → numexpr-2.13.1}/bench/vml_timing2.py +0 -0
  42. {numexpr-2.12.1 → numexpr-2.13.1}/bench/vml_timing3.py +0 -0
  43. {numexpr-2.12.1 → numexpr-2.13.1}/numexpr/__init__.py +0 -0
  44. {numexpr-2.12.1 → numexpr-2.13.1}/numexpr/cpuinfo.py +0 -0
  45. {numexpr-2.12.1 → numexpr-2.13.1}/numexpr/missing_posix_functions.hpp +0 -0
  46. {numexpr-2.12.1 → numexpr-2.13.1}/numexpr/module.hpp +0 -0
  47. {numexpr-2.12.1 → numexpr-2.13.1}/numexpr/numexpr_object.cpp +0 -0
  48. {numexpr-2.12.1 → numexpr-2.13.1}/numexpr/numexpr_object.hpp +0 -0
  49. {numexpr-2.12.1 → numexpr-2.13.1}/numexpr/str-two-way.hpp +0 -0
  50. {numexpr-2.12.1 → numexpr-2.13.1}/numexpr/tests/__init__.py +0 -0
  51. {numexpr-2.12.1 → numexpr-2.13.1}/numexpr/tests/conftest.py +0 -0
  52. {numexpr-2.12.1 → numexpr-2.13.1}/numexpr/utils.py +0 -0
  53. {numexpr-2.12.1 → numexpr-2.13.1}/numexpr/win32/pthread.c +0 -0
  54. {numexpr-2.12.1 → numexpr-2.13.1}/numexpr/win32/pthread.h +0 -0
  55. {numexpr-2.12.1 → numexpr-2.13.1}/numexpr/win32/stdint.h +0 -0
  56. {numexpr-2.12.1 → numexpr-2.13.1}/numexpr.egg-info/dependency_links.txt +0 -0
  57. {numexpr-2.12.1 → numexpr-2.13.1}/numexpr.egg-info/requires.txt +0 -0
  58. {numexpr-2.12.1 → numexpr-2.13.1}/numexpr.egg-info/top_level.txt +0 -0
  59. {numexpr-2.12.1 → numexpr-2.13.1}/pyproject.toml +0 -0
  60. {numexpr-2.12.1 → numexpr-2.13.1}/requirements.txt +0 -0
  61. {numexpr-2.12.1 → numexpr-2.13.1}/setup.cfg +0 -0
  62. {numexpr-2.12.1 → numexpr-2.13.1}/setup.py +0 -0
  63. {numexpr-2.12.1 → numexpr-2.13.1}/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,27 +1,31 @@
1
1
  =========================
2
- Announcing NumExpr 2.12.1
2
+ Announcing NumExpr 2.13.
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.1 introduces a couple of patches for maximum/minimum and
8
+ multiplication/addition for booleans to match NumPy behaviour.
9
+ Thanks to Luke Shaw for these contributions.
9
10
 
10
11
  Project documentation is available at:
11
12
 
12
- http://numexpr.readthedocs.io/
13
+ https://numexpr.readthedocs.io/
13
14
 
14
- Changes from 2.12.0 to 2.12.1
15
+ Changes from 2.12.1 to 2.13.0
15
16
  -----------------------------
16
17
 
17
- * Added complex counterparts for isnan/isfinite/isinf functions.
18
- Thanks to Luke Shaw.
18
+ * New functionality has been added:
19
+ * Bitwise operators (and, or, not, xor): `&, |, ~, ^`
20
+ * New binary arithmetic operator for floor division: `//`
21
+ * New functions: `signbit`, `hypot`, `copysign`, `nextafter`, `maximum`,
22
+ `minimum`, `log2`, `trunc`, `round` and `sign`.
23
+ * Also enables integer outputs for integer inputs for
24
+ `abs`, `fmod`, `copy`, `ones_like`, `sign` and `round`.
19
25
 
20
- * Updated documentation for the new functions and instructions
21
- for adding new functions to the virtual machine. Thanks to Luke Shaw.
26
+ Thanks to Luke Shaw for the contributions.
22
27
 
23
- * Fixed MKL support; it was broken in 2.12.0. Thanks to
24
- Christoph Gohlke for reporting the issue.
28
+ * New wheels for Python 3.14 and 3.14t are provided.
25
29
 
26
30
  What's Numexpr?
27
31
  ---------------
@@ -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.1
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,27 @@
1
1
  =====================================
2
- Release notes for NumExpr 2.12 series
2
+ Release notes for NumExpr 2.13 series
3
3
  =====================================
4
4
 
5
+ Changes from 2.13.0 to 2.13.1
6
+ -----------------------------
7
+
8
+ * Patch to maximum/minimum functions in order to match NumPy NaN handling
9
+ * Patch to convert '+'->'|' and '*'->'&' for booleans
10
+
11
+ Changes from 2.12.1 to 2.13.0
12
+ -----------------------------
13
+
14
+ * New functionality has been added:
15
+ * Bitwise operators (and, or, not, xor): `&, |, ~, ^`
16
+ * New binary arithmetic operator for floor division: `//`
17
+ * New functions: `signbit`, `hypot`, `copysign`, `nextafter`, `maximum`, `minimum`, `log2`, `trunc`, `round` and `sign`.
18
+ * Also enables integer outputs for integer inputs for `abs`, `copy`, `ones_like`, `sign` and `round`.
19
+
20
+ Thanks to Luke Shaw for the contributions.
21
+
22
+ * New wheels for Python 3.14 and 3.14t are provided.
23
+
24
+
5
25
  Changes from 2.12.0 to 2.12.1
6
26
  -----------------------------
7
27
 
numexpr-2.13.1/VERSION ADDED
@@ -0,0 +1 @@
1
+ 2.13.1
@@ -0,0 +1,339 @@
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
+ // To match Numpy behaviour for NaNs
39
+ static void vsFmax_(MKL_INT n, const float* x1, const float* x2, float* dest)
40
+ {
41
+ vsFmax(n, x1, x2, dest);
42
+ MKL_INT j;
43
+ for (j=0; j<n; j++) {
44
+ if (isnanf_(x1[j]) | isnanf_(x2[j])){
45
+ dest[j] = NAN;
46
+ }
47
+ };
48
+ };
49
+
50
+ static void vsFmin_(MKL_INT n, const float* x1, const float* x2, float* dest)
51
+ {
52
+ vsFmin(n, x1, x2, dest);
53
+ MKL_INT j;
54
+ for (j=0; j<n; j++) {
55
+ if (isnanf_(x1[j]) | isnanf_(x2[j])){
56
+ dest[j] = NAN;
57
+ }
58
+ };
59
+ };
60
+ // To match Numpy behaviour for NaNs
61
+ static void vdFmax_(MKL_INT n, const double* x1, const double* x2, double* dest)
62
+ {
63
+ vdFmax(n, x1, x2, dest);
64
+ MKL_INT j;
65
+ for (j=0; j<n; j++) {
66
+ if (isnand(x1[j]) | isnand(x2[j])){
67
+ dest[j] = NAN;
68
+ }
69
+ };
70
+ };
71
+
72
+ static void vdFmin_(MKL_INT n, const double* x1, const double* x2, double* dest)
73
+ {
74
+ vdFmin(n, x1, x2, dest);
75
+ MKL_INT j;
76
+ for (j=0; j<n; j++) {
77
+ if (isnand(x1[j]) | isnand(x2[j])){
78
+ dest[j] = NAN;
79
+ }
80
+ };
81
+ };
82
+
83
+ static void viRint(MKL_INT n, const int* x, int* dest)
84
+ {
85
+ memcpy(dest, x, n * sizeof(int)); // just copy x1 which is already int
86
+ };
87
+
88
+ static void vlRint(MKL_INT n, const long* x, long* dest)
89
+ {
90
+ memcpy(dest, x, n * sizeof(long)); // just copy x1 which is already int
91
+ };
92
+
93
+ static void viFabs(MKL_INT n, const int* x, int* dest)
94
+ {
95
+ MKL_INT j;
96
+ for (j=0; j<n; j++) {
97
+ dest[j] = x[j] < 0 ? -x[j]: x[j];
98
+ };
99
+ };
100
+
101
+ static void vlFabs(MKL_INT n, const long* x, long* dest)
102
+ {
103
+ MKL_INT j;
104
+ for (j=0; j<n; j++) {
105
+ dest[j] = x[j] < 0 ? -x[j]: x[j];
106
+ };
107
+ };
108
+
109
+ /* Fake vsConj function just for casting purposes inside numexpr */
110
+ static void vsConj(MKL_INT n, const float* x1, float* dest)
111
+ {
112
+ MKL_INT j;
113
+ for (j=0; j<n; j++) {
114
+ dest[j] = x1[j];
115
+ };
116
+ };
117
+
118
+ /* fmod not available in VML */
119
+ static void vsfmod(MKL_INT n, const float* x1, const float* x2, float* dest)
120
+ {
121
+ MKL_INT j;
122
+ for(j=0; j < n; j++) {
123
+ dest[j] = fmodf(x1[j], x2[j]);
124
+ };
125
+ }
126
+ static void vdfmod(MKL_INT n, const double* x1, const double* x2, double* dest)
127
+ {
128
+ MKL_INT j;
129
+ for(j=0; j < n; j++) {
130
+ dest[j] = fmod(x1[j], x2[j]);
131
+ };
132
+ };
133
+ // TODO: Have to add FUNC_III, FUNC_LLL signatures to functions.hpp
134
+ // static void vifmod(MKL_INT n, const int* x1, const int* x2, int* dest)
135
+ // {
136
+ // MKL_INT j;
137
+ // for(j=0; j < n; j++) {
138
+ // dest[j] = fmodi(x1[j], x2[j]);
139
+ // };
140
+ // };
141
+ // static void vlfmod(MKL_INT n, const long* x1, const long* x2, long* dest)
142
+ // {
143
+ // MKL_INT j;
144
+ // for(j=0; j < n; j++) {
145
+ // dest[j] = fmodl(x1[j], x2[j]);
146
+ // };
147
+ // };
148
+
149
+ /* no isnan, isfinite, isinf or signbit in VML */
150
+ static void vsIsfinite(MKL_INT n, const float* x1, bool* dest)
151
+ {
152
+ MKL_INT j;
153
+ for (j=0; j<n; j++) {
154
+ dest[j] = isfinitef_(x1[j]);
155
+ };
156
+ };
157
+ static void vsIsinf(MKL_INT n, const float* x1, bool* dest)
158
+ {
159
+ MKL_INT j;
160
+ for (j=0; j<n; j++) {
161
+ dest[j] = isinff_(x1[j]);
162
+ };
163
+ };
164
+ static void vsIsnan(MKL_INT n, const float* x1, bool* dest)
165
+ {
166
+ MKL_INT j;
167
+ for (j=0; j<n; j++) {
168
+ dest[j] = isnanf_(x1[j]);
169
+ };
170
+ };
171
+ static void vsSignBit(MKL_INT n, const float* x1, bool* dest)
172
+ {
173
+ MKL_INT j;
174
+ for (j=0; j<n; j++) {
175
+ dest[j] = signbitf(x1[j]);
176
+ };
177
+ };
178
+
179
+ /* no isnan, isfinite, isinf, signbit in VML */
180
+ static void vdIsfinite(MKL_INT n, const double* x1, bool* dest)
181
+ {
182
+ MKL_INT j;
183
+ for (j=0; j<n; j++) {
184
+ dest[j] = isfinited(x1[j]);
185
+ };
186
+ };
187
+ static void vdIsinf(MKL_INT n, const double* x1, bool* dest)
188
+ {
189
+ MKL_INT j;
190
+ for (j=0; j<n; j++) {
191
+ dest[j] = isinfd(x1[j]);
192
+ };
193
+ };
194
+ static void vdIsnan(MKL_INT n, const double* x1, bool* dest)
195
+ {
196
+ MKL_INT j;
197
+ for (j=0; j<n; j++) {
198
+ dest[j] = isnand(x1[j]);
199
+ };
200
+ };
201
+ static void vdSignBit(MKL_INT n, const double* x1, bool* dest)
202
+ {
203
+ MKL_INT j;
204
+ for (j=0; j<n; j++) {
205
+ dest[j] = signbit(x1[j]);
206
+ };
207
+ };
208
+
209
+ /* no isnan, isfinite or isinf in VML */
210
+ static void vzIsfinite(MKL_INT n, const MKL_Complex16* x1, bool* dest)
211
+ {
212
+ MKL_INT j;
213
+ for (j=0; j<n; j++) {
214
+ dest[j] = isfinited(x1[j].real) && isfinited(x1[j].imag);
215
+ };
216
+ };
217
+ static void vzIsinf(MKL_INT n, const MKL_Complex16* x1, bool* dest)
218
+ {
219
+ MKL_INT j;
220
+ for (j=0; j<n; j++) {
221
+ dest[j] = isinfd(x1[j].real) || isinfd(x1[j].imag);
222
+ };
223
+ };
224
+ static void vzIsnan(MKL_INT n, const MKL_Complex16* x1, bool* dest)
225
+ {
226
+ MKL_INT j;
227
+ for (j=0; j<n; j++) {
228
+ dest[j] = isnand(x1[j].real) || isnand(x1[j].imag);
229
+ };
230
+ };
231
+
232
+ /* Fake vdConj function just for casting purposes inside numexpr */
233
+ static void vdConj(MKL_INT n, const double* x1, double* dest)
234
+ {
235
+ MKL_INT j;
236
+ for (j=0; j<n; j++) {
237
+ dest[j] = x1[j];
238
+ };
239
+ };
240
+
241
+ /* various functions not available in VML */
242
+ static void vzExpm1(MKL_INT n, const MKL_Complex16* x1, MKL_Complex16* dest)
243
+ {
244
+ MKL_INT j;
245
+ vzExp(n, x1, dest);
246
+ for (j=0; j<n; j++) {
247
+ dest[j].real -= 1.0;
248
+ };
249
+ };
250
+
251
+ static void vzLog1p(MKL_INT n, const MKL_Complex16* x1, MKL_Complex16* dest)
252
+ {
253
+ MKL_INT j;
254
+ for (j=0; j<n; j++) {
255
+ dest[j].real = x1[j].real + 1;
256
+ dest[j].imag = x1[j].imag;
257
+ };
258
+ vzLn(n, dest, dest);
259
+ };
260
+
261
+ static void vzLog2(MKL_INT n, const MKL_Complex16* x1, MKL_Complex16* dest)
262
+ {
263
+ MKL_INT j;
264
+ vzLn(n, x1, dest);
265
+ for (j=0; j<n; j++) {
266
+ dest[j].real = dest[j].real * M_LOG2_E;
267
+ dest[j].imag = dest[j].imag * M_LOG2_E;
268
+ };
269
+ };
270
+
271
+ static void vzRint(MKL_INT n, const MKL_Complex16* x1, MKL_Complex16* dest)
272
+ {
273
+ MKL_INT j;
274
+ for (j=0; j<n; j++) {
275
+ dest[j].real = rint(x1[j].real);
276
+ dest[j].imag = rint(x1[j].imag);
277
+ };
278
+ };
279
+
280
+ /* Use this instead of native vzAbs in VML as it seems to work badly */
281
+ static void vzAbs_(MKL_INT n, const MKL_Complex16* x1, MKL_Complex16* dest)
282
+ {
283
+ MKL_INT j;
284
+ for (j=0; j<n; j++) {
285
+ dest[j].real = sqrt(x1[j].real*x1[j].real + x1[j].imag*x1[j].imag);
286
+ dest[j].imag = 0;
287
+ };
288
+ };
289
+
290
+ /*sign functions*/
291
+ static void vsSign(MKL_INT n, const float* x1, float* dest)
292
+ {
293
+ MKL_INT j;
294
+ for(j=0; j < n; j++) {
295
+ dest[j] = signf(x1[j]);
296
+ };
297
+ };
298
+ static void vdSign(MKL_INT n, const double* x1, double* dest)
299
+ {
300
+ MKL_INT j;
301
+ for(j=0; j < n; j++) {
302
+ dest[j] = sign(x1[j]);
303
+ };
304
+ };
305
+ static void viSign(MKL_INT n, const int* x1, int* dest)
306
+ {
307
+ MKL_INT j;
308
+ for(j=0; j < n; j++) {
309
+ dest[j] = signi(x1[j]);
310
+ };
311
+ };
312
+ static void vlSign(MKL_INT n, const long* x1, long* dest)
313
+ {
314
+ MKL_INT j;
315
+ for(j=0; j < n; j++) {
316
+ dest[j] = signl(x1[j]);
317
+ };
318
+ };
319
+ static void vzSign(MKL_INT n, const MKL_Complex16* x1, MKL_Complex16* dest)
320
+ {
321
+ MKL_INT j;
322
+ double mag;
323
+ for(j=0; j < n; j++) {
324
+ mag = sqrt(x1[j].real*x1[j].real + x1[j].imag*x1[j].imag);
325
+ if (isnand(mag)) {
326
+ dest[j].real = NAN;
327
+ dest[j].imag = NAN;
328
+ }
329
+ else if (mag == 0) {
330
+ dest[j].real = 0;
331
+ dest[j].imag = 0;
332
+ }
333
+ else {
334
+ dest[j].real = x1[j].real / mag;
335
+ dest[j].imag = x1[j].imag / mag;
336
+ }
337
+ };
338
+ };
339
+ #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')
@@ -518,6 +531,9 @@ class OpNode(ExpressionNode):
518
531
  def __init__(self, opcode=None, args=None, kind=None):
519
532
  if (kind is None) and (args is not None):
520
533
  kind = commonKind(args)
534
+ if kind=='bool': # handle bool*bool and bool+bool cases
535
+ opcode = 'and' if opcode=='mul' else opcode
536
+ opcode = 'or' if opcode=='add' else opcode
521
537
  ExpressionNode.__init__(self, value=opcode, kind=kind, children=args)
522
538
 
523
539
 
@@ -525,6 +541,6 @@ class FuncNode(OpNode):
525
541
  def __init__(self, opcode=None, args=None, kind=None):
526
542
  if (kind is None) and (args is not None):
527
543
  kind = commonKind(args)
528
- if opcode in ("isnan", "isfinite", "isinf"): # bodge for boolean return functions
544
+ if opcode in ("isnan", "isfinite", "isinf", "signbit"): # bodge for boolean return functions
529
545
  kind = 'bool'
530
546
  OpNode.__init__(self, opcode, args, kind)