dft: fix len=0,1 + test

This commit is contained in:
Pascal 2017-10-22 22:44:24 +02:00
parent 4469966ae0
commit c2fb3c8221
8 changed files with 69 additions and 41 deletions

View file

@ -179,11 +179,8 @@ void acb_dft_step(acb_ptr w, acb_srcptr v, acb_dft_step_ptr cyc, slong num, slon
void acb_dft_precomp(acb_ptr w, acb_srcptr v, const acb_dft_pre_t pre, slong prec); void acb_dft_precomp(acb_ptr w, acb_srcptr v, const acb_dft_pre_t pre, slong prec);
void acb_dft_inverse_precomp(acb_ptr w, acb_srcptr v, const acb_dft_pre_t pre, slong prec); void acb_dft_inverse_precomp(acb_ptr w, acb_srcptr v, const acb_dft_pre_t pre, slong prec);
void acb_dft_naive_precomp(acb_ptr w, acb_srcptr v, const acb_dft_naive_t pol, slong prec); void acb_dft_naive_precomp(acb_ptr w, acb_srcptr v, const acb_dft_naive_t pol, slong prec);
ACB_DFT_INLINE void void acb_dft_cyc_precomp(acb_ptr w, acb_srcptr v, const acb_dft_cyc_t cyc, slong prec);
acb_dft_cyc_precomp(acb_ptr w, acb_srcptr v, const acb_dft_cyc_t cyc, slong prec)
{
acb_dft_step(w, v, cyc->cyc, cyc->num, prec);
}
void acb_dft_rad2_precomp_inplace(acb_ptr v, const acb_dft_rad2_t rad2, slong prec); void acb_dft_rad2_precomp_inplace(acb_ptr v, const acb_dft_rad2_t rad2, slong prec);
void acb_dft_rad2_precomp(acb_ptr w, acb_srcptr v, const acb_dft_rad2_t rad2, slong prec); void acb_dft_rad2_precomp(acb_ptr w, acb_srcptr v, const acb_dft_rad2_t rad2, slong prec);
void acb_dft_crt_precomp(acb_ptr w, acb_srcptr v, const acb_dft_crt_t crt, slong prec); void acb_dft_crt_precomp(acb_ptr w, acb_srcptr v, const acb_dft_crt_t crt, slong prec);

View file

@ -18,7 +18,10 @@ crt_init(crt_t c, ulong n)
n_factor_t fac; n_factor_t fac;
n_factor_init(&fac); n_factor_init(&fac);
n_factor(&fac, n, 1); if (n)
n_factor(&fac, n, 1);
else
fac.num = 0;
nmod_init(&c->n, n); nmod_init(&c->n, n);
@ -172,33 +175,49 @@ acb_dft_crt_clear(acb_dft_crt_t crt)
void void
acb_dft_crt_precomp(acb_ptr w, acb_srcptr v, const acb_dft_crt_t crt, slong prec) acb_dft_crt_precomp(acb_ptr w, acb_srcptr v, const acb_dft_crt_t crt, slong prec)
{ {
acb_ptr t; if (crt->n <= 1)
t = _acb_vec_init(crt->n);
if (w == v)
{ {
_acb_vec_set(t, v, crt->n); if (crt->n == 1)
v = t; acb_set(w, v);
}
else
{
acb_ptr t;
t = _acb_vec_init(crt->n);
if (w == v)
{
_acb_vec_set(t, v, crt->n);
v = t;
}
crt_decomp(w, v, crt->dv, crt->c, crt->n);
acb_dft_step(t, w, crt->cyc, crt->c->num, prec);
crt_recomp(w, t, crt->c, crt->n);
_acb_vec_clear(t, crt->n);
} }
crt_decomp(w, v, crt->dv, crt->c, crt->n);
acb_dft_step(t, w, crt->cyc, crt->c->num, prec);
crt_recomp(w, t, crt->c, crt->n);
_acb_vec_clear(t, crt->n);
} }
void void
acb_dft_crt(acb_ptr w, acb_srcptr v, slong len, slong prec) acb_dft_crt(acb_ptr w, acb_srcptr v, slong len, slong prec)
{ {
crt_t c; if (len <= 1)
acb_ptr t;
t = _acb_vec_init(len);
if (w == v)
{ {
_acb_vec_set(t, v, len); if (len == 1)
v = t; acb_set(w, v);
}
else
{
crt_t c;
acb_ptr t;
t = _acb_vec_init(len);
if (w == v)
{
_acb_vec_set(t, v, len);
v = t;
}
crt_init(c, len);
crt_decomp(w, v, 1, c, len);
acb_dft_prod(t, w, c->m, c->num, prec);
crt_recomp(w, t, c, len);
_acb_vec_clear(t, len);
} }
crt_init(c, len);
crt_decomp(w, v, 1, c, len);
acb_dft_prod(t, w, c->m, c->num, prec);
crt_recomp(w, t, c, len);
_acb_vec_clear(t, len);
} }

View file

@ -70,7 +70,10 @@ _acb_dft_cyc_init(acb_dft_cyc_t t, slong dv, slong len, slong prec)
{ {
n_factor_t fac; n_factor_t fac;
n_factor_init(&fac); n_factor_init(&fac);
n_factor(&fac, len, 0); if (len)
n_factor(&fac, len, 1);
else
fac.num = 0;
_acb_dft_cyc_init_z_fac(t, fac, dv, NULL, 0, len, prec); _acb_dft_cyc_init_z_fac(t, fac, dv, NULL, 0, len, prec);
} }
@ -85,6 +88,18 @@ acb_dft_cyc_clear(acb_dft_cyc_t t)
flint_free(t->cyc); flint_free(t->cyc);
} }
void
acb_dft_cyc_precomp(acb_ptr w, acb_srcptr v, const acb_dft_cyc_t cyc, slong prec)
{
if (cyc->num == 0)
{
if (cyc->n == 1)
acb_set(w, v);
}
else
acb_dft_step(w, v, cyc->cyc, cyc->num, prec);
}
void void
acb_dft_cyc(acb_ptr w, acb_srcptr v, slong len, slong prec) acb_dft_cyc(acb_ptr w, acb_srcptr v, slong len, slong prec)
{ {

View file

@ -17,10 +17,10 @@ _acb_dft_precomp_init(acb_dft_pre_t pre, slong dv, acb_ptr z, slong dz, slong le
pre->n = len; pre->n = len;
if (len <= 1) if (len <= 1)
{ {
flint_printf("precomp init: trivial group. abort.\n"); pre->type = DFT_NAIVE;
abort(); _acb_dft_naive_init(pre->t.naive, dv, z, dz, len, prec);
} }
if (n_is_prime(len)) else if (n_is_prime(len))
{ {
if (len < 100) if (len < 100)
{ {

View file

@ -51,9 +51,7 @@ acb_dft_prod_clear(acb_dft_prod_t t)
void void
acb_dft_prod_precomp(acb_ptr w, acb_srcptr v, const acb_dft_prod_t prod, slong prec) acb_dft_prod_precomp(acb_ptr w, acb_srcptr v, const acb_dft_prod_t prod, slong prec)
{ {
if (prod->num == 0) if (prod->num >= 1)
acb_set(w + 0, v + 0);
else
acb_dft_step(w, v, prod->cyc, prod->num, prec); acb_dft_step(w, v, prod->cyc, prod->num, prec);
} }

View file

@ -19,8 +19,9 @@ acb_dft_step(acb_ptr w, acb_srcptr v, acb_dft_step_ptr cyc, slong num, slong pre
acb_dft_step_struct c; acb_dft_step_struct c;
if (num == 0) if (num == 0)
{ {
/* only possible if len = 0 */
flint_printf("error: reached num = 0 in acb_dft_step\n"); flint_printf("error: reached num = 0 in acb_dft_step\n");
abort(); /* or just copy v to w */ return;
} }
c = cyc[0]; c = cyc[0];
if (num == 1) if (num == 1)

View file

@ -54,8 +54,8 @@ int main()
{ {
slong k; slong k;
slong prec = 100, digits = 30; slong prec = 100, digits = 30;
slong nq = 17; slong nq = 19;
ulong q[17] = { 2, 3, 4, 5, 6, 23, 10, 15, 16, 30, 59, 125, 308, 335, 525, 961, 1225}; ulong q[19] = { 0, 1, 2, 3, 4, 5, 6, 23, 10, 15, 16, 30, 59, 125, 308, 335, 525, 961, 1225};
flint_rand_t state; flint_rand_t state;
slong f, nf = 5; slong f, nf = 5;
@ -103,10 +103,8 @@ int main()
check_vec_eq_prec(w1, w2, q[k], prec, digits, q[k], "no alias", name[0], name[f]); check_vec_eq_prec(w1, w2, q[k], prec, digits, q[k], "no alias", name[0], name[f]);
} }
/*
acb_dft_inverse(w2, w1, q[k], prec); acb_dft_inverse(w2, w1, q[k], prec);
check_vec_eq_prec(v, w2, q[k], prec, digits, q[k], "original", "inverse"); check_vec_eq_prec(v, w2, q[k], prec, digits, q[k], "inverse", "original", "inverse");
*/
_acb_vec_clear(v, q[k]); _acb_vec_clear(v, q[k]);
_acb_vec_clear(w1, q[k]); _acb_vec_clear(w1, q[k]);
@ -115,7 +113,7 @@ int main()
} }
/* radix2 dft */ /* radix2 dft */
for (k = 1; k < 12; k++) for (k = 0; k < 12; k++)
{ {
slong n = 1 << k, j; slong n = 1 << k, j;
acb_ptr v, w1, w2; acb_ptr v, w1, w2;

View file

@ -225,7 +225,7 @@ CRT decomposition
Sets *w* to the DFT of *v* of size *t->n*, using the CRT decomposition scheme *t*. Sets *w* to the DFT of *v* of size *t->n*, using the CRT decomposition scheme *t*.
Cooley-Tuckey decomposition Cooley-Tukey decomposition
............................................................................... ...............................................................................
.. function:: void acb_dft_cyc(acb_ptr w, acb_srcptr v, slong n, slong prec) .. function:: void acb_dft_cyc(acb_ptr w, acb_srcptr v, slong n, slong prec)