#include <stdio.h>
#include <windows.h>
#include <math.h>
#include <stdlib.h>
#include <conio.h>
#include <time.h>
#include "diplomka_optimalizace.h"

#define NAZEV "C:\\Users\\Omajo\\Desktop\\VUT\\SP_code\\2D.dat"
#define NAZEVVYSTUPU "C:\\Users\\Omajo\\Desktop\\VUT\\SP_code\\CosxplusxVystup1.txt"
#define NAZEVVYSTUPU2 "C:\\Users\\Omajo\\Desktop\\VUT\\SP_code\\CosxplusxVystup2.txt"
#define NAZEVVYSTUPU3 "C:\\Users\\Omajo\\Desktop\\VUT\\SP_code\\CosxplusxVystup3.txt"
#define NAZEVVYSTUPU4 "C:\\Users\\Omajo\\Desktop\\VUT\\SP_code\\CosxplusxVystup4.txt"
#define NAZEVVYSTUPU5 "C:\\Users\\Omajo\\Desktop\\VUT\\SP_code\\CosxplusxVystup5.txt"
#define NAZEVVYSTUPU6 "C:\\Users\\Omajo\\Desktop\\VUT\\SP_code\\CosxplusxVystup6.txt"
//Polynom
#define NAZEVVYSTUPU7 "C:\\Users\\Omajo\\Desktop\\VUT\\SP_code\\PolynomVystup1.txt"
#define NAZEVVYSTUPU8 "C:\\Users\\Omajo\\Desktop\\VUT\\SP_code\\PolynomVystup2.txt"
#define NAZEVVYSTUPU9 "C:\\Users\\Omajo\\Desktop\\VUT\\SP_code\\PolynomVystup3.txt"
#define NAZEVVYSTUPU10 "C:\\Users\\Omajo\\Desktop\\VUT\\SP_code\\PolynomVystup4.txt"
#define NAZEVVYSTUPU11 "C:\\Users\\Omajo\\Desktop\\VUT\\SP_code\\PolynomVystup5.txt"
#define NAZEVVYSTUPU12 "C:\\Users\\Omajo\\Desktop\\VUT\\SP_code\\PolynomVystup6.txt"
//zadana funkce
#define NAZEVVYSTUPU13 "C:\\Users\\Omajo\\Desktop\\VUT\\SP_code\\ZadanaFunkcex1.txt"
#define NAZEVVYSTUPU14 "C:\\Users\\Omajo\\Desktop\\VUT\\SP_code\\ZadanaFunkcex2.txt"
#define NAZEVVYSTUPU15 "C:\\Users\\Omajo\\Desktop\\VUT\\SP_code\\ZadanaFunkcey.txt"
#define NAZEVVYSTUPU16 "C:\\Users\\Omajo\\Desktop\\VUT\\SP_code\\ZadanaFunkceR.txt"
#define NAZEVVYSTUPU17 "C:\\Users\\Omajo\\Desktop\\VUT\\SP_code\\ZadanaFunkceR-1.txt"
#define NAZEVVYSTUPU18 "C:\\Users\\Omajo\\Desktop\\VUT\\SP_code\\ZadanaFunkcePrediktor.txt"
#define NAZEVVYSTUPU19 "C:\\Users\\Omajo\\Desktop\\VUT\\SP_code\\ZadanaFunkceChyba.txt"
#define NAZEVVYSTUPU20 "C:\\Users\\Omajo\\Desktop\\VUT\\SP_code\\ZadanaFunkceZlepseni.txt"
#define NAZEVVYSTUPU21 "C:\\Users\\Omajo\\Desktop\\VUT\\SP_code\\x1.txt"
#define NAZEVVYSTUPU22 "C:\\Users\\Omajo\\Desktop\\VUT\\SP_code\\x2.txt"
#define NAZEVVYSTUPU23 "C:\\Users\\Omajo\\Desktop\\VUT\\SP_code\\ZadanaFunkcex1BB.txt"
#define NAZEVVYSTUPU24 "C:\\Users\\Omajo\\Desktop\\VUT\\SP_code\\ZadanaFunkcex2BB.txt"
#define NAZEVVYSTUPU25 "C:\\Users\\Omajo\\Desktop\\VUT\\SP_code\\ZadanaFunkceyBB.txt"

