//datainfo.cpp
#include"datainfo.h"
#include"allocmem.h"
#include"math.h"
#include"stdio.h"
#include<stdlib.h>



DataInfoAndPrepro::DataInfoAndPrepro()
{
	N = 0, Nout = 0, Nv = 0, ClustersSoFar = 0;	GlobalWtsMartrix = NULL; DistanceMeasure = NULL;
	Inputs = NULL; Outputs = NULL; InputMean = NULL; InputVariance = NULL;OutlierDistance = NULL; 
	GlobalCrossCor = NULL;	GlobalAutoCor = NULL; ModWts = NULL; ClusterCenters = NULL;
}

void DataInfoAndPrepro::init()
{
	int i;
	GlobalWtsMartrix = FarAllocateMatrixMemory(Nout,N+1);
	DistanceMeasure = FarAllocateMemory(N);InputMean = FarAllocateMemory(N);
	InputVariance = FarAllocateMemory(N); Inputs = FarAllocateMemory(N+1);
	Outputs = FarAllocateMemory(Nout); GlobalAutoCor = FarAllocateMatrixMemory(N+1,N+1);
	GlobalCrossCor = FarAllocateMatrixMemory(Nout,N+1);OutlierDistance = FarAllocateMemory(ClustersSoFar);
	ClusterCenters = FarAllocateMatrixMemory(ClustersSoFar,N);
	ModWts = (double***)calloc(ClustersSoFar, sizeof(double**));
	if(	ModWts == NULL)
	{
		printf("Memory could not be allocated....\n");
		exit(1);
	}

	for(i = 0; i < ClustersSoFar; i++)
	{
		ModWts[i]      = FarAllocateMatrixMemory(Nout, N+1);
	}
}

DataInfoAndPrepro::~DataInfoAndPrepro()
{
	free(GlobalWtsMartrix);free(DistanceMeasure);free(InputMean);free(InputVariance);free(Inputs);
	free(Outputs); free(GlobalAutoCor);free(OutlierDistance); free(ClusterCenters);free(ModWts);
	free(GlobalCrossCor); fclose(fpTestingdata);
}

void DataInfoAndPrepro::GetDataInformationFromUser()
{
	int i,j,k;
	char FileTemp[100];
	FILE * fpTemp, * fpwt;
	fpTemp = OpenFile("c:/temp.txt","r");
	fscanf(fpTemp,"%s",FileTemp);
   	i = 0;j = 0;
	do
	{
		if(FileTemp[i] == '"')
		{
			i ++;
			continue;
		}
		else
		{
			DatafileName[j] = FileTemp[i];
			i ++;
			j ++;
		}
	}while(FileTemp[i] != 0);
	DatafileName[j] = 0;
	fpTestingdata = OpenFile(DatafileName,"rt");
	
	fscanf(fpTemp,"%s",FileTemp);
   	i = 0;j = 0;
	do
	{
		if(FileTemp[i] == '"')
		{
			i ++;
			continue;
		}
		else
		{
			WeightsFileName[j] = FileTemp[i];
			i ++;
			j ++;
		}
	}while(FileTemp[i] != 0);
	WeightsFileName[j] = 0;
	fpwt = OpenFile(WeightsFileName,"r");
	fclose(fpTemp);

	fscanf(fpwt,"%s",Infile);
	fscanf(fpwt,"%d",&N);
	fscanf(fpwt,"%d",&Nout);
	fscanf(fpwt,"%d",&ClustersSoFar);
	//initiate the matrix
	init();
	/* next read the Linear Model wts	*/
	for( i =0; i < Nout; i++)
	{
		for(j = 0 ; j <= N; j ++)
		{
			fscanf(fpwt,"%lf", &GlobalWtsMartrix[i][j]);
		}
	}


	/* next read the Distance measure wts	*/

	for( i =0; i < N ; i++)
	{
		 
		fscanf(fpwt,"%lf",&DistanceMeasure[i]);
	}
	/* next read the feature mean vector	*/

	for( i =0; i < N; i++)
	{
		fscanf(fpwt,"%lf", &InputMean[i]);
	}
	/* next read the feature variance  vector	*/

	for( i =0; i < N; i++)
	{
		fscanf(fpwt,"%lf",&InputVariance[i]);
	}
	/* read now the individual module wts */
	for( i =0; i < ClustersSoFar; i++)
	{
		for( j =0; j < Nout; j++)
		{
			for( k =0; k <= N; k++)
			{
				fscanf(fpwt,"%lf",&ModWts[i][j][k]);
			}
			
		}
	}

	/* read cluster centers	*/
	for( i =0; i < ClustersSoFar; i++)
	{
		for( j =0; j < N; j++)
		{
			fscanf(fpwt,"%lf",&ClusterCenters[i][j]);
		}
		
	}
	/* read Outlier distances	*/
	for( i =0; i < ClustersSoFar; i++)
	{
		fscanf(fpwt,"%lf",&OutlierDistance[i]);
	}
	fclose(fpwt);
	
}

