private void CalRMS() { Complex32[] at = new Complex32[_sampleLength]; //原始信号 float[] freq = new float[_sampleLength]; for (int i = 0; i < _sampleLength; i++) { at[i] = new Complex32(_xval[i], _yval[i]); freq[i] = i * _sampleRate / _sampleLength; } Fourier.Forward(at); //FFT之后的结果保留在at序列中 for (int i = _sampleLength / 2 + 1; i < _sampleLength; i++) //去掉大于fs/2的成分,之后幅值再乘以2/N { at[i] = 0; } Complex32[] weight = new Complex32[_sampleLength]; Weight weigh = new Weight(_weightType, freq, out weight); Complex32[] aw = new Complex32[_sampleLength]; //aw为加权后的信号 for (int i = 0; i < _sampleLength; i++) { aw[i] = 2 * at[i] * weight[i] / _sampleLength; //恢复幅值,幅值乘以2/N } Fourier.Inverse(aw); double[] awAbs = new double[_sampleLength]; for (int i = 0; i < _sampleLength; i++) { awAbs[i] = Complex32.Abs(aw[i]); } _aw = awAbs; _RMS = _aw.RootMeanSquare(); }
/// <summary> /// 计算峰值系数和加权加速度时间历程 /// </summary> private void CalCF() { Complex32[] at = new Complex32[_sampleLength]; //原始信号 float[] freq = new float[_sampleLength]; for (int i = 0; i < _sampleLength; i++) { at[i] = new Complex32(_xval[i], _yval[i]); freq[i] = i * _sampleRate / _sampleLength; } Fourier.Forward(at); //FFT之后的结果保留在at序列中 Complex32[] weight = new Complex32[_sampleLength]; Weight weigh = new Weight(_weightType, freq, out weight); Complex32[] aw = new Complex32[_sampleLength]; //aw为加权后的信号 int halfNfft; if (_sampleLength % 2 == 1) { halfNfft = (int)Math.Floor((double)(_sampleLength / 2)) + 1; } else { halfNfft = (int)Math.Floor((double)(_sampleLength / 2)); } for (int i = 0; i < halfNfft; i++) { aw[i] = at[i] * weight[i]; aw[_sampleLength - i - 1] = aw[i]; } Fourier.Inverse(aw); double[] awAbs = new double[_sampleLength]; for (int i = 0; i < _sampleLength; i++) { awAbs[i] = Complex32.Abs(aw[i]); } _aw = awAbs; _rms = _aw.RootMeanSquare(); _Peak = awAbs.Max(); double tempAp = awAbs.Max() - awAbs.Min(); _Ap = Math.Abs(tempAp); _CF = _Peak / _rms; }
//Method has optional bool argument removeAverage, because in other methods it accepts already averaged vector. public static FftResult GetAmpSpectrumAndMax(double fs, List <double> vector, bool removeAverage = true) { if (vector == null || !vector.Any()) { return(null); } if (vector.Count == 1) { throw new ArgumentException("Vector must have more than 1 value", nameof(vector)); } if (fs <= 0) { throw new ArgumentException("Fs cannot be less than or equal to zero", nameof(fs)); } Complex32[] vec = new Complex32[vector.Count]; int i = 0; double vecAvg = removeAverage ? vector.Average():0;//don't compute avg if not needed foreach (var ve in vector) { vec[i] = removeAverage ? new Complex32((float)(ve - vecAvg), 0) : new Complex32((float)ve, 0); i++; } Fourier.Forward(vec, FourierOptions.Matlab); FftResult res = new FftResult(); res.Frequencies = new List <double>(); res.Values = new List <double>(); int l = (int)Math.Round((double)vec.Length / 2, MidpointRounding.AwayFromZero); double konec = fs / 2; var k = Generate.LinearSpaced(l, 0, konec); for (int p = 0; p < l; p++) { k[p] = Math.Round(k[p], 10); res.Frequencies.Add(k[p]); res.Values.Add(Complex32.Abs(vec[p])); } res.MaxIndex = res.Values.FindIndex(n => n == (res.Values.Max())); return(res); }
private void FFTDisplay(AccelerometerAxis axis) { // Clear points s4.Points.Clear(); List <DataPoint> pointsList; List <DataPoint> pointsList2; //Additional for Imaginary , Added by JP switch (axis) { case AccelerometerAxis.X_Axis: pointsList = s1.Points; pointsList2 = s1.Points; //Additional for Imaginary , Added by JP break; case AccelerometerAxis.Y_Axis: pointsList = s2.Points; pointsList2 = s2.Points; //Additional for Imaginary , Added by JP break; case AccelerometerAxis.Z_Axis: pointsList = s3.Points; pointsList2 = s3.Points; //Additional for Imaginary , Added by JP break; default: // This should not happen pointsList = null; pointsList2 = null; break; } //var pointsList = s1.Points; var pointsRealList = new List <double>(); var pointsImagList = new List <double>(); //Additional for Imaginary , Added by JP foreach (var dataPoint in pointsList) { pointsRealList.Add(dataPoint.Y); } foreach (var dataPoint in pointsList2) //Additional for Imaginary , Added by JP { pointsImagList.Add(dataPoint.Y * 0); // Multiply by 0, all imaginary values are 0. } int numSamples = pointsRealList.Count; int numSamples2 = pointsImagList.Count; //Additional for Imaginary , Added by JP if (pointsRealList.Count.IsEven()) { pointsRealList.Add(0); pointsRealList.Add(0); } else { pointsRealList.Add(0); } if (pointsImagList.Count.IsEven()) //Additional for Imaginary , Added by JP { pointsImagList.Add(0); pointsImagList.Add(0); } else { pointsImagList.Add(0); } var pointsRealArray = pointsRealList.ToArray(); var pointsImagArray = pointsImagList.ToArray(); //Additional for Imaginary , Added by JP var FFT_Count = pointsRealArray.Count(); int ctr = 0; //Additional for Imaginary , Added by JP Complex32[] For_FFTval = new Complex32[FFT_Count]; //Additional for Imaginary , Added by JP foreach (var data_points in pointsRealArray) //Additional for Imaginary , Added by JP { For_FFTval[ctr] = new Complex32((float)pointsRealArray[ctr], (float)pointsImagArray[ctr]); ctr = ctr + 1; } Fourier.Forward(For_FFTval); //Additional for Imaginary , Added by JP ctr = 0; double[] FFT_plot = new double[FFT_Count]; //Additional for Imaginary , Added by JP foreach (var data_points in For_FFTval) { FFT_plot[ctr] = Complex32.Abs(For_FFTval[ctr]); //Additional for Imaginary , Added by JP ctr = ctr + 1; } var x = 0; foreach (var realPoint in FFT_plot) { var count = (double)s4.Points.Count; s4.Points.Add(new DataPoint(count, realPoint)); } FFTPlotModel = fFTPlot; FFTPlotModel.InvalidatePlot(true); }