void mpir_fft_butterfly_twiddle(mp_ptr u, mp_ptr v, mp_ptr s, mp_ptr t, mp_size_t limbs, mp_bitcnt_t b1, mp_bitcnt_t b2) { mp_limb_t nw = limbs*GMP_LIMB_BITS; mp_size_t x, y; int negate1 = 0; int negate2 = 0; if (b1 >= nw) { negate2 = 1; b1 -= nw; } x = b1/GMP_LIMB_BITS; b1 = b1%GMP_LIMB_BITS; if (b2 >= nw) { negate1 = 1; b2 -= nw; } y = b2/GMP_LIMB_BITS; b2 = b2%GMP_LIMB_BITS; mpir_butterfly_lshB(u, v, s, t, limbs, x, y); mpn_mul_2expmod_2expp1(u, u, limbs, b1); if (negate2) mpn_neg_n(u, u, limbs + 1); mpn_mul_2expmod_2expp1(v, v, limbs, b2); if (negate1) mpn_neg_n(v, v, limbs + 1); }
void fft_adjust_sqrt2(mp_limb_t * r, mp_limb_t * i1, mp_size_t i, mp_size_t limbs, mp_bitcnt_t w, mp_limb_t * temp) { mp_bitcnt_t wn = limbs*FLINT_BITS; mp_limb_t cy; mp_size_t j = i/2, k = w/2; mp_size_t y; mp_bitcnt_t b1; int negate = 0; b1 = j + wn/4 + i*k; if (b1 >= wn) { negate = 1; b1 -= wn; } y = b1/FLINT_BITS; b1 = b1%FLINT_BITS; /* multiply by 2^{j + wn/4 + i*k} */ if (y) { mpn_copyi(temp + y, i1, limbs - y); cy = mpn_neg_n(temp, i1 + limbs - y, y); temp[limbs] = 0; mpn_addmod_2expp1_1(temp + y, limbs - y, -i1[limbs]); mpn_sub_1(temp + y, temp + y, limbs - y + 1, cy); mpn_mul_2expmod_2expp1(r, temp, limbs, b1); } else mpn_mul_2expmod_2expp1(r, i1, limbs, b1); /* multiply by 2^{wn/2} */ y = limbs/2; cy = 0; mpn_copyi(temp + y, r, limbs - y); temp[limbs] = 0; if (y) cy = mpn_neg_n(temp, r + limbs - y, y); mpn_addmod_2expp1_1(temp + y, limbs - y, -r[limbs]); mpn_sub_1(temp + y, temp + y, limbs - y + 1, cy); /* shift by an additional half limb (rare) */ if (limbs & 1) mpn_mul_2expmod_2expp1(temp, temp, limbs, FLINT_BITS/2); /* subtract */ if (negate) mpn_sub_n(r, r, temp, limbs + 1); else mpn_sub_n(r, temp, r, limbs + 1); }
void mpir_fft_adjust(mp_ptr r, mp_ptr i1, mp_size_t i, mp_size_t limbs, mp_bitcnt_t w) { mp_bitcnt_t b1; mp_limb_t cy; mp_size_t x; b1 = i*w; x = b1/GMP_LIMB_BITS; b1 = b1%GMP_LIMB_BITS; if (x) { mpn_copyi(r + x, i1, limbs - x); r[limbs] = 0; cy = mpn_neg_n(r, i1 + limbs - x, x); mpn_addmod_2expp1_1(r + x, limbs - x, -i1[limbs]); mpn_sub_1(r + x, r + x, limbs - x + 1, cy); mpn_mul_2expmod_2expp1(r, r, limbs, b1); } else mpn_mul_2expmod_2expp1(r, i1, limbs, b1); }
void fft_butterfly(mp_limb_t * s, mp_limb_t * t, mp_limb_t * i1, mp_limb_t * i2, mp_size_t i, mp_size_t limbs, mp_bitcnt_t w) { mp_size_t y; mp_bitcnt_t b1; b1 = i*w; y = b1/FLINT_BITS; b1 = b1%FLINT_BITS; butterfly_lshB(s, t, i1, i2, limbs, 0, y); mpn_mul_2expmod_2expp1(t, t, limbs, b1); }