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  :     ProcMatrix
0005 //
0006 
0007 // Implementation:
0008 //     Variable processor to apply a matrix transformation to the input
0009 //     variables. An n x m matrix applied to n input variables results in
0010 //     m output variables.
0011 //
0012 // Author:      Christophe Saout
0013 // Created:     Sat Apr 24 15:18 CEST 2007
0014 //
0015 
0016 #include <cstdlib>
0017 
0018 #include "PhysicsTools/MVAComputer/interface/VarProcessor.h"
0019 #include "PhysicsTools/MVAComputer/interface/Calibration.h"
0020 
0021 using namespace PhysicsTools;
0022 
0023 namespace {  // anonymous
0024 
0025   class ProcMatrix : public VarProcessor {
0026   public:
0027     typedef VarProcessor::Registry::Registry<ProcMatrix, Calibration::ProcMatrix> Registry;
0028 
0029     ProcMatrix(const char *name, const Calibration::ProcMatrix *calib, const MVAComputer *computer);
0030     ~ProcMatrix() override {}
0031 
0032     void configure(ConfIterator iter, unsigned int n) override;
0033     void eval(ValueIterator iter, unsigned int n) const override;
0034     std::vector<double> deriv(ValueIterator iter, unsigned int n) const override;
0035 
0036   private:
0037     class Matrix {
0038     public:
0039       inline Matrix(const Calibration::Matrix *calib)
0040           : rows(calib->rows), cols(calib->columns), coeffs(calib->elements) {}
0041 
0042       inline unsigned int getRows() const { return rows; }
0043       inline unsigned int getCols() const { return cols; }
0044 
0045       inline double operator()(unsigned int row, unsigned int col) const { return coeffs[row * cols + col]; }
0046 
0047     private:
0048       unsigned int rows;
0049       unsigned int cols;
0050       std::vector<double> coeffs;
0051     };
0052 
0053     Matrix matrix;
0054   };
0055 
0056   ProcMatrix::Registry registry("ProcMatrix");
0057 
0058   ProcMatrix::ProcMatrix(const char *name, const Calibration::ProcMatrix *calib, const MVAComputer *computer)
0059       : VarProcessor(name, calib, computer), matrix(&calib->matrix) {}
0060 
0061   void ProcMatrix::configure(ConfIterator iter, unsigned int n) {
0062     if (n != matrix.getCols())
0063       return;
0064 
0065     for (unsigned int col = 0; col < matrix.getCols(); col++)
0066       iter++(Variable::FLAG_NONE);
0067 
0068     for (unsigned int row = 0; row < matrix.getRows(); row++)
0069       iter << Variable::FLAG_NONE;
0070   }
0071 
0072   void ProcMatrix::eval(ValueIterator iter, unsigned int n) const {
0073     double *sums = (double *)alloca(matrix.getRows() * sizeof(double));
0074     for (unsigned int row = 0; row < matrix.getRows(); row++)
0075       sums[row] = 0.0;
0076 
0077     for (unsigned int col = 0; col < matrix.getCols(); col++) {
0078       double val = *iter++;
0079       for (unsigned int row = 0; row < matrix.getRows(); row++)
0080         sums[row] += matrix(row, col) * val;
0081     }
0082 
0083     for (unsigned int row = 0; row < matrix.getRows(); row++)
0084       iter(sums[row]);
0085   }
0086 
0087   std::vector<double> ProcMatrix::deriv(ValueIterator iter, unsigned int n) const {
0088     std::vector<double> result;
0089     result.reserve(matrix.getRows() * matrix.getCols());
0090 
0091     for (unsigned int row = 0; row < matrix.getRows(); row++)
0092       for (unsigned int col = 0; col < matrix.getCols(); col++)
0093         result.push_back(matrix(row, col));
0094 
0095     return result;
0096   }
0097 
0098 }  // anonymous namespace