diff --git a/acb.h b/acb.h index 9886f18d..3524eac2 100644 --- a/acb.h +++ b/acb.h @@ -754,6 +754,7 @@ void acb_rising_ui_bs(acb_t y, const acb_t x, ulong n, long prec); void acb_rising_ui_rs(acb_t y, const acb_t x, ulong n, ulong m, long prec); void acb_rising_ui_rec(acb_t y, const acb_t x, ulong n, long prec); void acb_rising_ui(acb_t z, const acb_t x, ulong n, long prec); +void acb_rising(acb_t z, const acb_t x, const acb_t n, long prec); void acb_rising2_ui_bs(acb_t u, acb_t v, const acb_t x, ulong n, long prec); void acb_rising2_ui_rs(acb_t u, acb_t v, const acb_t x, ulong n, ulong m, long prec); diff --git a/acb/rising_ui.c b/acb/rising_ui.c index 6cc41421..b6a04eb8 100644 --- a/acb/rising_ui.c +++ b/acb/rising_ui.c @@ -28,6 +28,40 @@ void acb_rising_ui(acb_t y, const acb_t x, ulong n, long prec) { - acb_rising_ui_rec(y, x, n, prec); + if (n < FLINT_MAX(prec, 100)) + { + acb_rising_ui_rec(y, x, n, prec); + } + else + { + acb_t t; + acb_init(t); + acb_add_ui(t, x, n, prec); + acb_gamma(t, t, prec); + acb_rgamma(y, x, prec); + acb_mul(y, y, t, prec); + acb_clear(t); + } +} + +void +acb_rising(acb_t y, const acb_t x, const acb_t n, long prec) +{ + if (acb_is_int(n) && arf_sgn(arb_midref(acb_realref(n))) >= 0 && + arf_cmpabs_ui(arb_midref(acb_realref(n)), FLINT_MAX(prec, 100)) < 0) + { + acb_rising_ui_rec(y, x, + arf_get_si(arb_midref(acb_realref(n)), ARF_RND_DOWN), prec); + } + else + { + acb_t t; + acb_init(t); + acb_add(t, x, n, prec); + acb_gamma(t, t, prec); + acb_rgamma(y, x, prec); + acb_mul(y, y, t, prec); + acb_clear(t); + } } diff --git a/arb.h b/arb.h index de2fdd9c..dcc02ef8 100644 --- a/arb.h +++ b/arb.h @@ -644,6 +644,7 @@ void arb_rising_ui_rs(arb_t y, const arb_t x, ulong n, ulong m, long prec); void arb_rising_ui_rec(arb_t y, const arb_t x, ulong n, long prec); void arb_rising_ui(arb_t z, const arb_t x, ulong n, long prec); void arb_rising_fmpq_ui(arb_t y, const fmpq_t x, ulong n, long prec); +void arb_rising(arb_t z, const arb_t x, const arb_t n, long prec); void arb_rising2_ui_rs(arb_t u, arb_t v, const arb_t x, ulong n, ulong m, long prec); void arb_rising2_ui_bs(arb_t u, arb_t v, const arb_t x, ulong n, long prec); diff --git a/arb/rising_ui.c b/arb/rising_ui.c index ea355747..dbe24920 100644 --- a/arb/rising_ui.c +++ b/arb/rising_ui.c @@ -28,6 +28,40 @@ void arb_rising_ui(arb_t y, const arb_t x, ulong n, long prec) { - arb_rising_ui_rec(y, x, n, prec); + if (n < FLINT_MAX(prec, 100)) + { + arb_rising_ui_rec(y, x, n, prec); + } + else + { + arb_t t; + arb_init(t); + arb_add_ui(t, x, n, prec); + arb_gamma(t, t, prec); + arb_rgamma(y, x, prec); + arb_mul(y, y, t, prec); + arb_clear(t); + } +} + +void +arb_rising(arb_t y, const arb_t x, const arb_t n, long prec) +{ + if (arb_is_int(n) && arf_sgn(arb_midref(n)) >= 0 && + arf_cmpabs_ui(arb_midref(n), FLINT_MAX(prec, 100)) < 0) + { + arb_rising_ui_rec(y, x, + arf_get_si(arb_midref(n), ARF_RND_DOWN), prec); + } + else + { + arb_t t; + arb_init(t); + arb_add(t, x, n, prec); + arb_gamma(t, t, prec); + arb_rgamma(y, x, prec); + arb_mul(y, y, t, prec); + arb_clear(t); + } } diff --git a/doc/source/acb.rst b/doc/source/acb.rst index 05541768..7eecfe0d 100644 --- a/doc/source/acb.rst +++ b/doc/source/acb.rst @@ -570,14 +570,14 @@ Rising factorials .. function:: void acb_rising_ui(acb_t z, const acb_t x, ulong n, long prec) +.. function:: void acb_rising(acb_t z, const acb_t x, const acb_t n, long prec) + Computes the rising factorial `z = x (x+1) (x+2) \cdots (x+n-1)`. The *bs* version uses binary splitting. The *rs* version uses rectangular splitting. The *rec* version uses either *bs* or *rs* depending - on the input. - The default version is currently identical to the *rec* version. - In a future version, it will use the gamma function or asymptotic - series when this is more efficient. + on the input. The default version uses the gamma function unless + *n* is a small integer. The *rs* version takes an optional *step* parameter for tuning purposes (to use the default step length, pass zero). diff --git a/doc/source/arb.rst b/doc/source/arb.rst index d52a8b52..f1313e0d 100644 --- a/doc/source/arb.rst +++ b/doc/source/arb.rst @@ -985,14 +985,14 @@ Gamma function and factorials .. function:: void arb_rising_ui(arb_t z, const arb_t x, ulong n, long prec) +.. function:: void arb_rising(arb_t z, const arb_t x, const arb_t n, long prec) + Computes the rising factorial `z = x (x+1) (x+2) \cdots (x+n-1)`. The *bs* version uses binary splitting. The *rs* version uses rectangular splitting. The *rec* version uses either *bs* or *rs* depending - on the input. - The default version is currently identical to the *rec* version. - In a future version, it will use the gamma function or asymptotic - series when this is more efficient. + on the input. The default version uses the gamma function unless + *n* is a small integer. The *rs* version takes an optional *step* parameter for tuning purposes (to use the default step length, pass zero).