Esempio n. 1
0
        public static double[,] Backward(Complex[,] grid, long visibilityCount)
        {
            double[,] output = new double[grid.GetLength(0), grid.GetLength(1)];
            using (var imageSpace = new AlignedArrayComplex(16, grid.GetLength(0), grid.GetLength(1)))
                using (var fourierSpace = new AlignedArrayComplex(16, imageSpace.GetSize()))
                {
                    for (int y = 0; y < grid.GetLength(0); y++)
                    {
                        for (int x = 0; x < grid.GetLength(1); x++)
                        {
                            fourierSpace[y, x] = grid[y, x];
                        }
                    }

                    DFT.IFFT(fourierSpace, imageSpace, PlannerFlags.Default, Environment.ProcessorCount);

                    for (int y = 0; y < grid.GetLength(0); y++)
                    {
                        for (int x = 0; x < grid.GetLength(1); x++)
                        {
                            output[y, x] = imageSpace[y, x].Real / visibilityCount;
                        }
                    }
                }

            return(output);
        }
Esempio n. 2
0
        public static Complex[,] Forward(float[,] image, double norm = 1.0)
        {
            Complex[,] output = new Complex[image.GetLength(0), image.GetLength(1)];
            using (var imageSpace = new AlignedArrayComplex(16, image.GetLength(0), image.GetLength(1)))
                using (var fourierSpace = new AlignedArrayComplex(16, imageSpace.GetSize()))
                {
                    for (int y = 0; y < image.GetLength(0); y++)
                    {
                        for (int x = 0; x < image.GetLength(1); x++)
                        {
                            imageSpace[y, x] = image[y, x];
                        }
                    }

                    DFT.FFT(imageSpace, fourierSpace);

                    for (int y = 0; y < image.GetLength(0); y++)
                    {
                        for (int x = 0; x < image.GetLength(1); x++)
                        {
                            output[y, x] = fourierSpace[y, x] / norm;
                        }
                    }
                }

            return(output);
        }
Esempio n. 3
0
        public static float[,] BackwardFloat(Complex[,] image, double norm)
        {
            var output = new float[image.GetLength(0), image.GetLength(1)];

            using (var imageSpace = new AlignedArrayComplex(16, image.GetLength(0), image.GetLength(1)))
                using (var fourierSpace = new AlignedArrayComplex(16, imageSpace.GetSize()))
                {
                    for (int y = 0; y < image.GetLength(0); y++)
                    {
                        for (int x = 0; x < image.GetLength(1); x++)
                        {
                            imageSpace[y, x] = image[y, x];
                        }
                    }

                    DFT.IFFT(imageSpace, fourierSpace, PlannerFlags.Default, Environment.ProcessorCount);

                    for (int y = 0; y < image.GetLength(0); y++)
                    {
                        for (int x = 0; x < image.GetLength(1); x++)
                        {
                            output[y, x] = (float)(fourierSpace[y, x].Real / norm);
                        }
                    }
                }

            return(output);
        }
Esempio n. 4
0
 public InverseComplexFft(int fftSize)
 {
     FftSize    = fftSize;
     Input      = new AlignedArrayComplex(16, fftSize);
     Output     = new AlignedArrayComplex(16, fftSize);
     InverseFft = FftwPlanC2C.Create(Input, Output, DftDirection.Backwards, PlannerFlags.Estimate);
 }
Esempio n. 5
0
        public static Complex[,] Forward(double[,] image, double norm = 1.0)
        {
            Complex[,] output = new Complex[image.GetLength(0), image.GetLength(1)];
            using (var imageSpace = new AlignedArrayComplex(16, image.GetLength(0), image.GetLength(1)))
                using (var fourierSpace = new AlignedArrayComplex(16, imageSpace.GetSize()))
                {
                    for (int y = 0; y < image.GetLength(0); y++)
                    {
                        for (int x = 0; x < image.GetLength(1); x++)
                        {
                            imageSpace[y, x] = image[y, x];
                        }
                    }

                    DFT.FFT(imageSpace, fourierSpace, PlannerFlags.Default, Environment.ProcessorCount);

                    for (int y = 0; y < image.GetLength(0); y++)
                    {
                        for (int x = 0; x < image.GetLength(1); x++)
                        {
                            output[y, x] = fourierSpace[y, x] / norm;
                        }
                    }
                }

            return(output);
        }
