1 /*
2     Copyright (C) 2021 Fredrik Johansson
3 
4     This file is part of Arb.
5 
6     Arb is free software: you can redistribute it and/or modify it under
7     the terms of the GNU Lesser General Public License (LGPL) as published
8     by the Free Software Foundation; either version 2.1 of the License, or
9     (at your option) any later version.  See <http://www.gnu.org/licenses/>.
10 */
11 
12 #include "arb_hypgeom.h"
13 #include "hypgeom.h"
14 
15 void
arb_gamma_const_1_3_eval(arb_t s,slong prec)16 arb_gamma_const_1_3_eval(arb_t s, slong prec)
17 {
18     hypgeom_t series;
19     arb_t t, u;
20     slong wp = prec + 4 + 2 * FLINT_BIT_COUNT(prec);
21 
22     arb_init(t);
23     arb_init(u);
24 
25     hypgeom_init(series);
26 
27     fmpz_poly_set_str(series->A, "1  1");
28     fmpz_poly_set_str(series->B, "1  1");
29     fmpz_poly_set_str(series->P, "4  5 -46 108 -72");
30     fmpz_poly_set_str(series->Q, "4  0 0 0 512000");
31 
32     prec += FLINT_CLOG2(prec);
33 
34     arb_hypgeom_infsum(s, t, series, wp, wp);
35 
36     arb_sqrt_ui(u, 10, wp);
37     arb_mul(t, t, u, wp);
38 
39     arb_const_pi(u, wp);
40     arb_pow_ui(u, u, 4, wp);
41     arb_mul_ui(u, u, 12, wp);
42     arb_mul(s, s, u, wp);
43 
44     arb_div(s, s, t, wp);
45     arb_root_ui(s, s, 2, wp);
46     arb_root_ui(s, s, 3, prec);
47 
48     hypgeom_clear(series);
49     arb_clear(t);
50     arb_clear(u);
51 }
52 
ARB_DEF_CACHED_CONSTANT(arb_gamma_const_1_3,arb_gamma_const_1_3_eval)53 ARB_DEF_CACHED_CONSTANT(arb_gamma_const_1_3, arb_gamma_const_1_3_eval)
54 
55 void
56 arb_gamma_const_1_4_eval(arb_t x, slong prec)
57 {
58     arb_t t, u;
59     slong wp = prec + 4 + 2 * FLINT_BIT_COUNT(prec);
60 
61     arb_init(t);
62     arb_init(u);
63 
64     arb_one(t);
65     arb_sqrt_ui(u, 2, wp);
66     arb_agm(x, t, u, wp);
67 
68     arb_const_pi(t, wp);
69     arb_mul_2exp_si(t, t, 1);
70     arb_sqrt(u, t, wp);
71     arb_mul(u, u, t, wp);
72 
73     arb_div(x, u, x, wp);
74     arb_sqrt(x, x, wp);
75 
76     arb_clear(t);
77     arb_clear(u);
78 }
79 
80 ARB_DEF_CACHED_CONSTANT(arb_gamma_const_1_4, arb_gamma_const_1_4_eval)
81 
82 
83 void arb_hypgeom_gamma_stirling_choose_param(int * reflect, slong * r, slong * n, const arb_t x, int use_reflect, int digamma, slong prec);
84 void arb_hypgeom_gamma_stirling_inner(arb_t s, const arb_t z, slong N, slong prec);
85 
86 void
arb_hypgeom_gamma_fmpq_stirling(arb_t y,const fmpq_t a,slong prec)87 arb_hypgeom_gamma_fmpq_stirling(arb_t y, const fmpq_t a, slong prec)
88 {
89     int reflect;
90     slong r, n, wp;
91     arb_t x, t, u, v;
92 
93     wp = prec + FLINT_BIT_COUNT(prec);
94 
95     arb_init(x);
96     arb_init(t);
97     arb_init(u);
98     arb_init(v);
99 
100     arb_set_fmpq(x, a, wp);
101     arb_hypgeom_gamma_stirling_choose_param(&reflect, &r, &n, x, 1, 0, wp);
102 
103     if (reflect)
104     {
105         /* gamma(x) = (rf(1-x, r) * pi) / (gamma(1-x+r) sin(pi x)) */
106         fmpq_t b;
107         fmpq_init(b);
108         fmpz_sub(fmpq_numref(b), fmpq_denref(a), fmpq_numref(a));
109         fmpz_set(fmpq_denref(b), fmpq_denref(a));
110         arb_rising_fmpq_ui(u, b, r, wp);
111         fmpq_clear(b);
112         arb_const_pi(v, wp);
113         arb_mul(u, u, v, wp);
114         arb_sub_ui(t, x, 1, wp);
115         arb_neg(t, t);
116         arb_add_ui(t, t, r, wp);
117         arb_hypgeom_gamma_stirling_inner(v, t, n, wp);
118         arb_exp(v, v, wp);
119         arb_sin_pi_fmpq(t, a, wp);
120         arb_mul(v, v, t, wp);
121     }
122     else
123     {
124         /* gamma(x) = gamma(x+r) / rf(x,r) */
125         arb_add_ui(t, x, r, wp);
126         arb_hypgeom_gamma_stirling_inner(u, t, n, wp);
127         arb_exp(u, u, prec);
128         arb_rising_fmpq_ui(v, a, r, wp);
129     }
130 
131     arb_div(y, u, v, prec);
132 
133     arb_clear(t);
134     arb_clear(u);
135     arb_clear(v);
136     arb_clear(x);
137 }
138 
139 void
arb_hypgeom_gamma_small_frac(arb_t y,unsigned int p,unsigned int q,slong prec)140 arb_hypgeom_gamma_small_frac(arb_t y, unsigned int p, unsigned int q, slong prec)
141 {
142     slong wp = prec + 4;
143 
144     if (q == 1)
145     {
146         arb_one(y);
147     }
148     else if (q == 2)  /* p = 1 */
149     {
150         arb_const_sqrt_pi(y, prec);
151     }
152     else if (q == 3)
153     {
154         if (p == 1)
155         {
156             arb_gamma_const_1_3(y, prec);
157         }
158         else  /* p = 2 */
159         {
160             arb_t t;
161             arb_init(t);
162             arb_gamma_const_1_3(y, wp);
163             arb_sqrt_ui(t, 3, wp);
164             arb_mul(y, y, t, wp);
165             arb_const_pi(t, wp);
166             arb_div(y, t, y, prec);
167             arb_mul_2exp_si(y, y, 1);
168             arb_clear(t);
169         }
170     }
171     else if (q == 4)
172     {
173         if (p == 1)
174         {
175             arb_gamma_const_1_4(y, prec);
176         }
177         else  /* p = 3 */
178         {
179             arb_t t;
180             arb_init(t);
181             arb_sqrt_ui(y, 2, wp);
182             arb_const_pi(t, wp);
183             arb_mul(y, y, t, wp);
184             arb_gamma_const_1_4(t, wp);
185             arb_div(y, y, t, prec);
186             arb_clear(t);
187         }
188     }
189     else if (q == 6)
190     {
191         arb_t t;
192         arb_init(t);
193         arb_const_pi(t, wp);
194         arb_div_ui(t, t, 3, wp);
195         arb_sqrt(t, t, wp);
196         arb_set_ui(y, 2);
197         arb_root_ui(y, y, 3, wp);
198         arb_mul(t, t, y, wp);
199         arb_gamma_const_1_3(y, wp);
200         arb_mul(y, y, y, prec);
201 
202         if (p == 1)
203         {
204             arb_div(y, y, t, prec);
205         }
206         else  /* p = 5 */
207         {
208             arb_div(y, t, y, wp);
209             arb_const_pi(t, wp);
210             arb_mul(y, y, t, prec);
211             arb_mul_2exp_si(y, y, 1);
212         }
213 
214         arb_clear(t);
215     }
216     else
217     {
218         flint_printf("small fraction not implemented!\n");
219         flint_abort();
220     }
221 }
222 
223 slong _arb_compute_bs_exponents(slong * tab, slong n);
224 slong _arb_get_exp_pos(const slong * tab, slong step);
225 
226 static void
bsplit2(arb_t P,arb_t Q,const fmpz_t zp,const fmpz_t zq,const slong * xexp,arb_srcptr xpow,ulong N,slong a,slong b,int cont,slong prec)227 bsplit2(arb_t P, arb_t Q, const fmpz_t zp, const fmpz_t zq,
228     const slong * xexp, arb_srcptr xpow,
229     ulong N, slong a, slong b, int cont, slong prec)
230 {
231     if (b - a == 1)
232     {
233         fmpz_t t;
234         fmpz_init(t);
235         fmpz_set(t, zp);
236         fmpz_addmul_ui(t, zq, a + 1);
237         arb_set_fmpz(P, t);
238         arb_set(Q, P);
239         fmpz_clear(t);
240     }
241     else
242     {
243         arb_t Pb, Qb;
244         slong step, i, m;
245 
246         arb_init(Pb);
247         arb_init(Qb);
248 
249         step = (b - a) / 2;
250         m = a + step;
251 
252         bsplit2(P, Q, zp, zq, xexp, xpow, N, a, m, 1, prec);
253         bsplit2(Pb, Qb, zp, zq, xexp, xpow, N, m, b, 1, prec);
254 
255         arb_mul(P, P, Pb, prec);
256         arb_mul(Q, Q, Pb, prec);
257 
258         i = (step == 1) ? 0 : _arb_get_exp_pos(xexp, step);
259         arb_addmul(Q, Qb, xpow + i, prec);
260 
261         arb_clear(Pb);
262         arb_clear(Qb);
263     }
264 }
265 
266 static void
bsplit3(arb_t P,arb_t Q,const fmpz_t zp,const fmpz_t zq,const slong * xexp,arb_srcptr xpow,ulong N,slong a,slong b,int cont,slong prec)267 bsplit3(arb_t P, arb_t Q, const fmpz_t zp, const fmpz_t zq,
268     const slong * xexp, arb_srcptr xpow,
269     ulong N, slong a, slong b, int cont, slong prec)
270 {
271     if (b - a == 1)
272     {
273         fmpz_t t;
274         fmpz_init(t);
275         arb_set(P, xpow + 0);  /* N zq */
276         fmpz_set(t, zp);
277         fmpz_submul_ui(t, zq, a + 1);  /* zp - (a + 1) zq */
278         arb_set_fmpz(Q, t);
279         fmpz_clear(t);
280     }
281     else
282     {
283         arb_t Pb, Qb;
284         slong step, i, m;
285 
286         arb_init(Pb);
287         arb_init(Qb);
288 
289         step = (b - a) / 2;
290         m = a + step;
291 
292         bsplit3(P, Q, zp, zq, xexp, xpow, N, a, m, 1, prec);
293         bsplit3(Pb, Qb, zp, zq, xexp, xpow, N, m, b, 1, prec);
294 
295         i = _arb_get_exp_pos(xexp, m - a);
296 
297         arb_mul(P, P, xpow + i, prec);
298         if (b - m != m - a)
299             arb_mul(P, P, xpow + 0, prec);
300 
301         arb_addmul(P, Q, Pb, prec);
302 
303         if (cont)
304         {
305             arb_mul(Q, Q, Qb, prec);
306         }
307         else
308         {
309             i = _arb_get_exp_pos(xexp, m - a);
310 
311             arb_mul(Q, xpow + i, xpow + i, prec);
312             if (b - m != m - a)
313                 arb_mul(Q, Q, xpow + 0, prec);
314         }
315 
316         arb_clear(Pb);
317         arb_clear(Qb);
318     }
319 }
320 
321 double d_lambertw_branch1(double x);
322 
323 static ulong
more_trailing_zeros(ulong N)324 more_trailing_zeros(ulong N)
325 {
326     ulong bc, N2;
327 
328     bc = FLINT_BIT_COUNT(N);
329 
330     if (bc >= 8)
331     {
332         N2 = (N >> (bc - 5)) << (bc - 5);
333         N2 += ((N2 != N) << (bc - 5));
334         return N2;
335     }
336     else
337     {
338         return N;
339     }
340 }
341 
342 #define C_LOG2 0.69314718055994530942
343 #define C_EXP1 2.7182818284590452354
344 
345 static void
build_bsplit_power_table(arb_ptr xpow,const slong * xexp,slong len,slong prec)346 build_bsplit_power_table(arb_ptr xpow, const slong * xexp, slong len, slong prec)
347 {
348     slong i;
349 
350     for (i = 1; i < len; i++)
351     {
352         if (xexp[i] == 2 * xexp[i-1])
353         {
354             arb_mul(xpow + i, xpow + i - 1, xpow + i - 1, prec);
355         }
356         else if (xexp[i] == 2 * xexp[i-2]) /* prefer squaring if possible */
357         {
358             arb_mul(xpow + i, xpow + i - 2, xpow + i - 2, prec);
359         }
360         else if (xexp[i] == 2 * xexp[i-1] + 1)
361         {
362             arb_mul(xpow + i, xpow + i - 1, xpow + i - 1, prec);
363             arb_mul(xpow + i, xpow + i, xpow, prec);
364         }
365         else if (xexp[i] == 2 * xexp[i-2] + 1)
366         {
367             arb_mul(xpow + i, xpow + i - 2, xpow + i - 2, prec);
368             arb_mul(xpow + i, xpow + i, xpow, prec);
369         }
370         else
371         {
372             flint_printf("power table has the wrong structure!\n");
373             flint_abort();
374         }
375     }
376 }
377 
378 /* assumes z in [1, 2] */
379 static void
arb_hypgeom_gamma_fmpq_general_off1(arb_t res,const fmpq_t z,slong prec)380 arb_hypgeom_gamma_fmpq_general_off1(arb_t res, const fmpq_t z, slong prec)
381 {
382     slong wp, N, n, n2, length, length2, wp2;
383     double alpha;
384     arb_t P, Q;
385     slong *xexp, *xexp2;
386     arb_ptr xpow;
387     mag_t err, err2;
388 
389     wp = prec + 30;
390 
391     alpha = 0.52;  /* tuning parameter between 0.5 and 1 */
392 
393     N = alpha * C_LOG2 * wp;
394     N = more_trailing_zeros(N);
395     alpha = N / (C_LOG2 * wp);
396 
397     /* Terms in convergent series */
398     n = (1 - alpha) / d_lambertw((1 - alpha) / (alpha * C_EXP1)) * C_LOG2 * wp;
399 
400     /* Precision and terms in asymptotic series */
401     wp2 = wp * (1 - alpha);
402     wp2 = FLINT_MAX(wp2, 30);
403     n2 = (alpha - 1) / d_lambertw_branch1((alpha - 1) / (alpha * C_EXP1)) * C_LOG2 * wp;
404     n2 = FLINT_MAX(n2, 2);  /* binary splitting correctness */
405 
406     mag_init(err);
407     mag_init(err2);
408     arb_init(P);
409     arb_init(Q);
410 
411     /* compute the powers of x = N*zq that will appear (at least x^1) */
412     xexp = flint_calloc(2 * FLINT_BITS, sizeof(slong));
413     xexp2 = flint_calloc(2 * FLINT_BITS, sizeof(slong));
414 
415     length = _arb_compute_bs_exponents(xexp, n);
416     length2 = _arb_compute_bs_exponents(xexp2, n2);
417 
418     xpow = _arb_vec_init(FLINT_MAX(length, length2));
419 
420     arb_set_fmpz(xpow + 0, fmpq_denref(z));
421     arb_mul_ui(xpow + 0, xpow + 0, N, wp);
422 
423     build_bsplit_power_table(xpow, xexp, length, wp);
424 
425     /* 1F1(1, 1+z, N) */
426     bsplit2(P, Q, fmpq_numref(z), fmpq_denref(z), xexp, xpow, N, 0, n, 0, wp);
427     arb_div(P, Q, P, wp);
428 
429     /* Convergent series error bound: N^n / n! (1 + (N/n) + ...) */
430     mag_set_ui(err, N);
431     mag_pow_ui(err, err, n);
432     mag_rfac_ui(err2, n);
433     mag_mul(err, err, err2);
434     mag_set_ui(err2, N);
435     mag_div_ui(err2, err2, n);
436     mag_geom_series(err2, err2, 0);
437     mag_mul(err, err, err2);
438     arb_add_error_mag(P, err);
439 
440     /* divide 1F1 by z */
441     arb_mul_fmpz(P, P, fmpq_denref(z), wp);
442     arb_div_fmpz(P, P, fmpq_numref(z), wp);
443     arb_swap(res, P);
444 
445     build_bsplit_power_table(xpow, xexp2, length2, wp2);
446 
447     bsplit3(P, Q, fmpq_numref(z), fmpq_denref(z), xexp2, xpow, N, 0, n2, 0, wp2);
448     arb_div(P, P, Q, wp2);
449 
450     /* 2F0 error bound (bounded by first omitted term) */
451     mag_fac_ui(err, n2);
452     mag_set_ui_lower(err2, N);
453     mag_pow_ui_lower(err2, err2, n2);
454     mag_div(err, err, err2);
455     arb_add_error_mag(P, err);
456 
457     /* N^z * exp(-N) * (1F1/z + 2F0/N)  */
458     arb_div_ui(P, P, N, wp2);
459 
460     arb_add(res, res, P, wp);
461     arb_set_ui(Q, N);
462     arb_pow_fmpq(Q, Q, z, wp);
463     arb_mul(res, res, Q, wp);
464 
465     arb_set_si(Q, -N);
466     arb_exp(Q, Q, wp);
467     arb_mul(res, res, Q, wp);
468 
469     _arb_vec_clear(xpow, FLINT_MAX(length, length2));
470     flint_free(xexp);
471     flint_free(xexp2);
472 
473     arb_clear(P);
474     arb_clear(Q);
475     mag_clear(err);
476     mag_clear(err2);
477 }
478 
479 /* assumes z in (0, 1] */
480 void
arb_hypgeom_gamma_fmpq_hyp(arb_t res,const fmpq_t z,slong prec)481 arb_hypgeom_gamma_fmpq_hyp(arb_t res, const fmpq_t z, slong prec)
482 {
483     fmpq_t t;
484     fmpq_init(t);
485     fmpq_add_ui(t, z, 1);
486     arb_hypgeom_gamma_fmpq_general_off1(res, t, prec);
487     arb_mul_fmpz(res, res, fmpq_denref(z), prec + 30);
488     arb_div_fmpz(res, res, fmpq_numref(z), prec);
489     fmpq_clear(t);
490 }
491 
492 void
arb_hypgeom_gamma_fmpq_outward(arb_t y,const fmpq_t x,slong prec)493 arb_hypgeom_gamma_fmpq_outward(arb_t y, const fmpq_t x, slong prec)
494 {
495     fmpq_t a;
496     fmpz_t n;
497     fmpz p, q;
498     slong m;
499     arb_t t, u;
500 
501     fmpq_init(a);
502     fmpz_init(n);
503     arb_init(t);
504     arb_init(u);
505 
506     /* write x = a + n with 0 < a <= 1 */
507     if (fmpz_is_one(fmpq_denref(x)))
508     {
509         fmpq_one(a);
510         fmpz_sub_ui(n, fmpq_numref(x), 1);
511     }
512     else
513     {
514         fmpz_fdiv_qr(n, fmpq_numref(a), fmpq_numref(x), fmpq_denref(x));
515         fmpz_set(fmpq_denref(a), fmpq_denref(x));
516     }
517 
518     if (!fmpz_fits_si(n))
519     {
520         flint_printf("gamma: too large fmpq to reduce to 0!\n");
521         flint_abort();
522     }
523 
524     m = fmpz_get_si(n);
525 
526     /* evaluate gamma(a) */
527     p = *fmpq_numref(a);
528     q = *fmpq_denref(a);
529 
530     if (q == 1 || q == 2 || q == 3 || q == 4 || q == 6)
531     {
532         arb_hypgeom_gamma_small_frac(t, p, q, prec + 4 * (m != 0));
533     }
534     else
535     {
536         arb_hypgeom_gamma_fmpq_hyp(t, a, prec + 4 * (m != 0));
537     }
538 
539     /* argument reduction */
540     if (m >= 0)
541     {
542         arb_rising_fmpq_ui(u, a, m, prec + 4);
543         arb_mul(y, t, u, prec);
544     }
545     else
546     {
547         arb_rising_fmpq_ui(u, x, -m, prec + 4);
548         arb_div(y, t, u, prec);
549     }
550 
551     fmpq_clear(a);
552     fmpz_clear(n);
553     arb_clear(t);
554     arb_clear(u);
555 }
556 
557 int
arb_hypgeom_gamma_fmpq_taylor(arb_t y,const fmpq_t x,slong prec)558 arb_hypgeom_gamma_fmpq_taylor(arb_t y, const fmpq_t x, slong prec)
559 {
560     fmpq_t a;
561     fmpz_t n;
562     slong m;
563     arb_t t;
564     int success;
565 
566     fmpq_init(a);
567     fmpz_init(n);
568     arb_init(t);
569 
570     success = 1;
571 
572     /* write x = a + n with 0 < a <= 1 */
573     if (fmpz_is_one(fmpq_denref(x)))
574     {
575         fmpq_one(a);
576         fmpz_sub_ui(n, fmpq_numref(x), 1);
577     }
578     else
579     {
580         fmpz_fdiv_qr(n, fmpq_numref(a), fmpq_numref(x), fmpq_denref(x));
581         fmpz_set(fmpq_denref(a), fmpq_denref(x));
582     }
583 
584     if (!fmpz_fits_si(n))
585     {
586         success = 0;
587         goto cleanup;
588     }
589 
590     m = fmpz_get_si(n);
591 
592     if (m < -(40 + (prec - 40) / 4))
593     {
594         success = 0;
595         goto cleanup;
596     }
597 
598     if (m > 70 + (prec - 40) / 8)
599     {
600         success = 0;
601         goto cleanup;
602     }
603 
604     arb_set_fmpq(t, a, prec + 4);
605     success = arb_hypgeom_gamma_taylor(t, t, 0, prec + 4);
606 
607     if (success)
608     {
609         arb_t u;
610         arb_init(u);
611 
612         if (m >= 0)
613         {
614             arb_rising_fmpq_ui(u, a, m, prec + 4);
615             arb_mul(y, t, u, prec);
616         }
617         else
618         {
619             arb_rising_fmpq_ui(u, x, -m, prec + 4);
620             arb_div(y, t, u, prec);
621         }
622 
623         arb_clear(u);
624     }
625 
626 cleanup:
627     fmpq_clear(a);
628     fmpz_clear(n);
629     arb_clear(t);
630 
631     return success;
632 }
633 
634 void
arb_hypgeom_gamma_fmpq(arb_t y,const fmpq_t x,slong prec)635 arb_hypgeom_gamma_fmpq(arb_t y, const fmpq_t x, slong prec)
636 {
637     fmpz p, q;
638 
639     p = *fmpq_numref(x);
640     q = *fmpq_denref(x);
641 
642     if ((q == 1 || q == 2 || q == 3 || q == 4 || q == 6) && !COEFF_IS_MPZ(p))
643     {
644         if (q == 1)
645         {
646             if (p <= 0)
647             {
648                 arb_indeterminate(y);
649                 return;
650             }
651 
652             if (p < 1200 || 1.44265 * (p*log(p) - p) < 15.0 * prec)
653             {
654                 fmpz_t t;
655                 fmpz_init(t);
656                 fmpz_fac_ui(t, p - 1);
657                 arb_set_round_fmpz(y, t, prec);
658                 fmpz_clear(t);
659                 return;
660             }
661         }
662 
663         p = FLINT_ABS(p);
664 
665         if (p < q * 500.0 || p < q * (500.0 + 0.1 * prec * sqrt(prec)))
666         {
667             arb_hypgeom_gamma_fmpq_outward(y, x, prec);
668             return;
669         }
670     }
671 
672     if (q != 1 && prec > 7000 + 300 * fmpz_bits(fmpq_denref(x)) &&
673         (slong) fmpz_bits(fmpq_numref(x)) - (slong) fmpz_bits(fmpq_denref(x)) < FLINT_BITS &&
674         fabs(fmpq_get_d(x)) < 0.03 * prec * sqrt(prec))
675     {
676         arb_hypgeom_gamma_fmpq_outward(y, x, prec);
677         return;
678     }
679 
680     if (fmpz_bits(fmpq_denref(x)) > 0.1 * prec || fmpz_bits(fmpq_numref(x)) > 0.1 * prec)
681     {
682         slong wp;
683 
684         wp = (slong) fmpz_bits(fmpq_numref(x)) - (slong) fmpz_bits(fmpq_denref(x));
685         wp = FLINT_MAX(wp, 0);
686         wp = FLINT_MIN(wp, 4 * prec);
687         wp += prec + 4;
688 
689         arb_set_fmpq(y, x, wp);
690 
691         if (!arb_hypgeom_gamma_taylor(y, y, 0, prec))
692             arb_hypgeom_gamma_stirling(y, y, 0, prec);
693 
694         return;
695     }
696 
697     if (arb_hypgeom_gamma_fmpq_taylor(y, x, prec))
698         return;
699 
700     arb_hypgeom_gamma_fmpq_stirling(y, x, prec);
701 }
702 
703 void
arb_hypgeom_gamma_fmpz(arb_t y,const fmpz_t x,slong prec)704 arb_hypgeom_gamma_fmpz(arb_t y, const fmpz_t x, slong prec)
705 {
706     fmpq_t t;
707     *fmpq_numref(t) = *x;
708     *fmpq_denref(t) = WORD(1);
709     arb_hypgeom_gamma_fmpq(y, t, prec);
710 }
711 
712