#include "fft.h" #define _USE_MATH_DEFINES #include #include #include "utils.h" namespace _sbsms_ { #define REAL(tr,ti,r,i) (tr*r - ti*i) #define IMAG(tr,ti,r,i) (tr*i + ti*r) t_fft *make_fft_buf(int N) { return (t_fft*) malloc(N*sizeof(t_fft)); } void free_fft_buf(t_fft *buf) { free(buf); } void optimizeFactors(int *f) { int n = 0; for(int k=0;;k++) { if(f[k]==0) break; n++; } int *g = (int*)calloc(n+1,sizeof(int)); for(int k=0;kdir = 1; plan->n = getNFactors(factors); plan->N2 = factors; plan->N1 = getN1(factors,N); plan->order = getOrder(plan->n,plan->N1,plan->N2); plan->reorder = (t_fft*)malloc(N*sizeof(t_fft)); plan->t = calcTwiddles(plan->n,plan->N1,plan->N2,plan->order,1); plan->f = getFuncs(factors); plan->N = N; plan->norm = 1.0; return plan; } fftplan *planIFFT(int N) { int *factors = factor(N); optimizeFactors(factors); fftplan *plan = new fftplan; plan->dir = -1; plan->n = getNFactors(factors); plan->N2 = factors; plan->N1 = getN1(factors,N); plan->order = getOrder(plan->n,plan->N1,plan->N2); plan->reorder = (t_fft*)malloc(N*sizeof(t_fft)); plan->t = calcTwiddles(plan->n,plan->N1,plan->N2,plan->order,-1); plan->f = getFuncs(factors); plan->N = N; plan->norm = 1.0/(real)N; return plan; } void destroy_fftplan(fftplan *plan) { free(plan->reorder); free(plan->order); free(plan->f); for(int i=0;in;i++) free(plan->t[i]); free(plan->t); free(plan->N1); free(plan->N2); free(plan); } void FFT(fftplan *plan, t_fft *x) { fft(plan,x,0,0); for(int k=0;kN;k++) { plan->reorder[k][0] = x[k][0]; plan->reorder[k][1] = x[k][1]; } for(int k=0;kN;k++) { int kr = plan->order[k]; if(k != kr) { x[k][0] = plan->reorder[kr][0]; x[k][1] = plan->reorder[kr][1]; } } } void IFFT(fftplan *plan, t_fft *x) { FFT(plan,x); /* real norm = plan->norm; for(int k=0;kN;k++) { x[k][0] *= norm; x[k][1] *= norm; } */ } void fft(fftplan *plan, t_fft *x, int r, int i) { int N1 = plan->N1[i]; int N2 = plan->N2[i]; for(int n1=0;n1f[i])(x,n1,N1,r,plan->t[i],plan->dir); } if(N1==1) return; for(int k2=0;k2