Example #1
0
        internal static FftwPlanRC Create(IPinnedArray <double> bufferReal, IPinnedArray <Complex> bufferComplex, int rank, int[] n, DftDirection direction, PlannerFlags plannerFlags, int nThreads)
        {
            FftwPlanRC plan = new FftwPlanRC(bufferReal, bufferComplex, rank, n, false, direction, plannerFlags, nThreads);

            if (plan.IsZero)
            {
                return(null);
            }
            return(plan);
        }
Example #2
0
 FftwPlanRC(IPinnedArray <double> bufferReal, IPinnedArray <Complex> bufferComplex, int rank, int[] n, bool verifyRankAndSize, DftDirection direction, PlannerFlags plannerFlags, int nThreads)
     : base(bufferReal, bufferComplex, rank, n, verifyRankAndSize, direction, plannerFlags, nThreads)
 {
 }
Example #3
0
        /// <summary>
        /// Initializes a new plan using the provided input and output buffers.
        /// These buffers may be overwritten during initialization.
        /// </summary>
        public static FftwPlanC2C Create(IPinnedArray <Complex> input, IPinnedArray <Complex> output, DftDirection direction, PlannerFlags plannerFlags = PlannerFlags.Default, int nThreads = 1)
        {
            FftwPlanC2C plan = new FftwPlanC2C(input, output, input.Rank, input.GetSize(), true, direction, plannerFlags, nThreads);

            if (plan.IsZero)
            {
                return(null);
            }
            return(plan);
        }
Example #4
0
        internal static FftwPlanC2C Create(IPinnedArray <Complex> input, IPinnedArray <Complex> output, int rank, int[] n, DftDirection direction, PlannerFlags plannerFlags, int nThreads)
        {
            FftwPlanC2C plan = new FftwPlanC2C(input, output, rank, n, false, direction, plannerFlags, nThreads);

            if (plan.IsZero)
            {
                return(null);
            }
            return(plan);
        }
Example #5
0
 FftwPlanC2C(IPinnedArray <Complex> input, IPinnedArray <Complex> output, int rank, int[] n, bool verifyRankAndSize, DftDirection direction, PlannerFlags plannerFlags, int nThreads)
     : base(input, output, rank, n, verifyRankAndSize, direction, plannerFlags, nThreads)
 {
 }
Example #6
0
 protected override IntPtr GetPlan(int rank, int[] n, IntPtr input, IntPtr output, DftDirection direction, PlannerFlags plannerFlags)
 {
     return(FftwInterop.fftw_plan_dft(rank, n, input, output, direction, plannerFlags));
 }
Example #7
0
 static extern IntPtr fftw_plan_dft_c2r_ARM(int rank, [MarshalAs(UnmanagedType.LPArray)] int[] n, IntPtr arrIn, IntPtr arrOut, PlannerFlags flags);
Example #8
0
        internal protected FftwPlan(IPinnedArray <T1> buffer1, IPinnedArray <T2> buffer2, int rank, int[] n, bool verifyRankAndSize, DftDirection direction, PlannerFlags plannerFlags, int nThreads)
        {
            if (!FftwInterop.IsAvailable)
            {
                throw new InvalidOperationException($"{nameof(FftwInterop.IsAvailable)} returns false.");
            }

            if (buffer1.IsDisposed)
            {
                throw new ObjectDisposedException(nameof(buffer1));
            }
            if (buffer2.IsDisposed)
            {
                throw new ObjectDisposedException(nameof(buffer2));
            }

            if (verifyRankAndSize)
            {
                VerifyRankAndSize(buffer1, buffer2);
            }
            else
            {
                VerifyMinSize(buffer1, buffer2, n);
            }

            if (nThreads < 1)
            {
                nThreads = Environment.ProcessorCount;
            }

            _buffer1 = buffer1;
            _buffer2 = buffer2;
            _plan    = IntPtr.Zero;

            lock (FftwInterop.Lock)
            {
                FftwInterop.fftw_plan_with_nthreads(nThreads);
                _plan = GetPlan(rank, n, _buffer1.Pointer, _buffer2.Pointer, direction, plannerFlags);
            }
        }
