C# 获取每个频率的均方根值

C# 获取每个频率的均方根值,c#,indexing,fft,frequency,rms,C#,Indexing,Fft,Frequency,Rms,我有一个输入信号,我计算了它的FFT。在那之后,我只需要在一个频带上计算它的均方根值,而不是所有的频谱 我用帕塞瓦尔定理解决了整个光谱的均方根计算问题,但如何计算这种“选择性”的均方根呢?我已经正确计算了索引,以获得三个感兴趣的频率(F0,FC,F1),但是当将RMS应用于这个bandwith时,似乎Parseval的定理不成立 我收到一个唯一的10 KHz频率,FFT总频谱的RMS是正确的,但其在10 KHz频率下的RMS选择性给了我一个错误的结果(-0.4V,RMS正确值),并且应该给我几乎

我有一个输入信号,我计算了它的FFT。在那之后,我只需要在一个频带上计算它的均方根值,而不是所有的频谱

我用帕塞瓦尔定理解决了整个光谱的均方根计算问题,但如何计算这种“选择性”的均方根呢?我已经正确计算了索引,以获得三个感兴趣的频率(F0,FC,F1),但是当将RMS应用于这个bandwith时,似乎Parseval的定理不成立

我收到一个唯一的10 KHz频率,FFT总频谱的RMS是正确的,但其在10 KHz频率下的RMS选择性给了我一个错误的结果(-0.4V,RMS正确值),并且应该给我几乎相同的结果,因为我在频谱中只得到了一个频率。在这里您可以看到我的RMS选择性计算:

 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;

    }
public static double rms选择计算(double[]trama,double samplingFreq,double F0,double Fc,double F1)
{
//感兴趣的频率
双fs=samplingFreq;//采样频率
双t1=1/fs;//采样时间
int l=trama.Length;//信号长度
双rmsSelective=0;
双ParsevalB=0;
双比例因子=fs;
双dt=1/fs;
//我们只使用了一半的数据,因为另一半是simmetric。中间的数据在NFFT/2+1中
int nFFT=(int)Math.Pow(2,NextPow2(l));
双df=fs/nFFT;
如果(nFFT>655600)
{ }
//为FFT变换创建复数数组。虚部使用0
络合物[]样品=新络合物[nFFT];
复合物[]反向样品=新复合物[nFFT];
double[]频率=新的double[nFFT];
对于(int i=0;i=轨道长度)
{
样本[i]=新的MathNet.Numerics.Complex(0,0);
}
其他的
{
样本[i]=新的MathNet.Numerics.Complex(trama[i],0);
}
}
ComplexFourierTransformation fft=新的ComplexFourierTransformation(TransformationConvention.Matlab);
变换前向(采样);
ComplexVector s=新的ComplexVector(样本);
//索引将获得每个频率的索引
int f0Index、fcIndex、f1Index;
双k=nFFT/fs;
f0Index=(int)数学层(k*F0);
fcIndex=(int)数学层(k*Fc);
f1Index=(int)数学上限(k*F1);

对于(int i=f0Index;i功率谱密度PSD的估计值由FFT幅度的平方给出

具有特定带宽的区段的RMS是该区段PSD面积的根


所以实际上,只需将FFT的绝对值积分在低频和高频之间


您以前是否多次问过同样的问题,例如和?请参见我的回答“因此,实际上,只需将FFT的绝对值在低频和高频之间进行积分。”这是不正确的。您需要将FFT的幅值平方在低频率和高频率之间进行积分,然后取平方根。积分绝对值会使结果产生偏差。此外,计算频谱中每个点的绝对值需要每个点的平方根,因此,即使是正确的,也会比最后只做一个平方根。