Example #1
0
        public static Complex[] RealFastFourierTransform(double[] src, double amplitude = 1.0)
        {
            int n4 = 1 << (Mt.Log2Int(src.Length) - 2);
            int n = n4 * 4, n2 = n4 * 2, n3 = n4 * 3;
            int n2mask = n2 - 1;

            Complex[] Data = new Complex[n2 + 1];
            for (int i = n2; --i >= 0;)
            {
                Data[i] = new Complex(src[i * 2], src[i * 2 + 1]);
            }
            Complex[]       Dst      = FastFourierTransform_(Data, true);
            TriangularTable Triangle = TriangularTable.Get(n);

            for (int i = n4; i >= 0; --i)
            {
                int     j  = n2 - i;
                Complex g1 = Dst[i];
                Complex g2 = Complex.Conjugate(Dst[j & n2mask]);
                Complex h1 = (g1 + g2);
                Complex h2 = (g1 - g2) * Triangle.Complex(n3 - i);
                Data[i] = (h1 + h2);
                Data[j] = Complex.Conjugate(h1 - h2);
            }
            LetMul(Data, amplitude / 2);
            return(Data);
        }
Example #2
0
 public static TriangularTable Get(int size)
 {
     for (int i = Stocks.Count; --i >= 0;)
     {
         var s = Stocks[i];
         if (s.size == size)
         {
             if (i < Stocks.Count - 1)
             {
                 Stocks.RemoveAt(i);
                 Stocks.Add(s);
             }
             return(s);
         }
     }
     {
         var s = new TriangularTable(size);
         if (Stocks.Count >= 8)
         {
             Stocks.RemoveAt(0);
         }
         Stocks.Add(s);
         return(s);
     }
 }
Example #3
0
        static Complex[] FastFourierTransform_(Complex[] src, bool sw)
        {
            int l = Mt.Log2Int(src.Length);
            int n = 1 << l;

            Complex[] Data = new Complex[n];
            for (int j = -(n >> 1), i = 0; i < n; i++)
            {
                int k = n;
                while ((k >>= 1) <= j)
                {
                    j -= k;
                }
                j      += k;
                Data[i] = src[j];
            }

            int             sign     = sw ? -1 : 1;
            TriangularTable Triangle = TriangularTable.Get(n);

            for (int m = 0; m < l; m++)
            {
                int step = 1 << m;
                int rotw = sign * (1 << (l - 1 - m));
                for (int k = 0; k < step; k++)
                {
                    Complex u = Triangle.Complex(rotw * k);  // (2 * Math.PI / n) * rotw * k
                    for (int i = k; i < n; i += step * 2)
                    {
                        Complex t = Data[i + step] * u;
                        Data[i + step] = Data[i] - t;
                        Data[i]       += t;
                    }
                }
            }
            return(Data);
        }
Example #4
0
        public static double[] RealFastFourierTransform(Complex[] src, double amplitude = 1.0)
        {
            int n4 = 1 << (Mt.Log2Int(src.Length) - 1);
            int n = n4 * 4, n2 = n4 * 2, n3 = n4 * 3;
            int n2mask = n2 - 1;

            Complex[]       Data     = new Complex[n2];
            TriangularTable Triangle = TriangularTable.Get(n);

            for (int i = n4; i >= 0; --i)
            {
                int     j  = n2 - i;
                Complex g1 = src[i];
                Complex g2 = Complex.Conjugate(src[j]);
                Complex h1 = (g1 + g2);
                Complex h2 = (g1 - g2) * Triangle.Complex(n4 + i);
                Data[i]          = (h1 + h2);
                Data[j & n2mask] = Complex.Conjugate(h1 - h2);
            }
            Data = FastFourierTransform_(Data, false);
            LetMul(Data, amplitude / n);
            double[] Dst = New.Array(n, i => (i & 1) == 0 ? Data[i / 2].Real : Data[i / 2].Imaginary);
            return(Dst);
        }