Back to home page

Project CMSSW displayed by LXR

 
 

    


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

0001 #ifndef PhysicsTools_MVAComputer_MVAComputer_icc
0002 #define PhysicsTools_MVAComputer_MVAComputer_icc
0003 // -*- C++ -*-
0004 //
0005 // Package:     Discriminator
0006 //
0007 
0008 //
0009 // Author:  Christophe Saout <christophe.saout@cern.ch>
0010 // Created:     Sat Apr 24 15:18 CEST 2007
0011 //
0012 
0013 #include <cstdlib>
0014 #include <cstring>
0015 #include <vector>
0016 
0017 #include "PhysicsTools/MVAComputer/interface/MVAComputer.h"
0018 
0019 namespace PhysicsTools {
0020 
0021 // use the alloca function to allocate a variable sized array on the stack
0022 // (since the array is small, there's really no
0023 // need to call down to malloc for that stuff)
0024 #ifdef alloca
0025 #define __TMP_ALLOC(n, type) ((type *)alloca((n) * sizeof(type)))
0026 #else
0027 #define __TMP_ALLOC(n, type) ((type *)::alloca((n) * sizeof(type)))
0028 #endif
0029 
0030   // template method to set up the arrays for the computation arrays
0031   //
0032   // two central arrays are used:
0033   // double *values: contains all actual double values of the variables
0034   //                 multiple values of a variable are grouped together
0035   //                 ordering of all values is according to the ascending
0036   //                 IDs of the variables as they appear in the variable
0037   //                 processor configuration
0038   // int    *conf:   "configuration" array which maps the index of the
0039   //                 variable to the offset in values where the respective
0040   //                 values appear. The actual number of values for
0041   //                 variable i is then (conf[i + 1] - conf[i])
0042 
0043   template <typename Iterator_t>
0044   double MVAComputer::eval(Iterator_t first, Iterator_t last) const {
0045     unsigned int size = inputVariables.size();
0046 
0047     int *conf = __TMP_ALLOC(nVars + 2, int);
0048     std::memset(conf, 0, (nVars + 2) * sizeof(int));
0049 
0050     // collect information about variables:
0051     // * count values in input variables and store in conf array
0052     // * estimate maximal size of value array
0053     unsigned int n = 0;
0054     unsigned int max = nVars;
0055     for (Iterator_t cur = first; cur < last; ++cur) {
0056       int id = getVariableId(cur->getName());
0057       if (id < 0)
0058         continue;
0059       conf[id + 1]++;
0060       max += inputVariables[id].multiplicity + 1;
0061       n++;
0062     }
0063 
0064     // integrate entries conf array to compute value offsets
0065     unsigned int sum = 0;
0066     for (unsigned int i = 1; i <= size; i++) {
0067       unsigned int tmp = conf[i];
0068       conf[i] = sum;
0069       sum += tmp;
0070     }
0071 
0072     // allocate value array and fill input variables
0073     double *values = __TMP_ALLOC(max - size + 1, double);
0074     std::fill_n(values, max - size + 1, 0.0);
0075     for (Iterator_t cur = first; cur < last; ++cur) {
0076       int id = getVariableId(cur->getName());
0077       if (id < 0)
0078         continue;
0079       values[conf[id + 1]++] = cur->getValue();
0080     }
0081 
0082     EvalContext ctx(values, conf, n);
0083     evalInternal(ctx);
0084 
0085     return ctx.output(output);
0086   }
0087 
0088 #undef __TMP_ALLOC
0089 
0090   template <typename Iterator_t>
0091   double MVAComputer::deriv(Iterator_t first, Iterator_t last) const {
0092     unsigned int size = inputVariables.size();
0093 
0094     DerivContext ctx;
0095     ctx.conf_.resize(nVars + 2);
0096 
0097     // collect information about variables:
0098     // * count values in input variables and store in conf array
0099     // * estimate maximal size of value array
0100     unsigned int max = nVars;
0101     for (Iterator_t cur = first; cur < last; ++cur) {
0102       int id = getVariableId(cur->getName());
0103       if (id < 0)
0104         continue;
0105       ctx.conf_[id + 1]++;
0106       max += inputVariables[id].multiplicity + 1;
0107       ctx.n_++;
0108     }
0109 
0110     // integrate entries conf array to compute value offsets
0111     unsigned int sum = 0;
0112     for (unsigned int i = 1; i <= size; i++) {
0113       unsigned int tmp = ctx.conf_[i];
0114       ctx.conf_[i] = sum;
0115       sum += tmp;
0116     }
0117 
0118     // allocate value array and fill input variables
0119     ctx.values_.resize(max - size + 1);
0120     ctx.deriv_.reserve((max - size + 1) * ctx.n_);
0121     for (Iterator_t cur = first; cur < last; ++cur) {
0122       int id = getVariableId(cur->getName());
0123       if (id < 0)
0124         continue;
0125       ctx.values_[ctx.conf_[id + 1]++] = cur->getValue();
0126     }
0127 
0128     evalInternal(ctx);
0129 
0130     std::vector<double> deriv;
0131     double value = ctx.output(output, deriv);
0132 
0133     for (Iterator_t cur = first; cur < last; ++cur) {
0134       int id = getVariableId(cur->getName());
0135       if (id < 0)
0136         continue;
0137       cur->setValue(deriv[ctx.conf_[id]++]);
0138     }
0139 
0140     return value;
0141   }
0142 
0143 }  // namespace PhysicsTools
0144 
0145 #endif  // PhysicsTools_MVAComputer_MVAComputer_icc