File: arb_fpwrap.rst

package info (click to toggle)
flint 3.4.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 68,996 kB
  • sloc: ansic: 915,350; asm: 14,605; python: 5,340; sh: 4,512; lisp: 2,621; makefile: 787; cpp: 341
file content (631 lines) | stat: -rw-r--r-- 30,473 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
.. _arb_fpwrap:

**arb_fpwrap.h** -- floating-point wrappers of Arb mathematical functions
=========================================================================================

This module provides wrappers of Arb functions intended users who
want accurate floating-point mathematical functions
without necessarily caring about ball arithmetic.
The wrappers take floating-point input, give floating-point output,
and automatically increase the internal working precision
to ensure that the output is accurate
(in the rare case of failure, they output NaN along with an error code).

**Warning:** This module is experimental (as of Arb 2.21). It has not
been extensively tested, and interfaces may change in the future.

Supported types:

* ``double`` and ``complex_double`` (53-bit precision)

Limitations:

* The wrappers currently only handle finite input and points where function
  value is finite. For example,
  they do not know that `\log(0) = -\infty` or that `\exp(-\infty) = 0`.
  Singular input or output result in ``FPWRAP_UNABLE`` and a NaN output value.
  Evaluation of limit values may be implemented in the future for some functions.
* The wrappers currently treat ``-0.0`` as ``+0.0``. Users who need to
  distinguish signs of zero, e.g. on branch cuts, currently need to do so
  manually.
* When requesting *correct rounding*, the wrappers can fail to converge
  in asymptotic or exact cases (where special algorithms are required).
* If the value is computed accurately internally but is too small to represent
  as a floating-point number, the result will be ``-0.0`` or ``+0.0`` (on underflow)
  or ``-Inf`` or ``+Inf`` (on overflow). Since the underflowed or overflowed
  result is the best possible floating-point approximation of the true value,
  this outcome is considered correct and the flag ``FPWRAP_SUCCESS`` is returned.
  In the future, return status flags may be added to indicate that underflow
  or overflow has occurred.
* Different rounding modes are not yet implemented.

Option and return flags
-------------------------------------------------------------------------------

Functions return an ``int`` flag indicating the status.

.. macro:: FPWRAP_SUCCESS

    Indicates an accurate result. (Up to inevitable underflow or
    overflow in the final conversion to a floating-point result; see above.)

    This flag has the numerical value 0.

.. macro:: FPWRAP_UNABLE

    Indicates failure (unable to achieve to target accuracy,
    possibly because of a singularity). The output is set to NaN.

    This flag has the numerical value 1.

Functions take a *flags* parameter specifying optional rounding and termination
behavior. This can be set to 0 to use defaults.

.. macro:: FPWRAP_ACCURATE_PARTS

    For complex output, compute both real and imaginary parts to full relative accuracy.
    By default (if this flag is not set), complex results are computed to
    at least 53-bit accuracy as a whole, but if either the real or imaginary
    part is much smaller than the other, that part can have a large relative error.
    Setting this flag can result in slower evaluation or failure to converge
    in some cases.

    This flag has the numerical value 1.

.. macro:: FPWRAP_CORRECT_ROUNDING

    Guarantees *correct rounding*.
    By default (if this flag is not set), real results are accurate up to the
    rounding of the last bit, but the last bit is not guaranteed to
    be rounded optimally.
    Setting this flag can result in slower
    evaluation or failure to converge in some cases.
    Correct rounding automatically applies to both real and imaginary parts
    of complex numbers, so it is unnecessary to set both this flag and
    *FPWRAP_ACCURATE_PARTS*.

    This flag has the numerical value 2.

