public void BackwardReal(double[] spectrum, int n, FourierTransformScaling scaling) { // TODO: backport proper, optimized implementation from Iridium Complex[] data = new Complex[n]; data[0] = new Complex(spectrum[0], 0d); for (int i = 1, j = 2; i < data.Length/2; i++) { data[i] = new Complex(spectrum[j++], spectrum[j++]); data[data.Length - i] = data[i].Conjugate(); } if (n.IsEven()) { data[data.Length/2] = new Complex(spectrum[n], 0d); } else { data[data.Length/2] = new Complex(spectrum[n-1], spectrum[n]); data[data.Length/2 + 1] = data[data.Length/2].Conjugate(); } Backward(data, scaling); for (int i = 0; i < data.Length; i++) { spectrum[i] = data[i].Real; } spectrum[n] = 0d; }
public void BackwardReal(double[] spectrum, int n, FourierTransformScaling scaling) { Kernel kernel = Configure(n, scaling, true); SafeNativeMethods.d_fft_backward(kernel.Handle, spectrum); Release(kernel); spectrum[n] = 0d; }
public void BackwardReal(float[] spectrum, int n, FourierTransformScaling scaling) { Kernel kernel = Configure(n, scaling, true, true); SafeNativeMethods.s_fft_backward(kernel.Handle, spectrum); Release(kernel); spectrum[n] = 0f; }
static double BackwardScaling(FourierTransformScaling scaling, long length) { switch (scaling) { case FourierTransformScaling.SymmetricScaling: return Math.Sqrt(1.0/length); case FourierTransformScaling.BackwardScaling: return 1.0/length; default: return 1.0; } }
Kernel Configure(int length, FourierTransformScaling scaling, bool real, bool single) { Kernel kernel = Interlocked.Exchange(ref _kernel, null); if (kernel == null) { kernel = new Kernel { Dimensions = new[] {length}, Scaling = scaling, Real = real, Single = single }; if (single) { if (real) SafeNativeMethods.s_fft_create(out kernel.Handle, length, (float)ForwardScaling(scaling, length), (float)BackwardScaling(scaling, length)); else SafeNativeMethods.c_fft_create(out kernel.Handle, length, (float)ForwardScaling(scaling, length), (float)BackwardScaling(scaling, length)); } else { if (real) SafeNativeMethods.d_fft_create(out kernel.Handle, length, ForwardScaling(scaling, length), BackwardScaling(scaling, length)); else SafeNativeMethods.z_fft_create(out kernel.Handle, length, ForwardScaling(scaling, length), BackwardScaling(scaling, length)); } return kernel; } if (kernel.Dimensions.Length != 1 || kernel.Dimensions[0] != length || kernel.Scaling != scaling || kernel.Real != real || kernel.Single != single) { SafeNativeMethods.x_fft_free(ref kernel.Handle); if (single) { if (real) SafeNativeMethods.s_fft_create(out kernel.Handle, length, (float)ForwardScaling(scaling, length), (float)BackwardScaling(scaling, length)); else SafeNativeMethods.c_fft_create(out kernel.Handle, length, (float)ForwardScaling(scaling, length), (float)BackwardScaling(scaling, length)); } else { if (real) SafeNativeMethods.d_fft_create(out kernel.Handle, length, ForwardScaling(scaling, length), BackwardScaling(scaling, length)); else SafeNativeMethods.z_fft_create(out kernel.Handle, length, ForwardScaling(scaling, length), BackwardScaling(scaling, length)); } kernel.Dimensions = new[] {length}; kernel.Scaling = scaling; kernel.Real = real; kernel.Single = single; return kernel; } return kernel; }
static double ForwardScaling(FourierTransformScaling scaling, long length) { switch (scaling) { case FourierTransformScaling.SymmetricScaling: return(Math.Sqrt(1.0 / length)); case FourierTransformScaling.ForwardScaling: return(1.0 / length); default: return(1.0); } }
public void Backward(Complex[] spectrum, FourierTransformScaling scaling) { switch (scaling) { case FourierTransformScaling.SymmetricScaling: Fourier.BluesteinInverse(spectrum, FourierOptions.Default); break; case FourierTransformScaling.BackwardScaling: Fourier.BluesteinInverse(spectrum, FourierOptions.AsymmetricScaling); break; default: Fourier.BluesteinInverse(spectrum, FourierOptions.NoScaling); break; } }
public void Backward(Complex32[] spectrum, FourierTransformScaling scaling) { switch (scaling) { case FourierTransformScaling.SymmetricScaling: Fourier.BluesteinInverse(spectrum, FourierOptions.Default); break; case FourierTransformScaling.BackwardScaling: Fourier.BluesteinInverse(spectrum, FourierOptions.AsymmetricScaling); break; default: Fourier.BluesteinInverse(spectrum, FourierOptions.NoScaling); break; } }
public void BackwardInplace(Complex[] complex, FourierTransformScaling scaling) { switch (scaling) { case FourierTransformScaling.SymmetricScaling: Fourier.BluesteinInverse(complex, FourierOptions.Default); break; case FourierTransformScaling.BackwardScaling: Fourier.BluesteinInverse(complex, FourierOptions.AsymmetricScaling); break; default: Fourier.BluesteinInverse(complex, FourierOptions.NoScaling); break; } }
public void Forward(Complex[] samples, FourierTransformScaling scaling) { switch (scaling) { case FourierTransformScaling.SymmetricScaling: Fourier.BluesteinForward(samples, FourierOptions.Default); break; case FourierTransformScaling.ForwardScaling: // Only backward scaling can be expressed with options, hence the double-inverse Fourier.BluesteinInverse(samples, FourierOptions.AsymmetricScaling | FourierOptions.InverseExponent); break; default: Fourier.BluesteinForward(samples, FourierOptions.NoScaling); break; } }
static void Verify( Complex32[] samples, int maximumErrorDecimalPlaces, FourierTransformScaling options, Action <Complex32[], FourierTransformScaling> expected, Action <Complex32[], FourierTransformScaling> actual) { var spectrumExpected = new Complex32[samples.Length]; samples.CopyTo(spectrumExpected, 0); expected(spectrumExpected, options); var spectrumActual = new Complex32[samples.Length]; samples.CopyTo(spectrumActual, 0); actual(spectrumActual, options); AssertHelpers.AlmostEqual(spectrumExpected, spectrumActual, maximumErrorDecimalPlaces); }
public void Forward(Complex[] samples, FourierTransformScaling scaling) { Kernel kernel = Configure(samples.Length, scaling, false, false); SafeNativeMethods.z_fft_forward(kernel.Handle, samples); Release(kernel); }
public void BackwardMultidim(Complex[] spectrum, int[] dimensions, FourierTransformScaling scaling) { Kernel kernel = Configure(dimensions, scaling); SafeNativeMethods.z_fft_backward(kernel.Handle, spectrum); Release(kernel); }
public void Backward(Complex[] spectrum, FourierTransformScaling scaling) { Kernel kernel = Configure(spectrum.Length, scaling, false); SafeNativeMethods.z_fft_backward(kernel.Handle, spectrum); Release(kernel); }
Kernel Configure(int[] dimensions, FourierTransformScaling scaling) { if (dimensions.Length == 1) { return Configure(dimensions[0], scaling, false); } Kernel kernel = Interlocked.Exchange(ref _kernel, null); if (kernel == null) { kernel = new Kernel { Dimensions = dimensions, Scaling = scaling, Real = false }; long length = 1; for (int i = 0; i < dimensions.Length; i++) { length *= dimensions[i]; } SafeNativeMethods.z_fft_create_multidim(out kernel.Handle, dimensions.Length, dimensions, ForwardScaling(scaling, length), BackwardScaling(scaling, length)); return kernel; } bool mismatch = kernel.Dimensions.Length != dimensions.Length || kernel.Scaling != scaling || kernel.Real != false; if (!mismatch) { for (int i = 0; i < dimensions.Length; i++) { if (dimensions[i] != kernel.Dimensions[i]) { mismatch = true; break; } } } if (mismatch) { long length = 1; for (int i = 0; i < dimensions.Length; i++) { length *= dimensions[i]; } SafeNativeMethods.x_fft_free(ref kernel.Handle); SafeNativeMethods.z_fft_create_multidim(out kernel.Handle, dimensions.Length, dimensions, ForwardScaling(scaling, length), BackwardScaling(scaling, length)); kernel.Dimensions = dimensions; kernel.Scaling = scaling; kernel.Real = false; return kernel; } return kernel; }
Kernel Configure(int length, FourierTransformScaling scaling, bool real) { Kernel kernel = Interlocked.Exchange(ref _kernel, null); if (kernel == null) { kernel = new Kernel { Dimensions = new[] {length}, Scaling = scaling, Real = real }; if (real) SafeNativeMethods.d_fft_create(out kernel.Handle, length, ForwardScaling(scaling, length), BackwardScaling(scaling, length)); else SafeNativeMethods.z_fft_create(out kernel.Handle, length, ForwardScaling(scaling, length), BackwardScaling(scaling, length)); return kernel; } if (kernel.Dimensions.Length != 1 || kernel.Dimensions[0] != length || kernel.Scaling != scaling || kernel.Real != real) { SafeNativeMethods.x_fft_free(ref kernel.Handle); if (real) SafeNativeMethods.d_fft_create(out kernel.Handle, length, ForwardScaling(scaling, length), BackwardScaling(scaling, length)); else SafeNativeMethods.z_fft_create(out kernel.Handle, length, ForwardScaling(scaling, length), BackwardScaling(scaling, length)); kernel.Dimensions = new[] {length}; kernel.Scaling = scaling; kernel.Real = real; return kernel; } return kernel; }
static double ForwardScaling(FourierTransformScaling scaling, long length) { switch (scaling) { case FourierTransformScaling.SymmetricScaling: return Math.Sqrt(1.0/length); case FourierTransformScaling.ForwardScaling: return 1.0/length; default: return 1.0; } }
public void ForwardReal(double[] samples, int n, FourierTransformScaling scaling) { Kernel kernel = Configure(n, scaling, true, false); SafeNativeMethods.d_fft_forward(kernel.Handle, samples); Release(kernel); }
Kernel Configure(int[] dimensions, FourierTransformScaling scaling, bool single) { if (dimensions.Length == 1) { return(Configure(dimensions[0], scaling, false, single)); } Kernel kernel = Interlocked.Exchange(ref _kernel, null); if (kernel == null) { kernel = new Kernel { Dimensions = dimensions, Scaling = scaling, Real = false, Single = single }; long length = 1; for (int i = 0; i < dimensions.Length; i++) { length *= dimensions[i]; } if (single) { SafeNativeMethods.c_fft_create_multidim(out kernel.Handle, dimensions.Length, dimensions, (float)ForwardScaling(scaling, length), (float)BackwardScaling(scaling, length)); } else { SafeNativeMethods.z_fft_create_multidim(out kernel.Handle, dimensions.Length, dimensions, ForwardScaling(scaling, length), BackwardScaling(scaling, length)); } return(kernel); } bool mismatch = kernel.Dimensions.Length != dimensions.Length || kernel.Scaling != scaling || kernel.Real != false || kernel.Single != single; if (!mismatch) { for (int i = 0; i < dimensions.Length; i++) { if (dimensions[i] != kernel.Dimensions[i]) { mismatch = true; break; } } } if (mismatch) { long length = 1; for (int i = 0; i < dimensions.Length; i++) { length *= dimensions[i]; } SafeNativeMethods.x_fft_free(ref kernel.Handle); if (single) { SafeNativeMethods.c_fft_create_multidim(out kernel.Handle, dimensions.Length, dimensions, (float)ForwardScaling(scaling, length), (float)BackwardScaling(scaling, length)); } else { SafeNativeMethods.z_fft_create_multidim(out kernel.Handle, dimensions.Length, dimensions, ForwardScaling(scaling, length), BackwardScaling(scaling, length)); } kernel.Dimensions = dimensions; kernel.Scaling = scaling; kernel.Real = false; kernel.Single = single; return(kernel); } return(kernel); }
public void ForwardMultidim(Complex[] samples, int[] dimensions, FourierTransformScaling scaling) { throw new NotSupportedException(); }
public void BackwardMultidim(Complex[] spectrum, int[] dimensions, FourierTransformScaling scaling) { throw new NotSupportedException(); }
public void BackwardMultidim(Complex[] spectrum, int[] dimensions, FourierTransformScaling scaling) { Kernel kernel = Configure(dimensions, scaling, false); SafeNativeMethods.z_fft_backward(kernel.Handle, spectrum); Release(kernel); }
public void ForwardMultidim(Complex32[] samples, int[] dimensions, FourierTransformScaling scaling) { Kernel kernel = Configure(dimensions, scaling, true); SafeNativeMethods.c_fft_forward(kernel.Handle, samples); Release(kernel); }
public void ForwardReal(double[] samples, int n, FourierTransformScaling scaling) { // TODO: backport proper, optimized implementation from Iridium Complex[] data = new Complex[n]; for (int i = 0; i < data.Length; i++) { data[i] = new Complex(samples[i], 0.0); } Forward(data, scaling); samples[0] = data[0].Real; samples[1] = 0d; for (int i = 1, j = 2; i < data.Length/2; i++) { samples[j++] = data[i].Real; samples[j++] = data[i].Imaginary; } if (n.IsEven()) { samples[n] = data[data.Length/2].Real; samples[n+1] = 0d; } else { samples[n-1] = data[data.Length / 2].Real; samples[n] = data[data.Length / 2].Imaginary; } }
public void Backward(Complex[] spectrum, FourierTransformScaling scaling) { Kernel kernel = Configure(spectrum.Length, scaling, false, false); SafeNativeMethods.z_fft_backward(kernel.Handle, spectrum); Release(kernel); }
public void ForwardReal(double[] samples, int n, FourierTransformScaling scaling) { Kernel kernel = Configure(n, scaling, true); SafeNativeMethods.d_fft_forward(kernel.Handle, samples); Release(kernel); }
public void Forward(Complex[] samples, FourierTransformScaling scaling) { Kernel kernel = Configure(samples.Length, scaling, false); SafeNativeMethods.z_fft_forward(kernel.Handle, samples); Release(kernel); }
public void ForwardMultidim(Complex[] samples, int[] dimensions, FourierTransformScaling scaling) { Kernel kernel = Configure(dimensions, scaling); SafeNativeMethods.z_fft_forward(kernel.Handle, samples); Release(kernel); }