File indexing completed on 2024-04-06 12:23:38
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
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 {
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 {
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 }
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 }