I am currently working on a problem that requires FFT for convolution, however when I brought in my FFT template from my archive I realize that there's something wrong with the output.
eg:
Input: (0, 0) (0, 0) (4166667, 0) (1, 0)
Correct output: (4166668, 0) (-4166667, 1) (4166666, 0) (-4166667, -1)
Template output: (4166668, 0) (-4166667, -1) (4166666, 0) (-4166667, 1)
The code:
#define MAXN
#define ld long double
#define op operator
struct base {
typedef ld T; T re, im;
base() :re(0), im(0) {}
base(T re) :re(re), im(0) {}
base(T re, T im) :re(re), im(im) {}
base op + (const base& o) const { return base(re + o.re, im + o.im); }
base op - (const base& o) const { return base(re - o.re, im - o.im); }
base op * (const base& o) const { return base(re * o.re - im * o.im, re * o.im + im * o.re); }
base op * (ld k) const { return base(re * k, im * k); }
base conj() const { return base(re, -im); }
};
base w[MAXN]; //omega lookup table
int rev[MAXN]; //reverse lookup table
void build_rev(int k) {
static int rk = -1;
if( k == rk )return ; rk = k;
for(int i = 1; i < (1<<k); i++) {
int j = rev[i-1], t = k-1;
while( t >= 0 && ((j>>t)&1) ) { j ^= 1 << t; --t; }
if( t >= 0 ) { j ^= 1 << t; --t; }
rev[i] = j;
}
}
void fft(base *a, int k) {
build_rev(k); int n = 1 << k;
for(int i = 0; i < n; i++) if( rev[i] > i ) swap(a[i], a[rev[i]]);
for(int l = 2, lll = 1; l <= n; l += l, lll += lll) {
if( w[lll].re == 0 && w[lll].im == 0 ) {
ld angle = PI / lll;
base ww( cosl(angle), sinl(angle) );
if( lll > 1 ) for(int j = 0; j < lll; ++j) {
if( j & 1 ) w[lll + j] = w[(lll+j)/2] * ww;
else w[lll + j] = w[(lll+j)/2];
} else w[lll] = base(1, 0);
}
for(int i = 0; i < n; i += l)
for(int j = 0; j < lll; j++){
base v = a[i + j], u = a[i + j + lll] * w[lll + j];
a[i + j] = v + u; a[i + j + lll] = v - u;
}
}
}
//ideone compiled example: http://ideone.com/8PTjW5
I tried to check the bit reverse and the root of unity table yet I didn't find any problems in those two parts. I also checked some online materials to verify the steps but there's nothing odd looking to me.
Would someone mind help me to find out what's the problem in this template?
Thanks in advance.
Edit: I decided to rely on another template at the end, thanks for all the reply from everyone.