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