Esempio n. 6
0
        static void Example2D()
        {
            using (var input = new AlignedArrayComplex(16, 64, 16))
                using (var output = new AlignedArrayComplex(16, input.GetSize()))
                {
                    for (int row = 0; row < input.GetLength(0); row++)
                    {
                        for (int col = 0; col < input.GetLength(1); col++)
                        {
                            input[row, col] = (double)row * col / input.Length;
                        }
                    }

                    DFT.FFT(input, output);
                    DFT.IFFT(output, output);

                    for (int row = 0; row < input.GetLength(0); row++)
                    {
                        for (int col = 0; col < input.GetLength(1); col++)
                        {
                            Console.Write((output[row, col].Real / input[row, col].Real / input.Length).ToString("F2").PadLeft(6));
                        }
                        Console.WriteLine();
                    }
                }
        }
Esempio n. 7
0
        public static float[,] WStackIFFTFloat(List <Complex[, ]> grid, long visibilityCount)
        {
            var output = new float[grid[0].GetLength(0), grid[0].GetLength(1)];

            using (var imageSpace = new AlignedArrayComplex(16, grid[0].GetLength(0), grid[0].GetLength(1)))
                using (var fourierSpace = new AlignedArrayComplex(16, imageSpace.GetSize()))
                {
                    for (int k = 0; k < grid.Count; k++)
                    {
                        Parallel.For(0, grid[0].GetLength(0), (y) =>
                        {
                            for (int x = 0; x < grid[0].GetLength(1); x++)
                            {
                                fourierSpace[y, x] = grid[k][y, x];
                            }
                        });

                        DFT.IFFT(fourierSpace, imageSpace, PlannerFlags.Default, Environment.ProcessorCount);

                        Parallel.For(0, grid[0].GetLength(0), (y) =>
                        {
                            for (int x = 0; x < grid[0].GetLength(1); x++)
                            {
                                output[y, x] += (float)(imageSpace[y, x].Real / visibilityCount);
                            }
                        });
                    }
                }

            return(output);
        }
Esempio n. 8
0
 public InverseRealFft(int fftSize)
 {
     FftSize    = fftSize;
     Waveform   = new AlignedArrayDouble(16, fftSize);
     Spectrum   = new AlignedArrayComplex(16, fftSize);
     InverseFft = FftwPlanRC.Create(Waveform, Spectrum, DftDirection.Backwards, PlannerFlags.Estimate);
 }
Esempio n. 9
0
        public FFT(int ySize, int xSize, int nCores)
        {
            var dims = new int[] { ySize, xSize };

            ImageBuffer   = new AlignedArrayComplex(16, dims);
            FourierBuffer = new AlignedArrayComplex(16, dims);
            fft           = FftwPlanC2C.Create(ImageBuffer, FourierBuffer, DftDirection.Forwards, PlannerFlags.Default, nCores);
            ifft          = FftwPlanC2C.Create(FourierBuffer, ImageBuffer, DftDirection.Backwards, PlannerFlags.Default, nCores);
        }
Esempio n. 10
0
            ///<summary>
            ///This routine casts the image to a format suitable for the FFTW engine
            /// </summary>
            /// <param name="im">Image double matrix to be cast to FTTW format</param>
            /// <returns>A pointer to an AlignedArrayComplex suitable for FFTW engine</returns>
            private static AlignedArrayComplex CastImageToFFTW(double[,] im)
            {
                int m      = im.GetLength(0);
                int n      = im.GetLength(1);
                var ImFFTW = new AlignedArrayComplex(16, m, n);

                for (int i = 0; i < m; i++)
                {
                    for (int j = 0; j < n; j++)
                    {
                        ImFFTW[i, j] = im[i, j];
                    }
                }
                return(ImFFTW);
            }
Esempio n. 11
0
            ///<summary>
            ///This routine casts the Fourier transform complex array to a format suitable for the FFTW engine
            /// </summary>
            /// <param name="Y">Spectrum to be sent to FFTW</param>
            /// <returns>A pointer to an AlignedArrayComplex suitable for FFTW engine</returns>
            private static AlignedArrayComplex CastSpectrumToFFTW(Complex[,] Y)
            {
                int    m          = Y.GetLength(0);
                int    n          = Y.GetLength(1);
                double S          = (double)m * n;
                var    FFTWHandle = new AlignedArrayComplex(16, m, n);

                for (int i = 0; i < m; i++)
                {
                    for (int j = 0; j < n; j++)
                    {
                        FFTWHandle[i, j] = Y[i, j] * S;
                    }
                }
                return(FFTWHandle);
            }
Esempio n. 12
0
        public static List <List <Complex[, ]> > Forward(GriddingConstants c, List <List <Complex[, ]> > subgrids)
        {
            var output = new List <List <Complex[, ]> >(subgrids.Count);

            for (int baseline = 0; baseline < subgrids.Count; baseline++)
            {
                var blSubgrids = subgrids[baseline];
                var blOutput   = new List <Complex[, ]>(blSubgrids.Count);
                for (int subgrid = 0; subgrid < blSubgrids.Count; subgrid++)
                {
                    var sub        = blSubgrids[subgrid];
                    var outFourier = new Complex[c.SubgridSize, c.SubgridSize];
                    using (var imageSpace = new AlignedArrayComplex(16, c.SubgridSize, c.SubgridSize))
                        using (var fourierSpace = new AlignedArrayComplex(16, imageSpace.GetSize()))
                        {
                            //copy
                            for (int i = 0; i < c.SubgridSize; i++)
                            {
                                for (int j = 0; j < c.SubgridSize; j++)
                                {
                                    imageSpace[i, j] = sub[i, j];
                                }
                            }

                            /*
                             * This is not a bug
                             * The original IDG implementation uses the inverse Fourier transform here, even though the
                             * Subgrids are already in image space.
                             */
                            DFT.IFFT(imageSpace, fourierSpace);
                            var norm = 1.0 / (c.SubgridSize * c.SubgridSize);

                            for (int i = 0; i < c.SubgridSize; i++)
                            {
                                for (int j = 0; j < c.SubgridSize; j++)
                                {
                                    outFourier[i, j] = fourierSpace[i, j] * norm;
                                }
                            }
                        }
                    blOutput.Add(outFourier);
                }
                output.Add(blOutput);
            }

            return(output);
        }
Esempio n. 13
0
            ///<summary>
            ///This routine casts the output of FFTW engine to a Complex matrix, so the spectrum can be saved
            ///and manipulated
            /// </summary>
            /// <param name="FFTOutput">The FFT spectrum output in FFTW format</param>
            /// <returns>Spectrum as matrix of double</returns>
            private static Complex[,] CastFFTWToComplexSpectrum(AlignedArrayComplex FFTOutput)
            {
                int    m     = FFTOutput.GetLength(0);
                int    n     = FFTOutput.GetLength(1);
                double N_spe = (double)m * n;

                Complex[,] spectrum = new Complex[m, n]; //Initialize spectrum
                for (int i = 0; i < m; i++)
                {
                    for (int j = 0; j < n; j++)
                    {
                        spectrum[i, j] = new Complex(FFTOutput[i, j].Real / N_spe, FFTOutput[i, j].Imaginary / N_spe);
                    }
                }

                return(spectrum);
            }
Esempio n. 14
0
        private bool disposedValue = false; // To detect redundant calls

        protected virtual void Dispose(bool disposing)
        {
            if (!disposedValue)
            {
                if (disposing)
                {
                    fft.Dispose();
                    ifft.Dispose();
                    ImageBuffer.Dispose();
                    FourierBuffer.Dispose();
                }

                ImageBuffer   = null;
                FourierBuffer = null;

                disposedValue = true;
            }
        }
Esempio n. 15
0
        public static void Shift(AlignedArrayComplex grid)
        {
            var n2 = grid.GetLength(0) / 2;

            for (int i = 0; i < n2; i++)
            {
                for (int j = 0; j < n2; j++)
                {
                    var tmp13 = grid[i, j];
                    grid[i, j]           = grid[i + n2, j + n2];
                    grid[i + n2, j + n2] = tmp13;

                    var tmp24 = grid[i + n2, j];
                    grid[i + n2, j] = grid[i, j + n2];
                    grid[i, j + n2] = tmp24;
                }
            }
        }
Esempio n. 16
0
        public static List <List <Complex[, ]> > Backward(GriddingConstants c, List <List <Complex[, ]> > subgrids)
        {
            var output = new List <List <Complex[, ]> >(subgrids.Count);

            for (int baseline = 0; baseline < subgrids.Count; baseline++)
            {
                var blSubgrids = subgrids[baseline];
                var blOutput   = new List <Complex[, ]>(blSubgrids.Count);
                for (int subgrid = 0; subgrid < blSubgrids.Count; subgrid++)
                {
                    var sub        = blSubgrids[subgrid];
                    var outFourier = new Complex[c.SubgridSize, c.SubgridSize];
                    using (var imageSpace = new AlignedArrayComplex(16, c.SubgridSize, c.SubgridSize))
                        using (var fourierSpace = new AlignedArrayComplex(16, imageSpace.GetSize()))
                        {
                            //copy
                            for (int i = 0; i < c.SubgridSize; i++)
                            {
                                for (int j = 0; j < c.SubgridSize; j++)
                                {
                                    imageSpace[i, j] = sub[i, j];
                                }
                            }

                            DFT.FFT(imageSpace, fourierSpace);
                            //normalization is done in the Gridder

                            for (int i = 0; i < c.SubgridSize; i++)
                            {
                                for (int j = 0; j < c.SubgridSize; j++)
                                {
                                    outFourier[i, j] = fourierSpace[i, j];
                                }
                            }
                        }
                    blOutput.Add(outFourier);
                }
                output.Add(blOutput);
            }

            return(output);
        }
Esempio n. 17
0
 public static cuDoubleComplex[] PerformFft(cuDoubleComplex[] data, int size, TransformDirection direction)
 {
     if (cudaAvailable)
     {
         return(cuHelper.PerformFFT(data, size, direction));
     }
     else
     {
         cuDoubleComplex[] result = new cuDoubleComplex[size * size];
         using (var input = new AlignedArrayComplex(16, size, size))
             using (var output = new AlignedArrayComplex(16, input.GetSize()))
             {
                 for (int i = 0; i < input.GetLength(0); i++)
                 {
                     for (int j = 0; j < input.GetLength(1); j++)
                     {
                         input[i, j] = new Complex(data[i * size + j].real, data[i * size + j].imag);
                     }
                 }
                 if (direction == TransformDirection.Forward)
                 {
                     DFT.FFT(input, output);
                 }
                 else
                 {
                     DFT.IFFT(input, output);
                 }
                 for (int i = 0; i < input.GetLength(0); i++)
                 {
                     for (int j = 0; j < input.GetLength(1); j++)
                     {
                         result[i * size + j].real = output[i, j].Real;
                         result[i * size + j].imag = output[i, j].Imaginary;
                     }
                 }
             }
         return(result);
     }
 }
