15 unsigned long long HardCodedPrimes[128] = {
16 2017llu, 18446744073709551557llu, 18446744073709551533llu,
17 18446744073709551521llu, 18446744073709551437llu, 18446744073709551427llu,
18 18446744073709551359llu, 18446744073709551337llu, 18446744073709551293llu,
19 18446744073709551263llu, 18446744073709551253llu, 18446744073709551191llu,
20 18446744073709551163llu, 18446744073709551113llu, 18446744073709550873llu,
21 18446744073709550791llu, 18446744073709550773llu, 18446744073709550771llu,
22 18446744073709550719llu, 18446744073709550717llu, 18446744073709550681llu,
23 18446744073709550671llu, 18446744073709550593llu, 18446744073709550591llu,
24 18446744073709550539llu, 18446744073709550537llu, 18446744073709550381llu,
25 18446744073709550341llu, 18446744073709550293llu, 18446744073709550237llu,
26 18446744073709550147llu, 18446744073709550141llu, 18446744073709550129llu,
27 18446744073709550111llu, 18446744073709550099llu, 18446744073709550047llu,
28 18446744073709550033llu, 18446744073709550009llu, 18446744073709549951llu,
29 18446744073709549861llu, 18446744073709549817llu, 18446744073709549811llu,
30 18446744073709549777llu, 18446744073709549757llu, 18446744073709549733llu,
31 18446744073709549667llu, 18446744073709549621llu, 18446744073709549613llu,
32 18446744073709549583llu, 18446744073709549571llu, 18446744073709549519llu,
33 18446744073709549483llu, 18446744073709549441llu, 18446744073709549363llu,
34 18446744073709549331llu, 18446744073709549327llu, 18446744073709549307llu,
35 18446744073709549237llu, 18446744073709549153llu, 18446744073709549123llu,
36 18446744073709549067llu, 18446744073709549061llu, 18446744073709549019llu,
37 18446744073709548983llu, 18446744073709548899llu, 18446744073709548887llu,
38 18446744073709548859llu, 18446744073709548847llu, 18446744073709548809llu,
39 18446744073709548703llu, 18446744073709548599llu, 18446744073709548587llu,
40 18446744073709548557llu, 18446744073709548511llu, 18446744073709548503llu,
41 18446744073709548497llu, 18446744073709548481llu, 18446744073709548397llu,
42 18446744073709548391llu, 18446744073709548379llu, 18446744073709548353llu,
43 18446744073709548349llu, 18446744073709548287llu, 18446744073709548271llu,
44 18446744073709548239llu, 18446744073709548193llu, 18446744073709548119llu,
45 18446744073709548073llu, 18446744073709548053llu, 18446744073709547821llu,
46 18446744073709547797llu, 18446744073709547777llu, 18446744073709547731llu,
47 18446744073709547707llu, 18446744073709547669llu, 18446744073709547657llu,
48 18446744073709547537llu, 18446744073709547521llu, 18446744073709547489llu,
49 18446744073709547473llu, 18446744073709547471llu, 18446744073709547371llu,
50 18446744073709547357llu, 18446744073709547317llu, 18446744073709547303llu,
51 18446744073709547117llu, 18446744073709547087llu, 18446744073709547003llu,
52 18446744073709546897llu, 18446744073709546879llu, 18446744073709546873llu,
53 18446744073709546841llu, 18446744073709546739llu, 18446744073709546729llu,
54 18446744073709546657llu, 18446744073709546643llu, 18446744073709546601llu,
55 18446744073709546561llu, 18446744073709546541llu, 18446744073709546493llu,
56 18446744073709546429llu, 18446744073709546409llu, 18446744073709546391llu,
57 18446744073709546363llu, 18446744073709546337llu, 18446744073709546333llu,
58 18446744073709546289llu, 18446744073709546271llu};
61 inline lst
syms(
const exvector & ev) {
64 for(const_preorder_iterator i=e.preorder_begin(); i!=e.preorder_end(); ++i)
65 if(is_a<symbol>(*i)) ss.insert(*i);
68 for(
auto item : ss) ls.append(item);
74 exvector _tables(pnum);
75 unsigned int nmin = 0;
76 for(
int i=0; i<pnum; i++) {
80 string ostr((istreambuf_iterator<char>(ifs)), (istreambuf_iterator<char>()));
84 _tables[i] = tp.
Read(ostr);
85 auto nn = _tables[i].op(1).nops();
86 if(i==0 || nmin>nn) nmin = nn;
89 vector<numeric> primes;
91 for(
int i=0; i<_tables.size(); i++) {
92 auto nn = _tables[i].op(1).nops();
94 cout <<
"RRTables: current table will be dropped." << endl;
97 if(!is_a<lst>(convs)) convs = _tables[i].op(1);
98 else if(!convs.is_equal(_tables[i].op(1))) {
99 throw Error(
"RRT: convs are different.");
101 tables.push_back(_tables[i].op(0));
102 primes.push_back(HardCodedPrimes[i+1]);
105 vector<pair<ex,vector<pair<ex,exvector>>>> int_mi_cs_vec;
107 for(
int i=0; i<tables.size(); i++) {
109 for(
auto ti : tables[0]) {
110 pair<ex,vector<pair<ex,exvector>>> int_mi_cs;
111 int_mi_cs.first = ti.op(0);
112 for(
auto tii : ti.op(1)) {
113 pair<ex,exvector> mi_cs;
114 mi_cs.first = tii.op(0);
115 mi_cs.second.push_back(tii.op(1));
116 int_mi_cs.second.push_back(mi_cs);
118 int_mi_cs_vec.push_back(int_mi_cs);
121 for(
int i2=0; i2<int_mi_cs_vec.size(); i2++) {
122 auto ti = tables[i].op(i2);
123 auto & int_mi_cs = int_mi_cs_vec[i2];
124 if(int_mi_cs.first != ti.op(0))
throw Error(
"E1");
125 for(
int j=0; j<int_mi_cs.second.size(); j++) {
126 auto & mi_cs = int_mi_cs.second[j];
127 if(mi_cs.first != ti.op(1).op(j).op(0))
throw Error(
"E2");
128 mi_cs.second.push_back(ti.op(1).op(j).op(1));
135 ofs.open(filename, ios::out);
138 for(
int i=0; i<int_mi_cs_vec.size(); i++) {
139 auto imc = int_mi_cs_vec[i];
140 ofs <<
" {" << imc.first <<
"," << endl;
142 for(
int j=0; j<imc.second.size(); j++) {
143 auto item = imc.second[j];
144 ofs <<
" {" << item.first <<
", ";
145 vector<numeric> nvec;
146 for(
auto e : item.second) nvec.push_back(ex_to<numeric>(e));
148 if(j+1<imc.second.size()) ofs <<
",";
153 if(i+1<int_mi_cs_vec.size()) ofs <<
",";
156 ofs <<
" }," << endl <<
" {" << endl;
157 for(
int i=0; i<convs.nops(); i++) {
158 auto item = convs.op(i);
159 ofs <<
" {" << item.op(0) <<
", " << item.op(1) <<
"}";
160 if(i+1<convs.nops()) ofs <<
",";
172 unsigned int nmin = 0;
173 for(
int i=si; i<=ei; i++) {
174 cout <<
"\r \r" << flush;
175 cout <<
"Reading tables: " << ei <<
"|" << i << flush;
176 string fn = filename;
179 string ostr((istreambuf_iterator<char>(ifs)), (istreambuf_iterator<char>()));
181 for(
auto & c : ostr)
if(c==
'\"') c =
' ';
183 _tables[i] = tp.
Read(ostr);
184 auto nn = _tables[i].op(1).nops();
185 if(i==si || nmin>nn) nmin = nn;
192 for(
int i=si; i<=ei; i++) {
193 auto nn = _tables[i].op(1).nops();
195 cout <<
"ThieleTables: current table will be dropped." << endl;
198 if(!is_a<lst>(convs)) convs = _tables[i].op(1);
199 else if(!convs.is_equal(_tables[i].op(1))) {
200 throw Error(
"RRT: convs are different.");
202 tables.push_back(_tables[i].op(0));
206 vector<pair<ex,vector<pair<ex,exvector>>>> int_mi_cs_vec;
208 for(
int i=0; i<tables.size(); i++) {
210 for(
auto ti : tables[0]) {
211 pair<ex,vector<pair<ex,exvector>>> int_mi_cs;
212 int_mi_cs.first = ti.op(0);
213 for(
auto tii : ti.op(1)) {
214 pair<ex,exvector> mi_cs;
215 mi_cs.first = tii.op(0);
216 mi_cs.second.push_back(tii.op(1));
217 int_mi_cs.second.push_back(mi_cs);
219 int_mi_cs_vec.push_back(int_mi_cs);
222 for(
int i2=0; i2<int_mi_cs_vec.size(); i2++) {
223 auto ti = tables[i].op(i2);
224 auto & int_mi_cs = int_mi_cs_vec[i2];
225 if(int_mi_cs.first != ti.op(0))
throw Error(
"E1");
226 for(
int j=0; j<int_mi_cs.second.size(); j++) {
227 auto & mi_cs = int_mi_cs.second[j];
228 if(mi_cs.first != ti.op(1).op(j).op(0))
throw Error(
"E2");
229 mi_cs.second.push_back(ti.op(1).op(j).op(1));
236 ofs.open(filename, ios::out);
239 for(
int i=0; i<int_mi_cs_vec.size(); i++) {
240 cout <<
"\r \r" << flush;
241 cout <<
"Thiele: " << int_mi_cs_vec.size() <<
"|" << i+1 << flush;
242 auto imc = int_mi_cs_vec[i];
243 ofs <<
" {" << imc.first <<
"," << endl;
246 auto nnn = imc.second.size();
247 vector<fmpz_mpoly_q_struct*> res_vec(nnn);
248 vector<lst> xs_vec(nnn);
249 #pragma omp parallel for schedule(dynamic, 1)
250 for(
int j=0; j<nnn; j++) {
251 auto item = imc.second[j];
252 xs_vec[j] =
syms(item.second);
253 fmpz_mpoly_ctx_t ctx;
254 fmpz_mpoly_ctx_init(ctx, xs_vec[j].nops(), ORD_LEX);
255 res_vec[j] = (fmpz_mpoly_q_struct*) flint_malloc(
sizeof(fmpz_mpoly_q_struct));
256 fmpz_mpoly_q_init(res_vec[j], ctx);
258 vector<fmpz_mpoly_q_struct*> key_vec(n);
259 vector<fmpz_mpoly_q_struct*> val_vec(n);
260 vector<fmpz_mpoly_q_struct*> coeff_vec(n);
261 for(
int k=0; k<n; k++) {
262 key_vec[j] = (fmpz_mpoly_q_struct*) flint_malloc(
sizeof(fmpz_mpoly_q_struct));
263 fmpz_mpoly_q_init(key_vec[k], ctx);
264 _to_(xs_vec[j], key_vec[k], ctx, item.first.op(k));
265 val_vec[j] = (fmpz_mpoly_q_struct*) flint_malloc(
sizeof(fmpz_mpoly_q_struct));
266 fmpz_mpoly_q_init(val_vec[k], ctx);
267 _to_(xs_vec[j], val_vec[j], ctx, item.second[k]);
268 coeff_vec[j] = (fmpz_mpoly_q_struct*) flint_malloc(
sizeof(fmpz_mpoly_q_struct));
269 fmpz_mpoly_q_init(coeff_vec[k], ctx);
270 fmpz_mpoly_q_zero(coeff_vec[k], ctx);
273 fmpz_mpoly_q_t t1, t2;
274 fmpz_mpoly_q_init(t1, ctx);
275 fmpz_mpoly_q_init(t2, ctx);
276 for(
int i=0; i<n; i++) {
277 fmpz_mpoly_q_set(t1, val_vec[i], ctx);
278 for(
int j=0; j<i; j++) {
279 if(fmpz_mpoly_q_equal(t1, coeff_vec[j], ctx)) {
283 fmpz_mpoly_q_sub(t2, key_vec[i], key_vec[j], ctx);
284 fmpz_mpoly_q_sub(t1, t1, coeff_vec[j], ctx);
285 fmpz_mpoly_q_div(t1, t2, t1, ctx);
287 fmpz_mpoly_q_set(coeff_vec[i], t1, ctx);
289 throw Error(
"Thiele unstable!");
291 fmpz_mpoly_q_set(t1, coeff_vec[n], ctx);
293 fmpz_mpoly_q_init(dx, ctx);
294 _to_(xs_vec[j], dx, ctx,
d);
295 for(
int i=n-1; i>=0; i--) {
296 fmpz_mpoly_q_sub(t2, dx, key_vec[i], ctx);
297 fmpz_mpoly_q_div(t2, t2, t1, ctx);
298 fmpz_mpoly_q_add(t1, coeff_vec[i], t2, ctx);
300 fmpz_mpoly_q_clear(dx, ctx);
301 fmpz_mpoly_q_set(res_vec[i], t1, ctx);
302 for(
int k=0; k<n; k++) {
303 fmpz_mpoly_q_clear(key_vec[k], ctx);
304 fmpz_mpoly_q_clear(val_vec[k], ctx);
305 fmpz_mpoly_q_clear(coeff_vec[k], ctx);
307 fmpz_mpoly_q_clear(t1, ctx);
308 fmpz_mpoly_q_clear(t2, ctx);
309 fmpz_mpoly_ctx_clear(ctx);
311 for(
int j=0; j<imc.second.size(); j++) {
312 fmpz_mpoly_ctx_t ctx;
313 fmpz_mpoly_ctx_init(ctx, xs_vec[j].nops(), ORD_LEX);
314 auto item = imc.second[j];
316 res = _to_(xs_vec[j], res_vec[j], ctx);
317 fmpz_mpoly_q_clear(res_vec[j], ctx);
318 ofs <<
" {" << item.first <<
", ";
319 ofs <<
"\"" << res <<
"\"}";
320 if(j+1<imc.second.size()) ofs <<
",";
325 if(i+1<int_mi_cs_vec.size()) ofs <<
",";
329 ofs <<
" }," << endl <<
" {" << endl;
330 for(
int i=0; i<convs.nops(); i++) {
331 auto item = convs.op(i);
332 ofs <<
" {" << item.op(0) <<
", " << item.op(1) <<
"}";
333 if(i+1<convs.nops()) ofs <<
",";
354 for(
auto ii :
Internal) InExternal.append(ii);
355 for(
auto ii :
External) InExternal.append(ii);
359 for(
auto ii : InExternal)
ISP.append(it*ii);
365 if(
ISP.nops() > pdim) {
366 cout <<
"ISP = " <<
ISP << endl;
367 cout <<
"Propagator = " <<
Propagator << endl;
368 throw Error(
"FIRE::Export: #(ISP) > #(Propagator).");
373 for(
auto item :
ISP) {
375 Symbol si(
"P"+to_string(_pic));
377 sp2s.append(
w*item==
w*si);
378 sp2s.append(item==si);
379 s2sp.append(si==item);
386 repl.append(
w*item.op(0) ==
w*item.op(1));
392 for(
int i=0; i<
ISP.nops(); i++) {
396 if(eq.has(iWF(
w)))
throw Error(
"FIRE::Export, iWF used in eq.");
397 eqns.append(eq == iWF(i));
399 auto s2p = lsolve(eqns, ss);
400 if(s2p.nops() !=
ISP.nops()) {
401 cout <<
"ISP=" <<
ISP << endl;
403 cout <<
"eqns=" << eqns << endl;
404 throw Error(
"FIRE::Export: lsolve failed.");
411 for(
auto p2 : InExternal)
412 DSP.append(lst{p1,p2});
418 for(
int i=0; i<
Internal.nops(); i++)
420 for(
auto p2 : InExternal)
DSP.append(lst{
Internal.op(0), p2});
421 DSP.append(lst{Internal, Internal});
428 for(
int i=0; i<pdim; i++) ns0.append(0);
431 auto ilp_lst =
sp.op(0);
432 auto iep_lst =
sp.op(1);
433 if(!is_a<lst>(ilp_lst)) {
434 ilp_lst = lst{ ilp_lst };
435 iep_lst = lst{ iep_lst };
439 for(
int ilst=0; ilst<ilp_lst.nops(); ilst++) {
441 auto ilp = ilp_lst.op(ilst);
442 auto iep = iep_lst.op(ilst);
444 for(
int i=0; i<pdim; i++) {
445 dp_lst.append(Propagator.op(i).subs(ilp==ss).diff(ss).subs(ss==ilp));
448 for(
int i=0; i<pdim; i++) {
450 ns.let_op(i) = ns.op(i)+1;
451 auto tmp = dp_lst.op(i) * iep;
453 tmp = tmp.subs(Replacement);
454 tmp = tmp.subs(sp2s);
456 tmp = tmp.subs(Replacement);
458 tmp = ex(0) - (Shift[i+1]+
a(i+1))*tmp;
460 for(
int j=0; j<pdim; j++) {
461 auto cj = tmp.coeff(iWF(j));
462 if(is_zero(cj))
continue;
464 cns.let_op(j) = cns.op(j)-1;
465 nc_map[cns] = nc_map[cns] + cj;
467 tmp = tmp.subs(iWF(w)==0);
468 if(!is_zero(tmp)) nc_map[ns] = nc_map[ns] + tmp;
471 auto cilp = iep.coeff(ilp);
472 if(!is_zero(cilp)) nc_map[ns0] = nc_map[ns0] + d*cilp;
476 for(
auto nc : nc_map) {
477 if(!is_zero(nc.second)) {
479 IBPvec.push_back(nc.second);
482 if(ok) ibps.push_back(nc_map);
486 for(
auto e : External) {
487 if(Variables.has(e)) {
488 cout <<
"IBPvec: " << IBPvec << endl;
489 cout <<
"Replacement: " << Replacement << endl;
490 cout <<
"Variables: " << Variables << endl;
491 throw Error(
"FIRE: Replacement NOT work!");
497 start <<
"ExampleDimension[" << pn <<
"]=" << pdim << endl << endl;
498 start <<
"ProblemNumber=" << pn << endl << endl;
503 start <<
"SBasisL[" << pn <<
",{";
504 for(
int i=0; i<pdim; i++) start << (ns[i]<1 ? -1 : 1) << (i<pdim-1 ?
"," :
"");
505 start <<
"}]=0" << endl << endl;
510 start <<
"SBasis0L[" << pn <<
"]=" << ibps.size() << endl << endl;
512 for(
int i=0; i<ibps.size(); i++) {
513 start <<
"SBasis0D[" << pn <<
"," << (i+1) <<
"]=";
515 for(
auto kv : ibps[i]) {
516 items.append(kv.first);
518 oss <<
"SBasis0C[" << pn <<
"," << (i+1) <<
"," << kv.first <<
"]=" <<
519 collect_common_factors(kv.second.normal()) << endl << endl;
523 for(
auto item : cv_lst) {
524 auto cc = item.op(0);
525 auto cv = item.op(1);
526 cc = collect_common_factors(cc.normal());
527 if(is_zero(cc))
continue;
528 if(is_zero(cv-1)) cv=0;
529 else cv = cv.subs(
a(w)==w);
530 olst.append(lst{cc, cv});
532 oss <<
"SBasis0C[" << pn <<
"," << (i+1) <<
"," << kv.first <<
"]=" << olst << endl << endl;
535 start << items << endl << endl;
540 start <<
"SBasisS[" << pn <<
"]={{{";
542 for(
int i=0; i<pdim; i++) start << (i+1) << (i<pdim-1 ?
"," :
"");
545 for(
int i=0; i<pdim; i++) start << 1 << (i<pdim-1 ?
"," :
"");
548 for(
int i=0; i<pdim; i++) start << 0 << (i<pdim-1 ?
"," :
"");
549 start <<
"}}}" << endl << endl;
554 for(
int i=0; i<pdim; i++) {
557 for(
auto lpi : Internal) {
560 for(
int i=0; i<pdim; i++) ns0.append(1);
561 for(
int i=0; i<pdim; i++) {
562 if(Propagator.op(i).has(lpi)) ns0.let_op(i) = -1;
563 else ns_vec.push_back(i);
565 size_t tot = std::pow(2LL,ns_vec.size());
566 for(
size_t n=0; n<tot; n++) {
569 for(
int j=0; j<ns_vec.size(); j++) {
570 if((cn%2)==1) ns1.let_op(ns_vec[j]) = -1;
582 for(
int i=0; i<pdim; i++) ns0.append(1);
583 size_t tot = std::pow(2LL,pdim);
585 for(
size_t n=0; n<tot; n++) {
588 for(
int j=0; j<pdim; j++) {
589 if((cn%2)==1) sector.let_op(j) = 0;
592 if(SECTOR.nops()==pdim) {
593 for(
int j=0; j<pdim; j++)
if(sector.op(j)>SECTOR.op(j))
goto add_sector_done;
595 sectors.insert(sector);
599 while(!sectors.empty()) {
600 auto first = *(sectors.begin());
601 sectors.erase(first);
603 auto sector = ex_to<lst>(first);
606 for(
int j=0; j<pdim; j++) {
607 if(sector.op(j).is_zero()) ns1.let_op(j) = -1;
611 for(
auto item : sectors) {
613 for(
int j=0; j<pdim; j++) {
614 if(sector.op(j)<item.op(j)) { ok =
false;
break; }
616 if(ok) subsets.insert(item);
618 for(
auto item : subsets) {
620 lst ns1 = ex_to<lst>(item);
621 for(
int j=0; j<pdim; j++) {
622 if(item.op(j).is_zero()) ns1.let_op(j) = -1;
627 if(IsAlwaysZero) IsAlwaysZero =
false;
629 for(
auto item : sectors) {
631 for(
int j=0; j<pdim; j++) {
632 if(sector.op(j)>item.op(j)) { ok =
false;
break; }
634 if(ok) supsets.insert(item);
636 for(
auto item : supsets) sectors.erase(item);
642 for(
auto ii : Integral) Rules.append(F(ProblemNumber, ii)==0);
650 int ci = ex_to<numeric>(cx-1).to_int();
652 for(
int i=0; i<pdim; i++) ns0.append(1);
654 for(
int n=0; n<std::pow(2,pdim-1); n++) {
657 for(
int j=0; j<pdim; j++) {
659 if((cn%2)==1) ns1.let_op(j) = -1;
671 for(
auto iR : Rlst) {
672 start <<
"SBasisR[" << pn <<
",{";
673 for(
int i=0; i<pdim; i++) start << iR.op(i) << (i<pdim-1 ?
"," :
"");
674 start <<
"}]=True" << endl << endl;
678 start <<
"SBasisRL[" << pn <<
"]=0" << endl << endl;
679 start <<
"HPI[" << pn <<
"]={}" << endl << endl;
681 string sss = start.str();
685 if(!
dir_exists(WorkingDir))
auto rc = system((
"mkdir -p " + WorkingDir).c_str());
687 ofstream start_out(WorkingDir+
"/"+spn+
".start");
688 start_out << sss << endl;
693 ostringstream config;
695 config <<
"#variables ";
698 for(
auto v : Variables) {
700 if(fw!=
fermat_weight.end()) ev_sort.push_back(lst{ fw->second, v });
701 else ev_sort.push_back(lst{ 0, v });
704 for(
auto nv : ev_sort) {
705 const symbol & s = ex_to<symbol>(nv.op(1));
706 if(
false && !islower(s.get_name()[0])) {
707 cout <<
"Replacement: " << Replacement << endl;
708 cout <<
"IBPvec: " << IBPvec << endl;
709 throw Error(
"FIRE: Fermat requires a name must begin with a lower case letter: "+s.get_name());
711 config << (first ?
"" :
",") << s;
712 auto itr = NVariables.find(nv.op(1));
713 if(itr!=NVariables.end()) config <<
"->" << itr->second;
718 if(PosPref!=1) config <<
"#pos_pref "<< PosPref << endl;
719 config <<
"#database db" << ProblemNumber << endl;
720 config <<
"##prime 111" << endl;
721 if(allIBP) config <<
"#allIBP" << endl;
722 config <<
"#start" << endl;
724 if(SECTOR.nops()==pdim) {
726 for(
int i=pdim-1; i>=0; i--) {
727 if(SECTOR.op(i)!=0) {
733 for(
int i=0; i<pdim; i++) {
734 if(SECTOR.op(i)!=0) {
739 config <<
"#problem " << pn <<
" ";
740 if(pmin>1) config <<
"|" << pmin <<
"," << pmax <<
"|";
741 else if(pmax!=pdim) config <<
"|" << pmax <<
"|";
742 config << ProblemNumber <<
".start" << endl;
743 }
else config <<
"#problem " << pn <<
" " << ProblemNumber <<
".start" << endl;
745 config <<
"#output " << ProblemNumber <<
".tables" << endl;
747 if(PIntegral.nops()>0) {
750 int nn = PIntegral.nops();
751 for(
int i=0; i<nn; i++) {
752 if(PIntegral.op(i).nops()!=pdim)
throw Error(
"FIRE::Export@1, Index dimension NOT match Propagator.");
753 oss <<
"{" << pn <<
"," << PIntegral.op(i) << (i<nn-1 ?
"}," :
"}");
756 ofstream pref_out(WorkingDir+
"/"+spn+
".pref");
757 pref_out << oss.str() << endl;
759 config <<
"#preferred " << ProblemNumber <<
".pref" << endl;
762 config <<
"#integrals " << ProblemNumber <<
".intg" << endl;
764 ofstream config_out(WorkingDir+
"/"+spn+
".config");
765 config_out << config.str() << endl;
775 for(
int i=0; i<Integral.nops(); i++) {
776 if(Integral[i].nops()!=pdim)
throw Error(
"FIRE::Export@2, Index dimension NOT match Propagator.");
777 intg <<
"{" << pn <<
"," << Integral[i] << (i<Integral.nops()-1 ?
"}," :
"}");
781 ofstream intg_out(WorkingDir+
"/"+spn+
".intg");
782 intg_out << intg.str() << endl;
788 garWrite(TO(), WorkingDir+
"/"+spn+
".gar");
796 if(IsAlwaysZero)
return;
798 if(
file_exists(WorkingDir +
"/" + to_string(ProblemNumber) +
".tables"))
return;
799 if(Integral.nops()<1)
return;
804 cmd <<
"cd " << WorkingDir <<
" && " << Execute;
806 if(opt==
"") cmd <<
" -silent -t " << T1 <<
"," << T2 <<
" -lt " << LT1 <<
"," << LT2;
807 else cmd <<
" " << opt;
809 cmd <<
" -c " << ProblemNumber <<
" 1>/dev/null 2>&1";
810 auto rc = system(cmd.str().c_str());
811 rc = system((
"rm -rf "+WorkingDir+
"/db"+to_string(ProblemNumber)).c_str());
812 if(
file_exists(WorkingDir +
"/" + to_string(ProblemNumber) +
".tables"))
break;
815 if(!
file_exists(WorkingDir +
"/" + to_string(ProblemNumber) +
".tables")) {
816 cout <<
"Propagator: " << Propagator << endl;
817 throw Error(
"FIRE::Run failed!");
824 void FIRE::Import() {
825 if(IsAlwaysZero)
return;
826 if(Integral.nops()<1)
return;
827 string spn = to_string(ProblemNumber);
828 ifstream ifs(WorkingDir+
"/"+spn+
".tables");
829 string ostr((istreambuf_iterator<char>(ifs)), (istreambuf_iterator<char>()));
833 for(
auto & c : ostr)
if(c==
'"') c =
' ';
836 auto tp_lst = tp.
Read(ostr);
838 for(
auto item : tp_lst.op(1)) {
839 if(!is_zero(item.op(1).op(0)))
throw Error(
"FIRE::Reduce: pn is NOT 0.");
840 id2F[item.op(0)] = F(ProblemNumber, item.op(1).op(1));
843 for(
auto item : tp_lst.op(0)) {
844 ex left = item.op(0).subs(id2F);
846 for(
auto it : item.op(1)) {
847 right += it.op(0).subs(id2F) * it.op(1);
849 if(left.is_equal(right)) MIntegral.append(left);
850 else Rules.append(left==right);
857 if(reCut && Cut.nops()>0) {
859 auto mis = MIntegral;
860 MIntegral.remove_all();
868 for(
auto item : mis) {
869 lst mi = ex_to<lst>(item.op(1));
872 if(!is_zero(mi.op(ex_to<numeric>(cx).to_int()-1)-1)) {
878 if(nrun==0 && isOK) MIntegral.append(item);
886 vector<int> ipos, ineg;
887 for(
int i=0; i<mi.nops(); i++) {
890 if(is_zero(cx-1-i)) {
895 if(isCut) pi.let_op(i)=1;
896 else if(mi.op(i)<=0) ineg.push_back(i);
897 else ipos.push_back(i);
902 ex total = pow(numeric(max), ineg.size());
903 for(numeric in=0; in<total; in++) {
906 for(
int i=0; i<ineg.size(); i++) {
907 int re = mod(cin,max).to_int();
908 pi2.let_op(ineg[i]) = ex(0)-re;
915 total = pow(numeric(max2), ipos.size());
917 for(numeric in=0; in<total; in++) {
920 for(
int i=0; i<ipos.size(); i++) {
921 int re = mod(cin,max2).to_int();
922 pi2.let_op(ipos[i]) = re-max;
951 fire.
WorkingDir = WorkingDir +
"_C"+to_string(ProblemNumber);
953 auto rc = system((
"rm -rf " + fire.
WorkingDir).c_str());
956 vis_chk = ex_to<lst>(
subs(vis_chk, fire.
Rules));
957 if(vis_chk.is_equal(vis))
break;
960 find(vis,F(
w1,
w2),fs);
962 for(
auto item : fs) mis.append(item);
967 for(
int i=0; i<ois.nops(); i++) c2m[ois.op(i)] = vis.op(i);
968 for(
auto item : mis) MIntegral.append(item);
976 for(
auto r : rules) {
979 for(
auto item : MIntegral) {
980 if(item.is_equal(ri)) {
982 rIntegral.append(ri);
988 rIntegral.append(rv);
989 Rules.append(ri==rv.subs(c2m));
995 find(rIntegral,F(
w1,
w2),fs);
996 MIntegral.remove_all();
997 for(
auto fi : fs) MIntegral.append(fi);
bool file_exists(const char *fn)
class used to wrap error message
IBP reduction using FIRE program.
static void RRTables(const string &filename, int pnum)
static void ThieleTables(const string &filename, int si, int ei)
void Export() override
Export start config intgral etc. files.
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)
bool file_exists(string fn)
lst syms(const exvector &ev)
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)