pyopencl 2025.2.7__cp314-cp314-macosx_11_0_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.

Potentially problematic release.


This version of pyopencl might be problematic. Click here for more details.

Files changed (46) hide show
  1. pyopencl/__init__.py +1995 -0
  2. pyopencl/_cl.cpython-314-darwin.so +0 -0
  3. pyopencl/_cl.pyi +2009 -0
  4. pyopencl/_cluda.py +57 -0
  5. pyopencl/_monkeypatch.py +1104 -0
  6. pyopencl/_mymako.py +17 -0
  7. pyopencl/algorithm.py +1454 -0
  8. pyopencl/array.py +3530 -0
  9. pyopencl/bitonic_sort.py +245 -0
  10. pyopencl/bitonic_sort_templates.py +597 -0
  11. pyopencl/cache.py +535 -0
  12. pyopencl/capture_call.py +200 -0
  13. pyopencl/characterize/__init__.py +461 -0
  14. pyopencl/characterize/performance.py +240 -0
  15. pyopencl/cl/pyopencl-airy.cl +324 -0
  16. pyopencl/cl/pyopencl-bessel-j-complex.cl +238 -0
  17. pyopencl/cl/pyopencl-bessel-j.cl +1084 -0
  18. pyopencl/cl/pyopencl-bessel-y.cl +435 -0
  19. pyopencl/cl/pyopencl-complex.h +303 -0
  20. pyopencl/cl/pyopencl-eval-tbl.cl +120 -0
  21. pyopencl/cl/pyopencl-hankel-complex.cl +444 -0
  22. pyopencl/cl/pyopencl-random123/array.h +325 -0
  23. pyopencl/cl/pyopencl-random123/openclfeatures.h +93 -0
  24. pyopencl/cl/pyopencl-random123/philox.cl +486 -0
  25. pyopencl/cl/pyopencl-random123/threefry.cl +864 -0
  26. pyopencl/clmath.py +281 -0
  27. pyopencl/clrandom.py +412 -0
  28. pyopencl/cltypes.py +217 -0
  29. pyopencl/compyte/.gitignore +21 -0
  30. pyopencl/compyte/__init__.py +0 -0
  31. pyopencl/compyte/array.py +211 -0
  32. pyopencl/compyte/dtypes.py +314 -0
  33. pyopencl/compyte/pyproject.toml +49 -0
  34. pyopencl/elementwise.py +1288 -0
  35. pyopencl/invoker.py +417 -0
  36. pyopencl/ipython_ext.py +70 -0
  37. pyopencl/py.typed +0 -0
  38. pyopencl/reduction.py +815 -0
  39. pyopencl/scan.py +1921 -0
  40. pyopencl/tools.py +1680 -0
  41. pyopencl/typing.py +61 -0
  42. pyopencl/version.py +11 -0
  43. pyopencl-2025.2.7.dist-info/METADATA +108 -0
  44. pyopencl-2025.2.7.dist-info/RECORD +46 -0
  45. pyopencl-2025.2.7.dist-info/WHEEL +6 -0
  46. pyopencl-2025.2.7.dist-info/licenses/LICENSE +282 -0
