numexpr 2.14.2__cp313-cp313-win_arm64.whl
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/__init__.py +66 -0
- numexpr/bespoke_functions.hpp +339 -0
- numexpr/complex_functions.hpp +498 -0
- numexpr/cpuinfo.py +861 -0
- numexpr/expressions.py +546 -0
- numexpr/functions.hpp +235 -0
- numexpr/interp_body.cpp +602 -0
- numexpr/interpreter.cp313-win_arm64.pyd +0 -0
- numexpr/interpreter.cpp +1585 -0
- numexpr/interpreter.hpp +137 -0
- numexpr/missing_posix_functions.hpp +102 -0
- numexpr/module.cpp +552 -0
- numexpr/module.hpp +60 -0
- numexpr/msvc_function_stubs.hpp +231 -0
- numexpr/necompiler.py +1074 -0
- numexpr/numexpr_config.hpp +71 -0
- numexpr/numexpr_object.cpp +408 -0
- numexpr/numexpr_object.hpp +34 -0
- numexpr/opcodes.hpp +214 -0
- numexpr/str-two-way.hpp +435 -0
- numexpr/tests/__init__.py +14 -0
- numexpr/tests/conftest.py +21 -0
- numexpr/tests/test_numexpr.py +1603 -0
- numexpr/utils.py +311 -0
- numexpr/version.py +5 -0
- numexpr/win32/pthread.c +218 -0
- numexpr/win32/pthread.h +119 -0
- numexpr/win32/stdint.h +235 -0
- numexpr-2.14.2.dist-info/METADATA +233 -0
- numexpr-2.14.2.dist-info/RECORD +34 -0
- numexpr-2.14.2.dist-info/WHEEL +5 -0
- numexpr-2.14.2.dist-info/licenses/LICENSE.txt +21 -0
- numexpr-2.14.2.dist-info/licenses/LICENSES/cpuinfo.txt +31 -0
- numexpr-2.14.2.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,498 @@
|
|
|
1
|
+
#ifndef NUMEXPR_COMPLEX_FUNCTIONS_HPP
|
|
2
|
+
#define NUMEXPR_COMPLEX_FUNCTIONS_HPP
|
|
3
|
+
|
|
4
|
+
/*********************************************************************
|
|
5
|
+
Numexpr - Fast numerical array expression evaluator for NumPy.
|
|
6
|
+
|
|
7
|
+
License: MIT
|
|
8
|
+
Author: See AUTHORS.txt
|
|
9
|
+
|
|
10
|
+
See LICENSE.txt for details about copyright and rights to use.
|
|
11
|
+
**********************************************************************/
|
|
12
|
+
|
|
13
|
+
// Replace npy_cdouble with std::complex<double>
|
|
14
|
+
#include <math.h> // NAN
|
|
15
|
+
#include <complex>
|
|
16
|
+
|
|
17
|
+
/* constants */
|
|
18
|
+
static std::complex<double> nc_1(1., 0.);
|
|
19
|
+
static std::complex<double> nc_half(0.5, 0.);
|
|
20
|
+
static std::complex<double> nc_i(0., 1.);
|
|
21
|
+
static std::complex<double> nc_i2(0., 0.5);
|
|
22
|
+
/*
|
|
23
|
+
static std::complex<double> nc_mi = {0., -1.};
|
|
24
|
+
static std::complex<double> nc_pi2 = {M_PI/2., 0.};
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
/* *************************** WARNING *****************************
|
|
28
|
+
Due to the way Numexpr places the results of operations, the *x and *r
|
|
29
|
+
pointers do point to the same address (apparently this doesn't happen
|
|
30
|
+
in NumPy). So, measures should be taken so as to not to reuse *x
|
|
31
|
+
after the first *r has been overwritten.
|
|
32
|
+
*********************************************************************
|
|
33
|
+
*/
|
|
34
|
+
|
|
35
|
+
static void
|
|
36
|
+
nc_assign(std::complex<double> *x, std::complex<double> *r)
|
|
37
|
+
{
|
|
38
|
+
r->real(x->real());
|
|
39
|
+
r->imag(x->imag());
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
static void
|
|
44
|
+
nc_sum(std::complex<double> *a, std::complex<double> *b, std::complex<double> *r)
|
|
45
|
+
{
|
|
46
|
+
r->real(a->real() + b->real());
|
|
47
|
+
r->imag(a->imag() + b->imag());
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
static void
|
|
52
|
+
nc_diff(std::complex<double> *a, std::complex<double> *b, std::complex<double> *r)
|
|
53
|
+
{
|
|
54
|
+
r->real(a->real() - b->real());
|
|
55
|
+
r->imag(a->imag() - b->imag());
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
static void
|
|
60
|
+
nc_neg(std::complex<double> *a, std::complex<double> *r)
|
|
61
|
+
{
|
|
62
|
+
r->real(-a->real());
|
|
63
|
+
r->imag(-a->imag());
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
static void
|
|
68
|
+
nc_conj(std::complex<double> *a, std::complex<double> *r)
|
|
69
|
+
{
|
|
70
|
+
r->real(a->real());
|
|
71
|
+
r->imag(-a->imag());
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Needed for allowing the internal casting in numexpr machinery for
|
|
76
|
+
// conjugate operations
|
|
77
|
+
inline float fconjf(float x)
|
|
78
|
+
{
|
|
79
|
+
return x;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Needed for allowing the internal casting in numexpr machinery for
|
|
83
|
+
// conjugate operations
|
|
84
|
+
inline double fconj(double x)
|
|
85
|
+
{
|
|
86
|
+
return x;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
static void
|
|
90
|
+
nc_prod(std::complex<double> *a, std::complex<double> *b, std::complex<double> *r)
|
|
91
|
+
{
|
|
92
|
+
double ar=a->real(), br=b->real(), ai=a->imag(), bi=b->imag();
|
|
93
|
+
r->real(ar*br - ai*bi);
|
|
94
|
+
r->imag(ar*bi + ai*br);
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
static void
|
|
99
|
+
nc_quot(std::complex<double> *a, std::complex<double> *b, std::complex<double> *r)
|
|
100
|
+
{
|
|
101
|
+
double ar=a->real(), br=b->real(), ai=a->imag(), bi=b->imag();
|
|
102
|
+
double d = br*br + bi*bi;
|
|
103
|
+
r->real((ar*br + ai*bi)/d);
|
|
104
|
+
r->imag((ai*br - ar*bi)/d);
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
static void
|
|
109
|
+
nc_sqrt(std::complex<double> *x, std::complex<double> *r)
|
|
110
|
+
{
|
|
111
|
+
double s,d;
|
|
112
|
+
if (x->real() == 0. && x->imag() == 0.)
|
|
113
|
+
*r = *x;
|
|
114
|
+
else {
|
|
115
|
+
s = sqrt((fabs(x->real()) + hypot(x->real(),x->imag()))/2);
|
|
116
|
+
d = x->imag()/(2*s);
|
|
117
|
+
if (x->real() > 0.) {
|
|
118
|
+
r->real(s);
|
|
119
|
+
r->imag(d);
|
|
120
|
+
}
|
|
121
|
+
else if (x->imag() >= 0.) {
|
|
122
|
+
r->real(d);
|
|
123
|
+
r->imag(s);
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
r->real(-d);
|
|
127
|
+
r->imag(-s);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
static void
|
|
134
|
+
nc_log(std::complex<double> *x, std::complex<double> *r)
|
|
135
|
+
{
|
|
136
|
+
double l = hypot(x->real(),x->imag());
|
|
137
|
+
r->imag(atan2(x->imag(), x->real()));
|
|
138
|
+
r->real(log(l));
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
static void
|
|
143
|
+
nc_log1p(std::complex<double> *x, std::complex<double> *r)
|
|
144
|
+
{
|
|
145
|
+
double l = hypot(x->real() + 1.0,x->imag());
|
|
146
|
+
r->imag(atan2(x->imag(), x->real() + 1.0));
|
|
147
|
+
r->real(log(l));
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
static void
|
|
152
|
+
nc_exp(std::complex<double> *x, std::complex<double> *r)
|
|
153
|
+
{
|
|
154
|
+
double a = exp(x->real());
|
|
155
|
+
r->real(a*cos(x->imag()));
|
|
156
|
+
r->imag(a*sin(x->imag()));
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
static void
|
|
161
|
+
nc_expm1(std::complex<double> *x, std::complex<double> *r)
|
|
162
|
+
{
|
|
163
|
+
double a = sin(x->imag() / 2);
|
|
164
|
+
double b = exp(x->real());
|
|
165
|
+
r->real(expm1(x->real()) * cos(x->imag()) - 2 * a * a);
|
|
166
|
+
r->imag(b * sin(x->imag()));
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
static void
|
|
171
|
+
nc_pow(std::complex<double> *a, std::complex<double> *b, std::complex<double> *r)
|
|
172
|
+
{
|
|
173
|
+
npy_intp n;
|
|
174
|
+
double ar=a->real(), br=b->real(), ai=a->imag(), bi=b->imag();
|
|
175
|
+
|
|
176
|
+
if (br == 0. && bi == 0.) {
|
|
177
|
+
r->real(1.);
|
|
178
|
+
r->imag(0.);
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
if (ar == 0. && ai == 0.) {
|
|
182
|
+
r->real(0.);
|
|
183
|
+
r->imag(0.);
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
if (bi == 0 && (n=(npy_intp)br) == br) {
|
|
187
|
+
if (n > -100 && n < 100) {
|
|
188
|
+
std::complex<double> p, aa;
|
|
189
|
+
npy_intp mask = 1;
|
|
190
|
+
if (n < 0) n = -n;
|
|
191
|
+
aa = nc_1;
|
|
192
|
+
p.real(ar); p.imag(ai);
|
|
193
|
+
while (1) {
|
|
194
|
+
if (n & mask)
|
|
195
|
+
nc_prod(&aa,&p,&aa);
|
|
196
|
+
mask <<= 1;
|
|
197
|
+
if (n < mask || mask <= 0) break;
|
|
198
|
+
nc_prod(&p,&p,&p);
|
|
199
|
+
}
|
|
200
|
+
r->real(aa.real()); r->imag(aa.imag());
|
|
201
|
+
if (br < 0) nc_quot(&nc_1, r, r);
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
/* complexobject.c uses an inline version of this formula
|
|
206
|
+
investigate whether this had better performance or accuracy */
|
|
207
|
+
nc_log(a, r);
|
|
208
|
+
nc_prod(r, b, r);
|
|
209
|
+
nc_exp(r, r);
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
static void
|
|
215
|
+
nc_prodi(std::complex<double> *x, std::complex<double> *r)
|
|
216
|
+
{
|
|
217
|
+
double xr = x->real();
|
|
218
|
+
r->real(-x->imag());
|
|
219
|
+
r->imag(xr);
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+
static void
|
|
225
|
+
nc_acos(std::complex<double> *x, std::complex<double> *r)
|
|
226
|
+
{
|
|
227
|
+
std::complex<double> a, *pa=&a;
|
|
228
|
+
|
|
229
|
+
nc_assign(x, pa);
|
|
230
|
+
nc_prod(x,x,r);
|
|
231
|
+
nc_diff(&nc_1, r, r);
|
|
232
|
+
nc_sqrt(r, r);
|
|
233
|
+
nc_prodi(r, r);
|
|
234
|
+
nc_sum(pa, r, r);
|
|
235
|
+
nc_log(r, r);
|
|
236
|
+
nc_prodi(r, r);
|
|
237
|
+
nc_neg(r, r);
|
|
238
|
+
return;
|
|
239
|
+
/* return nc_neg(nc_prodi(nc_log(nc_sum(x,nc_prod(nc_i,
|
|
240
|
+
nc_sqrt(nc_diff(nc_1,nc_prod(x,x))))))));
|
|
241
|
+
*/
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
static void
|
|
245
|
+
nc_acosh(std::complex<double> *x, std::complex<double> *r)
|
|
246
|
+
{
|
|
247
|
+
std::complex<double> t, a, *pa=&a;
|
|
248
|
+
|
|
249
|
+
nc_assign(x, pa);
|
|
250
|
+
nc_sum(x, &nc_1, &t);
|
|
251
|
+
nc_sqrt(&t, &t);
|
|
252
|
+
nc_diff(x, &nc_1, r);
|
|
253
|
+
nc_sqrt(r, r);
|
|
254
|
+
nc_prod(&t, r, r);
|
|
255
|
+
nc_sum(pa, r, r);
|
|
256
|
+
nc_log(r, r);
|
|
257
|
+
return;
|
|
258
|
+
/*
|
|
259
|
+
return nc_log(nc_sum(x,
|
|
260
|
+
nc_prod(nc_sqrt(nc_sum(x,nc_1)), nc_sqrt(nc_diff(x,nc_1)))));
|
|
261
|
+
*/
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
static void
|
|
265
|
+
nc_asin(std::complex<double> *x, std::complex<double> *r)
|
|
266
|
+
{
|
|
267
|
+
std::complex<double> a, *pa=&a;
|
|
268
|
+
nc_prodi(x, pa);
|
|
269
|
+
nc_prod(x, x, r);
|
|
270
|
+
nc_diff(&nc_1, r, r);
|
|
271
|
+
nc_sqrt(r, r);
|
|
272
|
+
nc_sum(pa, r, r);
|
|
273
|
+
nc_log(r, r);
|
|
274
|
+
nc_prodi(r, r);
|
|
275
|
+
nc_neg(r, r);
|
|
276
|
+
return;
|
|
277
|
+
/*
|
|
278
|
+
return nc_neg(nc_prodi(nc_log(nc_sum(nc_prod(nc_i,x),
|
|
279
|
+
nc_sqrt(nc_diff(nc_1,nc_prod(x,x)))))));
|
|
280
|
+
*/
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
static void
|
|
285
|
+
nc_asinh(std::complex<double> *x, std::complex<double> *r)
|
|
286
|
+
{
|
|
287
|
+
std::complex<double> a, *pa=&a;
|
|
288
|
+
nc_assign(x, pa);
|
|
289
|
+
nc_prod(x, x, r);
|
|
290
|
+
nc_sum(&nc_1, r, r);
|
|
291
|
+
nc_sqrt(r, r);
|
|
292
|
+
nc_sum(r, pa, r);
|
|
293
|
+
nc_log(r, r);
|
|
294
|
+
return;
|
|
295
|
+
/*
|
|
296
|
+
return nc_log(nc_sum(nc_sqrt(nc_sum(nc_1,nc_prod(x,x))),x));
|
|
297
|
+
*/
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
static void
|
|
301
|
+
nc_atan(std::complex<double> *x, std::complex<double> *r)
|
|
302
|
+
{
|
|
303
|
+
std::complex<double> a, *pa=&a;
|
|
304
|
+
nc_diff(&nc_i, x, pa);
|
|
305
|
+
nc_sum(&nc_i, x, r);
|
|
306
|
+
nc_quot(r, pa, r);
|
|
307
|
+
nc_log(r,r);
|
|
308
|
+
nc_prod(&nc_i2, r, r);
|
|
309
|
+
return;
|
|
310
|
+
/*
|
|
311
|
+
return nc_prod(nc_i2,nc_log(nc_quot(nc_sum(nc_i,x),nc_diff(nc_i,x))));
|
|
312
|
+
*/
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
static void
|
|
316
|
+
nc_atanh(std::complex<double> *x, std::complex<double> *r)
|
|
317
|
+
{
|
|
318
|
+
std::complex<double> a, b, *pa=&a, *pb=&b;
|
|
319
|
+
nc_assign(x, pa);
|
|
320
|
+
nc_diff(&nc_1, pa, r);
|
|
321
|
+
nc_sum(&nc_1, pa, pb);
|
|
322
|
+
nc_quot(pb, r, r);
|
|
323
|
+
nc_log(r, r);
|
|
324
|
+
nc_prod(&nc_half, r, r);
|
|
325
|
+
return;
|
|
326
|
+
/*
|
|
327
|
+
return nc_prod(nc_half,nc_log(nc_quot(nc_sum(nc_1,x),nc_diff(nc_1,x))));
|
|
328
|
+
*/
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
static void
|
|
332
|
+
nc_cos(std::complex<double> *x, std::complex<double> *r)
|
|
333
|
+
{
|
|
334
|
+
double xr=x->real(), xi=x->imag();
|
|
335
|
+
r->real(cos(xr)*cosh(xi));
|
|
336
|
+
r->imag(-sin(xr)*sinh(xi));
|
|
337
|
+
return;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
static void
|
|
341
|
+
nc_cosh(std::complex<double> *x, std::complex<double> *r)
|
|
342
|
+
{
|
|
343
|
+
double xr=x->real(), xi=x->imag();
|
|
344
|
+
r->real(cos(xi)*cosh(xr));
|
|
345
|
+
r->imag(sin(xi)*sinh(xr));
|
|
346
|
+
return;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
|
|
350
|
+
#define M_LOG10_E 0.434294481903251827651128918916605082294397
|
|
351
|
+
#define M_LOG2_E 1.44269504088896340735992468100189213742664
|
|
352
|
+
|
|
353
|
+
|
|
354
|
+
static void
|
|
355
|
+
nc_log10(std::complex<double> *x, std::complex<double> *r)
|
|
356
|
+
{
|
|
357
|
+
nc_log(x, r);
|
|
358
|
+
r->real(r->real() * M_LOG10_E);
|
|
359
|
+
r->imag(r->imag() * M_LOG10_E);
|
|
360
|
+
return;
|
|
361
|
+
}
|
|
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
|
+
|
|
372
|
+
static void
|
|
373
|
+
nc_sin(std::complex<double> *x, std::complex<double> *r)
|
|
374
|
+
{
|
|
375
|
+
double xr=x->real(), xi=x->imag();
|
|
376
|
+
r->real(sin(xr)*cosh(xi));
|
|
377
|
+
r->imag(cos(xr)*sinh(xi));
|
|
378
|
+
return;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
static void
|
|
382
|
+
nc_sinh(std::complex<double> *x, std::complex<double> *r)
|
|
383
|
+
{
|
|
384
|
+
double xr=x->real(), xi=x->imag();
|
|
385
|
+
r->real(cos(xi)*sinh(xr));
|
|
386
|
+
r->imag(sin(xi)*cosh(xr));
|
|
387
|
+
return;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
static void
|
|
391
|
+
nc_tan(std::complex<double> *x, std::complex<double> *r)
|
|
392
|
+
{
|
|
393
|
+
double xr = x->real();
|
|
394
|
+
double xi = x->imag();
|
|
395
|
+
double imag_part;
|
|
396
|
+
|
|
397
|
+
double denom = cos(2*xr) + cosh(2*xi);
|
|
398
|
+
// handle overflows
|
|
399
|
+
if (xi > 20) {
|
|
400
|
+
imag_part = 1.0 / (1.0 + exp(-4*xi));
|
|
401
|
+
} else if (xi < -20) {
|
|
402
|
+
imag_part = -1.0 / (1.0 + exp(4*xi));
|
|
403
|
+
} else {
|
|
404
|
+
imag_part = sinh(2*xi) / denom;
|
|
405
|
+
}
|
|
406
|
+
double real_part = sin(2*xr) / denom;
|
|
407
|
+
|
|
408
|
+
r->real(real_part);
|
|
409
|
+
r->imag(imag_part);
|
|
410
|
+
return;
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
static void
|
|
414
|
+
nc_tanh(std::complex<double> *x, std::complex<double> *r)
|
|
415
|
+
{
|
|
416
|
+
double xr = x->real();
|
|
417
|
+
double xi = x->imag();
|
|
418
|
+
double real_part;
|
|
419
|
+
double denom = cosh(2*xr) + cos(2*xi);
|
|
420
|
+
// handle overflows
|
|
421
|
+
if (xr > 20) {
|
|
422
|
+
real_part = 1.0 / (1.0 + exp(-4*xr));
|
|
423
|
+
} else if (xr < -20) {
|
|
424
|
+
real_part = -1.0 / (1.0 + exp(4*xr));
|
|
425
|
+
} else {
|
|
426
|
+
real_part = sinh(2*xr) / denom;
|
|
427
|
+
}
|
|
428
|
+
double imag_part = sin(2*xi) / denom;
|
|
429
|
+
|
|
430
|
+
r->real(real_part);
|
|
431
|
+
r->imag(imag_part);
|
|
432
|
+
return;
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
static void
|
|
436
|
+
nc_abs(std::complex<double> *x, std::complex<double> *r)
|
|
437
|
+
{
|
|
438
|
+
r->real(sqrt(x->real()*x->real() + x->imag()*x->imag()));
|
|
439
|
+
r->imag(0);
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
static void
|
|
443
|
+
nc_rint(std::complex<double> *x, std::complex<double> *r)
|
|
444
|
+
{
|
|
445
|
+
r->real(rint(x->real()));
|
|
446
|
+
r->imag(rint(x->imag()));
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
static bool
|
|
450
|
+
nc_isinf(std::complex<double> *x)
|
|
451
|
+
{
|
|
452
|
+
double xr=x->real(), xi=x->imag();
|
|
453
|
+
bool bi,br;
|
|
454
|
+
bi = isinfd(xi);
|
|
455
|
+
br = isinfd(xr);
|
|
456
|
+
return bi || br;
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
static bool
|
|
460
|
+
nc_isnan(std::complex<double> *x)
|
|
461
|
+
{
|
|
462
|
+
double xr=x->real(), xi=x->imag();
|
|
463
|
+
bool bi,br;
|
|
464
|
+
bi = isnand(xi);
|
|
465
|
+
br = isnand(xr);
|
|
466
|
+
return bi || br;
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
static bool
|
|
470
|
+
nc_isfinite(std::complex<double> *x)
|
|
471
|
+
{
|
|
472
|
+
double xr=x->real(), xi=x->imag();
|
|
473
|
+
bool bi,br;
|
|
474
|
+
bi = isfinited(xi);
|
|
475
|
+
br = isfinited(xr);
|
|
476
|
+
return bi && br;
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
static void
|
|
480
|
+
nc_sign(std::complex<double> *x, std::complex<double> *r)
|
|
481
|
+
{
|
|
482
|
+
if (nc_isnan(x)){
|
|
483
|
+
r->real(NAN);
|
|
484
|
+
r->imag(NAN);
|
|
485
|
+
}
|
|
486
|
+
std::complex<double> mag;
|
|
487
|
+
nc_abs(x, &mag);
|
|
488
|
+
if (mag.real() == 0){
|
|
489
|
+
r->real(0);
|
|
490
|
+
r->imag(0);
|
|
491
|
+
}
|
|
492
|
+
else{
|
|
493
|
+
r->real(x->real()/mag.real());
|
|
494
|
+
r->imag(x->imag()/mag.real());
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
#endif // NUMEXPR_COMPLEX_FUNCTIONS_HPP
|