#include "Calculation.hpp" Calculation::Calculation() { } Calculation::~Calculation() { } /************************************************************************/ /* 一维数据的复数快速傅里叶变换 */ /************************************************************************/ void Calculation::FFT(int n, fftw_complex* in, fftw_complex* out) { if (in == NULL || out == NULL) return; fftw_plan p; p = fftw_plan_dft_1d(n, in, out, FFTW_FORWARD, FFTW_ESTIMATE); fftw_execute(p); fftw_destroy_plan(p); fftw_cleanup(); } /************************************************************************/ /* 一维数据的实数快速傅里叶变换 */ /************************************************************************/ void Calculation::FFT_R(int n, std::vector & vecData, fftw_complex* out) { double in[n]; for (int i = 0; i < n; i++) { in[i] = vecData[i]; } for (int i = 0; i < n; i++) { out[i][0] = (double)vecData[i]; out[i][1] = 0; } //create a DFT plan and execute it fftw_plan plan = fftw_plan_dft_r2c_1d(n, in, out, FFTW_ESTIMATE); fftw_execute(plan); //destroy the plan to prevent a memory leak fftw_destroy_plan(plan); fftw_cleanup(); } /************************************************************************/ /* 一维数据的快速傅里叶逆变换 */ /************************************************************************/ void Calculation::iFFT(int n, fftw_complex* in, fftw_complex* out) { if (in == NULL || out == NULL) return; fftw_plan p; p = fftw_plan_dft_1d(n, in, out, FFTW_BACKWARD, FFTW_ESTIMATE); fftw_execute(p); fftw_destroy_plan(p); fftw_cleanup(); } void Calculation::_iFFT( std::vector & vecrealData,std::vector & vecimageData,std::vector & veciFFTData) { fftw_complex *inFFt, *outFFt; int N = vecrealData.size(); inFFt = (fftw_complex *)fftw_malloc(sizeof(fftw_complex) * N); outFFt = (fftw_complex *)fftw_malloc(sizeof(fftw_complex) * N); for (int j = 0; j < N; j++) { inFFt[j][0] = (double)vecrealData[j]; inFFt[j][1] = (double)vecimageData[j]; } iFFT(N,inFFt, outFFt); for (int i = 0; i < N; i++) { outFFt[i][0] *= 1./N; outFFt[i][1] *= 1./N; veciFFTData.push_back(outFFt[i][0]); } fftw_free(inFFt); fftw_free(outFFt); } void Calculation::_FFT(std::vector & vecData, std::vector & vecFFTrealData,std::vector & vecFFTimageData) { fftw_complex *inHilFFt, *outHilFFt; inHilFFt = (fftw_complex *)fftw_malloc(sizeof(fftw_complex) * vecData.size()); outHilFFt = (fftw_complex *)fftw_malloc(sizeof(fftw_complex) * vecData.size()); for (int j = 0; j < vecData.size(); j++) { inHilFFt[j][0] = (double)vecData[j]; inHilFFt[j][1] = 0; } FFT(vecData.size(), inHilFFt, outHilFFt); fftShift(outHilFFt, vecData.size()); for (int i = 0; i < vecData.size(); i++) { vecFFTrealData.push_back(outHilFFt[i][0]); vecFFTimageData.push_back(outHilFFt[i][1]); } fftw_free(inHilFFt); fftw_free(outHilFFt); } //************************************ // Method: caculateAmp_Pha // FullName: Calculation::caculateAmp_Pha // Access: public static // Returns: void // Qualifier: // Parameter: int n // Parameter: fftw_complex * in // Parameter: int frequency // Parameter: double & amplitude // Parameter: double & phase // 函数功能是计算特定频率的幅值和相位,原来的讨论中是传入一个特定的频率,然后在给定的频率左右范围内找幅值和相位 // 目前的函数实现是计算FFT变换后特定点的幅值和相位 // 然后还有一个地方需要修改,即给定频率和FFT变换结果序列 //************************************ void Calculation::caculateAmp_Pha(int n, fftw_complex* in, int frequency, double &litude, double &phase) { int index = frequency; amplitude = 2 * sqrt((in[index][0] / n) * (in[index][0] / n) + (in[index][1] / n) * (in[index][1] / n)); phase = 180 * atan(in[index][1] / in[index][0]) / M_PI; } float Calculation::max(std::vector & vecData) { std::vector::iterator it; it = std::max_element(vecData.begin(), vecData.end()); if (it != vecData.end()) { return *it; } return 0; } float Calculation::min(std::vector & vecData) { std::vector::iterator it; it = std::min_element(vecData.begin(), vecData.end()); if (it != vecData.end()) { return *it; } return 0; } void Calculation::absVec(std::vector & vecAbsData, std::vector & vecData) { for (int i = 0; i < vecData.size(); i++) { vecAbsData.push_back(fabs(vecData[i])); } return; } float Calculation::mean(std::vector & vecData) { double meanTemp = 0; for (int i = 0; i < vecData.size(); i++) { meanTemp = meanTemp += vecData[i]; } return meanTemp / vecData.size(); } void Calculation::drop_mean(std::vector & vecDropMeanData, std::vector & vecData) { float fMean = mean(vecData); for (int i = 0; i < vecData.size(); i++) { vecDropMeanData.push_back(vecData[i] - fMean); } return; } float Calculation::srm(std::vector & vecData) { double dSrmTemp = 0; for (int i = 0; i < vecData.size(); i++){ dSrmTemp = dSrmTemp + sqrt(vecData[i]); } dSrmTemp = dSrmTemp / vecData.size(); return dSrmTemp * dSrmTemp; } float Calculation::rms(std::vector & vecData) { double rmsTemp = 0; for (int i = 0; i < vecData.size(); i++) { rmsTemp = rmsTemp += (vecData[i] * vecData[i]); } rmsTemp = rmsTemp / vecData.size(); return sqrt(rmsTemp); } float Calculation::getSample_variance(std::vector a) { float ss = 0; float s = 0; float mx = mean(a); int len = a.size(); for (int i = 0; i < len; i++) { s = a[i] - mx; ss += pow(s, 2); } return ss / (len - 1); } float Calculation::variance(std::vector & vecDropMeanData) { double varianceTemp = 0; for (int i = 0; i < vecDropMeanData.size(); i++) { varianceTemp = varianceTemp += (vecDropMeanData[i] * vecDropMeanData[i]); } return varianceTemp/vecDropMeanData.size(); } float Calculation::skew_state(std::vector & vecDropMeanData, float fVariance) { double tempSkew = 0; for (int i = 0; i < vecDropMeanData.size(); i++) { tempSkew = tempSkew + pow(vecDropMeanData[i], 3); } tempSkew = tempSkew / vecDropMeanData.size(); tempSkew = tempSkew / pow(fVariance, 1.5); return tempSkew; } float Calculation::kurtosis(std::vector & vecDropMeanData, float fVariance) { double tempkurtosis = 0; for (int i = 0; i < vecDropMeanData.size(); i++) { tempkurtosis = tempkurtosis + pow(vecDropMeanData[i], 4); } tempkurtosis = tempkurtosis / vecDropMeanData.size(); tempkurtosis = tempkurtosis / pow(fVariance, 2); return tempkurtosis; } void Calculation::Hanning(std::vector & vecData,std::vector & vecHanningData) { int N = vecData.size(); float* w = NULL; w = (float*)calloc(N, sizeof(float)); int half, i, idx; if (N % 2 == 0) { half = N / 2; for (i = 0; i < half; i++) //CALC_HANNING Calculates Hanning window samples. w[i] = 0.5 * (1 - cos(2 * pi * (i + 1) / (N + 1))); idx = half - 1; for (i = half; i < N; i++) { w[i] = w[idx]; idx--; } } else { half = (N + 1) / 2; for (i = 0; i < half; i++) //CALC_HANNING Calculates Hanning window samples. w[i] = 0.5 * (1 - cos(2 * pi * (i + 1) / (N + 1))); idx = half - 2; for (i = half; i < N; i++) { w[i] = w[idx]; idx--; } } for(int j = 0; j < N;j++){ vecHanningData.push_back(w[j]); } free(w); } void Calculation::hilbert(std::vector & vecData, std::vector & vecHilbertData, int N) { double in[N]; for (int i = 0; i < N; i++) { in[i] = vecData[i]; } fftw_complex *out; out = (fftw_complex *)fftw_malloc(sizeof(fftw_complex) * N); for (int i = 0; i < N; ++i) { out[i][0] = (double)vecData[i]; out[i][1] = 0; } //create a DFT plan and execute it fftw_plan plan = fftw_plan_dft_r2c_1d(N, in, out, FFTW_ESTIMATE); fftw_execute(plan); //destroy the plan to prevent a memory leak fftw_destroy_plan(plan); int hN = N >> 1; // half of the length (N /2) int numRem = hN; // the number of remaining elements // multiply the appropriate values by 2 // (those that should be multiplied by 1 are left intact because they wouldn't change) for (int i = 1; i < hN; ++i) // 1,2,...,N/2 - 1 的项乘以2 { out[i][0] *= 2; out[i][1] *= 2; } // if the length is even, the number of remaining elements decreases by 1 if (N % 2 == 0) numRem--; // if it's odd and greater than 1, the middle value must be multiplied by 2 else if (N > 1) // 奇数非空 { out[hN][0] *= 2; out[hN][1] *= 2; } // set the remaining values to 0 // (multiplying by 0 gives 0, so we don't care about the multiplicands) memset(&out[hN + 1][0], 0, numRem * sizeof(fftw_complex)); // create an IDFT plan and execute it plan = fftw_plan_dft_1d(N, out, out, FFTW_BACKWARD, FFTW_ESTIMATE); fftw_execute(plan); // do some cleaning fftw_destroy_plan(plan); fftw_cleanup(); // scale the IDFT output for (int i = 0; i < N; ++i) { out[i][0] /= N; out[i][1] /= N; } for( int n=0; n & vecData, std::vector & vecFFTSpecData) { fftw_complex *inFFt, *outFFt; inFFt = (fftw_complex *)fftw_malloc(sizeof(fftw_complex) * vecData.size()); outFFt = (fftw_complex *)fftw_malloc(sizeof(fftw_complex) * vecData.size()); printf("1---------------------------------------------->%d\n",vecData.size()); for (int j = 0; j < vecData.size(); j++) { inFFt[j][0] = (double)vecData[j]; inFFt[j][1] = 0; } FFT(vecData.size(),inFFt, outFFt); for(int j = 0; j < vecData.size()/2; j++) { vecFFTSpecData.push_back(sqrt(outFFt[j][0]*outFFt[j][0] + outFFt[j][1]*outFFt[j][1])*2/vecData.size()); } } void Calculation::envSpec(std::vector & vecData, std::vector & vecEnvSpecData,int StartFrequency,int EndFrequency) { /*std::vector vecDropMeanData; drop_mean(vecDropMeanData, vecData); std::vector vecHilbertData; hilbert(vecDropMeanData, vecHilbertData, vecDropMeanData.size()); fftw_complex *inHilFFt, *outHilFFt; inHilFFt = (fftw_complex *)fftw_malloc(sizeof(fftw_complex) * vecHilbertData.size()); outHilFFt = (fftw_complex *)fftw_malloc(sizeof(fftw_complex) * vecHilbertData.size()); for (int j = 0; j < vecHilbertData.size(); j++) { inHilFFt[j][0] = (double)vecHilbertData[j]; inHilFFt[j][1] = 0; } FFT(vecHilbertData.size(), inHilFFt, outHilFFt); fftShift(outHilFFt, vecHilbertData.size()); vecEnvSpecData.push_back(0); for (int i = vecHilbertData.size() / 2 + 1; i < vecHilbertData.size(); i++) { float ftemp = 2 * sqrt(outHilFFt[i][0] * outHilFFt[i][0] + outHilFFt[i][1] * outHilFFt[i][1]) / vecHilbertData.size(); vecEnvSpecData.push_back(ftemp); }*/ std::vector vecFFTrealData,vecFFTimageData; std::vector vecRealData,vecImageData; std::vector veciFFtData; std::vector veciFFtData2; std::vector vecHilbertData; _FFT(vecData,vecFFTrealData,vecFFTimageData); for(int i = 0; i < vecFFTrealData.size();i++){ if(i > StartFrequency && i < EndFrequency){ vecRealData.push_back(vecFFTrealData.at(i)); vecImageData.push_back(vecFFTimageData.at(i)); }else{ vecRealData.push_back(0); vecImageData.push_back(0); } } _iFFT(vecRealData,vecImageData,veciFFtData); for(int j = 0; j < veciFFtData.size();j++){ veciFFtData2.push_back(veciFFtData[j]*2); } hilbert(veciFFtData2,vecHilbertData,veciFFtData2.size()); FFTSpec(vecHilbertData, vecEnvSpecData); } void Calculation::GenerateSin(std::vector & vecData) { int i; int ft = 1; /* 周期 hz */ int fs = 12800; /* 采样频率*/ /* generate data */ int data_len = (8*1024); for (i = 0; i < data_len; i++) { vecData.push_back(sin(1000 * 2 *3.1415926*ft*i/fs)); } }