ComplexFourierTransformation( TransformationConvention convention ) { _fft = new InternalFFT(); _convention = convention; }
Rescale( double[] samples, bool forward, TransformationConvention convention ) { if ((convention & TransformationConvention.NoScaling) > 0) { return; } bool asymmetric = (convention & TransformationConvention.AsymmetricScaling) > 0; if (forward && asymmetric) { return; } double factor = 2.0 / samples.Length; if (!asymmetric) { factor = Math.Sqrt(factor); } for (int i = 0; i < samples.Length; i++) { samples[i] *= factor; } }
RealFourierTransformation( TransformationConvention convention ) { _fft = new InternalFFT(); _convention = convention; }
public void DiscreteFourierTransform( double[] samples, bool forward, TransformationConvention convention) { ReorderSamples(samples); DanielsonLanczosTransform(samples, forward, convention); Rescale(samples, forward, convention); }
DiscreteFourierTransform( double[] samples, bool forward, TransformationConvention convention) { ReorderSamples(samples); DanielsonLanczosTransform(samples, forward, convention); Rescale(samples, forward, convention); }
DanielsonLanczosTransformMultiDim( double[] samples, int stride, int step, bool forward, TransformationConvention convention ) { int levels = Fn.IntLog2(stride / step); // precompute coefficients if they're not already there. BuildCoefficientsForLevels(levels); double expSignConvention = (convention & TransformationConvention.InverseExponent) > 0 ? -1d : 1d; int N = step; for (int level = 1; level <= levels; level++) { int M = N; N <<= 1; double[] realCosine = RealCosineCoefficients(level, forward); double[] imagSine = ImaginarySineCoefficients(level, forward); for (int j = 0, jj = 0; jj < M; j++, jj += step) { double uR = realCosine[j]; double uI = expSignConvention * imagSine[j]; for (int i = jj; i < jj + step; i += 2) { for (int even = i; even < samples.Length; even += N) { int odd = even + M; double re = samples[odd]; double im = samples[odd + 1]; double tmpr = re * uR - im * uI; double tmpi = re * uI + im * uR; re = samples[even]; im = samples[even + 1]; samples[even] = re + tmpr; samples[even + 1] = im + tmpi; samples[odd] = re - tmpr; samples[odd + 1] = im - tmpi; } } } } }
DanielsonLanczosTransform( double[] samples, bool forward, TransformationConvention convention) { int levels = Fn.IntLog2(samples.Length >> 1); // precompute coefficients if they're not already there. BuildCoefficientsForLevels(levels); double expSignConvention = (convention & TransformationConvention.InverseExponent) > 0 ? -1d : 1d; int n = 2; for (int level = 1; level <= levels; level++) { int m = n; n <<= 1; double[] realCosine = RealCosineCoefficients(level, forward); double[] imagSine = ImaginarySineCoefficients(level, forward); for (int j = 0, jj = 0; jj < m; j++, jj += 2) { double uR = realCosine[j]; double uI = expSignConvention * imagSine[j]; for (int even = jj; even < samples.Length; even += n) { int odd = even + m; double re = samples[odd]; double im = samples[odd + 1]; double tmpr = (re * uR) - (im * uI); double tmpi = (re * uI) + (im * uR); re = samples[even]; im = samples[even + 1]; samples[even] = re + tmpr; samples[even + 1] = im + tmpi; samples[odd] = re - tmpr; samples[odd + 1] = im - tmpi; } } } }
public void DiscreteFourierTransformMultiDim(double[] samples, int[] dimensions, bool forward, TransformationConvention convention) { int rank = dimensions.Length; int n, nprev = 1, step, stride; for(int idim = rank - 1; idim >= 0; idim--) { n = dimensions[idim]; step = nprev << 1; // complex numbers as pairs stride = n * step; ReorderSamplesMultiDim(samples, stride, step); DanielsonLanczosTransformMultiDim(samples, stride, step, forward, convention); nprev *= n; } Rescale(samples, forward, convention); }
DiscreteFourierTransformMultiDim( double[] samples, int[] dimensions, bool forward, TransformationConvention convention) { int rank = dimensions.Length; int nprev = 1; for (int idim = rank - 1; idim >= 0; idim--) { int n = dimensions[idim]; int step = nprev << 1; // complex numbers as pairs int stride = n * step; ReorderSamplesMultiDim(samples, stride, step); DanielsonLanczosTransformMultiDim(samples, stride, step, forward, convention); nprev *= n; } Rescale(samples, forward, convention); }
ComplexFourierTransformation() { _fft = new InternalFFT(); _convention = TransformationConvention.Default; }
internal void Rescale( double[] samples, bool forward, TransformationConvention convention) { if((convention & TransformationConvention.NoScaling) > 0) { return; } bool asymmetric = (convention & TransformationConvention.AsymmetricScaling) > 0; if(forward && asymmetric) { return; } double factor = 2.0 / samples.Length; if(!asymmetric) { factor = Math.Sqrt(factor); } for(int i = 0; i < samples.Length; i++) { samples[i] *= factor; } }
internal void DanielsonLanczosTransformMultiDim( double[] samples, int stride, int step, bool forward, TransformationConvention convention) { int levels = Fn.IntLog2(stride / step); // precompute coefficients if they're not already there. BuildCoefficientsForLevels(levels); double expSignConvention = (convention & TransformationConvention.InverseExponent) > 0 ? -1d : 1d; int n = step; for(int level = 1; level <= levels; level++) { int m = n; n <<= 1; double[] realCosine = RealCosineCoefficients(level, forward); double[] imagSine = ImaginarySineCoefficients(level, forward); for(int j = 0, jj = 0; jj < m; j++, jj += step) { double uR = realCosine[j]; double uI = expSignConvention * imagSine[j]; for(int i = jj; i < jj + step; i += 2) { for(int even = i; even < samples.Length; even += n) { int odd = even + m; double re = samples[odd]; double im = samples[odd + 1]; double tmpr = (re * uR) - (im * uI); double tmpi = (re * uI) + (im * uR); re = samples[even]; im = samples[even + 1]; samples[even] = re + tmpr; samples[even + 1] = im + tmpi; samples[odd] = re - tmpr; samples[odd + 1] = im - tmpi; } } } } }
RealFourierTransformation() { _fft = new InternalFFT(); _convention = TransformationConvention.Default; }
DanielsonLanczosTransform( double[] samples, bool forward, TransformationConvention convention ) { int levels = Fn.IntLog2(samples.Length >> 1); // precompute coefficients if they're not already there. BuildCoefficientsForLevels(levels); double expSignConvention = (convention & TransformationConvention.InverseExponent) > 0 ? -1d : 1d; int N = 2; for(int level = 1; level <= levels; level++) { int M = N; N <<= 1; double[] realCosine = RealCosineCoefficients(level, forward); double[] imagSine = ImaginarySineCoefficients(level, forward); for(int j = 0, jj = 0; jj < M; j++, jj += 2) { double uR = realCosine[j]; double uI = expSignConvention * imagSine[j]; for(int even = jj; even < samples.Length; even += N) { int odd = even + M; double re = samples[odd]; double im = samples[odd + 1]; double tmpr = re * uR - im * uI; double tmpi = re * uI + im * uR; re = samples[even]; im = samples[even + 1]; samples[even] = re + tmpr; samples[even + 1] = im + tmpi; samples[odd] = re - tmpr; samples[odd + 1] = im - tmpi; } } } }