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 auto pbit = mpfr::digits2bits(self->MPDigits);
43 if(mpfr::mpreal::get_default_prec()!=pbit) mpfr::mpreal::set_default_prec(pbit);
44 self->IntegrandMP(xdim, x+i*xdim, ydim, y+i*ydim, self->mpParameter, self->mpLambda);
45 // Final Check NaN/Inf
46 bool ok = true;
47 for(int j=0; j<ydim; j++) {
48 mpREAL ytmp = y[i*ydim+j];
49 if(isnan(ytmp) || isinf(ytmp)) { ok = false; break; }
50 }
51 if(!ok && (self->IntegrandMP!=NULL)) {
52 mpfr_free_cache();
53 auto pbit = mpfr::digits2bits(self->MPDigits*10);
54 if(mpfr::mpreal::get_default_prec()!=pbit) mpfr::mpreal::set_default_prec(pbit);
55 self->IntegrandMP(xdim, x+i*xdim, ydim, y+i*ydim, self->mpParameter, self->mpLambda);
56 pbit = mpfr::digits2bits(self->MPDigits);
57 if(mpfr::mpreal::get_default_prec()!=pbit) mpfr::mpreal::set_default_prec(pbit);
58 }
59
60 // final check
61 for(int j=0; j<ydim; j++) {
62 mpREAL ytmp = y[i*ydim+j];
63 if(isnan(ytmp) || isinf(ytmp)) {
64 #pragma omp atomic
65 self->nNAN++;
66 if(self->nNAN > self->NANMax) { NaNQ = true; break; }
67 else y[i*ydim+j] = 0;
68 }
69 }
70 if(self->YDim==2) {
71 if(self->ReIm == 1) y[i*ydim+1] = 0;
72 else if(self->ReIm == 2) y[i*ydim+0] = 0;
73 }
74 mpfr_free_cache();
75 }
76
77 return NaNQ ? 1 : 0;
78 }
79
80 void HCubatureMP::DefaultPrintHooker(mpREAL* result, mpREAL* epsabs, size_t * nrun, void *fdata) {
81 auto self = (HCubatureMP*)fdata;
82 if(*nrun == self->MaxPTS + 1979) return;
83 if(self->RunTime>0) {
84 auto cur_timer = time(NULL);
85 auto used_time = difftime(cur_timer,self->StartTimer);
86 if(used_time>self->RunTime) {
87 self->NEval = *nrun;
88 *nrun = self->MaxPTS + 1979;
89 if(Verbose>10) cout << WarnColor << " Exit with Run out of Time: " << used_time << RESET << endl;
90 return;
91 }
92 }
93 if(Verbose>10 && (*nrun-self->NEval) >= self->RunPTS) {
94 if(self->YDim==2) {
95 auto r0 = result[0];
96 auto r1 = result[1];
97 auto e0 = epsabs[0].toString(3);
98 auto e1 = epsabs[1].toString(3);
99 cout << " N: " << (*nrun) << ", ";
100 if(self->ReIm==3 || self->ReIm==1) cout << "[" << r0 << ", " << e0 << "]";
101 if(self->ReIm==3 || self->ReIm==2) cout << "+I*[" << r1 << ", " << e1 << "]";
102 cout << endl;
103 } else {
104 for(int j=0; j<self->YDim; j++) {
105 auto r = result[j];
106 auto e = epsabs[j].toString(3);
107 if(j==0) cout << " N: " << (*nrun) << ", ";
108 else {
109 cout << " ";
110 int ct = to_string(*nrun).length();
111 for(int k=0; k<ct; k++) cout << " ";
112 }
113 cout << "[" << r << ", " << e << "]";
114 cout << endl;
115 }
116 }
117 }
118 if((*nrun-self->NEval) >= self->RunPTS) self->NEval = *nrun;
119
120 bool any_NAN_Inf = false;
121 for(int j=0; j<self->YDim; j++) {
122 if(isnan(result[j]) || isnan(epsabs[j]) || isinf(result[j]) || isinf(epsabs[j])) {
123 any_NAN_Inf = true;
124 break;
125 }
126 }
127 if(any_NAN_Inf) {
128 self->NEval = *nrun;
129 *nrun = self->MaxPTS + 1979;
130 if(self->LastState>0) self->LastState = -1;
131 if(Verbose>10) cout << ErrColor << " Exit with NaN, LastN=" << self->lastNRUN << RESET << endl;
132 return;
133 }
134
135 bool any_Big = false;
136 for(int j=0; j<self->YDim; j++) {
137 if(epsabs[j] > 1E30*self->EpsAbs) {
138 any_Big = true;
139 break;
140 }
141 }
142 if(any_Big) {
143 self->NEval = *nrun;
144 *nrun = self->MaxPTS + 1979;
145 if(self->LastState>0) self->LastState = -1;
146 if(Verbose>10) cout << WarnColor << " Exit with EpsAbs, LastN=" << self->lastNRUN << RESET << endl;
147 return;
148 }
149
150 bool all_Done = true;
151 for(int j=0; j<self->YDim; j++) {
152 if(epsabs[j] > 2*self->LastAbsErr[j] ) {
153 all_Done = false;
154 break;
155 }
156 }
157 if((self->LastState == 0) || all_Done) {
158 for(int j=0; j<self->YDim; j++) {
159 self->LastResult[j] = result[j];
160 self->LastAbsErr[j] = epsabs[j];
161 }
162 self->LastState = 1;
163 self->lastNRUN = *nrun;
164 self->lastnNAN = self->nNAN;
165 }
166
167 bool bExit = true;
168 for(int j=0; j<self->YDim; j++) {
169 if((epsabs[j] > self->EpsAbs+1E-50Q) && (epsabs[j] > fabs(result[j])*self->EpsRel+1E-50Q)) {
170 bExit = false;
171 break;
172 }
173 }
174 if(bExit && (*nrun)>self->MinPTS) {
175 self->NEval = *nrun;
176 *nrun = self->MaxPTS + 1979;
177 return;
178 }
179
180 auto pid = getpid();
181 ostringstream fn;
182 fn << pid << ".int.done";
183 if(file_exists(fn.str().c_str())) {
184 self->NEval = *nrun;
185 *nrun = self->MaxPTS + 1979;
186 ostringstream cmd;
187 cmd << "rm " << fn.str();
188 auto rc = system(cmd.str().c_str());
189 if(Verbose>10) cout << " Exit: " << fn.str() << endl;
190 }
191 }
192
194 if(LastResult.size()!=YDim) LastResult.resize(YDim);
195 if(LastAbsErr.size()!=YDim) LastAbsErr.resize(YDim);
196 if(mpfr_buildopt_tls_p()<=0) throw Error("Integrate: mpfr_buildopt_tls_p()<=0.");
197 mpfr_free_cache();
198 auto pbit = mpfr::digits2bits(MPDigits);
199 if(mpfr::mpreal::get_default_prec()!=pbit) mpfr::mpreal::set_default_prec(pbit);
200 mpPi = mpfr::const_pi();
201 mpEuler = mpfr::const_euler();
202 mpiEpsilon = complex<mpREAL>(0,mpfr::machine_epsilon()*100);
203
204 unsigned int xdim = XDim;
205 unsigned int ydim = YDim;
206 mpREAL result[ydim], estabs[ydim];
207
208 mpREAL xmin[xdim], xmax[xdim];
209 for(int i=0; i<xdim; i++) {
210 xmin[i] = 0;
211 xmax[i] = 1;
212 }
213 LastState = 0;
214 NEval = 0;
215 nNAN = 0;
216
217 size_t _MinPTS_, _RunPTS_;
218 if(tn==0) {
219 _RunPTS_ = RunPTS;
220 MaxPTS = RunPTS * RunMAX;
221 _MinPTS_ = MinPTS>0 ? MinPTS : _RunPTS_/10;
222 } else {
223 MaxPTS = tn;
224 if(MaxPTS<10000) MaxPTS = 10000;
225 _RunPTS_ = MaxPTS/5;
226 _MinPTS_ = MinPTS>0 ? MinPTS : _RunPTS_/10;
227 }
228 StartTimer = time(NULL);
229 StartTimer = time(NULL);
230
231 Lib3_HCubatureMP::CPUCORES = omp_get_num_procs();
232 int nok = Lib3_HCubatureMP::hcubature_v(ydim, Wrapper, this, xdim, xmin, xmax, _MinPTS_, _RunPTS_, MaxPTS, EpsAbs, EpsRel, result, estabs, tn==0 ? PrintHooker : NULL);
233
234 if(nok) {
235 mpREAL abs_res = 0;
236 for(int j=0; j<ydim; j++) abs_res += result[j]*result[j];
237 abs_res = sqrt(abs_res);
238 mpREAL abs_est = 0;
239 for(int j=0; j<ydim; j++) abs_est += estabs[j]*estabs[j];
240 abs_est = sqrt(abs_est);
241 mpREAL mpfr_eps = 10*mpfr::machine_epsilon();
242 if( (abs_res < mpfr_eps) && (abs_est < mpfr_eps) ) {
243 cout << ErrColor << "HCubatureMP Failed with 0 result returned!" << RESET << endl;
244 return NaN;
245 }
246 }
247
248 if(LastState==-1 && use_last) {
249 for(int j=0; j<ydim; j++) {
250 result[j] = LastResult[j];
251 estabs[j] = LastAbsErr[j];
252 }
253 NEval = lastNRUN;
254 nNAN = lastnNAN;
255 }
256
257 ex FResult = 0;
258 bool any_NAN = false;
259 for(int j=0; j<ydim; j++) {
260 if(isnan(result[j])) {
261 any_NAN = true;
262 break;
263 }
264 }
265 if(any_NAN) FResult = NaN;
266 else {
267 try{
268 if(ydim==2) {
269 FResult = VE(mp2ex(result[0]), mp2ex(estabs[0])) + VE(mp2ex(result[1]), mp2ex(estabs[1])) * I;
270 } else {
271 lst res;
272 for(int j=0; j<ydim; j++) res.append(VE(mp2ex(result[j]), mp2ex(estabs[j])));
273 FResult = res;
274 }
275 } catch(...) {
276 FResult = NaN;
277 }
278 }
279
280 // Check nNAN / NEval
281 if(nNAN * 1000 > NEval && NEval>0) {
282 cout << ErrColor << "NAN=" << nNAN << " v.s. RUN=" << NEval << RESET << endl;
283 }
284
285 return FResult;
286 }
287
288}
#define RESET
Definition BASIC.h:79
complex< mpREAL > mpCOMPLEX
mpfr::mpreal mpREAL
mpREAL mpEuler
Definition SD.h:28
mpCOMPLEX mpiEpsilon
mpREAL mpPi
complex< mpREAL > mpCOMPLEX
Definition HCubature.cpp:20
mpfr::mpreal mpREAL
Definition HCubature.cpp:19
mpREAL mpEuler
Definition SD.h:28
mpCOMPLEX mpiEpsilon
mpREAL mpPi
SecDec header file.
class used to wrap error message
Definition BASIC.h:245
numerical integrator using HCubatureMP
Definition SD.h:210
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:216
mpfr::mpreal mpREAL
Definition SD.h:130
const char * ErrColor
Definition BASIC.cpp:246
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