HepLib
Loading...
Searching...
No Matches
ApartIBP.cpp
Go to the documentation of this file.
1
6#include "HEP.h"
7
8namespace HepLib {
9
10 namespace {
11
12 void AIR2F_Save(string save_dir, exvector air_vec, const lst & IntFs, vector<IBP*> &ibp_vec) {
13 auto rc = system(("mkdir -p "+save_dir+"/AIR2F").c_str());
14 rc = system(("rm -f "+save_dir+"/AIR2F/*.gar > /dev/null").c_str());
15 GiNaC_Parallel(air_vec.size(), [&air_vec,&save_dir](int idx) {
16 garWrite(air_vec[idx], save_dir+"/AIR2F/air-"+to_string(idx)+".gar");
17 return 0;
18 }, "AIR2F_AIR");
19
20 GiNaC_Parallel(ibp_vec.size(), [&ibp_vec,&save_dir](int idx) {
21 garWrite(ibp_vec[idx]->TO(), save_dir+"/AIR2F/ibp-"+to_string(idx)+".gar");
22 return 0;
23 }, "AIR2F_IBP");
24
25 ostringstream oss;
26 oss << air_vec.size() << " " << ibp_vec.size() << " " << IntFs.nops() << endl;
27 if(IntFs.nops()>0) {
28 oss << IntFs.op(0).op(1).nops() << endl;
29 for(auto const & f : IntFs) {
30 oss << f.op(0);
31 for(auto const & n : f.op(1)) oss << " " << n;
32 oss << endl;
33 }
34 }
35 auto oss_str = oss.str();
36 fstream ofs(save_dir+"/AIR2F.gar", fstream::out);
37 ofs.write(oss_str.c_str(), oss_str.size());
38 ofs.close();
39 }
40
41 void AIR2F_Get(string save_dir, exvector &air_vec, lst &IntFs, vector<IBP*> &ibp_vec, int IBPmethod) {
42 fstream ifs(save_dir+"/AIR2F.gar", fstream::in);
43 size_t nair, nibp, nf;
44 ifs >> nair >> nibp >> nf;
45
46 IntFs.remove_all();
47 if(nf>0) {
48 int nn;
49 ifs >> nn;
50 for(int i=0; i<nf; i++) {
51 int pn, ni;
52 ifs >> pn;
53 lst ns;
54 for(int j=0; j<nn; j++) {
55 ifs >> ni;
56 ns.append(ni);
57 }
58 IntFs.append(F(pn, ns));
59 }
60 }
61
62 for(int idx=0; idx<nair; idx++) {
63 air_vec[idx] = garRead(save_dir+"/AIR2F/air-"+to_string(idx)+".gar");
64 }
65
66 ibp_vec.resize(nibp);
67 for(int idx=0; idx<nibp; idx++) {
68 IBP* ibp;
69 if(IBPmethod==0) ibp = new IBP();
70 else if(IBPmethod==1) ibp = new FIRE();
71 else if(IBPmethod==2) ibp = new KIRA();
72 else if(IBPmethod==3) ibp = new UKIRA();
73 else ibp = new IBP();
74 ex ibp_from = garRead(save_dir+"/AIR2F/ibp-"+to_string(idx)+".gar");
75 ibp->FROM(ibp_from);
76 ibp_vec[idx] = ibp;
77 }
78 }
79
80 }
81
87 ex F2ex(const ex & expr_in) {
88 ex ret = expr_in;
89 ret = MapFunction([](const ex & e, MapFunction &self)->ex{
90 if(!e.has(F(w1,w2))) return e;
91 else if(e.match(F(w1, w2))) {
92 auto ps = e.op(0);
93 auto ns = e.op(1);
94 ex res = 1;
95 for(int i=0; i<ps.nops(); i++) res *= pow(ps.op(i), ex(0)-ns.op(i));
96 return res;
97 } else return e.map(self);
98 })(ret);
99 return ret;
100 }
101
109 void ApartIBP(exvector &air_vec, AIOption aio) {
110
111 if(aio.smap.size()<1) aio.init_smap();
112 int IBPmethod = aio.IBPmethod;
113 int rc;
114
115 lst lmom = ex_to<lst>(aio.Internal);
116 lst emom = ex_to<lst>(aio.External);
117
118 if(aio.SaveDir != "" && file_exists(aio.SaveDir+"/ApartIBP.gar")) {
119 if(Verbose > 1) cout << PRE << "\\--Reading ApartIBP" << flush;
120 garRead(air_vec, aio.SaveDir+"/ApartIBP.gar");
121 return;
122 }
123
124 string wdir;
125 if(aio.SaveDir != "") {
126 if(IBPmethod==1) wdir = aio.SaveDir + "/FIRE";
127 else if(IBPmethod==2) wdir = aio.SaveDir + "/KIRA";
128 else if(IBPmethod==3) wdir = aio.SaveDir + "/UKIRA";
129 } else {
130 wdir = to_string(getpid());
131 if(IBPmethod==1) wdir = wdir + "_FIRE";
132 else if(IBPmethod==2) wdir = wdir + "_KIRA";
133 else if(IBPmethod==3) wdir = wdir + "_UKIRA";
134 }
135
136 lst IntFs;
137 vector<IBP*> ibp_vec;
138 if(aio.SaveDir != "" && file_exists(aio.SaveDir+"/AIR2F.gar")) {
139 if(Verbose > 1) cout << PRE << "\\--Reading AIR2F" << flush;
140 AIR2F_Get(aio.SaveDir, air_vec, IntFs, ibp_vec, IBPmethod);
141 for(auto ibp : ibp_vec) ibp->WorkingDir = wdir; // update working directory
142 if(Verbose > 1) cout << " @ " << now(false) << endl;
143 goto AIR2F_Done;
144 }
145
146 if(aio.SaveDir != "") {
147 if(file_exists(aio.SaveDir+"/AP.gar")) {
148 if(Verbose > 1) cout << PRE << "\\--Reading AP.gar" << flush;
149 garRead(air_vec, aio.SaveDir+"/AP.gar");
150 if(Verbose > 1) cout << " @ " << now(false) << endl;
151 goto Apart_Done;
152 } else rc = system(("mkdir -p "+aio.SaveDir).c_str());
153 }
154
155 if(true) {
156 int av_size = air_vec.size();
157 air_vec = GiNaC_Parallel(av_size, [air_vec,lmom] (int idx) {
158 return collect_lst(air_vec[idx], lmom); // o_flint
159 }, "ApPre");
160
161 exset vset;
162 for(int i=0; i<av_size; i++) {
163 for(auto cv : ex_to<lst>(air_vec[i])) vset.insert(cv.op(1));
164 }
165 exvector vvec(vset.begin(), vset.end());
166 vset.clear();
167
168 exmap v2api;
169 for(int i=0; i<vvec.size(); i++) v2api[vvec[i]] = i;
170 for(int i=0; i<av_size; i++) {
171 lst av_item;
172 lst cvs = ex_to<lst>(air_vec[i]);
173 for(auto & cv : cvs) av_item.append(lst{cv.op(0).subs(iEpsilon==0,nopat), v2api[cv.op(1)]}); // set iEpsilon to 0 in coefficients
174 air_vec[i] = av_item;
175 }
176 v2api.clear();
177
178 auto ap_vec = GiNaC_Parallel(vvec.size(), [&vvec,lmom,emom,aio] (int idx) {
179 auto air = vvec[idx];
180 air = Apart(air,lmom,emom,aio.smap);
181 air = air.subs(ApartIR(1,w)==aio.apart1);
182 air = collect_lst(air, ApartIR(w1,w2), o_flintf);
183 return air;
184 }, "Apart");
185 vvec.clear();
186
187 exset ap_set;
188 for(auto cvs : ap_vec) for(auto cv : cvs) if(is_a<matrix>(cv.op(1).op(0))) ap_set.insert(cv.op(1));
189 exvector ap_ir_vec(ap_set.begin(), ap_set.end());
190 ap_set.clear();
191 exmap ap_rules;
192 if(aio.ap_rules) ap_rules = ApartRules(ap_ir_vec); // including ApartIRC
193 ap_ir_vec.clear();
194
195 if(false) { // Parallel Version
196 ap_vec = GiNaC_Parallel(ap_vec.size(), [&aio,&ap_vec,&ap_rules] (int idx) {
197 auto const & cvs = ap_vec[idx];
198 ex res = 0;
199 if(aio.ap_rules) {
200 for(auto const & cv : cvs) {
201 auto fi = ap_rules.find(cv.op(1));
202 if(fi==ap_rules.end()) res += cv.op(0) * cv.op(1);
203 else res += cv.op(0) * fi->second;
204 }
205 } else {
206 for(auto cv : cvs) res += cv.op(0) * ApartIRC(cv.op(1));
207 }
208 return res;
209 }, "ApRule");
210 } else {
211 int vn = ap_vec.size();
212 for(int idx=0; idx<vn; idx++) {
213 lst cvs = ex_to<lst>(ap_vec[idx]);
214 ex res = 0;
215 if(aio.ap_rules) {
216 for(auto const & cv : cvs) {
217 auto fi = ap_rules.find(cv.op(1));
218 if(fi==ap_rules.end()) res += cv.op(0) * cv.op(1);
219 else res += cv.op(0) * fi->second;
220 }
221 } else {
222 for(auto cv : cvs) res += cv.op(0) * ApartIRC(cv.op(1));
223 }
224 ap_vec[idx] = res;
225 }
226 }
227 ap_rules.clear();
228
229 if(GiNaC_Parallel_NP.find("ApPost")==GiNaC_Parallel_NP.end() && CpuCores()>8) GiNaC_Parallel_NP["ApPost"] = 8;
230 if(GiNaC_Parallel_NB.find("ApPost")==GiNaC_Parallel_NB.end() && CpuCores()>100) GiNaC_Parallel_NB["ApPost"] = 100;
231 air_vec = GiNaC_Parallel(av_size, [&air_vec,&ap_vec] (int idx) {
232 lst cvs = ex_to<lst>(air_vec[idx]);
233 ex res = 0;
234 for(auto const & cv : cvs) {
235 int idx = ex_to<numeric>(cv.op(1)).to_int();
236 res += cv.op(0) * ap_vec[idx];
237 }
238 res = collect_ex(res, ApartIR(w1,w2)); // o_flint
239 return res; // air_vec updated to ApartIR
240 }, "ApPost");
241 ap_vec.clear();
242
243 if(aio.SaveDir != "") {
244 garWrite(air_vec,aio.SaveDir+"/AP.gar");
245 garRead(air_vec,aio.SaveDir+"/AP.gar");
246 }
247 }
248 Apart_Done: ;
249
250 if(true) {
251
252 exvector AIR;
253 if(true) {
254 auto ret = GiNaC_Parallel(air_vec.size(), [&air_vec](int idx)->ex {
255 auto air = air_vec[idx];
256 exset airs;
257 find(air, ApartIR(w1,w2), airs);
258 lst ret;
259 for(auto item : airs) ret.append(item);
260 return ret;
261 }, "ApIRC");
262 exset intg;
263 for(auto airs : ret) for(auto air : ex_to<lst>(airs)) intg.insert(air);
264 AIR = exvector(intg.begin(), intg.end());
265 }
266
267 for(auto sp : aio.CSP) SP_map.erase(sp);
268 // from here, Vector will be replaced by its name Symbol
269
270 lst repls;
271 auto sps = sp_map();
272 for(auto kv : sps) {
273 repls.append(w*kv.first == w*kv.second);
274 repls.append(kv.first == kv.second);
275 }
276
277 lst loops, exts; // to match FIRE notation, not Vector, just Symbol
278 for(auto li : lmom) {
279 if(is_a<Vector>(li)) loops.append(ex_to<Vector>(li).name);
280 else loops.append(li);
281 }
282 for(auto li : emom) {
283 if(is_a<Vector>(li)) exts.append(ex_to<Vector>(li).name);
284 else exts.append(li);
285 }
286
287 if(Verbose>0) cout << PRE << "\\--Prepare " << WHITE << "IBP" << RESET << " reduction @ " << now(false) << flush;
288
289 exmap AIR2F;
290 std::map<ex, IBP*, ex_is_less> p2IBP;
291 int pn=1;
292 int ntot = AIR.size();
293 for(int i=0; i<ntot; i++) {
294 if(Verbose>0 && (((i+1)%1000)==0 || i+1==ntot)) {
295 cout << "\r \r" << flush;
296 cout << PRE << "\\--Prepare " << WHITE << "IBP" << RESET << " reduction [" << (i+1) << "/" << ntot << "] @ " << now(false) << flush;
297 }
298 auto const & ir = AIR[i];
299 auto mat = ex_to<matrix>(ir.op(0));
300 auto vars = ex_to<lst>(ir.op(1));
301 lst pns;
302 int nrow = mat.rows();
303 int den_tot = 0;
304 for(int c=0; c<mat.cols(); c++) {
305 ex pc = 0;
306 for(int r=0; r<nrow-2; r++) pc += mat(r,c) * vars.op(r);
307 pc += mat(nrow-2,c);
308 pc = SP2sp(pc);
309 ex nc = ex(0)-mat(nrow-1,c);
310 int ncn;
311 if(nc>0) ncn = -1;
312 else ncn = 1;
313 if(ncn==-1) den_tot++;
314 pns.append(lst{ ncn, pc, nc }); // note the convension, ncn just for sorting
315 }
316 bool pn_sector = false;
317 if(aio.pn_sector>0 && den_tot>=aio.pn_sector) pn_sector = true;
318 if(!pn_sector) { // back to original format
319 for(int i=0; i<pns.nops(); i++) pns[i] = lst{ pns.op(i).op(1), pns.op(i).op(2) };
320 }
321 sort_lst(pns);
322 if(pn_sector) { // back to original format
323 for(int i=0; i<pns.nops(); i++) pns[i] = lst{ pns.op(i).op(1), pns.op(i).op(2) };
324 }
325
326 int nCut = aio.Cut.nops();
327 if(nCut>0) {
328 ex cuts = aio.Cut;
329 cuts = cuts.subs(SP_map,nopat);
330 if(aio.CutFirst) for(auto cut : cuts) pns.prepend(lst{ SP2sp(cut), 1 });
331 else for(auto cut : cuts) pns.append(lst{ SP2sp(cut), 1 });
332 }
333
334 lst props, ns;
335 for(auto item : pns) {
336 props.append(item.op(0));
337 ns.append(item.op(1));
338 }
339
340 ex key = props;
341 if(pn_sector) {
342 lst nss;
343 for(int i=0; i<ns.nops(); i++) nss.append(ns.op(i)>0 ? 1 : 0);
344 key = lst{props,nss};
345 }
346
347 auto kv = p2IBP.find(key);
348 if(kv==p2IBP.end()) {
349 IBP* ibp;
350 if(IBPmethod==0) ibp = new IBP();
351 else if(IBPmethod==1) ibp = new FIRE();
352 else if(IBPmethod==2) ibp = new KIRA();
353 else if(IBPmethod==3) ibp = new UKIRA();
354 else {
355 ibp = new IBP();
356 IBPmethod = 0;
357 }
358
359 p2IBP.insert(make_pair(key,ibp));
360 ibp->Propagator = props;
361 ibp->Internal = loops;
362 ibp->External = exts;
363 ibp->Replacement = repls;
364 if(aio.ISP.nops()>0) for(auto item : aio.ISP) ibp->ISP.append(SP2sp(item));
365 if(aio.DSP.nops()>0) {
366 for(auto item : aio.DSP) {
367 lst sp = ex_to<lst>(item);
368 if(is_a<Vector>(sp.op(0))) sp[0] = (ex_to<Vector>(sp.op(0)).name);
369 if(is_a<Vector>(sp.op(1))) sp[1] = (ex_to<Vector>(sp.op(1)).name);
370 ibp->DSP.append(sp);
371 }
372 }
373 if(pn_sector) {
374 lst sector;
375 for(auto const & item : ns) {
376 if(item>0) sector.append(1);
377 else sector.append(0);
378 }
379 ibp->SECTOR = sector;
380 }
381 ibp->WorkingDir = wdir;
382 ibp->ProblemNumber = pn;
383 pn++;
384 if(nCut>0) {
385 if(aio.CutFirst) for(int i=0; i<nCut; i++) ibp->Cut.append(i+1);
386 else for(int i=0; i<nCut; i++) ibp->Cut.append(nCut-i);
387 }
388 ibp_vec.push_back(ibp);
389 ibp->Integral.append(ns);
390 AIR2F[AIR[i]] = F(ibp->ProblemNumber, ns);
391 } else {
392 IBP* ibp = kv->second;
393 ibp->Integral.append(ns);
394 AIR2F[AIR[i]] = F(ibp->ProblemNumber, ns);
395 }
396 }
397 if(Verbose>0) cout << endl;
398
399 if(Verbose>0) cout << PRE << "\\--Total Ints/Pros: " << WHITE << ntot << "/" << ibp_vec.size() << RESET << " @ " << now(false) << endl;
400
401 if(true) {
402 //vector<IBP*> ibp_vec2;
403 //for(auto ibp : ibp_vec) ibp_vec2.push_back(ibp);
404 auto int_fr = FindRules(ibp_vec, false, aio.UF);
405 IntFs = int_fr.second;
406 if(GiNaC_Parallel_NP.find("AIR2F")==GiNaC_Parallel_NP.end() && CpuCores()>8) GiNaC_Parallel_NP["AIR2F"] = 8;
407 if(GiNaC_Parallel_NB.find("AIR2F")==GiNaC_Parallel_NB.end() && CpuCores()>100) GiNaC_Parallel_NB["AIR2F"] = 100;
408 air_vec = GiNaC_Parallel(air_vec.size(), [&air_vec,&AIR2F,&int_fr] (int idx) {
409 auto air = air_vec[idx];
410 air = air.subs(AIR2F,nopat);
411 air = air.subs(int_fr.first,nopat);
412 air = collect_ex(air, F(w1,w2)); // o_flint
413 return air;
414 }, "AIR2F");
415 if(aio.SaveDir != "") AIR2F_Save(aio.SaveDir, air_vec, IntFs, ibp_vec);
416 }
417 }
418 AIR2F_Done: ;
419
420 MapFunction _F2ex([&ibp_vec,aio](const ex &e, MapFunction &self)->ex {
421 if(!e.has(F(w1,w2))) return e;
422 else if(e.match(F(w1,w2))) {
423 int pn = ex_to<numeric>(e.op(0)).to_int();
424 auto pso = ex_to<lst>(ibp_vec[pn-1]->Propagator);
425 auto nso = ex_to<lst>(e.op(1));
426 lst ps, ns;
427 for(int i=0; i<pso.nops(); i++) {
428 if(!aio.keep0F && nso.op(i).is_zero()) continue;
429 ps.append(pso.op(i));
430 ns.append(nso.op(i));
431 }
432 return F(ps,ns);
433 } else return e.map(self);
434 });
435
436 if(IBPmethod==0) { // no IBP reduction
437 air_vec = GiNaC_Parallel(air_vec.size(), [&air_vec,&_F2ex](int idx)->ex {
438 auto res = air_vec[idx];
439 return _F2ex(res);
440 }, "F2F");
441 for(auto fp : ibp_vec) delete fp;
442 if(aio.SaveDir == "") rc = system(("rm -rf "+wdir).c_str());
443 return;
444 }
445
446 exmap ibpRules; // IBP rules for problem pn
447 if(aio.SaveDir != "" && file_exists(aio.SaveDir+"/MIs.gar")) {
448 goto Rules_Done;
449 }
450 if(true) {
451 vector<IBP*> ibp_vec_re;
452 if(true) {
453 map<int,lst> pn_ints_map;
454 for(auto item : IntFs) {
455 int pn = ex_to<numeric>(item.op(0)).to_int();
456 pn_ints_map[pn].append(item.op(1));
457 }
458
459 int nints = 0;
460 for(auto pi : pn_ints_map) {
461 auto ibp = ibp_vec[pi.first-1];
462 ibp->Integral = pi.second;
463 nints += ibp->Integral.nops();
464 ibp_vec_re.push_back(ibp);
465 }
466
467 if(Verbose>0) cout << PRE << "\\--Refined Ints/Pros: " << WHITE << nints << "/" << ibp_vec_re.size() << RESET << " @ " << now(false) << endl;
468 }
469
470 if(IBPmethod==1) {
471 //if(GiNaC_Parallel_NB.find("Expo")==GiNaC_Parallel_NB.end()) GiNaC_Parallel_NB["Expo"] = 1;
472 auto pRes = GiNaC_Parallel(ibp_vec_re.size(), [&ibp_vec_re](int idx)->ex {
473 ibp_vec_re[idx]->Export();
474 auto ret = lst{ ibp_vec_re[idx]->IsAlwaysZero ? 1 : 0, ibp_vec_re[idx]->Rules };
475 return ret;
476 }, "Expo");
477 for(int i=0; i<ibp_vec_re.size(); i++) {
478 ibp_vec_re[i]->IsAlwaysZero = (pRes[i].op(0)==1 ? true : false);
479 ibp_vec_re[i]->Rules = ex_to<lst>(pRes[i].op(1));
480 }
481
482 int nproc = aio.NIBP;
483 if(nproc<1) nproc = 8;
484 int cproc = 0;
485 if(nproc<1) nproc = 1;
486 size_t nibp = ibp_vec_re.size();
487
488 //#define using_openMP
489 #ifdef using_openMP
490 #pragma omp parallel for num_threads(nproc) schedule(dynamic, 1)
491 for(int pi=0; pi<nibp; pi++) {
492 if(Verbose>1) {
493 #pragma omp critical
494 {
495 cout << "\r \r" << flush;
496 cout << PRE << "\\--" << WHITE << "FIRE" << RESET << " Reduction [" << (++cproc) << "/" << nibp << "] " << flush;
497 }
498 }
499 ibp_vec_re[pi]->Run();
500 }
501 if(Verbose>1 && nibp>0) cout << "@" << now(false) << endl;
502 #else
503 if(nproc>1) {
504 if(GiNaC_Parallel_NP.find("FIRE")==GiNaC_Parallel_NB.end()) GiNaC_Parallel_NP["FIRE"] = nproc;
505 if(GiNaC_Parallel_NB.find("FIRE")==GiNaC_Parallel_NB.end()) GiNaC_Parallel_NB["FIRE"] = 1;
506 GiNaC_Parallel(nibp, [&ibp_vec_re](int idx)->ex {
507 ibp_vec_re[idx]->Run();
508 return 0;
509 }, "FIRE");
510 } else {
511 for(int pi=0; pi<nibp; pi++) {
512 if(Verbose>1) cout << "\r \r" << PRE << "\\--" << WHITE << "FIRE" << RESET << " Reduction [" << (++cproc) << "/" << nibp << "] " << flush;
513 ibp_vec_re[pi]->Run();
514 }
515 if(Verbose>1 && nibp>0) cout << "@" << now(false) << endl;
516 }
517 #endif
518
519 if(ibp_vec_re.size()>100) {
520 auto ret = GiNaC_Parallel(ibp_vec_re.size(), [&ibp_vec_re,wdir](int idx)->ex {
521 ibp_vec_re[idx]->Import();
522 return ibp_vec_re[idx]->TO();
523 }, "Impo");
524 for(int i=0; i<ibp_vec_re.size(); i++) ibp_vec_re[i]->FROM(ret[i]);
525 } else {
526 cproc = 0;
527 for(auto item : ibp_vec_re) {
528 if(Verbose>1) cout << "\r \r" << PRE << "\\--" << WHITE << "FIRE" << RESET << " Import [" << (++cproc) << "/" << ibp_vec_re.size() << "] " << flush;
529 item->Import();
530 }
531 if(Verbose>1 && ibp_vec_re.size()>0) cout << "@" << now(false) << endl;
532 }
533 //IBP::ReShare(ibp_vec_re);
534
535 if(aio.SaveDir == "") rc = system(("rm -rf "+wdir).c_str());
536 } else if(IBPmethod==2 || IBPmethod==3) {
537 for(auto ibp : ibp_vec_re) ibp->Reduce();
538 if(aio.SaveDir == "") rc = system(("rm -rf "+wdir).c_str());
539 }
540
541 // Find Rules in MIs
542 auto fr = FindRules(ibp_vec_re, true, aio.UF);
543 exmap miRules = fr.first;
544 if(true) { // scope for ret
545 if(aio.SaveDir != "") rc = system(("mkdir -p "+aio.SaveDir+"/Rules").c_str());
546 auto rules_vec = GiNaC_Parallel(ibp_vec_re.size(), [&ibp_vec_re,&miRules,&aio](int idx)->ex {
547 lst rules = ex_to<lst>(ibp_vec_re[idx]->Rules);
548 lst res;
549 for(auto ri : rules) res.append(lst {
550 ri.op(0),
551 collect_ex(ri.op(1).subs(miRules,nopat),F(w1,w2),o_flint)
552 });
553 for(auto mi : ibp_vec_re[idx]->MIntegral) {
554 auto fi = miRules.find(mi);
555 if(fi!=miRules.end()) res.append(lst{ mi, fi->second });
556 }
557 auto pn = ibp_vec_re[idx]->ProblemNumber;
558 if(aio.SaveDir != "") {
559 garWrite(aio.SaveDir+"/Rules/"+to_string(pn)+".gar", res);
560 return 0;
561 } else return res;
562 }, "FR2MI");
563 if(aio.SaveDir != "") {
564 garWrite(aio.SaveDir+"/MIs.gar", _F2ex(fr.second));
565 } else {
566 for(auto rs : rules_vec) {
567 for(auto ri : rs) if(ri.op(0)!=ri.op(1)) ibpRules[ri.op(0)] = ri.op(1);
568 }
569 }
570 }
571 }
572 Rules_Done: ;
573
574 if(GiNaC_Parallel_NP.find("F2MI")==GiNaC_Parallel_NP.end() && CpuCores()>16) GiNaC_Parallel_NP["F2MI"] = 16;
575 air_vec =
576 GiNaC_Parallel(air_vec.size(), [&air_vec,&ibpRules,&_F2ex,&aio](int idx)->ex {
577 ex res = air_vec[idx];
578 exmap rules;
579 if(aio.SaveDir != "") {
580 exset fs;
581 find(res, F(w1,w2), fs);
582 exset pns;
583 for(auto fi : fs) pns.insert(fi.op(0));
584 for(auto pn : pns) {
585 auto rs = ex_to<lst>(garRead(aio.SaveDir+"/Rules/"+ex2str(pn)+".gar"));
586 for(auto ri : rs) if(ri.op(0)!=ri.op(1)) rules[ri.op(0)] = ri.op(1);
587 }
588 } else rules = ibpRules;
589 res = res.subs(rules,nopat);
590 if(aio.pat.nops()>0) {
591 auto cvs = collect_lst(res, aio.pat);
592 res = 0;
593 for(auto cv : cvs) {
594 auto c = cv.op(0);
595 auto v = cv.op(1);
596 if(aio.cv!=nullptr) {
597 auto _cv = aio.cv(c,v);
598 c = _cv.op(0);
599 v = _cv.op(1);
600 }
601 res += c * v;
602 }
603 }
604 return _F2ex(res);
605 }, "F2MI");
606
607 for(auto fp : ibp_vec) delete fp;
608
609 if(aio.SaveDir != "") garWrite(air_vec, aio.SaveDir+"/ApartIBP.gar");
610 }
611
622 void ApartIBP(exvector &air_vec, int IBPmethod, const lst & loops, const lst & exts, const lst & cut_props,
623 std::function<lst(const IBP &, const ex &)> uf) {
624
625 AIOption aio;
626 aio.IBPmethod = IBPmethod;
627 //aio.pn_sector = 4;
628 aio.Internal = loops;
629 aio.External = exts;
630 aio.Cut = cut_props;
631 if(cut_props.nops()>0) {
632 for(auto p1 : loops) {
633 for(auto p2 : loops) aio.CSP.append(SP(p1,p2,false));
634 for(auto p2 : exts) aio.CSP.append(SP(p1,p2,false));
635 }
636 aio.CSP.sort();
637 aio.CSP.unique();
638 }
639 for(auto li : loops) aio.smap[SP(li,false)] = 1;
640 aio.UF = uf;
641 ApartIBP(air_vec, aio);
642 }
643
644}
#define WHITE
Definition BASIC.h:87
#define RESET
Definition BASIC.h:79
HEP header file.
int pn
Definition Others.cpp:25
lst intg
Definition Others.cpp:26
bool file_exists(const char *fn)
Definition Process.cpp:9
IBP base class for IBP reduction.
Definition IBP.h:24
class to wrap map_function of GiNaC
Definition BASIC.h:679
HepLib namespace.
Definition BASIC.cpp:17
ex SP2sp(const ex &exin)
convert SP(a,b) to sp(a,b)
Definition Pair.cpp:302
const iSymbol iEpsilon
ex sp(const ex &a, const ex &b)
translated the vector dot a.b to a*b, useful in SecDec
Definition Pair.cpp:237
exmap sp_map()
the SP_map with SP(a,b) replaced to sp(a,b)
Definition Pair.cpp:318
exmap SP_map
Definition Init.cpp:188
ex ApartIRC(const ex &expr_in)
complete the ApartIR elements
Definition Apart.cpp:915
void ApartIBP(exvector &air_vec, AIOption aio)
perform IBP reduction on the Aparted input
Definition ApartIBP.cpp:109
ex collect_ex(ex const &expr_in, std::function< bool(const ex &)> has_func, int opt)
the collect function like Mathematica
Definition BASIC.cpp:1203
void garRead(const string &garfn, map< string, ex > &resMap)
garRead from file, and output in a map
Definition BASIC.cpp:592
map< string, int > GiNaC_Parallel_NB
Definition Init.cpp:154
bool file_exists(string fn)
Definition BASIC.h:292
pair< exmap, lst > FindRules(vector< IBP * > fs, bool mi, std::function< lst(const IBP &, const ex &)> uf)
Find Rules for Integral or Master Integral.
Definition IBP.cpp:574
string now(bool use_date)
date/time string
Definition BASIC.cpp:526
ex F2ex(const ex &expr_in)
convert F(ps, ns) to normal ex, ns is like FIRE convention
Definition ApartIBP.cpp:87
int CpuCores()
return the cpu cores using OpenMP
Definition BASIC.cpp:1821
map< string, int > GiNaC_Parallel_NP
Definition Init.cpp:151
lst collect_lst(ex const &expr_in, std::function< bool(const ex &)> has_func, int opt)
the collect function like Mathematica, reture the lst { {c1,v1}, {c2,v2}, ... }
Definition BASIC.cpp:1223
exmap ApartRules(const exvector &airs, bool irc)
Definition Apart.cpp:156
int Verbose
Definition Init.cpp:145
void sort_lst(lst &ilst, bool less=true)
sort the list in less order, or the reverse
Definition Sort.cpp:79
void garWrite(const string &garfn, const map< string, ex > &resMap)
garWrite to write the string-key map to the archive
Definition BASIC.cpp:640
ex w1
Definition BASIC.h:503
unsigned nopat
Definition Init.cpp:91
ex SP(const ex &a, bool use_map=true)
Definition Pair.cpp:166
exvector GiNaC_Parallel(int ntotal, std::function< ex(int)> f, const string &key)
GiNaC Parallel Evaluation using fork.
Definition BASIC.cpp:259
ex w2
Definition BASIC.h:503
string PRE
Definition Init.cpp:146
std::function< lst(const IBP &, const ex &)> UF
Definition HEP.h:620
exmap smap
Definition HEP.h:609
string SaveDir
Definition HEP.h:619
int IBPmethod
Definition HEP.h:605
bool ap_rules
Definition HEP.h:604
void init_smap()
Definition HEP.h:621