.. macro:: FPWRAP_WORK_LIMIT

    Multiplied by an integer, specifies the maximum working precision to use
    before giving up. With ``n * FPWRAP_WORK_LIMIT`` added to *flags*,
    `n` levels of precision will be used.
    The default `n = 0` is equivalent to `n = 8`, which for ``double``
    means trying with a working precision of 64, 128, 256, 512, 1024, 2048,
    4096, 8192 bits.
    With ``flags = 2 * FPWRAP_WORK_LIMIT``, we only try 64 and 128
    bits, and with ``flags = 16 * FPWRAP_WORK_LIMIT`` we
    go up to 2097152 bits.

    This flag has the numerical value 65536.

Types
-------------------------------------------------------------------------------

Outputs are passed by reference so that we can return status
flags and so that the interface is uniform for functions with
multiple outputs.

.. type:: complex_double

    A struct of two ``double`` components (``real`` and ``imag``), used to
    represent a machine-precision complex number. We use this custom type
    instead of the complex types defined in ``<complex.h>`` since Arb
    does not depend on C99. Users should easily be able to convert
    to the C99 complex type since the layout in memory is identical.

Functions
-------------------------------------------------------------------------------

Elementary functions
...............................................................................

.. function:: int arb_fpwrap_double_exp(double * res, double x, int flags)
              int arb_fpwrap_cdouble_exp(complex_double * res, complex_double x, int flags)

.. function:: int arb_fpwrap_double_expm1(double * res, double x, int flags)
              int arb_fpwrap_cdouble_expm1(complex_double * res, complex_double x, int flags)

.. function:: int arb_fpwrap_double_log(double * res, double x, int flags)
              int arb_fpwrap_cdouble_log(complex_double * res, complex_double x, int flags)

.. function:: int arb_fpwrap_double_log1p(double * res, double x, int flags)
              int arb_fpwrap_cdouble_log1p(complex_double * res, complex_double x, int flags)

.. function:: int arb_fpwrap_double_pow(double * res, double x, double y, int flags)
              int arb_fpwrap_cdouble_pow(complex_double * res, complex_double x, complex_double y, int flags)

.. function:: int arb_fpwrap_double_sqrt(double * res, double x, int flags)
              int arb_fpwrap_cdouble_sqrt(complex_double * res, complex_double x, int flags)

.. function:: int arb_fpwrap_double_rsqrt(double * res, double x, int flags)
              int arb_fpwrap_cdouble_rsqrt(complex_double * res, complex_double x, int flags)

.. function:: int arb_fpwrap_double_cbrt(double * res, double x, int flags)
              int arb_fpwrap_cdouble_cbrt(complex_double * res, complex_double x, int flags)

.. function:: int arb_fpwrap_double_sin(double * res, double x, int flags)
              int arb_fpwrap_cdouble_sin(complex_double * res, complex_double x, int flags)

.. function:: int arb_fpwrap_double_cos(double * res, double x, int flags)
              int arb_fpwrap_cdouble_cos(complex_double * res, complex_double x, int flags)

.. function:: int arb_fpwrap_double_tan(double * res, double x, int flags)
              int arb_fpwrap_cdouble_tan(complex_double * res, complex_double x, int flags)

.. function:: int arb_fpwrap_double_cot(double * res, double x, int flags)
              int arb_fpwrap_cdouble_cot(complex_double * res, complex_double x, int flags)

.. function:: int arb_fpwrap_double_sec(double * res, double x, int flags)
              int arb_fpwrap_cdouble_sec(complex_double * res, complex_double x, int flags)

.. function:: int arb_fpwrap_double_csc(double * res, double x, int flags)
              int arb_fpwrap_cdouble_csc(complex_double * res, complex_double x, int flags)

.. function:: int arb_fpwrap_double_sinc(double * res, double x, int flags)
              int arb_fpwrap_cdouble_sinc(complex_double * res, complex_double x, int flags)

.. function:: int arb_fpwrap_double_sin_pi(double * res, double x, int flags)
              int arb_fpwrap_cdouble_sin_pi(complex_double * res, complex_double x, int flags)

