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.
@@ -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