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;
        }
Example #3
0
        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;
        }
Example #6
0
        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;
     }
 }
Example #8
0
        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;
            }
        }
Example #10
0
        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);
 }
Example #19
0
        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)
 {
     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;
     }
 }
 public void BackwardMultidim(Complex[] spectrum, int[] dimensions, FourierTransformScaling scaling)
 {
     throw new NotSupportedException();
 }
 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);
 }
 public void ForwardMultidim(Complex[] samples, int[] dimensions, FourierTransformScaling scaling)
 {
     throw new NotSupportedException();
 }