.. function:: int arb_fpwrap_double_cos_pi(double * res, double x, int flags)
              int arb_fpwrap_cdouble_cos_pi(complex_double * res, complex_double x, int flags)

.. function:: int arb_fpwrap_double_tan_pi(double * res, double x, int flags)
              int arb_fpwrap_cdouble_tan_pi(complex_double * res, complex_double x, int flags)

.. function:: int arb_fpwrap_double_cot_pi(double * res, double x, int flags)
              int arb_fpwrap_cdouble_cot_pi(complex_double * res, complex_double x, int flags)

.. function:: int arb_fpwrap_double_sinc_pi(double * res, double x, int flags)
              int arb_fpwrap_cdouble_sinc_pi(complex_double * res, complex_double x, int flags)

.. function:: int arb_fpwrap_double_asin(double * res, double x, int flags)
              int arb_fpwrap_cdouble_asin(complex_double * res, complex_double x, int flags)

.. function:: int arb_fpwrap_double_acos(double * res, double x, int flags)
              int arb_fpwrap_cdouble_acos(complex_double * res, complex_double x, int flags)

.. function:: int arb_fpwrap_double_atan(double * res, double x, int flags)
              int arb_fpwrap_cdouble_atan(complex_double * res, complex_double x, int flags)

.. function:: int arb_fpwrap_double_atan2(double * res, double x1, double x2, int flags)

.. function:: int arb_fpwrap_double_asinh(double * res, double x, int flags)
              int arb_fpwrap_cdouble_asinh(complex_double * res, complex_double x, int flags)

.. function:: int arb_fpwrap_double_acosh(double * res, double x, int flags)
              int arb_fpwrap_cdouble_acosh(complex_double * res, complex_double x, int flags)

.. function:: int arb_fpwrap_double_atanh(double * res, double x, int flags)
              int arb_fpwrap_cdouble_atanh(complex_double * res, complex_double x, int flags)

.. function:: int arb_fpwrap_double_lambertw(double * res, double x, slong branch, int flags)
              int arb_fpwrap_cdouble_lambertw(complex_double * res, complex_double x, slong branch, int flags)

Gamma, zeta and related functions
...............................................................................

.. function:: int arb_fpwrap_double_rising(double * res, double x, double n, int flags)
              int arb_fpwrap_cdouble_rising(complex_double * res, complex_double x, complex_double n, int flags)

    Rising factorial.

.. function:: int arb_fpwrap_double_gamma(double * res, double x, int flags)
              int arb_fpwrap_cdouble_gamma(complex_double * res, complex_double x, int flags)

    Gamma function.

.. function:: int arb_fpwrap_double_rgamma(double * res, double x, int flags)
              int arb_fpwrap_cdouble_rgamma(complex_double * res, complex_double x, int flags)

    Reciprocal gamma function.

.. function:: int arb_fpwrap_double_lgamma(double * res, double x, int flags)
              int arb_fpwrap_cdouble_lgamma(complex_double * res, complex_double x, int flags)

    Log-gamma function.

.. function:: int arb_fpwrap_double_digamma(double * res, double x, int flags)
              int arb_fpwrap_cdouble_digamma(complex_double * res, complex_double x, int flags)

    Digamma function.

.. function:: int arb_fpwrap_double_zeta(double * res, double x, int flags)
              int arb_fpwrap_cdouble_zeta(complex_double * res, complex_double x, int flags)

    Riemann zeta function.

.. function:: int arb_fpwrap_double_hurwitz_zeta(double * res, double s, double z, int flags)
              int arb_fpwrap_cdouble_hurwitz_zeta(complex_double * res, complex_double s, complex_double z, int flags)

    Hurwitz zeta function.

.. function:: int arb_fpwrap_double_lerch_phi(double * res, double z, double s, double a, int flags)
              int arb_fpwrap_cdouble_lerch_phi(complex_double * res, complex_double z, complex_double s, complex_double a, int flags)

    Lerch transcendent.

