#include "mpn_extras.h"
#include "thread_support.h"
#include "fmpz.h"
#include "fmpz_vec.h"
static void _fmpz_vec_get_fft_coeff(ulong ** coeffs_f,
const fmpz * coeffs_m, slong l, slong i)
{
slong size_f = l + 1;
ulong * coeff;
slong size_j, c;
int signed_c;
c = coeffs_m[i];
signed_c = 0;
if (!COEFF_IS_MPZ(c))
{
size_j = 1;
if (c < 0)
{
signed_c = 1;
c = -c;
coeff = (ulong *) &c;
}
else
coeff = (ulong *) coeffs_m + i;
}
else
{
mpz_ptr mc = COEFF_TO_PTR(c);
size_j = mc->_mp_size;
if (size_j < 0)
{
signed_c = 1;
size_j = -size_j;
}
coeff = mc->_mp_d;
}
if (signed_c)
{
mpn_neg(coeffs_f[i], coeff, size_j);
flint_mpn_store(coeffs_f[i] + size_j, size_f - size_j, WORD(-1));
}
else
{
flint_mpn_copyi(coeffs_f[i], coeff, size_j);
flint_mpn_zero(coeffs_f[i] + size_j, size_f - size_j);
}
}
typedef struct
{
ulong ** coeffs_f;
const fmpz * coeffs_m;
slong limbs;
}
work_t;
static void
worker(slong i, work_t * work)
{
_fmpz_vec_get_fft_coeff(work->coeffs_f, work->coeffs_m, work->limbs, i);
}
void _fmpz_vec_get_fft(ulong ** coeffs_f,
const fmpz * coeffs_m, slong limbs, slong length)
{
work_t work;
slong max_threads;
work.coeffs_f = coeffs_f;
work.coeffs_m = coeffs_m;
work.limbs = limbs;
max_threads = flint_get_num_threads();
max_threads = FLINT_MIN(max_threads, 1e-5 * limbs * length + 1);
flint_parallel_do((do_func_t) worker, &work, length, max_threads, FLINT_PARALLEL_UNIFORM);
}