QMCPACK
GKIntegration< F, GKRule > Class Template Reference
+ Collaboration diagram for GKIntegration< F, GKRule >:

Classes

class  IntervalResult
 

Public Member Functions

 GKIntegration (F &f_)
 
void SetAbsoluteErrorMode ()
 
void SetRelativeErrorMode ()
 
double Integrate (const double a, const double b, const double acc)
 
double Integrate (const double a, const double b, const double accAbs, const double accRel, const bool andFlag)
 

Private Member Functions

void GK (IntervalResult &r)
 
void GKGeneral (const int n, const double xgk[], const double wg[], const double wgk[], IntervalResult &r)
 
void PrintList ()
 
void PrintMax ()
 
void CheckList ()
 
void CheckError (const double err)
 
double RecomputeError ()
 
void Insert (const IntervalResult &r)
 
double Integrate (const double a, const double b, const double absError, const bool absErrorFlag, const double relError, const bool relErrorFlag, const bool andFlag)
 

Private Attributes

std::list< IntervalResultir
 
F & f
 
bool relativeErrors
 

Detailed Description

template<class F, class GKRule = GK31>
class GKIntegration< F, GKRule >

Definition at line 90 of file GKIntegration.h.

Constructor & Destructor Documentation

◆ GKIntegration()

GKIntegration ( F &  f_)
inline

Definition at line 115 of file GKIntegration.h.

115 : f(f_), relativeErrors(false) {}

Member Function Documentation

◆ CheckError()

void CheckError ( const double  err)
inlineprivate

Definition at line 215 of file GKIntegration.h.

References qmcplusplus::abs(), BMWrite4, qmcplusplus::Units::charge::e, error(), and GKIntegration< F, GKRule >::ir.

216  {
217  double errorSum = 0.0;
218 
219  if (ir.size() > 0)
220  {
221  for (typename std::list<IntervalResult>::iterator p = ir.begin(); p != ir.end(); p++)
222  {
223  errorSum += (*p).err;
224  }
225  }
226 
227  if (errorSum == 0.0)
228  {
229  if (err != 0.0)
230  error("CheckError", errorSum, err);
231  }
232  else
233  {
234  if (err / errorSum - 1.0 > 1e-8 && std::abs(err - errorSum) > 1e-14)
235  error("CheckError", errorSum, err, errorSum - err);
236  }
237 
238  BMWrite4("PassedErrorCheck", errorSum, err, errorSum - err);
239  }
std::list< IntervalResult > ir
MakeReturn< UnaryNode< FnFabs, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t abs(const Vector< T1, C1 > &l)
void error(char const *m)
Definition: Standard.h:204
#define BMWrite4(i, j, k, l)
Definition: Standard.h:151

◆ CheckList()

void CheckList ( )
inlineprivate

Definition at line 196 of file GKIntegration.h.

References BMWrite2, error(), GKIntegration< F, GKRule >::ir, and GKIntegration< F, GKRule >::PrintList().

197  {
198  if (ir.size() == 0)
199  return;
200 
201  for (typename std::list<IntervalResult>::iterator p = ir.begin(); p != ir.end(); p++)
202  {
203  typename std::list<IntervalResult>::iterator pn = p;
204  pn++;
205  if (pn != ir.end())
206  if (((*p).err) < ((*pn).err))
207  {
208  PrintList();
209  BMWrite2(*pn, *p);
210  ::error("Ordering problem in list");
211  }
212  }
213  }
std::list< IntervalResult > ir
#define BMWrite2(i, j)
Definition: Standard.h:141
void error(char const *m)
Definition: Standard.h:204

◆ GK()

void GK ( IntervalResult r)
inlineprivate

Definition at line 122 of file GKIntegration.h.

References GKIntegration< F, GKRule >::GKGeneral(), and qmcplusplus::n.

Referenced by GKIntegration< F, GKRule >::Integrate().

122 { GKGeneral(GKRule::n, GKRule::xgk, GKRule::wg, GKRule::wgk, r); }
void GKGeneral(const int n, const double xgk[], const double wg[], const double wgk[], IntervalResult &r)

◆ GKGeneral()

void GKGeneral ( const int  n,
const double  xgk[],
const double  wg[],
const double  wgk[],
IntervalResult r 
)
inlineprivate

Definition at line 125 of file GKIntegration.h.