.. function:: int arb_fpwrap_double_barnes_g(double * res, double x, int flags)
              int arb_fpwrap_cdouble_barnes_g(complex_double * res, complex_double x, int flags)

    Barnes G-function.

.. function:: int arb_fpwrap_double_log_barnes_g(double * res, double x, int flags)
              int arb_fpwrap_cdouble_log_barnes_g(complex_double * res, complex_double x, int flags)

    Logarithmic Barnes G-function.

.. function:: int arb_fpwrap_double_polygamma(double * res, double s, double z, int flags)
              int arb_fpwrap_cdouble_polygamma(complex_double * res, complex_double s, complex_double z, int flags)

    Polygamma function.

.. function:: int arb_fpwrap_double_polylog(double * res, double s, double z, int flags)
              int arb_fpwrap_cdouble_polylog(complex_double * res, complex_double s, complex_double z, int flags)

    Polylogarithm.

.. function:: int arb_fpwrap_cdouble_dirichlet_eta(complex_double * res, complex_double s, int flags)

.. function:: int arb_fpwrap_cdouble_riemann_xi(complex_double * res, complex_double s, int flags)

.. function:: int arb_fpwrap_cdouble_hardy_theta(complex_double * res, complex_double z, int flags)

.. function:: int arb_fpwrap_cdouble_hardy_z(complex_double * res, complex_double z, int flags)

.. function:: int arb_fpwrap_cdouble_zeta_zero(complex_double * res, ulong n, int flags)

Error functions and exponential integrals
...............................................................................

.. function:: int arb_fpwrap_double_erf(double * res, double x, int flags)
              int arb_fpwrap_cdouble_erf(complex_double * res, complex_double x, int flags)

.. function:: int arb_fpwrap_double_erfc(double * res, double x, int flags)
              int arb_fpwrap_cdouble_erfc(complex_double * res, complex_double x, int flags)

.. function:: int arb_fpwrap_double_erfi(double * res, double x, int flags)
              int arb_fpwrap_cdouble_erfi(complex_double * res, complex_double x, int flags)

.. function:: int arb_fpwrap_double_erfinv(double * res, double x, int flags)
.. function:: int arb_fpwrap_double_erfcinv(double * res, double x, int flags)

.. function:: int arb_fpwrap_double_fresnel_s(double * res, double x, int normalized, int flags)
              int arb_fpwrap_cdouble_fresnel_s(complex_double * res, complex_double x, int normalized, int flags)

.. function:: int arb_fpwrap_double_fresnel_c(double * res, double x, int normalized, int flags)
              int arb_fpwrap_cdouble_fresnel_c(complex_double * res, complex_double x, int normalized, int flags)

.. function:: int arb_fpwrap_double_gamma_upper(double * res, double s, double z, int regularized, int flags)
              int arb_fpwrap_cdouble_gamma_upper(complex_double * res, complex_double s, complex_double z, int regularized, int flags)

.. function:: int arb_fpwrap_double_gamma_lower(double * res, double s, double z, int regularized, int flags)
              int arb_fpwrap_cdouble_gamma_lower(complex_double * res, complex_double s, complex_double z, int regularized, int flags)

.. function:: int arb_fpwrap_double_beta_lower(double * res, double a, double b, double z, int regularized, int flags)
              int arb_fpwrap_cdouble_beta_lower(complex_double * res, complex_double a, complex_double b, complex_double z, int regularized, int flags)

.. function:: int arb_fpwrap_double_exp_integral_e(double * res, double s, double z, int flags)
              int arb_fpwrap_cdouble_exp_integral_e(complex_double * res, complex_double s, complex_double z, int flags)

.. function:: int arb_fpwrap_double_exp_integral_ei(double * res, double x, int flags)
              int arb_fpwrap_cdouble_exp_integral_ei(complex_double * res, complex_double x, int flags)

