ATLAS Offline Software
eflowCellIntegrator.h
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 /*
6  * eflowCellIntegration.h
7  *
8  * Created on: 12.08.2013
9  * Author: tlodd
10  */
11 
12 #ifndef EFLOWCELLINTEGRATION_H_
13 #define EFLOWCELLINTEGRATION_H_
14 
15 #include <stdexcept>
16 #include <iostream>
17 
18 #include <math.h>
19 
20 #include "eflowRec/eflowUtil.h"
23 
25 enum Exp_t {stdExp = 0, lookupExp};
26 
33 template <class IntegrandType>
35 public:
36  eflowRecursiveGaussLegendreIntegrator(IntegrandType* integrand, double error) :
37  m_integrand(integrand), m_error(error), m_depth(1) {
38  assert(m_integrand);
39  }
41 
42  virtual double integrate(const eflowRange& range) {
43  /* Try a 5th and 6th order Gauss-Legendre quadrature */
44  double I5 = DoGaussLegendreIntegration(range, 5);
45  double I6 = DoGaussLegendreIntegration(range, 6);
46 
47  /* If results agree within m_error threshold, return the mean... */
48  double Imean = (I5 + I6) / 2.0;
49  if (fabs(I5 - I6) / Imean <= m_error) {
50  return Imean;
51  } else {
52  /* ...else recursively part up the integration into n subRanges */
53  return RecurseIntegration(range, 2);
54  }
55  }
56 
57  double getError() const {return m_error;}
58 
59 private:
60 
61  double DoGaussLegendreIntegration(const eflowRange& range, int nOrder){
62  /* Perform nth order Gauss-Legendre quadrature, see
63  * http://en.wikipedia.org/wiki/Gaussian_quadrature#Gauss.E2.80.93Legendre_quadrature */
64 
65  /* Array offset for legendre weights/roots */
66  int j = nOrder * (nOrder - 1) / 2;
67  const double* roots = legendreRoots + j;
68  const double* weights = legendreWeights + j;
69 
70  double rangeCenter = range.getCenter();
71  double rangeHalfWidth = range.getWidth()/2;
72 
73  double I = 0.0;
74  double x;
75  if(m_integrand){
76  for (int i = 0; i < nOrder; i++) {
77  x = rangeCenter + roots[i] * rangeHalfWidth;
78  I += weights[i] * m_integrand->evaluate(x);
79  }
80  }
81  else{
82  std::cerr << "eflowCellIntergrator::DoGaussLegendreIntegration ERROR : Invalid pointer to IntegrandType and cannot perform integration" << std::endl;
83  }
84  if (I < 0. || rangeHalfWidth < 0.) std::cerr << "eflowCellIntergrator::DoGaussLegendreIntegration WARNING: I = " << I << "\trange = " << range.print() << std::endl;
85 
86  return I * rangeHalfWidth;
87  }
88 
89  double RecurseIntegration(const eflowRange& range, int nSubRanges){
90  m_depth++;
91  /* Part up integration range in n subRanges */
92  double subRangeWidth = range.getWidth() / nSubRanges;
93  eflowRange subRange(range.getMin(), range.getMin() + subRangeWidth);
94 
95  /* Loop over subranges */
96  double Integral(0.0);
97  for (int i = 0; i < nSubRanges; i++) {
98  Integral += integrate(subRange);
99  subRange.shift(subRangeWidth);
100  }
101  m_depth--;
102 
103  return Integral;
104  }
105 
106  IntegrandType* m_integrand;
107  double m_error;
108  int m_depth;
109 };
110 
120 template <Exp_t expType> class eflowCellIntegrand {
121 public:
125 
126  inline void setEtaSq(double xSq) { m_etaSq = xSq; }
127 
128  inline double evaluateStdExp(double rSq) const { return m_norm * exp(-rSq * m_oneOverTwoSigmaSq); }
129  inline double evaluateLookupExp(double rSq) const { return m_lookupExp->evaluate(rSq * m_oneOverTwoSigmaSq)*m_norm; }
130 
132  inline double evaluate(double y);
133 
134 private:
137  double m_norm;
138  double m_etaSq;
139 };
140 template<> inline double eflowCellIntegrand<stdExp>::evaluate(double phi) { return evaluateStdExp(m_etaSq+phi*phi); }
141 template<> inline double eflowCellIntegrand<lookupExp>::evaluate(double phi) { return evaluateLookupExp(m_etaSq+phi*phi); }
142 
154 template <int expType> class eflowCellIntegrator {
155 public:
158  m_rangePhi (original.m_rangePhi)
159  {
160  }
162  m_integrand2D(std::make_unique<eflowCellIntegrand<(Exp_t)expType> >(*(original.m_integrand2D.get())));
163  m_outerIntegrator(this, original.m_outerIntegrator.getError());
165  m_rangePhi = original.m_rangePhi;
166  }
168 
170  inline double integrate(const eflowRange& etaRange, const eflowRange& phiRange) {
171  /* Store the phi range for the inner integration */
173  /* Invoke the outer integration */
175  }
176 
178  inline double evaluate(double eta) {
179  /* Set the eta (square) value for the inner integration */
180  m_integrand2D->setEtaSq(eta*eta);
181  /* Perform the inner (i.e. phi) integration (will invoke the evaluate() method on m_innerIntegrator) */
183  }
184 
185 private:
186  std::unique_ptr<eflowCellIntegrand<(Exp_t)expType> > m_integrand2D;
190 };
191 
192 
193 #endif /* EFLOWCELLINTEGRATION_H_ */
eflowCellIntegrator::~eflowCellIntegrator
~eflowCellIntegrator()
Definition: eflowCellIntegrator.h:167
eflowCellIntegrator
Class that controls the 2D integration.
Definition: eflowCellIntegrator.h:154
eflowLookupExp.h
eflowUtil.h
pdg_comparison.sigma
sigma
Definition: pdg_comparison.py:324
phi
Scalar phi() const
phi method
Definition: AmgMatrixBasePlugin.h:64
Exp_t
Exp_t
Enum used as template argument to switch between std::exp and the lookup-table based version.
Definition: eflowCellIntegrator.h:25
make_unique
std::unique_ptr< T > make_unique(Args &&... args)
Definition: SkimmingToolEXOT5.cxx:23
eta
Scalar eta() const
pseudorapidity method
Definition: AmgMatrixBasePlugin.h:79
LArCellBinning.etaRange
etaRange
Filling Eta range.
Definition: LArCellBinning.py:128
legendreRoots
constexpr double legendreRoots[21]
Stores roots of 5th and 6th order Legendre polynomials.
Definition: LegendreWeights.h:30
eflowLookupExp
Lookup-table based exponential function to save CPU time, which is used by eflowCellIntegrator.
Definition: eflowLookupExp.h:22
M_PI
#define M_PI
Definition: ActiveFraction.h:11
eflowRecursiveGaussLegendreIntegrator
Class to perform a generic recursive Gauss-Legendre Integration, see http://en.wikipedia....
Definition: eflowCellIntegrator.h:34
eflowRecursiveGaussLegendreIntegrator::integrate
virtual double integrate(const eflowRange &range)
Definition: eflowCellIntegrator.h:42
eflowCellIntegrand::m_etaSq
double m_etaSq
Definition: eflowCellIntegrator.h:138
eflowCellIntegrator::operator=
eflowCellIntegrator & operator=(const eflowCellIntegrator &original)
Definition: eflowCellIntegrator.h:161
drawFromPickle.exp
exp
Definition: drawFromPickle.py:36
x
#define x
eflowCellIntegrand::evaluateStdExp
double evaluateStdExp(double rSq) const
Definition: eflowCellIntegrator.h:128
eflowCellIntegrator::m_innerIntegrator
eflowRecursiveGaussLegendreIntegrator< eflowCellIntegrand<(Exp_t) expType > > m_innerIntegrator
Definition: eflowCellIntegrator.h:188
legendreWeights
constexpr double legendreWeights[21]
Stores weights of 5th and 6th order Legendre polynomials.
Definition: LegendreWeights.h:11
eflowCellIntegrand::evaluateLookupExp
double evaluateLookupExp(double rSq) const
Definition: eflowCellIntegrator.h:129
eflowLookupExp::evaluate
double evaluate(double x) const
Definition: eflowLookupExp.h:42
eflowRecursiveGaussLegendreIntegrator::m_error
double m_error
Definition: eflowCellIntegrator.h:107
eflowRecursiveGaussLegendreIntegrator::getError
double getError() const
Definition: eflowCellIntegrator.h:57
lumiFormat.i
int i
Definition: lumiFormat.py:92
eflowCellIntegrator::m_rangePhi
eflowRange m_rangePhi
Definition: eflowCellIntegrator.h:189
eflowCellIntegrator::m_integrand2D
std::unique_ptr< eflowCellIntegrand<(Exp_t) expType > > m_integrand2D
Definition: eflowCellIntegrator.h:186
eflowCellIntegrator::evaluate
double evaluate(double eta)
Evaluate method for the outer (i.e.
Definition: eflowCellIntegrator.h:178
eflowCellIntegrand::evaluate
double evaluate(double y)
The evaluate method for the integration.
eflowCellIntegrator::eflowCellIntegrator
eflowCellIntegrator(double stdDev, double error)
Definition: eflowCellIntegrator.h:156
eflowRecursiveGaussLegendreIntegrator::m_depth
int m_depth
Definition: eflowCellIntegrator.h:108
plotBeamSpotVxVal.range
range
Definition: plotBeamSpotVxVal.py:195
eflowRecursiveGaussLegendreIntegrator::m_integrand
IntegrandType * m_integrand
Definition: eflowCellIntegrator.h:106
eflowCellIntegrator::m_outerIntegrator
eflowRecursiveGaussLegendreIntegrator< eflowCellIntegrator< expType > > m_outerIntegrator
Definition: eflowCellIntegrator.h:187
eflowCellIntegrand::m_lookupExp
const eflowLookupExp * m_lookupExp
Definition: eflowCellIntegrator.h:135
eflowCellIntegrator::integrate
double integrate(const eflowRange &etaRange, const eflowRange &phiRange)
Main method, which starts the integration.
Definition: eflowCellIntegrator.h:170
eflowRecursiveGaussLegendreIntegrator::RecurseIntegration
double RecurseIntegration(const eflowRange &range, int nSubRanges)
Definition: eflowCellIntegrator.h:89
eflowCellIntegrand::~eflowCellIntegrand
~eflowCellIntegrand()
Definition: eflowCellIntegrator.h:124
eflowCellIntegrand::setEtaSq
void setEtaSq(double xSq)
Definition: eflowCellIntegrator.h:126
y
#define y
LegendreWeights.h
eflowCellIntegrand::m_norm
double m_norm
Definition: eflowCellIntegrator.h:137
eflowCellIntegrand::m_oneOverTwoSigmaSq
double m_oneOverTwoSigmaSq
Definition: eflowCellIntegrator.h:136
get
T * get(TKey *tobj)
get a TObject* from a TKey* (why can't a TObject be a TKey?)
Definition: hcg.cxx:127
eflowCellIntegrand::eflowCellIntegrand
eflowCellIntegrand(double sigma)
Definition: eflowCellIntegrator.h:122
LArCellBinning.phiRange
phiRange
Filling Phi ranges.
Definition: LArCellBinning.py:107
lookupExp
@ lookupExp
Definition: eflowCellIntegrator.h:25
I
#define I(x, y, z)
Definition: MD5.cxx:116
eflowRecursiveGaussLegendreIntegrator::~eflowRecursiveGaussLegendreIntegrator
virtual ~eflowRecursiveGaussLegendreIntegrator()
Definition: eflowCellIntegrator.h:40
eflowRangeBase::shift
void shift(double shift)
Definition: eflowUtil.h:116
error
Definition: IImpactPoint3dEstimator.h:70
stdExp
@ stdExp
Definition: eflowCellIntegrator.h:25
eflowRangeBase< double >
eflowCellIntegrator::eflowCellIntegrator
eflowCellIntegrator(const eflowCellIntegrator &original)
Definition: eflowCellIntegrator.h:157
eflowRecursiveGaussLegendreIntegrator::DoGaussLegendreIntegration
double DoGaussLegendreIntegration(const eflowRange &range, int nOrder)
Definition: eflowCellIntegrator.h:61
eflowCellIntegrand
Class to represent the 2D Gaussian integrand.
Definition: eflowCellIntegrator.h:120
eflowRecursiveGaussLegendreIntegrator::eflowRecursiveGaussLegendreIntegrator
eflowRecursiveGaussLegendreIntegrator(IntegrandType *integrand, double error)
Definition: eflowCellIntegrator.h:36