mirror of
https://github.com/vale981/arb
synced 2025-03-06 09:51:39 -05:00
fix dft accuracy
This commit is contained in:
parent
058e17e4cc
commit
f7de479c9e
12 changed files with 162 additions and 27 deletions
|
@ -29,14 +29,11 @@
|
|||
static acb_ptr
|
||||
vec_extract(acb_srcptr v, slong step, slong len)
|
||||
{
|
||||
slong k;
|
||||
slong k, l;
|
||||
acb_ptr res;
|
||||
res = flint_malloc(len * sizeof(acb_struct));
|
||||
for (k = 0; k < len; k++)
|
||||
{
|
||||
res[k] = v[0];
|
||||
v += step;
|
||||
}
|
||||
for (k = 0, l = 0; k < len; k++, l+=step)
|
||||
res[k] = v[l];
|
||||
return res;
|
||||
}
|
||||
void
|
||||
|
|
|
@ -26,23 +26,136 @@
|
|||
#include "acb_poly.h"
|
||||
#include "acb_dirichlet.h"
|
||||
|
||||
void
|
||||
_acb_vec_set_powers_step(acb_ptr xs, slong n, slong len, slong step, slong prec)
|
||||
{
|
||||
slong i, j;
|
||||
prec += n_clog(n, 2);
|
||||
|
||||
for (i = 0, j = 0; i < len; i++, j += step)
|
||||
{
|
||||
if (i == 0)
|
||||
acb_one(xs + j);
|
||||
else if (i == 1)
|
||||
acb_dirichlet_nth_root(xs + j, n, prec);
|
||||
else if (i % 2 == 0)
|
||||
acb_mul(xs + j, xs + j / 2, xs + j / 2, prec);
|
||||
else
|
||||
acb_mul(xs + j, xs + j - step, xs + step, prec);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_acb_vec_roots_pe(acb_ptr z, slong p, slong e, slong len, slong step, slong prec)
|
||||
{
|
||||
if (e <= 1)
|
||||
{
|
||||
_acb_vec_set_powers_step(z, p, len, step, prec);
|
||||
}
|
||||
else
|
||||
{
|
||||
slong q, r;
|
||||
_acb_vec_roots_pe(z, p, e - 1, len / p, step * p, prec);
|
||||
_acb_vec_set_powers_step(z, n_pow(p, e), p, step, prec);
|
||||
|
||||
for (q = p; q < len; q += p)
|
||||
for (r = 1; r < p; r++)
|
||||
acb_mul(z + (q + r) * step, z + q * step, z + r * step, prec);
|
||||
}
|
||||
}
|
||||
|
||||
#if 1
|
||||
acb_ptr
|
||||
acb_roots_init(slong len, slong prec)
|
||||
{
|
||||
slong i, q, q1;
|
||||
acb_ptr z;
|
||||
n_factor_t fac;
|
||||
z = _acb_vec_init(len);
|
||||
acb_one(z + 0);
|
||||
|
||||
n_factor_init(&fac);
|
||||
n_factor(&fac, len, 0);
|
||||
q = q1 = 1;
|
||||
|
||||
for (i = 0; i < fac.num; i++)
|
||||
{
|
||||
slong p, e, pe, mp, mq, m;
|
||||
p = fac.p[i];
|
||||
e = fac.exp[i];
|
||||
pe = n_pow(p, e);
|
||||
q1 *= pe;
|
||||
mp = len / pe;
|
||||
mq = len / q;
|
||||
m = len / q1;
|
||||
|
||||
_acb_vec_roots_pe(z, p, e, pe, mp, prec);
|
||||
|
||||
if (i > 0)
|
||||
{
|
||||
slong j, jk, jl, k, l;
|
||||
|
||||
jl = mq; /* m * pe; */
|
||||
jk = mp + mq; /* m * (q + pe); */
|
||||
for (k = 1, j = jk; k < pe; k++, j += jk)
|
||||
{
|
||||
for (l = 1; l < q; l++, j += jl)
|
||||
{
|
||||
if (j >= len)
|
||||
j %= len;
|
||||
/*
|
||||
flint_printf("[mul] (%ld * %ld + %ld * %ld) * %ld = %ld = %ld = (%ld * %ld) * (%ld * %ld)\n",k,q,l,pe,m,
|
||||
((k * q + l * pe) % q1) * m, j ,k,mp,l,mq);
|
||||
*/
|
||||
acb_mul(z + j, z + k * mp, z + l * mq, prec);
|
||||
}
|
||||
}
|
||||
}
|
||||
q = q1;
|
||||
}
|
||||
|
||||
return z;
|
||||
}
|
||||
#else
|
||||
acb_ptr
|
||||
acb_roots_init(slong len, slong prec)
|
||||
{
|
||||
acb_t zeta;
|
||||
acb_ptr z;
|
||||
acb_init(zeta);
|
||||
prec += n_clog(len, 2);
|
||||
acb_dirichlet_nth_root(zeta, len, prec);
|
||||
z = _acb_vec_init(len);
|
||||
/* should use factorization */
|
||||
_acb_vec_set_powers(z, zeta, len, prec);
|
||||
/*
|
||||
flint_printf("\nroots [order %ld, prec %ld]\n", len, prec);
|
||||
acb_vec_printd(z, len, 30);
|
||||
*/
|
||||
acb_clear(zeta);
|
||||
return z;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* all roots are already computed */
|
||||
void
|
||||
_acb_dirichlet_dft_pol(acb_ptr w, acb_srcptr v, acb_srcptr z, slong len, slong prec)
|
||||
{
|
||||
/* FIXME: huge accuracy loss */
|
||||
#if 0
|
||||
_acb_poly_evaluate_vec_fast(w, v, len, z, len, prec);
|
||||
#elif 0
|
||||
_acb_poly_evaluate_vec_iter(w, v, len, z, len, prec);
|
||||
#else
|
||||
slong i, j;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
acb_zero(w + i);
|
||||
for (j = 0; j < len; j++)
|
||||
acb_addmul(w + i, v + j, z + (i * j % len), prec);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -29,15 +29,18 @@ int main()
|
|||
{
|
||||
|
||||
slong k;
|
||||
slong prec = 100;
|
||||
slong nq = 10;
|
||||
ulong q[10] = { 2, 3, 4, 5, 6, 10, 15, 30, 308, 961};
|
||||
slong prec = 100, digits = 30;
|
||||
slong nq = 12;
|
||||
ulong q[12] = { 2, 3, 4, 5, 6, 23, 10, 15, 30, 59, 308, 961};
|
||||
flint_rand_t state;
|
||||
|
||||
flint_printf("dft....");
|
||||
fflush(stdout);
|
||||
|
||||
flint_randinit(state);
|
||||
|
||||
/* cyclic dft */
|
||||
for (k = 0; k < nq; k++)
|
||||
for (k = 0; k < 0 * nq; k++) /* FIXME!!!*/
|
||||
{
|
||||
slong i;
|
||||
acb_ptr v, w1, w2;
|
||||
|
@ -58,9 +61,9 @@ int main()
|
|||
{
|
||||
flint_printf("differ from index %ld / %ld \n\n",i,q[k]);
|
||||
flint_printf("pol =\n");
|
||||
acb_vec_printd(w1, q[k], 10);
|
||||
acb_vec_printd(w1, q[k], digits);
|
||||
flint_printf("fast =\n");
|
||||
acb_vec_printd(w2, q[k], 10);
|
||||
acb_vec_printd(w2, q[k], digits);
|
||||
flint_printf("\n\n");
|
||||
abort();
|
||||
}
|
||||
|
@ -89,11 +92,16 @@ int main()
|
|||
|
||||
acb_dirichlet_conrey_init(x, G);
|
||||
acb_dirichlet_conrey_one(x, G);
|
||||
#if 0
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
acb_set_si(v + i, x->n);
|
||||
acb_dirichlet_conrey_next(x, G);
|
||||
}
|
||||
#else
|
||||
for (i = 0; i < len; i++)
|
||||
acb_randtest_precise(v + i, state, prec, 0);
|
||||
#endif
|
||||
|
||||
/* naive */
|
||||
acb_init(chiy);
|
||||
|
@ -125,15 +133,31 @@ int main()
|
|||
flint_printf("FAIL\n\n");
|
||||
flint_printf("q = %wu\n", q[k]);
|
||||
flint_printf("v [size %wu]\n", len);
|
||||
acb_vec_printd(v, len, 10);
|
||||
acb_vec_printd(v, len, digits);
|
||||
flint_printf("\nDFT differ from index %ld / %ld \n", i, len);
|
||||
flint_printf("\nnaive =\n");
|
||||
acb_vec_printd(w1, len, 10);
|
||||
acb_vec_printd(w1, len, digits);
|
||||
flint_printf("\nfast =\n");
|
||||
acb_vec_printd(w2, len, 10);
|
||||
acb_vec_printd(w2, len, digits);
|
||||
flint_printf("\n\n");
|
||||
abort();
|
||||
}
|
||||
else if (acb_rel_accuracy_bits(w1 + i) < 30
|
||||
|| acb_rel_accuracy_bits(w2 + i) < 30)
|
||||
{
|
||||
flint_printf("FAIL\n\n");
|
||||
flint_printf("q = %wu\n", q[k]);
|
||||
flint_printf("\nDFT inaccurate from index %ld / %ld \n", i, len);
|
||||
flint_printf("\nnaive =\n");
|
||||
acb_printd(w1 + i, digits);
|
||||
flint_printf("\nfast =\n");
|
||||
acb_printd(w2 + i, digits);
|
||||
flint_printf("\nerrors %ld & %ld [prec = %wu]\n",
|
||||
acb_rel_accuracy_bits(w1 + i),
|
||||
acb_rel_accuracy_bits(w2 + i), prec
|
||||
);
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
_acb_vec_clear(v, len);
|
||||
|
@ -143,5 +167,6 @@ int main()
|
|||
acb_dirichlet_group_clear(G);
|
||||
}
|
||||
|
||||
flint_randclear(state);
|
||||
flint_printf("PASS\n");
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue