Beispiel #1
0
        /// <summary>
        /// Backward short-time Fourier Transform.
        /// </summary>
        /// <param name="B">Array</param>
        /// <returns>Array</returns>
        public Complex32[] Backward(Complex32[] B)
        {
            int N = B.Length, i, j;

            Complex32[] A     = new Complex32[N];
            int         frame = coefs.Length;

            for (i = 0; i < N; i += frame)
            {
                Complex32[] data = new Complex32[frame];

                for (j = 0; j < frame; j++)
                {
                    data[j] = B[i + j];
                }

                data = FFT.Backward(data);

                for (j = 0; j < frame; j++)
                {
                    A[i + j] = data[j] / coefs[Maths.Mod(i - frame / 2, frame)];
                }
            }

            return(A);
        }
        /// <summary>
        /// Fast forward Weyl-Heisenberg transform.
        /// </summary>
        /// <param name="input">Array</param>
        /// <param name="g0">Function</param>
        /// <param name="M">Number of frequency shifts</param>
        /// <returns>Array</returns>
        public static Complex32[] WHT(Complex32[] input, float[] g0, int M)
        {
            // The function implements a fast Weil-Heisenberg direct transformation algorithm,
            // stated in the following articles:
            // A. Vahlin, "EFFICIENT ALGORITHMS FOR MODULATION AND DEMODULATION IN OFDM-SYSTEMS" [1].
            // V.M. Asiryan, V.P. Volchkov, "EFFECTIVE IMPLEMENTATION OF THE DIRECT TRANSFORMATION OF WEIL-HEISENBERG" [2].
            // The algorithm is computationally efficient for large M.

            int N = input.Length, L = N / M, M2 = M / 2, M4 = M2 / 2;

            Complex32[] output = new Complex32[N];
            Complex32[] exp    = FastWeylHeisenbergTransform.GetRotation(M);

            Complex32[,] s0 = new Complex32[M, L];
            Complex32[,] a0 = new Complex32[M, L];
            Complex32[,] b0 = new Complex32[M, L];
            Complex32[,] A0 = new Complex32[L, M];
            Complex32[,] B0 = new Complex32[L, M];
            Complex32[,] A1 = new Complex32[L, M2];
            Complex32[,] B1 = new Complex32[L, M2];
            Complex32 c1re, c2re;
            Complex32 c1im, c2im;
            int       k, i, j, u, n, m, l;

            for (m = 0; m < M; m++)
            {
                for (n = 0; n < L; n++)
                {
                    u = n * M;
                    i = Maths.Mod(m + M4 + u, N);
                    j = Maths.Mod(m - M4 + u, N);
                    k = Maths.Mod(-m - M4 - u, N);

                    s0[m, n] = input[k];
                    a0[m, n] = g0[i];
                    b0[m, n] = g0[j];
                }
            }

            for (l = 0; l < L; l++)
            {
                for (n = 0; n < L; n++)
                {
                    k = Maths.Mod(n - l, L);

                    for (m = 0; m < M; m++)
                    {
                        A0[l, m] += a0[m, n] * s0[m, k];
                        B0[l, m] += b0[m, n] * s0[m, k];
                    }
                }
            }

            Complex32 x, y, z, w;

            for (l = 0; l < L; l++)
            {
                for (m = 0; m < M2; m++)
                {
                    x = A0[l, m];
                    y = A0[l, m + M2];
                    z = A0[l, M2 - m].Conjugate;
                    w = A0[l, Maths.Mod(M - m, M)].Conjugate;

                    c1re = x + y + z + w;
                    c2re = x - y - z + w;

                    x = B0[l, m];
                    y = B0[l, m + M2];
                    z = B0[l, M2 - m].Conjugate;
                    w = B0[l, Maths.Mod(M - m, M)].Conjugate;

                    c1im = x + y - z - w;
                    c2im = x - y + z - w;

                    A1[l, m] = 1.0 / (2) * (c1re + Maths.I * c2re * exp[m]);
                    B1[l, m] = 1.0 / (2 * Maths.I) * (c1im + Maths.I * c2im * exp[m]);
                }
            }

            A1 = FFT.Backward(Matrice.Conjugate(A1));
            B1 = FFT.Backward(Matrice.Conjugate(B1));

            for (k = 0; k < M2; k++)
            {
                for (l = 0; l < L; l++)
                {
                    i = l * M + 2 * k;
                    j = l * M + 2 * k + 1;

                    x = A1[l, k];
                    y = B1[l, k];

                    output[i] = x.Real + Maths.I * y.Real;
                    output[j] = x.Imag + Maths.I * y.Imag;
                }
            }

            return(output);
        }