mirror of
https://github.com/vale981/arb
synced 2025-03-05 17:31:38 -05:00
623 lines
29 KiB
ReStructuredText
623 lines
29 KiB
ReStructuredText
.. _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_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)
|
|
|
|
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
|
|
|