/*****************************************************************************************************************
									K  -  M E A N
  
	Author: Pramod Lakshmi Narasimha
			Image Processing and Neural Networks Lab,
			Electrical Engineering Department,
			University of Texas at Arlington.

	This program refines the clusters got in Seqential Leader clustering.
****************************************************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include "Kmean_SL.c"

void main()
{
	FILE *fpIn, *fpOut;
	int Nit, N, It, i, k, minIndex;
	char Infile[_MAX_PATH];
	double *x, dist, min_dist;

	printf("Enter the Input File Name : ");
	scanf("%s", &Infile);

	printf("Enter the Number of Elements in a Vector : ");
	scanf("%d", &N);

	printf("Enter the Number of Iterations : ");
	scanf("%d", &Nit);

	x = (double *) malloc(sizeof(double));

	SL_Clustering(Infile, N);

	fpOut = fopen("KmeanResult.txt", "w");

	if(fpOut == NULL)
	{
		perror("KmeanResult.txt");
		exit(1);
	}

	for(It = 0; It < Nit; It++)
	{
		for(Pres_Clust = Start_Clust; Pres_Clust->next != NULL; Pres_Clust = Pres_Clust->next)
		{
			for(i = 0; i < N; i++)
				Pres_Clust->mean[i] = 0.0;

			if(Pres_Clust->Num_vec != 0)
			{
				for(Pres_Clust->Clust_Pattern = Pres_Clust->Clust_Start_Pattern; Pres_Clust->Clust_Pattern->next != NULL; Pres_Clust->Clust_Pattern = Pres_Clust->Clust_Pattern->next)
				{
					for(i = 0; i < N; i++)
						Pres_Clust->mean[i] += Pres_Clust->Clust_Pattern->x[i] / Pres_Clust->Num_vec;
				}

				for(i = 0; i < N; i++)
					Pres_Clust->mean[i] += Pres_Clust->Clust_Pattern->x[i] / Pres_Clust->Num_vec;
			}

			Pres_Clust->Clust_Start_Pattern->next = NULL;

			Pres_Clust->Num_vec = 1;
		}

		for(i = 0; i < N; i++)
			Pres_Clust->mean[i] = 0.0;

		if(Pres_Clust->Num_vec != 0)
		{
			for(Pres_Clust->Clust_Pattern = Pres_Clust->Clust_Start_Pattern; Pres_Clust->Clust_Pattern->next != NULL; Pres_Clust->Clust_Pattern = Pres_Clust->Clust_Pattern->next)
			{
				for(i = 0; i < N; i++)
					Pres_Clust->mean[i] += Pres_Clust->Clust_Pattern->x[i] / Pres_Clust->Num_vec;
			}

			for(i = 0; i < N; i++)
				Pres_Clust->mean[i] += Pres_Clust->Clust_Pattern->x[i] / Pres_Clust->Num_vec;
		}

		Pres_Clust->Clust_Start_Pattern->next = NULL;

		Pres_Clust->Num_vec = 1;

		fpIn = fopen(Infile, "r");

		if(fpIn == NULL)
		{
			perror(Infile);
			exit(0);
		}

		for(i = 0; i < N; i++)
		{
			fscanf(fpIn, "%lf", &Pres_Clust->Clust_Pattern->x[i]);
		}

		while(!feof(fpIn))
		{
			for(i = 0; i < N; i++)
				fscanf(fpIn, "%lf", &x[i]);

			min_dist = Distance(x, Start_Clust->mean, N);
			minIndex = 1;

			for(Pres_Clust = Start_Clust, k = 1; Pres_Clust->next != NULL; Pres_Clust = Pres_Clust->next, k++)
			{
				dist = Distance(x, Pres_Clust->mean, N);

				if(dist < min_dist)
				{
					min_dist = dist;
					minIndex = k;
				}
			}

			dist = Distance(x, Pres_Clust->mean, N);

			if(dist < min_dist)
			{
				min_dist = dist;
				minIndex = k;
			}

			if(min_dist <= T)
			{
				for(Pres_Clust = Start_Clust, k = 1; minIndex > k; Pres_Clust = Pres_Clust->next, k++);
				Pres_Clust->Num_vec ++;
				Pres_Clust->ClassId = k;
				for(Pres_Clust->Clust_Pattern = Pres_Clust->Clust_Start_Pattern; Pres_Clust->Clust_Pattern->next != NULL; Pres_Clust->Clust_Pattern = Pres_Clust->Clust_Pattern->next);
				Pres_Clust->Clust_Prev_Pattern = Pres_Clust->Clust_Pattern;
				Pres_Clust->Clust_Pattern = (struct pattern *) malloc(sizeof(struct pattern));
				Pres_Clust->Clust_Prev_Pattern->next = Pres_Clust->Clust_Pattern;
				Pres_Clust->Clust_Pattern->x = (double *) calloc(N, sizeof(double));
				Pres_Clust->Clust_Pattern->next = NULL;

				for(i = 0; i < N; i++)
					Pres_Clust->Clust_Pattern->x[i] = x[i];

				Pres_Clust->Clust_Pattern->Membership = k;
			}
			else
			{
				for(Pres_Clust = Start_Clust, k = 1; Pres_Clust->next != NULL; Pres_Clust = Pres_Clust->next, k++);

				Prev_Clust = Pres_Clust;
				Pres_Clust = (struct Clust *) malloc(sizeof(struct Clust));
				Prev_Clust->next = Pres_Clust;
				Pres_Clust->Clust_Pattern = (struct pattern *) malloc(sizeof(struct pattern));

				Pres_Clust->Clust_Start_Pattern = Pres_Clust->Clust_Pattern;
				Pres_Clust->Clust_Pattern->next = NULL;

				Pres_Clust->Clust_Pattern->x = (double *) calloc(N, sizeof(double));
				Pres_Clust->mean = (double *) calloc(N, sizeof(double));
				Pres_Clust->next = NULL;
				Pres_Clust->Num_vec = 1;
				Pres_Clust->ClassId = k + 1;
				Pres_Clust->Clust_Pattern->Membership = k + 1;

				for(i = 0; i < N; i++)
				{
					Pres_Clust->Clust_Pattern->x[i] = x[i];
					Pres_Clust->mean[i] = x[i];
				}
			}
		}

		fclose(fpIn);

		E = Error(N);

		printf("Error = %lf\n", E);

		fprintf(fpOut, "Error in %d Iteration is %lf\n", It + 1, E);

	}

	fprintf(fpOut, "\n\nCluster Center Vectors : \n\n");

	for(Pres_Clust = Start_Clust; Pres_Clust->next != NULL; Pres_Clust = Pres_Clust->next)
	{
		for(i = 0; i < N; i++)
			fprintf(fpOut, "%lf\t", Pres_Clust->mean[i]);
		fprintf(fpOut, "%d", Pres_Clust->ClassId);

		fprintf(fpOut, "\n");
	}

	for(i = 0; i < N; i++)
		fprintf(fpOut, "%lf\t", Pres_Clust->mean[i]);
	fprintf(fpOut, "%d", Pres_Clust->ClassId);

	fprintf(fpOut, "\n");

	fclose(fpOut);

}
