Получение RMS из БПФ

Я хочу получить RMS после выполнения fft для моих данных, чтобы получить тот же результат, что и RMS данных напрямую.

Я следил за этой темой https://fr.mathworks.com/matlabcentral/answers/131353-relation-between-fft-and-rms, но я не могу получить те же результаты, это большая разница.

По теореме Парсеваля «Полная энергия сигнала сохраняется при преобразовании Фурье (теорема Парсеваля), поэтому сумма (или интеграл) квадрата функции равна сумме (или интегралу) квадрата ее преобразования. Среднеквадратичное значение будет квадратным корнем из этого значения».

Поэтому, взяв «_tempMonitorChannelValues» в качестве моих данных с длиной = 400000 выборок, прежде всего я вычисляю среднеквадратичное значение данных следующим образом:

 for (int i = 0; i < _tempMonitorChannelValues.Length; i++)
                    {
                        RMSTIME += Math.Pow(_tempMonitorChannelValues[i], 2.0);
                    }
                    RMSTIME = RMSTIME / _tempMonitorChannelValues.Length;
                    RMSTIME = Math.Sqrt(RMSTIME);

После этого я вычисляю fft "_tempMonitorChannelValues" следующим образом:

 public static VectorDPoint FFT(double[] trama, double samplingFreq)
    {
        double fs = samplingFreq;   // Sampling frequency
        double t1 = 1 / fs;          // Sample time
        int l = trama.Length;       // Length of signal

        // Time vector
        //Vector t = Normal(0, l, 1) * t1;

        //// Values vector
        //Vector y = new Vector(trama);

        // We just use half of the data as the other half is simetric. The middle is found in NFFT/2 + 1
        int nFFT = (int)Math.Pow(2, NextPow2(l));

        if (nFFT > 655600)
        { }

        // Create complex array for FFT transformation. Use 0s for imaginary part
        Complex[] samples = new Complex[nFFT];
        for (int i = 0; i < nFFT; i++)
        {
            if (i >= trama.Length)
            {
                samples[i] = new MathNet.Numerics.Complex(0, 0);
            }
            else
            {
                samples[i] = new MathNet.Numerics.Complex(trama[i], 0);
            }
        }
        ComplexFourierTransformation fft = new ComplexFourierTransformation(TransformationConvention.Matlab);
        fft.TransformForward(samples);
        ComplexVector s = new ComplexVector(samples);
        s = s / l;

        Vector f = (fs / 2.0) * Linspace(0, 1, (nFFT / 2) + 1);
        VectorDPoint result = new VectorDPoint();

        for (int i = 0; i < (nFFT / 2) + 1; i++)
        {
            result.Add(new DPoint(f[i], 2 * s[i].Modulus));
        }

        s = null;
        f = null;
        samples = null;

        return result;
    }

И, наконец, я вычисляю среднеквадратичное значение модуля в фтп:

VectorDPoint fftVector = MathPlus.FFT(_tempMonitorChannelValues, _sampleRate);
                    double[] fftX, fftY;
                    fftVector.GetDoubleArrays(out fftX, out fftY);


for (int i = 0; i < (fftY.Length / 2) + 1; i++)
                      {
                         RMSFFT2 += Math.Pow((fftY[i]), 2.0);
                      }
                    RMSFFT2 = Math.Sqrt(RMSFFT2);

Не знаю, почему такие разные результаты...


person dataProcs    schedule 17.04.2017    source источник
comment
Почему вы делаете математику в С# вместо Matlab? С помощью Matlab вы можете создать dll, которая может выполнять fft намного эффективнее, чем в С#.   -  person jdweng    schedule 17.04.2017
comment
Потому что входные данные поступают из реального источника и сложно изменить реализацию arquitectura. Любая помощь @jdweng?   -  person dataProcs    schedule 17.04.2017
comment
Насколько отключены данные? При умножении и делении на 2 используйте 2,0, чтобы не обрезать цифры.   -  person jdweng    schedule 17.04.2017
comment
400 000 образцов   -  person dataProcs    schedule 17.04.2017
comment
Возможный дубликат (тот же пользователь): Получить RMS из БПФ   -  person Paul R    schedule 17.04.2017