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 auto pbit = mpfr::digits2bits(self->MPDigits);
43 if(mpfr::mpreal::get_default_prec()!=pbit) mpfr::mpreal::set_default_prec(pbit);
44 int iDQMP = self->XDQMP(x+i*xdim);
45 if( (self->IntegrandMP!=NULL) && (self->DQMP>2 || iDQMP>2) ) {
46 mpREAL mpx[xdim], mpy[ydim];
47 for(
int j=0; j<xdim; j++) mpx[j] = x[i*xdim+j];
48 self->IntegrandMP(xdim, mpx, ydim, mpy, self->mpParameter, self->mpLambda);
49 for(
int j=0; j<ydim; j++) y[i*ydim+j] = mpy[j].toFloat128();
50 }
else if(self->DQMP>1 || iDQMP>1) {
51 self->IntegrandQ(xdim, x+i*xdim, ydim, y+i*ydim, self->qParameter, self->qLambda);
53 for(
int j=0; j<ydim; j++) {
54 qREAL ytmp = y[i*ydim+j];
55 if(isnanq(ytmp) || isinfq(ytmp)) { ok =
false;
break; }
58 if(!ok && (self->IntegrandMP!=NULL)) {
59 mpREAL mpx[xdim], mpy[ydim];
60 for(
int j=0; j<xdim; j++) mpx[j] = x[i*xdim+j];
61 self->IntegrandMP(xdim, mpx, ydim, mpy, self->mpParameter, self->mpLambda);
62 for(
int j=0; j<ydim; j++) y[i*ydim+j] = mpy[j].toFloat128();
65 dREAL dx[xdim], dy[ydim];
66 for(
int j=0; j<xdim; j++) dx[j] = (
dREAL)x[i*xdim+j];
67 self->IntegrandD(xdim, dx, ydim, dy, self->dParameter, self->dLambda);
68 for(
int j=0; j<ydim; j++) y[i*ydim+j] = dy[j];
70 for(
int j=0; j<ydim; j++) {
71 qREAL ytmp = y[i*ydim+j];
72 if(isnanq(ytmp) || isinfq(ytmp)) { ok =
false;
break; }
75 if(!ok) self->IntegrandQ(xdim, x+i*xdim, ydim, y+i*ydim, self->qParameter, self->qLambda);
78 for(
int j=0; j<ydim; j++) {
79 qREAL ytmp = y[i*ydim+j];
80 if(isnanq(ytmp) || isinfq(ytmp)) { ok =
false;
break; }
82 if(!ok && (self->IntegrandMP!=NULL)) {
83 mpREAL mpx[xdim], mpy[ydim];
84 for(
int j=0; j<xdim; j++) mpx[j] = x[i*xdim+j];
85 self->IntegrandMP(xdim, mpx, ydim, mpy, self->mpParameter, self->mpLambda);
86 for(
int j=0; j<ydim; j++) y[i*ydim+j] = mpy[j].toFloat128();
92 for(
int j=0; j<ydim; j++) {
93 qREAL ytmp = y[i*ydim+j];
94 if(isnanq(ytmp) || isinfq(ytmp)) { ok =
false;
break; }
96 if(!ok && (self->IntegrandMP!=NULL)) {
98 auto pbit = mpfr::digits2bits(self->MPDigits*10);
99 if(mpfr::mpreal::get_default_prec()!=pbit) mpfr::mpreal::set_default_prec(pbit);
100 mpREAL mpx[xdim], mpy[ydim];
101 for(
int j=0; j<xdim; j++) mpx[j] = x[i*xdim+j];
102 self->IntegrandMP(xdim, mpx, ydim, mpy, self->mpParameter, self->mpLambda);
103 for(
int j=0; j<ydim; j++) y[i*ydim+j] = mpy[j].toFloat128();
104 pbit = mpfr::digits2bits(self->MPDigits);
105 if(mpfr::mpreal::get_default_prec()!=pbit) mpfr::mpreal::set_default_prec(pbit);
109 for(
int j=0; j<ydim; j++) {
110 qREAL ytmp = y[i*ydim+j];
111 if(isnanq(ytmp) || isinfq(ytmp)) {
114 if(self->nNAN > self->NANMax) { NaNQ =
true;
break; }
115 else y[i*ydim+j] = 0;
119 if(self->ReIm == 1) y[i*ydim+1] = 0;
120 else if(self->ReIm == 2) y[i*ydim+0] = 0;
130 if(*nrun == self->MaxPTS + 1979)
return;
131 if(self->RunTime>0) {
132 auto cur_timer = time(NULL);
133 auto used_time = difftime(cur_timer,self->StartTimer);
134 if(used_time>self->RunTime) {
136 *nrun = self->MaxPTS + 1979;
142 if((*nrun-self->NEval) >= self->RunPTS) {
145 char r0[64], r1[64], e0[32], e1[32];
146 quadmath_snprintf(r0,
sizeof r0,
"%.10QG", result[0]);
147 quadmath_snprintf(r1,
sizeof r1,
"%.10QG", result[1]);
148 quadmath_snprintf(e0,
sizeof e0,
"%.5QG", epsabs[0]);
149 quadmath_snprintf(e1,
sizeof e1,
"%.5QG", epsabs[1]);
150 cout <<
" N: " << (*nrun) <<
", ";
151 if(self->ReIm==3 || self->ReIm==1) cout <<
"[" << r0 <<
", " << e0 <<
"]";
152 if(self->ReIm==3 || self->ReIm==2) cout <<
"+I*[" << r1 <<
", " << e1 <<
"]";
155 for(
int j=0; j<self->YDim; j++) {
157 quadmath_snprintf(r,
sizeof r,
"%.10QG", result[j]);
158 quadmath_snprintf(e,
sizeof e,
"%.5QG", epsabs[j]);
159 if(j==0) cout <<
" N: " << (*nrun) <<
", ";
162 int ct = to_string(*nrun).length();
163 for(
int k=0; k<ct; k++) cout <<
" ";
165 cout <<
"[" << r <<
", " << e <<
"]";
173 bool any_NAN_Inf =
false;
174 for(
int j=0; j<self->YDim; j++) {
175 if(isnanq(result[j]) || isnanq(epsabs[j]) || isinfq(result[j]) || isinfq(epsabs[j])) {
182 *nrun = self->MaxPTS + 1979;
183 if(self->LastState>0) self->LastState = -1;
188 bool any_Big =
false;
189 for(
int j=0; j<self->YDim; j++) {
190 if(epsabs[j] > 1E30*self->EpsAbs) {
197 *nrun = self->MaxPTS + 1979;
198 if(self->LastState>0) self->LastState = -1;
203 bool all_Done =
true;
204 for(
int j=0; j<self->YDim; j++) {
205 if(epsabs[j] > 2*self->LastAbsErr[j] ) {
210 if((self->LastState == 0) || all_Done) {
211 for(
int j=0; j<self->YDim; j++) {
212 self->LastResult[j] = result[j];
213 self->LastAbsErr[j] = epsabs[j];
216 self->lastNRUN = *nrun;
217 self->lastnNAN = self->nNAN;
221 for(
int j=0; j<self->YDim; j++) {
222 if((epsabs[j] > self->EpsAbs+1E-50Q) && (epsabs[j] > fabsq(result[j])*self->EpsRel+1E-50Q)) {
227 if(bExit && (*nrun)>self->MinPTS) {
229 *nrun = self->MaxPTS + 1979;
235 fn << pid <<
".int.done";
238 *nrun = self->MaxPTS + 1979;
240 cmd <<
"rm " << fn.str();
241 auto rc = system(cmd.str().c_str());
242 if(
Verbose>10) cout <<
" Exit: " << fn.str() << endl;
247 if(LastResult.size()!=
YDim) LastResult.resize(
YDim);
248 if(LastAbsErr.size()!=
YDim) LastAbsErr.resize(
YDim);
249 if(mpfr_buildopt_tls_p()<=0)
throw Error(
"Integrate: mpfr_buildopt_tls_p()<=0.");
251 auto pbit = mpfr::digits2bits(
MPDigits);
252 if(mpfr::mpreal::get_default_prec()!=pbit) mpfr::mpreal::set_default_prec(pbit);
253 mpPi = mpfr::const_pi();
255 mpiEpsilon = complex<mpREAL>(0,mpfr::machine_epsilon()*100);
257 unsigned int xdim =
XDim;
258 unsigned int ydim =
YDim;
259 qREAL result[ydim], estabs[ydim];
261 qREAL xmin[xdim], xmax[xdim];
262 for(
int i=0; i<xdim; i++) {
270 size_t _MinPTS_, _RunPTS_;
283 int nok = hcubature_v(ydim,
Wrapper,
this, xdim, xmin, xmax, _MinPTS_, _RunPTS_,
MaxPTS,
EpsAbs,
EpsRel, result, estabs, tn==0 ?
PrintHooker : NULL);
287 for(
int j=0; j<ydim; j++) abs_res += result[j]*result[j];
288 abs_res = sqrtq(abs_res);
290 for(
int j=0; j<ydim; j++) abs_est += estabs[j]*estabs[j];
291 abs_est = sqrtq(abs_est);
292 qREAL flt128_eps = 10*FLT128_EPSILON;
294 if( (abs_res < flt128_eps) && (abs_est < flt128_eps) ) {
295 cout <<
ErrColor <<
"HCubature Failed with 0 result returned!" <<
RESET << endl;
301 for(
int j=0; j<ydim; j++) {
302 result[j] = LastResult[j];
303 estabs[j] = LastAbsErr[j];
310 bool any_NAN =
false;
311 for(
int j=0; j<ydim; j++) {
312 if(isnanq(result[j])) {
317 if(any_NAN) FResult =
NaN;
321 FResult = VE(
q2ex(result[0]),
q2ex(estabs[0])) + VE(
q2ex(result[1]),
q2ex(estabs[1])) * I;
324 for(
int j=0; j<ydim; j++) res.append(VE(
q2ex(result[j]),
q2ex(estabs[j])));