#define iterace 1000
#define dtheta 1
#define dph 1
#define npoints 1000
#define step 0.02


int main(int argc, char **argv)
{
	FILE *vystup;
	FILE *vystup2;
	FILE *vystup3;
	srand((unsigned int) time(NULL));
	
	int size,i,j,pocetpridanychbodu=1;
	double *polea,*poleb,*polec,cas; 
	//double truemin[3];
	double proMaticiR[300], detmatR, mojeMaticeR[100][100], mojeInvMaticeR[100][100], jednotkovaMatice[100][100], k, **detMatice, pozbod[3], odhady, x, 
	interval[100],nalezeneminimum[3];
	__int64 frekvence, start, stop;
	
	if (!QueryPerformanceFrequency((LARGE_INTEGER*)&frekvence)) // Zjistíme frekvenci performance counteru
	{
	printf("Vas hardware nepodporuje Performance Counter\n");
	return 0; // Hardware nepodporuje Performance Counter proto skončíme bez měření
	}
	/*	
	vystup = fopen(NAZEVVYSTUPU13, "w");			//Nahodne vyorky zadane funkce x1
	
	for(i=0; i<21; i++){				
		fprintf(vystup, "%20.15lf %s", 0.1049+((double)rand() / (double)RAND_MAX)*(4.9951-0.1049), "\n");
	}
	fclose(vystup);
	
	vystup = fopen(NAZEVVYSTUPU14, "w");			//Nahodne vyorky zadane funkce x2
	
	for(i=0; i<21; i++){				
		fprintf(vystup, "%20.15lf %s", 0.1049+((double)rand() / (double)RAND_MAX)*(4.9951-0.1049), "\n");
	}
	fclose(vystup);
	*/
	//double bod1[3] = {1,1,1};
	//double bod2[3] = {2,2,2};
	if(nacti(&polea,&poleb,&polec,&size) == 1){
		printf("Data nebyla nactena !!!\n Soubor se nepodarilo otevrit nebo chybi pamet.\n");	
	}
	else{
		printf("Data se nacetla v poradku.\n");
	}
	k=size;	//uchovani velikosti pole
	/*
	for(i=0; i<10; i++){				//testovaci data cos(x)+x
		proMaticiR[i*2]=(double)(i*2);
		proMaticiR[(i*2)+1]=cos((double)(i*2))+((double)(i*2))/2;
	}
	vystup = fopen(NAZEVVYSTUPU, "w");
	
	for(i=0; i<10; i++){				//ulozeni dat cos(x)+x do souboru
		fprintf(vystup, "%20.15lf %s %20.15lf %s", proMaticiR[i*2], "\t", proMaticiR[(i*2)+1], "\n");
	}
	fclose(vystup);
	
	detMatice = (double **) malloc((size_t)10 * (sizeof(double *)));		//dynamicka alokace matice
    if (detMatice == NULL)
        return 1;

    for (i = 0; i < 10; i++) {
        detMatice[i] = (double *) malloc((size_t)20 * (sizeof(double)));
        if (detMatice[i] == NULL)
            return 1;
    }
	
	maticeR(&proMaticiR[0],mojeMaticeR,10,1);
	
	vystup = fopen(NAZEVVYSTUPU2, "w");		//Matice R do souboru
	for (i = 0; i < 10; i++) {		
		fprintf(vystup, "%s", "\n");		
		for (j = 0; j < 10; j++){	
			fprintf(vystup, "%20.15lf %s", mojeMaticeR[i][j], "  ");
			detMatice[i][j] = mojeMaticeR[i][j];
		}
    }
	fclose(vystup);
	
	//detmatR = determinant(mojeMaticeR,11);
	//detmatR = Determinant(detMatice,10);
	//printf("Determinant = %20.15lf\n", detmatR);
	detmatR = LUdeterminant(mojeMaticeR,10);
	printf("DeterminantLU = %20.15lf\n", detmatR);
	cofactors(mojeMaticeR, mojeInvMaticeR ,10);
	
	//multiply(mojeMaticeR,mojeInvMaticeR,jednotkovaMatice,6,6,6,6);
	
	vystup = fopen(NAZEVVYSTUPU3, "w");		//inverzni matice R do souboru
	for (i = 0; i < 10; i++) {		
		fprintf(vystup, "%s", "\n");		
		for (j = 0; j < 10; j++){	
			fprintf(vystup, "%20.15lf %s", mojeInvMaticeR[i][j], "  ");
		}
    }
	fclose(vystup);
	
	vystup = fopen(NAZEVVYSTUPU4, "w");
	for (i = 0; i <= npoints; i++) {	
		pozbod[0] = step*i;
		odhady = predictor(&pozbod[0],&proMaticiR[0],mojeInvMaticeR,10,1);		
		fprintf(vystup, "%20.15lf %s", odhady, "\n");
    }
	fclose(vystup);
	
	vystup = fopen(NAZEVVYSTUPU5, "w");
	for (i = 0; i <= npoints; i++) {	
		pozbod[0] = step*i;
		odhady = meansquarederror(&pozbod[0],&proMaticiR[0],mojeInvMaticeR,10,1);		
		fprintf(vystup, "%20.15lf %s", odhady, "\n");
    }
	fclose(vystup);
	
	vystup = fopen(NAZEVVYSTUPU6, "w");
	for (i = 0; i <= npoints; i++) {	
		pozbod[0] = step*i;
		odhady = expectedimprovement(&pozbod[0],&proMaticiR[0],mojeInvMaticeR,10,1);		
		fprintf(vystup, "%20.15lf %s", odhady, "\n");
    }
	fclose(vystup);
	
	//polynom
	//testovaci data polynom f(x) = a + b*x + c*x^2 + d*x^3 + ... + p*x^15
		
		/*proMaticiR[0]= 1;
		proMaticiR[1]=polynom(1);
		proMaticiR[2]= 2;
		proMaticiR[3]=polynom(2);
		proMaticiR[4]= 3;
		proMaticiR[5]=polynom(3);
		proMaticiR[6]= 4;
		proMaticiR[7]=polynom(4);
		proMaticiR[8]= 12;
		proMaticiR[9]=polynom(12);
		proMaticiR[10]= 2.56;
		proMaticiR[11]=polynom(2.56);
		proMaticiR[12]= 7.72;
		proMaticiR[13]=polynom(7.72);
		proMaticiR[14]= 8.22;
		proMaticiR[15]=polynom(8.22);
		
		proMaticiR[0]= 1;
		proMaticiR[1]=polynom(1);
		proMaticiR[2]= 2;
		proMaticiR[3]=polynom(2);
		proMaticiR[4]= 2.56;
		proMaticiR[5]=polynom(2.56);
		proMaticiR[6]= 3;
		proMaticiR[7]=polynom(3);
		proMaticiR[8]= 4;
		proMaticiR[9]=polynom(4);
		proMaticiR[10]= 7.72;
		proMaticiR[11]=polynom(7.72);
		proMaticiR[12]= 8.22;
		proMaticiR[13]=polynom(8.22);
		proMaticiR[14]= 12;
		proMaticiR[15]=polynom(12);
		
	vystup = fopen(NAZEVVYSTUPU7, "w");
	
	for(i=0; i<8; i++){				//ulozeni dat polynom f(x) = a + b*x + c*x^2 + d*x^3 + ... + p*x^15
		fprintf(vystup, "%20.15lf %s %20.15lf %s", proMaticiR[i*2], "\t", proMaticiR[(i*2)+1], "\n");
	}
	fclose(vystup);
	
	maticeR(&proMaticiR[0],mojeMaticeR,8,1);
	
	vystup = fopen(NAZEVVYSTUPU8, "w");		//Matice R do souboru
	for (i = 0; i < 8; i++) {		
		fprintf(vystup, "%s", "\n");		
		for (j = 0; j < 8; j++){	
			fprintf(vystup, "%20.15lf %s", mojeMaticeR[i][j], "  ");
			//detMatice[i][j] = mojeMaticeR[i][j];
		}
    }
	fclose(vystup);
	
	detmatR = LUdeterminant(mojeMaticeR,8);
	printf("DeterminantLU = %20.15lf\n", detmatR);
	cofactors(mojeMaticeR,mojeInvMaticeR,8);
	
	//multiply(mojeMaticeR,mojeInvMaticeR,jednotkovaMatice,8,8,8,8);
	
	vystup = fopen(NAZEVVYSTUPU9, "w");		//inverzni matice R do souboru
	for (i = 0; i < 8; i++) {		
		fprintf(vystup, "%s", "\n");		
		for (j = 0; j < 8; j++){	
			fprintf(vystup, "%20.15lf %s", mojeInvMaticeR[i][j], "  ");
		}
    }
	fclose(vystup);
	
	vystup = fopen(NAZEVVYSTUPU10, "w");
	for (i = 0; i <= 600; i++) {	
		pozbod[0] = step*i;
		odhady = predictor(&pozbod[0],&proMaticiR[0],mojeInvMaticeR,8,1);		
		fprintf(vystup, "%20.15lf %s", odhady, "\n");
    }
	fclose(vystup);
	
	vystup = fopen(NAZEVVYSTUPU11, "w");
	for (i = 0; i <= 600; i++) {	
		pozbod[0] = step*i;
		odhady = meansquarederror(&pozbod[0],&proMaticiR[0],mojeInvMaticeR,8,1);		
		fprintf(vystup, "%20.15lf %s", odhady, "\n");
    }
	fclose(vystup);
	
	vystup = fopen(NAZEVVYSTUPU12, "w");
	for (i = 0; i <= 600; i++) {	
		pozbod[0] = step*i;
		odhady = expectedimprovement(&pozbod[0],&proMaticiR[0],mojeInvMaticeR,8,1);		
		fprintf(vystup, "%20.15lf %s", odhady, "\n");
    }
	fclose(vystup);
	*/
	//Funkce zadaná k optimalizaci
	if ((vystup = fopen(NAZEVVYSTUPU13, "r")) == NULL) {
        fprintf(stderr, "Chyba otevreni souboru %s pro cteni\n", NAZEVVYSTUPU13);
        return 1;
    }
	if ((vystup2 = fopen(NAZEVVYSTUPU14, "r")) == NULL) {
        fprintf(stderr, "Chyba otevreni souboru %s pro cteni\n", NAZEVVYSTUPU14);
        return 1;
    }
	
	i=0;
	while(fscanf(vystup, "%lf", &x) != EOF){
	i++;	
	}
	rewind (vystup);
	size=i;
	
	for (i = 0; i < size; i++) {
        fscanf(vystup, "%lf", &proMaticiR[i*3]);
		fscanf(vystup2, "%lf", &proMaticiR[(i*3)+1]);
		proMaticiR[(i*3)+2] = interpoluj(proMaticiR[i*3],proMaticiR[(i*3)+1],polea,poleb,polec,k);
    }
	fclose(vystup);
	fclose(vystup2);
	
	vystup = fopen(NAZEVVYSTUPU15, "w");
	for (i = 0; i < size; i++) {	
		fprintf(vystup, "%20.15lf %s", interpoluj(proMaticiR[i*3],proMaticiR[(i*3)+1],polea,poleb,polec,k), "\n");
    }
	fclose(vystup);
	
	maticeR(&proMaticiR[0],mojeMaticeR,size,2);
	
	vystup = fopen(NAZEVVYSTUPU16, "w");		//Matice R do souboru
	for (i = 0; i < size; i++) {		
		fprintf(vystup, "%s", "\n");		
		for (j = 0; j < size; j++){	
			fprintf(vystup, "%20.15lf %s", mojeMaticeR[i][j], "  ");
		}
    }
	fclose(vystup);
	
	detmatR = LUdeterminant(mojeMaticeR,size);
	printf("DeterminantLU = %20.15lf\n",detmatR);
	cofactors(mojeMaticeR,mojeInvMaticeR,size);
	
	//multiply(mojeMaticeR,mojeInvMaticeR,jednotkovaMatice,size,size,size,size);
	
	vystup = fopen(NAZEVVYSTUPU17, "w");		//inverzni matice R do souboru
	for (i = 0; i < size; i++) {		
		fprintf(vystup, "%s", "\n");		
		for (j = 0; j < size; j++){	
			fprintf(vystup, "%20.15lf %s", mojeInvMaticeR[i][j], "  ");
		}
    }
	fclose(vystup);
	
	vystup = fopen(NAZEVVYSTUPU18, "w");
	for (i = 0; i < 100; i++) {	
		for (j = 0; j < 100; j++) {
			pozbod[0] = 0.1049+(((double)i / 99)*(4.9951-0.1049));
			pozbod[1] = 0.1049+(((double)j / 99)*(4.9951-0.1049));
			odhady = predictor(&pozbod[0],&proMaticiR[0],mojeInvMaticeR,size,2);		
			fprintf(vystup, "%20.15lf %s", odhady, "\n");
    }
	}
	fclose(vystup);
	
	vystup = fopen(NAZEVVYSTUPU19, "w");
	for (i = 0; i < 100; i++) {	
		for (j = 0; j < 100; j++) {
			pozbod[0] = 0.1049+(((double)i / 99)*(4.9951-0.1049));
			pozbod[1] = 0.1049+(((double)j / 99)*(4.9951-0.1049));
			odhady = meansquarederror(&pozbod[0],&proMaticiR[0],mojeInvMaticeR,size,2);		
			fprintf(vystup, "%20.15lf %s", odhady, "\n");
    }
	}
	fclose(vystup);
	
	vystup2 = fopen(NAZEVVYSTUPU21, "w");
	vystup3 = fopen(NAZEVVYSTUPU22, "w");
	vystup = fopen(NAZEVVYSTUPU20, "w");
	for (i = 0; i < 100; i++) {	
		for (j = 0; j < 100; j++) {
			pozbod[0] = 0.1049+(((double)i / 99)*(4.9951-0.1049));
			pozbod[1] = 0.1049+(((double)j / 99)*(4.9951-0.1049));
			odhady = expectedimprovement(&pozbod[0],&proMaticiR[0],mojeInvMaticeR,size,2);		
			fprintf(vystup, "%20.15lf %s", odhady, "\n");
			fprintf(vystup2, "%20.15lf %s", pozbod[0], "\n");
			fprintf(vystup3, "%20.15lf %s", pozbod[1], "\n");
    }
	}
	fclose(vystup);
	fclose(vystup2);
	fclose(vystup3);
	
	//optimalizace zadane funkce
	interval[0]=0.1049;
	interval[1]=4.9951;
	interval[2]=0.1049;
	interval[3]=4.9951;
	
	QueryPerformanceCounter((LARGE_INTEGER*)&start);//zacatek mereni casu
	
	for (j = 0; j < pocetpridanychbodu; j++){
		for (i = 0; i < 5; i++){
			BBoptimalizace2D(&proMaticiR[0],&interval[0],size,2);
		}
		proMaticiR[size*3]=interval[0]+((double)rand() / (double)RAND_MAX)*(interval[1]-interval[0]);
		proMaticiR[size*3+1]=interval[2]+((double)rand() / (double)RAND_MAX)*(interval[3]-interval[2]);
		proMaticiR[size*3+2]=interpoluj(proMaticiR[size*3],proMaticiR[(size*3)+1],polea,poleb,polec,k);
		proMaticiR[size*3+3]=proMaticiR[size*3+1];
		proMaticiR[size*3+4]=proMaticiR[size*3];
		proMaticiR[size*3+5]=proMaticiR[size*3+2];
		size=size+2;
		interval[0]=0.1049;
		interval[1]=4.9951;
		interval[2]=0.1049;
		interval[3]=4.9951;
	}
	
	QueryPerformanceCounter((LARGE_INTEGER*)&stop);	//konec mereni casu
	cas = ((double)(stop-start))/(double)frekvence;	//vypocet casu v sekundach
	printf("Namereny cas: %f s\n",cas);
	
	vystup = fopen(NAZEVVYSTUPU23, "w");			//x1 po pridani bodu
	
	for(i=0; i<size; i++){				
		fprintf(vystup, "%20.15lf %s", proMaticiR[i*3], "\n");
	}
	fclose(vystup);
	
	vystup = fopen(NAZEVVYSTUPU24, "w");			//x2 po pridani bodu
	
	for(i=0; i<size; i++){				
		fprintf(vystup, "%20.15lf %s", proMaticiR[i*3+1], "\n");
	}
	fclose(vystup);
	vystup = fopen(NAZEVVYSTUPU25, "w");			//y po pridani bodu
	
	for(i=0; i<size; i++){				
		fprintf(vystup, "%20.15lf %s", proMaticiR[i*3+2], "\n");
	}
	fclose(vystup);
	
	maticeR(&proMaticiR[0],mojeMaticeR,size,2);
	detmatR = LUdeterminant(mojeMaticeR,size);
	printf("DeterminantLU = %20.15lf\n",detmatR);
	cofactors(mojeMaticeR,mojeInvMaticeR,size);
	
	vystup = fopen(NAZEVVYSTUPU18, "w");
	for (i = 0; i < 100; i++) {	
		for (j = 0; j < 100; j++) {
			pozbod[0] = 0.1049+(((double)i / 99)*(4.9951-0.1049));
			pozbod[1] = 0.1049+(((double)j / 99)*(4.9951-0.1049));
			odhady = predictor(&pozbod[0],&proMaticiR[0],mojeInvMaticeR,size,2);		
			fprintf(vystup, "%20.15lf %s", odhady, "\n");
			if(i==0 && j==0){
				nalezeneminimum[0]=pozbod[0];
				nalezeneminimum[1]=pozbod[1];
				nalezeneminimum[2]=odhady;
			}
			if(nalezeneminimum[2]>odhady){
				nalezeneminimum[0]=pozbod[0];
				nalezeneminimum[1]=pozbod[1];
				nalezeneminimum[2]=odhady;
			}
    }
	}
	printf("Nalezene minimum (x1, x2, y)(%20.15lf, %20.15lf, %20.15lf)\n",nalezeneminimum[0],nalezeneminimum[1],nalezeneminimum[2]);
	fclose(vystup);
	
	vystup = fopen(NAZEVVYSTUPU19, "w");
	for (i = 0; i < 100; i++) {	
		for (j = 0; j < 100; j++) {
			pozbod[0] = 0.1049+(((double)i / 99)*(4.9951-0.1049));
			pozbod[1] = 0.1049+(((double)j / 99)*(4.9951-0.1049));
			odhady = meansquarederror(&pozbod[0],&proMaticiR[0],mojeInvMaticeR,size,2);		
			fprintf(vystup, "%20.15lf %s", odhady, "\n");
    }
	}
	fclose(vystup);
	
	vystup = fopen(NAZEVVYSTUPU20, "w");
	for (i = 0; i < 100; i++) {	
		for (j = 0; j < 100; j++) {
			pozbod[0] = 0.1049+(((double)i / 99)*(4.9951-0.1049));
			pozbod[1] = 0.1049+(((double)j / 99)*(4.9951-0.1049));
			odhady = expectedimprovement(&pozbod[0],&proMaticiR[0],mojeInvMaticeR,size,2);		
			fprintf(vystup, "%20.15lf %s", odhady, "\n");
    }
	}
	fclose(vystup);
	printf("Skutcne min = %20.15lf\n",interpoluj(2.1301,1.0928,polea,poleb,polec,k));
	
	//vzdalenost(&bod1[0], &bod2[0], 1, 2, 3);
	//interpoluj(3 , 2.75 ,polea ,poleb ,polec ,size);
	//printf("%lf\n", *polec);
	
	//qsort(polec, size, sizeof(double), compare_ints);
	
	//printf("Skutecne minimum min=[x, x, %lf]\n", *(polec+size-1));
	/*for(i=0; i<=2; i++){
	truemin[2]=nahodnehledani(polea ,poleb ,polec , &truemin[0], size);
	
	printf("Minimum nalezene nahodnym prohledavanim min=[%lf, %lf, %lf]\n", truemin[0], truemin[1], truemin[2]);
	
	truemin[2]=evolucnistrategie(polea ,poleb ,polec , &truemin[0], size);
	
	printf("Minimum nalezene evolucni strategii min=[%lf, %lf, %lf]\n", truemin[0], truemin[1], truemin[2]);
	}
	for (i = 0; i < 20; i++) {
        free(mojeMaticeR[i]);
    }
    free(mojeMaticeR);*/
	//free(polea);
	//free(poleb);
	//free(polec);
	
	getch();
	return 0;
}
