public static double[] FFTWPaddedFFT(ref double[] @in) { Debug.Assert(@in.Length > 0); int n = @in.Length; int padded = n > 256 ? MathUtils.NextLowPrimeFactorization(n) : n; Array.Resize <double>(ref @in, padded); // 4096 real numbers on input processed by FFTW dft_r2c_1d transform gives // 4096/2+1 = 2049 complex numbers at output // prepare the input arrays var fftwInput = new FFTW.DoubleArray(@in); int complexSize = (padded >> 1) + 1; // this is the same as (padded / 2 + 1); var fftwOutput = new FFTW.ComplexArray(complexSize); FFTW.ForwardTransform(fftwInput, fftwOutput); Array.Resize <double>(ref @in, n); // free up memory GC.Collect(); return(fftwOutput.ComplexValues); }
public static void ForwardTransform(FFTW.DoubleArray input, FFTW.ComplexArray output) { IntPtr plan = FFTW.dft_r2c_1d(input.Length, input.Handle, output.Handle, Flags.Estimate); //FFTW.print_plan(plan); FFTW.execute(plan); FFTW.destroy_plan(plan); }
public static void BackwardTransform(FFTW.ComplexArray input, FFTW.DoubleArray output) { // TODO: will there be a time where input.Length should be used instead? IntPtr plan = FFTW.dft_c2r_1d(output.Length, input.Handle, output.Handle, Flags.Estimate); //FFTW.print_plan(plan); FFTW.execute(plan); FFTW.destroy_plan(plan); }
public static double[] FFTWPaddedIFFT(ref double[] @in, bool doProperScaling = true) { Debug.Assert(@in.Length > 1); int originalLength = @in.Length; int n = @in.Length - 2; // the complex array should in theory always be correct size? // int padded = n > 256 ? MathUtils.NextLowPrimeFactorization(n) : n; int padded = n; //Array.Resize<double>(ref @in, padded); // prepare the input arrays var fftwBackwardInput = new FFTW.ComplexArray(@in); var fftwBackwardOutput = new FFTW.DoubleArray(padded); // this method needs that the backwards transform uses the output.length as it's N // i.e. FFTW.dft_c2r_1d(output.Length, input.Handle, output.Handle, Flags.Estimate); FFTW.BackwardTransform(fftwBackwardInput, fftwBackwardOutput); double[] @out = null; if (doProperScaling) { @out = fftwBackwardOutput.ValuesDivedByN; } else { // in the original method it wasn't scaled correctly (meaning ValuesDivedByN) @out = fftwBackwardOutput.Values; } //Array.Resize<double>(ref @in, originalLength); // free up memory GC.Collect(); return(@out); }