void DataInfoAndPrepro::CaculateError()
{
	int i,j,NearestCluster, *PatternsPerCluster,Members, ClassId, ErrorPattern;
	double *ClusterErrors;
	double  DistanceSum,MinDistance, temp, TotalError=0.0;
	char str[25];
	FILE * result;

	double Max_y;
	int Class_obtained;

	ErrorPattern = 0;
	PatternsPerCluster = (int*)calloc(ClustersSoFar,sizeof(int));
	ClusterErrors = AllocateMemory(ClustersSoFar);
	result = OpenFile("c:/result.txt","w+");

	rewind(fpTestingdata);
	Inputs[N] = 1.0;

	/* initialize  PatternsPerCluster array to 0	*/
	for ( i = 0; i < ClustersSoFar; i++)
	{
		PatternsPerCluster[i] = 0 ;
	}
	rewind(fpTestingdata);
	Nv = 0;
//	while(!feof(fpForFitData))
	while(!feof(fpTestingdata))
	{
		Nv ++;
		/* read one vector from estimated outputs file	*/


		for ( i = 0; i < N; i++)
		{
			if (fscanf(fpTestingdata, "%s",str ))
			{
				{
					Inputs[i] = atof(str);
				}
			}
		}
		fscanf(fpTestingdata,"%d",&ClassId);

		for(i = 0; i < Nout; i ++){
			Outputs[i] = 0.0;
		}
		
		if(feof(fpTestingdata))
		{
			break;
		}
		
		//first adding the global linear mapping
		for(i = 0 ; i < Nout; i ++)
		{
			for( j = 0; j <= N; j ++)
			{
				Outputs[i] += Inputs[j] *  GlobalWtsMartrix[i][j];
			}
		}
		//then norminize the inputs 
		for( i = 0 ; i < N; i ++)
		{
			Inputs[i] -= InputMean[i];
			Inputs[i] /= InputVariance[i];
		}
		//determine the membership of this pattern
		DistanceSum = 0.0;
		MinDistance = 1.0E40;

		for(i = 0; i < ClustersSoFar; i++)
		{
			DistanceSum = 0.0;
			for ( j = 0; j < N; j++)
			{
				temp = Inputs[j] - ClusterCenters[i][j];
				DistanceSum += (DistanceMeasure[j]* (temp*temp));
			}
			if(DistanceSum <= MinDistance)
			{
				MinDistance = DistanceSum;
				NearestCluster = i;
			}
		}
		//adding the clusters mapping 
		for(i = 0; i < Nout; i ++)
		{
			for( j = 0 ; j <= N; j ++)
			{
				Outputs[i] += Inputs[j]*ModWts[NearestCluster][i][j];
			}
		}
		PatternsPerCluster[NearestCluster] += 1;
		for( i = 0; i < Nout; i ++)
		{
			if( i == ClassId) ClusterErrors[NearestCluster] += abs(5.0-Outputs[i]);
			else ClusterErrors[NearestCluster] += abs(-5.0-Outputs[i]);
			
		}
		//here we find the maxima of the output and calculate the misclassified patterns
		Max_y= Outputs[0];
	    Class_obtained=1;

		for (i=1;i<Nout;i++)
		{
			if(Outputs[i]>Max_y) {
				Max_y= Outputs[i];
				Class_obtained= i+1;
			}
		}
		if ( ClassId != Class_obtained ) {
			ErrorPattern += 1;
		}


	}
	Nv --;
	for(i = 0; i < ClustersSoFar; i++)
	{
		Members = PatternsPerCluster[i];
		printf("Module %d has %d members  Error %lf\n",
		 i,Members,ClusterErrors[i]  );
//		fprintf(fpResultDatail,"Module %d has %d members  Error %lf\n",
//		 i,Members,ClusterErrors[i]  );
		 TotalError += ClusterErrors[i];
	}
	printf("\n\tTotal MS Error :  %lf\n",TotalError/ Nv);
	fprintf(result,"\t%s\n","Testing File Name:");
	fprintf(result,"\t%s\n\n",DatafileName);
	fprintf(result,"\t%s\n","Testing Weights File Name:");
	fprintf(result,"\t%s\n\n",WeightsFileName);
	fprintf(result,"\tNo of Input:\t%d\n",N);
	fprintf(result,"\tNo of Class:\t%d\n",Nout);
	fprintf(result,"\tNo of Clusters:\t%d\n\n",ClustersSoFar);
	for(i = 0; i < ClustersSoFar; i++)
	{
		Members = PatternsPerCluster[i];
		fprintf(result,"\tModule %d has %d members  Error %lf\n",
		 i,Members,ClusterErrors[i]  );
		
		
	}
	fprintf(result,"\tNo. of patterns in error %d,\tErrorPercentage is: %f\n",ErrorPattern,(double)ErrorPattern/(double(Nv)));
	printf("\tNo. of patterns in error %d,\tErrorPercentage is: %f\n",ErrorPattern,(double)ErrorPattern/(double(Nv)));
	fprintf(result,"\n\tTotal MS Error :  %lf\n",TotalError/ Nv);
//	fprintf(fpResultDatail,"\nTotal MS Error :  %lf\n",TotalError/Nv);
//	fprintf(fpResultSimple,"\nCluster : %d   Total Ms Error : %lf\n", ClustersSoFar,TotalError/Nv);  
//	fprintf(fpResultSimple,"%d %lf\n", ClustersSoFar,TotalError/Nv);
//	TotalOrigError = TotalError


}
