mirror of
https://github.com/vale981/arb
synced 2025-03-05 09:21:38 -05:00
173 lines
4.2 KiB
C
173 lines
4.2 KiB
C
/*
|
|
Copyright (C) 2021 Fredrik Johansson
|
|
|
|
This file is part of Arb.
|
|
|
|
Arb is free software: you can redistribute it and/or modify it under
|
|
the terms of the GNU Lesser General Public License (LGPL) as published
|
|
by the Free Software Foundation; either version 2.1 of the License, or
|
|
(at your option) any later version. See <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "arb_hypgeom.h"
|
|
|
|
void
|
|
arb_hypgeom_rising_ui_jet_rs(arb_ptr res, const arb_t x, ulong n, ulong m, slong len, slong prec)
|
|
{
|
|
slong i, j, k, l, m0, xmlen, tlen, ulen, climbs, climbs_max, wp;
|
|
arb_ptr tmp, xpow;
|
|
arb_ptr t, u;
|
|
mp_ptr c;
|
|
TMP_INIT;
|
|
|
|
if (len == 0)
|
|
return;
|
|
|
|
if (len > n + 1)
|
|
{
|
|
_arb_vec_zero(res + n + 1, len - n - 1);
|
|
len = n + 1;
|
|
}
|
|
|
|
if (len == n + 1)
|
|
{
|
|
arb_one(res + n);
|
|
len = n;
|
|
}
|
|
|
|
if (n <= 1)
|
|
{
|
|
if (n == 1)
|
|
arb_set_round(res, x, prec);
|
|
return;
|
|
}
|
|
|
|
if (len == 1)
|
|
{
|
|
arb_hypgeom_rising_ui_rs(res, x, n, m, prec);
|
|
return;
|
|
}
|
|
|
|
TMP_START;
|
|
|
|
if (m == 0)
|
|
{
|
|
if (n <= 7)
|
|
m = n;
|
|
else if (n <= 12)
|
|
m = (n + 1) / 2;
|
|
else if (n <= 32)
|
|
m = (n + 2) / 3;
|
|
else
|
|
{
|
|
m0 = n_sqrt(n);
|
|
m = 8 + 0.5 * pow(prec, 0.4);
|
|
m = FLINT_MIN(m, m0);
|
|
m = FLINT_MIN(m, 64);
|
|
}
|
|
}
|
|
|
|
wp = ARF_PREC_ADD(prec, FLINT_BIT_COUNT(n));
|
|
|
|
climbs_max = FLINT_BIT_COUNT(n - 1) * m;
|
|
c = TMP_ALLOC(sizeof(mp_limb_t) * climbs_max * m);
|
|
|
|
/* length of (x+t)^m */
|
|
xmlen = FLINT_MIN(len, m + 1);
|
|
|
|
tmp = _arb_vec_init(2 * len + (m + 1) * xmlen);
|
|
t = tmp;
|
|
u = tmp + len;
|
|
xpow = tmp + 2 * len;
|
|
|
|
_arb_vec_set_powers(xpow, x, m + 1, wp);
|
|
|
|
tlen = 1;
|
|
|
|
/* First derivatives */
|
|
for (i = 1; i <= m; i++)
|
|
arb_mul_ui(xpow + (m + 1) + i, xpow + i - 1, i, wp);
|
|
|
|
/* Higher derivatives if we need them */
|
|
if (len >= 3)
|
|
{
|
|
fmpz * f = _fmpz_vec_init(len);
|
|
|
|
fmpz_one(f + 0);
|
|
fmpz_one(f + 1);
|
|
|
|
for (i = 2; i <= m; i++)
|
|
{
|
|
for (j = FLINT_MIN(xmlen - 1, i + 1); j >= 1; j--)
|
|
fmpz_add(f + j, f + j, f + j - 1);
|
|
|
|
for (j = 2; j < FLINT_MIN(xmlen, i + 1); j++)
|
|
arb_mul_fmpz(xpow + (m + 1) * j + i, xpow + i - j, f + j, wp);
|
|
}
|
|
|
|
_fmpz_vec_clear(f, len);
|
|
}
|
|
|
|
for (k = 0; k < n; k += m)
|
|
{
|
|
l = FLINT_MIN(m, n - k);
|
|
climbs = FLINT_BIT_COUNT(k + l - 1) * l;
|
|
climbs = (climbs + FLINT_BITS - 1) / FLINT_BITS;
|
|
|
|
ulen = FLINT_MIN(len, l + 1);
|
|
|
|
if (l == 1)
|
|
{
|
|
arb_add_ui(u, x, k, wp);
|
|
arb_one(u + 1);
|
|
}
|
|
else
|
|
{
|
|
if (climbs == 1)
|
|
{
|
|
_arb_hypgeom_rising_coeffs_1(c, k, l);
|
|
for (j = 0; j < ulen; j++)
|
|
arb_dot_ui(u + j, xpow + (m + 1) * j + l, 0, xpow + (m + 1) * j + j, 1, c + j, 1, l - j, wp);
|
|
}
|
|
else if (climbs == 2)
|
|
{
|
|
_arb_hypgeom_rising_coeffs_2(c, k, l);
|
|
for (j = 0; j < ulen; j++)
|
|
arb_dot_uiui(u + j, xpow + (m + 1) * j + l, 0, xpow + (m + 1) * j + j, 1, c + 2 * j, 1, l - j, wp);
|
|
}
|
|
else
|
|
{
|
|
fmpz * f = (fmpz *) c;
|
|
|
|
for (i = 0; i < l; i++)
|
|
fmpz_init(f + i);
|
|
|
|
_arb_hypgeom_rising_coeffs_fmpz(f, k, l);
|
|
|
|
for (j = 0; j < ulen; j++)
|
|
arb_dot_fmpz(u + j, xpow + (m + 1) * j + l, 0, xpow + (m + 1) * j + j, 1, f + j, 1, l - j, wp);
|
|
|
|
for (i = 0; i < l; i++)
|
|
fmpz_clear(f + i);
|
|
}
|
|
}
|
|
|
|
if (k == 0)
|
|
{
|
|
tlen = ulen;
|
|
_arb_vec_swap(t, u, ulen);
|
|
}
|
|
else
|
|
{
|
|
_arb_poly_mullow(res, t, tlen, u, ulen, FLINT_MIN(len, tlen + ulen - 1), wp);
|
|
tlen = FLINT_MIN(len, tlen + ulen - 1);
|
|
_arb_vec_swap(t, res, tlen);
|
|
}
|
|
}
|
|
|
|
_arb_vec_set_round(res, t, len, prec);
|
|
|
|
_arb_vec_clear(tmp, 2 * len + (m + 1) * xmlen);
|
|
TMP_END;
|
|
}
|
|
|