2019年4月4日木曜日

FFTプログラムの作成(3)

少し暇ができたので見直し。Complex構造体を使ってみました。ビット反転をもう少し効率化したい。

        public static void FFT2Radix2(ref Complex[] Wave)
        {
            int Number = Wave.Length;
            const double PI = Math.PI;
            int StageCount;
            int BlockCount;
            int NodeCount;
            int StageNumber;
            int BlockNumber;
            int NodeNumber;
            int[] IndexBitChange = new int[Number];

            int TempN1;
            int TempN2;

            Complex Temp1;
            Complex Temp2;
            Complex RotationFactor;
            Complex ButterflyResolution;

            //計算準備
            //累乗数を計算
            StageCount = PrimeFactors(Number).Length;

            //バタフライ演算の繰り返しループ
            for (StageNumber = 0; StageNumber < StageCount; StageNumber++)
            {
                //回転因子の分割数
                BlockCount = (int)(Math.Pow(2, StageNumber));
                //分割した回転因子内の信号数
                NodeCount = Number / BlockCount;
                //回転因子の刻み度数
                ButterflyResolution = new Complex(0, -2 * PI / Number * BlockCount);

                //回転因子の分割数に達するまでループを回す
                for (BlockNumber = 0; BlockNumber < BlockCount; BlockNumber++)
                {
                    //バタフライ演算
                    for (NodeNumber = 0; NodeNumber < NodeCount / 2; NodeNumber++)
                    {
                        //回転因子
                        RotationFactor = Complex.Exp(ButterflyResolution * NodeNumber);
                        //バタフライ演算
                        TempN1 = NodeNumber + NodeCount * BlockNumber;
                        TempN2 = TempN1 + NodeCount / 2;
                        Temp1 = Wave[TempN1];
                        Temp2 = Wave[TempN2];
                        Wave[TempN1] = Temp1 + Temp2;
                        Wave[TempN2] = (Temp1 - Temp2) * RotationFactor;
                    }
                }
            }
            //ビット反転
            for (StageNumber = 0; StageNumber < StageCount; StageNumber++)
            {
                for (int i = 0; i < Math.Pow(2, StageNumber); i++)
                {
                    IndexBitChange[(int)Math.Pow(2, StageNumber) + i] = IndexBitChange[i] +
         (int)Math.Pow(2, StageCount - StageNumber - 1);
                }
            }

            for (int i = 0; i < Number; i++)
            {
                if (IndexBitChange[i] > i)
                {
                    Temp1 = Wave[IndexBitChange[i]];
                    Wave[IndexBitChange[i]] = Wave[i];
                    Wave[i] = Temp1;
                }
            }
        }

0 件のコメント:

コメントを投稿