@@ -0,0 +1,1084 @@
1
+ // Pieced together from Boost C++ and Cephes by
2
+ // Andreas Kloeckner (C) 2012
3
+ //
4
+ // Pieces from:
5
+ //
6
+ // Copyright (c) 2006 Xiaogang Zhang, John Maddock
7
+ // Use, modification and distribution are subject to the
8
+ // Boost Software License, Version 1.0. (See
9
+ // http://www.boost.org/LICENSE_1_0.txt)
10
+ //
11
+ // Cephes Math Library Release 2.8: June, 2000
12
+ // Copyright 1984, 1987, 1989, 1992, 2000 by Stephen L. Moshier
13
+ // What you see here may be used freely, but it comes with no support or
14
+ // guarantee.
15
+
16
+
17
+
18
+
19
+
20
+ #pragma once
21
+
22
+ #include <pyopencl-eval-tbl.cl>
23
+ #include <pyopencl-airy.cl>
24
+
25
+ typedef double bessel_j_scalar_type;
26
+ // FIXME: T is really a bad name
27
+ typedef bessel_j_scalar_type T;
28
+
29
+ // {{{ bessel_j0
30
+
31
+ __constant const bessel_j_scalar_type bessel_j0_P1[] = {
32
+ -4.1298668500990866786e+11,
33
+ 2.7282507878605942706e+10,
34
+ -6.2140700423540120665e+08,
35
+ 6.6302997904833794242e+06,
36
+ -3.6629814655107086448e+04,
37
+ 1.0344222815443188943e+02,
38
+ -1.2117036164593528341e-01
39
+ };
40
+ __constant const bessel_j_scalar_type bessel_j0_Q1[] = {
41
+ 2.3883787996332290397e+12,
42
+ 2.6328198300859648632e+10,
43
+ 1.3985097372263433271e+08,
44
+ 4.5612696224219938200e+05,
45
+ 9.3614022392337710626e+02,
46
+ 1.0,
47
+ 0.0
48
+ };
49
+ __constant const bessel_j_scalar_type bessel_j0_P2[] = {
50
+ -1.8319397969392084011e+03,
51
+ -1.2254078161378989535e+04,
52
+ -7.2879702464464618998e+03,
53
+ 1.0341910641583726701e+04,
54
+ 1.1725046279757103576e+04,
55
+ 4.4176707025325087628e+03,
56
+ 7.4321196680624245801e+02,
57
+ 4.8591703355916499363e+01
58
+ };
59
+ __constant const bessel_j_scalar_type bessel_j0_Q2[] = {
60
+ -3.5783478026152301072e+05,
61
+ 2.4599102262586308984e+05,
62
+ -8.4055062591169562211e+04,
63
+ 1.8680990008359188352e+04,
64
+ -2.9458766545509337327e+03,
65
+ 3.3307310774649071172e+02,
66
+ -2.5258076240801555057e+01,
67
+ 1.0
68
+ };
69
+ __constant const bessel_j_scalar_type bessel_j0_PC[] = {
70
+ 2.2779090197304684302e+04,
71
+ 4.1345386639580765797e+04,
72
+ 2.1170523380864944322e+04,
73
+ 3.4806486443249270347e+03,
74
+ 1.5376201909008354296e+02,
75
+ 8.8961548424210455236e-01
76
+ };
77
+ __constant const bessel_j_scalar_type bessel_j0_QC[] = {
78
+ 2.2779090197304684318e+04,
79
+ 4.1370412495510416640e+04,
80
+ 2.1215350561880115730e+04,
81
+ 3.5028735138235608207e+03,
82
+ 1.5711159858080893649e+02,
83
+ 1.0
84
+ };
85
+ __constant const bessel_j_scalar_type bessel_j0_PS[] = {
86
+ -8.9226600200800094098e+01,
87
+ -1.8591953644342993800e+02,
88
+ -1.1183429920482737611e+02,
89
+ -2.2300261666214198472e+01,
90
+ -1.2441026745835638459e+00,
91
+ -8.8033303048680751817e-03
92
+ };
93
+ __constant const bessel_j_scalar_type bessel_j0_QS[] = {
94
+ 5.7105024128512061905e+03,
95
+ 1.1951131543434613647e+04,
96
+ 7.2642780169211018836e+03,
97
+ 1.4887231232283756582e+03,
98
+ 9.0593769594993125859e+01,
99
+ 1.0
100
+ };
101
+
102
+ bessel_j_scalar_type bessel_j0(bessel_j_scalar_type x)
103
+ {
104
+ const bessel_j_scalar_type x1 = 2.4048255576957727686e+00,
105
+ x2 = 5.5200781102863106496e+00,
106
+ x11 = 6.160e+02,
107
+ x12 = -1.42444230422723137837e-03,
108
+ x21 = 1.4130e+03,
109
+ x22 = 5.46860286310649596604e-04;
110
+
111
+ bessel_j_scalar_type value, factor, r, rc, rs;
112
+
113
+ if (x < 0)
114
+ {
115
+ x = -x; // even function
116
+ }
117
+ if (x == 0)
118
+ {
119
+ return 1;
120
+ }
121
+ if (x <= 4) // x in (0, 4]
122
+ {
123
+ bessel_j_scalar_type y = x * x;
124
+ r = boost_evaluate_rational(bessel_j0_P1, bessel_j0_Q1, y);
125
+ factor = (x + x1) * ((x - x11/256) - x12);
126
+ value = factor * r;
127
+ }
128
+ else if (x <= 8.0) // x in (4, 8]
129
+ {
130
+ bessel_j_scalar_type y = 1 - (x * x)/64;
131
+ r = boost_evaluate_rational(bessel_j0_P2, bessel_j0_Q2, y);
132
+ factor = (x + x2) * ((x - x21/256) - x22);
133
+ value = factor * r;
134
+ }
135
+ else // x in (8, \infty)
136
+ {
137
+ bessel_j_scalar_type y = 8 / x;
138
+ bessel_j_scalar_type y2 = y * y;
139
+ bessel_j_scalar_type z = x - 0.25f * M_PI;
140
+ rc = boost_evaluate_rational(bessel_j0_PC, bessel_j0_QC, y2);
141
+ rs = boost_evaluate_rational(bessel_j0_PS, bessel_j0_QS, y2);
142
+ factor = sqrt(2 / (x * M_PI));
143
+ value = factor * (rc * cos(z) - y * rs * sin(z));
144
+ }
145
+
146
+ return value;
147
+ }
148
+
149
+ // }}}
150
+
151
+ // {{{ bessel_j1
152
+
153
+ __constant const bessel_j_scalar_type bessel_j1_P1[] = {
154
+ -1.4258509801366645672e+11,
155
+ 6.6781041261492395835e+09,
156
+ -1.1548696764841276794e+08,
157
+ 9.8062904098958257677e+05,
158
+ -4.4615792982775076130e+03,
159
+ 1.0650724020080236441e+01,
160
+ -1.0767857011487300348e-02
161
+ };
162
+ __constant const bessel_j_scalar_type bessel_j1_Q1[] = {
163
+ 4.1868604460820175290e+12,
164
+ 4.2091902282580133541e+10,
165
+ 2.0228375140097033958e+08,
166
+ 5.9117614494174794095e+05,
167
+ 1.0742272239517380498e+03,
168
+ 1.0,
169
+ 0.0
170
+ };
171
+ __constant const bessel_j_scalar_type bessel_j1_P2[] = {
172
+ -1.7527881995806511112e+16,
173
+ 1.6608531731299018674e+15,
174
+ -3.6658018905416665164e+13,
175
+ 3.5580665670910619166e+11,
176
+ -1.8113931269860667829e+09,
177
+ 5.0793266148011179143e+06,
178
+ -7.5023342220781607561e+03,
179
+ 4.6179191852758252278e+00
180
+ };
181
+ __constant const bessel_j_scalar_type bessel_j1_Q2[] = {
182
+ 1.7253905888447681194e+18,
183
+ 1.7128800897135812012e+16,
184
+ 8.4899346165481429307e+13,
185
+ 2.7622777286244082666e+11,
186
+ 6.4872502899596389593e+08,
187
+ 1.1267125065029138050e+06,
188
+ 1.3886978985861357615e+03,
189
+ 1.0
190
+ };
191
+ __constant const bessel_j_scalar_type bessel_j1_PC[] = {
192
+ -4.4357578167941278571e+06,
193
+ -9.9422465050776411957e+06,
194
+ -6.6033732483649391093e+06,
195
+ -1.5235293511811373833e+06,
196
+ -1.0982405543459346727e+05,
197
+ -1.6116166443246101165e+03,
198
+ 0.0
199
+ };
200
+ __constant const bessel_j_scalar_type bessel_j1_QC[] = {
201
+ -4.4357578167941278568e+06,
202
+ -9.9341243899345856590e+06,
203
+ -6.5853394797230870728e+06,
204
+ -1.5118095066341608816e+06,
205
+ -1.0726385991103820119e+05,
206
+ -1.4550094401904961825e+03,
207
+ 1.0
208
+ };
209
+ __constant const bessel_j_scalar_type bessel_j1_PS[] = {
210
+ 3.3220913409857223519e+04,
211
+ 8.5145160675335701966e+04,
212
+ 6.6178836581270835179e+04,
213
+ 1.8494262873223866797e+04,
214
+ 1.7063754290207680021e+03,
215
+ 3.5265133846636032186e+01,
216
+ 0.0
217
+ };
218
+ __constant const bessel_j_scalar_type bessel_j1_QS[] = {
219
+ 7.0871281941028743574e+05,
220
+ 1.8194580422439972989e+06,
221
+ 1.4194606696037208929e+06,
222
+ 4.0029443582266975117e+05,
223
+ 3.7890229745772202641e+04,
224
+ 8.6383677696049909675e+02,
225
+ 1.0
226
+ };
227
+
228
+
229
+ bessel_j_scalar_type bessel_j1(bessel_j_scalar_type x)
230
+ {
231
+ const bessel_j_scalar_type x1 = 3.8317059702075123156e+00,
232
+ x2 = 7.0155866698156187535e+00,
233
+ x11 = 9.810e+02,
234
+ x12 = -3.2527979248768438556e-04,
235
+ x21 = 1.7960e+03,
236
+ x22 = -3.8330184381246462950e-05;
237
+
238
+ bessel_j_scalar_type value, factor, r, rc, rs, w;
239
+
240
+ w = fabs(x);
241
+ if (x == 0)
242
+ {
243
+ return 0;
244
+ }
245
+ if (w <= 4) // w in (0, 4]
246
+ {
247
+ bessel_j_scalar_type y = x * x;
248
+ r = boost_evaluate_rational(bessel_j1_P1, bessel_j1_Q1, y);
249
+ factor = w * (w + x1) * ((w - x11/256) - x12);
250
+ value = factor * r;
251
+ }
252
+ else if (w <= 8) // w in (4, 8]
253
+ {
254
+ bessel_j_scalar_type y = x * x;
255
+ r = boost_evaluate_rational(bessel_j1_P2, bessel_j1_Q2, y);
256
+ factor = w * (w + x2) * ((w - x21/256) - x22);
257
+ value = factor * r;
258
+ }
259
+ else // w in (8, \infty)
260
+ {
261
+ bessel_j_scalar_type y = 8 / w;
262
+ bessel_j_scalar_type y2 = y * y;
263
+ bessel_j_scalar_type z = w - 0.75f * M_PI;
264
+ rc = boost_evaluate_rational(bessel_j1_PC, bessel_j1_QC, y2);
265
+ rs = boost_evaluate_rational(bessel_j1_PS, bessel_j1_QS, y2);
266
+ factor = sqrt(2 / (w * M_PI));
267
+ value = factor * (rc * cos(z) - y * rs * sin(z));
268
+ }
269
+
270
+ if (x < 0)
271
+ {
272
+ value *= -1; // odd function
273
+ }
274
+ return value;
275
+ }
276
+
277
+ // }}}
278
+
279
+ // {{{ bessel_recur
280
+
281
+ /* Reduce the order by backward recurrence.
282
+ * AMS55 #9.1.27 and 9.1.73.
283
+ */
284
+
285
+ #define BESSEL_BIG 1.44115188075855872E+17
286
+
287
+ double bessel_recur(double *n, double x, double *newn, int cancel )
288
+ {
289
+ double pkm2, pkm1, pk, qkm2, qkm1;
290
+ /* double pkp1; */
291
+ double k, ans, qk, xk, yk, r, t, kf;
292
+ const double big = BESSEL_BIG;
293
+ int nflag, ctr;
294
+
295
+ /* continued fraction for Jn(x)/Jn-1(x) */
296
+ if( *n < 0.0 )
297
+ nflag = 1;
298
+ else
299
+ nflag = 0;
300
+
301
+ fstart:
302
+
303
+ #if DEBUG
304
+ printf( "recur: n = %.6e, newn = %.6e, cfrac = ", *n, *newn );
305
+ #endif
306
+
307
+ pkm2 = 0.0;
308
+ qkm2 = 1.0;
309
+ pkm1 = x;
310
+ qkm1 = *n + *n;
311
+ xk = -x * x;
312
+ yk = qkm1;
313
+ ans = 1.0;
314
+ ctr = 0;
315
+ do
316
+ {
317
+ yk += 2.0;
318
+ pk = pkm1 * yk + pkm2 * xk;
319
+ qk = qkm1 * yk + qkm2 * xk;
320
+ pkm2 = pkm1;
321
+ pkm1 = pk;
322
+ qkm2 = qkm1;
323
+ qkm1 = qk;
324
+ if( qk != 0 )
325
+ r = pk/qk;
326
+ else
327
+ r = 0.0;
328
+ if( r != 0 )
329
+ {
330
+ t = fabs( (ans - r)/r );
331
+ ans = r;
332
+ }
333
+ else
334
+ t = 1.0;
335
+
336
+ if( ++ctr > 1000 )
337
+ {
338
+ //mtherr( "jv", UNDERFLOW );
339
+ pk = nan((uint)24);
340
+
341
+ goto done;
342
+ }
343
+ if( t < DBL_EPSILON )
344
+ goto done;
345
+
346
+ if( fabs(pk) > big )
347
+ {
348
+ pkm2 /= big;
349
+ pkm1 /= big;
350
+ qkm2 /= big;
351
+ qkm1 /= big;
352
+ }
353
+ }
354
+ while( t > DBL_EPSILON );
355
+
356
+ done:
357
+
358
+ #if DEBUG
359
+ printf( "%.6e\n", ans );
360
+ #endif
361
+
362
+ /* Change n to n-1 if n < 0 and the continued fraction is small
363
+ */
364
+ if( nflag > 0 )
365
+ {
366
+ if( fabs(ans) < 0.125 )
367
+ {
368
+ nflag = -1;
369
+ *n = *n - 1.0;
370
+ goto fstart;
371
+ }
372
+ }
373
+
374
+
375
+ kf = *newn;
376
+
377
+ /* backward recurrence
378
+ * 2k
379
+ * J (x) = --- J (x) - J (x)
380
+ * k-1 x k k+1
381
+ */
382
+
383
+ pk = 1.0;
384
+ pkm1 = 1.0/ans;
385
+ k = *n - 1.0;
386
+ r = 2 * k;
387
+ do
388
+ {
389
+ pkm2 = (pkm1 * r - pk * x) / x;
390
+ /* pkp1 = pk; */
391
+ pk = pkm1;
392
+ pkm1 = pkm2;
393
+ r -= 2.0;
394
+ /*
395
+ t = fabs(pkp1) + fabs(pk);
396
+ if( (k > (kf + 2.5)) && (fabs(pkm1) < 0.25*t) )
397
+ {
398
+ k -= 1.0;
399
+ t = x*x;
400
+ pkm2 = ( (r*(r+2.0)-t)*pk - r*x*pkp1 )/t;
401
+ pkp1 = pk;
402
+ pk = pkm1;
403
+ pkm1 = pkm2;
404
+ r -= 2.0;
405
+ }
406
+ */
407
+ k -= 1.0;
408
+ }
409
+ while( k > (kf + 0.5) );
410
+
411
+ /* Take the larger of the last two iterates
412
+ * on the theory that it may have less cancellation error.
413
+ */
414
+
415
+ if( cancel )
416
+ {
417
+ if( (kf >= 0.0) && (fabs(pk) > fabs(pkm1)) )
418
+ {
419
+ k += 1.0;
420
+ pkm2 = pk;
421
+ }
422
+ }
423
+ *newn = k;
424
+ #if DEBUG
425
+ printf( "newn %.6e rans %.6e\n", k, pkm2 );
426
+ #endif
427
+ return( pkm2 );
428
+ }
429
+
430
+ // }}}
431
+
432
+ // {{{ bessel_jvs
433
+
434
+ #define BESSEL_MAXGAM 171.624376956302725
435
+ #define BESSEL_MAXLOG 7.09782712893383996843E2
436
+
437
+ /* Ascending power series for Jv(x).
438
+ * AMS55 #9.1.10.
439
+ */
440
+
441
+ double bessel_jvs(double n, double x)
442
+ {
443
+ double t, u, y, z, k;
444
+ int ex;
445
+ int sgngam = 1;
446
+
447
+ z = -x * x / 4.0;
448
+ u = 1.0;
449
+ y = u;
450
+ k = 1.0;
451
+ t = 1.0;
452
+
453
+ while( t > DBL_EPSILON )
454
+ {
455
+ u *= z / (k * (n+k));
456
+ y += u;
457
+ k += 1.0;
458
+ if( y != 0 )
459
+ t = fabs( u/y );
460
+ }
461
+ #if DEBUG
462
+ printf( "power series=%.5e ", y );
463
+ #endif
464
+ t = frexp( 0.5*x, &ex );
465
+ ex = ex * n;
466
+ if( (ex > -1023)
467
+ && (ex < 1023)
468
+ && (n > 0.0)
469
+ && (n < (BESSEL_MAXGAM-1.0)) )
470
+ {
471
+ t = pow( 0.5*x, n ) / tgamma( n + 1.0 );
472
+ #if DEBUG
473
+ printf( "pow(.5*x, %.4e)/gamma(n+1)=%.5e\n", n, t );
474
+ #endif
475
+ y *= t;
476
+ }
477
+ else
478
+ {
479
+ #if DEBUG
480
+ z = n * log(0.5*x);
481
+ k = lgamma( n+1.0 );
482
+ t = z - k;
483
+ printf( "log pow=%.5e, lgam(%.4e)=%.5e\n", z, n+1.0, k );
484
+ #else
485
+ t = n * log(0.5*x) - lgamma(n + 1.0);
486
+ #endif
487
+ if( y < 0 )
488
+ {
489
+ sgngam = -sgngam;
490
+ y = -y;
491
+ }
492
+ t += log(y);
493
+ #if DEBUG
494
+ printf( "log y=%.5e\n", log(y) );
495
+ #endif
496
+ if( t < -BESSEL_MAXLOG )
497
+ {
498
+ return( 0.0 );
499
+ }
500
+ if( t > BESSEL_MAXLOG )
501
+ {
502
+ // mtherr( "Jv", OVERFLOW );
503
+ return( DBL_MAX);
504
+ }
505
+ y = sgngam * exp( t );
506
+ }
507
+ return(y);
508
+ }
509
+
510
+ // }}}
511
+
512
+ // {{{ bessel_jnt
513
+
514
+ __constant const double bessel_jnt_PF2[] = {
515
+ -9.0000000000000000000e-2,
516
+ 8.5714285714285714286e-2
517
+ };
518
+ __constant const double bessel_jnt_PF3[] = {
519
+ 1.3671428571428571429e-1,
520
+ -5.4920634920634920635e-2,
521
+ -4.4444444444444444444e-3
522
+ };
523
+ __constant const double bessel_jnt_PF4[] = {
524
+ 1.3500000000000000000e-3,
525
+ -1.6036054421768707483e-1,
526
+ 4.2590187590187590188e-2,
527
+ 2.7330447330447330447e-3
528
+ };
529
+ __constant const double bessel_jnt_PG1[] = {
530
+ -2.4285714285714285714e-1,
531
+ 1.4285714285714285714e-2
532
+ };
533
+ __constant const double bessel_jnt_PG2[] = {
534
+ -9.0000000000000000000e-3,
535
+ 1.9396825396825396825e-1,
536
+ -1.1746031746031746032e-2
537
+ };
538
+ __constant const double bessel_jnt_PG3[] = {
539
+ 1.9607142857142857143e-2,
540
+ -1.5983694083694083694e-1,
541
+ 6.3838383838383838384e-3
542
+ };
543
+
544
+ double bessel_jnt(double n, double x)
545
+ {
546
+ double z, zz, z3;
547
+ double cbn, n23, cbtwo;
548
+ double ai, aip, bi, bip; /* Airy functions */
549
+ double nk, fk, gk, pp, qq;
550
+ double F[5], G[4];
551
+ int k;
552
+
553
+ cbn = cbrt(n);
554
+ z = (x - n)/cbn;
555
+ cbtwo = cbrt( 2.0 );
556
+
557
+ /* Airy function */
558
+ zz = -cbtwo * z;
559
+ airy( zz, &ai, &aip, &bi, &bip );
560
+
561
+ /* polynomials in expansion */
562
+ zz = z * z;
563
+ z3 = zz * z;
564
+ F[0] = 1.0;
565
+ F[1] = -z/5.0;
566
+ F[2] = cephes_polevl( z3, bessel_jnt_PF2, 1 ) * zz;
567
+ F[3] = cephes_polevl( z3, bessel_jnt_PF3, 2 );
568
+ F[4] = cephes_polevl( z3, bessel_jnt_PF4, 3 ) * z;
569
+ G[0] = 0.3 * zz;
570
+ G[1] = cephes_polevl( z3, bessel_jnt_PG1, 1 );
571
+ G[2] = cephes_polevl( z3, bessel_jnt_PG2, 2 ) * z;
572
+ G[3] = cephes_polevl( z3, bessel_jnt_PG3, 2 ) * zz;
573
+ #if DEBUG
574
+ for( k=0; k<=4; k++ )
575
+ printf( "F[%d] = %.5E\n", k, F[k] );
576
+ for( k=0; k<=3; k++ )
577
+ printf( "G[%d] = %.5E\n", k, G[k] );
578
+ #endif
579
+ pp = 0.0;
580
+ qq = 0.0;
581
+ nk = 1.0;
582
+ n23 = cbrt( n * n );
583
+
584
+ for( k=0; k<=4; k++ )
585
+ {
586
+ fk = F[k]*nk;
587
+ pp += fk;
588
+ if( k != 4 )
589
+ {
590
+ gk = G[k]*nk;
591
+ qq += gk;
592
+ }
593
+ #if DEBUG
594
+ printf("fk[%d] %.5E, gk[%d] %.5E\n", k, fk, k, gk );
595
+ #endif
596
+ nk /= n23;
597
+ }
598
+
599
+ fk = cbtwo * ai * pp/cbn + cbrt(4.0) * aip * qq/n;
600
+ return(fk);
601
+ }
602
+
603
+ // }}}
604
+
605
+ // {{{ bessel_jnx
606
+
607
+ __constant const double bessel_jnx_lambda[] = {
608
+ 1.0,
609
+ 1.041666666666666666666667E-1,
610
+ 8.355034722222222222222222E-2,
611
+ 1.282265745563271604938272E-1,
612
+ 2.918490264641404642489712E-1,
613
+ 8.816272674437576524187671E-1,
614
+ 3.321408281862767544702647E+0,
615
+ 1.499576298686255465867237E+1,
616
+ 7.892301301158651813848139E+1,
617
+ 4.744515388682643231611949E+2,
618
+ 3.207490090890661934704328E+3
619
+ };
620
+ __constant const double bessel_jnx_mu[] = {
621
+ 1.0,
622
+ -1.458333333333333333333333E-1,
623
+ -9.874131944444444444444444E-2,
624
+ -1.433120539158950617283951E-1,
625
+ -3.172272026784135480967078E-1,
626
+ -9.424291479571202491373028E-1,
627
+ -3.511203040826354261542798E+0,
628
+ -1.572726362036804512982712E+1,
629
+ -8.228143909718594444224656E+1,
630
+ -4.923553705236705240352022E+2,
631
+ -3.316218568547972508762102E+3
632
+ };
633
+ __constant const double bessel_jnx_P1[] = {
634
+ -2.083333333333333333333333E-1,
635
+ 1.250000000000000000000000E-1
636
+ };
637
+ __constant const double bessel_jnx_P2[] = {
638
+ 3.342013888888888888888889E-1,
639
+ -4.010416666666666666666667E-1,
640
+ 7.031250000000000000000000E-2
641
+ };
642
+ __constant const double bessel_jnx_P3[] = {
643
+ -1.025812596450617283950617E+0,
644
+ 1.846462673611111111111111E+0,
645
+ -8.912109375000000000000000E-1,
646
+ 7.324218750000000000000000E-2
647
+ };
648
+ __constant const double bessel_jnx_P4[] = {
649
+ 4.669584423426247427983539E+0,
650
+ -1.120700261622299382716049E+1,
651
+ 8.789123535156250000000000E+0,
652
+ -2.364086914062500000000000E+0,
653
+ 1.121520996093750000000000E-1
654
+ };
655
+ __constant const double bessel_jnx_P5[] = {
656
+ -2.8212072558200244877E1,
657
+ 8.4636217674600734632E1,
658
+ -9.1818241543240017361E1,
659
+ 4.2534998745388454861E1,
660
+ -7.3687943594796316964E0,
661
+ 2.27108001708984375E-1
662
+ };
663
+ __constant const double bessel_jnx_P6[] = {
664
+ 2.1257013003921712286E2,
665
+ -7.6525246814118164230E2,
666
+ 1.0599904525279998779E3,
667
+ -6.9957962737613254123E2,
668
+ 2.1819051174421159048E2,
669
+ -2.6491430486951555525E1,
670
+ 5.7250142097473144531E-1
671
+ };
672
+ __constant const double bessel_jnx_P7[] = {
673
+ -1.9194576623184069963E3,
674
+ 8.0617221817373093845E3,
675
+ -1.3586550006434137439E4,
676
+ 1.1655393336864533248E4,
677
+ -5.3056469786134031084E3,
678
+ 1.2009029132163524628E3,
679
+ -1.0809091978839465550E2,
680
+ 1.7277275025844573975E0
681
+ };
682
+
683
+ double bessel_jnx(double n, double x)
684
+ {
685
+ double zeta, sqz, zz, zp, np;
686
+ double cbn, n23, t, z, sz;
687
+ double pp, qq, z32i, zzi;
688
+ double ak, bk, akl, bkl;
689
+ int sign, doa, dob, nflg, k, s, tk, tkp1, m;
690
+ double u[8];
691
+ double ai, aip, bi, bip;
692
+
693
+ /* Test for x very close to n.
694
+ * Use expansion for transition region if so.
695
+ */
696
+ cbn = cbrt(n);
697
+ z = (x - n)/cbn;
698
+ if( fabs(z) <= 0.7 )
699
+ return( bessel_jnt(n,x) );
700
+
701
+ z = x/n;
702
+ zz = 1.0 - z*z;
703
+ if( zz == 0.0 )
704
+ return(0.0);
705
+
706
+ if( zz > 0.0 )
707
+ {
708
+ sz = sqrt( zz );
709
+ t = 1.5 * (log( (1.0+sz)/z ) - sz ); /* zeta ** 3/2 */
710
+ zeta = cbrt( t * t );
711
+ nflg = 1;
712
+ }
713
+ else
714
+ {
715
+ sz = sqrt(-zz);
716
+ t = 1.5 * (sz - acos(1.0/z));
717
+ zeta = -cbrt( t * t );
718
+ nflg = -1;
719
+ }
720
+ z32i = fabs(1.0/t);
721
+ sqz = cbrt(t);
722
+
723
+ /* Airy function */
724
+ n23 = cbrt( n * n );
725
+ t = n23 * zeta;
726
+
727
+ #if DEBUG
728
+ printf("zeta %.5E, Airy(%.5E)\n", zeta, t );
729
+ #endif
730
+ airy( t, &ai, &aip, &bi, &bip );
731
+
732
+ /* polynomials in expansion */
733
+ u[0] = 1.0;
734
+ zzi = 1.0/zz;
735
+ u[1] = cephes_polevl( zzi, bessel_jnx_P1, 1 )/sz;
736
+ u[2] = cephes_polevl( zzi, bessel_jnx_P2, 2 )/zz;
737
+ u[3] = cephes_polevl( zzi, bessel_jnx_P3, 3 )/(sz*zz);
738
+ pp = zz*zz;
739
+ u[4] = cephes_polevl( zzi, bessel_jnx_P4, 4 )/pp;
740
+ u[5] = cephes_polevl( zzi, bessel_jnx_P5, 5 )/(pp*sz);
741
+ pp *= zz;
742
+ u[6] = cephes_polevl( zzi, bessel_jnx_P6, 6 )/pp;
743
+ u[7] = cephes_polevl( zzi, bessel_jnx_P7, 7 )/(pp*sz);
744
+
745
+ #if DEBUG
746
+ for( k=0; k<=7; k++ )
747
+ printf( "u[%d] = %.5E\n", k, u[k] );
748
+ #endif
749
+
750
+ pp = 0.0;
751
+ qq = 0.0;
752
+ np = 1.0;
753
+ /* flags to stop when terms get larger */
754
+ doa = 1;
755
+ dob = 1;
756
+ akl = DBL_MAX;
757
+ bkl = DBL_MAX;
758
+
759
+ for( k=0; k<=3; k++ )
760
+ {
761
+ tk = 2 * k;
762
+ tkp1 = tk + 1;
763
+ zp = 1.0;
764
+ ak = 0.0;
765
+ bk = 0.0;
766
+ for( s=0; s<=tk; s++ )
767
+ {
768
+ if( doa )
769
+ {
770
+ if( (s & 3) > 1 )
771
+ sign = nflg;
772
+ else
773
+ sign = 1;
774
+ ak += sign * bessel_jnx_mu[s] * zp * u[tk-s];
775
+ }
776
+
777
+ if( dob )
778
+ {
779
+ m = tkp1 - s;
780
+ if( ((m+1) & 3) > 1 )
781
+ sign = nflg;
782
+ else
783
+ sign = 1;
784
+ bk += sign * bessel_jnx_lambda[s] * zp * u[m];
785
+ }
786
+ zp *= z32i;
787
+ }
788
+
789
+ if( doa )
790
+ {
791
+ ak *= np;
792
+ t = fabs(ak);
793
+ if( t < akl )
794
+ {
795
+ akl = t;
796
+ pp += ak;
797
+ }
798
+ else
799
+ doa = 0;
800
+ }
801
+
802
+ if( dob )
803
+ {
804
+ bk += bessel_jnx_lambda[tkp1] * zp * u[0];
805
+ bk *= -np/sqz;
806
+ t = fabs(bk);
807
+ if( t < bkl )
808
+ {
809
+ bkl = t;
810
+ qq += bk;
811
+ }
812
+ else
813
+ dob = 0;
814
+ }
815
+ #if DEBUG
816
+ printf("a[%d] %.5E, b[%d] %.5E\n", k, ak, k, bk );
817
+ #endif
818
+ if( np < DBL_EPSILON )
819
+ break;
820
+ np /= n*n;
821
+ }
822
+
823
+ /* normalizing factor ( 4*zeta/(1 - z**2) )**1/4 */
824
+ t = 4.0 * zeta/zz;
825
+ t = sqrt( sqrt(t) );
826
+
827
+ t *= ai*pp/cbrt(n) + aip*qq/(n23*n);
828
+ return(t);
829
+ }
830
+
831
+ // }}}
832
+
833
+ // {{{ bessel_hankel
834
+
835
+ /* Hankel's asymptotic expansion
836
+ * for large x.
837
+ * AMS55 #9.2.5.
838
+ */
839
+
840
+ double bessel_hankel( double n, double x )
841
+ {
842
+ double t, u, z, k, sign, conv;
843
+ double p, q, j, m, pp, qq;
844
+ int flag;
845
+
846
+ m = 4.0*n*n;
847
+ j = 1.0;
848
+ z = 8.0 * x;
849
+ k = 1.0;
850
+ p = 1.0;
851
+ u = (m - 1.0)/z;
852
+ q = u;
853
+ sign = 1.0;
854
+ conv = 1.0;
855
+ flag = 0;
856
+ t = 1.0;
857
+ pp = 1.0e38;
858
+ qq = 1.0e38;
859
+
860
+ while( t > DBL_EPSILON )
861
+ {
862
+ k += 2.0;
863
+ j += 1.0;
864
+ sign = -sign;
865
+ u *= (m - k * k)/(j * z);
866
+ p += sign * u;
867
+ k += 2.0;
868
+ j += 1.0;
869
+ u *= (m - k * k)/(j * z);
870
+ q += sign * u;
871
+ t = fabs(u/p);
872
+ if( t < conv )
873
+ {
874
+ conv = t;
875
+ qq = q;
876
+ pp = p;
877
+ flag = 1;
878
+ }
879
+ /* stop if the terms start getting larger */
880
+ if( (flag != 0) && (t > conv) )
881
+ {
882
+ #if DEBUG
883
+ printf( "Hankel: convergence to %.4E\n", conv );
884
+ #endif
885
+ goto hank1;
886
+ }
887
+ }
888
+
889
+ hank1:
890
+ u = x - (0.5*n + 0.25) * M_PI;
891
+ t = sqrt( 2.0/(M_PI*x) ) * ( pp * cos(u) - qq * sin(u) );
892
+ #if DEBUG
893
+ printf( "hank: %.6e\n", t );
894
+ #endif
895
+ return( t );
896
+ }
897
+ // }}}
898
+
899
+ // {{{ bessel_jv
900
+
901
+ // SciPy says jn has no advantage over jv, so alias the two.
902
+
903
+ #define bessel_jn bessel_jv
904
+
905
+ double bessel_jv(double n, double x)
906
+ {
907
+ double k, q, t, y, an;
908
+ int i, sign, nint;
909
+
910
+ nint = 0; /* Flag for integer n */
911
+ sign = 1; /* Flag for sign inversion */
912
+ an = fabs( n );
913
+ y = floor( an );
914
+ if( y == an )
915
+ {
916
+ nint = 1;
917
+ i = an - 16384.0 * floor( an/16384.0 );
918
+ if( n < 0.0 )
919
+ {
920
+ if( i & 1 )
921
+ sign = -sign;
922
+ n = an;
923
+ }
924
+ if( x < 0.0 )
925
+ {
926
+ if( i & 1 )
927
+ sign = -sign;
928
+ x = -x;
929
+ }
930
+ if( n == 0.0 )
931
+ return( bessel_j0(x) );
932
+ if( n == 1.0 )
933
+ return( sign * bessel_j1(x) );
934
+ }
935
+
936
+ if( (x < 0.0) && (y != an) )
937
+ {
938
+ // mtherr( "Jv", DOMAIN );
939
+ // y = 0.0;
940
+ y = nan((uint)22);
941
+ goto done;
942
+ }
943
+
944
+ y = fabs(x);
945
+
946
+ if( y < DBL_EPSILON )
947
+ goto underf;
948
+
949
+ k = 3.6 * sqrt(y);
950
+ t = 3.6 * sqrt(an);
951
+ if( (y < t) && (an > 21.0) )
952
+ return( sign * bessel_jvs(n,x) );
953
+ if( (an < k) && (y > 21.0) )
954
+ return( sign * bessel_hankel(n,x) );
955
+
956
+ if( an < 500.0 )
957
+ {
958
+ /* Note: if x is too large, the continued
959
+ * fraction will fail; but then the
960
+ * Hankel expansion can be used.
961
+ */
962
+ if( nint != 0 )
963
+ {
964
+ k = 0.0;
965
+ q = bessel_recur( &n, x, &k, 1 );
966
+ if( k == 0.0 )
967
+ {
968
+ y = bessel_j0(x)/q;
969
+ goto done;
970
+ }
971
+ if( k == 1.0 )
972
+ {
973
+ y = bessel_j1(x)/q;
974
+ goto done;
975
+ }
976
+ }
977
+
978
+ if( an > 2.0 * y )
979
+ goto rlarger;
980
+
981
+ if( (n >= 0.0) && (n < 20.0)
982
+ && (y > 6.0) && (y < 20.0) )
983
+ {
984
+ /* Recur backwards from a larger value of n
985
+ */
986
+ rlarger:
987
+ k = n;
988
+
989
+ y = y + an + 1.0;
990
+ if( y < 30.0 )
991
+ y = 30.0;
992
+ y = n + floor(y-n);
993
+ q = bessel_recur( &y, x, &k, 0 );
994
+ y = bessel_jvs(y,x) * q;
995
+ goto done;
996
+ }
997
+
998
+ if( k <= 30.0 )
999
+ {
1000
+ k = 2.0;
1001
+ }
1002
+ else if( k < 90.0 )
1003
+ {
1004
+ k = (3*k)/4;
1005
+ }
1006
+ if( an > (k + 3.0) )
1007
+ {
1008
+ if( n < 0.0 )
1009
+ k = -k;
1010
+ q = n - floor(n);
1011
+ k = floor(k) + q;
1012
+ if( n > 0.0 )
1013
+ q = bessel_recur( &n, x, &k, 1 );
1014
+ else
1015
+ {
1016
+ t = k;
1017
+ k = n;
1018
+ q = bessel_recur( &t, x, &k, 1 );
1019
+ k = t;
1020
+ }
1021
+ if( q == 0.0 )
1022
+ {
1023
+ underf:
1024
+ y = 0.0;
1025
+ goto done;
1026
+ }
1027
+ }
1028
+ else
1029
+ {
1030
+ k = n;
1031
+ q = 1.0;
1032
+ }
1033
+
1034
+ /* boundary between convergence of
1035
+ * power series and Hankel expansion
1036
+ */
1037
+ y = fabs(k);
1038
+ if( y < 26.0 )
1039
+ t = (0.0083*y + 0.09)*y + 12.9;
1040
+ else
1041
+ t = 0.9 * y;
1042
+
1043
+ if( x > t )
1044
+ y = bessel_hankel(k,x);
1045
+ else
1046
+ y = bessel_jvs(k,x);
1047
+ #if DEBUG
1048
+ printf( "y = %.16e, recur q = %.16e\n", y, q );
1049
+ #endif
1050
+ if( n > 0.0 )
1051
+ y /= q;
1052
+ else
1053
+ y *= q;
1054
+ }
1055
+
1056
+ else
1057
+ {
1058
+ /* For large n, use the uniform expansion
1059
+ * or the transitional expansion.
1060
+ * But if x is of the order of n**2,
1061
+ * these may blow up, whereas the
1062
+ * Hankel expansion will then work.
1063
+ */
1064
+ if( n < 0.0 )
1065
+ {
1066
+ //mtherr( "Jv", TLOSS );
1067
+ //y = 0.0;
1068
+ y = nan((uint)23);
1069
+ goto done;
1070
+ }
1071
+ t = x/n;
1072
+ t /= n;
1073
+ if( t > 0.3 )
1074
+ y = bessel_hankel(n,x);
1075
+ else
1076
+ y = bessel_jnx(n,x);
1077
+ }
1078
+
1079
+ done: return( sign * y);
1080
+ }
1081
+
1082
+ // }}}
1083
+
1084
+ // vim: fdm=marker