 
 
 //knn code below{{{{{{{{{{{{{{{{{{{{{{{{
-int* digits=NULL;
-int* digitsDevice=NULL;
+
 float* trainDataHost=NULL;
 float* trainDataKernel=NULL;
 float* distantHost=NULL;
 float* distantKernel=NULL;
 
+int* digits=NULL;
+int* digitsDevice=NULL;
+float* EigenVectors;
 float* trainDataPCAHost=NULL;
 float* trainDataPCAKernel=NULL;
 float* distantPCAHost=NULL;
 float* distantPCAKernel=NULL;
 
+void freePCAKNN() {
+	free(digits);
+	cudaFree(digitsDevice);
+	cudaFree(EigenVectors);
+	free(trainDataPCAHost);
+	cudaFree(trainDataPCAKernel);
+	free(distantPCAHost);
+	cudaFree(distantPCAKernel);
+}
 //init the answer to the training data
 //return by pointer
 //this is because the training data only holds the data

	merge(distantHost, n, m);
}


void recognizePCA(int* ans, int count) {
	int distantPCASize=sizeof(float)*TrainDataNum*count;
	dim3 dimBlock(Reduced_Data_Length, 1, 1);
	dim3 dimGrid(TrainDataNum, 1, 1);

	knnPCA<<<dimGrid, dimBlock>>>(trainDataPCAKernel, distantPCAKernel, count);
	cudaDeviceSynchronize();

	cudaMemcpy(distantPCAHost, distantPCAKernel, distantPCASize, cudaMemcpyDeviceToHost);
	cuCheck(__LINE__);
	for(int j=0; j<count; ++j) {
		cudaMemcpy(digitsHost, digitsDevice, sizeof(int)*TrainDataNum, cudaMemcpyDeviceToHost);
		cuCheck(__LINE__);
		float* curDistantHost=distantPCAKernel+j*TrainDataNum;
		mergeSortPCA(curDistantHost, digitsHost, TrainDataNum);
		int num[10]={};
		// if(curDistantHost[0]>180) {
		// 	ans[j]=-1;
		// 	continue;
		// }
		for(int i=0; i<5; i++) {
			num[digitsHost[i]]+=1;
		}
		int curBest=-1;
		int curInt=-1;
		for(int i=0; i<10; i++) {
			if(num[i]!=0&&num[i]>curBest) {
				curBest=num[i];
				curInt=i;
			}
		}
		ans[j]=curInt;
	}
}

