Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 12:50:13

0001 #ifndef CommonTools_Utils_FormulaEvaluator_h
0002 #define CommonTools_Utils_FormulaEvaluator_h
0003 // -*- C++ -*-
0004 //
0005 // Package:     CommonTools/Utils
0006 // Class  :     FormulaEvaluator
0007 //
0008 /**\class FormulaEvaluator FormulaEvaluator.h "CommonTools/Utils/interface/FormulaEvaluator.h"
0009 
0010  Description: [one line class summary]
0011 
0012  Usage:
0013     <usage>
0014 
0015 */
0016 //
0017 // Original Author:  Christopher Jones
0018 //         Created:  Wed, 23 Sep 2015 21:12:11 GMT
0019 //
0020 
0021 // system include files
0022 #include <array>
0023 #include <vector>
0024 #include <memory>
0025 #include <string>
0026 
0027 // user include files
0028 
0029 // forward declarations
0030 namespace reco {
0031   namespace formula {
0032     struct ArrayAdaptor {
0033       ArrayAdaptor(double const* iStart, size_t iSize) : m_start(iStart), m_size(iSize) {}
0034       size_t size() const { return m_size; }
0035       bool empty() const { return m_size == 0; }
0036       double const* start() const { return m_start; }
0037 
0038     private:
0039       double const* m_start;
0040       size_t m_size;
0041     };
0042     inline double const* startingAddress(ArrayAdaptor const& iV) {
0043       if (iV.empty()) {
0044         return nullptr;
0045       }
0046       return iV.start();
0047     }
0048 
0049     class EvaluatorBase;
0050     inline double const* startingAddress(std::vector<double> const& iV) {
0051       if (iV.empty()) {
0052         return nullptr;
0053       }
0054       return &iV[0];
0055     }
0056 
0057     template <size_t t>
0058     inline double const* startingAddress(std::array<double, t> const& iV) {
0059       if (iV.empty()) {
0060         return nullptr;
0061       }
0062       return &iV[0];
0063     }
0064 
0065   }  // namespace formula
0066 
0067   class FormulaEvaluator {
0068   public:
0069     explicit FormulaEvaluator(std::string const& iFormula);
0070 
0071     // ---------- const member functions ---------------------
0072     template <typename V, typename P>
0073     double evaluate(V const& iVariables, P const& iParameters) const {
0074       if (m_nVariables > iVariables.size()) {
0075         throwWrongNumberOfVariables(iVariables.size());
0076       }
0077       if (m_nParameters > iParameters.size()) {
0078         throwWrongNumberOfParameters(iParameters.size());
0079       }
0080       return evaluate(formula::startingAddress(iVariables), formula::startingAddress(iParameters));
0081     }
0082 
0083     unsigned int numberOfParameters() const { return m_nParameters; }
0084     unsigned int numberOfVariables() const { return m_nVariables; }
0085 
0086     std::vector<std::string> abstractSyntaxTree() const;
0087 
0088   private:
0089     double evaluate(double const* iVariables, double const* iParameters) const;
0090 
0091     void throwWrongNumberOfVariables(size_t) const;
0092     void throwWrongNumberOfParameters(size_t) const;
0093 
0094     std::shared_ptr<formula::EvaluatorBase const> m_evaluator;
0095     unsigned int m_nVariables = 0;
0096     unsigned int m_nParameters = 0;
0097   };
0098 }  // namespace reco
0099 
0100 #endif