Example #9
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);
                        }
            }
        }
Example #10
0
 static extern IntPtr fftw_plan_dft_x64(int rank, [MarshalAs(UnmanagedType.LPArray)] int[] n, IntPtr arrIn, IntPtr arrOut, DftDirection direction, PlannerFlags flags);
Example #11
0
 /// <summary>
 /// Performs a complex-to-complex inverse fast fourier transformation. The dimension is inferred from the input (<see cref="Array{T}.Rank"/>).
 /// </summary>
 /// <seealso cref="http://www.fftw.org/fftw3_doc/Complex-One_002dDimensional-DFTs.html#Complex-One_002dDimensional-DFTs"/>
 /// <seealso cref="http://www.fftw.org/fftw3_doc/Complex-Multi_002dDimensional-DFTs.html#Complex-Multi_002dDimensional-DFTs"/>
 public static void IFFT(IPinnedArray <Complex> input, IPinnedArray <Complex> output, PlannerFlags plannerFlags = PlannerFlags.Default, int nThreads = 1) => Transform(input, output, DftDirection.Backwards, plannerFlags, nThreads);
Example #12
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();
                    }
        }
Example #13
0
 protected abstract IntPtr GetPlan(int rank, int[] n, IntPtr input, IntPtr output, DftDirection direction, PlannerFlags plannerFlags);
Example #14
0
 protected override IntPtr GetPlan(int rank, int[] n, IntPtr bufferReal, IntPtr bufferComplex, DftDirection direction, PlannerFlags plannerFlags)
 {
     if (direction == DftDirection.Forwards)
     {
         return(FftwInterop.fftw_plan_dft_r2c(rank, n, bufferReal, bufferComplex, plannerFlags));
     }
     else
     {
         return(FftwInterop.fftw_plan_dft_c2r(rank, n, bufferComplex, bufferReal, plannerFlags));
     }
 }
Example #15
0
 public static IntPtr fftw_plan_dft_c2r(int rank, [MarshalAs(UnmanagedType.LPArray)] int[] n, IntPtr arrIn, IntPtr arrOut, PlannerFlags flags)
 {
     if (RuntimeInformation.ProcessArchitecture == Architecture.X64)
     {
         return(fftw_plan_dft_c2r_x64(rank, n, arrIn, arrOut, flags));
     }
     else if (RuntimeInformation.ProcessArchitecture == Architecture.X86)
     {
         return(fftw_plan_dft_c2r_x86(rank, n, arrIn, arrOut, flags));
     }
     else if (RuntimeInformation.ProcessArchitecture == Architecture.Arm)
     {
         return(fftw_plan_dft_c2r_ARM(rank, n, arrIn, arrOut, flags));
     }
     else
     {
         throw new PlatformNotSupportedException();
     }
 }
Example #16
0
        /// <summary>
        /// Initializes a new plan using the provided input and output buffers.
        /// These buffers may be overwritten during initialization.
        /// </summary>
        public static FftwPlanRC Create(IPinnedArray <double> bufferReal, IPinnedArray <Complex> bufferComplex, DftDirection direction, PlannerFlags plannerFlags = PlannerFlags.Default, int nThreads = 1)
        {
            FftwPlanRC plan = new FftwPlanRC(bufferReal, bufferComplex, bufferReal.Rank, bufferReal.GetSize(), true, direction, plannerFlags, nThreads);

            if (plan.IsZero)
            {
                return(null);
            }
            return(plan);
        }
Example #17
0
 FftwPlanR2R(IPinnedArray <Double> input, IPinnedArray <Double> output, int rank, int[] n, bool verifyRankAndSize, DftDirection direction, PlannerFlags plannerFlags, int nThreads)
     : base(input, output, rank, n, verifyRankAndSize, direction, plannerFlags, 1)
 {
     //int[] ns = input.GetSize();
     //lock (FftwInterop.Lock)
     //{
     //    //_plan = FftwInterop.fftw_plan_r2r(rank,ns,input.Pointer,output.Pointer,direction,plannerFlags);
     //    _plan = GetPlan(rank, n, input.Pointer, output.Pointer, direction, plannerFlags);
     //}
 }