13 unsigned long long HardCodedPrimes[128] = {
14 2017llu, 18446744073709551557llu, 18446744073709551533llu,
15 18446744073709551521llu, 18446744073709551437llu, 18446744073709551427llu,
16 18446744073709551359llu, 18446744073709551337llu, 18446744073709551293llu,
17 18446744073709551263llu, 18446744073709551253llu, 18446744073709551191llu,
18 18446744073709551163llu, 18446744073709551113llu, 18446744073709550873llu,
19 18446744073709550791llu, 18446744073709550773llu, 18446744073709550771llu,
20 18446744073709550719llu, 18446744073709550717llu, 18446744073709550681llu,
21 18446744073709550671llu, 18446744073709550593llu, 18446744073709550591llu,
22 18446744073709550539llu, 18446744073709550537llu, 18446744073709550381llu,
23 18446744073709550341llu, 18446744073709550293llu, 18446744073709550237llu,
24 18446744073709550147llu, 18446744073709550141llu, 18446744073709550129llu,
25 18446744073709550111llu, 18446744073709550099llu, 18446744073709550047llu,
26 18446744073709550033llu, 18446744073709550009llu, 18446744073709549951llu,
27 18446744073709549861llu, 18446744073709549817llu, 18446744073709549811llu,
28 18446744073709549777llu, 18446744073709549757llu, 18446744073709549733llu,
29 18446744073709549667llu, 18446744073709549621llu, 18446744073709549613llu,
30 18446744073709549583llu, 18446744073709549571llu, 18446744073709549519llu,
31 18446744073709549483llu, 18446744073709549441llu, 18446744073709549363llu,
32 18446744073709549331llu, 18446744073709549327llu, 18446744073709549307llu,
33 18446744073709549237llu, 18446744073709549153llu, 18446744073709549123llu,
34 18446744073709549067llu, 18446744073709549061llu, 18446744073709549019llu,
35 18446744073709548983llu, 18446744073709548899llu, 18446744073709548887llu,
36 18446744073709548859llu, 18446744073709548847llu, 18446744073709548809llu,
37 18446744073709548703llu, 18446744073709548599llu, 18446744073709548587llu,
38 18446744073709548557llu, 18446744073709548511llu, 18446744073709548503llu,
39 18446744073709548497llu, 18446744073709548481llu, 18446744073709548397llu,
40 18446744073709548391llu, 18446744073709548379llu, 18446744073709548353llu,
41 18446744073709548349llu, 18446744073709548287llu, 18446744073709548271llu,
42 18446744073709548239llu, 18446744073709548193llu, 18446744073709548119llu,
43 18446744073709548073llu, 18446744073709548053llu, 18446744073709547821llu,
44 18446744073709547797llu, 18446744073709547777llu, 18446744073709547731llu,
45 18446744073709547707llu, 18446744073709547669llu, 18446744073709547657llu,
46 18446744073709547537llu, 18446744073709547521llu, 18446744073709547489llu,
47 18446744073709547473llu, 18446744073709547471llu, 18446744073709547371llu,
48 18446744073709547357llu, 18446744073709547317llu, 18446744073709547303llu,
49 18446744073709547117llu, 18446744073709547087llu, 18446744073709547003llu,
50 18446744073709546897llu, 18446744073709546879llu, 18446744073709546873llu,
51 18446744073709546841llu, 18446744073709546739llu, 18446744073709546729llu,
52 18446744073709546657llu, 18446744073709546643llu, 18446744073709546601llu,
53 18446744073709546561llu, 18446744073709546541llu, 18446744073709546493llu,
54 18446744073709546429llu, 18446744073709546409llu, 18446744073709546391llu,
55 18446744073709546363llu, 18446744073709546337llu, 18446744073709546333llu,
56 18446744073709546289llu, 18446744073709546271llu};
61 exvector _tables(pnum);
62 unsigned int nmin = 0;
63 for(
int i=0; i<pnum; i++) {
67 string ostr((istreambuf_iterator<char>(ifs)), (istreambuf_iterator<char>()));
71 _tables[i] = tp.
Read(ostr);
72 auto nn = _tables[i].op(1).nops();
73 if(i==0 || nmin>nn) nmin = nn;
76 vector<numeric> primes;
78 for(
int i=0; i<_tables.size(); i++) {
79 auto nn = _tables[i].op(1).nops();
81 cout <<
"RRTables: current table will be dropped." << endl;
84 if(!is_a<lst>(convs)) convs = _tables[i].op(1);
85 else if(!convs.is_equal(_tables[i].op(1))) {
86 throw Error(
"RRT: convs are different.");
88 tables.push_back(_tables[i].op(0));
89 primes.push_back(HardCodedPrimes[i+1]);
92 vector<pair<ex,vector<pair<ex,exvector>>>> int_mi_cs_vec;
94 for(
int i=0; i<tables.size(); i++) {
96 for(
auto ti : tables[0]) {
97 pair<ex,vector<pair<ex,exvector>>> int_mi_cs;
98 int_mi_cs.first = ti.op(0);
99 for(
auto tii : ti.op(1)) {
100 pair<ex,exvector> mi_cs;
101 mi_cs.first = tii.op(0);
102 mi_cs.second.push_back(tii.op(1));
103 int_mi_cs.second.push_back(mi_cs);
105 int_mi_cs_vec.push_back(int_mi_cs);
108 for(
int i2=0; i2<int_mi_cs_vec.size(); i2++) {
109 auto ti = tables[i].op(i2);
110 auto & int_mi_cs = int_mi_cs_vec[i2];
111 if(int_mi_cs.first != ti.op(0))
throw Error(
"E1");
112 for(
int j=0; j<int_mi_cs.second.size(); j++) {
113 auto & mi_cs = int_mi_cs.second[j];
114 if(mi_cs.first != ti.op(1).op(j).op(0))
throw Error(
"E2");
115 mi_cs.second.push_back(ti.op(1).op(j).op(1));
122 ofs.open(filename, ios::out);
125 for(
int i=0; i<int_mi_cs_vec.size(); i++) {
126 auto imc = int_mi_cs_vec[i];
127 ofs <<
" {" << imc.first <<
"," << endl;
129 for(
int j=0; j<imc.second.size(); j++) {
130 auto item = imc.second[j];
131 ofs <<
" {" << item.first <<
", ";
132 vector<numeric> nvec;
133 for(
auto e : item.second) nvec.push_back(ex_to<numeric>(e));
135 if(j+1<imc.second.size()) ofs <<
",";
140 if(i+1<int_mi_cs_vec.size()) ofs <<
",";
143 ofs <<
" }," << endl <<
" {" << endl;
144 for(
int i=0; i<convs.nops(); i++) {
145 auto item = convs.op(i);
146 ofs <<
" {" << item.op(0) <<
", " << item.op(1) <<
"}";
147 if(i+1<convs.nops()) ofs <<
",";
159 unsigned int nmin = 0;
160 for(
int i=si; i<=ei; i++) {
161 cout <<
"\r \r" << flush;
162 cout <<
"Reading tables: " << ei <<
"|" << i << flush;
163 string fn = filename;
166 string ostr((istreambuf_iterator<char>(ifs)), (istreambuf_iterator<char>()));
168 for(
auto & c : ostr)
if(c==
'\"') c =
' ';
170 _tables[i] = tp.
Read(ostr);
171 auto nn = _tables[i].op(1).nops();
172 if(i==si || nmin>nn) nmin = nn;
179 for(
int i=si; i<=ei; i++) {
180 auto nn = _tables[i].op(1).nops();
182 cout <<
"ThieleTables: current table will be dropped." << endl;
185 if(!is_a<lst>(convs)) convs = _tables[i].op(1);
186 else if(!convs.is_equal(_tables[i].op(1))) {
187 throw Error(
"RRT: convs are different.");
189 tables.push_back(_tables[i].op(0));
193 vector<pair<ex,vector<pair<ex,exvector>>>> int_mi_cs_vec;
195 for(
int i=0; i<tables.size(); i++) {
197 for(
auto ti : tables[0]) {
198 pair<ex,vector<pair<ex,exvector>>> int_mi_cs;
199 int_mi_cs.first = ti.op(0);
200 for(
auto tii : ti.op(1)) {
201 pair<ex,exvector> mi_cs;
202 mi_cs.first = tii.op(0);
203 mi_cs.second.push_back(tii.op(1));
204 int_mi_cs.second.push_back(mi_cs);
206 int_mi_cs_vec.push_back(int_mi_cs);
209 for(
int i2=0; i2<int_mi_cs_vec.size(); i2++) {
210 auto ti = tables[i].op(i2);
211 auto & int_mi_cs = int_mi_cs_vec[i2];
212 if(int_mi_cs.first != ti.op(0))
throw Error(
"E1");
213 for(
int j=0; j<int_mi_cs.second.size(); j++) {
214 auto & mi_cs = int_mi_cs.second[j];
215 if(mi_cs.first != ti.op(1).op(j).op(0))
throw Error(
"E2");
216 mi_cs.second.push_back(ti.op(1).op(j).op(1));
223 ofs.open(filename, ios::out);
226 for(
int i=0; i<int_mi_cs_vec.size(); i++) {
227 cout <<
"\r \r" << flush;
228 cout <<
"Thiele " << int_mi_cs_vec.size() <<
"|" << i+1 << flush;
229 auto imc = int_mi_cs_vec[i];
230 ofs <<
" {" << imc.first <<
"," << endl;
232 for(
int j=0; j<imc.second.size(); j++) {
233 auto item = imc.second[j];
234 ofs <<
" {" << item.first <<
", ";
235 exvector vals(item.second.begin(), item.second.end());
236 auto res =
Thiele(keys, vals,
d);
237 ofs <<
"\"" << res <<
"\"}";
238 if(j+1<imc.second.size()) ofs <<
",";
243 if(i+1<int_mi_cs_vec.size()) ofs <<
",";
247 ofs <<
" }," << endl <<
" {" << endl;
248 for(
int i=0; i<convs.nops(); i++) {
249 auto item = convs.op(i);
250 ofs <<
" {" << item.op(0) <<
", " << item.op(1) <<
"}";
251 if(i+1<convs.nops()) ofs <<
",";
272 for(
auto ii :
Internal) InExternal.append(ii);
273 for(
auto ii :
External) InExternal.append(ii);
277 for(
auto ii : InExternal)
ISP.append(it*ii);
283 if(
ISP.nops() > pdim) {
284 cout <<
"ISP = " <<
ISP << endl;
285 cout <<
"Propagator = " <<
Propagator << endl;
286 throw Error(
"FIRE::Export: #(ISP) > #(Propagator).");
291 for(
auto item :
ISP) {
293 Symbol si(
"P"+to_string(_pic));
295 sp2s.append(
w*item==
w*si);
296 sp2s.append(item==si);
297 s2sp.append(si==item);
304 repl.append(
w*item.op(0) ==
w*item.op(1));
310 for(
int i=0; i<
ISP.nops(); i++) {
314 if(eq.has(iWF(
w)))
throw Error(
"FIRE::Export, iWF used in eq.");
315 eqns.append(eq == iWF(i));
317 auto s2p = lsolve(eqns, ss);
318 if(s2p.nops() !=
ISP.nops()) {
319 cout <<
"ISP=" <<
ISP << endl;
321 cout <<
"eqns=" << eqns << endl;
322 throw Error(
"FIRE::Export: lsolve failed.");
329 for(
auto p2 : InExternal)
330 DSP.append(lst{p1,p2});
336 for(
int i=0; i<
Internal.nops(); i++)
337 DSP.append(lst{Internal.op(i), Internal.op(i==Internal.nops()-1 ? 0 : i+1)});
338 for(
auto p2 : InExternal)
DSP.append(lst{
Internal.op(0), p2});
346 for(
int i=0; i<pdim; i++) ns0.append(0);
349 auto ilp_lst =
sp.op(0);
350 auto iep_lst =
sp.op(1);
351 if(!is_a<lst>(ilp_lst)) {
352 ilp_lst = lst{ ilp_lst };
353 iep_lst = lst{ iep_lst };
357 for(
int ilst=0; ilst<ilp_lst.nops(); ilst++) {
359 auto ilp = ilp_lst.op(ilst);
360 auto iep = iep_lst.op(ilst);
362 for(
int i=0; i<pdim; i++) {
363 dp_lst.append(
Propagator.op(i).subs(ilp==ss).diff(ss).subs(ss==ilp));
366 for(
int i=0; i<pdim; i++) {
368 ns.let_op(i) = ns.op(i)+1;
369 auto tmp = dp_lst.op(i) * iep;
372 tmp = tmp.subs(sp2s);
376 tmp = ex(0) - (
Shift[i+1]+
a(i+1))*tmp;
378 for(
int j=0; j<pdim; j++) {
379 auto cj = tmp.coeff(iWF(j));
380 if(is_zero(cj))
continue;
382 cns.let_op(j) = cns.op(j)-1;
383 nc_map[cns] = nc_map[cns] + cj;
385 tmp = tmp.subs(iWF(
w)==0);
386 if(!is_zero(tmp)) nc_map[ns] = nc_map[ns] + tmp;
389 auto cilp = iep.coeff(ilp);
390 if(!is_zero(cilp)) nc_map[ns0] = nc_map[ns0] +
d*cilp;
394 for(
auto nc : nc_map) {
395 if(!is_zero(nc.second)) {
397 IBPvec.push_back(nc.second);
400 if(ok) ibps.push_back(nc_map);
405 if(Variables.has(e)) {
406 cout <<
"IBPvec: " << IBPvec << endl;
408 cout <<
"Variables: " << Variables << endl;
409 throw Error(
"FIRE: Replacement NOT work!");
415 start <<
"ExampleDimension[" << pn <<
"]=" << pdim << endl << endl;
416 start <<
"ProblemNumber=" << pn << endl << endl;
421 start <<
"SBasisL[" << pn <<
",{";
422 for(
int i=0; i<pdim; i++) start << (ns[i]<1 ? -1 : 1) << (i<pdim-1 ?
"," :
"");
423 start <<
"}]=0" << endl << endl;
428 start <<
"SBasis0L[" << pn <<
"]=" << ibps.size() << endl << endl;
430 for(
int i=0; i<ibps.size(); i++) {
431 start <<
"SBasis0D[" << pn <<
"," << (i+1) <<
"]=";
433 for(
auto kv : ibps[i]) {
434 items.append(kv.first);
436 oss <<
"SBasis0C[" << pn <<
"," << (i+1) <<
"," << kv.first <<
"]=" <<
437 collect_common_factors(kv.second.normal()) << endl << endl;
441 for(
auto item : cv_lst) {
442 auto cc = item.op(0);
443 auto cv = item.op(1);
444 cc = collect_common_factors(cc.normal());
445 if(is_zero(cc))
continue;
446 if(is_zero(cv-1)) cv=0;
447 else cv = cv.subs(
a(
w)==
w);
448 olst.append(lst{cc, cv});
450 oss <<
"SBasis0C[" << pn <<
"," << (i+1) <<
"," << kv.first <<
"]=" << olst << endl << endl;
453 start << items << endl << endl;
458 start <<
"SBasisS[" << pn <<
"]={{{";
460 for(
int i=0; i<pdim; i++) start << (i+1) << (i<pdim-1 ?
"," :
"");
463 for(
int i=0; i<pdim; i++) start << 1 << (i<pdim-1 ?
"," :
"");
466 for(
int i=0; i<pdim; i++) start << 0 << (i<pdim-1 ?
"," :
"");
467 start <<
"}}}" << endl << endl;
472 for(
int i=0; i<pdim; i++) {
478 for(
int i=0; i<pdim; i++) ns0.append(1);
479 for(
int i=0; i<pdim; i++) {
480 if(
Propagator.op(i).has(lpi)) ns0.let_op(i) = -1;
481 else ns_vec.push_back(i);
483 size_t tot = std::pow(2LL,ns_vec.size());
484 for(
size_t n=0; n<tot; n++) {
487 for(
int j=0; j<ns_vec.size(); j++) {
488 if((cn%2)==1) ns1.let_op(ns_vec[j]) = -1;
500 for(
int i=0; i<pdim; i++) ns0.append(1);
501 size_t tot = std::pow(2LL,pdim);
503 for(
size_t n=0; n<tot; n++) {
506 for(
int j=0; j<pdim; j++) {
507 if((cn%2)==1) sector.let_op(j) = 0;
511 for(
int j=0; j<pdim; j++)
if(sector.op(j)>
SECTOR.op(j))
goto add_sector_done;
513 sectors.insert(sector);
517 while(!sectors.empty()) {
518 auto first = *(sectors.begin());
519 sectors.erase(first);
521 auto sector = ex_to<lst>(first);
524 for(
int j=0; j<pdim; j++) {
525 if(sector.op(j).is_zero()) ns1.let_op(j) = -1;
529 for(
auto item : sectors) {
531 for(
int j=0; j<pdim; j++) {
532 if(sector.op(j)<item.op(j)) { ok =
false;
break; }
534 if(ok) subsets.insert(item);
536 for(
auto item : subsets) {
538 lst ns1 = ex_to<lst>(item);
539 for(
int j=0; j<pdim; j++) {
540 if(item.op(j).is_zero()) ns1.let_op(j) = -1;
547 for(
auto item : sectors) {
549 for(
int j=0; j<pdim; j++) {
550 if(sector.op(j)>item.op(j)) { ok =
false;
break; }
552 if(ok) supsets.insert(item);
554 for(
auto item : supsets) sectors.erase(item);
568 int ci = ex_to<numeric>(cx-1).to_int();
570 for(
int i=0; i<pdim; i++) ns0.append(1);
572 for(
int n=0; n<std::pow(2,pdim-1); n++) {
575 for(
int j=0; j<pdim; j++) {
577 if((cn%2)==1) ns1.let_op(j) = -1;
589 for(
auto iR : Rlst) {
590 start <<
"SBasisR[" << pn <<
",{";
591 for(
int i=0; i<pdim; i++) start << iR.op(i) << (i<pdim-1 ?
"," :
"");
592 start <<
"}]=True" << endl << endl;
596 start <<
"SBasisRL[" << pn <<
"]=0" << endl << endl;
597 start <<
"HPI[" << pn <<
"]={}" << endl << endl;
599 string sss = start.str();
605 ofstream start_out(
WorkingDir+
"/"+spn+
".start");
606 start_out << sss << endl;
611 ostringstream config;
613 config <<
"#variables ";
616 for(
auto v : Variables) {
618 if(fw!=
fermat_weight.end()) ev_sort.push_back(lst{ fw->second, v });
619 else ev_sort.push_back(lst{ 0, v });
622 for(
auto nv : ev_sort) {
623 const symbol & s = ex_to<symbol>(nv.op(1));
624 if(
false && !islower(s.get_name()[0])) {
626 cout <<
"IBPvec: " << IBPvec << endl;
627 throw Error(
"FIRE: Fermat requires a name must begin with a lower case letter: "+s.get_name());
629 config << (first ?
"" :
",") << s;
631 if(itr!=
NVariables.end()) config <<
"->" << itr->second;
638 config <<
"##prime 111" << endl;
639 if(
allIBP) config <<
"#allIBP" << endl;
640 config <<
"#start" << endl;
644 for(
int i=pdim-1; i>=0; i--) {
651 for(
int i=0; i<pdim; i++) {
657 config <<
"#problem " << pn <<
" ";
658 if(pmin>1) config <<
"|" << pmin <<
"," << pmax <<
"|";
659 else if(pmax!=pdim) config <<
"|" << pmax <<
"|";
661 }
else config <<
"#problem " << pn <<
" " <<
ProblemNumber <<
".start" << endl;
669 for(
int i=0; i<nn; i++) {
670 if(
PIntegral.op(i).nops()!=pdim)
throw Error(
"FIRE::Export@1, Index dimension NOT match Propagator.");
671 oss <<
"{" << pn <<
"," <<
PIntegral.op(i) << (i<nn-1 ?
"}," :
"}");
674 ofstream pref_out(
WorkingDir+
"/"+spn+
".pref");
675 pref_out << oss.str() << endl;
682 ofstream config_out(
WorkingDir+
"/"+spn+
".config");
683 config_out << config.str() << endl;
693 for(
int i=0; i<
Integral.nops(); i++) {
694 if(
Integral[i].nops()!=pdim)
throw Error(
"FIRE::Export@2, Index dimension NOT match Propagator.");
695 intg <<
"{" << pn <<
"," <<
Integral[i] << (i<
Integral.nops()-1 ?
"}," :
"}");
699 ofstream intg_out(
WorkingDir+
"/"+spn+
".intg");
700 intg_out << intg.str() << endl;
724 if(
opt==
"") cmd <<
" -silent -t " <<
T1 <<
"," <<
T2 <<
" -lt " <<
LT1 <<
"," <<
LT2;
725 else cmd <<
" " <<
opt;
728 auto rc = system(cmd.str().c_str());
735 throw Error(
"FIRE::Run failed!");
747 string ostr((istreambuf_iterator<char>(ifs)), (istreambuf_iterator<char>()));
751 for(
auto & c : ostr)
if(c==
'"') c =
' ';
754 auto tp_lst = tp.
Read(ostr);
756 for(
auto item : tp_lst.op(1)) {
757 if(!is_zero(item.op(1).op(0)))
throw Error(
"FIRE::Reduce: pn is NOT 0.");
761 for(
auto item : tp_lst.op(0)) {
762 ex left = item.op(0).subs(id2F);
764 for(
auto it : item.op(1)) {
765 right += it.op(0).subs(id2F) * it.op(1);
767 if(left.is_equal(right))
MIntegral.append(left);
768 else Rules.append(left==right);
786 for(
auto item : mis) {
787 lst mi = ex_to<lst>(item.op(1));
790 if(!is_zero(mi.op(ex_to<numeric>(cx).to_int()-1)-1)) {
796 if(nrun==0 && isOK)
MIntegral.append(item);
804 vector<int> ipos, ineg;
805 for(
int i=0; i<mi.nops(); i++) {
808 if(is_zero(cx-1-i)) {
813 if(isCut) pi.let_op(i)=1;
814 else if(mi.op(i)<=0) ineg.push_back(i);
815 else ipos.push_back(i);
820 ex total = pow(numeric(max), ineg.size());
821 for(numeric in=0; in<total; in++) {
824 for(
int i=0; i<ineg.size(); i++) {
825 int re = mod(cin,max).to_int();
826 pi2.let_op(ineg[i]) = ex(0)-re;
833 total = pow(numeric(max2), ipos.size());
835 for(numeric in=0; in<total; in++) {
838 for(
int i=0; i<ipos.size(); i++) {
839 int re = mod(cin,max2).to_int();
840 pi2.let_op(ipos[i]) = re-max;
871 auto rc = system((
"rm -rf " + fire.
WorkingDir).c_str());
874 vis_chk = ex_to<lst>(
subs(vis_chk, fire.
Rules));
875 if(vis_chk.is_equal(vis))
break;
878 find(vis,F(
w1,
w2),fs);
880 for(
auto item : fs) mis.append(item);
885 for(
int i=0; i<ois.nops(); i++) c2m[ois.op(i)] = vis.op(i);
886 for(
auto item : mis)
MIntegral.append(item);
894 for(
auto r : rules) {
898 if(item.is_equal(ri)) {
900 rIntegral.append(ri);
906 rIntegral.append(rv);
907 Rules.append(ri==rv.subs(c2m));
913 find(rIntegral,F(
w1,
w2),fs);
class used to wrap error message
IBP reduction using FIRE program.
static void RRTables(const string &filename, int pnum)
void Import() override
Import tables
static void ThieleTables(const string &filename, int si, int ei)
void Export() override
Export start config intgral etc. files.
void Run() override
Run FIRE reduction.
class to parse for string or file, helpful with Symbol class
ex Read(const string &instr, bool s2S=true)
class extended to GiNaC symbol class, represent a positive symbol
ex sp(const ex &a, const ex &b)
translated the vector dot a.b to a*b, useful in SecDec
lst gather_symbols(const ex &e)
get all symbols from input expression
map< ex, long long, ex_is_less > fermat_weight
numeric RationalReconstruct(numeric a, numeric p)
ex Thiele(const exvector &keys, const exvector &values, const ex &d)
bool file_exists(string fn)
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}, ... }
void sort_vec(exvector &ivec, bool less=true)
sort the list in less order, or the reverse
void sort_lst(lst &ilst, bool less=true)
sort the list in less order, or the reverse
void string_replace_all(string &str, const string &from, const string &to)
void garWrite(const string &garfn, const map< string, ex > &resMap)
garWrite to write the string-key map to the archive
void let_op_append(ex &ex_in, const ex item)
append item into expression
bool dir_exists(string dir)
void PermutationsR(int n, int m, std::function< void(const int *)> f)
ex subs(const ex &e, init_list sl)