0

I've got an input signal and I calculated its FFT. After that, I need to calculate its RMS ONLY at a bandwith of frequencies, not for all spectrum.

I solved RMS calculation of the entire spectrum applying Parseval's theorem, but how do I calculate this kind of RMS "selective"? I've got the indexes correctly calculated to get the three frecuencies of interest (F0, FC, F1), but when applying RMS to this bandwith, it seems Parseval's theorem is not holded.

I receive an unique 10 KHz frequency, the RMS from FFT total spectrum is correct, but its RMS selective at 10 KHz frequency gives me a wrong result (-0.4V from RMS correct one) and should give me almost the same result as I only got one frecuency in the spectrum. Here you can see my RMS selective calculation:

 public static double RMSSelectiveCalculation(double[] trama, double samplingFreq, double F0, double Fc, double F1)
    {
    //Frequency of interest          
        double fs = samplingFreq;   // Sampling frequency
        double t1 = 1 / fs;          // Sample time
        int l = trama.Length;       // Length of signal
        double rmsSelective = 0;
        double ParsevalB = 0;
        double scalingFactor = fs;
        double dt = 1 / fs;

        // 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));
        double df = fs / nFFT;
        if (nFFT > 655600)
        { }

        // Create complex array for FFT transformation. Use 0s for imaginary part
        Complex[] samples = new Complex[nFFT];
        Complex[] reverseSamples = new Complex[nFFT];
        double[] frecuencies = new double[nFFT];
        for (int i = 0; i < nFFT; i++)
        {
            frecuencies[i] = i * (fs / nFFT);

            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);
        //The indexes will get the index of each frecuency
        int f0Index, fcIndex, f1Index;
        double k = nFFT / fs;
        f0Index = (int)Math.Floor(k * F0);
        fcIndex = (int)Math.Floor(k * Fc);
        f1Index = (int)Math.Ceiling(k * F1);

        for (int i = f0Index; i <= f1Index; i++)
        {
            ParsevalB += Math.Pow(Math.Abs(s[i].Modulus / scalingFactor), 2.0);
        }

        ParsevalB = ParsevalB * df;

        double ownSF = fs / l; //This is a own scale factor used to take the square root after

        rmsSelective = Math.Sqrt(ParsevalB * ownSF);

        samples = null;
        s = null;

        return rmsSelective;

    }
dataProcs
  • 55
  • 1
  • 13
  • Haven't you asked this same question several times before, e.g. [Getting RMS from FFT](http://stackoverflow.com/questions/43452138/getting-rms-from-fft) and [Get RMS from FFT](http://stackoverflow.com/questions/43363860/get-rms-from-fft) ? – Paul R Apr 21 '17 at 08:34

1 Answers1

0

An estimate of the power spectral density PSD is given by the square of magnitude of the FFT.

The RMS of a section with a certain bandwidth is the root of the area of the PSD of that section.

So practically, just integrate the absolute value of the FFT between the lower and upper frequency.

MATLAB example

Tom
  • 3,281
  • 26
  • 33
  • see my answer please – dataProcs Apr 25 '17 at 08:53
  • "So practically, just integrate the absolute value of the FFT between the lower and upper frequency." This is not correct. You need to integrate the magnitude squared of the FFT between the lower and upper frequency, then take the square root. Integrating the absolute value will bias your result. Also, calculating absolute value at each point in the spectrum requires a square root for each point, so even if it were correct it would be slower than doing just one square root at the end. – Eric Backus Jun 29 '20 at 18:21