References GKIntegration< F, GKRule >::IntervalResult::a, qmcplusplus::abs(), GKIntegration< F, GKRule >::IntervalResult::b, GKIntegration< F, GKRule >::IntervalResult::delta, GKIntegration< F, GKRule >::IntervalResult::err, GKIntegration< F, GKRule >::f, qmcplusplus::n, and GKIntegration< F, GKRule >::IntervalResult::result.

Referenced by GKIntegration< F, GKRule >::GK().

126  {
127  const double center = 0.5 * (r.a + r.b);
128  const double halfLength = 0.5 * r.delta;
129  const double fCenter = f(center);
130 
131  double resultGauss = 0;
132  double resultKronrod = fCenter * wgk[n - 1];
133 
134  if (n % 2 == 0)
135  {
136  resultGauss = fCenter * wg[n / 2 - 1];
137  }
138 
139  for (int j = 0; j < (n - 1) / 2; j++)
140  {
141  const int jtw = j * 2 + 1; // j=1,2,3 jtw=2,4,6
142  const double xx = halfLength * xgk[jtw];
143  const double fval1 = f(center - xx);
144  const double fval2 = f(center + xx);
145  const double fsum = fval1 + fval2;
146  resultGauss += wg[j] * fsum;
147  resultKronrod += wgk[jtw] * fsum;
148  }
149 
150  for (int j = 0; j < n / 2; j++)
151  {
152  int jtwm1 = j * 2;
153  const double xx = halfLength * xgk[jtwm1];
154  const double fval1 = f(center - xx);
155  const double fval2 = f(center + xx);
156  resultKronrod += wgk[jtwm1] * (fval1 + fval2);
157  };
158 
159  /* scale by the width of the integration region */
160  resultGauss *= halfLength;
161  resultKronrod *= halfLength;
162 
163  r.result = resultKronrod;
164  r.err = std::abs(resultKronrod - resultGauss);
165  //r.err = pow(200.0 * std::abs(resultKronrod - resultGauss), 1.5);
166  // BMWrite(r);
167  }
MakeReturn< UnaryNode< FnFabs, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t abs(const Vector< T1, C1 > &l)

◆ Insert()

void Insert ( const IntervalResult r)
inlineprivate

Definition at line 256 of file GKIntegration.h.

References GKIntegration< F, GKRule >::IntervalResult::err, and GKIntegration< F, GKRule >::ir.

Referenced by GKIntegration< F, GKRule >::Integrate().

257  {
258  // std::cout << "Inserting.." << std::endl;
259  // PrintList();
260 
261  if (ir.empty())
262  {
263  ir.push_back(r);
264  return;
265  }
266 
267  if (ir.back().err >= r.err)
268  {
269  ir.push_back(r);
270  return;
271  }
272 
273  if (r.err >= ir.front().err)
274  {
275  ir.push_front(r);
276  return;
277  }
278 
279  // size must be >=2
280  typename std::list<IntervalResult>::iterator p = ir.end();
281  p--;
282 
283  // p cannot become less the begin() because of check above
284  while (r.err > (*p).err)
285  p--;
286 
287  // go one down because insert put the element before p
288  p++;
289  ir.insert(p, r);
290  // CheckList();
291  }
std::list< IntervalResult > ir

◆ Integrate() [1/3]

double Integrate ( const double  a,
const double  b,
const double  absError,
const bool  absErrorFlag,
const double  relError,
const bool  relErrorFlag,
const bool  andFlag 
)
inlineprivate

Definition at line 293 of file GKIntegration.h.

References qmcplusplus::abs(), GKIntegration< F, GKRule >::IntervalResult::delta, qmcplusplus::Units::charge::e, GKIntegration< F, GKRule >::IntervalResult::err, GKIntegration< F, GKRule >::GK(), GKIntegration< F, GKRule >::Insert(), GKIntegration< F, GKRule >::ir, qmcplusplus::ldexp(), GKIntegration< F, GKRule >::PrintMax(), GKIntegration< F, GKRule >::RecomputeError(), GKIntegration< F, GKRule >::IntervalResult::result, and warning().

Referenced by GKIntegration< F, GKRule >::Integrate().

