Hammer  1.0.0
Helicity Amplitude Module for Matrix Element Reweighting
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Integrator.cc
Go to the documentation of this file.
1 ///
2 /// @file Integrator.cc
3 /// @brief Hammer numerical integration classes
4 ///
5 
6 //**** This file is a part of the HAMMER library
7 //**** Copyright (C) 2016 - 2020 The HAMMER Collaboration
8 //**** HAMMER is licensed under version 3 of the GPL; see COPYING for details
9 //**** Please note the MCnet academic guidelines; see GUIDELINES for details
10 
11 // -*- C++ -*-
12 #include <iostream>
13 
15 #include "Hammer/Math/Utils.hh"
16 #include "Hammer/Exceptions.hh"
17 
18 using namespace std;
19 
20 namespace Hammer {
21 
22  double integrate(std::function<double(double)>& func, double low, double high) {
23 
24  double value = 0.;
25  enum { n = 19 };
26 
27  double xi[n];
28  double wi[n];
29 
30  xi[0] = 0.0;
31  wi[0] = 0.16105444984878362;
32  xi[1] = 0.16035862813102394;
33  wi[1] = 0.15896882598519965;
34  xi[2] = -xi[1];
35  wi[2] = wi[1];
36  xi[3] = 0.3165642266117781;
37  wi[3] = 0.1527663007284602;
38  xi[4] = -xi[3];
39  wi[4] = wi[3];
40  xi[5] = 0.46457038687717755;
41  wi[5] = 0.1426055640976579;
42  xi[6] = -xi[5];
43  wi[6] = wi[5];
44  xi[7] = 0.6005459122435153;
45  wi[7] = 0.1287567549009922;
46  xi[8] = -xi[7];
47  wi[8] = wi[7];
48  xi[9] = 0.7209655043062628;
49  wi[9] = 0.11156236184219351;
50  xi[10] = -xi[9];
51  wi[10] = wi[9];
52  xi[11] = 0.8227150489105877;
53  wi[11] = 0.09149349482553046;
54  xi[12] = -xi[11];
55  wi[12] = wi[11];
56  xi[13] = 0.9031559802279142;
57  wi[13] = 0.06904552773838758;
58  xi[14] = -xi[13];
59  wi[14] = wi[13];
60  xi[15] = 0.9602078316107117;
61  wi[15] = 0.044807508218039215;
62  xi[16] = -xi[15];
63  wi[16] = wi[15];
64  xi[17] = 0.9924070086164836;
65  wi[17] = 0.019469784466159833;
66  xi[18] = -xi[17];
67  wi[18] = wi[17];
68 
69  for (int i = 0; i < n; ++i) {
70  double yi = (high - low) * xi[i] / 2.0 + (high + low) / 2.0;
71  double dGi = func(yi);
72  value += wi[i] * dGi;
73  }
74 
75  value *= (high - low) / 2.0;
76 
77  return value;
78  }
79 
80  Integrator::Integrator() {
81  _basePoints = {0.,
82  0.16035862813102394,
83  0.3165642266117781,
84  0.46457038687717755,
85  0.6005459122435153,
86  0.7209655043062628,
87  0.8227150489105877,
88  0.9031559802279142,
89  0.9602078316107117,
90  0.9924070086164836};
91  _baseWeights = {0.16105444984878362, 0.15896882598519965, 0.1527663007284602, 0.1426055640976579,
92  0.1287567549009922, 0.11156236184219351, 0.09149349482553046, 0.06904552773838758,
93  0.044807508218039215, 0.019469784466159833};
94  for (size_t j = 1; j < 10; ++j) {
95  _basePoints.push_back(-_basePoints[j]);
96  _baseWeights.push_back(_baseWeights[j]);
97  }
98  }
99 
100  Integrator::~Integrator() {
101  _evaluationPoints.clear();
102  _evaluationWeights.clear();
103  _basePoints.clear();
104  _baseWeights.clear();
105  }
106 
107  const EvaluationGrid& Integrator::getEvaluationPoints() const {
108  return _evaluationPoints;
109  }
110 
111  const EvaluationWeights& Integrator::getEvaluationWeights() const {
112  return _evaluationWeights;
113  }
114 
115  void Integrator::applyRange(IntegrationBoundaries&& boundaries) {
116  auto tmpboundaries = move(boundaries);
117  applyRange(tmpboundaries);
118  }
119 
120  void Integrator::applyRange(const IntegrationBoundaries& boundaries) {
121  size_t totN = static_cast<size_t>(pow(_basePoints.size(), boundaries.size()));
122  ASSERT(totN < numeric_limits<uint16_t>::max() && totN > 0);
123  ASSERT(boundaries.size() > 0);
124  vector<double> tmp(boundaries.size(), 0.);
125  _evaluationPoints.clear();
126  _evaluationPoints.reserve(totN);
127  _evaluationPoints.insert(_evaluationPoints.end(), totN, tmp);
128  _evaluationWeights = EvaluationWeights(totN, 1.);
129  size_t outerStride = _evaluationPoints.size();
130  for (size_t i = 0; i < boundaries.size(); ++i) {
131  outerStride /= (i == 0) ? 1 : _basePoints.size();
132  size_t currentStride = outerStride / _basePoints.size();
133  for (size_t jOut = 0; jOut < _evaluationPoints.size(); jOut += outerStride) {
134  auto coords = _evaluationPoints[jOut];
135  coords.resize(i);
136  auto range = boundaries[i](coords);
137  double sum = (range.second + range.first) / 2.;
138  double diff = (range.second - range.first) / 2.;
139  for (size_t k = 0; k < _basePoints.size(); ++k) {
140  size_t delta = k * currentStride;
141  for (size_t jIn = 0; jIn < currentStride; ++jIn) {
142  size_t pos = jOut + delta + jIn;
143  _evaluationWeights[pos] *= _baseWeights[k] * diff;
144  _evaluationPoints[pos][i] = sum + diff * _basePoints[k];
145  }
146  }
147  }
148  }
149  }
150 
151  uint16_t Integrator::getPointsNumber() const {
152  return static_cast<uint16_t>(_basePoints.size());
153  }
154 
155 } // namespace Hammer
double integrate(std::function< double(double)> &func, double low, double high)
integration function based on gaussian method
Definition: Integrator.cc:22
#define ASSERT(x)
Definition: Exceptions.hh:95
std::vector< BoundaryFunction > IntegrationBoundaries
Definition: Integrator.fhh:25
Hammer exception definitions.
Hammer numerical integration classes.
std::vector< double > EvaluationWeights
Definition: Integrator.fhh:27
TensorData sum(TensorData origin, const IContainer &other)
Definition: Operations.cc:56
std::vector< std::vector< double >> EvaluationGrid
Definition: Integrator.fhh:26