Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 13:32:42

0001 // -*- C++ -*-
0002 //
0003 // Package:     MVAComputer
0004 // Class  :     ProcSort
0005 //
0006 
0007 // Implementation:
0008 //     Sorts the input variables. Each input variable must appear in the
0009 //     multiplicity as the others. One variable is the sorting "leader" by
0010 //     which all variables are reordered the same way. The ordering is
0011 //     determined by either ascending or descending order of the leader.
0012 //
0013 // Author:      Christophe Saout
0014 // Created:     Sun Sep 16 14:52 CEST 2007
0015 //
0016 
0017 #include <cstdlib>
0018 #include <algorithm>
0019 #include <iterator>
0020 #include <vector>
0021 
0022 #include <boost/iterator/transform_iterator.hpp>
0023 
0024 #include "PhysicsTools/MVAComputer/interface/VarProcessor.h"
0025 #include "PhysicsTools/MVAComputer/interface/Calibration.h"
0026 
0027 using namespace PhysicsTools;
0028 
0029 namespace {  // anonymous
0030 
0031   class ProcSort : public VarProcessor {
0032   public:
0033     typedef VarProcessor::Registry::Registry<ProcSort, Calibration::ProcSort> Registry;
0034 
0035     ProcSort(const char *name, const Calibration::ProcSort *calib, const MVAComputer *computer);
0036     ~ProcSort() override {}
0037 
0038     void configure(ConfIterator iter, unsigned int n) override;
0039     void eval(ValueIterator iter, unsigned int n) const override;
0040     std::vector<double> deriv(ValueIterator iter, unsigned int n) const override;
0041 
0042   private:
0043     unsigned int leader;
0044     bool descending;
0045   };
0046 
0047   ProcSort::Registry registry("ProcSort");
0048 
0049   ProcSort::ProcSort(const char *name, const Calibration::ProcSort *calib, const MVAComputer *computer)
0050       : VarProcessor(name, calib, computer), leader(calib->sortByIndex), descending(calib->descending) {}
0051 
0052   void ProcSort::configure(ConfIterator iter, unsigned int n) {
0053     if (leader >= n)
0054       return;
0055 
0056     iter << iter;
0057     while (iter)
0058       iter << iter++(Variable::FLAG_ALL);
0059   }
0060 
0061   namespace {  // anonymous
0062     struct LeaderLookup {
0063       inline LeaderLookup() {}
0064       inline LeaderLookup(const double *values) : values(values) {}
0065 
0066       inline double operator()(int index) const { return values[index]; }
0067 
0068       const double *values;
0069     };
0070   }  // anonymous namespace
0071 
0072   void ProcSort::eval(ValueIterator iter, unsigned int n) const {
0073     ValueIterator leaderIter = iter;
0074     for (unsigned int i = 0; i < leader; i++, leaderIter++)
0075       ;
0076     unsigned int size = leaderIter.size();
0077     LeaderLookup lookup(leaderIter.begin());
0078 
0079     int *sort = (int *)alloca(size * sizeof(int));
0080     for (unsigned int i = 0; i < size; i++)
0081       sort[i] = (int)i;
0082 
0083     boost::transform_iterator<LeaderLookup, int *> begin(sort, lookup);
0084     boost::transform_iterator<LeaderLookup, int *> end = begin;
0085 
0086     for (unsigned int i = 0; i < size; i++, end++) {
0087       unsigned int pos = std::lower_bound(begin, end, leaderIter[i]) - begin;
0088       std::memmove(sort + (pos + 1), sort + pos, (i - pos) * sizeof(*sort));
0089       sort[pos] = i;
0090     }
0091 
0092     if (descending)
0093       std::reverse(sort, sort + size);
0094 
0095     for (unsigned int i = 0; i < size; i++)
0096       iter << (double)sort[i];
0097     iter();
0098 
0099     while (iter) {
0100       for (unsigned int i = 0; i < size; i++)
0101         iter << iter[sort[i]];
0102       iter();
0103       iter++;
0104     }
0105   }
0106 
0107   std::vector<double> ProcSort::deriv(ValueIterator iter, unsigned int n) const {
0108     unsigned int in = 0;
0109     for (ValueIterator iter2 = iter; iter2; ++iter2)
0110       in += iter2.size();
0111 
0112     ValueIterator leaderIter = iter;
0113     for (unsigned int i = 0; i < leader; i++, leaderIter++)
0114       ;
0115     unsigned int size = leaderIter.size();
0116     LeaderLookup lookup(leaderIter.begin());
0117 
0118     std::vector<int> sort;
0119     for (unsigned int i = 0; i < size; i++)
0120       sort.push_back((int)i);
0121 
0122     boost::transform_iterator<LeaderLookup, std::vector<int>::const_iterator> begin(sort.begin(), lookup);
0123     boost::transform_iterator<LeaderLookup, std::vector<int>::const_iterator> end = begin;
0124 
0125     for (unsigned int i = 0; i < size; i++, end++) {
0126       unsigned int pos = std::lower_bound(begin, end, leaderIter[i]) - begin;
0127       std::memmove(&sort.front() + (pos + 1), &sort.front() + pos, (i - pos) * sizeof(sort.front()));
0128       sort[pos] = i;
0129     }
0130 
0131     if (descending)
0132       std::reverse(sort.begin(), sort.end());
0133 
0134     std::vector<double> result(size * in, 0.0);
0135 
0136     for (unsigned int pos = 0; iter; pos += (iter++).size()) {
0137       for (unsigned int i = 0; i < size; i++) {
0138         unsigned int row = result.size();
0139         result.resize(row + in);
0140         result[row + pos + sort[i]] = 1.0;
0141       }
0142     }
0143 
0144     return result;
0145   }
0146 
0147 }  // anonymous namespace