predict.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604
  1. #include <stdio.h>
  2. #include <ctype.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <errno.h>
  6. #include "svm.h"
  7. #include <math.h>
  8. #define N 128
  9. #define PI 3.1415926
  10. /*复数结构体类型*/
  11. // typedef struct {
  12. // double realPart;
  13. // double imaginaryPart;
  14. // }complexNumber;
  15. // void fastFourierOperation(complexNumber* x, complexNumber* W);//快速傅里叶变换算法
  16. // //void initRotationFactor(complexNumber* W); //生成旋转因子数组
  17. // void changePosition(complexNumber* x); //偶奇变换算法
  18. // //void outputArray(); //遍历输出数组
  19. // void add(complexNumber, complexNumber, complexNumber*); //复数加法
  20. // void mul(complexNumber, complexNumber, complexNumber*); //复数乘法
  21. // void sub(complexNumber, complexNumber, complexNumber*); //复数减法
  22. // double* calculateMagnitude(complexNumber* x);
  23. // double* get_feature(double* arr, int win, int hold, int count);
  24. // struct svm_model* model;
  25. // struct svm_node* l2x(int* buff, int size) {
  26. // struct svm_node* data = (struct svm_node*)malloc((size + 1) * sizeof(struct svm_node));
  27. // if (data == NULL) {
  28. // return NULL;
  29. // }
  30. // // Convert input string to array of doubles
  31. // double* arr = (double*)malloc(size * sizeof(double));
  32. // for (int i = 0; i < size; i++) {
  33. // arr[i] = (double)buff[i];
  34. // }
  35. // // Process the data here
  36. // double I_arr[128];
  37. // double P_arr[3];
  38. // memcpy(I_arr, &arr[3], 128 * sizeof(double));
  39. // memcpy(P_arr, arr, 3 * sizeof(double));
  40. // double* feature = (double*)malloc(23 * sizeof(double));
  41. // double *fftres = get_feature(I_arr, 3, 10, 10);
  42. // for (int i = 0; i < 23; i++)
  43. // {
  44. // if (i < 3){
  45. // feature[i] = P_arr[i];
  46. // }
  47. // else {
  48. // feature[i] = fftres[i-3];
  49. // }
  50. // }
  51. // // Populate the svm_node array with processed data
  52. // for (int i = 0; i < 23; i++) {
  53. // data[i].index = i + 1;
  54. // data[i].value = feature[i]; // Replace with processed data
  55. // }
  56. // data[size].index = -1; // The last element should have index -1 to indicate the end
  57. // return data;
  58. // }
  59. // ///------------------------------FFT算法 & 寻找局部最优幅度组----------------------------------
  60. // double* calculateMagnitude(complexNumber* x) {
  61. // double* magnitude = (double*)malloc(N * sizeof(double));
  62. // // 遍历信号x中的每个复数对象
  63. // for (int i = 0; i < N / 2; i++) {
  64. // double real = x[i].realPart;
  65. // double imag = x[i].imaginaryPart;
  66. // // 计算实部平方和虚部平方的和
  67. // double magnitudeSquare = real * real + imag * imag;
  68. // magnitude[i] = 2 * sqrt(magnitudeSquare) / N;
  69. // }
  70. // return magnitude;
  71. // }
  72. // /*快速傅里叶变换*/
  73. // void fastFourierOperation(complexNumber* x, complexNumber* W)
  74. // {
  75. // int l = 0;
  76. // complexNumber up, down, product;
  77. // changePosition(x); //偶奇变换算法
  78. // for (int i = 0; i < log(N) / log(2); i++) //一级蝶形运算
  79. // {
  80. // l = 1 << i;
  81. // for (int j = 0; j < N; j += 2 * l) //一组蝶形运算
  82. // {
  83. // for (int k = 0; k < l; k++) //一个蝶形运算
  84. // {
  85. // mul(x[j + k + l], W[N * k / 2 / l], &product);
  86. // add(x[j + k], product, &up);
  87. // sub(x[j + k], product, &down);
  88. // x[j + k] = up;
  89. // x[j + k + l] = down;
  90. // }
  91. // }
  92. // }
  93. // }
  94. // /*偶奇变换算法*/
  95. // void changePosition(complexNumber* x)
  96. // {
  97. // int j = 0, k;//待会儿进行运算时需要用到的变量
  98. // complexNumber temp;
  99. // for (int i = 0; i < N - 1; i++)
  100. // {
  101. // if (i < j)
  102. // {
  103. // //若倒序数大于顺序数,进行变址(换位);否则不变,防止重复交换,变回原数
  104. // temp = x[i];
  105. // x[i] = x[j];
  106. // x[j] = temp;
  107. // }
  108. // k = N / 2; //判断j的最高位是否为0
  109. // while (j >= k)
  110. // { //最高位为1
  111. // j = j - k;
  112. // k = k / 2;
  113. // }
  114. // j = j + k; //最高位为0
  115. // }
  116. // }
  117. // /*复数加法的定义*/
  118. // void add(complexNumber a, complexNumber b, complexNumber* c)
  119. // {
  120. // c->realPart = a.realPart + b.realPart;
  121. // c->imaginaryPart = a.imaginaryPart + b.imaginaryPart;
  122. // }
  123. // /*复数乘法的定义*/
  124. // void mul(complexNumber a, complexNumber b, complexNumber* c)
  125. // {
  126. // c->realPart = a.realPart * b.realPart - a.imaginaryPart * b.imaginaryPart;
  127. // c->imaginaryPart = a.realPart * b.imaginaryPart + a.imaginaryPart * b.realPart;
  128. // }
  129. // /*复数减法的定义*/
  130. // void sub(complexNumber a, complexNumber b, complexNumber* c)
  131. // {
  132. // c->realPart = a.realPart - b.realPart;
  133. // c->imaginaryPart = a.imaginaryPart - b.imaginaryPart;
  134. // }
  135. // /*FFT*/
  136. // double* fft(double* arr) {
  137. // complexNumber x[N], W[N / 2];
  138. // for (int i = 0; i < N; i++)
  139. // {
  140. // x[i].realPart = arr[i];
  141. // x[i].imaginaryPart = 0;
  142. // }
  143. // for (int i = 0; i < N / 2; i++)
  144. // {
  145. // W[i].realPart = cos(2 * PI / N * i);//用欧拉公式计算旋转因子
  146. // W[i].imaginaryPart = -1 * sin(2 * PI / N * i);
  147. // }
  148. // fastFourierOperation(x, W);//调用快速傅里叶变换
  149. // double* magnitudes = calculateMagnitude(x);
  150. // return magnitudes;
  151. // }
  152. // int min(int a,int b) {
  153. // if(a>b) {return b;}
  154. // return a;
  155. // }
  156. // int max(int a,int b) {
  157. // if(a>b){return a;}
  158. // return b;
  159. // }
  160. // /*获取局部最优*/
  161. // int isLocalMax(double* data, int idx, int win, int size) {
  162. // if(idx<win) {
  163. // for(int i=0;i<idx;i++) {
  164. // if(data[idx]<data[i]){return 0;}
  165. // }
  166. // for(int i=idx+1;i<min(size,idx+win+1);i++){
  167. // if(data[idx]<data[i]) {return 0;}
  168. // }
  169. // }
  170. // else if(idx>=size-win) {
  171. // for(int i=0;i<max(0,idx-win);i++) {
  172. // if(data[idx]<data[i]){return 0;}
  173. // }
  174. // for(int i=idx+1;i<size;i++) {
  175. // if(data[idx<data[i]]){return 0;}
  176. // }
  177. // }
  178. // else if(idx>=win && idx<size-win) {
  179. // for(int i=1;i<win+1;i++) {
  180. // if(data[idx]<data[idx-i] || data[idx]<data[idx+i])
  181. // {return 0;}
  182. // }
  183. // }
  184. // return 1;
  185. // }
  186. // /*取得feature训练可用*/
  187. // double* get_feature(double* arr, int win, int hold, int count)
  188. // {
  189. // double(*result)[2] = (double(*)[2])calloc(count, sizeof(*result));
  190. // double* pFft = fft(arr);
  191. // double pFrq[N / 2];
  192. // for (int i = 0; i < N / 2; i++) {
  193. // pFrq[i] = (double)i * 3906 / 129; // 计算每个点的值
  194. // }
  195. // int idx = 0;
  196. // for (int i = 0; i < 64 ; i++) {
  197. // if (isLocalMax(pFft, i, win, 64) && pFft[i] > hold) {
  198. // // Store results
  199. // result[idx][0] = pFrq[i];
  200. // result[idx][1] = pFft[i];
  201. // idx++;
  202. // }
  203. // if (idx >= count) {
  204. // break;
  205. // }
  206. // }
  207. // double* res = (double*)malloc(count * 2 * sizeof(double));
  208. // int index = 0;
  209. // for (int i = 0; i < 2 * count; i += 2)
  210. // {
  211. // res[i] = result[index][0];
  212. // res[i + 1] = result[index][1];
  213. // index++;
  214. // }
  215. // return res;
  216. // }
  217. typedef struct {
  218. double realPart;
  219. double imaginaryPart;
  220. }complexNumber;
  221. void fastFourierOperation(complexNumber* x, complexNumber* W);//快速傅里叶变换算法
  222. //void initRotationFactor(complexNumber* W); //生成旋转因子数组
  223. void changePosition(complexNumber* x); //偶奇变换算法
  224. //void outputArray(); //遍历输出数组
  225. void add(complexNumber, complexNumber, complexNumber*); //复数加法
  226. void mul(complexNumber, complexNumber, complexNumber*); //复数乘法
  227. void sub(complexNumber, complexNumber, complexNumber*); //复数减法
  228. double* calculateMagnitude(complexNumber* x);
  229. double* get_feature(double* arr, int win, int hold, int count);
  230. struct svm_model* model;
  231. struct svm_node* l2x(int* buff, int size) {
  232. struct svm_node* data = (struct svm_node*)malloc((size + 1) * sizeof(struct svm_node));
  233. if (data == NULL) {
  234. return NULL;
  235. }
  236. // Convert input string to array of doubles
  237. //double arr[size];
  238. double* arr = (double*)malloc(size * sizeof(double));
  239. for (int i = 0; i < size; i++) {
  240. arr[i] = (double)buff[i];
  241. }
  242. // Process the data here
  243. //double I_arr[128] = memcpy(arr, &arr[0], 128 * sizeof(int));
  244. //double V_arr[128] = memcpy(arr, &arr[127], 128 * sizeof(int)]);
  245. //double P_arr[3] = memcpy(arr, &arr[256], 3 * sizeof(int));
  246. double I_arr[128];
  247. //double V_arr[128];
  248. //memcpy(V_arr, &arr[127], 128 * sizeof(double));
  249. double P_arr[3];
  250. memcpy(I_arr, &arr[3], 128 * sizeof(double));
  251. memcpy(P_arr, arr, 3 * sizeof(double));
  252. // for(int i=0;i<3;i++) {
  253. // printf("P:%f\n",P_arr[i]);
  254. // }
  255. //-------------------------------------------------------------------------------->改
  256. double* feature = (double*)malloc(23 * sizeof(double));
  257. double *fftres = get_feature(I_arr, 2, 10, 10);
  258. for (int i = 0; i < 23; i++)
  259. {
  260. if (i < 3){
  261. feature[i] = P_arr[i];
  262. }
  263. else {
  264. feature[i] = fftres[i-3];
  265. }
  266. }
  267. for (int i = 0; i < 23; i++) {
  268. // for (int i = 0; i < 20; i++) {
  269. data[i].index = i + 1;
  270. data[i].value = feature[i]; // Replace with processed data
  271. //printf("data[%d].index=%d ",i,data[i].index);
  272. //printf("data[%d].value=%f\n",i,data[i].value);
  273. //printf("(%d,%f), ",i+1,data[i].value);
  274. }
  275. // for (int i = 0; i < 20; i++)
  276. // {feature[i] = fftres[i];}
  277. // for (int i = 0; i < 20; i++) {
  278. // data[i].index = i + 1;
  279. // data[i].value = feature[i]; // Replace with processed data}
  280. data[size].index = -1; // The last element should have index -1 to indicate the end
  281. return data;
  282. }
  283. ///------------------------------FFT算法 & 寻找局部最优幅度组----------------------------------
  284. double* calculateMagnitude(complexNumber* x) {
  285. double* magnitude = (double*)malloc(N * sizeof(double));
  286. // 遍历信号x中的每个复数对象
  287. for (int i = 0; i < N / 2; i++) {
  288. double real = x[i].realPart;
  289. double imag = x[i].imaginaryPart;
  290. // 计算实部平方和虚部平方的和
  291. double magnitudeSquare = real * real + imag * imag;
  292. magnitude[i] = 2 * sqrt(magnitudeSquare) / N;
  293. //printf("magnitude[%d] = %f", i, magnitude[i]);
  294. }
  295. return magnitude;
  296. }
  297. /*快速傅里叶变换*/
  298. void fastFourierOperation(complexNumber* x, complexNumber* W)
  299. {
  300. int l = 0;
  301. complexNumber up, down, product;
  302. changePosition(x); //偶奇变换算法
  303. for (int i = 0; i < log(N) / log(2); i++) //一级蝶形运算
  304. {
  305. l = 1 << i;
  306. for (int j = 0; j < N; j += 2 * l) //一组蝶形运算
  307. {
  308. for (int k = 0; k < l; k++) //一个蝶形运算
  309. {
  310. mul(x[j + k + l], W[N * k / 2 / l], &product);
  311. add(x[j + k], product, &up);
  312. sub(x[j + k], product, &down);
  313. x[j + k] = up;
  314. x[j + k + l] = down;
  315. }
  316. }
  317. }
  318. }
  319. /*偶奇变换算法*/
  320. void changePosition(complexNumber* x)
  321. {
  322. int j = 0, k;//待会儿进行运算时需要用到的变量
  323. complexNumber temp;
  324. for (int i = 0; i < N - 1; i++)
  325. {
  326. if (i < j)
  327. {
  328. //若倒序数大于顺序数,进行变址(换位);否则不变,防止重复交换,变回原数
  329. temp = x[i];
  330. x[i] = x[j];
  331. x[j] = temp;
  332. }
  333. k = N / 2; //判断j的最高位是否为0
  334. while (j >= k)
  335. { //最高位为1
  336. j = j - k;
  337. k = k / 2;
  338. }
  339. j = j + k; //最高位为0
  340. }
  341. }
  342. /*复数加法的定义*/
  343. void add(complexNumber a, complexNumber b, complexNumber* c)
  344. {
  345. c->realPart = a.realPart + b.realPart;
  346. c->imaginaryPart = a.imaginaryPart + b.imaginaryPart;
  347. }
  348. /*复数乘法的定义*/
  349. void mul(complexNumber a, complexNumber b, complexNumber* c)
  350. {
  351. c->realPart = a.realPart * b.realPart - a.imaginaryPart * b.imaginaryPart;
  352. c->imaginaryPart = a.realPart * b.imaginaryPart + a.imaginaryPart * b.realPart;
  353. }
  354. /*复数减法的定义*/
  355. void sub(complexNumber a, complexNumber b, complexNumber* c)
  356. {
  357. c->realPart = a.realPart - b.realPart;
  358. c->imaginaryPart = a.imaginaryPart - b.imaginaryPart;
  359. }
  360. /*FFT*/
  361. double* fft(double* arr) {
  362. complexNumber x[N], W[N / 2];
  363. for (int i = 0; i < N; i++)
  364. {
  365. x[i].realPart = arr[i];
  366. x[i].imaginaryPart = 0;
  367. }
  368. for (int i = 0; i < N / 2; i++)
  369. {
  370. W[i].realPart = cos(2 * PI / N * i);//用欧拉公式计算旋转因子
  371. W[i].imaginaryPart = -1 * sin(2 * PI / N * i);
  372. }
  373. fastFourierOperation(x, W);//调用快速傅里叶变换
  374. double* magnitudes = calculateMagnitude(x);
  375. return magnitudes;
  376. }
  377. int min(int a,int b) {
  378. if(a>b) {return b;}
  379. return a;
  380. }
  381. int max(int a,int b) {
  382. if(a>b){return a;}
  383. return b;
  384. }
  385. /*获取局部最优*/
  386. int isLocalMax(double* data, int idx, int win, int size) {
  387. if(idx<win) {
  388. for(int i=0;i<idx;i++) {
  389. if(data[idx]<data[i]){return 0;}
  390. }
  391. for(int i=idx+1;i<min(size,idx+win+1);i++){
  392. if(data[idx]<data[i]) {return 0;}
  393. }
  394. }
  395. else if(idx>=size-win) {
  396. for(int i=0;i<max(0,idx-win);i++) {
  397. if(data[idx]<data[i]){return 0;}
  398. }
  399. for(int i=idx+1;i<size;i++) {
  400. if(data[idx<data[i]]){return 0;}
  401. }
  402. }
  403. else if(idx>=win && idx<size-win) {
  404. for(int i=1;i<win+1;i++) {
  405. if(data[idx]<data[idx-i] || data[idx]<data[idx+i])
  406. {return 0;}
  407. }
  408. }
  409. return 1;
  410. //if ((idx < win) || (idx > (size - win))) {
  411. // return 0;
  412. //}
  413. //for (int i = 1; i <= win; i++) {
  414. // if ((data[idx] < data[idx - i]) || (data[idx] < data[idx + i])) {
  415. // //printf("%d %f\n", idx, data[idx]);
  416. // return 0;
  417. // }
  418. //}
  419. //return 1;
  420. }
  421. /*取得feature训练可用*/
  422. double* get_feature(double* arr, int win, int hold, int count)
  423. {
  424. //printf(("win:%d, hold:%d, count:%d\n"));
  425. //double(*result)[2] = calloc(count, sizeof(*result));
  426. double(*result)[2] = (double(*)[2])calloc(count, sizeof(*result));
  427. // printf("打印getfeature传入数组\n");
  428. // for (int i = 0; i < N ; i++)
  429. // {
  430. // printf("%f\n", arr[i]);
  431. // }
  432. double* pFft = fft(arr);
  433. double pFrq[N / 2];
  434. // printf("打印幅度:=======================\n");
  435. // for (int i = 0; i < N / 2; i++)
  436. // {
  437. // printf("%f\n", pFft[i]);
  438. // }
  439. //printf("打印频率:=======================\n");
  440. for (int i = 0; i < N / 2; i++) {
  441. pFrq[i] = (double)i * 3906 / 129; // 计算每个点的值
  442. //printf("%f\n", pFrq[i]);
  443. }
  444. int idx = 0;
  445. //printf("%d\n", sizeof(pFft) / sizeof(pFft[0]));
  446. //64为pFft长度
  447. for (int i = 0; i < 64; i++) {
  448. //printf("%d", isLocalMax(pFft, i, win, 64));
  449. //printf("%d\n",isLocalMax(pFft, i, win, 64));
  450. if (isLocalMax(pFft, i, win, 64) && pFft[i] > hold) {
  451. // Store results
  452. result[idx][0] = pFrq[i];
  453. result[idx][1] = pFft[i];
  454. idx++;
  455. }
  456. if (idx >= count) {
  457. break;
  458. }
  459. }
  460. // printf("fft_localmax:=======================\n");
  461. // for (int i = 0; i < count; i++) {
  462. // printf("%f %f\n", result[i][0], result[i][1]);
  463. // }
  464. double* res = (double*)malloc(count * 2 * sizeof(double));
  465. int index = 0;
  466. for (int i = 0; i < 2 * count; i += 2)
  467. {
  468. res[i] = result[index][0];
  469. res[i + 1] = result[index][1];
  470. index++;
  471. }
  472. return res;
  473. }
  474. //------------------------------------------- FFT END ------------------------------------------------
  475. //*******************************************************************************************************
  476. //**************************************************************************************************
  477. //-------------------------------------- 预测函数 -------------------------------------------------
  478. int run_predict(int *arr) {
  479. FILE *file = fopen("./config.txt", "r");
  480. if (file == NULL) {
  481. perror("Error opening file");
  482. return 1;
  483. }
  484. char model_path[100]; // 假设模型名称不会超过100个字符
  485. if (fscanf(file, "model_path = %99s", model_path) != 1) {
  486. fprintf(stderr, "Error reading model path from config file\n");
  487. fclose(file);
  488. return 1;
  489. }
  490. //打印模型名称
  491. // for (int i = 0; i < 131; i++)
  492. // {
  493. // printf("%d, ",arr[i]);/* code */
  494. // }
  495. // printf("hello");
  496. // printf("Model path: %s\n", model_path);
  497. //关闭文件
  498. struct svm_model* model = svm_load_model(model_path);; // �����
  499. struct svm_node* y = l2x(arr,131);
  500. double res = svm_predict(model, y);
  501. fclose(file);
  502. return res;
  503. }
  504. // int main() {
  505. // //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};
  506. // 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};
  507. // int a = run_predict(arr);
  508. // printf("result is : %d\n",a);
  509. // return 0;
  510. // }