use dft convol for smooth integers

This commit is contained in:
Pascal 2017-10-13 15:15:56 +02:00
parent 4d880302bd
commit 46cceb956a
4 changed files with 47 additions and 4 deletions

View file

@ -37,6 +37,7 @@ void acb_dft_prod(acb_ptr w, acb_srcptr v, slong * cyc, slong num, slong prec);
void acb_dft_convol_naive(acb_ptr w, acb_srcptr f, acb_srcptr g, slong len, slong prec);
void acb_dft_convol_dft(acb_ptr w, acb_srcptr f, acb_srcptr g, slong len, slong prec);
void acb_dft_convol_rad2(acb_ptr w, acb_srcptr f, acb_srcptr g, slong len, slong prec);
void acb_dft_convol(acb_ptr w, acb_srcptr f, acb_srcptr g, slong len, slong prec);
#define CRT_MAX 15
typedef struct

35
acb_dft/convol.c Normal file
View file

@ -0,0 +1,35 @@
/*
Copyright (C) 2016 Pascal Molin
This file is part of Arb.
Arb is free software: you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License (LGPL) as published
by the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version. See <http://www.gnu.org/licenses/>.
*/
#include "acb_dft.h"
static int use_dft(slong len, slong prec)
{
slong l2 = len;
while (l2 >= 16) l2 >>= 1;
if (l2 < 11)
{
while (!(len & 1)) len >>= 1;
while (len % 3 == 0) len /= 3;
while (len % 5 == 0) len /= 5;
while (len % 7 == 0) len /= 7;
return (len == 1);
}
return 0;
}
void acb_dft_convol(acb_ptr w, acb_srcptr f, acb_srcptr g, slong len, slong prec)
{
if (use_dft(len, prec))
acb_dft_convol_dft(w, f, g, len, prec);
else
acb_dft_convol_rad2(w, f, g, len, prec);
}

View file

@ -26,16 +26,18 @@ int main(int argc, char *argv[])
flint_rand_t state;
slong r, nr;
int l, nf = 3;
do_f func[3] = {
int l, nf = 4;
do_f func[4] = {
acb_dft_convol_naive,
acb_dft_convol_dft,
acb_dft_convol_rad2,
acb_dft_convol,
};
char * name[3] = {
char * name[4] = {
"naive",
"dft",
"rad2"
"rad2",
"default"
};
int i, ni = 14;

View file

@ -141,6 +141,8 @@ For functions `f` and `g` on `G` we consider the convolution
.. function:: void acb_dft_convol_rad2(acb_ptr w, acb_srcptr f, acb_srcptr g, slong len, slong prec)
.. function:: void acb_dft_convol(acb_ptr w, acb_srcptr f, acb_srcptr g, slong len, slong prec)
Sets *w* to the convolution of *f* and *g* of length *len*.
The *naive* version simply uses the definition.
@ -153,3 +155,6 @@ For functions `f` and `g` on `G` we consider the convolution
\widehat{f \star g}(\chi) = \hat f(\chi)\hat g(\chi)
to compute it using three radix 2 FFT.
The default version uses radix 2 FFT unless *len* is a product of small
primes where a non padded fft is faster.