#include #include #include #include #include #include "svm.h" #include #define N 128 #define PI 3.1415926 /*复数结构体类型*/ // typedef struct { // double realPart; // double imaginaryPart; // }complexNumber; // void fastFourierOperation(complexNumber* x, complexNumber* W);//快速傅里叶变换算法 // //void initRotationFactor(complexNumber* W); //生成旋转因子数组 // void changePosition(complexNumber* x); //偶奇变换算法 // //void outputArray(); //遍历输出数组 // void add(complexNumber, complexNumber, complexNumber*); //复数加法 // void mul(complexNumber, complexNumber, complexNumber*); //复数乘法 // void sub(complexNumber, complexNumber, complexNumber*); //复数减法 // double* calculateMagnitude(complexNumber* x); // double* get_feature(double* arr, int win, int hold, int count); // struct svm_model* model; // struct svm_node* l2x(int* buff, int size) { // struct svm_node* data = (struct svm_node*)malloc((size + 1) * sizeof(struct svm_node)); // if (data == NULL) { // return NULL; // } // // Convert input string to array of doubles // double* arr = (double*)malloc(size * sizeof(double)); // for (int i = 0; i < size; i++) { // arr[i] = (double)buff[i]; // } // // Process the data here // double I_arr[128]; // double P_arr[3]; // memcpy(I_arr, &arr[3], 128 * sizeof(double)); // memcpy(P_arr, arr, 3 * sizeof(double)); // double* feature = (double*)malloc(23 * sizeof(double)); // double *fftres = get_feature(I_arr, 3, 10, 10); // for (int i = 0; i < 23; i++) // { // if (i < 3){ // feature[i] = P_arr[i]; // } // else { // feature[i] = fftres[i-3]; // } // } // // Populate the svm_node array with processed data // for (int i = 0; i < 23; i++) { // data[i].index = i + 1; // data[i].value = feature[i]; // Replace with processed data // } // data[size].index = -1; // The last element should have index -1 to indicate the end // return data; // } // ///------------------------------FFT算法 & 寻找局部最优幅度组---------------------------------- // double* calculateMagnitude(complexNumber* x) { // double* magnitude = (double*)malloc(N * sizeof(double)); // // 遍历信号x中的每个复数对象 // for (int i = 0; i < N / 2; i++) { // double real = x[i].realPart; // double imag = x[i].imaginaryPart; // // 计算实部平方和虚部平方的和 // double magnitudeSquare = real * real + imag * imag; // magnitude[i] = 2 * sqrt(magnitudeSquare) / N; // } // return magnitude; // } // /*快速傅里叶变换*/ // void fastFourierOperation(complexNumber* x, complexNumber* W) // { // int l = 0; // complexNumber up, down, product; // changePosition(x); //偶奇变换算法 // for (int i = 0; i < log(N) / log(2); i++) //一级蝶形运算 // { // l = 1 << i; // for (int j = 0; j < N; j += 2 * l) //一组蝶形运算 // { // for (int k = 0; k < l; k++) //一个蝶形运算 // { // mul(x[j + k + l], W[N * k / 2 / l], &product); // add(x[j + k], product, &up); // sub(x[j + k], product, &down); // x[j + k] = up; // x[j + k + l] = down; // } // } // } // } // /*偶奇变换算法*/ // void changePosition(complexNumber* x) // { // int j = 0, k;//待会儿进行运算时需要用到的变量 // complexNumber temp; // for (int i = 0; i < N - 1; i++) // { // if (i < j) // { // //若倒序数大于顺序数,进行变址(换位);否则不变,防止重复交换,变回原数 // temp = x[i]; // x[i] = x[j]; // x[j] = temp; // } // k = N / 2; //判断j的最高位是否为0 // while (j >= k) // { //最高位为1 // j = j - k; // k = k / 2; // } // j = j + k; //最高位为0 // } // } // /*复数加法的定义*/ // void add(complexNumber a, complexNumber b, complexNumber* c) // { // c->realPart = a.realPart + b.realPart; // c->imaginaryPart = a.imaginaryPart + b.imaginaryPart; // } // /*复数乘法的定义*/ // void mul(complexNumber a, complexNumber b, complexNumber* c) // { // c->realPart = a.realPart * b.realPart - a.imaginaryPart * b.imaginaryPart; // c->imaginaryPart = a.realPart * b.imaginaryPart + a.imaginaryPart * b.realPart; // } // /*复数减法的定义*/ // void sub(complexNumber a, complexNumber b, complexNumber* c) // { // c->realPart = a.realPart - b.realPart; // c->imaginaryPart = a.imaginaryPart - b.imaginaryPart; // } // /*FFT*/ // double* fft(double* arr) { // complexNumber x[N], W[N / 2]; // for (int i = 0; i < N; i++) // { // x[i].realPart = arr[i]; // x[i].imaginaryPart = 0; // } // for (int i = 0; i < N / 2; i++) // { // W[i].realPart = cos(2 * PI / N * i);//用欧拉公式计算旋转因子 // W[i].imaginaryPart = -1 * sin(2 * PI / N * i); // } // fastFourierOperation(x, W);//调用快速傅里叶变换 // double* magnitudes = calculateMagnitude(x); // return magnitudes; // } // int min(int a,int b) { // if(a>b) {return b;} // return a; // } // int max(int a,int b) { // if(a>b){return a;} // return b; // } // /*获取局部最优*/ // int isLocalMax(double* data, int idx, int win, int size) { // if(idx=size-win) { // for(int i=0;i=win && idx hold) { // // Store results // result[idx][0] = pFrq[i]; // result[idx][1] = pFft[i]; // idx++; // } // if (idx >= count) { // break; // } // } // double* res = (double*)malloc(count * 2 * sizeof(double)); // int index = 0; // for (int i = 0; i < 2 * count; i += 2) // { // res[i] = result[index][0]; // res[i + 1] = result[index][1]; // index++; // } // return res; // } typedef struct { double realPart; double imaginaryPart; }complexNumber; void fastFourierOperation(complexNumber* x, complexNumber* W);//快速傅里叶变换算法 //void initRotationFactor(complexNumber* W); //生成旋转因子数组 void changePosition(complexNumber* x); //偶奇变换算法 //void outputArray(); //遍历输出数组 void add(complexNumber, complexNumber, complexNumber*); //复数加法 void mul(complexNumber, complexNumber, complexNumber*); //复数乘法 void sub(complexNumber, complexNumber, complexNumber*); //复数减法 double* calculateMagnitude(complexNumber* x); double* get_feature(double* arr, int win, int hold, int count); struct svm_model* model; struct svm_node* l2x(int* buff, int size) { struct svm_node* data = (struct svm_node*)malloc((size + 1) * sizeof(struct svm_node)); if (data == NULL) { return NULL; } // Convert input string to array of doubles //double arr[size]; double* arr = (double*)malloc(size * sizeof(double)); for (int i = 0; i < size; i++) { arr[i] = (double)buff[i]; } // Process the data here //double I_arr[128] = memcpy(arr, &arr[0], 128 * sizeof(int)); //double V_arr[128] = memcpy(arr, &arr[127], 128 * sizeof(int)]); //double P_arr[3] = memcpy(arr, &arr[256], 3 * sizeof(int)); double I_arr[128]; //double V_arr[128]; //memcpy(V_arr, &arr[127], 128 * sizeof(double)); double P_arr[3]; memcpy(I_arr, &arr[3], 128 * sizeof(double)); memcpy(P_arr, arr, 3 * sizeof(double)); // for(int i=0;i<3;i++) { // printf("P:%f\n",P_arr[i]); // } //-------------------------------------------------------------------------------->改 double* feature = (double*)malloc(23 * sizeof(double)); double *fftres = get_feature(I_arr, 2, 10, 10); for (int i = 0; i < 23; i++) { if (i < 3){ feature[i] = P_arr[i]; } else { feature[i] = fftres[i-3]; } } for (int i = 0; i < 23; i++) { // for (int i = 0; i < 20; i++) { data[i].index = i + 1; data[i].value = feature[i]; // Replace with processed data //printf("data[%d].index=%d ",i,data[i].index); //printf("data[%d].value=%f\n",i,data[i].value); //printf("(%d,%f), ",i+1,data[i].value); } // for (int i = 0; i < 20; i++) // {feature[i] = fftres[i];} // for (int i = 0; i < 20; i++) { // data[i].index = i + 1; // data[i].value = feature[i]; // Replace with processed data} data[size].index = -1; // The last element should have index -1 to indicate the end return data; } ///------------------------------FFT算法 & 寻找局部最优幅度组---------------------------------- double* calculateMagnitude(complexNumber* x) { double* magnitude = (double*)malloc(N * sizeof(double)); // 遍历信号x中的每个复数对象 for (int i = 0; i < N / 2; i++) { double real = x[i].realPart; double imag = x[i].imaginaryPart; // 计算实部平方和虚部平方的和 double magnitudeSquare = real * real + imag * imag; magnitude[i] = 2 * sqrt(magnitudeSquare) / N; //printf("magnitude[%d] = %f", i, magnitude[i]); } return magnitude; } /*快速傅里叶变换*/ void fastFourierOperation(complexNumber* x, complexNumber* W) { int l = 0; complexNumber up, down, product; changePosition(x); //偶奇变换算法 for (int i = 0; i < log(N) / log(2); i++) //一级蝶形运算 { l = 1 << i; for (int j = 0; j < N; j += 2 * l) //一组蝶形运算 { for (int k = 0; k < l; k++) //一个蝶形运算 { mul(x[j + k + l], W[N * k / 2 / l], &product); add(x[j + k], product, &up); sub(x[j + k], product, &down); x[j + k] = up; x[j + k + l] = down; } } } } /*偶奇变换算法*/ void changePosition(complexNumber* x) { int j = 0, k;//待会儿进行运算时需要用到的变量 complexNumber temp; for (int i = 0; i < N - 1; i++) { if (i < j) { //若倒序数大于顺序数,进行变址(换位);否则不变,防止重复交换,变回原数 temp = x[i]; x[i] = x[j]; x[j] = temp; } k = N / 2; //判断j的最高位是否为0 while (j >= k) { //最高位为1 j = j - k; k = k / 2; } j = j + k; //最高位为0 } } /*复数加法的定义*/ void add(complexNumber a, complexNumber b, complexNumber* c) { c->realPart = a.realPart + b.realPart; c->imaginaryPart = a.imaginaryPart + b.imaginaryPart; } /*复数乘法的定义*/ void mul(complexNumber a, complexNumber b, complexNumber* c) { c->realPart = a.realPart * b.realPart - a.imaginaryPart * b.imaginaryPart; c->imaginaryPart = a.realPart * b.imaginaryPart + a.imaginaryPart * b.realPart; } /*复数减法的定义*/ void sub(complexNumber a, complexNumber b, complexNumber* c) { c->realPart = a.realPart - b.realPart; c->imaginaryPart = a.imaginaryPart - b.imaginaryPart; } /*FFT*/ double* fft(double* arr) { complexNumber x[N], W[N / 2]; for (int i = 0; i < N; i++) { x[i].realPart = arr[i]; x[i].imaginaryPart = 0; } for (int i = 0; i < N / 2; i++) { W[i].realPart = cos(2 * PI / N * i);//用欧拉公式计算旋转因子 W[i].imaginaryPart = -1 * sin(2 * PI / N * i); } fastFourierOperation(x, W);//调用快速傅里叶变换 double* magnitudes = calculateMagnitude(x); return magnitudes; } int min(int a,int b) { if(a>b) {return b;} return a; } int max(int a,int b) { if(a>b){return a;} return b; } /*获取局部最优*/ int isLocalMax(double* data, int idx, int win, int size) { if(idx=size-win) { for(int i=0;i=win && idx (size - win))) { // return 0; //} //for (int i = 1; i <= win; i++) { // if ((data[idx] < data[idx - i]) || (data[idx] < data[idx + i])) { // //printf("%d %f\n", idx, data[idx]); // return 0; // } //} //return 1; } /*取得feature训练可用*/ double* get_feature(double* arr, int win, int hold, int count) { //printf(("win:%d, hold:%d, count:%d\n")); //double(*result)[2] = calloc(count, sizeof(*result)); double(*result)[2] = (double(*)[2])calloc(count, sizeof(*result)); // printf("打印getfeature传入数组\n"); // for (int i = 0; i < N ; i++) // { // printf("%f\n", arr[i]); // } double* pFft = fft(arr); double pFrq[N / 2]; // printf("打印幅度:=======================\n"); // for (int i = 0; i < N / 2; i++) // { // printf("%f\n", pFft[i]); // } //printf("打印频率:=======================\n"); for (int i = 0; i < N / 2; i++) { pFrq[i] = (double)i * 3906 / 129; // 计算每个点的值 //printf("%f\n", pFrq[i]); } int idx = 0; //printf("%d\n", sizeof(pFft) / sizeof(pFft[0])); //64为pFft长度 for (int i = 0; i < 64; i++) { //printf("%d", isLocalMax(pFft, i, win, 64)); //printf("%d\n",isLocalMax(pFft, i, win, 64)); if (isLocalMax(pFft, i, win, 64) && pFft[i] > hold) { // Store results result[idx][0] = pFrq[i]; result[idx][1] = pFft[i]; idx++; } if (idx >= count) { break; } } // printf("fft_localmax:=======================\n"); // for (int i = 0; i < count; i++) { // printf("%f %f\n", result[i][0], result[i][1]); // } double* res = (double*)malloc(count * 2 * sizeof(double)); int index = 0; for (int i = 0; i < 2 * count; i += 2) { res[i] = result[index][0]; res[i + 1] = result[index][1]; index++; } return res; } //------------------------------------------- FFT END ------------------------------------------------ //******************************************************************************************************* //************************************************************************************************** //-------------------------------------- 预测函数 ------------------------------------------------- int run_predict(int *arr) { FILE *file = fopen("./config.txt", "r"); if (file == NULL) { perror("Error opening file"); return 1; } char model_path[100]; // 假设模型名称不会超过100个字符 if (fscanf(file, "model_path = %99s", model_path) != 1) { fprintf(stderr, "Error reading model path from config file\n"); fclose(file); return 1; } //打印模型名称 // for (int i = 0; i < 131; i++) // { // printf("%d, ",arr[i]);/* code */ // } // printf("hello"); // printf("Model path: %s\n", model_path); //关闭文件 struct svm_model* model = svm_load_model(model_path);; // ����ģ�� struct svm_node* y = l2x(arr,131); double res = svm_predict(model, y); fclose(file); return res; } // int main() { // //int arr[131] ={297,5,301,-2834,-568,1548,3610,1072,-1076,-2288,-1600,-222,1810,3178,768,-1370,-3316,-1338,816,2162,1796,-340,-2018,-2142,-232,1162,2282,1406,-678,-2156,-1764,62,1908,2552,436,-1644,-3526,-1030,1114,2004,2030,96,-1882,-3038,-642,1390,3608,1210,-964,-2246,-1734,344,1994,2084,860,-1276,-2584,-1436,738,2158,1694,-212,-1998,-2302,-408,1740,3322,934,-550,-2102,-2010,-58,1918,2812,538,-1524,-3632,-1136,996,2234,1578,-502,-1812,-3230,-840,1336,3180,1314,-832,-2228,-1778,292,1986,2136,242,-1806,-2306,-1456,618,2112,1788,-92,-1944,-2680,-500,1600,3488,994,-1170,-2290,-1510,-148,1800,3022,632,-1462,-3592,-1300,916,2192,1696,-354,-2048,-2106,-176,1238,2372,1372,-752,-2180,-1760}; // int arr[131] = {572,76,658,-5062,-1258,986,9294,1686,274,-1832,-4292,-876,1294,6122,1420,-804,-9456,-1772,210,7318,2224,288,-1810,-8588,-1558,544,8540,1930,0,-5700,-3572,-544,1576,4762,1112,-1118,-8924,-2196,-194,1872,4034,724,-1404,-5524,-1360,894,9512,1758,-334,-7362,-2230,-998,1194,7336,1464,-728,-9058,-1804,104,6862,2442,398,-1700,-4574,-1034,442,7892,2074,96,-3126,-3894,-646,1494,4996,1174,-984,-9384,-1742,392,7650,4230,894,-1348,-6456,-1452,776,9440,1728,-272,-7344,-2302,-368,1774,4270,1550,-608,-8530,-2022,-30,5658,3494,528,-1638,-4832,-1110,1066,8682,1566,150,-1920,-4090,-800,1378,5628,1316,-928,-9528,-1816,298,7398,2198,196,-1884,-7440,-1490,670,9080,1828,-126,-6832,-2676}; // int a = run_predict(arr); // printf("result is : %d\n",a); // return 0; // }