SpinParser  1.0
Integrator.hpp
Go to the documentation of this file.
1 
9 #pragma once
10 #include <functional>
11 #include "lib/Assert.hpp"
12 #include "FrgCommon.hpp"
13 
14 namespace Integrator
15 {
25  template <class T> T integrate(const FrequencyIterator min, const FrequencyIterator max, const std::function<T(float)> &integrand)
26  {
27  ASSERT(*min <= *max, "Lower integration boundary must not be larger than upper boundary. ");
28 
29  FrequencyIterator umin(min);
30  if (umin != max)
31  {
32  T integral = (*(umin + 1) - *umin) * integrand(*umin);
33  while (++umin != max) integral += (*(umin + 1) - *(umin - 1)) * integrand(*umin);
34  integral += (*umin - *(umin - 1)) * integrand(*umin);
35  return 0.5f * integral;
36  }
37  else return 0.0f;
38  }
39 
49  template <class T> T integrateWithObscureLeftBoundary(const float min, const FrequencyIterator max, const std::function<T(float)> &integrand)
50  {
51  ASSERT(min <= *max, "Lower integration boundary must not be larger than upper boundary. ");
52 
54  if (umin != max)
55  {
56  T integral = (*umin - min) * integrand(min);
57  integral += (*(umin + 1) - min) * integrand(*umin);
58  while (++umin != max) integral += (*(umin + 1) - *(umin - 1)) * integrand(*umin);
59  integral += (*umin - *(umin - 1)) * integrand(*umin);
60  return 0.5f * integral;
61  }
62  else return 0.5f * (*umin - min) * (integrand(min) + integrand(*umin));
63  }
64 
74  template <class T> T integrateWithObscureRightBoundary(const FrequencyIterator min, const float max, const std::function<T(float)> &integrand)
75  {
76  ASSERT(*min <= max, "Lower integration boundary must not be larger than upper boundary. ");
77 
78  FrequencyIterator umin(min);
80  if (umin != umax)
81  {
82  T integral = (*(umin + 1) - *umin) * integrand(*umin);
83  while (++umin != umax) integral += (*(umin + 1) - *(umin - 1)) * integrand(*umin);
84  integral += (max - *(umin - 1)) * integrand(*umin);
85  integral += (max - *umin) * integrand(max);
86  return 0.5f * integral;
87  }
88  else return 0.5f * (max - *umin) * (integrand(max) + integrand(*umin));
89  }
90 
100  template <class T>
101  T integrateWithObscureBoundaries(const float min, const float max, const std::function<T(float)> &integrand)
102  {
103  ASSERT(min <= max, "Lower integration boundary must not be larger than upper boundary. ");
104 
107  if (umax >= umin)
108  {
109  T integral = (*umin - min) * integrand(min);
110  if (umax != umin)
111  {
112  integral += (*(umin + 1) - min) * integrand(*umin);
113  while (++umin != umax) integral += (*(umin + 1) - *(umin - 1)) * integrand(*umin);
114  integral += (max - *(umin - 1)) * integrand(*umin);
115  }
116  else integral += (max - min) * integrand(*umin);
117  integral += (max - *umin) * integrand(max);
118  return 0.5f * integral;
119  }
120  else return 0.5f * (max - min) * (integrand(max) + integrand(min));
121  }
122 }
123 
124 namespace ImplicitIntegrator
125 {
137  template <class T>
138  void integrateWithObscureLeftBoundary(const float min, const FrequencyIterator max, const std::function<void(float, T &)> &integrand, T &integrandBuffer, T &resultBuffer)
139  {
140  ASSERT(&integrandBuffer != &resultBuffer);
141  ASSERT(min <= *max, "Lower integration boundary must not be larger than upper boundary. ");
142 
143  resultBuffer.reset();
145  if (umin != max)
146  {
147  integrand(min, integrandBuffer);
148  resultBuffer.multAdd(*umin - min, integrandBuffer);
149 
150  integrand(*umin, integrandBuffer);
151  resultBuffer.multAdd(*(umin + 1) - min, integrandBuffer);
152 
153  while (++umin != max)
154  {
155  integrand(*umin, integrandBuffer);
156  resultBuffer.multAdd(*(umin + 1) - *(umin - 1), integrandBuffer);
157  }
158 
159  integrand(*umin, integrandBuffer);
160  resultBuffer.multAdd(*umin - *(umin - 1), integrandBuffer);
161 
162  resultBuffer *= 0.5f;
163  }
164  else
165  {
166  integrand(min, integrandBuffer);
167  resultBuffer += integrandBuffer;
168 
169  integrand(*umin, integrandBuffer);
170  resultBuffer += integrandBuffer;
171 
172  resultBuffer *= 0.5f * (*umin - min);
173  }
174  }
175 
187  template <class T>
188  void integrateWithObscureRightBoundary(const FrequencyIterator min, const float max, const std::function<void(float, T &)> &integrand, T &integrandBuffer, T &resultBuffer)
189  {
190  ASSERT(&integrandBuffer != &resultBuffer);
191  ASSERT(*min <= max, "Lower integration boundary must not be larger than upper boundary. ");
192 
193  resultBuffer.reset();
194  FrequencyIterator umin(min);
196  if (umin != umax)
197  {
198  integrand(*umin, integrandBuffer);
199  resultBuffer.multAdd(*(umin + 1) - *umin, integrandBuffer);
200 
201  while (++umin != umax)
202  {
203  integrand(*umin, integrandBuffer);
204  resultBuffer.multAdd(*(umin + 1) - *(umin - 1), integrandBuffer);
205  }
206 
207  integrand(*umin, integrandBuffer);
208  resultBuffer.multAdd(max - *(umin - 1), integrandBuffer);
209 
210  integrand(max, integrandBuffer);
211  resultBuffer.multAdd(max - *umin, integrandBuffer);
212 
213  resultBuffer *= 0.5f;
214  }
215  else
216  {
217  integrand(max, integrandBuffer);
218  resultBuffer += integrandBuffer;
219 
220  integrand(*umin, integrandBuffer);
221  resultBuffer += integrandBuffer;
222 
223  resultBuffer *= 0.5f * (max - *umin);
224  }
225  }
226 
238  template <class T>
239  void integrateWithObscureBoundaries(const float min, const float max, const std::function<void(float, T &)> &integrand, T &integrandBuffer, T &resultBuffer)
240  {
241  ASSERT(&integrandBuffer != &resultBuffer);
242  ASSERT(min <= max, "Lower integration boundary must not be larger than upper boundary. ");
243 
244  resultBuffer.reset();
247  if (umax >= umin)
248  {
249  integrand(min, integrandBuffer);
250  resultBuffer.multAdd(*umin - min, integrandBuffer);
251 
252  if (umax != umin)
253  {
254  integrand(*umin, integrandBuffer);
255  resultBuffer.multAdd(*(umin + 1) - min, integrandBuffer);
256 
257  while (++umin != umax)
258  {
259  integrand(*umin, integrandBuffer);
260  resultBuffer.multAdd(*(umin + 1) - *(umin - 1), integrandBuffer);
261  }
262 
263  integrand(*umin, integrandBuffer);
264  resultBuffer.multAdd(max - *(umin - 1), integrandBuffer);
265  }
266  else
267  {
268  integrand(*umin, integrandBuffer);
269  resultBuffer.multAdd(max - min, integrandBuffer);
270  }
271 
272  integrand(max, integrandBuffer);
273  resultBuffer.multAdd(max - *umin, integrandBuffer);
274 
275  resultBuffer *= 0.5f;
276  }
277  else
278  {
279  integrand(max, integrandBuffer);
280  resultBuffer += integrandBuffer;
281 
282  integrand(min, integrandBuffer);
283  resultBuffer += integrandBuffer;
284 
285  resultBuffer *= 0.5f * (max - min);
286  }
287  }
288 }
ASSERT
#define ASSERT(...)
Ensure that the first argument is true. Optionally provide a message as the second argument,...
Definition: Assert.hpp:26
FrequencyIterator
Frequency iterator.
Definition: FrequencyDiscretization.hpp:21
FrgCommon::frequency
static const FrequencyDiscretization & frequency()
Retrieve the Matsubara frequency discretization.
Definition: FrgCommon.hpp:36
Integrator::integrateWithObscureLeftBoundary
T integrateWithObscureLeftBoundary(const float min, const FrequencyIterator max, const std::function< T(float)> &integrand)
One-dimensional trapezoidal integration in one-dimensional frequency space.
Definition: Integrator.hpp:49
FrgCommon.hpp
Hub for central objects in pf-FRG calculations.
Integrator::integrateWithObscureRightBoundary
T integrateWithObscureRightBoundary(const FrequencyIterator min, const float max, const std::function< T(float)> &integrand)
One-dimensional trapezoidal integration in one-dimensional frequency space.
Definition: Integrator.hpp:74
Assert.hpp
Lightweight macro library for assertions.
FrequencyDiscretization::lesser
FrequencyIterator lesser(const float w) const
Retrieve an iterator to the closest mesh point that is lesser than the specified frequency value....
Definition: FrequencyDiscretization.hpp:253
Integrator::integrateWithObscureBoundaries
T integrateWithObscureBoundaries(const float min, const float max, const std::function< T(float)> &integrand)
One-dimensional trapezoidal integration in one-dimensional frequency space.
Definition: Integrator.hpp:101
Integrator::integrate
T integrate(const FrequencyIterator min, const FrequencyIterator max, const std::function< T(float)> &integrand)
One-dimensional trapezoidal integration in one-dimensional frequency space.
Definition: Integrator.hpp:25
FrequencyDiscretization::greater
FrequencyIterator greater(const float w) const
Retrieve an iterator to the closest mesh point that is greater than the specified frequency value....
Definition: FrequencyDiscretization.hpp:279