allow computing Bessel J and Y simultaneously

This commit is contained in:
Fredrik Johansson 2015-11-28 05:12:44 +01:00
parent 57c1a7fed8
commit d9eb026ae0
4 changed files with 47 additions and 16 deletions

View file

@ -108,6 +108,7 @@ void acb_hypgeom_bessel_k_asymp(acb_t res, const acb_t nu, const acb_t z, slong
void acb_hypgeom_bessel_k(acb_t res, const acb_t nu, const acb_t z, slong prec);
void acb_hypgeom_bessel_y(acb_t res, const acb_t nu, const acb_t z, slong prec);
void acb_hypgeom_bessel_jy(acb_t res1, acb_t res2, const acb_t nu, const acb_t z, slong prec);
void acb_hypgeom_0f1_asymp(acb_t res, const acb_t a, const acb_t z, int regularized, slong prec);
void acb_hypgeom_0f1_direct(acb_t res, const acb_t a, const acb_t z, int regularized, slong prec);

View file

@ -47,14 +47,17 @@ phase(acb_t res, const arb_t re, const arb_t im)
}
void
acb_hypgeom_bessel_y(acb_t res, const acb_t nu, const acb_t z, slong prec)
acb_hypgeom_bessel_jy(acb_t res1, acb_t res2, const acb_t nu, const acb_t z, slong prec)
{
acb_t t, u, v;
acb_t jnu, t, u, v;
acb_init(jnu);
acb_init(t);
acb_init(u);
acb_init(v);
acb_hypgeom_bessel_j(jnu, nu, z, prec);
if (acb_is_int(nu))
{
int is_real = acb_is_real(nu) && acb_is_real(z)
@ -70,32 +73,37 @@ acb_hypgeom_bessel_y(acb_t res, const acb_t nu, const acb_t z, slong prec)
acb_mul_2exp_si(t, t, 1);
acb_neg(t, t);
acb_hypgeom_bessel_j(u, nu, z, prec);
phase(v, acb_realref(z), acb_imagref(z));
acb_mul(u, u, v, prec);
acb_mul(u, jnu, v, prec);
acb_mul_onei(u, u);
acb_sub(res, t, u, prec);
acb_sub(res2, t, u, prec);
if (is_real)
arb_zero(acb_imagref(res));
arb_zero(acb_imagref(res2));
}
else
{
acb_sin_cos_pi(t, u, nu, prec);
acb_hypgeom_bessel_j(v, nu, z, prec);
acb_mul(v, v, u, prec);
acb_mul(v, jnu, u, prec);
acb_neg(u, nu);
acb_hypgeom_bessel_j(u, u, z, prec);
acb_sub(v, v, u, prec);
acb_div(res, v, t, prec);
acb_div(res2, v, t, prec);
}
if (res1 != NULL)
acb_set(res1, jnu);
acb_clear(jnu);
acb_clear(t);
acb_clear(u);
acb_clear(v);
}
void
acb_hypgeom_bessel_y(acb_t res, const acb_t nu, const acb_t z, slong prec)
{
acb_hypgeom_bessel_jy(NULL, res, nu, z, prec);
}

View file

@ -60,10 +60,25 @@ int main()
acb_add_ui(nu1, nu, 1, prec);
acb_hypgeom_bessel_j(jv, nu, z, prec);
acb_hypgeom_bessel_j(jv1, nu1, z, prec);
acb_hypgeom_bessel_y(yv, nu, z, prec);
acb_hypgeom_bessel_y(yv1, nu1, z, prec);
if (n_randint(state, 2))
{
acb_hypgeom_bessel_j(jv, nu, z, prec);
acb_hypgeom_bessel_y(yv, nu, z, prec);
}
else
{
acb_hypgeom_bessel_jy(jv, yv, nu, z, prec);
}
if (n_randint(state, 2))
{
acb_hypgeom_bessel_j(jv1, nu1, z, prec);
acb_hypgeom_bessel_y(yv1, nu1, z, prec);
}
else
{
acb_hypgeom_bessel_jy(jv1, yv1, nu1, z, prec);
}
acb_mul(r, jv1, yv, prec);
acb_submul(r, jv, yv1, prec);

View file

@ -400,6 +400,13 @@ Bessel functions
As currently implemented, the output is indeterminate if `\nu` is nonexact
and contains an integer.
.. function:: void acb_hypgeom_bessel_jy(acb_t res1, acb_t res2, const acb_t nu, const acb_t z, slong prec)
Sets *res1* to `J_{\nu}(z)` and *res2* to `Y_{\nu}(z)`, computed
simultaneously. From these values, the user can easily
construct the Bessel functions of the third kind (Hankel functions)
`H_{\nu}^{(1)}(z), H_{\nu}^{(2)}(z) = J_{\nu}(z) \pm i Y_{\nu}(z)`.
.. function:: void acb_hypgeom_bessel_i_asymp(acb_t res, const acb_t nu, const acb_t z, slong prec)
.. function:: void acb_hypgeom_bessel_i_0f1(acb_t res, const acb_t nu, const acb_t z, slong prec)