Beispiel #1
0
        /// <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());
        }
Beispiel #2
0
        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();
        }
Beispiel #4
0
        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();
        }
Beispiel #5
0
        // 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));
        }
Beispiel #6
0
        /// <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();
        }
Beispiel #8
0
    /// <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();
    }
Beispiel #9
0
        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.");
        }
Beispiel #10
0
        // 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);
        }
Beispiel #11
0
        /// <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);
        }
Beispiel #13
0
        //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();
            }
        }