mirror of
https://github.com/vale981/arb
synced 2025-03-04 17:01:40 -05:00
multithreaded euler numbers
This commit is contained in:
parent
8b2c1704f0
commit
196f3f7f3c
2 changed files with 43 additions and 55 deletions
|
@ -417,57 +417,34 @@ divisor_table_odd(unsigned int * tab, slong len)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
ulong n;
|
||||||
|
const unsigned int * divtab;
|
||||||
|
mp_ptr primes;
|
||||||
|
mp_ptr residues;
|
||||||
|
}
|
||||||
|
mod_p_param_t;
|
||||||
|
|
||||||
|
static void
|
||||||
|
mod_p_worker(slong i, void * param)
|
||||||
|
{
|
||||||
|
mod_p_param_t * p = (mod_p_param_t *) param;
|
||||||
|
|
||||||
|
p->residues[i] = euler_mod_p_powsum(p->n, p->primes[i], p->divtab);
|
||||||
|
}
|
||||||
|
|
||||||
#define TIMING 0
|
#define TIMING 0
|
||||||
#define DEBUG 0
|
#define DEBUG 0
|
||||||
|
|
||||||
static void
|
/* todo: optimize basecase and move to flint */
|
||||||
_fmpz_crt_combine(fmpz_t r1r2, fmpz_t m1m2, const fmpz_t r1, const fmpz_t m1, const fmpz_t r2, const fmpz_t m2)
|
void
|
||||||
{
|
_arb_tree_crt(fmpz_t r, fmpz_t m, mp_srcptr residues, mp_srcptr primes, slong len);
|
||||||
fmpz_invmod(m1m2, m1, m2);
|
|
||||||
fmpz_mul(m1m2, m1m2, m1);
|
|
||||||
fmpz_sub(r1r2, r2, r1);
|
|
||||||
fmpz_mul(r1r2, r1r2, m1m2);
|
|
||||||
fmpz_add(r1r2, r1r2, r1);
|
|
||||||
fmpz_mul(m1m2, m1, m2);
|
|
||||||
fmpz_mod(r1r2, r1r2, m1m2);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
tree_crt(fmpz_t r, fmpz_t m, mp_srcptr residues, mp_srcptr primes, slong len)
|
|
||||||
{
|
|
||||||
if (len == 0)
|
|
||||||
{
|
|
||||||
fmpz_zero(r);
|
|
||||||
fmpz_one(m);
|
|
||||||
}
|
|
||||||
else if (len == 1)
|
|
||||||
{
|
|
||||||
fmpz_set_ui(r, residues[0]);
|
|
||||||
fmpz_set_ui(m, primes[0]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
fmpz_t r1, m1, r2, m2;
|
|
||||||
|
|
||||||
fmpz_init(r1);
|
|
||||||
fmpz_init(m1);
|
|
||||||
fmpz_init(r2);
|
|
||||||
fmpz_init(m2);
|
|
||||||
|
|
||||||
tree_crt(r1, m1, residues, primes, len / 2);
|
|
||||||
tree_crt(r2, m2, residues + len / 2, primes + len / 2, len - len / 2);
|
|
||||||
_fmpz_crt_combine(r, m, r1, m1, r2, m2);
|
|
||||||
|
|
||||||
fmpz_clear(r1);
|
|
||||||
fmpz_clear(m1);
|
|
||||||
fmpz_clear(r2);
|
|
||||||
fmpz_clear(m2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
arb_fmpz_euler_number_ui_multi_mod(fmpz_t num, ulong n, double alpha)
|
arb_fmpz_euler_number_ui_multi_mod(fmpz_t num, ulong n, double alpha)
|
||||||
{
|
{
|
||||||
|
n_primes_t prime_iter;
|
||||||
slong i, bits, mod_bits, zeta_bits, num_primes;
|
slong i, bits, mod_bits, zeta_bits, num_primes;
|
||||||
ulong p;
|
ulong p;
|
||||||
mp_ptr primes, residues;
|
mp_ptr primes, residues;
|
||||||
|
@ -517,7 +494,12 @@ arb_fmpz_euler_number_ui_multi_mod(fmpz_t num, ulong n, double alpha)
|
||||||
mag_init(primes_product);
|
mag_init(primes_product);
|
||||||
mag_one(primes_product);
|
mag_one(primes_product);
|
||||||
|
|
||||||
for (p = 5; mag_cmp_2exp_si(primes_product, mod_bits) < 0; p = n_nextprime(p, 1))
|
n_primes_init(prime_iter);
|
||||||
|
|
||||||
|
p = 5;
|
||||||
|
n_primes_jump_after(prime_iter, 5);
|
||||||
|
|
||||||
|
for ( ; mag_cmp_2exp_si(primes_product, mod_bits) < 0; p = n_primes_next(prime_iter))
|
||||||
{
|
{
|
||||||
if (n % (p - 1) != 0)
|
if (n % (p - 1) != 0)
|
||||||
{
|
{
|
||||||
|
@ -533,7 +515,10 @@ arb_fmpz_euler_number_ui_multi_mod(fmpz_t num, ulong n, double alpha)
|
||||||
primes = flint_malloc(sizeof(mp_limb_t) * num_primes);
|
primes = flint_malloc(sizeof(mp_limb_t) * num_primes);
|
||||||
residues = flint_malloc(sizeof(mp_limb_t) * num_primes);
|
residues = flint_malloc(sizeof(mp_limb_t) * num_primes);
|
||||||
|
|
||||||
for (p = 5, i = 0; i < num_primes; p = n_nextprime(p, 1))
|
p = 5;
|
||||||
|
n_primes_jump_after(prime_iter, 5);
|
||||||
|
|
||||||
|
for (i = 0; i < num_primes; p = n_primes_next(prime_iter))
|
||||||
{
|
{
|
||||||
if (n % (p - 1) != 0)
|
if (n % (p - 1) != 0)
|
||||||
{
|
{
|
||||||
|
@ -542,6 +527,8 @@ arb_fmpz_euler_number_ui_multi_mod(fmpz_t num, ulong n, double alpha)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
n_primes_clear(prime_iter);
|
||||||
|
|
||||||
if (num_primes == 0)
|
if (num_primes == 0)
|
||||||
{
|
{
|
||||||
divtab_odd = NULL;
|
divtab_odd = NULL;
|
||||||
|
@ -559,16 +546,17 @@ arb_fmpz_euler_number_ui_multi_mod(fmpz_t num, ulong n, double alpha)
|
||||||
printf("num_primes = %ld\n", num_primes);
|
printf("num_primes = %ld\n", num_primes);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (i = 0; i < num_primes; i++)
|
|
||||||
{
|
{
|
||||||
#if TIMING
|
mod_p_param_t param;
|
||||||
if (i % 10000 == 0)
|
param.n = n;
|
||||||
printf("%ld / %ld\n", i, num_primes);
|
param.primes = primes;
|
||||||
#endif
|
param.residues = residues;
|
||||||
|
param.divtab = divtab_odd;
|
||||||
|
|
||||||
residues[i] = euler_mod_p_powsum(n, primes[i], divtab_odd);
|
flint_parallel_do(mod_p_worker, ¶m, num_primes, 0, FLINT_PARALLEL_STRIDED /* | FLINT_PARALLEL_VERBOSE */);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if TIMING
|
#if TIMING
|
||||||
t2 = clock();
|
t2 = clock();
|
||||||
printf("mod time = %f\n", (t2 - t1) / (double) CLOCKS_PER_SEC);
|
printf("mod time = %f\n", (t2 - t1) / (double) CLOCKS_PER_SEC);
|
||||||
|
@ -577,7 +565,7 @@ arb_fmpz_euler_number_ui_multi_mod(fmpz_t num, ulong n, double alpha)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
fmpz_init(M);
|
fmpz_init(M);
|
||||||
tree_crt(num, M, residues, primes, num_primes);
|
_arb_tree_crt(num, M, residues, primes, num_primes);
|
||||||
fmpz_mod(num, num, M);
|
fmpz_mod(num, num, M);
|
||||||
|
|
||||||
if (n % 4 == 2)
|
if (n % 4 == 2)
|
||||||
|
|
|
@ -126,7 +126,7 @@ typedef struct
|
||||||
}
|
}
|
||||||
mod_p_param_t;
|
mod_p_param_t;
|
||||||
|
|
||||||
void
|
static void
|
||||||
mod_p_worker(slong i, void * param)
|
mod_p_worker(slong i, void * param)
|
||||||
{
|
{
|
||||||
mod_p_param_t * p = (mod_p_param_t *) param;
|
mod_p_param_t * p = (mod_p_param_t *) param;
|
||||||
|
@ -178,7 +178,7 @@ _bernoulli_fmpq_ui_multi_mod(fmpz_t num, fmpz_t den, ulong n, double alpha)
|
||||||
mag_one(primes_product);
|
mag_one(primes_product);
|
||||||
|
|
||||||
n_primes_init(prime_iter);
|
n_primes_init(prime_iter);
|
||||||
|
|
||||||
p = 5;
|
p = 5;
|
||||||
n_primes_jump_after(prime_iter, 5);
|
n_primes_jump_after(prime_iter, 5);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue