Ejemplo 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);
        }
Ejemplo n.º 2
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();
                    }
                }
        }
Ejemplo n.º 3
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);
        }
Ejemplo n.º 4
0
        public double[] timeDelaySignal(short[] signalInput, double s)
        {
            double[] input = new double[signalInput.Length];
            for (int j = 0; j < signalInput.Length; j++)
            {
                input[j] = (double)signalInput[j];
            }

            Complex[] output = new Complex[input.GetLength(input.Rank - 1) / 2 + 1];
            double[]  inOut  = new double[input.Length];

            using (var pinIn = new PinnedArray <double>(input))
                using (var pinOut = new PinnedArray <Complex>(output))
                    using (var in1Out = new PinnedArray <double>(inOut))
                    {
                        DFT.FFT(pinIn, pinOut);
                        for (int j = 0; j < pinOut.Length; j++)
                        {
                            double angle = ((2 * Math.PI) / pinOut.Length) * SampleRate * j * s;
                            pinOut[j] = pinOut[j] * Complex.Exp(new Complex(0, -angle));
                        }

                        DFT.IFFT(pinOut, in1Out);
                        for (int j = 0; j < inOut.Length; j++)
                        {
                            inOut[j] = inOut[j] / input.Length;
                        }
                        return(inOut);
                    }
        }
Ejemplo n.º 5
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);
        }
Ejemplo n.º 6
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);
        }
Ejemplo n.º 7
0
        static void Example1D()
        {
            double[]  input  = new double[24];
            Complex[] output = new Complex[input.GetLength(input.Rank - 1) / 2 + 1];
            double[]  inOut  = new double[input.Length];

            for (int i = 0; i < input.Length; i++)
            {
                input[i] = Math.Sin(i * 2 * Math.PI * 128 / input.Length);
            }

            using (var pinIn = new PinnedArray <double>(input))
                using (var pinOut = new PinnedArray <Complex>(output))
                    using (var in1Out = new PinnedArray <double>(inOut))
                    {
                        Console.WriteLine(pinIn.GetLength(input.Rank - 1) / 2 + 1);
                        Console.WriteLine(pinOut.GetLength(input.Rank - 1));

                        Console.WriteLine(input.Length);
                        Console.WriteLine(output.Length);

                        DFT.FFT(pinIn, pinOut);
                        DFT.IFFT(pinOut, in1Out);
                    }

            Console.WriteLine("Input");

            for (int i = 0; i < input.Length; i++)
            {
                Console.WriteLine(Math.Sin(i * 2 * Math.PI * 128 / input.Length));
            }

            Console.WriteLine();
            Console.WriteLine();

            Console.WriteLine("output");
            for (int i = 0; i < inOut.Length; i++)
            {
                Console.WriteLine(inOut[i] / input.Length);
            }
        }
Ejemplo n.º 8
0
        static void Example1D()
        {
            Complex[] input  = new Complex[2048];
            Complex[] output = new Complex[input.Length];

            for (int i = 0; i < input.Length; i++)
            {
                input[i] = Math.Sin(i * 2 * Math.PI * 128 / input.Length);
            }

            using (var pinIn = new PinnedArray <Complex>(input))
                using (var pinOut = new PinnedArray <Complex>(output))
                {
                    DFT.FFT(pinIn, pinOut);
                    DFT.IFFT(pinOut, pinOut);
                }

            for (int i = 0; i < input.Length; i++)
            {
                Console.WriteLine(output[i] / input[i]);
            }
        }
Ejemplo n.º 9
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);
     }
 }
