0

I want to get the RMS after doing the fft to my data in order to get the same result as the RMS of data directly.

I followed this topic https://fr.mathworks.com/matlabcentral/answers/131353-relation-between-fft-and-rms but I can't get the same results, it's a big difference.

By Parseval's theorem "The total energy of a signal is preserved under the Fourier transform ( Parseval's theorem ), so the sum (or integral) of the square of a function is equal to the sum (or integral) of the square of its transform. The RMS would be the square root of that value."

So taking "_tempMonitorChannelValues" as my data, with lenght = 400000 samples, first of all I calculate the RMS of data as follows:

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

After that, I calculate the fft of "_tempMonitorChannelValues" as follows:

 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;
    }

And finally I calculate the RMS of the modulus in fft:

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);

I don't know why they are so different results...

dataProcs
  • 55
  • 1
  • 13
  • Why are you doing the math in c# instead of Matlab? With Matlab you can generate a dll which can do the fft much more efficiently than in c#. – jdweng Apr 17 '17 at 13:20
  • Because the input data is coming from a real source and it is hard to change the arquitectura implementation. Any help @jdweng ? – dataProcs Apr 17 '17 at 13:50
  • How much is the data off? When multiplying and dividing by 2 use 2.0 so you don't truncate digits. – jdweng Apr 17 '17 at 14:38
  • 400.000 samples – dataProcs Apr 17 '17 at 14:46
  • Possible duplicate (same user): [Get RMS from FFT](http://stackoverflow.com/questions/43363860/get-rms-from-fft) – Paul R Apr 17 '17 at 18:35

0 Answers0