HepLib
Loading...
Searching...
No Matches
QuadMP.cpp
Go to the documentation of this file.
1
6#include <math.h>
7#include <complex>
8extern "C" {
9#include <quadmath.h>
10}
11#include "mpreal.h"
12#include "Lib3_GK.h"
13#include "SD.h"
14
15/* error return codes */
16#define SUCCESS 0
17#define FAILURE 1
18
19using namespace std;
20namespace {
21 typedef mpfr::mpreal mpREAL;
22 typedef const mpREAL & mpREAL_t;
23 typedef complex<mpREAL> mpCOMPLEX;
24 typedef std::function<int(unsigned yn, mpREAL *y, mpREAL *e, const mpREAL & x, void *fdata)> f1Type;
25 typedef const f1Type & f1Type_t;
26 typedef std::function<int(unsigned yn, mpREAL *y, mpREAL *e, unsigned xdim, const mpREAL *x, void *fdata)> fnType;
27 typedef const fnType & fnType_t;
28 typedef void (*PrintHookerType) (mpREAL *, mpREAL *, size_t *, void *);
29}
30
31extern mpREAL mpPi;
32extern mpREAL mpEuler;
34
35namespace {
36 size_t _nGK_ = 10000;
37 size_t _mGK_ = 10; // sets (2m+1)-point Gauss-Kronrod
38
39 int QuadPack1(unsigned yn, mpREAL *oval, mpREAL *oerr, f1Type_t f, mpREAL_t epsabs, PrintHookerType PrintHooker, void *fdata) {
40 GK gk(_nGK_, _mGK_);
41 Function F(yn,f,fdata);
42 try {
43 return gk.QAG(F, 0, 1, epsabs, 0, oval, oerr, PrintHooker);
44 } catch (const char* reason) {
45 cout << reason << endl;
46 throw reason;
47 }
48 return SUCCESS;
49 }
50
51 int QuadPackN(unsigned yn, mpREAL *oval, mpREAL *oerr, unsigned xdim, fnType_t f, mpREAL_t eps, PrintHookerType PrintHooker, void *fdata) {
52 if(xdim==1) {
53 auto f1 = [f,eps](unsigned yn, mpREAL *y, mpREAL *e, mpREAL_t x, void *fdata)->int {
54 mpREAL xs[1];
55 xs[0] = x;
56 return f(yn,y,e,1,xs,fdata);
57 };
58 return QuadPack1(yn, oval, oerr, f1, eps, PrintHooker, fdata);
59 }
60
61 auto f1 = [f,eps,xdim](unsigned yn, mpREAL *y, mpREAL *e, mpREAL_t x, void *fdata)->int {
62 auto f2 =[f,x](unsigned yn, mpREAL *y1, mpREAL *e1, unsigned xdim1, const mpREAL *xs1, void *fdata1)->int {
63 mpREAL xs[xdim1+1];
64 if(true) { // insert first
65 xs[0] = x;
66 for(int i=0; i<xdim1; i++) xs[i+1] = xs1[i];
67 } else { // insert last
68 for(int i=0; i<xdim1; i++) xs[i] = xs1[i];
69 xs[xdim1] = x;
70 }
71 return f(yn,y1,e1,xdim1+1,xs,fdata1);
72 };
73 return QuadPackN(yn,y,e,xdim-1,f2,eps/xdim,NULL,fdata);
74 };
75 return QuadPack1(yn, oval, oerr, f1, eps, PrintHooker, fdata);
76 }
77
78}
79
80namespace HepLib::SD {
81
82/*-----------------------------------------------------*/
83// QuadMP Classes
84/*-----------------------------------------------------*/
85
86ex QuadMP::mp2ex(const mpREAL & num) {
87 ostringstream oss;
88 oss.precision(MPDigits);
89 oss << num;
90 string sn = oss.str();
91 numeric ret(sn.c_str());
92 return ret;
93}
94
95int QuadMP::Wrapper(unsigned ydim, mpREAL *y, mpREAL *e, unsigned xdim, const mpREAL *x, void *fdata) {
96 auto self = (QuadMP*)fdata;
97 self->IntegrandMP(xdim, x, ydim, y, self->mpParameter, self->mpLambda);
98 // Check NaN/Inf
99 bool ok = true;
100 for(int j=0; j<ydim; j++) {
101 if(!isfinite(y[j])) { ok = false; break; }
102 }
103 if(!ok) {
104 mpfr::mpreal::set_default_prec(mpfr::digits2bits(self->MPDigits*10));
105 self->IntegrandMP(xdim, x, ydim, y, self->mpParameter, self->mpLambda);
106 mpfr::mpreal::set_default_prec(mpfr::digits2bits(self->MPDigits));
107 }
108 for(int j=0; j<ydim; j++) e[j] = 0; // assume error can be ignored
109 return SUCCESS;
110}
111
112void QuadMP::DefaultPrintHooker(mpREAL* result, mpREAL* epsabs, size_t * nrun, void *fdata) {
113 auto self = (QuadMP*)fdata;
114 if(*nrun == self->nGK + 1979) return;
115 if(self->RunTime>0) {
116 auto cur_timer = time(NULL);
117 auto used_time = difftime(cur_timer,self->StartTimer);
118 if(used_time>self->RunTime) {
119 self->NEval = *nrun;
120 *nrun = self->nGK + 1979;
121 if(Verbose>10) cout << WarnColor << " Exit with Run out of Time: " << used_time << RESET << endl;
122 return;
123 }
124 }
125 if(Verbose>10) {
126 if(self->YDim==2) {
127 auto r0 = result[0];
128 auto r1 = result[1];
129 auto e0 = epsabs[0].toString(3);
130 auto e1 = epsabs[1].toString(3);
131 cout << " L: " << (*nrun) << ", ";
132 if(self->ReIm==3 || self->ReIm==1) cout << "[" << r0 << ", " << e0 << "]";
133 if(self->ReIm==3 || self->ReIm==2) cout << "+I*[" << r1 << ", " << e1 << "]";
134 cout << endl;
135 } else {
136 for(int j=0; j<self->YDim; j++) {
137 auto r = result[j];
138 auto e = epsabs[j].toString(3);
139 if(j==0) cout << " L: " << (*nrun) << ", ";
140 else cout << " >>L: " << (*nrun) << ", ";
141 cout << "[" << r << ", " << e << "]";
142 cout << endl;
143 }
144 }
145 }
146 self->NEval = *nrun;
147
148 bool bExit = true;
149 for(int j=0; j<self->YDim; j++) {
150 if((epsabs[j] > self->EpsAbs+1E-50Q) && (epsabs[j] > fabs(result[j])*self->EpsRel+1E-50Q)) {
151 bExit = false;
152 break;
153 }
154 }
155
156 if(bExit) {
157 *nrun = self->nGK + 1979;
158 return;
159 }
160
161 auto pid = getpid();
162 ostringstream fn;
163 fn << pid << ".int.done";
164 if(file_exists(fn.str().c_str())) {
165 self->NEval = *nrun;
166 *nrun = self->nGK + 1979;
167 ostringstream cmd;
168 cmd << "rm " << fn.str();
169 auto rc = system(cmd.str().c_str());
170 if(Verbose>10) cout << " Exit: " << fn.str() << endl;
171 }
172}
173
174ex QuadMP::Integrate(size_t n) {
175 if(mpfr_buildopt_tls_p()<=0) throw Error("Integrate: mpfr_buildopt_tls_p()<=0.");
176 mpfr_free_cache();
177 mpfr::mpreal::set_default_prec(mpfr::digits2bits(MPDigits));
178 mpPi = mpfr::const_pi();
179 mpEuler = mpfr::const_euler();
180 mpiEpsilon = complex<mpREAL>(0,mpfr::machine_epsilon()*100);
181
182 unsigned int xdim = XDim;
183 unsigned int ydim = YDim;
184 mpREAL result[ydim], estabs[ydim];
185
186 NEval = 0;
187 _mGK_ = mGK;
188 _nGK_ = n==0 ? nGK : n;
189 StartTimer = time(NULL);
190 auto nok = QuadPackN(ydim, result, estabs, xdim, Wrapper, EpsAbs, n==0 ? PrintHooker : NULL, this);
191
192 if(nok) {
193 mpREAL abs_res = 0;
194 for(int j=0; j<ydim; j++) abs_res += result[j]*result[j];
195 abs_res = sqrt(abs_res);
196 mpREAL abs_est = 0;
197 for(int j=0; j<ydim; j++) abs_est += estabs[j]*estabs[j];
198 abs_est = sqrt(abs_est);
199 mpREAL mpfr_eps = 10*mpfr::machine_epsilon();
200 if( (abs_res < mpfr_eps) && (abs_est < mpfr_eps) ) {
201 cout << ErrColor << "QuadMP Failed with 0 result returned!" << RESET << endl;
202 return NaN;
203 }
204 }
205
206 ex FResult = 0;
207 bool any_NAN = false;
208 for(int j=0; j<ydim; j++) {
209 if(isnan(result[j])) {
210 any_NAN = true;
211 break;
212 }
213 }
214 if(any_NAN) FResult = NaN;
215 else {
216 try{
217 if(ydim==2) {
218 FResult = VE(mp2ex(result[0]), mp2ex(estabs[0])) + VE(mp2ex(result[1]), mp2ex(estabs[1])) * I;
219 } else {
220 lst res;
221 for(int j=0; j<ydim; j++) res.append(VE(mp2ex(result[j]), mp2ex(estabs[j])));
222 FResult = res;
223 }
224 } catch(...) {
225 FResult = NaN;
226 }
227 }
228
229 return FResult;
230}
231
232}
#define RESET
Definition BASIC.h:79
complex< mpREAL > mpCOMPLEX
Definition HCubature.cpp:20
mpfr::mpreal mpREAL
Definition HCubature.cpp:19
mpREAL mpEuler
Definition SD.h:28
mpCOMPLEX mpiEpsilon
mpREAL mpPi
#define SUCCESS
mpREAL mpEuler
Definition SD.h:28
#define SUCCESS
Definition QuadMP.cpp:16
mpCOMPLEX mpiEpsilon
mpREAL mpPi
SecDec header file.
class used to wrap error message
Definition BASIC.h:245
numerical integrator using QuadMP
Definition SD.h:253
size_t nGK
Definition SD.h:262
static void DefaultPrintHooker(mpREAL *, mpREAL *, size_t *, void *)
Definition QuadMP.cpp:112
size_t mGK
Definition SD.h:263
static int Wrapper(unsigned yn, mpREAL *y, mpREAL *e, unsigned xdim, const mpREAL *x, void *fdata)
Definition QuadMP.cpp:95
virtual ex Integrate(size_t n=0) override
Definition QuadMP.cpp:174
PrintHookerType PrintHooker
Definition SD.h:259
mpfr::mpreal mpREAL
Definition SD.h:130
const char * ErrColor
Definition BASIC.cpp:246
const Symbol eps
bool file_exists(string fn)
Definition BASIC.h:292
const char * WarnColor
Definition BASIC.cpp:247
int Verbose
Definition Init.cpp:145
const Symbol NaN