#include "sgm_esl.h"
#include "progressBar.h"

void SGM_ESL::CalGKernel(){
	int i, j;
	double x1,x2,y1,y2,z1,z2;
	double R222,R122,R212,R112,R221,R121,R211,R111;
	double G222,G122,G212,G112,G221,G121,G211,G111;

	GM_kernel_.resize(obs_points_num_);
	for (i = 0; i < obs_points_num_; i++){
		GM_kernel_[i].resize(mod_blocks_num_,0.0);
	}

	ProgressBar *bar = new ProgressBar(obs_points_num_,"Calculating GMKernel");
	for (i = 0; i < obs_points_num_; i++){
		bar->Progressed(i);
#pragma omp parallel for private(j,x1,x2,y1,y2,z1,z2,R222,R122,R212,R112,R221,R121,R211,R111,G222,G122,G212,G112,G221,G121,G211,G111) shared(i) schedule(guided)
		for (j = 0; j < mod_blocks_num_; j++){
			x1 = mod_blocks_[j].xmin; x2 = mod_blocks_[j].xmax;
			y1 = mod_blocks_[j].ymin; y2 = mod_blocks_[j].ymax;
			z1 = mod_blocks_[j].zmin; z2 = mod_blocks_[j].zmax;

			R222=sqrt((x2- obs_points_[i].x)*(x2- obs_points_[i].x)+(y2- obs_points_[i].y)*(y2- obs_points_[i].y)+(z2- obs_points_[i].z)*(z2- obs_points_[i].z));
			R122=sqrt((x1- obs_points_[i].x)*(x1- obs_points_[i].x)+(y2- obs_points_[i].y)*(y2- obs_points_[i].y)+(z2- obs_points_[i].z)*(z2- obs_points_[i].z));
			R212=sqrt((x2- obs_points_[i].x)*(x2- obs_points_[i].x)+(y1- obs_points_[i].y)*(y1- obs_points_[i].y)+(z2- obs_points_[i].z)*(z2- obs_points_[i].z));
			R112=sqrt((x1- obs_points_[i].x)*(x1- obs_points_[i].x)+(y1- obs_points_[i].y)*(y1- obs_points_[i].y)+(z2- obs_points_[i].z)*(z2- obs_points_[i].z));
			R221=sqrt((x2- obs_points_[i].x)*(x2- obs_points_[i].x)+(y2- obs_points_[i].y)*(y2- obs_points_[i].y)+(z1- obs_points_[i].z)*(z1- obs_points_[i].z));
			R121=sqrt((x1- obs_points_[i].x)*(x1- obs_points_[i].x)+(y2- obs_points_[i].y)*(y2- obs_points_[i].y)+(z1- obs_points_[i].z)*(z1- obs_points_[i].z));
			R211=sqrt((x2- obs_points_[i].x)*(x2- obs_points_[i].x)+(y1- obs_points_[i].y)*(y1- obs_points_[i].y)+(z1- obs_points_[i].z)*(z1- obs_points_[i].z));
			R111=sqrt((x1- obs_points_[i].x)*(x1- obs_points_[i].x)+(y1- obs_points_[i].y)*(y1- obs_points_[i].y)+(z1- obs_points_[i].z)*(z1- obs_points_[i].z));

			G222=(x2- obs_points_[i].x)*log((y2- obs_points_[i].y)+R222)+(y2- obs_points_[i].y)*log((x2- obs_points_[i].x)+R222)+(z2- obs_points_[i].z)*arctg((z2- obs_points_[i].z)*R222/(x2- obs_points_[i].x)/(y2- obs_points_[i].y));
			G122=(x1- obs_points_[i].x)*log((y2- obs_points_[i].y)+R122)+(y2- obs_points_[i].y)*log((x1- obs_points_[i].x)+R122)+(z2- obs_points_[i].z)*arctg((z2- obs_points_[i].z)*R122/(x1- obs_points_[i].x)/(y2- obs_points_[i].y));
			G212=(x2- obs_points_[i].x)*log((y1- obs_points_[i].y)+R212)+(y1- obs_points_[i].y)*log((x2- obs_points_[i].x)+R212)+(z2- obs_points_[i].z)*arctg((z2- obs_points_[i].z)*R212/(x2- obs_points_[i].x)/(y1- obs_points_[i].y));
			G112=(x1- obs_points_[i].x)*log((y1- obs_points_[i].y)+R112)+(y1- obs_points_[i].y)*log((x1- obs_points_[i].x)+R112)+(z2- obs_points_[i].z)*arctg((z2- obs_points_[i].z)*R112/(x1- obs_points_[i].x)/(y1- obs_points_[i].y));
			G221=(x2- obs_points_[i].x)*log((y2- obs_points_[i].y)+R221)+(y2- obs_points_[i].y)*log((x2- obs_points_[i].x)+R221)+(z1- obs_points_[i].z)*arctg((z1- obs_points_[i].z)*R221/(x2- obs_points_[i].x)/(y2- obs_points_[i].y));
			G121=(x1- obs_points_[i].x)*log((y2- obs_points_[i].y)+R121)+(y2- obs_points_[i].y)*log((x1- obs_points_[i].x)+R121)+(z1- obs_points_[i].z)*arctg((z1- obs_points_[i].z)*R121/(x1- obs_points_[i].x)/(y2- obs_points_[i].y));
			G211=(x2- obs_points_[i].x)*log((y1- obs_points_[i].y)+R211)+(y1- obs_points_[i].y)*log((x2- obs_points_[i].x)+R211)+(z1- obs_points_[i].z)*arctg((z1- obs_points_[i].z)*R211/(x2- obs_points_[i].x)/(y1- obs_points_[i].y));
			G111=(x1- obs_points_[i].x)*log((y1- obs_points_[i].y)+R111)+(y1- obs_points_[i].y)*log((x1- obs_points_[i].x)+R111)+(z1- obs_points_[i].z)*arctg((z1- obs_points_[i].z)*R111/(x1- obs_points_[i].x)/(y1- obs_points_[i].y));

			GM_kernel_[i][j] = -1.0*G0*(G222-G122-G212+G112-G221+G121+G211-G111);
		}
	}
	return;
}