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.
- {numexpr-2.12.1 → numexpr-2.13.1}/ADDFUNCS.rst +3 -3
- {numexpr-2.12.1 → numexpr-2.13.1}/ANNOUNCE.rst +15 -11
- {numexpr-2.12.1 → numexpr-2.13.1}/AUTHORS.txt +3 -0
- {numexpr-2.12.1 → numexpr-2.13.1}/PKG-INFO +1 -1
- {numexpr-2.12.1 → numexpr-2.13.1}/RELEASE_NOTES.rst +21 -1
- numexpr-2.13.1/VERSION +1 -0
- numexpr-2.13.1/numexpr/bespoke_functions.hpp +339 -0
- {numexpr-2.12.1 → numexpr-2.13.1}/numexpr/complex_functions.hpp +39 -0
- {numexpr-2.12.1 → numexpr-2.13.1}/numexpr/expressions.py +29 -13
- {numexpr-2.12.1 → numexpr-2.13.1}/numexpr/functions.hpp +56 -3
- {numexpr-2.12.1 → numexpr-2.13.1}/numexpr/interp_body.cpp +30 -0
- {numexpr-2.12.1 → numexpr-2.13.1}/numexpr/interpreter.cpp +49 -145
- {numexpr-2.12.1 → numexpr-2.13.1}/numexpr/interpreter.hpp +12 -0
- {numexpr-2.12.1 → numexpr-2.13.1}/numexpr/module.cpp +4 -0
- numexpr-2.13.1/numexpr/msvc_function_stubs.hpp +231 -0
- {numexpr-2.12.1 → numexpr-2.13.1}/numexpr/necompiler.py +10 -0
- {numexpr-2.12.1 → numexpr-2.13.1}/numexpr/numexpr_config.hpp +17 -8
- numexpr-2.13.1/numexpr/opcodes.hpp +214 -0
- {numexpr-2.12.1 → numexpr-2.13.1}/numexpr/tests/test_numexpr.py +87 -15
- {numexpr-2.12.1 → numexpr-2.13.1}/numexpr/version.py +2 -2
- {numexpr-2.12.1 → numexpr-2.13.1}/numexpr.egg-info/PKG-INFO +1 -1
- {numexpr-2.12.1 → numexpr-2.13.1}/numexpr.egg-info/SOURCES.txt +1 -0
- numexpr-2.12.1/VERSION +0 -1
- numexpr-2.12.1/numexpr/msvc_function_stubs.hpp +0 -174
- numexpr-2.12.1/numexpr/opcodes.hpp +0 -193
- {numexpr-2.12.1 → numexpr-2.13.1}/LICENSE.txt +0 -0
- {numexpr-2.12.1 → numexpr-2.13.1}/LICENSES/cpuinfo.txt +0 -0
- {numexpr-2.12.1 → numexpr-2.13.1}/MANIFEST.in +0 -0
- {numexpr-2.12.1 → numexpr-2.13.1}/README.rst +0 -0
- {numexpr-2.12.1 → numexpr-2.13.1}/bench/boolean_timing.py +0 -0
- {numexpr-2.12.1 → numexpr-2.13.1}/bench/free_threading.py +0 -0
- {numexpr-2.12.1 → numexpr-2.13.1}/bench/issue-36.py +0 -0
- {numexpr-2.12.1 → numexpr-2.13.1}/bench/issue-47.py +0 -0
- {numexpr-2.12.1 → numexpr-2.13.1}/bench/large_array_vs_numpy.py +0 -0
- {numexpr-2.12.1 → numexpr-2.13.1}/bench/multidim.py +0 -0
- {numexpr-2.12.1 → numexpr-2.13.1}/bench/poly.py +0 -0
- {numexpr-2.12.1 → numexpr-2.13.1}/bench/timing.py +0 -0
- {numexpr-2.12.1 → numexpr-2.13.1}/bench/unaligned-simple.py +0 -0
- {numexpr-2.12.1 → numexpr-2.13.1}/bench/varying-expr.py +0 -0
- {numexpr-2.12.1 → numexpr-2.13.1}/bench/vml_timing.py +0 -0
- {numexpr-2.12.1 → numexpr-2.13.1}/bench/vml_timing2.py +0 -0
- {numexpr-2.12.1 → numexpr-2.13.1}/bench/vml_timing3.py +0 -0
- {numexpr-2.12.1 → numexpr-2.13.1}/numexpr/__init__.py +0 -0
- {numexpr-2.12.1 → numexpr-2.13.1}/numexpr/cpuinfo.py +0 -0
- {numexpr-2.12.1 → numexpr-2.13.1}/numexpr/missing_posix_functions.hpp +0 -0
- {numexpr-2.12.1 → numexpr-2.13.1}/numexpr/module.hpp +0 -0
- {numexpr-2.12.1 → numexpr-2.13.1}/numexpr/numexpr_object.cpp +0 -0
- {numexpr-2.12.1 → numexpr-2.13.1}/numexpr/numexpr_object.hpp +0 -0
- {numexpr-2.12.1 → numexpr-2.13.1}/numexpr/str-two-way.hpp +0 -0
- {numexpr-2.12.1 → numexpr-2.13.1}/numexpr/tests/__init__.py +0 -0
- {numexpr-2.12.1 → numexpr-2.13.1}/numexpr/tests/conftest.py +0 -0
- {numexpr-2.12.1 → numexpr-2.13.1}/numexpr/utils.py +0 -0
- {numexpr-2.12.1 → numexpr-2.13.1}/numexpr/win32/pthread.c +0 -0
- {numexpr-2.12.1 → numexpr-2.13.1}/numexpr/win32/pthread.h +0 -0
- {numexpr-2.12.1 → numexpr-2.13.1}/numexpr/win32/stdint.h +0 -0
- {numexpr-2.12.1 → numexpr-2.13.1}/numexpr.egg-info/dependency_links.txt +0 -0
- {numexpr-2.12.1 → numexpr-2.13.1}/numexpr.egg-info/requires.txt +0 -0
- {numexpr-2.12.1 → numexpr-2.13.1}/numexpr.egg-info/top_level.txt +0 -0
- {numexpr-2.12.1 → numexpr-2.13.1}/pyproject.toml +0 -0
- {numexpr-2.12.1 → numexpr-2.13.1}/requirements.txt +0 -0
- {numexpr-2.12.1 → numexpr-2.13.1}/setup.cfg +0 -0
- {numexpr-2.12.1 → numexpr-2.13.1}/setup.py +0 -0
- {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,
|
|
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
|
|
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
|
|
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.
|
|
2
|
+
Announcing NumExpr 2.13.
|
|
3
3
|
=========================
|
|
4
4
|
|
|
5
5
|
Hi everyone,
|
|
6
6
|
|
|
7
|
-
NumExpr 2.
|
|
8
|
-
|
|
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
|
-
|
|
13
|
+
https://numexpr.readthedocs.io/
|
|
13
14
|
|
|
14
|
-
Changes from 2.12.
|
|
15
|
+
Changes from 2.12.1 to 2.13.0
|
|
15
16
|
-----------------------------
|
|
16
17
|
|
|
17
|
-
*
|
|
18
|
-
|
|
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
|
-
|
|
21
|
-
for adding new functions to the virtual machine. Thanks to Luke Shaw.
|
|
26
|
+
Thanks to Luke Shaw for the contributions.
|
|
22
27
|
|
|
23
|
-
*
|
|
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
|
---------------
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: numexpr
|
|
3
|
-
Version: 2.
|
|
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.
|
|
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
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
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, '
|
|
370
|
-
'isfinite': func(numpy.isfinite, '
|
|
371
|
-
'isinf': func(numpy.isinf, '
|
|
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
|
-
#
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
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)
|