41 UInt_t NChooseK(UInt_t n, UInt_t k);
55 void TKDEFGT::BuildModel(
const std::vector<Double_t> &sources, Double_t sigma,
56 UInt_t dim, UInt_t p, UInt_t k)
58 if (!sources.size()) {
59 Warning(
"TKDEFGT::BuildModel",
"Bad input - zero size vector");
64 Warning(
"TKDEFGT::BuildModel",
"Number of dimensions is zero");
69 Warning(
"TKDEFGT::BuildModel",
"Order of truncation is zero, 8 will be used");
75 const UInt_t nP = UInt_t(sources.size()) / fDim;
76 fK = !k ? UInt_t(TMath::Sqrt(Double_t(nP))) : k;
78 fPD = NChooseK(fP + fDim - 1, fDim);
80 fWeights.assign(nP, 1.);
81 fXC.assign(fDim * fK, 0.);
82 fA_K.assign(fPD * fK, 0.);
86 fXboxsz.assign(fK, 0);
87 fDistC.assign(nP, 0.);
89 fHeads.assign(fDim + 1, 0);
90 fCinds.assign(fPD, 0);
92 fProds.assign(fPD, 0.);
105 void TKDEFGT::BuildModel(
const TGL5DDataSet *sources, Double_t sigma, UInt_t p, UInt_t k)
107 if (!sources->SelectedSize()) {
108 Warning(
"TKDEFGT::BuildModel",
"Bad input - zero size vector");
115 Warning(
"TKDEFGT::BuildModel",
"Order of truncation is zero, 8 will be used");
120 const UInt_t nP = sources->SelectedSize();
121 fK = !k ? UInt_t(TMath::Sqrt(Double_t(nP))) : k;
123 fPD = NChooseK(fP + fDim - 1, fDim);
125 fWeights.assign(nP, 1.);
126 fXC.assign(fDim * fK, 0.);
127 fA_K.assign(fPD * fK, 0.);
128 fIndxc.assign(fK, 0);
130 fXhead.assign(fK, 0);
131 fXboxsz.assign(fK, 0);
132 fDistC.assign(nP, 0.);
133 fC_K.assign(fPD, 0.);
134 fHeads.assign(fDim + 1, 0);
135 fCinds.assign(fPD, 0);
136 fDx.assign(fDim, 0.);
137 fProds.assign(fPD, 0.);
141 Compute_A_k(sources);
150 Double_t DDist(
const Double_t *x ,
const Double_t *y , Int_t d);
151 Double_t DDist(Double_t x1, Double_t y1, Double_t z1, Double_t x2, Double_t y2, Double_t z2);
153 UInt_t Idmax(
const std::vector<Double_t> &x , UInt_t n);
160 void TKDEFGT::Kcenter(
const std::vector<double> &x)
163 const UInt_t nP = UInt_t(x.size()) / fDim;
165 UInt_t *indxc = &fIndxc[0];
169 const Double_t *x_j = &x[0];
170 const Double_t *x_ind = &x[0] + ind * fDim;
172 for (UInt_t j = 0; j < nP; x_j += fDim, ++j) {
173 fDistC[j] = (j == ind) ? 0. : DDist(x_j , x_ind , fDim);
177 for (UInt_t i = 1 ; i < fK; ++i) {
178 ind = Idmax(fDistC, nP);
181 x_ind = &x[0] + ind * fDim;
182 for (UInt_t j = 0; j < nP; x_j += fDim, ++j) {
183 const Double_t temp = (j==ind) ? 0.0 : DDist(x_j, x_ind, fDim);
184 if (temp < fDistC[j]) {
191 for (UInt_t i = 0, nd = 0 ; i < nP; i++, nd += fDim) {
193 Int_t ibase = fIndx[i] * fDim;
194 for (UInt_t j = 0 ; j < fDim; ++j)
195 fXC[j + ibase] += x[j + nd];
198 for (UInt_t i = 0, ibase = 0; i < fK ; ++i, ibase += fDim) {
199 const Double_t temp = 1. / fXboxsz[i];
200 for (UInt_t j = 0; j < fDim; ++j)
201 fXC[j + ibase] *= temp;
209 void TKDEFGT::Kcenter(
const TGL5DDataSet *sources)
211 const UInt_t nP = sources->SelectedSize();
213 UInt_t *indxc = &fIndxc[0];
218 const Double_t x_ind = sources->V1(1);
219 const Double_t y_ind = sources->V2(1);
220 const Double_t z_ind = sources->V3(1);
222 for (UInt_t j = 0; j < nP; ++j) {
223 const Double_t x_j = sources->V1(j);
224 const Double_t y_j = sources->V2(j);
225 const Double_t z_j = sources->V3(j);
226 fDistC[j] = (j == 1) ? 0. : DDist(x_j, y_j, z_j, x_ind, y_ind, z_ind);
232 for (UInt_t i = 1 ; i < fK; ++i) {
233 const UInt_t ind = Idmax(fDistC, nP);
234 const Double_t x_ind = sources->V1(ind);
235 const Double_t y_ind = sources->V2(ind);
236 const Double_t z_ind = sources->V3(ind);
239 for (UInt_t j = 0; j < nP; ++j) {
240 const Double_t x_j = sources->V1(j);
241 const Double_t y_j = sources->V2(j);
242 const Double_t z_j = sources->V3(j);
244 const Double_t temp = (j==ind) ? 0.0 : DDist(x_j, y_j, z_j, x_ind, y_ind, z_ind);
245 if (temp < fDistC[j]) {
252 for (UInt_t i = 0, nd = 0 ; i < nP; i++, nd += fDim) {
254 UInt_t ibase = fIndx[i] * fDim;
255 fXC[ibase] += sources->V1(i);
256 fXC[ibase + 1] += sources->V2(i);
257 fXC[ibase + 2] += sources->V3(i);
260 for (UInt_t i = 0, ibase = 0; i < fK ; ++i, ibase += fDim) {
261 const Double_t temp = 1. / fXboxsz[i];
262 for (UInt_t j = 0; j < fDim; ++j)
263 fXC[j + ibase] *= temp;
270 void TKDEFGT::Compute_C_k()
272 fHeads[fDim] = UINT_MAX;
276 for (UInt_t k = 1, t = 1, tail = 1; k < fP; ++k, tail = t) {
277 for (UInt_t i = 0; i < fDim; ++i) {
278 const UInt_t head = fHeads[i];
280 for (UInt_t j = head; j < tail; ++j, ++t) {
281 fCinds[t] = (j < fHeads[i + 1]) ? fCinds[j] + 1 : 1;
282 fC_K[t] = 2.0 * fC_K[j];
283 fC_K[t] /= fCinds[t];
292 void TKDEFGT::Compute_A_k(
const std::vector<Double_t> &x)
294 const Double_t ctesigma = 1. / fSigma;
295 const UInt_t nP = UInt_t(x.size()) / fDim;
297 for (UInt_t n = 0; n < nP; n++) {
298 UInt_t nbase = n * fDim;
299 UInt_t ix2c = fIndx[n];
300 UInt_t ix2cbase = ix2c * fDim;
301 UInt_t ind = ix2c * fPD;
302 Double_t temp = fWeights[n];
305 for (UInt_t i = 0; i < fDim; ++i) {
306 fDx[i] = (x[i + nbase] - fXC[i + ix2cbase]) * ctesigma;
307 sum += fDx[i] * fDx[i];
311 fProds[0] = TMath::Exp(-sum);
313 for (UInt_t k = 1, t = 1, tail = 1; k < fP; ++k, tail = t) {
314 for (UInt_t i = 0; i < fDim; ++i) {
315 const UInt_t head = fHeads[i];
317 const Double_t temp1 = fDx[i];
318 for (UInt_t j = head; j < tail; ++j, ++t)
319 fProds[t] = temp1 * fProds[j];
323 for (UInt_t i = 0 ; i < fPD ; i++)
324 fA_K[i + ind] += temp * fProds[i];
327 for (UInt_t k = 0; k < fK; ++k) {
328 const UInt_t ind = k * fPD;
329 for (UInt_t i = 0; i < fPD; ++i)
330 fA_K[i + ind] *= fC_K[i];
337 void TKDEFGT::Compute_A_k(
const TGL5DDataSet *sources)
339 const Double_t ctesigma = 1. / fSigma;
340 const UInt_t nP = sources->SelectedSize();
342 for (UInt_t n = 0; n < nP; n++) {
343 UInt_t ix2c = fIndx[n];
344 UInt_t ix2cbase = ix2c * 3;
345 UInt_t ind = ix2c * fPD;
346 Double_t temp = fWeights[n];
349 fDx[0] = (sources->V1(n) - fXC[ix2cbase]) * ctesigma;
350 fDx[1] = (sources->V2(n) - fXC[ix2cbase + 1]) * ctesigma;
351 fDx[2] = (sources->V3(n) - fXC[ix2cbase + 2]) * ctesigma;
353 sum += (fDx[0] * fDx[0] + fDx[1] * fDx[1] + fDx[2] * fDx[2]);
354 fHeads[0] = fHeads[1] = fHeads[2] = 0;
356 fProds[0] = TMath::Exp(-sum);
358 for (UInt_t k = 1, t = 1, tail = 1; k < fP; ++k, tail = t) {
359 for (UInt_t i = 0; i < 3; ++i) {
360 const UInt_t head = fHeads[i];
362 const Double_t temp1 = fDx[i];
363 for (UInt_t j = head; j < tail; ++j, ++t)
364 fProds[t] = temp1 * fProds[j];
368 for (UInt_t i = 0 ; i < fPD ; i++)
369 fA_K[i + ind] += temp * fProds[i];
372 for (UInt_t k = 0; k < fK; ++k) {
373 const Int_t ind = k * fPD;
374 for (UInt_t i = 0; i < fPD; ++i)
375 fA_K[i + ind] *= fC_K[i];
381 UInt_t InvNChooseK(UInt_t d, UInt_t cnk);
388 void TKDEFGT::Predict(
const std::vector<Double_t> &ts, std::vector<Double_t> &v, Double_t eval)
const
391 Error(
"TKDEFGT::Predict",
"Call BuildModel first!");
396 Warning(
"TKDEFGT::Predict",
"Empty targets vector.");
400 v.assign(ts.size() / fDim, 0.);
402 fHeads.assign(fDim + 1, 0);
403 fDx.assign(fDim, 0.);
404 fProds.assign(fPD, 0.);
406 const Double_t ctesigma = 1. / fSigma;
407 const UInt_t p = InvNChooseK(fDim , fPD);
408 const UInt_t nP = UInt_t(ts.size()) / fDim;
410 for (UInt_t m = 0; m < nP; ++m) {
412 const UInt_t mbase = m * fDim;
414 for (UInt_t kn = 0 ; kn < fK ; ++kn) {
415 const UInt_t xbase = kn * fDim;
416 const UInt_t ind = kn * fPD;
418 for (UInt_t i = 0; i < fDim ; ++i) {
419 fDx[i] = (ts[i + mbase] - fXC[i + xbase]) * ctesigma;
420 sum2 += fDx[i] * fDx[i];
424 if (sum2 > eval)
continue;
426 fProds[0] = TMath::Exp(-sum2);
428 for (UInt_t k = 1, t = 1, tail = 1; k < p; ++k, tail = t) {
429 for (UInt_t i = 0; i < fDim; ++i) {
430 UInt_t head = fHeads[i];
432 const Double_t temp1 = fDx[i];
433 for (UInt_t j = head; j < tail; ++j, ++t)
434 fProds[t] = temp1 * fProds[j];
438 for (UInt_t i = 0 ; i < fPD ; ++i)
439 temp += fA_K[i + ind] * fProds[i];
445 Double_t dMin = v[0], dMax = dMin;
446 for (UInt_t i = 1; i < nP; ++i) {
447 dMin = TMath::Min(dMin, v[i]);
448 dMax = TMath::Max(dMax, v[i]);
451 const Double_t dRange = dMax - dMin;
452 for (UInt_t i = 0; i < nP; ++i)
453 v[i] = (v[i] - dMin) / dRange;
455 dMin = v[0], dMax = dMin;
456 for (UInt_t i = 1; i < nP; ++i) {
457 dMin = TMath::Min(dMin, v[i]);
458 dMax = TMath::Max(dMax, v[i]);
467 UInt_t NChooseK(UInt_t n, UInt_t k)
475 for (UInt_t i = 1; i <= n_k; ++i) {
485 Double_t DDist(Double_t x1, Double_t y1, Double_t z1, Double_t x2, Double_t y2, Double_t z2)
487 return (x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2) + (z1 - z2) * (z1 - z2);
492 Double_t DDist(
const Double_t *x ,
const Double_t *y , Int_t d)
494 Double_t t = 0., s = 0.;
496 for (Int_t i = 0 ; i < d ; i++) {
506 UInt_t Idmax(
const std::vector<Double_t> &x , UInt_t n)
510 for (UInt_t i = 0; i < n; ++i) {
522 UInt_t InvNChooseK(UInt_t d, UInt_t cnk)
525 for (UInt_t i = 2 ; i <= d ; ++i)
528 const UInt_t cte = cnk * cted;
529 UInt_t p = 2, ctep = 2;
531 for (UInt_t i = p + 1; i < p + d; ++i)
534 while (ctep != cte) {
535 ctep = ((p + d) * ctep) / p;