numexpr 2.12.0__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.0 → numexpr-2.13.0}/ADDFUNCS.rst +20 -1
  2. {numexpr-2.12.0 → numexpr-2.13.0}/ANNOUNCE.rst +12 -12
  3. {numexpr-2.12.0 → numexpr-2.13.0}/AUTHORS.txt +3 -0
  4. {numexpr-2.12.0 → numexpr-2.13.0}/PKG-INFO +2 -2
  5. {numexpr-2.12.0 → numexpr-2.13.0}/README.rst +1 -1
  6. {numexpr-2.12.0 → numexpr-2.13.0}/RELEASE_NOTES.rst +30 -1
  7. numexpr-2.13.0/VERSION +1 -0
  8. numexpr-2.13.0/numexpr/bespoke_functions.hpp +294 -0
  9. {numexpr-2.12.0 → numexpr-2.13.0}/numexpr/complex_functions.hpp +68 -0
  10. {numexpr-2.12.0 → numexpr-2.13.0}/numexpr/expressions.py +26 -13
  11. {numexpr-2.12.0 → numexpr-2.13.0}/numexpr/functions.hpp +70 -3
  12. {numexpr-2.12.0 → numexpr-2.13.0}/numexpr/interp_body.cpp +41 -0
  13. {numexpr-2.12.0 → numexpr-2.13.0}/numexpr/interpreter.cpp +70 -68
  14. {numexpr-2.12.0 → numexpr-2.13.0}/numexpr/interpreter.hpp +18 -0
  15. {numexpr-2.12.0 → numexpr-2.13.0}/numexpr/module.cpp +6 -0
  16. {numexpr-2.12.0 → numexpr-2.13.0}/numexpr/msvc_function_stubs.hpp +47 -0
  17. {numexpr-2.12.0 → numexpr-2.13.0}/numexpr/necompiler.py +10 -0
  18. {numexpr-2.12.0 → numexpr-2.13.0}/numexpr/numexpr_config.hpp +14 -9
  19. numexpr-2.13.0/numexpr/opcodes.hpp +214 -0
  20. {numexpr-2.12.0 → numexpr-2.13.0}/numexpr/tests/test_numexpr.py +74 -12
  21. {numexpr-2.12.0 → numexpr-2.13.0}/numexpr/version.py +2 -2
  22. {numexpr-2.12.0 → numexpr-2.13.0}/numexpr.egg-info/PKG-INFO +2 -2
  23. {numexpr-2.12.0 → numexpr-2.13.0}/numexpr.egg-info/SOURCES.txt +1 -0
  24. {numexpr-2.12.0 → numexpr-2.13.0}/site.cfg.example +5 -3
  25. numexpr-2.12.0/VERSION +0 -1
  26. numexpr-2.12.0/numexpr/opcodes.hpp +0 -192
  27. {numexpr-2.12.0 → numexpr-2.13.0}/LICENSE.txt +0 -0
  28. {numexpr-2.12.0 → numexpr-2.13.0}/LICENSES/cpuinfo.txt +0 -0
  29. {numexpr-2.12.0 → numexpr-2.13.0}/MANIFEST.in +0 -0
  30. {numexpr-2.12.0 → numexpr-2.13.0}/bench/boolean_timing.py +0 -0
  31. {numexpr-2.12.0 → numexpr-2.13.0}/bench/free_threading.py +0 -0
  32. {numexpr-2.12.0 → numexpr-2.13.0}/bench/issue-36.py +0 -0
  33. {numexpr-2.12.0 → numexpr-2.13.0}/bench/issue-47.py +0 -0
  34. {numexpr-2.12.0 → numexpr-2.13.0}/bench/large_array_vs_numpy.py +0 -0
  35. {numexpr-2.12.0 → numexpr-2.13.0}/bench/multidim.py +0 -0
  36. {numexpr-2.12.0 → numexpr-2.13.0}/bench/poly.py +0 -0
  37. {numexpr-2.12.0 → numexpr-2.13.0}/bench/timing.py +0 -0
  38. {numexpr-2.12.0 → numexpr-2.13.0}/bench/unaligned-simple.py +0 -0
  39. {numexpr-2.12.0 → numexpr-2.13.0}/bench/varying-expr.py +0 -0
  40. {numexpr-2.12.0 → numexpr-2.13.0}/bench/vml_timing.py +0 -0
  41. {numexpr-2.12.0 → numexpr-2.13.0}/bench/vml_timing2.py +0 -0
  42. {numexpr-2.12.0 → numexpr-2.13.0}/bench/vml_timing3.py +0 -0
  43. {numexpr-2.12.0 → numexpr-2.13.0}/numexpr/__init__.py +0 -0
  44. {numexpr-2.12.0 → numexpr-2.13.0}/numexpr/cpuinfo.py +0 -0
  45. {numexpr-2.12.0 → numexpr-2.13.0}/numexpr/missing_posix_functions.hpp +0 -0
  46. {numexpr-2.12.0 → numexpr-2.13.0}/numexpr/module.hpp +0 -0
  47. {numexpr-2.12.0 → numexpr-2.13.0}/numexpr/numexpr_object.cpp +0 -0
  48. {numexpr-2.12.0 → numexpr-2.13.0}/numexpr/numexpr_object.hpp +0 -0
  49. {numexpr-2.12.0 → numexpr-2.13.0}/numexpr/str-two-way.hpp +0 -0
  50. {numexpr-2.12.0 → numexpr-2.13.0}/numexpr/tests/__init__.py +0 -0
  51. {numexpr-2.12.0 → numexpr-2.13.0}/numexpr/tests/conftest.py +0 -0
  52. {numexpr-2.12.0 → numexpr-2.13.0}/numexpr/utils.py +0 -0
  53. {numexpr-2.12.0 → numexpr-2.13.0}/numexpr/win32/pthread.c +0 -0
  54. {numexpr-2.12.0 → numexpr-2.13.0}/numexpr/win32/pthread.h +0 -0
  55. {numexpr-2.12.0 → numexpr-2.13.0}/numexpr/win32/stdint.h +0 -0
  56. {numexpr-2.12.0 → numexpr-2.13.0}/numexpr.egg-info/dependency_links.txt +0 -0
  57. {numexpr-2.12.0 → numexpr-2.13.0}/numexpr.egg-info/requires.txt +0 -0
  58. {numexpr-2.12.0 → numexpr-2.13.0}/numexpr.egg-info/top_level.txt +0 -0
  59. {numexpr-2.12.0 → numexpr-2.13.0}/pyproject.toml +0 -0
  60. {numexpr-2.12.0 → numexpr-2.13.0}/requirements.txt +0 -0
  61. {numexpr-2.12.0 → numexpr-2.13.0}/setup.cfg +0 -0
  62. {numexpr-2.12.0 → numexpr-2.13.0}/setup.py +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,6 +171,23 @@ 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 in ``bespoke_functions.hpp`` as well:
