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