
#include "head.h"
#include "tools.h"
#include "function.h"
#include "kmeans.h"
#include "coreset.h"
using namespace std;

double Mean(vector<double> a) {
	double sum = 0;
	for (double x : a) sum += x;
	return sum / (int)a.size();
}

double Max(vector<double> a) {
	double ret = 0;
	for (double x : a) ret = max(ret, x);
	return ret;
}

double Min(vector<double> a) {
	double ret = 1;
	for (double x : a) ret = min(ret, x);
	return ret;
}

double Var(vector<double> a) {
	double ret = 0, ave = Mean(a);
	for (double x : a) ret += (x - ave) * (x - ave);
	return ret / (int)a.size();
}




int main(int argc, char** argv) {

	if (argc < 7) {
		printf("6 arguments are required (data_name, data_size, data_dim, num_of_centers, num_of_outliers,threshold).");
		return 0;
	}
	FILE* FIN = fopen(argv[1], "r");
	//N : number of datapoints;
	//D : dimension;
	//k : number of clusters;
	//m : number of outliers;
	//thr : determine how the rings and groups are formed (see Implementation Details in Section 5 of our paper)

	int N = atoi(argv[2]), D = atoi(argv[3]), k = atoi(argv[4]), m = atoi(argv[5]);
	double thr = atof(argv[6]);

	dataset X;
	cerr << "-----------Reading Data 1D-----------" << endl;
	for (int i = 1; i <= N; i++) {
		datapoint x; x.resize(D + 1);
		x[0] = 1;
		for (int j = 1; j <= D; j++)
			fscanf(FIN, "%lf", &x[j]);
		X.push_back(x);
	}
	fclose(FIN);
	cerr << "-----------Reading Over 1D-----------" << endl;
	cerr << "-----------Approximating KRMeans 1D-----------" << endl;
	dataset C_approx;
	FILE* APPKM = fopen("approx_median.txt", "r");
	int nn; fscanf(APPKM, "%d", &nn);
	for (int i = 0; i < nn; i++) {
		datapoint x; x.resize(D+1);
		for (int i = 1; i < x.size(); i++) fscanf(APPKM, "%lf", &x[i]);
		C_approx.push_back(x);
	}
	cerr << rcost(X, C_approx, m, 1) << endl;

	fclose(APPKM);
	cerr << "-----------Approximating End 1D-----------" << endl;

	int TT = 10, T;
	vector<pair<dataset, double> > testdata;

	FILE* TESTDATA = fopen("testdata.txt", "r");
	fscanf(TESTDATA, "%d", &T);
	for (int i = 0; i < T; i++) {
		dataset A; double cst;
		fscanf(TESTDATA, "%lf", &cst);
		for (int j = 1; j <= k; j++) {
			datapoint x; x.resize(D+1);
			for (int l = 1; l < x.size(); l++)
				fscanf(TESTDATA, "%lf", &x[l]);
			A.push_back(x);
		}
		testdata.push_back({ A, cst });
	}
	cerr << "-----------End-----------" << endl;
	dataset Our1D;
	FILE* RES = fopen("res.txt", "a");
	for (int i = 200; i <= 10000; i += 500)
	{
		double eps = ((double)1 / (double)i);
		vector<double> dres;
		for (int tt = 1; tt <= TT; tt++) {
			cerr << tt << " ";
			Our1D = Bucket_Coreset(X, m, eps);

			double max_serr, max_derr = 0;
			for (int t = 0; t < T; t++) {
				dataset C = testdata[t].first;
				double xcost = testdata[t].second;
				double dcost = rcost(Our1D, C, m, 1);

				double derr = fabs(xcost - dcost) / xcost;
				max_derr = max(max_derr, derr);

			}
			dres.push_back(max_derr);
		}
		cerr << "Testing end." << endl;
		fprintf(RES, "coreset size 1D : %d\n", (int)Our1D.size());
		fprintf(RES, "Ours1D, ave: %lf max: %lf min: %lf var: %lf\n", Mean(dres), Max(dres), Min(dres), Var(dres));

		cerr << "coreset size 1D : " << (int)Our1D.size() << endl;
		cerr << "Ours1D, ave: " << Mean(dres) << "; max: " << Max(dres) << "; min: " << Min(dres) << "; var: " << Var(dres) << endl;
	}

	
	return 0;




}