HepLib
Loading...
Searching...
No Matches
HCubatureMP.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 "SD.h"
13
14using namespace std;
15typedef mpfr::mpreal mpREAL;
16typedef complex<mpREAL> mpCOMPLEX;
17
18extern mpREAL mpPi;
19extern mpREAL mpEuler;
21
22#include "Lib3_HCubatureMP.h"
23namespace HepLib::SD {
24
25 ex HCubatureMP::mp2ex(const mpREAL & num) {
26 ostringstream oss;
27 oss.precision(MPDigits);
28 oss << num;
29 string sn = oss.str();
30 numeric ret(sn.c_str());
31 return ret;
32 }
33
34 int HCubatureMP::Wrapper(unsigned int xdim, size_t npts, const mpREAL *x, void *fdata, unsigned int ydim, mpREAL *y) {
35 auto self = (HCubatureMP*)fdata;
36 bool NaNQ = false;
37
38 unsigned int nthreads = self->Threads>0 ? self->Threads : omp_get_num_procs();
39 #pragma omp parallel for num_threads(nthreads) schedule(dynamic, 1)
40 for(int i=0; i<npts; i++) {
41 mpfr_free_cache();
42 mpfr::mpreal::set_default_prec(mpfr::digits2bits(self->MPDigits));
43 self->IntegrandMP(xdim, x+i*xdim, ydim, y+i*ydim, self->mpParameter, self->mpLambda);
44 // Final Check NaN/Inf
45 bool ok = true;
46 for(int j=0; j<ydim; j++) {
47 mpREAL ytmp = y[i*ydim+j];
48 if(isnan(ytmp) || isinf(ytmp)) { ok = false; break; }
49 }
50 if(!ok && (self->IntegrandMP!=NULL)) {
51 mpfr_free_cache();
52 mpfr::mpreal::set_default_prec(mpfr::digits2bits(self->MPDigits*10));
53 self->IntegrandMP(xdim, x+i*xdim, ydim, y+i*ydim, self->mpParameter, self->mpLambda);
54 mpfr::mpreal::set_default_prec(mpfr::digits2bits(self->MPDigits));
55 }
56
57 // final check
58 for(int j=0; j<ydim; j++) {
59 mpREAL ytmp = y[i*ydim+j];
60 if(isnan(ytmp) || isinf(ytmp)) {
61 #pragma omp atomic
62 self->nNAN++;
63 if(self->nNAN > self->NANMax) { NaNQ = true; break; }
64 else y[i*ydim+j] = 0;
65 }
66 }
67 if(self->ReIm == 1) y[i*ydim+1] = 0;
68 else if(self->ReIm == 2) y[i*ydim+0] = 0;
69 mpfr_free_cache();
70 }
71
72 return NaNQ ? 1 : 0;
73 }
74
75 void HCubatureMP::DefaultPrintHooker(mpREAL* result, mpREAL* epsabs, size_t * nrun, void *fdata) {
76 auto self = (HCubatureMP*)fdata;
77 if(*nrun == self->MaxPTS + 1979) return;
78 if(self->RunTime>0) {
79 auto cur_timer = time(NULL);
80 auto used_time = difftime(cur_timer,self->StartTimer);
81 if(used_time>self->RunTime) {
82 self->NEval = *nrun;
83 *nrun = self->MaxPTS + 1979;
84 if(Verbose>10) cout << WarnColor << " Exit with Run out of Time: " << used_time << RESET << endl;
85 return;
86 }
87 }
88 if(Verbose>10 && (*nrun-self->NEval) >= self->RunPTS) {
89 auto r0 = result[0];
90 auto r1 = result[1];
91 auto e0 = epsabs[0].toString(3);
92 auto e1 = epsabs[1].toString(3);
93 cout << " N: " << (*nrun) << ", ";
94 if(self->ReIm==3 || self->ReIm==1) cout << "[" << r0 << ", " << e0 << "]";
95 if(self->ReIm==3 || self->ReIm==2) cout << "+I*[" << r1 << ", " << e1 << "]";
96 cout << endl;
97 }
98 if((*nrun-self->NEval) >= self->RunPTS) self->NEval = *nrun;
99
100 if((isnan(result[0]) || isnan(result[1]) || isnan(epsabs[0]) || isnan(epsabs[1])) || (isinf(result[0]) || isinf(result[1]) || isinf(epsabs[0]) || isinf(epsabs[1]))) {
101 self->NEval = *nrun;
102 *nrun = self->MaxPTS + 1979;
103 if(self->LastState>0) self->LastState = -1;
104 if(Verbose>10) cout << ErrColor << " Exit with NaN, LastN=" << self->lastNRUN << RESET << endl;
105 return;
106 }
107
108 if(epsabs[0] > 1E30*self->EpsAbs || epsabs[1] > 1E30*self->EpsAbs) {
109 self->NEval = *nrun;
110 *nrun = self->MaxPTS + 1979;
111 if(self->LastState>0) self->LastState = -1;
112 if(Verbose>10) cout << WarnColor << " Exit with EpsAbs, LastN=" << self->lastNRUN << RESET << endl;
113 return;
114 }
115
116 if((self->LastState == 0) || (epsabs[0]<=2*self->LastAbsErr[0] && epsabs[1]<=2*self->LastAbsErr[1])) {
117 self->LastResult[0] = result[0];
118 self->LastResult[1] = result[1];
119 self->LastAbsErr[0] = epsabs[0];
120 self->LastAbsErr[1] = epsabs[1];
121 self->LastState = 1;
122 self->lastNRUN = *nrun;
123 self->lastnNAN = self->nNAN;
124 }
125
126 bool rExit = (epsabs[0] < self->EpsAbs+1E-50Q) || (epsabs[0] < fabs(result[0])*self->EpsRel+1E-50Q);
127 bool iExit = (epsabs[1] < self->EpsAbs+1E-50Q) || (epsabs[1] < fabs(result[1])*self->EpsRel+1E-50Q);
128 if(rExit && iExit && (*nrun)>self->MinPTS) {
129 self->NEval = *nrun;
130 *nrun = self->MaxPTS + 1979;
131 return;
132 }
133
134 auto pid = getpid();
135 ostringstream fn;
136 fn << pid << ".int.done";
137 if(file_exists(fn.str().c_str())) {
138 self->NEval = *nrun;
139 *nrun = self->MaxPTS + 1979;
140 ostringstream cmd;
141 cmd << "rm " << fn.str();
142 auto rc = system(cmd.str().c_str());
143 if(Verbose>10) cout << " Exit: " << fn.str() << endl;
144 }
145 }
146
148 if(mpfr_buildopt_tls_p()<=0) throw Error("Integrate: mpfr_buildopt_tls_p()<=0.");
149 mpfr_free_cache();
150 mpfr::mpreal::set_default_prec(mpfr::digits2bits(MPDigits));
151 mpPi = mpfr::const_pi();
152 mpEuler = mpfr::const_euler();
153 mpiEpsilon = complex<mpREAL>(0,mpfr::machine_epsilon()*100);
154
155 unsigned int xdim = XDim;
156 unsigned int ydim = 2;
157 mpREAL result[ydim], estabs[ydim];
158
159 mpREAL xmin[xdim], xmax[xdim];
160 for(int i=0; i<xdim; i++) {
161 xmin[i] = 0;
162 xmax[i] = 1;
163 }
164 LastState = 0;
165 NEval = 0;
166 nNAN = 0;
167
168 size_t _MinPTS_, _RunPTS_;
169 if(tn==0) {
170 _RunPTS_ = RunPTS;
171 MaxPTS = RunPTS * RunMAX;
172 _MinPTS_ = MinPTS>0 ? MinPTS : _RunPTS_/10;
173 } else {
174 MaxPTS = tn;
175 if(MaxPTS<10000) MaxPTS = 10000;
176 _RunPTS_ = MaxPTS/5;
177 _MinPTS_ = MinPTS>0 ? MinPTS : _RunPTS_/10;
178 }
179 StartTimer = time(NULL);
180 StartTimer = time(NULL);
181
182 Lib3_HCubatureMP::CPUCORES = omp_get_num_procs();
183 int nok = Lib3_HCubatureMP::hcubature_v(ydim, Wrapper, this, xdim, xmin, xmax, _MinPTS_, _RunPTS_, MaxPTS, EpsAbs, EpsRel, result, estabs, tn==0 ? PrintHooker : NULL);
184
185 if(nok) {
186 mpREAL abs_res = sqrt(result[0]*result[0]+result[1]*result[1]);
187 mpREAL abs_est = sqrt(estabs[0]*estabs[0]+estabs[1]*estabs[1]);
188 mpREAL mpfr_eps = 10*mpfr::machine_epsilon();
189 if( (abs_res < mpfr_eps) && (abs_est < mpfr_eps) ) {
190 cout << ErrColor << "HCubatureMP Failed with 0 result returned!" << RESET << endl;
191 return NaN;
192 }
193 }
194
195 if(LastState==-1 && use_last) {
196 result[0] = LastResult[0];
197 result[1] = LastResult[1];
198 estabs[0] = LastAbsErr[0];
199 estabs[1] = LastAbsErr[1];
200 NEval = lastNRUN;
201 nNAN = lastnNAN;
202 }
203
204 ex FResult = 0;
205 if(isnan(result[0]) || isnan(result[1])) FResult += NaN;
206 else {
207 try{
208 FResult += VE(mp2ex(result[0]), mp2ex(estabs[0]));
209 FResult += VE(mp2ex(result[1]), mp2ex(estabs[1])) * I;
210 } catch(...) {
211 FResult += NaN;
212 }
213 }
214
215 // Check nNAN / NEval
216 if(nNAN * 1000 > NEval && NEval>0) {
217 cout << ErrColor << "NAN=" << nNAN << " v.s. RUN=" << NEval << RESET << endl;
218 }
219
220 return FResult;
221 }
222
223}
#define RESET
Definition BASIC.h:79
complex< mpREAL > mpCOMPLEX
mpfr::mpreal mpREAL
mpREAL mpEuler
mpCOMPLEX mpiEpsilon
mpREAL mpPi
complex< mpREAL > mpCOMPLEX
Definition HCubature.cpp:20
mpfr::mpreal mpREAL
Definition HCubature.cpp:19
mpREAL mpEuler
mpCOMPLEX mpiEpsilon
mpREAL mpPi
SecDec header file.
class used to wrap error message
Definition BASIC.h:242
numerical integrator using HCubatureMP
Definition SD.h:204
static int Wrapper(unsigned int xdim, size_t npts, const mpREAL *x, void *fdata, unsigned int ydim, mpREAL *y)
static void DefaultPrintHooker(mpREAL *, mpREAL *, size_t *, void *)
virtual ex Integrate(size_t n=0) override
PrintHookerType PrintHooker
Definition SD.h:210
namespace for Numerical integration with Sector Decomposition method
Definition AsyMB.cpp:10
mpfr::mpreal mpREAL
Definition SD.h:125
const char * ErrColor
Definition BASIC.cpp:246
bool file_exists(string fn)
Definition BASIC.h:289
const char * WarnColor
Definition BASIC.cpp:247
int Verbose
Definition Init.cpp:142
const Symbol NaN