ROOT logo
// #include "TSystem.h"
// #include "TFile.h"
// #include "TTree.h"
// #include "TProfile.h"
// #include "TF1.h"
// #include "TF2.h"
// #include "TF3.h"
// #include "TLegend.h"
// #include "TRandom.h"
// #include "TString.h"
// #include "TGraph.h"
// #include "TMarker.h"
// #include "TStopwatch.h"
// #include "../src/TKDPDF.h"
// #include "../src/TKDInterpolator.h"

void interpolTest(const Int_t ndim = 1);
Double_t interpolation(const int nstat, const int ndim, const int first);
void build(const int ndim, const int npoints);

TF1 *f = 0x0;

//__________________________________________________________
void interpolTest(const Int_t ndim)
{
// Test interpolator on a variable dimension (ndim<=5) uncorrelated
// Gauss model. The macro displays the chi2 between interpolation and
// model for various statistics of experimental data.
//
// Check the worker function interpolation() to fine tune the
// algorithm.
// 
// Attention:
// The macro works in compiled mode !

	// define model
	switch(ndim){
	case 1:
		f=new TF1("f1", "gaus(0);x;f(x)", -5., 5.);
		f->SetParameter(0, 1.);
		f->SetParameter(1, 0.);
		f->SetParameter(2, 1.);
		f->SetParameter(0, 1./f->Integral(-5., 5.));
		break;
	case 2:
		f=new TF2("f2", "[0]*exp(-0.5*((x-[1])/[2])**2)*exp(-0.5*((y-[3])/[4])**2)", -5., 5., -5., 5.);
		f->SetParameter(0, 1.);
		f->SetParameter(1, 0.);
		f->SetParameter(2, 1.);
		f->SetParameter(3, 0.);
		f->SetParameter(4, 1.);
		f->SetParameter(0, 1./f->Integral(-5., 5., -5., 5.));
		break;
	case 3:
	case 4:
	case 5:
		f=new TF3("f3", "[0]*exp(-0.5*((x-[1])/[2])**2)*exp(-0.5*((y-[3])/[4])**2)*exp(-0.5*((z-[5])/[6])**2)", -5., 5., -5., 5., -5., 5.);
		f->SetParameter(0, 1.);
		f->SetParameter(1, 0.);
		f->SetParameter(2, 1.);
		f->SetParameter(3, 0.);
		f->SetParameter(4, 1.);
		f->SetParameter(5, 0.);
		f->SetParameter(6, 1.);
		f->SetParameter(0, 1./f->Integral(-5., 5., -5., 5., -5., 5.));
		if(ndim>3) printf("Warning : chi2 results are unreliable !\n");
		break;
	default:
		printf("%dD not supported in this macro.\n", ndim);
		return;
	}

	Double_t chi2;
	const Int_t nchi2 = 18;
	const Int_t nfirst = 1;
 	//TProfile *hp = new TProfile("hp", "", 100, 1.E4, 1.E6);
 	//hp->SetMarkerStyle(24);
	TGraph *gChi2 = new TGraph(nchi2);
 	gChi2->SetMarkerStyle(24);
	Int_t ip = 0, nstat, first;
	for(int ifirst=0; ifirst<nfirst; ifirst++){
		first = 0;//Int_t(gRandom->Uniform(1.E4));
		for(int i=2; i<10; i++){
			nstat = 10000*i;
			chi2 = interpolation(nstat, ndim, first);
			gChi2->SetPoint(ip++, TMath::Log10(float(nstat)), chi2);
			//hp->Fill(float(nstat), chi2);
		}
		for(int i=1; i<10; i++){
			nstat = 100000*i;
			chi2 = interpolation(nstat, ndim, first);
			gChi2->SetPoint(ip++, TMath::Log10(float(nstat)), chi2);
			//hp->Fill(float(nstat), chi2);
		}
		gChi2->Draw("apl");
	}
	//hp->Draw("pl");
}

void test()
{
	TClonesArray ar("TKDNodeInfo", 10);
}