300  {
301  ir.clear();
302 
303  // #define PRINT_IT
304 #ifdef PRINT_IT
305  std::cout << "Beginning integration" << std::endl;
306 #endif
307 
308  double errorUnresolved = 0.0;
309  const int iterationMax = 30;
310  // double lengthMin = (b-a)*pow(0.5,iterationMax);
311  double lengthMin = ldexp(b - a, -iterationMax);
312 
313  IntervalResult r0(a, b, b - a);
314  GK(r0);
315  double result = r0.result;
316  double err = r0.err;
317  double errLast = err;
318 
319  ir.push_back(r0);
320 
321  bool quitFlag;
322  do
323  {
324  // PrintList();
325 
326  // Test if the interval with the biggest error has already been subdivided
327  // the maximum number of times. If this is the case throw it out and print add
328  // this contribution to the 'unresolved' errors to be printed at the end
329  while (ir.size() > 0)
330  {
331  IntervalResult& rTest(ir.front());
332  double lengthTest = rTest.delta;
333  if (lengthTest < lengthMin)
334  {
335  warning("KC:Interval was divided too many times", iterationMax, rTest.a, rTest.b, rTest.err, ir.size());
336  // warning("KC:current result=",result,"error=",err);
337  if (absErrorFlag)
338  warning("Absolute accuracy = ", absError);
339  if (relErrorFlag)
340  warning("Relative accuracy = ", relError, "->absolute accuracy=", relError * std::abs(result));
341  // this means there is a problem with the integrand->you could exit here
342  // exit(1);
343  errorUnresolved += rTest.err;
344  // PrintList();
345  ir.pop_front();
346  }
347  else
348  break;
349  }
350  // do you want to exit with a warning after the first unresolved sub-interval occurred?
351  if (ir.size() == 0 || errorUnresolved > 0.0)
352  break;
353  // or print as many as occur
354  // if (ir.size()==0) break;
355 
356  IntervalResult& r(ir.front());
357 
358  double center = 0.5 * (r.a + r.b);
359  IntervalResult r1(r.a, center, 0.5 * r.delta);
360  IntervalResult r2(center, r.b, 0.5 * r.delta);
361 
362  GK(r1);
363  GK(r2);
364 
365  // must not use r after popping
366  result += r1.result + r2.result - r.result;
367  err += r1.err + r2.err - r.err;
368 
369 #ifdef PRINT_IT
370  std::cout.setf(std::ios::scientific);
371  std::cout << "Refined [ " << r.a << " " << r.b << " ] err/L=" << (r1.err + r2.err) / (r.b - r.a)
372  << " error=" << err << std::endl;
373 #endif
374 
375  // must remove old element first because new ones could move to top
376  ir.pop_front();
377 
378  Insert(r1);
379  Insert(r2);
380 
381  // In rare events, the error decreases over may (>10) orders of magnitude
382  // during the refinement. Rounding errors from the beginning can prevent
383  // err from becoming small enough. Recompute err after a substantial decrease.
384  if (err < 1e-6 * errLast)
385  {
386  err = RecomputeError();
387  errLast = err;
388  }
389 
390  // CheckError(err);
391  // PrintList();
392 
393  const bool relOk = (err < relError * std::abs(result) || result == 0.0);
394  const bool absOk = (err < absError);
395 
396  if (absErrorFlag && relErrorFlag)
397  {
398  quitFlag = andFlag ? (relOk && absOk) : (relOk || absOk);
399  }
400  else
401  {
402  quitFlag = absErrorFlag ? absOk : relOk;
403  }
404 
405  } while (!quitFlag);
406 
407 #ifdef PRINT_IT
408  PrintMax();
409 #endif
410 
411  if (errorUnresolved > 0.0)
412  {
413  warning("KC:Unresolved error sum=", errorUnresolved, "for integration interval", a, b);
414  warning("KC:--> Result=", result, "total error=", err,
415  "rel. error=", ((result != 0.0) ? err / std::abs(result) : 0.0));
416  // if (absErrorFlag) warning("Absolute accuracy = ",absError);
417  // if (relErrorFlag) warning("Relative accuracy = ",relError,
418  // "->absolute accuracy=",relError*std::abs(result));
419  }
420 
421  // CheckList();
422 #ifdef PRINT_IT
423  std::cout << "End integration" << std::endl;
424 #endif
425  double sum = 0.0;
426  int numIntervals = 0;
427  for (typename std::list<IntervalResult>::iterator p = ir.begin(); p != ir.end(); p++)
428  {
429  sum += p->result;
430  numIntervals++;
431  }
432 
433  // if (numIntervals > 2000)
434  // std::cerr << "Number of intervals = " << numIntervals << std::endl;
435 
436  double badSum = std::abs((result - sum) / sum);
437  if ((badSum > 1.0e-7) && (std::abs(result - sum) > absError))
438  {
439  std::cerr << "absError tolerance = " << absError << std::endl;
440  std::cerr << "Percent error = " << badSum * 100.0 << std::endl;
441  std::cerr << "Number of intervals = " << numIntervals << std::endl;
442  std::cerr << "result = " << result << " sum = " << sum << std::endl;
443  }
444 
445 
446  return result;
447  }
void warning()
Definition: Standard.h:275
std::list< IntervalResult > ir
void GK(IntervalResult &r)
MakeReturn< UnaryNode< FnFabs, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t > >::Expression_t abs(const Vector< T1, C1 > &l)
MakeReturn< BinaryNode< FnLdexp, typename CreateLeaf< Vector< T1, C1 > >::Leaf_t, typename CreateLeaf< Vector< T2, C2 > >::Leaf_t > >::Expression_t ldexp(const Vector< T1, C1 > &l, const Vector< T2, C2 > &r)
double RecomputeError()
void Insert(const IntervalResult &r)

