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  :
0005 //
0006 
0007 // Implementation:
0008 //     Multiplies n input variables to produce one output variable.
0009 //
0010 // Author:      Christophe Saout
0011 // Created:     Sat Apr 24 15:18 CEST 2007
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 {  // anonymous
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 }  // anonymous namespace