File indexing completed on 2024-04-06 12:23:38
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #include <cstdlib>
0015 #include <algorithm>
0016 #include <iterator>
0017 #include <vector>
0018
0019 #include "FWCore/Utilities/interface/Exception.h"
0020
0021 #include "PhysicsTools/MVAComputer/interface/VarProcessor.h"
0022 #include "PhysicsTools/MVAComputer/interface/Calibration.h"
0023
0024 using namespace PhysicsTools;
0025
0026 namespace {
0027
0028 class ProcMultiply : public VarProcessor {
0029 public:
0030 typedef VarProcessor::Registry::Registry<ProcMultiply, Calibration::ProcMultiply> Registry;
0031
0032 ProcMultiply(const char *name, const Calibration::ProcMultiply *calib, const MVAComputer *computer);
0033 ~ProcMultiply() override {}
0034
0035 void configure(ConfIterator iter, unsigned int n) override;
0036 void eval(ValueIterator iter, unsigned int n) const override;
0037 std::vector<double> deriv(ValueIterator iter, unsigned int n) const override;
0038
0039 private:
0040 typedef std::vector<unsigned int> Config;
0041
0042 unsigned int in;
0043 std::vector<Config> out;
0044 };
0045
0046 ProcMultiply::Registry registry("ProcMultiply");
0047
0048 ProcMultiply::ProcMultiply(const char *name, const Calibration::ProcMultiply *calib, const MVAComputer *computer)
0049 : VarProcessor(name, calib, computer), in(calib->in) {
0050 std::copy(calib->out.begin(), calib->out.end(), std::back_inserter(out));
0051 }
0052
0053 void ProcMultiply::configure(ConfIterator iter, unsigned int n) {
0054 if (in != n)
0055 return;
0056
0057 for (unsigned int i = 0; i < in; i++)
0058 iter++(Variable::FLAG_NONE);
0059
0060 for (unsigned int i = 0; i < out.size(); i++)
0061 iter << Variable::FLAG_NONE;
0062 }
0063
0064 void ProcMultiply::eval(ValueIterator iter, unsigned int n) const {
0065 double *values = (double *)alloca(in * sizeof(double));
0066 for (double *pos = values; iter; iter++, pos++) {
0067 if (iter.size() != 1)
0068 throw cms::Exception("ProcMultiply") << "Special input variable encountered "
0069 "at index "
0070 << (pos - values) << "." << std::endl;
0071 *pos = *iter;
0072 }
0073
0074 for (std::vector<Config>::const_iterator config = out.begin(); config != out.end(); ++config) {
0075 double product = 1.0;
0076 for (std::vector<unsigned int>::const_iterator var = config->begin(); var != config->end(); var++)
0077 product *= values[*var];
0078
0079 iter(product);
0080 }
0081 }
0082
0083 std::vector<double> ProcMultiply::deriv(ValueIterator iter, unsigned int n) const {
0084 std::vector<double> values;
0085 std::vector<unsigned int> offsets;
0086 unsigned int size = 0;
0087 while (iter) {
0088 offsets.push_back(size);
0089 size += iter.size();
0090 values.push_back(*iter++);
0091 }
0092
0093 std::vector<double> result(out.size() * size, 0.0);
0094 unsigned int k = 0;
0095 for (std::vector<Config>::const_iterator config = out.begin(); config != out.end(); ++config, k++) {
0096 for (unsigned int i = 0; i < config->size(); i++) {
0097 double product = 1.0;
0098 for (unsigned int j = 0; j < config->size(); j++)
0099 if (i != j)
0100 product *= values[(*config)[j]];
0101
0102 result[k * size + offsets[i]] = product;
0103 }
0104 }
0105
0106 return result;
0107 }
0108
0109 }