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.
- {numexpr-2.12.0 → numexpr-2.13.0}/ADDFUNCS.rst +20 -1
- {numexpr-2.12.0 → numexpr-2.13.0}/ANNOUNCE.rst +12 -12
- {numexpr-2.12.0 → numexpr-2.13.0}/AUTHORS.txt +3 -0
- {numexpr-2.12.0 → numexpr-2.13.0}/PKG-INFO +2 -2
- {numexpr-2.12.0 → numexpr-2.13.0}/README.rst +1 -1
- {numexpr-2.12.0 → numexpr-2.13.0}/RELEASE_NOTES.rst +30 -1
- numexpr-2.13.0/VERSION +1 -0
- numexpr-2.13.0/numexpr/bespoke_functions.hpp +294 -0
- {numexpr-2.12.0 → numexpr-2.13.0}/numexpr/complex_functions.hpp +68 -0
- {numexpr-2.12.0 → numexpr-2.13.0}/numexpr/expressions.py +26 -13
- {numexpr-2.12.0 → numexpr-2.13.0}/numexpr/functions.hpp +70 -3
- {numexpr-2.12.0 → numexpr-2.13.0}/numexpr/interp_body.cpp +41 -0
- {numexpr-2.12.0 → numexpr-2.13.0}/numexpr/interpreter.cpp +70 -68
- {numexpr-2.12.0 → numexpr-2.13.0}/numexpr/interpreter.hpp +18 -0
- {numexpr-2.12.0 → numexpr-2.13.0}/numexpr/module.cpp +6 -0
- {numexpr-2.12.0 → numexpr-2.13.0}/numexpr/msvc_function_stubs.hpp +47 -0
- {numexpr-2.12.0 → numexpr-2.13.0}/numexpr/necompiler.py +10 -0
- {numexpr-2.12.0 → numexpr-2.13.0}/numexpr/numexpr_config.hpp +14 -9
- numexpr-2.13.0/numexpr/opcodes.hpp +214 -0
- {numexpr-2.12.0 → numexpr-2.13.0}/numexpr/tests/test_numexpr.py +74 -12
- {numexpr-2.12.0 → numexpr-2.13.0}/numexpr/version.py +2 -2
- {numexpr-2.12.0 → numexpr-2.13.0}/numexpr.egg-info/PKG-INFO +2 -2
- {numexpr-2.12.0 → numexpr-2.13.0}/numexpr.egg-info/SOURCES.txt +1 -0
- {numexpr-2.12.0 → numexpr-2.13.0}/site.cfg.example +5 -3
- numexpr-2.12.0/VERSION +0 -1
- numexpr-2.12.0/numexpr/opcodes.hpp +0 -192
- {numexpr-2.12.0 → numexpr-2.13.0}/LICENSE.txt +0 -0
- {numexpr-2.12.0 → numexpr-2.13.0}/LICENSES/cpuinfo.txt +0 -0
- {numexpr-2.12.0 → numexpr-2.13.0}/MANIFEST.in +0 -0
- {numexpr-2.12.0 → numexpr-2.13.0}/bench/boolean_timing.py +0 -0
- {numexpr-2.12.0 → numexpr-2.13.0}/bench/free_threading.py +0 -0
- {numexpr-2.12.0 → numexpr-2.13.0}/bench/issue-36.py +0 -0
- {numexpr-2.12.0 → numexpr-2.13.0}/bench/issue-47.py +0 -0
- {numexpr-2.12.0 → numexpr-2.13.0}/bench/large_array_vs_numpy.py +0 -0
- {numexpr-2.12.0 → numexpr-2.13.0}/bench/multidim.py +0 -0
- {numexpr-2.12.0 → numexpr-2.13.0}/bench/poly.py +0 -0
- {numexpr-2.12.0 → numexpr-2.13.0}/bench/timing.py +0 -0
- {numexpr-2.12.0 → numexpr-2.13.0}/bench/unaligned-simple.py +0 -0
- {numexpr-2.12.0 → numexpr-2.13.0}/bench/varying-expr.py +0 -0
- {numexpr-2.12.0 → numexpr-2.13.0}/bench/vml_timing.py +0 -0
- {numexpr-2.12.0 → numexpr-2.13.0}/bench/vml_timing2.py +0 -0
- {numexpr-2.12.0 → numexpr-2.13.0}/bench/vml_timing3.py +0 -0
- {numexpr-2.12.0 → numexpr-2.13.0}/numexpr/__init__.py +0 -0
- {numexpr-2.12.0 → numexpr-2.13.0}/numexpr/cpuinfo.py +0 -0
- {numexpr-2.12.0 → numexpr-2.13.0}/numexpr/missing_posix_functions.hpp +0 -0
- {numexpr-2.12.0 → numexpr-2.13.0}/numexpr/module.hpp +0 -0
- {numexpr-2.12.0 → numexpr-2.13.0}/numexpr/numexpr_object.cpp +0 -0
- {numexpr-2.12.0 → numexpr-2.13.0}/numexpr/numexpr_object.hpp +0 -0
- {numexpr-2.12.0 → numexpr-2.13.0}/numexpr/str-two-way.hpp +0 -0
- {numexpr-2.12.0 → numexpr-2.13.0}/numexpr/tests/__init__.py +0 -0
- {numexpr-2.12.0 → numexpr-2.13.0}/numexpr/tests/conftest.py +0 -0
- {numexpr-2.12.0 → numexpr-2.13.0}/numexpr/utils.py +0 -0
- {numexpr-2.12.0 → numexpr-2.13.0}/numexpr/win32/pthread.c +0 -0
- {numexpr-2.12.0 → numexpr-2.13.0}/numexpr/win32/pthread.h +0 -0
- {numexpr-2.12.0 → numexpr-2.13.0}/numexpr/win32/stdint.h +0 -0
- {numexpr-2.12.0 → numexpr-2.13.0}/numexpr.egg-info/dependency_links.txt +0 -0
- {numexpr-2.12.0 → numexpr-2.13.0}/numexpr.egg-info/requires.txt +0 -0
- {numexpr-2.12.0 → numexpr-2.13.0}/numexpr.egg-info/top_level.txt +0 -0
- {numexpr-2.12.0 → numexpr-2.13.0}/pyproject.toml +0 -0
- {numexpr-2.12.0 → numexpr-2.13.0}/requirements.txt +0 -0
- {numexpr-2.12.0 → numexpr-2.13.0}/setup.cfg +0 -0
- {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,
|
|
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.
|
|
2
|
+
Announcing NumExpr 2.13.0
|
|
3
3
|
=========================
|
|
4
4
|
|
|
5
5
|
Hi everyone,
|
|
6
6
|
|
|
7
|
-
NumExpr 2.
|
|
8
|
-
|
|
9
|
-
|
|
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.
|
|
16
|
+
Changes from 2.12.0 to 2.12.1
|
|
17
17
|
-----------------------------
|
|
18
18
|
|
|
19
|
-
* Added isnan/isfinite/isinf functions.
|
|
19
|
+
* Added complex counterparts for isnan/isfinite/isinf functions.
|
|
20
|
+
Thanks to Luke Shaw.
|
|
20
21
|
|
|
21
|
-
*
|
|
22
|
-
|
|
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
|
-
*
|
|
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
|
---------------
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: numexpr
|
|
3
|
-
Version: 2.
|
|
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
|
-
|
|
140
|
+
pip install [-e] .
|
|
141
141
|
|
|
142
142
|
You can test `numexpr` with::
|
|
143
143
|
|
|
@@ -1,7 +1,36 @@
|
|
|
1
1
|
=====================================
|
|
2
|
-
Release notes for NumExpr 2.
|
|
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
|
-
|
|
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')
|
|
@@ -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)
|