.. function:: int arb_fpwrap_double_sin_integral(double * res, double x, int flags)
              int arb_fpwrap_cdouble_sin_integral(complex_double * res, complex_double x, int flags)

.. function:: int arb_fpwrap_double_cos_integral(double * res, double x, int flags)
              int arb_fpwrap_cdouble_cos_integral(complex_double * res, complex_double x, int flags)

.. function:: int arb_fpwrap_double_sinh_integral(double * res, double x, int flags)
              int arb_fpwrap_cdouble_sinh_integral(complex_double * res, complex_double x, int flags)

.. function:: int arb_fpwrap_double_cosh_integral(double * res, double x, int flags)
              int arb_fpwrap_cdouble_cosh_integral(complex_double * res, complex_double x, int flags)

.. function:: int arb_fpwrap_double_log_integral(double * res, double x, int offset, int flags)
              int arb_fpwrap_cdouble_log_integral(complex_double * res, complex_double x, int offset, int flags)

.. function:: int arb_fpwrap_double_dilog(double * res, double x, int flags)
              int arb_fpwrap_cdouble_dilog(complex_double * res, complex_double x, int flags)

Bessel, Airy and Coulomb functions
...............................................................................

.. function:: int arb_fpwrap_double_bessel_j(double * res, double nu, double x, int flags)
              int arb_fpwrap_cdouble_bessel_j(complex_double * res, complex_double nu, complex_double x, int flags)

.. function:: int arb_fpwrap_double_bessel_y(double * res, double nu, double x, int flags)
              int arb_fpwrap_cdouble_bessel_y(complex_double * res, complex_double nu, complex_double x, int flags)

.. function:: int arb_fpwrap_double_bessel_i(double * res, double nu, double x, int flags)
              int arb_fpwrap_cdouble_bessel_i(complex_double * res, complex_double nu, complex_double x, int flags)

.. function:: int arb_fpwrap_double_bessel_k(double * res, double nu, double x, int flags)
              int arb_fpwrap_cdouble_bessel_k(complex_double * res, complex_double nu, complex_double x, int flags)

.. function:: int arb_fpwrap_double_bessel_k_scaled(double * res, double nu, double x, int flags)
              int arb_fpwrap_cdouble_bessel_k_scaled(complex_double * res, complex_double nu, complex_double x, int flags)

.. function:: int arb_fpwrap_double_airy_ai(double * res, double x, int flags)
              int arb_fpwrap_cdouble_airy_ai(complex_double * res, complex_double x, int flags)

.. function:: int arb_fpwrap_double_airy_ai_prime(double * res, double x, int flags)
              int arb_fpwrap_cdouble_airy_ai_prime(complex_double * res, complex_double x, int flags)

.. function:: int arb_fpwrap_double_airy_bi(double * res, double x, int flags)
              int arb_fpwrap_cdouble_airy_bi(complex_double * res, complex_double x, int flags)

.. function:: int arb_fpwrap_double_airy_bi_prime(double * res, double x, int flags)
              int arb_fpwrap_cdouble_airy_bi_prime(complex_double * res, complex_double x, int flags)

.. function:: int arb_fpwrap_double_airy_ai_zero(double * res, ulong n, int flags)

.. function:: int arb_fpwrap_double_airy_ai_prime_zero(double * res, ulong n, int flags)

.. function:: int arb_fpwrap_double_airy_bi_zero(double * res, ulong n, int flags)

.. function:: int arb_fpwrap_double_airy_bi_prime_zero(double * res, ulong n, int flags)

.. function:: int arb_fpwrap_double_coulomb_f(double * res, double l, double eta, double x, int flags)
              int arb_fpwrap_cdouble_coulomb_f(complex_double * res, complex_double l, complex_double eta, complex_double x, int flags)

