diff --git a/src/frontend/com_fft.c b/src/frontend/com_fft.c index b77d8a28d..637602e64 100644 --- a/src/frontend/com_fft.c +++ b/src/frontend/com_fft.c @@ -7,8 +7,6 @@ Author: 2008 Holger Vogt * Code to do fast fourier transform on data. */ -#define GREEN /* select fast Green's fft */ - #include "ngspice/ngspice.h" #include "ngspice/ftedefs.h" #include "ngspice/dvec.h" @@ -20,6 +18,10 @@ Author: 2008 Holger Vogt #include "../misc/misc_time.h" #include "ngspice/fftext.h" +#ifdef HAVE_LIBFFTW3 +#include "fftw3.h" +#endif + void com_fft(wordlist *wl) @@ -33,13 +35,16 @@ com_fft(wordlist *wl) struct pnode *pn, *names = NULL; char window[BSIZE_SP]; double maxt; + double *in = NULL; -#ifdef GREEN - int M; +#ifdef HAVE_LIBFFTW3 + fftw_complex *out = NULL; + fftw_plan plan_forward = NULL; +#else + int N, M; #endif - double *reald = NULL, *imagd = NULL; - int N, order; + int order; double scale; if (!plot_cur || !plot_cur->pl_scale) { @@ -56,7 +61,9 @@ com_fft(wordlist *wl) time = (plot_cur->pl_scale)->v_realdata; span = time[tlen-1] - time[0]; -#ifdef GREEN +#ifdef HAVE_LIBFFTW3 + fpts = tlen/2 + 1; +#else /* size of fft input vector is power of two and larger or equal than spice vector */ N = 1; M = 0; @@ -64,14 +71,8 @@ com_fft(wordlist *wl) N <<= 1; M++; } -#else - /* size of input vector is power of two and larger than spice vector */ - N = 1; - while (N < tlen) - N *= 2; -#endif - /* output vector has length of N/2 */ fpts = N/2; +#endif win = TMALLOC(double, tlen); maxt = time[tlen-1]; @@ -138,7 +139,11 @@ com_fft(wordlist *wl) vec_new(f); for (i = 0; iv_link2; } - printf("FFT: Time span: %g s, input length: %d, zero padding: %d\n", span, N, N-tlen); - printf("FFT: Freq. resolution: %g Hz, output length: %d\n", 1.0/span*tlen/N, fpts); +#ifdef HAVE_LIBFFTW3 + + printf("FFT: Time span: %g s, input length: %d\n", span, tlen); + printf("FFT: Frequency resolution: %g Hz, output length: %d\n", 1.0/span, fpts); - reald = TMALLOC(double, N); - imagd = TMALLOC(double, N); for (i = 0; iwl_next; +#ifdef HAVE_LIBFFTW3 + fpts = tlen/2 + 1; +#else /* size of fft input vector is power of two and larger or equal than spice vector */ N = 1; M = 0; @@ -258,9 +294,8 @@ com_psd(wordlist *wl) N <<= 1; M++; } - - // output vector has length of N/2 fpts = N/2; +#endif win = TMALLOC(double, tlen); maxt = time[tlen-1]; @@ -326,8 +361,13 @@ com_psd(wordlist *wl) f->v_realdata = freq; vec_new(f); +#ifdef HAVE_LIBFFTW3 + for (i = 0; i <= fpts; i++) + freq[i] = i*1./span; +#else for (i = 0; i <= fpts; i++) freq[i] = i*1./span*tlen/N; +#endif tdvec = TMALLOC(double*, ngood); fdvec = TMALLOC(ngcomplex_t*, ngood); @@ -345,26 +385,55 @@ com_psd(wordlist *wl) vec = vec->v_link2; } - printf("PSD: Time span: %g s, input length: %d, zero padding: %d\n", span, N, N-tlen); - printf("PSD: Freq. resolution: %g Hz, output length: %d\n", 1.0/span*tlen/N, fpts); +#ifdef HAVE_LIBFFTW3 - reald = TMALLOC(double, N); - imagd = TMALLOC(double, N); + printf("PSD: Time span: %g s, input length: %d\n", span, tlen); + printf("PSD: Frequency resolution: %g Hz, output length: %d\n", 1.0/span, fpts); - // scale = 0.66; + reald = TMALLOC(double, fpts); + + in = fftw_malloc(sizeof(double) * (unsigned int) tlen); + out = fftw_malloc(sizeof(fftw_complex) * (unsigned int) fpts); for (i = 0; i