Esempio n. 18
0
            /// <summary>
            /// Routine to simulate motion blur, given the amount of motion blur (it can be any real number!)
            /// and the direction of motion blur.
            /// </summary>
            /// <param name="im">Input double matrix image</param>
            /// <param name="W">Amount of motion blur i.e. 1.3</param>
            /// <param name="alpha">Motion blur direction angle (in degrees) - clockwise</param>
            /// <param name="Parallelize">Boolean to state if you want to parallelize spectral convolution</param>
            /// <returns>The blurred image as double matrix</returns>
            public static double[,] SimulateMotionBlurRoutine(double[,] im, double W, double alpha, bool Parallelize)
            {
                int m = im.GetLength(0);
                int n = im.GetLength(1);

                double[,] outputMat = new double[m, n];
                //Initialize FFTW arrays
                var ImgFFTWInput = CastImageToFFTW(im);
                AlignedArrayComplex FFTWOutputArray     = new AlignedArrayComplex(16, ImgFFTWInput.GetSize());
                AlignedArrayComplex FFTWConvOutputArray = new AlignedArrayComplex(16, ImgFFTWInput.GetSize());

                //Step 1 - Compute image spectrum
                DFT.FFT(ImgFFTWInput, FFTWOutputArray);
                var ImSpectrum = CastFFTWToComplexSpectrum(FFTWOutputArray);
                //Step 2 - Generate Optical Transfer function (OTF)
                var GridU = GenerateFFTMeshGrid(m, n, 1);
                var GridV = GenerateFFTMeshGrid(m, n, 2);

                Complex[,] MB_OTF = new Complex[m, n]; //Initialize OTF
                Double f_indx = new double();          //kernel effective frequency

                for (int u = 0; u < m; u++)
                {
                    for (int v = 0; v < n; v++)
                    {
                        double f_u = GridU[u, v] / m;
                        double f_v = GridV[u, v] / n;
                        f_indx       = Math.Cos(alpha / 180 * Math.PI) * f_u + Math.Sin(alpha / 180 * Math.PI) * f_v;
                        MB_OTF[u, v] = new Complex(Sinc(W * f_indx), 0);
                    }
                }
                //Step 3 - Spectral convolution
                Complex[,] SpecConvolution = new Complex[m, n];
                if (Parallelize)
                {
                    Parallel.For(0, m, u =>
                    {
                        for (int v = 0; v < n; v++)
                        {
                            SpecConvolution[u, v] = Complex.Multiply(MB_OTF[u, v], ImSpectrum[u, v]);
                        }
                    });
                }
                else
                {
                    for (int u = 0; u < m; u++)
                    {
                        for (int v = 0; v < n; v++)
                        {
                            SpecConvolution[u, v] = Complex.Multiply(MB_OTF[u, v], ImSpectrum[u, v]);
                        }
                    }
                }
                //Step 4 - Inverse fourier transform to get the blurred image
                var FFTWSpecConvolution = CastSpectrumToFFTW(SpecConvolution);

                DFT.IFFT(FFTWSpecConvolution, FFTWConvOutputArray);
                var ConvOutputArray = CastFFTWToComplexSpectrum(FFTWConvOutputArray); //Just doing this to get the real part of IFFT

                if (Parallelize)
                {
                    Parallel.For(0, m, u =>
                    {
                        for (int v = 0; v < n; v++)
                        {
                            outputMat[u, v] = ConvOutputArray[u, v].Magnitude;
                        }
                    });
                }
                else
                {
                    for (int u = 0; u < m; u++)
                    {
                        for (int v = 0; v < n; v++)
                        {
                            outputMat[u, v] = ConvOutputArray[u, v].Magnitude;
                        }
                    }
                }
                //Print wisdom
                DFT.Wisdom.Export("exp_wis.txt");
                //Try to clear out as much memory as I can
                FFTWOutputArray.Dispose();
                ImgFFTWInput.Dispose();
                FFTWConvOutputArray.Dispose();
                GC.Collect();
                return(outputMat);
            }