//__________________________________________________________
Double_t interpolation(const int nstat, const int ndim, const int first)
{
// Steer interpolation of a nD (n<=5) uncorrelated Gauss distribution.
// The user is suppose to give the experimental statistics (nstat) the
// dimension of the experimental point (ndim). The entry from which the
// data base is being read is steered by "first".

 	const int bs = 400;
 	const int npoints = 100;
	// switch on chi2 calculation between interpolation and model.
	// Default calculates distance.
	const Bool_t kCHI2 = kFALSE; 
	const Bool_t kINT  = kFALSE; // switch on integral interpolator

	// open data base
	TString fn("5D_Gauss.root");
	if(!gSystem->FindFile(".", fn)) build(5, 1000000);
	TFile::Open("5D_Gauss.root");
	TTree *t = (TTree*)gFile->Get("db");

	// build interpolator
	TString var = "x0"; for(int idim=1; idim<ndim; idim++) var += Form(":x%d", idim);
	TKDPDF pdf(t, var.Data(), "", bs, nstat, first);
	printf("\n\nFINISH BUILDING PDF\n\n");
	
	Double_t fx;
	Int_t inode = 0;
	TKDNodeInfo *node = 0x0;
	TKDInterpolator in(ndim, pdf.GetNTNodes());
/*	while(node = pdf.GetNodeInfo(inode)){
		if(node->fVal[0] > 0.){
			fx = node->fVal[0];
			node->fVal[0] = TMath::Log(fx);
			node->fVal[1] = node->fVal[1]/fx;
		}
		in.SetNode(inode, *node);
		inode++;
	}*/
	//pdf.SetInterpolationMethod(kINT);
	pdf.SetAlpha(2.);
	//in.SetStore();


	Double_t x[2], r, e, chi2;
	TH2 *h2 = new TH2F("h2", "", 50, -4., 4., 50, -4., 4.);
	TAxis *ax = h2->GetXaxis(), *ay = h2->GetYaxis();
	for(int ix=1; ix<=ax->GetNbins(); ix++){
		x[0] = ax->GetBinCenter(ix);
		for(int iy=1; iy<=ay->GetNbins(); iy++){
			x[1] = ay->GetBinCenter(iy);

			chi2 = pdf.Eval(x, r, e);
			printf("x[%2d] x[%2d] r[%f] e[%f] chi2[%f]\n", ix, iy, r, e, chi2);
			h2->SetBinContent(ix, iy, r/*TMath::Exp(r)*/);
		}
	}
	h2->Draw("lego2");
	return;
	
	// define testing grid
	Double_t x[5], r, e;
	Double_t dx[5] = {4., 4., 4., 4., 4.};
	Double_t chi2, theor, result, err;
	for(int idim=0; idim<ndim; idim++){
		dx[idim] = (ndim<<2)/float(npoints);
		x[idim]  = -2.+dx[idim]/2.;
	}

	
	// setup the integral interpolator and do memory test
	Float_t c[5], v, ve;
	for(int ip=0; ip<in.GetNTNodes(); ip++){
		in.GetCOGPoint(ip, c, v, ve);
		for(int idim=0; idim<ndim; idim++) x[idim] = (Double_t)c[idim];
		in.Eval(x, result, err);
	}
	printf("\nInterpolating %d data points in %dD ...\n", nstat, ndim);
	printf("\tbucket size %d\n", bs);
	printf("\tstarting interpolation ...\n");
	return;

	
	// evaluate relative error
	for(int idim=0; idim<ndim; idim++) x[idim] = 0.;
	in.Eval(x, result, err);
	Double_t threshold = err/result;
	
	// starting interpolation over the testing grid
	chi2 = 0.; Int_t nsample = 0;
	x[4]  = -2.+dx[4]/2.;
	do{
		x[3]  = -2.+dx[3]/2.;
		do{
			x[2]  = -2.+dx[2]/2.;
			do{
				x[1]  = -2.+dx[1]/2.;
				do{
					x[0]  = -2.+dx[0]/2.;
					do{
						in.Eval(x, result, err);
						if(err/TMath::Abs(result) < 1.1*threshold){
							theor = f->Eval(x[0], x[1], x[2]);
							Double_t tmp = result - theor; tmp *= tmp;
							chi2 += tmp/(kCHI2 ? err*err : theor);
							nsample++;
						}
					} while((x[0] += dx[0]) < 2.);
				} while((x[1] += dx[1]) < 2.);
			} while((x[2] += dx[2]) < 2.);
		} while((x[3] += dx[3]) < 2.);
	} while((x[4] += dx[4]) < 2.);
	chi2 /= float(nsample);
	printf("\tinterpolation quality (chi2) %f\n", chi2);
	
	return kCHI2 ? chi2 : TMath::Sqrt(chi2);
}