Ejemplo n.º 10
0
        public void FFTWTest()
        {
            Complex[] input  = new Complex[8192];
            Complex[] output = new Complex[input.Length];

            GetData(input, input.Length);
            //for (int i = 0; i < input.Length; i++)
            //    input[i] = Math.Sin(i * 2 * Math.PI * 128 / input.Length);

            using (var pinIn = new PinnedArray <Complex>(input))
                using (var pinOut = new PinnedArray <Complex>(output))
                {
                    DFT.FFT(pinIn, pinOut, nThreads: 12);
                    DFT.IFFT(pinOut, pinOut, nThreads: 12);
                }

            Console.WriteLine("Real, Imaginary, Magnitude, Phase, ToString");
            for (int i = 0; i < input.Length; i++)
            {
                Complex result = output[i] / input[i];
                Console.WriteLine($"{result.Real},{result.Imaginary}, {result.Magnitude},{result.Phase},{result.ToString()}");
            }
        }
Ejemplo n.º 11
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);
            }
Ejemplo n.º 12
0
        public static double[] ApplyDistortion(double[] samples, double distortionStrength, WaveFormat fmt)
        {
            List <double> processedSamples = new List <double>();

            //list containing overlapping sound frames
            List <double> savedTimeDomain = new List <double>(SoundProcessing.Constants.FFT_FRAME_LENGTH);

            SoundProcessing.PadZeroes(savedTimeDomain, SoundProcessing.Constants.FFT_FRAME_LENGTH);//pad zeroes to have required container size

            //build a filter mask specified for the distortion
            double[] filterMask = FilterMasks.DistortionMask(
                SoundProcessing.Constants.FREQUENCY_DOMAIN_LENGTH,
                distortionStrength,
                fmt
                );

            for (int i = 0; i < samples.Length; i += SoundProcessing.Constants.FFT_FRAME_LENGTH)
            {
                //cut out a data frame from samples
                var data = samples.Slice(i, SoundProcessing.Constants.FFT_LENGTH);
                //prepare a buffer for FFT
                var complices = new Complex[SoundProcessing.Constants.FREQUENCY_DOMAIN_LENGTH];

                //arrays containing the input samples, the result of FFT and the result of IFFT
                PinnedArray <double>  input           = new PinnedArray <double>(data);
                PinnedArray <Complex> frequencyDomain = new PinnedArray <Complex>(complices);
                PinnedArray <double>  timeDomain      = new PinnedArray <double>(data.Length);

                //convert time domain to frequency domain
                DFT.FFT(input, frequencyDomain);

                //mask the frequencies using a mask created earlier
                for (int j = 0; j < frequencyDomain.Length; ++j)
                {
                    frequencyDomain[j] *= filterMask[j];
                }

                //mask negative frequencies
                for (int j = frequencyDomain.Length - 1; j > frequencyDomain.Length / 2; --j)
                {
                    frequencyDomain[j] *= filterMask[frequencyDomain.Length - j];
                }

                //convert back to time domain
                DFT.IFFT(frequencyDomain, timeDomain);

                //overlapping of the frames
                for (int j = 0; j < SoundProcessing.Constants.OVERLAP; ++j)
                {
                    timeDomain[j] *= (j + 0.0) / SoundProcessing.Constants.OVERLAP;
                    timeDomain[j] += savedTimeDomain[j] * (1.0 - (j + 0.00) / (double)SoundProcessing.Constants.OVERLAP); //overlap with previous samples to avoid stuttering
                }

                //add overlapping sound samples
                savedTimeDomain.Clear();
                for (int j = SoundProcessing.Constants.FFT_FRAME_LENGTH; j < timeDomain.Length; ++j)
                {
                    savedTimeDomain.Add(MathUtils.Clamp(timeDomain[j], -1.0, 1.0));
                }

                //add the actual samples
                for (int j = 0; j < SoundProcessing.Constants.FFT_FRAME_LENGTH; ++j)
                {
                    processedSamples.Add(MathUtils.Clamp(timeDomain[j], -1.0, 1.0));
                }

                //dispose of the PinnedArray objects
                input.Dispose();
                frequencyDomain.Dispose();
                timeDomain.Dispose();
            }

            return(processedSamples.ToArray());
        }