.. function:: int arb_fpwrap_double_coulomb_g(double * res, double l, double eta, double x, int flags)
              int arb_fpwrap_cdouble_coulomb_g(complex_double * res, complex_double l, complex_double eta, complex_double x, int flags)

.. function:: int arb_fpwrap_cdouble_coulomb_hpos(complex_double * res, complex_double l, complex_double eta, complex_double x, int flags)
              int arb_fpwrap_cdouble_coulomb_hneg(complex_double * res, complex_double l, complex_double eta, complex_double x, int flags)

Orthogonal polynomials
...............................................................................

.. function:: int arb_fpwrap_double_chebyshev_t(double * res, double n, double x, int flags)
              int arb_fpwrap_cdouble_chebyshev_t(complex_double * res, complex_double n, complex_double x, int flags)

.. function:: int arb_fpwrap_double_chebyshev_u(double * res, double n, double x, int flags)
              int arb_fpwrap_cdouble_chebyshev_u(complex_double * res, complex_double n, complex_double x, int flags)

.. function:: int arb_fpwrap_double_jacobi_p(double * res, double n, double a, double b, double x, int flags)
              int arb_fpwrap_cdouble_jacobi_p(complex_double * res, complex_double n, complex_double a, complex_double b, complex_double x, int flags)

.. function:: int arb_fpwrap_double_gegenbauer_c(double * res, double n, double m, double x, int flags)
              int arb_fpwrap_cdouble_gegenbauer_c(complex_double * res, complex_double n, complex_double m, complex_double x, int flags)

.. function:: int arb_fpwrap_double_laguerre_l(double * res, double n, double m, double x, int flags)
              int arb_fpwrap_cdouble_laguerre_l(complex_double * res, complex_double n, complex_double m, complex_double x, int flags)

.. function:: int arb_fpwrap_double_hermite_h(double * res, double n, double x, int flags)
              int arb_fpwrap_cdouble_hermite_h(complex_double * res, complex_double n, complex_double x, int flags)

.. function:: int arb_fpwrap_double_legendre_p(double * res, double n, double m, double x, int type, int flags)
              int arb_fpwrap_cdouble_legendre_p(complex_double * res, complex_double n, complex_double m, complex_double x, int type, int flags)

.. function:: int arb_fpwrap_double_legendre_q(double * res, double n, double m, double x, int type, int flags)
              int arb_fpwrap_cdouble_legendre_q(complex_double * res, complex_double n, complex_double m, complex_double x, int type, int flags)

.. function:: int arb_fpwrap_double_legendre_root(double * res1, double * res2, ulong n, ulong k, int flags)

    Sets *res1* to the index *k* root of the Legendre polynomial `P_n(x)`,
    and simultaneously sets *res2* to the corresponding weight for
    Gauss-Legendre quadrature.

.. function:: int arb_fpwrap_cdouble_spherical_y(complex_double * res, slong n, slong m, complex_double x1, complex_double x2, int flags)

Hypergeometric functions
...............................................................................

.. function:: int arb_fpwrap_double_hypgeom_0f1(double * res, double a, double x, int regularized, int flags)
              int arb_fpwrap_cdouble_hypgeom_0f1(complex_double * res, complex_double a, complex_double x, int regularized, int flags)

.. function:: int arb_fpwrap_double_hypgeom_1f1(double * res, double a, double b, double x, int regularized, int flags)
              int arb_fpwrap_cdouble_hypgeom_1f1(complex_double * res, complex_double a, complex_double b, complex_double x, int regularized, int flags)

.. function:: int arb_fpwrap_double_hypgeom_u(double * res, double a, double b, double x, int flags)
              int arb_fpwrap_cdouble_hypgeom_u(complex_double * res, complex_double a, complex_double b, complex_double x, int flags)

.. function:: int arb_fpwrap_double_hypgeom_2f1(double * res, double a, double b, double c, double x, int regularized, int flags)
              int arb_fpwrap_cdouble_hypgeom_2f1(complex_double * res, complex_double a, complex_double b, complex_double c, complex_double x, int regularized, int flags)

