Esempio n. 1
0
        /// <summary>
        /// Performs a complex-to-real inverse fast fourier transformation.
        /// </summary>
        /// <seealso cref="http://www.fftw.org/fftw3_doc/One_002dDimensional-DFTs-of-Real-Data.html#One_002dDimensional-DFTs-of-Real-Data"/>
        /// <seealso cref="http://www.fftw.org/fftw3_doc/Multi_002dDimensional-DFTs-of-Real-Data.html#Multi_002dDimensional-DFTs-of-Real-Data"/>
        public static void IFFT(IPinnedArray <Complex> input, IPinnedArray <double> output, PlannerFlags plannerFlags = PlannerFlags.Default, int nThreads = 1)
        {
            if ((plannerFlags & PlannerFlags.Estimate) == PlannerFlags.Estimate)
            {
                using (var plan = FftwPlanRC.Create(output, input, DftDirection.Backwards, plannerFlags, nThreads))
                {
                    plan.Execute();
                    return;
                }
            }

            using (var plan = FftwPlanRC.Create(output, input, DftDirection.Backwards, plannerFlags | PlannerFlags.WisdomOnly, nThreads))
            {
                if (plan != null)
                {
                    plan.Execute();
                    return;
                }
            }

            /// If with <see cref="PlannerFlags.WisdomOnly"/> no plan can be created
            /// and <see cref="PlannerFlags.Estimate"/> is not specified, we use
            /// a different buffer to avoid overwriting the input
            using (var bufferContainer = _bufferPool.RequestBuffer(input.Length * Marshal.SizeOf <Complex>() + MemoryAlignment))
                using (var buffer = new AlignedArrayComplex(bufferContainer.Buffer, MemoryAlignment, input.GetSize()))
                    using (var plan = FftwPlanRC.Create(output, buffer, DftDirection.Backwards, plannerFlags, nThreads))
                    {
                        input.CopyTo(plan.BufferComplex);
                        plan.Execute();
                    }
        }
Esempio n. 2
0
        static void Transform(IPinnedArray <Complex> input, IPinnedArray <Complex> output, DftDirection direction, PlannerFlags plannerFlags, int nThreads)
        {
            if ((plannerFlags & PlannerFlags.Estimate) == PlannerFlags.Estimate)
            {
                using (var plan = FftwPlanC2C.Create(input, output, direction, plannerFlags, nThreads))
                {
                    plan.Execute();
                    return;
                }
            }

            using (var plan = FftwPlanC2C.Create(input, output, direction, plannerFlags | PlannerFlags.WisdomOnly, nThreads))
            {
                if (plan != null)
                {
                    plan.Execute();
                    return;
                }
            }

            /// If with <see cref="PlannerFlags.WisdomOnly"/> no plan can be created
            /// and <see cref="PlannerFlags.Estimate"/> is not specified, we use
            /// a different buffer to avoid overwriting the input
            if (input != output)
            {
                using (var plan = FftwPlanC2C.Create(output, output, input.Rank, input.GetSize(), direction, plannerFlags, nThreads))
                {
                    input.CopyTo(output);
                    plan.Execute();
                }
            }
            else
            {
                using (var bufferContainer = _bufferPool.RequestBuffer(input.Length * Marshal.SizeOf <Complex>() + MemoryAlignment))
                    using (var buffer = new AlignedArrayComplex(bufferContainer.Buffer, MemoryAlignment, input.GetSize()))
                        using (var plan = FftwPlanC2C.Create(buffer, buffer, input.Rank, input.GetSize(), direction, plannerFlags, nThreads))
                        {
                            input.CopyTo(plan.Input);
                            plan.Execute();
                            plan.Output.CopyTo(output, 0, 0, input.Length);
                        }
            }
        }