Я хочу получить 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);
Не знаю, почему такие разные результаты...