Logo ROOT   6.08/07
Reference Guide
ModulekNN.cxx
Go to the documentation of this file.
1 // @(#)root/tmva $Id$
2 // Author: Rustem Ospanov
3 
4 /**********************************************************************************
5  * Project: TMVA - a Root-integrated toolkit for multivariate data analysis *
6  * Package: TMVA *
7  * Class : ModulekNN *
8  * Web : http://tmva.sourceforge.net *
9  * *
10  * Description: *
11  * Implementation *
12  * *
13  * Author: *
14  * Rustem Ospanov <rustem@fnal.gov> - U. of Texas at Austin, USA *
15  * *
16  * Copyright (c) 2007: *
17  * CERN, Switzerland *
18  * MPI-K Heidelberg, Germany *
19  * U. of Texas at Austin, USA *
20  * *
21  * Redistribution and use in source and binary forms, with or without *
22  * modification, are permitted according to the terms listed in LICENSE *
23  * (http://tmva.sourceforge.net/LICENSE) *
24  **********************************************************************************/
25 
26 #include "TMVA/ModulekNN.h"
27 
28 #include "TMVA/MsgLogger.h"
29 #include "TMVA/Types.h"
30 
31 #include "ThreadLocalStorage.h"
32 #include "TMath.h"
33 #include "TRandom3.h"
34 
35 #include <assert.h>
36 #include <iomanip>
37 #include <iostream>
38 #include <sstream>
39 #include <algorithm>
40 
41 ////////////////////////////////////////////////////////////////////////////////
42 /// default constructor
43 
45  :fVar(),
46  fWeight(-1.0),
47  fType(-1)
48 {
49 }
50 
51 ////////////////////////////////////////////////////////////////////////////////
52 /// constructor
53 
54 TMVA::kNN::Event::Event(const VarVec &var, const Double_t weight, const Short_t type)
55  :fVar(var),
56  fWeight(weight),
57  fType(type)
58 {
59 }
60 
61 ////////////////////////////////////////////////////////////////////////////////
62 /// constructor
63 
64 TMVA::kNN::Event::Event(const VarVec &var, const Double_t weight, const Short_t type, const VarVec &tvec)
65  :fVar(var),
66  fTgt(tvec),
67  fWeight(weight),
68  fType(type)
69 {
70 }
71 
72 ////////////////////////////////////////////////////////////////////////////////
73 /// destructor
74 
76 {
77 }
78 
79 ////////////////////////////////////////////////////////////////////////////////
80 /// compute distance
81 
83 {
84  const UInt_t nvar = GetNVar();
85 
86  if (nvar != other.GetNVar()) {
87  std::cerr << "Distance: two events have different dimensions" << std::endl;
88  return -1.0;
89  }
90 
91  VarType sum = 0.0;
92  for (UInt_t ivar = 0; ivar < nvar; ++ivar) {
93  sum += GetDist(other.GetVar(ivar), ivar);
94  }
95 
96  return sum;
97 }
98 
99 ////////////////////////////////////////////////////////////////////////////////
100 
102 {
103  fTgt = tvec;
104 }
105 
106 ////////////////////////////////////////////////////////////////////////////////
107 
109 {
110  return fTgt;
111 }
112 
113 ////////////////////////////////////////////////////////////////////////////////
114 
116 {
117  return fVar;
118 }
119 
120 ////////////////////////////////////////////////////////////////////////////////
121 /// print
122 
124 {
125  Print(std::cout);
126 }
127 
128 ////////////////////////////////////////////////////////////////////////////////
129 /// print
130 
131 void TMVA::kNN::Event::Print(std::ostream& os) const
132 {
133  Int_t dp = os.precision();
134  os << "Event: ";
135  for (UInt_t ivar = 0; ivar != GetNVar(); ++ivar) {
136  if (ivar == 0) {
137  os << "(";
138  }
139  else {
140  os << ", ";
141  }
142 
143  os << std::setfill(' ') << std::setw(5) << std::setprecision(3) << GetVar(ivar);
144  }
145 
146  if (GetNVar() > 0) {
147  os << ")";
148  }
149  else {
150  os << " no variables";
151  }
152  os << std::setprecision(dp);
153 }
154 
155 ////////////////////////////////////////////////////////////////////////////////
156 /// streamer
157 
158 std::ostream& TMVA::kNN::operator<<(std::ostream& os, const TMVA::kNN::Event& event)
159 {
160  event.Print(os);
161  return os;
162 }
163 
164 ////////////////////////////////////////////////////////////////////////////////
165 /// default constructor
166 
168  :fDimn(0),
169  fTree(0),
170  fLogger( new MsgLogger("ModulekNN") )
171 {
172 }
173 
174 ////////////////////////////////////////////////////////////////////////////////
175 /// destructor
176 
178 {
179  if (fTree) {
180  delete fTree; fTree = 0;
181  }
182  delete fLogger;
183 }
184 
185 ////////////////////////////////////////////////////////////////////////////////
186 /// clean up
187 
189 {
190  fDimn = 0;
191 
192  if (fTree) {
193  delete fTree;
194  fTree = 0;
195  }
196 
197  fVarScale.clear();
198  fCount.clear();
199  fEvent.clear();
200  fVar.clear();
201 }
202 
203 ////////////////////////////////////////////////////////////////////////////////
204 /// add an event to tree
205 
207 {
208  if (fTree) {
209  Log() << kFATAL << "<Add> Cannot add event: tree is already built" << Endl;
210  return;
211  }
212 
213  if (fDimn < 1) {
214  fDimn = event.GetNVar();
215  }
216  else if (fDimn != event.GetNVar()) {
217  Log() << kFATAL << "ModulekNN::Add() - number of dimension does not match previous events" << Endl;
218  return;
219  }
220 
221  fEvent.push_back(event);
222 
223  for (UInt_t ivar = 0; ivar < fDimn; ++ivar) {
224  fVar[ivar].push_back(event.GetVar(ivar));
225  }
226 
227  std::map<Short_t, UInt_t>::iterator cit = fCount.find(event.GetType());
228  if (cit == fCount.end()) {
229  fCount[event.GetType()] = 1;
230  }
231  else {
232  ++(cit->second);
233  }
234 }
235 
236 ////////////////////////////////////////////////////////////////////////////////
237 /// fill the tree
238 
239 Bool_t TMVA::kNN::ModulekNN::Fill(const UShort_t odepth, const UInt_t ifrac, const std::string &option)
240 {
241  if (fTree) {
242  Log() << kFATAL << "ModulekNN::Fill - tree has already been created" << Endl;
243  return kFALSE;
244  }
245 
246  // If trim option is set then find class with lowest number of events
247  // and set that as maximum number of events for all other classes.
248  UInt_t min = 0;
249  if (option.find("trim") != std::string::npos) {
250  for (std::map<Short_t, UInt_t>::const_iterator it = fCount.begin(); it != fCount.end(); ++it) {
251  if (min == 0 || min > it->second) {
252  min = it->second;
253  }
254  }
255 
256  Log() << kINFO << "<Fill> Will trim all event types to " << min << " events" << Endl;
257 
258  fCount.clear();
259  fVar.clear();
260 
261  EventVec evec;
262 
263  for (EventVec::const_iterator event = fEvent.begin(); event != fEvent.end(); ++event) {
264  std::map<Short_t, UInt_t>::iterator cit = fCount.find(event->GetType());
265  if (cit == fCount.end()) {
266  fCount[event->GetType()] = 1;
267  }
268  else if (cit->second < min) {
269  ++(cit->second);
270  }
271  else {
272  continue;
273  }
274 
275  for (UInt_t d = 0; d < fDimn; ++d) {
276  fVar[d].push_back(event->GetVar(d));
277  }
278 
279  evec.push_back(*event);
280  }
281 
282  Log() << kINFO << "<Fill> Erased " << fEvent.size() - evec.size() << " events" << Endl;
283 
284  fEvent = evec;
285  }
286 
287  // clear event count
288  fCount.clear();
289 
290  // sort each variable for all events - needs this before Optimize() and ComputeMetric()
291  for (VarMap::iterator it = fVar.begin(); it != fVar.end(); ++it) {
292  std::sort((it->second).begin(), (it->second).end());
293  }
294 
295  if (option.find("metric") != std::string::npos && ifrac > 0) {
296  ComputeMetric(ifrac);
297 
298  // sort again each variable for all events - needs this before Optimize()
299  // rescaling has changed variable values
300  for (VarMap::iterator it = fVar.begin(); it != fVar.end(); ++it) {
301  std::sort((it->second).begin(), (it->second).end());
302  }
303  }
304 
305  // If odepth > 0 then fill first odepth levels
306  // with empty nodes that split separating variable in half for
307  // all child nodes. If odepth = 0 then split variable 0
308  // at the median (in half) and return it as root node
309  fTree = Optimize(odepth);
310 
311  if (!fTree) {
312  Log() << kFATAL << "ModulekNN::Fill() - failed to create tree" << Endl;
313  return kFALSE;
314  }
315 
316  for (EventVec::const_iterator event = fEvent.begin(); event != fEvent.end(); ++event) {
317  fTree->Add(*event, 0);
318 
319  std::map<Short_t, UInt_t>::iterator cit = fCount.find(event->GetType());
320  if (cit == fCount.end()) {
321  fCount[event->GetType()] = 1;
322  }
323  else {
324  ++(cit->second);
325  }
326  }
327 
328  for (std::map<Short_t, UInt_t>::const_iterator it = fCount.begin(); it != fCount.end(); ++it) {
329  Log() << kINFO << "<Fill> Class " << it->first << " has " << std::setw(8)
330  << it->second << " events" << Endl;
331  }
332 
333  return kTRUE;
334 }
335 
336 ////////////////////////////////////////////////////////////////////////////////
337 /// find in tree
338 /// if tree has been filled then search for nfind closest events
339 /// if metic (fVarScale map) is computed then rescale event variables
340 /// using previsouly computed width of variable distribution
341 
342 Bool_t TMVA::kNN::ModulekNN::Find(Event event, const UInt_t nfind, const std::string &option) const
343 {
344  if (!fTree) {
345  Log() << kFATAL << "ModulekNN::Find() - tree has not been filled" << Endl;
346  return kFALSE;
347  }
348  if (fDimn != event.GetNVar()) {
349  Log() << kFATAL << "ModulekNN::Find() - number of dimension does not match training events" << Endl;
350  return kFALSE;
351  }
352  if (nfind < 1) {
353  Log() << kFATAL << "ModulekNN::Find() - requested 0 nearest neighbors" << Endl;
354  return kFALSE;
355  }
356 
357  // if variable widths are computed then rescale variable in this event
358  // to same widths as events in stored kd-tree
359  if (!fVarScale.empty()) {
360  event = Scale(event);
361  }
362 
363  // latest event for k-nearest neighbor search
364  fkNNEvent = event;
365  fkNNList.clear();
366 
367  if(option.find("weight") != std::string::npos)
368  {
369  // recursive kd-tree search for nfind-nearest neighbors
370  // use event weight to find all nearest events
371  // that have sum of weights >= nfind
372  kNN::Find<kNN::Event>(fkNNList, fTree, event, Double_t(nfind), 0.0);
373  }
374  else
375  {
376  // recursive kd-tree search for nfind-nearest neighbors
377  // count nodes and do not use event weight
378  kNN::Find<kNN::Event>(fkNNList, fTree, event, nfind);
379  }
380 
381  return kTRUE;
382 }
383 
384 ////////////////////////////////////////////////////////////////////////////////
385 /// find in tree
386 
387 Bool_t TMVA::kNN::ModulekNN::Find(const UInt_t nfind, const std::string &option) const
388 {
389  if (fCount.empty() || !fTree) {
390  return kFALSE;
391  }
392  typedef std::map<Short_t, UInt_t>::const_iterator const_iterator;
393  TTHREAD_TLS_DECL_ARG(const_iterator,cit,fCount.end());
394 
395  if (cit == fCount.end()) {
396  cit = fCount.begin();
397  }
398 
399  const Short_t etype = (cit++)->first;
400 
401  if (option == "flat") {
402  VarVec dvec;
403  for (UInt_t d = 0; d < fDimn; ++d) {
404  VarMap::const_iterator vit = fVar.find(d);
405  if (vit == fVar.end()) {
406  return kFALSE;
407  }
408 
409  const std::vector<Double_t> &vvec = vit->second;
410 
411  if (vvec.empty()) {
412  return kFALSE;
413  }
414 
415  // assume that vector elements of fVar are sorted
416  const VarType min = vvec.front();
417  const VarType max = vvec.back();
418  const VarType width = max - min;
419 
420  if (width < 0.0 || width > 0.0) {
421  dvec.push_back(min + width*GetRndmThreadLocal().Rndm());
422  }
423  else {
424  return kFALSE;
425  }
426  }
427 
428  const Event event(dvec, 1.0, etype);
429 
430  Find(event, nfind);
431 
432  return kTRUE;
433  }
434 
435  return kFALSE;
436 }
437 
438 ////////////////////////////////////////////////////////////////////////////////
439 /// Optimize() balances binary tree for first odepth levels
440 /// for each depth we split sorted depth % dimension variables
441 /// into 2^odepth parts
442 
444 {
445  if (fVar.empty() || fDimn != fVar.size()) {
446  Log() << kWARNING << "<Optimize> Cannot build a tree" << Endl;
447  return 0;
448  }
449 
450  const UInt_t size = (fVar.begin()->second).size();
451  if (size < 1) {
452  Log() << kWARNING << "<Optimize> Cannot build a tree without events" << Endl;
453  return 0;
454  }
455 
456  VarMap::const_iterator it = fVar.begin();
457  for (; it != fVar.end(); ++it) {
458  if ((it->second).size() != size) {
459  Log() << kWARNING << "<Optimize> # of variables doesn't match between dimensions" << Endl;
460  return 0;
461  }
462  }
463 
464  if (double(fDimn*size) < TMath::Power(2.0, double(odepth))) {
465  Log() << kWARNING << "<Optimize> Optimization depth exceeds number of events" << Endl;
466  return 0;
467  }
468 
469  Log() << kHEADER << "Optimizing tree for " << fDimn << " variables with " << size << " values" << Endl;
470 
471  std::vector<Node<Event> *> pvec, cvec;
472 
473  it = fVar.find(0);
474  if (it == fVar.end() || (it->second).size() < 2) {
475  Log() << kWARNING << "<Optimize> Missing 0 variable" << Endl;
476  return 0;
477  }
478 
479  const Event pevent(VarVec(fDimn, (it->second)[size/2]), -1.0, -1);
480 
481  Node<Event> *tree = new Node<Event>(0, pevent, 0);
482 
483  pvec.push_back(tree);
484 
485  for (UInt_t depth = 1; depth < odepth; ++depth) {
486  const UInt_t mod = depth % fDimn;
487 
488  VarMap::const_iterator vit = fVar.find(mod);
489  if (vit == fVar.end()) {
490  Log() << kFATAL << "Missing " << mod << " variable" << Endl;
491  return 0;
492  }
493  const std::vector<Double_t> &dvec = vit->second;
494 
495  if (dvec.size() < 2) {
496  Log() << kFATAL << "Missing " << mod << " variable" << Endl;
497  return 0;
498  }
499 
500  UInt_t ichild = 1;
501  for (std::vector<Node<Event> *>::iterator pit = pvec.begin(); pit != pvec.end(); ++pit) {
502  Node<Event> *parent = *pit;
503 
504  const VarType lmedian = dvec[size*ichild/(2*pvec.size() + 1)];
505  ++ichild;
506 
507  const VarType rmedian = dvec[size*ichild/(2*pvec.size() + 1)];
508  ++ichild;
509 
510  const Event levent(VarVec(fDimn, lmedian), -1.0, -1);
511  const Event revent(VarVec(fDimn, rmedian), -1.0, -1);
512 
513  Node<Event> *lchild = new Node<Event>(parent, levent, mod);
514  Node<Event> *rchild = new Node<Event>(parent, revent, mod);
515 
516  parent->SetNodeL(lchild);
517  parent->SetNodeR(rchild);
518 
519  cvec.push_back(lchild);
520  cvec.push_back(rchild);
521  }
522 
523  pvec = cvec;
524  cvec.clear();
525  }
526 
527  return tree;
528 }
529 
530 ////////////////////////////////////////////////////////////////////////////////
531 /// compute scale factor for each variable (dimension) so that
532 /// distance is computed uniformely along each dimension
533 /// compute width of interval that includes (100 - 2*ifrac)% of events
534 /// below, assume that in fVar each vector of values is sorted
535 
537 {
538  if (ifrac == 0) {
539  return;
540  }
541  if (ifrac > 100) {
542  Log() << kFATAL << "ModulekNN::ComputeMetric - fraction can not exceed 100%" << Endl;
543  return;
544  }
545  if (!fVarScale.empty()) {
546  Log() << kFATAL << "ModulekNN::ComputeMetric - metric is already computed" << Endl;
547  return;
548  }
549  if (fEvent.size() < 100) {
550  Log() << kFATAL << "ModulekNN::ComputeMetric - number of events is too small" << Endl;
551  return;
552  }
553 
554  const UInt_t lfrac = (100 - ifrac)/2;
555  const UInt_t rfrac = 100 - (100 - ifrac)/2;
556 
557  Log() << kINFO << "Computing scale factor for 1d distributions: "
558  << "(ifrac, bottom, top) = (" << ifrac << "%, " << lfrac << "%, " << rfrac << "%)" << Endl;
559 
560  fVarScale.clear();
561 
562  for (VarMap::const_iterator vit = fVar.begin(); vit != fVar.end(); ++vit) {
563  const std::vector<Double_t> &dvec = vit->second;
564 
565  std::vector<Double_t>::const_iterator beg_it = dvec.end();
566  std::vector<Double_t>::const_iterator end_it = dvec.end();
567 
568  Int_t dist = 0;
569  for (std::vector<Double_t>::const_iterator dit = dvec.begin(); dit != dvec.end(); ++dit, ++dist) {
570 
571  if ((100*dist)/dvec.size() == lfrac && beg_it == dvec.end()) {
572  beg_it = dit;
573  }
574 
575  if ((100*dist)/dvec.size() == rfrac && end_it == dvec.end()) {
576  end_it = dit;
577  }
578  }
579 
580  if (beg_it == dvec.end() || end_it == dvec.end()) {
581  beg_it = dvec.begin();
582  end_it = dvec.end();
583 
584  assert(beg_it != end_it && "Empty vector");
585 
586  --end_it;
587  }
588 
589  const Double_t lpos = *beg_it;
590  const Double_t rpos = *end_it;
591 
592  if (!(lpos < rpos)) {
593  Log() << kFATAL << "ModulekNN::ComputeMetric() - min value is greater than max value" << Endl;
594  continue;
595  }
596 
597  // Rustem: please find a solution that does not use distance (it does not exist on solaris)
598  // Log() << kINFO << "Variable " << vit->first
599  // << " included " << distance(beg_it, end_it) + 1
600  // << " events: width = " << std::setfill(' ') << std::setw(5) << std::setprecision(3) << rpos - lpos
601  // << ", (min, max) = (" << std::setfill(' ') << std::setw(5) << std::setprecision(3) << lpos
602  // << ", " << std::setfill(' ') << std::setw(5) << std::setprecision(3) << rpos << ")" << Endl;
603 
604  fVarScale[vit->first] = rpos - lpos;
605  }
606 
607  fVar.clear();
608 
609  for (UInt_t ievent = 0; ievent < fEvent.size(); ++ievent) {
610  fEvent[ievent] = Scale(fEvent[ievent]);
611 
612  for (UInt_t ivar = 0; ivar < fDimn; ++ivar) {
613  fVar[ivar].push_back(fEvent[ievent].GetVar(ivar));
614  }
615  }
616 }
617 
618 ////////////////////////////////////////////////////////////////////////////////
619 /// scale each event variable so that rms of variables is approximately 1.0
620 /// this allows comparisons of variables with distinct scales and units
621 
623 {
624  if (fVarScale.empty()) {
625  return event;
626  }
627 
628  if (event.GetNVar() != fVarScale.size()) {
629  Log() << kFATAL << "ModulekNN::Scale() - mismatched metric and event size" << Endl;
630  return event;
631  }
632 
633  VarVec vvec(event.GetNVar(), 0.0);
634 
635  for (UInt_t ivar = 0; ivar < event.GetNVar(); ++ivar) {
636  std::map<int, Double_t>::const_iterator fit = fVarScale.find(ivar);
637  if (fit == fVarScale.end()) {
638  Log() << kFATAL << "ModulekNN::Scale() - failed to find scale for " << ivar << Endl;
639  continue;
640  }
641 
642  if (fit->second > 0.0) {
643  vvec[ivar] = event.GetVar(ivar)/fit->second;
644  }
645  else {
646  Log() << kFATAL << "Variable " << ivar << " has zero width" << Endl;
647  }
648  }
649 
650  return Event(vvec, event.GetWeight(), event.GetType(), event.GetTargets());
651 }
652 
653 ////////////////////////////////////////////////////////////////////////////////
654 /// print
655 
657 {
658  Print(std::cout);
659 }
660 
661 ////////////////////////////////////////////////////////////////////////////////
662 /// print
663 
664 void TMVA::kNN::ModulekNN::Print(std::ostream &os) const
665 {
666  os << "----------------------------------------------------------------------"<< std::endl;
667  os << "Printing knn result" << std::endl;
668  os << fkNNEvent << std::endl;
669 
670  UInt_t count = 0;
671 
672  std::map<Short_t, Double_t> min, max;
673 
674  os << "Printing " << fkNNList.size() << " nearest neighbors" << std::endl;
675  for (List::const_iterator it = fkNNList.begin(); it != fkNNList.end(); ++it) {
676  os << ++count << ": " << it->second << ": " << it->first->GetEvent() << std::endl;
677 
678  const Event &event = it->first->GetEvent();
679  for (UShort_t ivar = 0; ivar < event.GetNVar(); ++ivar) {
680  if (min.find(ivar) == min.end()) {
681  min[ivar] = event.GetVar(ivar);
682  }
683  else if (min[ivar] > event.GetVar(ivar)) {
684  min[ivar] = event.GetVar(ivar);
685  }
686 
687  if (max.find(ivar) == max.end()) {
688  max[ivar] = event.GetVar(ivar);
689  }
690  else if (max[ivar] < event.GetVar(ivar)) {
691  max[ivar] = event.GetVar(ivar);
692  }
693  }
694  }
695 
696  if (min.size() == max.size()) {
697  for (std::map<Short_t, Double_t>::const_iterator mit = min.begin(); mit != min.end(); ++mit) {
698  const Short_t i = mit->first;
699  Log() << kINFO << "(var, min, max) = (" << i << "," << min[i] << ", " << max[i] << ")" << Endl;
700  }
701  }
702 
703  os << "----------------------------------------------------------------------" << std::endl;
704 }
Event()
default constructor
Definition: ModulekNN.cxx:44
~ModulekNN()
destructor
Definition: ModulekNN.cxx:177
double dist(Rotation3D const &r1, Rotation3D const &r2)
Definition: 3DDistances.cxx:48
static long int sum(long int i)
Definition: Factory.cxx:1786
MsgLogger & Endl(MsgLogger &ml)
Definition: MsgLogger.h:162
ModulekNN()
default constructor
Definition: ModulekNN.cxx:167
void Print() const
print
Definition: ModulekNN.cxx:656
unsigned short UShort_t
Definition: RtypesCore.h:36
int Int_t
Definition: RtypesCore.h:41
bool Bool_t
Definition: RtypesCore.h:59
const Bool_t kFALSE
Definition: Rtypes.h:92
Bool_t Find(Event event, UInt_t nfind=100, const std::string &option="count") const
find in tree if tree has been filled then search for nfind closest events if metic (fVarScale map) is...
Definition: ModulekNN.cxx:342
VarType GetVar(UInt_t i) const
Definition: ModulekNN.h:187
std::ostream & operator<<(std::ostream &os, const Event &event)
streamer
Definition: ModulekNN.cxx:158
Double_t GetWeight() const
Definition: ModulekNN.h:183
LongDouble_t Power(LongDouble_t x, LongDouble_t y)
Definition: TMath.h:501
std::map< Int_t, Double_t > fVarScale
Definition: ModulekNN.h:161
MsgLogger & Log() const
Definition: ModulekNN.h:172
Short_t GetType() const
Definition: ModulekNN.h:204
const VarVec & GetTargets() const
Definition: ModulekNN.cxx:108
std::vector< TMVA::kNN::Event > EventVec
Definition: ModulekNN.h:105
Double_t fWeight
Definition: ModulekNN.h:101
const Event Scale(const Event &event) const
scale each event variable so that rms of variables is approximately 1.0 this allows comparisons of va...
Definition: ModulekNN.cxx:622
void SetTargets(const VarVec &tvec)
Definition: ModulekNN.cxx:101
Bool_t Fill(const UShort_t odepth, UInt_t ifrac, const std::string &option="")
fill the tree
Definition: ModulekNN.cxx:239
void SetNodeL(Node *node)
Definition: NodekNN.h:149
VarType GetDist(VarType var, UInt_t ivar) const
Definition: ModulekNN.h:178
Float_t VarType
Definition: ModulekNN.h:64
UInt_t GetNVar() const
Definition: ModulekNN.h:196
unsigned int UInt_t
Definition: RtypesCore.h:42
short Short_t
Definition: RtypesCore.h:35
void Add(const Event &event)
add an event to tree
Definition: ModulekNN.cxx:206
PyObject * fType
double Double_t
Definition: RtypesCore.h:55
int type
Definition: TGX11.cxx:120
static TRandom3 & GetRndmThreadLocal()
Definition: ModulekNN.h:155
MsgLogger * fLogger
Definition: ModulekNN.h:171
const VarVec & GetVars() const
Definition: ModulekNN.cxx:115
void Print() const
print
Definition: ModulekNN.cxx:123
std::map< Short_t, UInt_t > fCount
Definition: ModulekNN.h:166
Node< Event > * Optimize(UInt_t optimize_depth)
Optimize() balances binary tree for first odepth levels for each depth we split sorted depth % dimens...
Definition: ModulekNN.cxx:443
void Clear()
clean up
Definition: ModulekNN.cxx:188
void SetNodeR(Node *node)
Definition: NodekNN.h:155
Definition: tree.py:1
Definition: first.py:1
const Bool_t kTRUE
Definition: Rtypes.h:91
std::vector< VarType > VarVec
Definition: ModulekNN.h:65
Node< Event > * fTree
Definition: ModulekNN.h:159
void ComputeMetric(UInt_t ifrac)
compute scale factor for each variable (dimension) so that distance is computed uniformely along each...
Definition: ModulekNN.cxx:536
~Event()
destructor
Definition: ModulekNN.cxx:75