◆ Integrate() [2/3]

double Integrate ( const double  a,
const double  b,
const double  acc 
)
inline

Definition at line 450 of file GKIntegration.h.

References GKIntegration< F, GKRule >::Integrate(), and GKIntegration< F, GKRule >::relativeErrors.

451  {
452  return Integrate(a, b, acc, !relativeErrors, acc, relativeErrors, false);
453  }
double Integrate(const double a, const double b, const double absError, const bool absErrorFlag, const double relError, const bool relErrorFlag, const bool andFlag)

◆ Integrate() [3/3]

double Integrate ( const double  a,
const double  b,
const double  accAbs,
const double  accRel,
const bool  andFlag 
)
inline

Definition at line 454 of file GKIntegration.h.

References GKIntegration< F, GKRule >::Integrate().

455  {
456  return Integrate(a, b, accAbs, true, accRel, true, andFlag);
457  }
double Integrate(const double a, const double b, const double absError, const bool absErrorFlag, const double relError, const bool relErrorFlag, const bool andFlag)

◆ PrintList()

void PrintList ( )
inlineprivate

Definition at line 169 of file GKIntegration.h.

References BMWrite2, and GKIntegration< F, GKRule >::ir.

Referenced by GKIntegration< F, GKRule >::CheckList().

170  {
171  std::cout << "/------------------------------------------\\" << std::endl;
172  int i = 0;
173  for (typename std::list<IntervalResult>::iterator p = ir.begin(); p != ir.end(); p++)
174  {
175  BMWrite2(i, *p);
176  i++;
177  }
178  std::cout << "\\------------------------------------------/" << std::endl;
179  }
std::list< IntervalResult > ir
#define BMWrite2(i, j)
Definition: Standard.h:141

◆ PrintMax()

void PrintMax ( )
inlineprivate

Definition at line 183 of file GKIntegration.h.

References BMWrite, and GKIntegration< F, GKRule >::ir.

Referenced by GKIntegration< F, GKRule >::Integrate().

184  {
185  typename std::list<IntervalResult>::iterator rMax(ir.begin());
186 
187  for (typename std::list<IntervalResult>::iterator r = ir.begin()++; r != ir.end(); r++)
188  {
189  if ((*r).ErrorL() > (*rMax).ErrorL())
190  rMax = r;
191  }
192 
193  BMWrite(*rMax);
194  }
std::list< IntervalResult > ir
#define BMWrite(i)
Definition: Standard.h:136

◆ RecomputeError()

double RecomputeError ( )
inlineprivate

Definition at line 241 of file GKIntegration.h.

References GKIntegration< F, GKRule >::ir.

Referenced by GKIntegration< F, GKRule >::Integrate().

242  {
243  double errorSum = 0.0;
244 
245  if (ir.size() > 0)
246  {
247  for (typename std::list<IntervalResult>::iterator p = ir.begin(); p != ir.end(); p++)
248  {
249  errorSum += (*p).err;
250  }
251  }
252 
253  return errorSum;
254  }
std::list< IntervalResult > ir

◆ SetAbsoluteErrorMode()

void SetAbsoluteErrorMode ( )
inline

Definition at line 117 of file GKIntegration.h.

References GKIntegration< F, GKRule >::relativeErrors.

117 { relativeErrors = false; }

◆ SetRelativeErrorMode()

void SetRelativeErrorMode ( )
inline

Definition at line 118 of file GKIntegration.h.

References GKIntegration< F, GKRule >::relativeErrors.

118 { relativeErrors = true; }

Member Data Documentation

◆ f

F& f
private

Definition at line 111 of file GKIntegration.h.

Referenced by GKIntegration< F, GKRule >::GKGeneral().

◆ ir

◆ relativeErrors


The documentation for this class was generated from the following file: