mirror of
https://github.com/vale981/arb
synced 2025-03-06 01:41:39 -05:00
106 lines
2.9 KiB
C
106 lines
2.9 KiB
C
![]() |
/*=============================================================================
|
||
|
|
||
|
This file is part of ARB.
|
||
|
|
||
|
ARB is free software; you can redistribute it and/or modify
|
||
|
it under the terms of the GNU General Public License as published by
|
||
|
the Free Software Foundation; either version 2 of the License, or
|
||
|
(at your option) any later version.
|
||
|
|
||
|
ARB is distributed in the hope that it will be useful,
|
||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
GNU General Public License for more details.
|
||
|
|
||
|
You should have received a copy of the GNU General Public License
|
||
|
along with ARB; if not, write to the Free Software
|
||
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||
|
|
||
|
=============================================================================*/
|
||
|
/******************************************************************************
|
||
|
|
||
|
Copyright (C) 2016 Pascal Molin
|
||
|
|
||
|
******************************************************************************/
|
||
|
|
||
|
#include "acb_dirichlet.h"
|
||
|
|
||
|
/* assume xs has size >= len * step */
|
||
|
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);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* assume len = p^e and z has size >= len * step */
|
||
|
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);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void
|
||
|
acb_dirichlet_vec_nth_roots(acb_ptr z, slong len, slong prec)
|
||
|
{
|
||
|
slong i, q;
|
||
|
n_factor_t fac;
|
||
|
|
||
|
acb_one(z + 0);
|
||
|
|
||
|
n_factor_init(&fac);
|
||
|
n_factor(&fac, len, 0);
|
||
|
q = 1;
|
||
|
|
||
|
for (i = 0; i < fac.num; i++)
|
||
|
{
|
||
|
slong p, e, pe, mp, mq;
|
||
|
p = fac.p[i];
|
||
|
e = fac.exp[i];
|
||
|
pe = n_pow(p, e);
|
||
|
mp = len / pe;
|
||
|
mq = len / q;
|
||
|
|
||
|
_acb_vec_roots_pe(z, p, e, pe, mp, prec);
|
||
|
|
||
|
if (i > 0)
|
||
|
{
|
||
|
slong k, l;
|
||
|
|
||
|
for (k = mp; k < len; k += mp)
|
||
|
{
|
||
|
for (l = mq; l < len - k; l += mq)
|
||
|
acb_mul(z + k + l, z + k, z + l, prec);
|
||
|
for (; l < len; l += mq)
|
||
|
acb_mul(z + k + l - len, z + k, z + l, prec);
|
||
|
}
|
||
|
}
|
||
|
q *= pe;
|
||
|
}
|
||
|
}
|