22 #include "Lib3_HCubatureMP.h"
25 ex HCubatureMP::mp2ex(
const mpREAL & num) {
27 oss.precision(MPDigits);
29 string sn = oss.str();
30 numeric ret(sn.c_str());
34 int HCubatureMP::Wrapper(
unsigned int xdim,
size_t npts,
const mpREAL *x,
void *fdata,
unsigned int ydim,
mpREAL *y) {
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++) {
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);
46 for(
int j=0; j<ydim; j++) {
48 if(isnan(ytmp) || isinf(ytmp)) { ok =
false;
break; }
50 if(!ok && (self->IntegrandMP!=NULL)) {
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));
58 for(
int j=0; j<ydim; j++) {
60 if(isnan(ytmp) || isinf(ytmp)) {
63 if(self->nNAN > self->NANMax) { NaNQ =
true;
break; }
67 if(self->ReIm == 1) y[i*ydim+1] = 0;
68 else if(self->ReIm == 2) y[i*ydim+0] = 0;
75 void HCubatureMP::DefaultPrintHooker(
mpREAL* result,
mpREAL* epsabs,
size_t * nrun,
void *fdata) {
77 if(*nrun == self->MaxPTS + 1979)
return;
79 auto cur_timer = time(NULL);
80 auto used_time = difftime(cur_timer,self->StartTimer);
81 if(used_time>self->RunTime) {
83 *nrun =
self->MaxPTS + 1979;
88 if(
Verbose>10 && (*nrun-self->NEval) >= self->RunPTS) {
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 <<
"]";
98 if((*nrun-self->NEval) >= self->RunPTS)
self->NEval = *nrun;
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]))) {
102 *nrun =
self->MaxPTS + 1979;
103 if(self->LastState>0)
self->LastState = -1;
108 if(epsabs[0] > 1E30*self->EpsAbs || epsabs[1] > 1E30*self->EpsAbs) {
110 *nrun =
self->MaxPTS + 1979;
111 if(self->LastState>0)
self->LastState = -1;
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];
122 self->lastNRUN = *nrun;
123 self->lastnNAN =
self->nNAN;
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) {
130 *nrun =
self->MaxPTS + 1979;
136 fn << pid <<
".int.done";
139 *nrun =
self->MaxPTS + 1979;
141 cmd <<
"rm " << fn.str();
142 auto rc = system(cmd.str().c_str());
143 if(
Verbose>10) cout <<
" Exit: " << fn.str() << endl;
147 ex HCubatureMP::Integrate(
size_t tn) {
148 if(mpfr_buildopt_tls_p()<=0)
throw Error(
"Integrate: mpfr_buildopt_tls_p()<=0.");
150 mpfr::mpreal::set_default_prec(mpfr::digits2bits(MPDigits));
151 mpPi = mpfr::const_pi();
153 mpiEpsilon = complex<mpREAL>(0,mpfr::machine_epsilon()*100);
155 unsigned int xdim = XDim;
156 unsigned int ydim = 2;
157 mpREAL result[ydim], estabs[ydim];
159 mpREAL xmin[xdim], xmax[xdim];
160 for(
int i=0; i<xdim; i++) {
168 size_t _MinPTS_, _RunPTS_;
171 MaxPTS = RunPTS * RunMAX;
172 _MinPTS_ = MinPTS>0 ? MinPTS : _RunPTS_/10;
175 if(MaxPTS<10000) MaxPTS = 10000;
177 _MinPTS_ = MinPTS>0 ? MinPTS : _RunPTS_/10;
179 StartTimer = time(NULL);
180 StartTimer = time(NULL);
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);
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;
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];
205 if(isnan(result[0]) || isnan(result[1])) FResult +=
NaN;
208 FResult += VE(mp2ex(result[0]), mp2ex(estabs[0]));
209 FResult += VE(mp2ex(result[1]), mp2ex(estabs[1])) * I;
216 if(nNAN * 1000 > NEval && NEval>0) {
217 cout <<
ErrColor <<
"NAN=" << nNAN <<
" v.s. RUN=" << NEval <<
RESET << endl;
complex< mpREAL > mpCOMPLEX
complex< mpREAL > mpCOMPLEX
bool file_exists(const char *fn)
class used to wrap error message
numerical integrator using HCubatureMP
namespace for Numerical integration with Sector Decomposition method