/// <summary> /// Calculate function self-convolution values /// </summary> /// <param name="f">Function values</param> /// <returns></returns> public double[] Build(double[] f) { int length = (_functionType == FunctionType.Periodic) ? f.Length : (f.Length + f.Length - 1); var input = new fftw_complexarray(length); var output = new fftw_complexarray(length); fftw_plan forward = fftw_plan.dft_1d(length, input, output, fftw_direction.Forward, fftw_flags.Estimate); fftw_plan backward = fftw_plan.dft_1d(length, input, output, fftw_direction.Backward, fftw_flags.Estimate); var complex = new Complex[length]; for (int i = 0; i < f.Length; i++) { complex[i] = f[i]; } input.SetData(complex); forward.Execute(); complex = output.GetData_Complex(); input.SetData(complex.Select(x => x * x / length).ToArray()); backward.Execute(); complex = output.GetData_Complex(); return(complex.Select(x => x.Magnitude).ToArray()); }
private Complex FFTW(int index_Entry, int index_Value) { int SIZE = Convert.ToInt32(mCFGData.SamplingPoint / mCFGData.Hz); double[] data = new double[SIZE]; Complex[] cdata = new Complex[SIZE]; for (int i = 0; i < SIZE; i++) { if ((index_Entry < SIZE / 2 && (i < SIZE / 2 - index_Entry)) || (i + index_Entry - (SIZE / 2 - 1)) > mCFGData.TotalPoint) { cdata[i] = new Complex(0, 0); } else { cdata[i] = new Complex(Convert.ToDouble(mDATData.arrData[i + index_Entry - SIZE / 2].value[index_Value]), 0); } } fftw_complexarray input = new fftw_complexarray(SIZE); fftw_complexarray ReData = new fftw_complexarray(SIZE); input.SetData(cdata); fftw_plan pf = fftw_plan.dft_1d(SIZE, input, ReData, fftw_direction.Forward, fftw_flags.Estimate); pf.Execute(); var data_Complex = ReData.GetData_Complex(); return(data_Complex[1]); }
private void CreateMaxLenSequence() { var minDisc = 1; var nPer = 1; var tEnv = 0.8; var dnl = 0.4; var q = 2; var N = Period * minDisc * nPer; var ArrSz = ((N + 1) / 2) * 2; var OnePer = Period * minDisc; var exp = 1.0; if (Math.Sign(tEnv) != 0) { exp = 1 - Math.Exp(-1.0 / tEnv); } var aq = q * Math.Pow(q, 1.0 / (q - 1)) / (q - 1) * dnl; var uc = 0.0; var unl = 0.0; Reset(); for (var i = 0; i < N; i++) { var x = NextValue() * 2 - 1; _mls[i] = x; _correlations[i] = unl; uc += (x - uc) * exp; unl = uc + (Math.Abs(Math.Pow(uc, q - 1)) - 1) * aq * uc; } _real.SetData(_mls); _forward.Execute(); var fftMls = _complex.GetData_Complex(); _real.SetData(_correlations); _forward.Execute(); _complex.SetData(_complex.GetData_Complex().Zip(fftMls, (x, y) => Complex.Conjugate(y) * x / N).ToArray()); _backward.Execute(); _correlations = _real.GetData_double(); }
static void Main(string[] args) { const int sampleSize = 1024; double[] din = new double[sampleSize * 2]; double[] dout = new double[sampleSize * 2]; din[0] = 1; fftw_complexarray mdin = new fftw_complexarray(din); fftw_complexarray mdout = new fftw_complexarray(dout); fftw_plan plan = fftw_plan.dft_1d(sampleSize, mdin, mdout, fftw_direction.Forward, fftw_flags.Estimate); plan.Execute(); plan = fftw_plan.dft_1d(sampleSize, mdout, mdin, fftw_direction.Forward, fftw_flags.Estimate); plan.Execute(); System.Numerics.Complex[] o = mdin.GetData_Complex(); }
// Tests a single plan, displaying results // plan: Pointer to plan to test public void TestPlan(object plan, string planName) { // a: adds, b: muls, c: fmas double a = 0, b = 0, c = 0; int start = System.Environment.TickCount; if (plan is IntPtr) { IntPtr umplan = (IntPtr)plan; for (int i = 0; i < repeatPlan; i++) { fftwf.execute(umplan); } fftwf.flops(umplan, ref a, ref b, ref c); } if (plan is fftw_plan) { fftw_plan mplan = (fftw_plan)plan; for (int i = 0; i < repeatPlan; i++) { mplan.Execute(); } fftw.flops(mplan.Handle, ref a, ref b, ref c); } if (plan is fftwf_plan) { fftwf_plan mplan = (fftwf_plan)plan; for (int i = 0; i < repeatPlan; i++) { mplan.Execute(); } fftwf.flops(mplan.Handle, ref a, ref b, ref c); } double mflops = (((a + b + 2 * c)) * repeatPlan) / (1024 * 1024); long ticks = (System.Environment.TickCount - start); //Console.WriteLine($"Plan '{planName}': {ticks.ToString("#,0")} us | mflops: {FormatNumber(mflops)} | mflops/s: {(1000*mflops/ticks).ToString("#,0.0")}"); Console.WriteLine("Plan '{0}': {1,8:N0} us | mflops: {2,8:N0} | mflops/s: {3,8:N0}", planName, ticks, mflops, (1000 * mflops / ticks)); }
/// <summary> /// Generate a spectrogram array spaced linearily /// </summary> /// <param name="samples">audio data</param> /// <param name="fftWindowsSize">fft window size</param> /// <param name="fftOverlap">overlap in number of samples (normaly half of the fft window size) [low number = high overlap]</param> /// <returns>spectrogram jagged array</returns> public static double[][] CreateSpectrogramFFTWLIB(float[] samples, int fftWindowsSize, int fftOverlap) { int numberOfSamples = samples.Length; // overlap must be an integer smaller than the window size // half the windows size is quite normal double[] windowArray = FFTWindow.GetWindowFunction(FFTWindowType.HANNING, fftWindowsSize); // width of the segment - e.g. split the file into 78 time slots (numberOfSegments) and do analysis on each slot int numberOfSegments = (numberOfSamples - fftWindowsSize) / fftOverlap; var frames = new double[numberOfSegments][]; // even - Re, odd - Img var complexSignal = new double[2 * fftWindowsSize]; for (int i = 0; i < numberOfSegments; i++) { // apply Hanning Window for (int j = 0; j < fftWindowsSize; j++) { // Weight by Hann Window complexSignal[2 * j] = (double)(windowArray[j] * samples[i * fftOverlap + j]); // need to clear out as fft modifies buffer (phase) complexSignal[2 * j + 1] = 0; } // prepare the input arrays var complexInput = new fftw_complexarray(complexSignal); var complexOutput = new fftw_complexarray(complexSignal.Length / 2); fftw_plan fft = fftw_plan.dft_1d(complexSignal.Length / 2, complexInput, complexOutput, fftw_direction.Forward, fftw_flags.Estimate); // perform the FFT fft.Execute(); // get the result frames[i] = complexOutput.Abs; // free up memory complexInput = null; complexOutput = null; //GC.Collect(); } return(frames); }
/// <summary> /// Perform the Fast Fourier Transform utilisizing the FFTW library /// </summary> /// <param name="in">Input Signal</param> /// <param name="out">Output Signal</param> /// <param name="N">N</param> /// <param name="method">FFT Method (DFT, IDFT, DHT)</param> public static void FFT(ref double[] @in, ref double[] @out, int N, FFTMethod method) { var complexInput = new fftw_complexarray(@in); var complexOutput = new fftw_complexarray(@out); switch (method) { case FFTMethod.DFT: // fftw_kind.R2HC: input is expected to be real while output is returned in the halfcomplex format fftw_plan fft = fftw_plan.r2r_1d(N, complexInput, complexOutput, fftw_kind.R2HC, fftw_flags.Estimate); fft.Execute(); @out = complexOutput.Values; // free up memory fft = null; break; case FFTMethod.IDFT: // fftw_kind.HC2R: input is expected to be halfcomplex format while output is returned as real fftw_plan ifft = fftw_plan.r2r_1d(N, complexInput, complexOutput, fftw_kind.HC2R, fftw_flags.Estimate); ifft.Execute(); //@out = complexOutput.ValuesDividedByN; // dividing by N gives the correct scale @out = complexOutput.Values; // free up memory ifft = null; break; case FFTMethod.DHT: fftw_plan dht = fftw_plan.r2r_1d(N, complexInput, complexOutput, fftw_kind.DHT, fftw_flags.Estimate); dht.Execute(); @out = complexOutput.Values; // free up memory dht = null; break; } // free up memory complexInput = null; complexOutput = null; GC.Collect(); }
/// <summary> /// Perform the Fast Fourier Transform utilisizing the FFTW library /// </summary> /// <param name="in">Input Signal</param> /// <param name="out">Output Signal</param> /// <param name="N">N</param> /// <param name="method">FFT Method (DFT, IDFT, DHT)</param> public static void FFT(ref double[] @in, ref double[] @out, int N, FFTMethod method) { fftw_complexarray complexInput = new fftw_complexarray(@in); fftw_complexarray complexOutput = new fftw_complexarray(@out); switch (method) { case FFTMethod.DFT: fftw_plan fft = fftw_plan.r2r_1d(N, complexInput, complexOutput, fftw_kind.R2HC, fftw_flags.Estimate); fft.Execute(); @out = complexOutput.Values; // free up memory fft = null; break; case FFTMethod.IDFT: fftw_plan ifft = fftw_plan.r2r_1d(N, complexInput, complexOutput, fftw_kind.HC2R, fftw_flags.Estimate); ifft.Execute(); @out = complexOutput.ValuesDividedByN; // free up memory ifft = null; break; case FFTMethod.DHT: fftw_plan dht = fftw_plan.r2r_1d(N, complexInput, complexOutput, fftw_kind.DHT, fftw_flags.Estimate); dht.Execute(); @out = complexOutput.Values; // free up memory dht = null; break; } // free up memory complexInput = null; complexOutput = null; GC.Collect(); }
public void TestAll() { System.Console.WriteLine("Testing single precision:\n"); TestPlan(fplan1); TestPlan(fplan2); TestPlan(fplan3); // set fin to 0, and try to refill it from a backwards fft from fout (aka hin/hout) for (int i = 0; i < fftLength * 2; i++) { fin[i] = 0; } TestPlan(fplan4); // check and see how we did, don't say anyt for (int i = 0; i < fftLength * 2; i++) { // check against original values // note that we need to scale down by length, due to FFTW scaling by N if (System.Math.Abs(fin[i] / fftLength - (i % 50)) > 1e-3) { System.Console.WriteLine("FFTW consistency error!"); return; } } System.Console.WriteLine("FFT consistency check ok.\n\nTesting double precision:\n"); //TestPlan(fplan5); System.Console.WriteLine("Testing managed interface:\n"); mplan.Execute(); // yeah alright so this was kind of a trivial test and of course it's gonna work. but still. System.Console.WriteLine("Ok."); }
// seem to the be the fastest FFT? static double[] FFTWLIB(double[] signal) { var complexSignal = FFTUtils.DoubleToComplexDouble(signal); // prepare the input arrays var complexInput = new fftw_complexarray(complexSignal); var complexOutput = new fftw_complexarray(complexSignal.Length / 2); fftw_plan fft = fftw_plan.dft_1d(complexSignal.Length / 2, complexInput, complexOutput, fftw_direction.Forward, fftw_flags.Estimate); // perform the FFT fft.Execute(); // get the result var spectrum_fft_abs = complexOutput.Abs; //Export.ExportCSV("audio_buffer_padded2.csv", signal); //Export.ExportCSV("spectrum_fft_abs2.csv", spectrum_fft_abs2, fftSize); // free up memory complexInput = null; complexOutput = null; return(spectrum_fft_abs); }
/// <summary> /// Blur bitmap with the Fastest Fourier Transform /// </summary> /// <returns>Blured bitmap</returns> private double[,,] Blur(double[,,] imageData) { int length = imageData.Length; int n0 = imageData.GetLength(0); int n1 = imageData.GetLength(1); int n2 = imageData.GetLength(2); var input = new fftw_complexarray(length); var output = new fftw_complexarray(length); fftw_plan forward = fftw_plan.dft_3d(n0, n1, n2, input, output, fftw_direction.Forward, fftw_flags.Estimate); fftw_plan backward = fftw_plan.dft_3d(n0, n1, n2, input, output, fftw_direction.Backward, fftw_flags.Estimate); var doubles = new double[length]; Buffer.BlockCopy(imageData, 0, doubles, 0, length * sizeof(double)); double average = doubles.Average(); double delta = Math.Sqrt(doubles.Average(x => x * x) - average * average); switch (_keepOption) { case KeepOption.AverageAndDelta: break; case KeepOption.Sum: average = doubles.Sum(); break; case KeepOption.Square: average = Math.Sqrt(doubles.Sum(x => x * x)); break; case KeepOption.AverageSquare: average = Math.Sqrt(doubles.Average(x => x * x)); break; default: throw new NotImplementedException(); } input.SetData(doubles.Select(x => new Complex(x, 0)).ToArray()); forward.Execute(); Complex[] complex = output.GetData_Complex(); var data = new Complex[n0, n1, n2]; var buffer = new double[length * 2]; GCHandle complexHandle = GCHandle.Alloc(complex, GCHandleType.Pinned); GCHandle dataHandle = GCHandle.Alloc(data, GCHandleType.Pinned); IntPtr complexPtr = complexHandle.AddrOfPinnedObject(); IntPtr dataPtr = dataHandle.AddrOfPinnedObject(); Marshal.Copy(complexPtr, buffer, 0, buffer.Length); Marshal.Copy(buffer, 0, dataPtr, buffer.Length); switch (_mode) { case Mode.BlinderSize: Blind(data, _blinderSize); break; case Mode.FilterStep: int filterStep = _filterStep; var blinderSize = new Size(MulDiv(n1, filterStep, filterStep + 1), MulDiv(n0, filterStep, filterStep + 1)); Blind(data, blinderSize); break; default: throw new NotImplementedException(); } Marshal.Copy(dataPtr, buffer, 0, buffer.Length); Marshal.Copy(buffer, 0, complexPtr, buffer.Length); complexHandle.Free(); dataHandle.Free(); input.SetData(complex); backward.Execute(); doubles = output.GetData_Complex().Select(x => x.Magnitude).ToArray(); double average2 = doubles.Average(); double delta2 = Math.Sqrt(doubles.Average(x => x * x) - average2 * average2); switch (_keepOption) { case KeepOption.AverageAndDelta: break; case KeepOption.Sum: average2 = doubles.Sum(); break; case KeepOption.Square: average2 = Math.Sqrt(doubles.Sum(x => x * x)); break; case KeepOption.AverageSquare: average2 = Math.Sqrt(doubles.Average(x => x * x)); break; default: throw new NotImplementedException(); } // a*average2 + b == average // a*delta2 == delta double a = (_keepOption == KeepOption.AverageAndDelta) ? (delta / delta2) : (average / average2); double b = (_keepOption == KeepOption.AverageAndDelta) ? (average - a * average2) : 0; Debug.Assert(Math.Abs(a * average2 + b - average) < 0.1); doubles = doubles.Select(x => Math.Round(a * x + b)).ToArray(); Buffer.BlockCopy(doubles, 0, imageData, 0, length * sizeof(double)); return(imageData); }
/// <summary> /// Catch pattern bitmap with the Fastest Fourier Transform /// </summary> /// <returns>Matrix of values</returns> private Matrix <double> Catch(Image <Gray, double> image) { const double f = 1.0; int length = image.Data.Length; int n0 = image.Data.GetLength(0); int n1 = image.Data.GetLength(1); int n2 = image.Data.GetLength(2); Debug.Assert(n2 == 1); // Allocate FFTW structures var input = new fftw_complexarray(length); var output = new fftw_complexarray(length); fftw_plan forward = fftw_plan.dft_3d(n0, n1, n2, input, output, fftw_direction.Forward, fftw_flags.Estimate); fftw_plan backward = fftw_plan.dft_3d(n0, n1, n2, input, output, fftw_direction.Backward, fftw_flags.Estimate); var matrix = new Matrix <double>(n0, n1); double[,,] patternData = _patternImage.Data; double[,,] imageData = image.Data; double[,] data = matrix.Data; var doubles = new double[length]; // Calculate Divisor Copy(patternData, data); Buffer.BlockCopy(data, 0, doubles, 0, length * sizeof(double)); input.SetData(doubles.Select(x => new Complex(x, 0)).ToArray()); forward.Execute(); Complex[] complex = output.GetData_Complex(); Buffer.BlockCopy(imageData, 0, doubles, 0, length * sizeof(double)); input.SetData(doubles.Select(x => new Complex(x, 0)).ToArray()); forward.Execute(); input.SetData(complex.Zip(output.GetData_Complex(), (x, y) => x * y).ToArray()); backward.Execute(); IEnumerable <double> doubles1 = output.GetData_Complex().Select(x => x.Magnitude); if (_fastMode) { // Fast Result Buffer.BlockCopy(doubles1.ToArray(), 0, data, 0, length * sizeof(double)); return(matrix); } // Calculate Divider (aka Power) input.SetData(doubles.Select(x => new Complex(x * x, 0)).ToArray()); forward.Execute(); complex = output.GetData_Complex(); CopyAndReplace(_patternImage.Data, data); Buffer.BlockCopy(data, 0, doubles, 0, length * sizeof(double)); input.SetData(doubles.Select(x => new Complex(x, 0)).ToArray()); forward.Execute(); input.SetData(complex.Zip(output.GetData_Complex(), (x, y) => x * y).ToArray()); backward.Execute(); IEnumerable <double> doubles2 = output.GetData_Complex().Select(x => x.Magnitude); // Result Buffer.BlockCopy(doubles1.Zip(doubles2, (x, y) => (f + x * x) / (f + y)).ToArray(), 0, data, 0, length * sizeof(double)); return(matrix); }
//public float[] Correct(float[] data) //{ // var res = new float[ArrSz]; // for (int i = 1; i < N; i++) // { // res[i] = data[i] - data[N - i]; // } // res[0] = data[0]; // return res; //} //public int GetPeak() //{ // int maxI = Correlation.Length/2; // for (int i = 2; i < Correlation.Length; i++) // { // if (Correlation[i].CompareTo(Correlation[maxI]) > 0) maxI = i; // } // return maxI; //} //public void Normalize() //{ // int n = Correlation.Length; // Correlation = Correlation.Select(x => (float)Math.Round(x + 1)).ToArray(); //} //public float[] DeltaCalculate() //{ // var mlsInt = new int[ArrSz]; // var responseNlInt = new int[ArrSz]; // int amp = (int)Math.Round(Math.Pow(10, 180 / 20.0)); // double uc = 0; // _gen.Reset(); // for (int i = 0; i < N; i++) // { // var x = _gen.NextValue() * 2 - 1; // var unl = (1 - aq) * uc + aq * uc * Math.Abs(Math.Pow(uc, q - 1)); // mlsInt[i] = i < _gen.Period ? x : 0; // responseNlInt[i] = (int)Math.Round(unl * amp); // uc += (x - uc) * exp; // } // real.SetData(mlsInt.Select((x)=>(float)x).ToArray()); // forward.Execute(); // var fftMls = complex.GetData_Complex(); // real.SetData(responseNlInt.Select((x) => (float)x).ToArray()); // forward.Execute(); // complex.SetData(complex.GetData_Complex().Zip(fftMls, (x, y) => Complex.Conjugate(y) * x / N).ToArray()); // backward.Execute(); // var fftCorr = real.GetData_float(); // var delta = new float[ArrSz]; // for (int i = 0; i < N; i++) // { // long res = 0; // for (int j = 0; j < N; j++) // { // int k = i + j - N; // if (k < 0) k += N; // res += mlsInt[j] *1L* responseNlInt[k]; // } // delta[i] = (long)Math.Round(fftCorr[i]) - res; // } // return delta; //} public void Calculate() { double uc = 0; double unl = 0; _gen.Reset(); if (_isFastMode) { for (int i = 0; i < N; i++) { var x = _gen.NextValue() * 2 - 1; Mls[i] = x; ResponseNL[i] = (T)unl; uc += (x - uc) * _exp; unl = uc + (Math.Abs(Math.Pow(uc, _q - 1)) - 1) * _aq * uc; } } else { for (int i = 0; i < N / _minDisc; i++) { var x = _gen.NextValue() * 2 - 1; for (int j = 0; j < _minDisc; j++) { var arrI = i * _minDisc + j; if (arrI < OnePer) { Mls[arrI] = x; } ResponseE[arrI] = (T)uc; ResponseNL[arrI] = (T)unl; uc += (x - uc) * _exp; unl = uc + (Math.Abs(Math.Pow(uc, _q - 1)) - 1) * _aq * uc; } } } real.SetData(Mls); forward.Execute(); var fftMls = complex.GetData_Complex(); if (!_isFastMode) { real.SetData(ResponseE); forward.Execute(); complex.SetData(complex.GetData_Complex() .Zip(fftMls, (x, y) => Complex.Conjugate(y) * x / N) .ToArray()); backward.Execute(); CorrelationE = real.GetData_double(); } real.SetData(ResponseNL); forward.Execute(); complex.SetData(complex.GetData_Complex().Zip(fftMls, (x, y) => Complex.Conjugate(y) * x / N).ToArray()); backward.Execute(); if (_isFastMode) { ResponseNL = real.GetData_double(); } else { CorrelationNL = real.GetData_double(); } }