.. function:: int arb_fpwrap_double_hypgeom_pfq(double * res, const double * a, slong p, const double * b, slong q, double z, int regularized, int flags)
              int arb_fpwrap_cdouble_hypgeom_pfq(complex_double * res, const complex_double * a, slong p, const complex_double * b, slong q, complex_double z, int regularized, int flags)


Elliptic integrals, elliptic functions and modular forms
...............................................................................

.. function:: int arb_fpwrap_double_agm(double * res, double x, double y, int flags)
              int arb_fpwrap_cdouble_agm(complex_double * res, complex_double x, complex_double y, int flags)

    Arithmetic-geometric mean.

.. function:: int arb_fpwrap_cdouble_elliptic_k(complex_double * res, complex_double m, int flags)

.. function:: int arb_fpwrap_cdouble_elliptic_e(complex_double * res, complex_double m, int flags)

.. function:: int arb_fpwrap_cdouble_elliptic_pi(complex_double * res, complex_double n, complex_double m, int flags)

.. function:: int arb_fpwrap_cdouble_elliptic_f(complex_double * res, complex_double phi, complex_double m, int pi, int flags)

.. function:: int arb_fpwrap_cdouble_elliptic_e_inc(complex_double * res, complex_double phi, complex_double m, int pi, int flags)

.. function:: int arb_fpwrap_cdouble_elliptic_pi_inc(complex_double * res, complex_double n, complex_double phi, complex_double m, int pi, int flags)

    Complete and incomplete elliptic integrals.

.. function:: int arb_fpwrap_cdouble_elliptic_rf(complex_double * res, complex_double x, complex_double y, complex_double z, int option, int flags)

.. function:: int arb_fpwrap_cdouble_elliptic_rg(complex_double * res, complex_double x, complex_double y, complex_double z, int option, int flags)

.. function:: int arb_fpwrap_cdouble_elliptic_rj(complex_double * res, complex_double x, complex_double y, complex_double z, complex_double w, int option, int flags)

    Carlson symmetric elliptic integrals.

.. function:: int arb_fpwrap_cdouble_elliptic_p(complex_double * res, complex_double z, complex_double tau, int flags)

.. function:: int arb_fpwrap_cdouble_elliptic_p_prime(complex_double * res, complex_double z, complex_double tau, int flags)

.. function:: int arb_fpwrap_cdouble_elliptic_inv_p(complex_double * res, complex_double z, complex_double tau, int flags)

.. function:: int arb_fpwrap_cdouble_elliptic_zeta(complex_double * res, complex_double z, complex_double tau, int flags)

.. function:: int arb_fpwrap_cdouble_elliptic_sigma(complex_double * res, complex_double z, complex_double tau, int flags)

    Weierstrass elliptic functions.

.. function:: int arb_fpwrap_cdouble_jacobi_theta_1(complex_double * res, complex_double z, complex_double tau, int flags)

.. function:: int arb_fpwrap_cdouble_jacobi_theta_2(complex_double * res, complex_double z, complex_double tau, int flags)

.. function:: int arb_fpwrap_cdouble_jacobi_theta_3(complex_double * res, complex_double z, complex_double tau, int flags)

.. function:: int arb_fpwrap_cdouble_jacobi_theta_4(complex_double * res, complex_double z, complex_double tau, int flags)

    Jacobi theta functions.

.. function:: int arb_fpwrap_cdouble_dedekind_eta(complex_double * res, complex_double tau, int flags)

.. function:: int arb_fpwrap_cdouble_modular_j(complex_double * res, complex_double tau, int flags)

.. function:: int arb_fpwrap_cdouble_modular_lambda(complex_double * res, complex_double tau, int flags)

.. function:: int arb_fpwrap_cdouble_modular_delta(complex_double * res, complex_double tau, int flags)

Calling from C
-------------------------------------------------------------------------------

The program ``examples/fpwrap.c`` provides a usage example::

    #include "arb_fpwrap.h"

    int main()
    {
        double x, y;
        complex_double cx, cy;
        int flags = 0;    /* default options */

        x = 2.0;
        cx.real = 0.5;
        cx.imag = 123.0;

        arb_fpwrap_double_zeta(&y, x, flags);
        arb_fpwrap_cdouble_zeta(&cy, cx, flags);

        printf("zeta(%g) = %.16g\n", x, y);
        printf("zeta(%g + %gi) = %.16g + %.16gi\n", cx.real, cx.imag, cy.real, cy.imag);

        flint_cleanup();
        return 0;
    }

.. highlight:: text

This should print::

    > build/examples/fpwrap 
    zeta(2) = 1.644934066848226
    zeta(0.5 + 123i) = 0.006252861175594465 + 0.08206030514520983i

Note that this program does not check the return flag
to perform error handling.


Interfacing from Python
-------------------------------------------------------------------------------

.. highlight:: python

This illustrates how to call functions from Python using ``ctypes``::

    import ctypes
    import ctypes.util

    libarb_path = ctypes.util.find_library('arb')
    libarb = ctypes.CDLL(libarb_path)

    class _complex_double(ctypes.Structure):
        _fields_ = [('real', ctypes.c_double),
                    ('imag', ctypes.c_double)]

    def wrap_double_fun(fun):
        def f(x):
            y = ctypes.c_double()
            if fun(ctypes.byref(y), ctypes.c_double(x), 0):
                raise ValueError(f"unable to evaluate function accurately at {x}")
            return y.value
        return f

    def wrap_cdouble_fun(fun):
        def f(x):
            x = complex(x)
            cx = _complex_double()
            cy = _complex_double()
            cx.real = x.real
            cx.imag = x.imag
            if fun(ctypes.byref(cy), cx, 0):
                raise ValueError(f"unable to evaluate function accurately at {x}")
            return complex(cy.real, cy.imag)
        return f

    zeta = wrap_double_fun(libarb.arb_fpwrap_double_zeta)
    czeta = wrap_cdouble_fun(libarb.arb_fpwrap_cdouble_zeta)

    print(zeta(2.0))
    print(czeta(0.5+1e9j))
    print(zeta(1.0))       # pole, where wrapper throws exception

.. highlight:: text

This should print::

    1.6449340668482264
    (-2.761748029838061-1.6775122409894598j)
    Traceback (most recent call last):
      ...
    ValueError: unable to evaluate function accurately at 1.0

Interfacing from Julia
-------------------------------------------------------------------------------

.. highlight:: julia

This illustrates how to call functions from Julia using ``ccall``::

    using Libdl

    dlopen("/home/fredrik/src/arb/libarb.so")

    function zeta(x::Float64)
        cy = Ref{Float64}()
        if Bool(ccall((:arb_fpwrap_double_zeta, :libarb), Cint, (Ptr{Float64}, Float64, Cint), cy, x, 0))
            error("unable to evaluate accurately at ", x)
        end
        return cy[]
    end

    function zeta(x::Complex{Float64})
        cy = Ref{Complex{Float64}}()
        if Bool(ccall((:arb_fpwrap_cdouble_zeta, :libarb), Cint, (Ptr{Complex{Float64}}, Complex{Float64}, Cint), cy, x, 0))
            error("unable to evaluate accurately at ", x)
        end
        return cy[]
    end

    println(zeta(2.0))
    println(zeta(0.5 + 1e9im))
    println(zeta(1.0))       # pole, where wrapper throws exception

.. highlight:: text

This should print::

    1.6449340668482264
    -2.761748029838061 - 1.6775122409894598im
    ERROR: unable to evaluate accurately at 1.0
    Stacktrace:
     ...


.. highlight:: c