//___________________________________________________________
void build(const int ndim, const int npoints)
{
	printf("Building DB ...\n");
	Float_t data[ndim];
	TFile::Open(Form("%dD_Gauss.root", ndim), "RECREATE");
	TTree *t = new TTree("db", Form("%dD data base for kD statistics", ndim));
	for(int idim=0; idim<ndim; idim++) t->Branch(Form("x%d", idim), &data[idim], Form("x%d/F", idim));

	for (Int_t ip=0; ip<npoints; ip++){
		for (Int_t id=0; id<ndim; id++) data[id]= gRandom->Gaus();
		t->Fill();
	}

	t->Write();
	gFile->Close();
	delete gFile;
}
 interpolTest.C:1
 interpolTest.C:2
 interpolTest.C:3
 interpolTest.C:4
 interpolTest.C:5
 interpolTest.C:6
 interpolTest.C:7
 interpolTest.C:8
 interpolTest.C:9
 interpolTest.C:10
 interpolTest.C:11
 interpolTest.C:12
 interpolTest.C:13
 interpolTest.C:14
 interpolTest.C:15
 interpolTest.C:16
 interpolTest.C:17
 interpolTest.C:18
 interpolTest.C:19
 interpolTest.C:20
 interpolTest.C:21
 interpolTest.C:22
 interpolTest.C:23
 interpolTest.C:24
 interpolTest.C:25
 interpolTest.C:26
 interpolTest.C:27
 interpolTest.C:28
 interpolTest.C:29
 interpolTest.C:30
 interpolTest.C:31
 interpolTest.C:32
 interpolTest.C:33
 interpolTest.C:34
 interpolTest.C:35
 interpolTest.C:36
 interpolTest.C:37
 interpolTest.C:38
 interpolTest.C:39
 interpolTest.C:40
 interpolTest.C:41
 interpolTest.C:42
 interpolTest.C:43
 interpolTest.C:44
 interpolTest.C:45
 interpolTest.C:46
 interpolTest.C:47
 interpolTest.C:48
 interpolTest.C:49
 interpolTest.C:50
 interpolTest.C:51
 interpolTest.C:52
 interpolTest.C:53
 interpolTest.C:54
 interpolTest.C:55
 interpolTest.C:56
 interpolTest.C:57
 interpolTest.C:58
 interpolTest.C:59
 interpolTest.C:60
 interpolTest.C:61
 interpolTest.C:62
 interpolTest.C:63
 interpolTest.C:64
 interpolTest.C:65
 interpolTest.C:66
 interpolTest.C:67
 interpolTest.C:68
 interpolTest.C:69
 interpolTest.C:70
 interpolTest.C:71
 interpolTest.C:72
 interpolTest.C:73
 interpolTest.C:74
 interpolTest.C:75
 interpolTest.C:76
 interpolTest.C:77
 interpolTest.C:78
 interpolTest.C:79
 interpolTest.C:80
 interpolTest.C:81
 interpolTest.C:82
 interpolTest.C:83
 interpolTest.C:84
 interpolTest.C:85
 interpolTest.C:86
 interpolTest.C:87
 interpolTest.C:88
 interpolTest.C:89
 interpolTest.C:90
 interpolTest.C:91
 interpolTest.C:92
 interpolTest.C:93
 interpolTest.C:94
 interpolTest.C:95
 interpolTest.C:96
 interpolTest.C:97
 interpolTest.C:98
 interpolTest.C:99
 interpolTest.C:100
 interpolTest.C:101
 interpolTest.C:102
 interpolTest.C:103
 interpolTest.C:104
 interpolTest.C:105
 interpolTest.C:106
 interpolTest.C:107
 interpolTest.C:108
 interpolTest.C:109
 interpolTest.C:110
 interpolTest.C:111
 interpolTest.C:112
 interpolTest.C:113
 interpolTest.C:114
 interpolTest.C:115
 interpolTest.C:116
 interpolTest.C:117
 interpolTest.C:118
 interpolTest.C:119
 interpolTest.C:120
 interpolTest.C:121
 interpolTest.C:122
 interpolTest.C:123
 interpolTest.C:124
 interpolTest.C:125
 interpolTest.C:126
 interpolTest.C:127
 interpolTest.C:128
 interpolTest.C:129
 interpolTest.C:130
 interpolTest.C:131
 interpolTest.C:132
 interpolTest.C:133
 interpolTest.C:134
 interpolTest.C:135
 interpolTest.C:136
 interpolTest.C:137
 interpolTest.C:138
 interpolTest.C:139
 interpolTest.C:140
 interpolTest.C:141
 interpolTest.C:142
 interpolTest.C:143
 interpolTest.C:144
 interpolTest.C:145
 interpolTest.C:146
 interpolTest.C:147
 interpolTest.C:148
 interpolTest.C:149
 interpolTest.C:150
 interpolTest.C:151
 interpolTest.C:152
 interpolTest.C:153
 interpolTest.C:154
 interpolTest.C:155
 interpolTest.C:156
 interpolTest.C:157
 interpolTest.C:158
 interpolTest.C:159
 interpolTest.C:160
 interpolTest.C:161
 interpolTest.C:162
 interpolTest.C:163
 interpolTest.C:164
 interpolTest.C:165
 interpolTest.C:166
 interpolTest.C:167
 interpolTest.C:168
 interpolTest.C:169
 interpolTest.C:170
 interpolTest.C:171
 interpolTest.C:172
 interpolTest.C:173
 interpolTest.C:174
 interpolTest.C:175
 interpolTest.C:176
 interpolTest.C:177
 interpolTest.C:178
 interpolTest.C:179
 interpolTest.C:180
 interpolTest.C:181
 interpolTest.C:182
 interpolTest.C:183
 interpolTest.C:184
 interpolTest.C:185
 interpolTest.C:186
 interpolTest.C:187
 interpolTest.C:188
 interpolTest.C:189
 interpolTest.C:190
 interpolTest.C:191
 interpolTest.C:192
 interpolTest.C:193
 interpolTest.C:194
 interpolTest.C:195
 interpolTest.C:196
 interpolTest.C:197
 interpolTest.C:198
 interpolTest.C:199
 interpolTest.C:200
 interpolTest.C:201
 interpolTest.C:202
 interpolTest.C:203
 interpolTest.C:204
 interpolTest.C:205
 interpolTest.C:206
 interpolTest.C:207
 interpolTest.C:208
 interpolTest.C:209
 interpolTest.C:210
 interpolTest.C:211
 interpolTest.C:212
 interpolTest.C:213
 interpolTest.C:214
 interpolTest.C:215
 interpolTest.C:216
 interpolTest.C:217
 interpolTest.C:218
 interpolTest.C:219
 interpolTest.C:220
 interpolTest.C:221
 interpolTest.C:222
 interpolTest.C:223
 interpolTest.C:224
 interpolTest.C:225
 interpolTest.C:226
 interpolTest.C:227
 interpolTest.C:228
 interpolTest.C:229
 interpolTest.C:230
 interpolTest.C:231
 interpolTest.C:232
 interpolTest.C:233
 interpolTest.C:234
 interpolTest.C:235
 interpolTest.C:236
 interpolTest.C:237
 interpolTest.C:238
 interpolTest.C:239
 interpolTest.C:240
 interpolTest.C:241
 interpolTest.C:242