コード例 #1
0
        /// <summary>
        /// Performs the DFT -- converting a 2D position-domain signal into a 2D frequency-domain signal.
        /// </summary>
        /// <param name="samples">
        /// The samples from an input signal.
        /// </param>
        /// <param name="outResult">
        /// The output array.
        /// If it's null or the wrong size, it will be automatically created.
        /// Contains the sine/cosine wave amplitudes for each frequency in the signal.
        /// </param>
        public static void Forward(Complex[,] samples, ref Complex[,] outResult)
        {
            //Make sure the output array is the right size.
            if (outResult == null ||
                outResult.GetLength(0) != samples.GetLength(0) ||
                outResult.GetLength(1) != samples.GetLength(1))
            {
                outResult = new Complex[samples.GetLength(0), samples.GetLength(1)];
            }


            //Perform the 1D DFT along every row and column.

            //Row:
            Complex[][] dftByRow = new Complex[samples.GetLength(1)][];
            ThreadedRunner.Run(NThreads, samples.GetLength(1),
                               (startY, endY) =>
            {
                Complex[] sampleLine = new Complex[samples.GetLength(0)];
                for (int sampleY = startY; sampleY <= endY; ++sampleY)
                {
                    //Populate the sample array.
                    for (int sampleX = 0; sampleX < samples.GetLength(0); ++sampleX)
                    {
                        sampleLine[sampleX] = samples[sampleX, sampleY];
                    }
                    //Run the dft.
                    dftByRow[sampleY] = Algo1D.Forward(sampleLine);
                }
            });

            //Column:
            var _outResult = outResult; //ref variables can't be used inside a lambda.

            ThreadedRunner.Run(NThreads, samples.GetLength(0),
                               (startX, endX) =>
            {
                Complex[] sampleLine = new Complex[samples.GetLength(1)];
                for (int sampleX = startX; sampleX <= endX; ++sampleX)
                {
                    //Populate the sample array.
                    for (int sampleY = 0; sampleY < samples.GetLength(1); ++sampleY)
                    {
                        sampleLine[sampleY] = dftByRow[sampleY][sampleX];
                    }
                    //Run the dft.
                    var results = Algo1D.Forward(sampleLine);
                    for (int sampleY = 0; sampleY < samples.GetLength(1); ++sampleY)
                    {
                        _outResult[sampleX, sampleY] = results[sampleY];
                    }
                }
            });
        }
コード例 #2
0
        /// <summary>
        /// Performs the inverse DFT -- converting a frequency-domain signal
        ///     back into a 2D position-domain signal.
        /// </summary>
        /// <param name="dftResults">
        /// The frequency-domain signal.
        /// </param>
        /// <param name="outSamples">
        /// The position-domain signal samples.
        /// If the array is null or the wrong size, it will be automatically created.
        /// </param>
        public static void Inverse(Complex[,] dftResults, ref Complex[,] outSamples)
        {
            //Make sure the output array is the right size.
            if (outSamples == null ||
                outSamples.GetLength(0) != dftResults.GetLength(0) ||
                outSamples.GetLength(1) != dftResults.GetLength(1))
            {
                outSamples = new Complex[dftResults.GetLength(0), dftResults.GetLength(1)];
            }

            //Perform the 1D inverse DFT along each row/column.
            //Column:
            Complex[][] inverseDFTByCol = new Complex[dftResults.GetLength(0)][];
            ThreadedRunner.Run(NThreads, dftResults.GetLength(0),
                               (startX, endX) =>
            {
                Complex[] sampleLine = new Complex[dftResults.GetLength(1)];
                for (int sampleX = startX; sampleX <= endX; ++sampleX)
                {
                    //Populate the sample array.
                    for (int sampleY = 0; sampleY < dftResults.GetLength(1); ++sampleY)
                    {
                        sampleLine[sampleY] = dftResults[sampleX, sampleY];
                    }
                    //Run the dft.
                    inverseDFTByCol[sampleX] = Algo1D.Inverse(sampleLine);
                }
            });
            //Row:
            var _outSamples = outSamples; //Can't use a ref variable in a lambda.

            ThreadedRunner.Run(NThreads, dftResults.GetLength(1),
                               (startY, endY) =>
            {
                Complex[] sampleLine = new Complex[dftResults.GetLength(0)];
                for (int sampleY = startY; sampleY <= endY; ++sampleY)
                {
                    //Populate the sample array.
                    for (int sampleX = 0; sampleX < dftResults.GetLength(0); ++sampleX)
                    {
                        sampleLine[sampleX] = inverseDFTByCol[sampleX][sampleY];
                    }
                    //Run the dft.
                    var results = Algo1D.Inverse(sampleLine);
                    for (int sampleX = 0; sampleX < dftResults.GetLength(0); ++sampleX)
                    {
                        _outSamples[sampleX, sampleY] = results[sampleX];
                    }
                }
            });
        }