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); }
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(); } } }
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); }
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); } }
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); }
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); }
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); } }
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]); } }
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); } }
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()}"); } }
/// <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); }
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()); }