#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "svm.h"
#include <math.h>
#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<win) {
//     for(int i=0;i<idx;i++) {
//        if(data[idx]<data[i]){return 0;}
//     }
//     for(int i=idx+1;i<min(size,idx+win+1);i++){
//        if(data[idx]<data[i]) {return 0;}
//     }
// 	}
// 	else if(idx>=size-win) {
// 	    for(int i=0;i<max(0,idx-win);i++) {
// 	       if(data[idx]<data[i]){return 0;}
// 	    }
// 	    for(int i=idx+1;i<size;i++) {
// 	       if(data[idx<data[i]]){return 0;}
// 	    }
// 	}
// 	else if(idx>=win && idx<size-win) {
// 	    for(int i=1;i<win+1;i++) {
// 	       if(data[idx]<data[idx-i] || data[idx]<data[idx+i])
// 	       {return 0;}
// 	    }
// 	}
// 	return 1;
// }


// /*取得feature训练可用*/
// double* get_feature(double* arr, int win, int hold, int count)
// {
// 	double(*result)[2] = (double(*)[2])calloc(count, sizeof(*result));

// 	double* pFft = fft(arr);
// 	double pFrq[N / 2];

// 	for (int i = 0; i < N / 2; i++) {
// 		pFrq[i] = (double)i * 3906 / 129;  // 计算每个点的值
// 	}

// 	int idx = 0;
// 	for (int i = 0; i < 64 ; i++) {
// 		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;
// 		}
// 	}

// 	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<win) {
		for(int i=0;i<idx;i++) {
			if(data[idx]<data[i]){return 0;}
		}
		for(int i=idx+1;i<min(size,idx+win+1);i++){
			if(data[idx]<data[i]) {return 0;}
		}
	}
	else if(idx>=size-win) {
		for(int i=0;i<max(0,idx-win);i++) {
			if(data[idx]<data[i]){return 0;}
		}
		for(int i=idx+1;i<size;i++) {
			if(data[idx<data[i]]){return 0;}
		}
	}
	else if(idx>=win && idx<size-win) {
		for(int i=1;i<win+1;i++) {
			if(data[idx]<data[idx-i] || data[idx]<data[idx+i])
			{return 0;}
		}
	}
	return 1;

	//if ((idx < 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;
// }