175
+
176
+ .. code-block:: cpp
177
+
178
+ #ifdef USE_VML
179
+ /* no isnan, isfinite or isinf 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
+ #endif
188
+
189
+ The complex case is slightly different (see other examples in the same file).
190
+
174
191
  Add case handling to the ``check_program`` function
175
192
 
176
193
  .. code-block:: cpp
@@ -219,4 +236,6 @@ In many cases this process will not be very smooth since one relies on the inter
219
236
 
220
237
  * Depending on the new function signature (above all if the out type is different to the input types), one may have to edit the ``__init__`` function in the ``FuncNode`` class in ``expressions.py``.
221
238
 
239
+ * Functions which accept and/or return complex arguments must be added to the ``complex_functions.hpp`` file (take care when adding them in ``interpreter.cpp`` and ``interp_body.cpp``, since their signatures are usually a bit different).
240
+
222
241
  * Depending on MSVC support, namespace clashes, casting problems, it may be necessary to make various changes to ``numexpr/numexpr_config.hpp`` and ``numexpr/msvc_function_stubs.hpp``. For example, in PR #523, non-clashing wrappers were introduced for ``isnan`` and ``isfinite`` since the float versions ``isnanf, isfinitef`` were inconsistently defined (and output ints) - depending on how strict the platform interpreter is, the implicit cast from int to bool was acceptable or not for example. In addition, the base functions were in different namespaces or had different names across platforms.
@@ -1,29 +1,29 @@
1
1
  =========================
2
- Announcing NumExpr 2.12.0
2
+ Announcing NumExpr 2.13.0
3
3
  =========================
4
4
 
5
5
  Hi everyone,
6
6
 
7
- NumExpr 2.12.0 comes with new isnan/isfinite/isinf functions.
8
- Most importantly, we have added instructions for adding new functions
9
- to the virtual machine. See ADDFUNCS.rst for more details. Thanks to
10
- 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.
11
11
 
12
12
  Project documentation is available at:
13
13
 
14
14
  http://numexpr.readthedocs.io/
15
15
 
16
- Changes from 2.11.0 to 2.12.0
16
+ Changes from 2.12.0 to 2.12.1
17
17
  -----------------------------
18
18
 
19
- * Added isnan/isfinite/isinf functions. Thanks to Luke Shaw.
19
+ * Added complex counterparts for isnan/isfinite/isinf functions.
20
+ Thanks to Luke Shaw.
20
21
 
21
- * New instructions for adding new functions to the virtual machine.
22
- They are available at ADDFUNCS.rst. Thanks to Luke Shaw.
22
+ * Updated documentation for the new functions and instructions
23
+ for adding new functions to the virtual machine. Thanks to Luke Shaw.
23
24
 
24
- * We are distributing binary wheels for Python 3.14 and 3.14t now.
25
-
26
- * We are distributing musllinux wheels too! Thanks to Clément Robert.
25
+ * Fixed MKL support; it was broken in 2.12.0. Thanks to
26
+ Christoph Gohlke for reporting the issue.
27
27
 
28
28
  What's Numexpr?
29
29
  ---------------
@@ -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.0
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>
@@ -137,7 +137,7 @@ See `requirements.txt` for the required version of NumPy.
137
137
 
138
138
  NumExpr is built in the standard Python way::
139
139
 
140
- python setup.py build install
140
+ pip install [-e] .
141
141
 
142
142
  You can test `numexpr` with::
143
143
 
@@ -106,7 +106,7 @@ See `requirements.txt` for the required version of NumPy.
106
106
 
107
107
  NumExpr is built in the standard Python way::
108
108
 
109
- python setup.py build install
109
+ pip install [-e] .
110
110
 
111
111
  You can test `numexpr` with::
112
112
 
@@ -1,7 +1,36 @@
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
+
21
+ Changes from 2.12.0 to 2.12.1
22
+ -----------------------------
23
+
24
+ * Added complex counterparts for isnan/isfinite/isinf functions.
25
+ Thanks to Luke Shaw.
26
+
27
+ * Updated documentation for the new functions and instructions
28
+ for adding new functions to the virtual machine. Thanks to Luke Shaw.
29
+
30
+ * Fixed MKL support; it was broken in 2.12.0. Thanks to
31
+ Christoph Gohlke for reporting the issue.
32
+
33
+
5
34
  Changes from 2.11.0 to 2.12.0
6
35
  -----------------------------
7
36
 
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,4 +436,60 @@ 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
+
446
+ static bool
447
+ nc_isinf(std::complex<double> *x)
448
+ {
449
+ double xr=x->real(), xi=x->imag();
450
+ bool bi,br;
451
+ bi = isinfd(xi);
452
+ br = isinfd(xr);
453
+ return bi || br;
454
+ }
455
+
456
+ static bool
457
+ nc_isnan(std::complex<double> *x)
458
+ {
459
+ double xr=x->real(), xi=x->imag();
460
+ bool bi,br;
461
+ bi = isnand(xi);
462
+ br = isnand(xr);
463
+ return bi || br;
464
+ }
465
+
466
+ static bool
467
+ nc_isfinite(std::complex<double> *x)
468
+ {
469
+ double xr=x->real(), xi=x->imag();
470
+ bool bi,br;
471
+ bi = isfinited(xi);
472
+ br = isfinited(xr);
473
+ return bi && br;
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
+
427
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)