CMS 3D CMS Logo

ProcSort.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: MVAComputer
4 // Class : ProcSort
5 //
6 
7 // Implementation:
8 // Sorts the input variables. Each input variable must appear in the
9 // multiplicity as the others. One variable is the sorting "leader" by
10 // which all variables are reordered the same way. The ordering is
11 // determined by either ascending or descending order of the leader.
12 //
13 // Author: Christophe Saout
14 // Created: Sun Sep 16 14:52 CEST 2007
15 //
16 
17 #include <cstdlib>
18 #include <algorithm>
19 #include <iterator>
20 #include <vector>
21 
22 #include <boost/iterator/transform_iterator.hpp>
23 
26 
27 using namespace PhysicsTools;
28 
29 namespace { // anonymous
30 
31 class ProcSort : public VarProcessor {
32  public:
33  typedef VarProcessor::Registry::Registry<ProcSort,
34  Calibration::ProcSort> Registry;
35 
36  ProcSort(const char *name,
38  const MVAComputer *computer);
39  ~ProcSort() override {}
40 
41  void configure(ConfIterator iter, unsigned int n) override;
42  void eval(ValueIterator iter, unsigned int n) const override;
43  std::vector<double> deriv(
44  ValueIterator iter, unsigned int n) const override;
45 
46  private:
47  unsigned int leader;
48  bool descending;
49 };
50 
51 ProcSort::Registry registry("ProcSort");
52 
53 ProcSort::ProcSort(const char *name,
55  const MVAComputer *computer) :
56  VarProcessor(name, calib, computer),
57  leader(calib->sortByIndex),
58  descending(calib->descending)
59 {
60 }
61 
62 void ProcSort::configure(ConfIterator iter, unsigned int n)
63 {
64  if (leader >= n)
65  return;
66 
67  iter << iter;
68  while(iter)
69  iter << iter++(Variable::FLAG_ALL);
70 }
71 
72 namespace { // anonymous
73  struct LeaderLookup {
74  inline LeaderLookup() {}
75  inline LeaderLookup(const double *values) : values(values) {}
76 
77  inline double operator () (int index) const
78  { return values[index]; }
79 
80  const double *values;
81  };
82 } // anonymous namespace
83 
84 void ProcSort::eval(ValueIterator iter, unsigned int n) const
85 {
86  ValueIterator leaderIter = iter;
87  for(unsigned int i = 0; i < leader; i++, leaderIter++);
88  unsigned int size = leaderIter.size();
89  LeaderLookup lookup(leaderIter.begin());
90 
91  int *sort = (int*)alloca(size * sizeof(int));
92  for(unsigned int i = 0; i < size; i++)
93  sort[i] = (int)i;
94 
95  boost::transform_iterator<LeaderLookup, int*> begin(sort, lookup);
96  boost::transform_iterator<LeaderLookup, int*> end = begin;
97 
98  for(unsigned int i = 0; i < size; i++, end++) {
99  unsigned int pos = std::lower_bound(begin, end,
100  leaderIter[i]) - begin;
101  std::memmove(sort + (pos + 1), sort + pos,
102  (i - pos) * sizeof(*sort));
103  sort[pos] = i;
104  }
105 
106  if (descending)
107  std::reverse(sort, sort + size);
108 
109  for(unsigned int i = 0; i < size; i++)
110  iter << (double)sort[i];
111  iter();
112 
113  while(iter) {
114  for(unsigned int i = 0; i < size; i++)
115  iter << iter[sort[i]];
116  iter();
117  iter++;
118  }
119 }
120 
121 std::vector<double> ProcSort::deriv(ValueIterator iter, unsigned int n) const
122 {
123  unsigned int in = 0;
124  for(ValueIterator iter2 = iter; iter2; ++iter2)
125  in += iter2.size();
126 
127  ValueIterator leaderIter = iter;
128  for(unsigned int i = 0; i < leader; i++, leaderIter++);
129  unsigned int size = leaderIter.size();
130  LeaderLookup lookup(leaderIter.begin());
131 
132  std::vector<int> sort;
133  for(unsigned int i = 0; i < size; i++)
134  sort.push_back((int)i);
135 
136  boost::transform_iterator<LeaderLookup,
137  std::vector<int>::const_iterator > begin(
138  sort.begin(), lookup);
139  boost::transform_iterator<LeaderLookup,
140  std::vector<int>::const_iterator > end =
141  begin;
142 
143  for(unsigned int i = 0; i < size; i++, end++) {
144  unsigned int pos = std::lower_bound(begin, end,
145  leaderIter[i]) - begin;
146  std::memmove(&sort.front() + (pos + 1), &sort.front() + pos,
147  (i - pos) * sizeof(sort.front()));
148  sort[pos] = i;
149  }
150 
151  if (descending)
152  std::reverse(sort.begin(), sort.end());
153 
154  std::vector<double> result(size * in, 0.0);
155 
156  for(unsigned int pos = 0; iter; pos += (iter++).size()) {
157  for(unsigned int i = 0; i < size; i++) {
158  unsigned int row = result.size();
159  result.resize(row + in);
160  result[row + pos + sort[i]] = 1.0;
161  }
162  }
163 
164  return result;
165 }
166 
167 } // anonymous namespace
size
Write out results.
template to generate a registry singleton for a type.
Main interface class to the generic discriminator computer framework.
Definition: MVAComputer.h:39
#define end
Definition: vmac.h:39
#define begin
Definition: vmac.h:32
static Interceptor::Registry registry("Interceptor")
Common base class for variable processors.
Definition: VarProcessor.h:36