HepLib
FIRE.cpp
Go to the documentation of this file.
1 
6 #include "IBP.h"
7 #include <cmath>
8 
9 namespace HepLib {
10 
11  // FROM FIRE6.m
12  namespace {
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};
57  }
58 
59  void FIRE::RRTables(const string & filename, int pnum) {
60  if(pnum<1) return;
61  exvector _tables(pnum);
62  unsigned int nmin = 0;
63  for(int i=0; i<pnum; i++) {
64  string fn = filename;
65  string_replace_all(fn, ".tables", "-"+to_string(i+1)+".tables");
66  ifstream ifs(fn);
67  string ostr((istreambuf_iterator<char>(ifs)), (istreambuf_iterator<char>()));
68  ifs.close();
69  string_replace_all(ostr, "\"", "");
70  Parser tp;
71  _tables[i] = tp.Read(ostr);
72  auto nn = _tables[i].op(1).nops();
73  if(i==0 || nmin>nn) nmin = nn;
74  }
75  exvector tables;
76  vector<numeric> primes;
77  ex convs = 0;
78  for(int i=0; i<_tables.size(); i++) {
79  auto nn = _tables[i].op(1).nops();
80  if(nmin<nn) {
81  cout << "RRTables: current table will be dropped." << endl;
82  continue;
83  }
84  if(!is_a<lst>(convs)) convs = _tables[i].op(1); // second part is equal
85  else if(!convs.is_equal(_tables[i].op(1))) {
86  throw Error("RRT: convs are different.");
87  }
88  tables.push_back(_tables[i].op(0));
89  primes.push_back(HardCodedPrimes[i+1]);
90  }
91 
92  vector<pair<ex,vector<pair<ex,exvector>>>> int_mi_cs_vec;
93  int ci = 0;
94  for(int i=0; i<tables.size(); i++) {
95  if(i==0) {
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);
104  }
105  int_mi_cs_vec.push_back(int_mi_cs);
106  }
107  } else {
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));
116  }
117  }
118  }
119  }
120 
121  std::ofstream ofs;
122  ofs.open(filename, ios::out);
123  ofs << "{" << endl;
124  ofs << " {" << endl;
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;
128  ofs << " {" << 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));
134  ofs << "\"" << RationalReconstruct(nvec,primes) << "\"}";
135  if(j+1<imc.second.size()) ofs << ",";
136  ofs << endl;
137  }
138  ofs << " }" << endl;
139  ofs << " }";
140  if(i+1<int_mi_cs_vec.size()) ofs << ",";
141  ofs << endl;
142  }
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 << ",";
148  ofs << endl;
149  }
150  ofs << " }" << endl;
151  ofs << "}" << endl;
152  ofs.close();
153  }
154 
155  void FIRE::ThieleTables(const string & filename, int si, int ei) {
156  int pnum = 40;
157  map<int,ex> _tables;
158  int nd;
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;
164  string_replace_all(fn, ".tables", "-"+to_string(i)+".tables");
165  ifstream ifs(fn);
166  string ostr((istreambuf_iterator<char>(ifs)), (istreambuf_iterator<char>()));
167  ifs.close();
168  for(auto & c : ostr) if(c=='\"') c = ' ';
169  Parser tp;
170  _tables[i] = tp.Read(ostr);
171  auto nn = _tables[i].op(1).nops();
172  if(i==si || nmin>nn) nmin = nn;
173  }
174  cout << endl;
175 
176  exvector tables;
177  exvector keys;
178  ex convs = 0;
179  for(int i=si; i<=ei; i++) {
180  auto nn = _tables[i].op(1).nops();
181  if(nmin<nn) {
182  cout << "ThieleTables: current table will be dropped." << endl;
183  continue;
184  }
185  if(!is_a<lst>(convs)) convs = _tables[i].op(1); // second part is equal
186  else if(!convs.is_equal(_tables[i].op(1))) {
187  throw Error("RRT: convs are different.");
188  }
189  tables.push_back(_tables[i].op(0));
190  keys.push_back(i);
191  }
192 
193  vector<pair<ex,vector<pair<ex,exvector>>>> int_mi_cs_vec;
194  int ci = 0;
195  for(int i=0; i<tables.size(); i++) {
196  if(i==0) {
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);
205  }
206  int_mi_cs_vec.push_back(int_mi_cs);
207  }
208  } else {
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));
217  }
218  }
219  }
220  }
221 
222  std::ofstream ofs;
223  ofs.open(filename, ios::out);
224  ofs << "{" << endl;
225  ofs << " {" << endl;
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;
231  ofs << " {" << 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 << ",";
239  ofs << endl;
240  }
241  ofs << " }" << endl;
242  ofs << " }";
243  if(i+1<int_mi_cs_vec.size()) ofs << ",";
244  ofs << endl;
245  }
246  cout << endl;
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 << ",";
252  ofs << endl;
253  }
254  ofs << " }" << endl;
255  ofs << "}" << endl;
256  ofs.close();
257  }
258 
262  void FIRE::Export() {
263  if(WorkingDir=="") WorkingDir = to_string(getpid())+"IBP";
264  int pdim = Propagator.nops();
265  string spn = to_string(ProblemNumber);
266  int pn = 0; // to avoid unsigned short overflow in FIRE
267 
268  if(!file_exists(WorkingDir+"/"+spn+".start") || !file_exists(WorkingDir+"/"+spn+".config")) {
269 
270  if(Integral.nops()<1) return;
271  lst InExternal;
272  for(auto ii : Internal) InExternal.append(ii);
273  for(auto ii : External) InExternal.append(ii);
274 
275  if(ISP.nops()<1) {
276  for(auto it : Internal) {
277  for(auto ii : InExternal) ISP.append(it*ii);
278  }
279  ISP.sort();
280  ISP.unique();
281  }
282 
283  if(ISP.nops() > pdim) {
284  cout << "ISP = " << ISP << endl;
285  cout << "Propagator = " << Propagator << endl;
286  throw Error("FIRE::Export: #(ISP) > #(Propagator).");
287  }
288 
289  lst sp2s, s2sp, ss;
290  int _pic=0;
291  for(auto item : ISP) {
292  _pic++;
293  Symbol si("P"+to_string(_pic));
294  ss.append(si);
295  sp2s.append(w*item==w*si);
296  sp2s.append(item==si);
297  s2sp.append(si==item);
298  }
299 
300  if(!has_w(Replacement)) {
301  lst repl;
302  for(auto item : Replacement) {
303  repl.append(item);
304  repl.append(w*item.op(0) == w*item.op(1));
305  }
306  Replacement = repl;
307  }
308 
309  lst eqns;
310  for(int i=0; i<ISP.nops(); i++) { // note NOT pdim
311  auto eq = expand(Propagator.op(i)).subs(iEpsilon==0); // drop iEpsilon
312  eq = eq.subs(sp2s);
313  eq = eq.subs(Replacement);
314  if(eq.has(iWF(w))) throw Error("FIRE::Export, iWF used in eq.");
315  eqns.append(eq == iWF(i));
316  }
317  auto s2p = lsolve(eqns, ss);
318  if(s2p.nops() != ISP.nops()) {
319  cout << "ISP=" << ISP << endl;
320  cout << "Propagator=" << Propagator << endl;
321  cout << "eqns=" << eqns << endl;
322  throw Error("FIRE::Export: lsolve failed.");
323  }
324 
325  // FIRE version
326  if(true)
327  if(DSP.nops()<1) {
328  for(auto p1 : Internal)
329  for(auto p2 : InExternal)
330  DSP.append(lst{p1,p2});
331  }
332 
333  // Lee version
334  if(false)
335  if(DSP.nops()<1) {
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});
339  DSP.append(lst{Internal, Internal});
340  allIBP = true;
341  }
342 
343  vector<exmap> ibps;
344  exvector IBPvec;
345  lst ns0;
346  for(int i=0; i<pdim; i++) ns0.append(0);
347 
348  for(auto sp : DSP) {
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 };
354  }
355 
356  exmap nc_map;
357  for(int ilst=0; ilst<ilp_lst.nops(); ilst++) {
358  symbol ss;
359  auto ilp = ilp_lst.op(ilst);
360  auto iep = iep_lst.op(ilst);
361  lst dp_lst;
362  for(int i=0; i<pdim; i++) {
363  dp_lst.append(Propagator.op(i).subs(ilp==ss).diff(ss).subs(ss==ilp));
364  }
365 
366  for(int i=0; i<pdim; i++) { // diff on each propagator
367  auto ns = ns0;
368  ns.let_op(i) = ns.op(i)+1; // note the covention
369  auto tmp = dp_lst.op(i) * iep;
370  tmp = expand(tmp);
371  tmp = tmp.subs(Replacement);
372  tmp = tmp.subs(sp2s);
373  tmp = tmp.subs(s2p);
374  tmp = tmp.subs(Replacement);
375 
376  tmp = ex(0) - (Shift[i+1]+a(i+1))*tmp; // note Shift here
377 
378  for(int j=0; j<pdim; j++) {
379  auto cj = tmp.coeff(iWF(j));
380  if(is_zero(cj)) continue;
381  lst cns = ns;
382  cns.let_op(j) = cns.op(j)-1; // note the covention
383  nc_map[cns] = nc_map[cns] + cj;
384  }
385  tmp = tmp.subs(iWF(w)==0); // constant term
386  if(!is_zero(tmp)) nc_map[ns] = nc_map[ns] + tmp;
387  }
388 
389  auto cilp = iep.coeff(ilp);
390  if(!is_zero(cilp)) nc_map[ns0] = nc_map[ns0] + d*cilp;
391  }
392 
393  bool ok = false;
394  for(auto nc : nc_map) {
395  if(!is_zero(nc.second)) {
396  ok = true;
397  IBPvec.push_back(nc.second);
398  }
399  }
400  if(ok) ibps.push_back(nc_map);
401  }
402 
403  auto Variables = gather_symbols(IBPvec);
404  for(auto e : External) {
405  if(Variables.has(e)) {
406  cout << "IBPvec: " << IBPvec << endl;
407  cout << "Replacement: " << Replacement << endl;
408  cout << "Variables: " << Variables << endl;
409  throw Error("FIRE: Replacement NOT work!");
410  }
411  }
412 
413  ostringstream start;
414 
415  start << "ExampleDimension[" << pn << "]=" << pdim << endl << endl;
416  start << "ProblemNumber=" << pn << endl << endl;
417 
418  // .start - SBasisL
419  if(Version==5) {
420  PermutationsR(2, pdim, [pdim,pn,&start](const int *ns) {
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;
424  });
425  }
426 
427  // .start - SBasis0L, SBasis0D && SBasis0C
428  start << "SBasis0L[" << pn << "]=" << ibps.size() << endl << endl;
429  ostringstream oss;
430  for(int i=0; i<ibps.size(); i++) {
431  start << "SBasis0D[" << pn << "," << (i+1) << "]=";
432  lst items;
433  for(auto kv : ibps[i]) {
434  items.append(kv.first);
435  if(Version==5) {
436  oss << "SBasis0C[" << pn << "," << (i+1) << "," << kv.first << "]=" <<
437  collect_common_factors(kv.second.normal()) << endl << endl;
438  } else {
439  lst olst;
440  auto cv_lst = collect_lst(kv.second, a(w));
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});
449  }
450  oss << "SBasis0C[" << pn << "," << (i+1) << "," << kv.first << "]=" << olst << endl << endl;
451  }
452  }
453  start << items << endl << endl;
454  }
455  start << oss.str();
456 
457  // .start - SBasisS
458  start << "SBasisS[" << pn << "]={{{";
459  // 1,2,3,...
460  for(int i=0; i<pdim; i++) start << (i+1) << (i<pdim-1 ? "," : "");
461  start << "},{";
462  // 1,1,1,...
463  for(int i=0; i<pdim; i++) start << 1 << (i<pdim-1 ? "," : "");
464  start << "},{";
465  // 0,0,0,...
466  for(int i=0; i<pdim; i++) start << 0 << (i<pdim-1 ? "," : "");
467  start << "}}}" << endl << endl;
468 
469  // .start - SBasisR
470  lst Rlst;
471  Rlst.append(lst{});
472  for(int i=0; i<pdim; i++) {
473  let_op_append(Rlst, 0, -1);
474  }
475  for(auto lpi : Internal) {
476  vector<int> ns_vec;
477  lst ns0;
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);
482  }
483  size_t tot = std::pow(2LL,ns_vec.size());
484  for(size_t n=0; n<tot; n++) {
485  int cn = n;
486  lst ns1 = ns0;
487  for(int j=0; j<ns_vec.size(); j++) {
488  if((cn%2)==1) ns1.let_op(ns_vec[j]) = -1;
489  cn /= 2;
490  }
491  Rlst.append(ns1);
492  }
493  }
494 
495  // Lee Zero Sector
496  if(true) {
497  exset sectors;
498  IsAlwaysZero = true;
499  lst ns0;
500  for(int i=0; i<pdim; i++) ns0.append(1);
501  size_t tot = std::pow(2LL,pdim);
502 
503  for(size_t n=0; n<tot; n++) {
504  int cn = n;
505  lst sector = ns0;
506  for(int j=0; j<pdim; j++) {
507  if((cn%2)==1) sector.let_op(j) = 0;
508  cn /= 2;
509  }
510  if(SECTOR.nops()==pdim) {
511  for(int j=0; j<pdim; j++) if(sector.op(j)>SECTOR.op(j)) goto add_sector_done;
512  }
513  sectors.insert(sector);
514  add_sector_done: ;
515  }
516 
517  while(!sectors.empty()) {
518  auto first = *(sectors.begin());
519  sectors.erase(first);
520 
521  auto sector = ex_to<lst>(first);
522  if(IsZero(sector)) { // from LiteRed: all subsector is zero
523  lst ns1 = sector;
524  for(int j=0; j<pdim; j++) {
525  if(sector.op(j).is_zero()) ns1.let_op(j) = -1;
526  }
527  Rlst.append(ns1);
528  exset subsets;
529  for(auto item : sectors) {
530  bool ok = true;
531  for(int j=0; j<pdim; j++) {
532  if(sector.op(j)<item.op(j)) { ok = false; break; }
533  }
534  if(ok) subsets.insert(item);
535  }
536  for(auto item : subsets) {
537  sectors.erase(item);
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;
541  }
542  Rlst.append(ns1);
543  }
544  } else { // from LiteRed: all supersector is non-zero
545  if(IsAlwaysZero) IsAlwaysZero = false;
546  exset supsets;
547  for(auto item : sectors) {
548  bool ok = true;
549  for(int j=0; j<pdim; j++) {
550  if(sector.op(j)>item.op(j)) { ok = false; break; }
551  }
552  if(ok) supsets.insert(item);
553  }
554  for(auto item : supsets) sectors.erase(item);
555  }
556  }
557 
558  if(IsAlwaysZero) {
559  Rules.remove_all();
560  for(auto ii : Integral) Rules.append(F(ProblemNumber, ii)==0);
561  return;
562  }
563  }
564 
565  // handle Cut Propagator
566  if(Cut.nops()>0) {
567  for(auto cx : Cut) {
568  int ci = ex_to<numeric>(cx-1).to_int(); // start from 1 in Cut
569  lst ns0;
570  for(int i=0; i<pdim; i++) ns0.append(1);
571  ns0.let_op(ci) = -1;
572  for(int n=0; n<std::pow(2,pdim-1); n++) {
573  int cn = n;
574  lst ns1 = ns0;
575  for(int j=0; j<pdim; j++) {
576  if(ci==j) continue;
577  if((cn%2)==1) ns1.let_op(j) = -1;
578  cn /= 2;
579  }
580  Rlst.append(ns1);
581  }
582  }
583  }
584 
585  Rlst.sort();
586  Rlst.unique();
587  //sort_lst(Rlst);
588 
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;
593  }
594 
595  // .start - Others
596  start << "SBasisRL[" << pn << "]=0" << endl << endl;
597  start << "HPI[" << pn << "]={}" << endl << endl;
598 
599  string sss = start.str();
600  string_replace_all(sss, "=", " = ");
601  string_replace_all(sss, ",", ", ");
602 
603  if(!dir_exists(WorkingDir)) auto rc = system(("mkdir -p " + WorkingDir).c_str());
604 
605  ofstream start_out(WorkingDir+"/"+spn+".start");
606  start_out << sss << endl;
607  start_out.close();
608 
609  // .config
610  {
611  ostringstream config;
612 
613  config << "#variables ";
614  bool first = true;
615  exvector ev_sort;
616  for(auto v : Variables) {
617  auto fw = fermat_weight.find(v);
618  if(fw!=fermat_weight.end()) ev_sort.push_back(lst{ fw->second, v });
619  else ev_sort.push_back(lst{ 0, v });
620  }
621  sort_vec(ev_sort);
622  for(auto nv : ev_sort) {
623  const symbol & s = ex_to<symbol>(nv.op(1));
624  if(false && !islower(s.get_name()[0])) {
625  cout << "Replacement: " << Replacement << endl;
626  cout << "IBPvec: " << IBPvec << endl;
627  throw Error("FIRE: Fermat requires a name must begin with a lower case letter: "+s.get_name());
628  }
629  config << (first ? "" : ",") << s;
630  auto itr = NVariables.find(nv.op(1));
631  if(itr!=NVariables.end()) config << "->" << itr->second;
632  first=false;
633  }
634  config << endl;
635 
636  if(PosPref!=1) config << "#pos_pref "<< PosPref << endl;
637  config << "#database db" << ProblemNumber << endl;
638  config << "##prime 111" << endl; // ## for comment
639  if(allIBP) config << "#allIBP" << endl;
640  config << "#start" << endl;
641 
642  if(SECTOR.nops()==pdim) {
643  int pmax = pdim;
644  for(int i=pdim-1; i>=0; i--) {
645  if(SECTOR.op(i)!=0) {
646  pmax = i+1;
647  break;
648  }
649  }
650  int pmin = -1;
651  for(int i=0; i<pdim; i++) {
652  if(SECTOR.op(i)!=0) {
653  pmin = i+1;
654  break;
655  }
656  }
657  config << "#problem " << pn << " ";
658  if(pmin>1) config << "|" << pmin << "," << pmax << "|";
659  else if(pmax!=pdim) config << "|" << pmax << "|";
660  config << ProblemNumber << ".start" << endl;
661  } else config << "#problem " << pn << " " << ProblemNumber << ".start" << endl;
662 
663  config << "#output " << ProblemNumber << ".tables" << endl;
664 
665  if(PIntegral.nops()>0) {
666  ostringstream oss;
667  oss << "{";
668  int nn = PIntegral.nops();
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 ? "}," : "}");
672  }
673  oss << "}";
674  ofstream pref_out(WorkingDir+"/"+spn+".pref");
675  pref_out << oss.str() << endl;
676  pref_out.close();
677  config << "#preferred " << ProblemNumber << ".pref" << endl;
678  }
679 
680  config << "#integrals " << ProblemNumber << ".intg" << endl;
681 
682  ofstream config_out(WorkingDir+"/"+spn+".config");
683  config_out << config.str() << endl;
684  config_out.close();
685  }
686 
687  }
688 
689  // *.intg
690  if(!file_exists(WorkingDir+"/"+spn+".intg")) {
691  ostringstream intg;
692  intg << "{";
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 ? "}," : "}");
696  }
697  intg << "}" << endl;
698 
699  ofstream intg_out(WorkingDir+"/"+spn+".intg");
700  intg_out << intg.str() << endl;
701  intg_out.close();
702  }
703 
704  // export .gar here
705  if(!file_exists(WorkingDir+"/"+spn+".gar")) {
706  garWrite(TO(), WorkingDir+"/"+spn+".gar");
707  }
708  }
709 
713  void FIRE::Run() {
714  if(IsAlwaysZero) return;
715  if(Execute=="") Execute = InstallPrefix + "/FIRE/M/FIRE";
716  if(file_exists(WorkingDir + "/" + to_string(ProblemNumber) + ".tables")) return;
717  if(Integral.nops()<1) return;
718  int tried = 0;
719  while(tried<3) {
720  tried++;
721  ostringstream cmd;
722  cmd << "cd " << WorkingDir << " && " << Execute;
723  if(Version>5) {
724  if(opt=="") cmd << " -silent -t " << T1 << "," << T2 << " -lt " << LT1 << "," << LT2;
725  else cmd << " " << opt;
726  }
727  cmd << " -c " << ProblemNumber << " 1>/dev/null 2>&1";
728  auto rc = system(cmd.str().c_str());
729  rc = system(("rm -rf "+WorkingDir+"/db"+to_string(ProblemNumber)).c_str());
730  if(file_exists(WorkingDir + "/" + to_string(ProblemNumber) + ".tables")) break;
731  sleep(3);
732  }
733  if(!file_exists(WorkingDir + "/" + to_string(ProblemNumber) + ".tables")) {
734  cout << "Propagator: " << Propagator << endl;
735  throw Error("FIRE::Run failed!");
736  }
737  }
738 
742  void FIRE::Import() {
743  if(IsAlwaysZero) return;
744  if(Integral.nops()<1) return;
745  string spn = to_string(ProblemNumber);
746  ifstream ifs(WorkingDir+"/"+spn+".tables");
747  string ostr((istreambuf_iterator<char>(ifs)), (istreambuf_iterator<char>()));
748  ifs.close();
749 
750  //string_replace_all(ostr, "\"", "");
751  for(auto & c : ostr) if(c=='"') c = ' ';
752 
753  Parser tp;
754  auto tp_lst = tp.Read(ostr);
755  exmap id2F;
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.");
758  id2F[item.op(0)] = F(ProblemNumber, item.op(1).op(1));
759  }
760 
761  for(auto item : tp_lst.op(0)) {
762  ex left = item.op(0).subs(id2F);
763  ex right = 0;
764  for(auto it : item.op(1)) {
765  right += it.op(0).subs(id2F) * it.op(1);
766  }
767  if(left.is_equal(right)) MIntegral.append(left);
768  else Rules.append(left==right);
769  }
770  MIntegral.sort();
771  MIntegral.unique();
773 
774  // handle Cut not equal 1, using #preferred
775  if(reCut && Cut.nops()>0) {
776  lst ois, vis;
777  auto mis = MIntegral;
778  MIntegral.remove_all();
779  int nrun = -1;
780  while(true) {
781  nrun++;
782  if(nrun>100) break;
783 
784  lst iis, pis;
785  bool allOK = true;
786  for(auto item : mis) {
787  lst mi = ex_to<lst>(item.op(1));
788  bool isOK = true;
789  for(auto cx : Cut) {
790  if(!is_zero(mi.op(ex_to<numeric>(cx).to_int()-1)-1)) {
791  isOK = false;
792  allOK = false;
793  break;
794  }
795  }
796  if(nrun==0 && isOK) MIntegral.append(item);
797  else if(!isOK) {
798  if(nrun==0) {
799  ois.append(item);
800  vis.append(item);
801  }
802  iis.append(mi);
803  auto pi = mi;
804  vector<int> ipos, ineg;
805  for(int i=0; i<mi.nops(); i++) {
806  bool isCut = false;
807  for(auto cx : Cut) {
808  if(is_zero(cx-1-i)) {
809  isCut = true;
810  break;
811  }
812  }
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);
816  }
817 
818  lst tis;
819  int max = 2;
820  ex total = pow(numeric(max), ineg.size());
821  for(numeric in=0; in<total; in++) {
822  auto cin = in;
823  auto pi2 = pi;
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;
827  cin = (cin-re)/max;
828  }
829  tis.append(pi2);
830  }
831 
832  int max2 = 2*max+1;
833  total = pow(numeric(max2), ipos.size());
834  for(auto pi : tis) {
835  for(numeric in=0; in<total; in++) {
836  auto cin = in;
837  auto pi2 = pi;
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;
841  cin = (cin-re)/max2;
842  }
843  pis.append(pi2);
844  }
845  }
846  }
847  }
848  if(allOK) break;
849 
850  // Reduce again
851  pis.sort();
852  pis.unique();
853  iis.sort();
854  iis.unique();
855  if(pis.nops()>0) {
856  FIRE fire;
857  fire.Propagator = Propagator;
858  fire.Internal = Internal;
859  fire.External = External;
860  fire.Replacement = Replacement;
862  fire.ISP = ISP;
863  fire.DSP = DSP;
864  fire.Cut = Cut;
865  fire.reCut = false;
866  fire.Shift = Shift;
867  fire.Integral = iis;
868  fire.PIntegral = pis;
869  fire.WorkingDir = WorkingDir + "_C"+to_string(ProblemNumber);
870  fire.Reduce();
871  auto rc = system(("rm -rf " + fire.WorkingDir).c_str());
872 
873  auto vis_chk = vis;
874  vis_chk = ex_to<lst>(subs(vis_chk, fire.Rules));
875  if(vis_chk.is_equal(vis)) break;
876  vis = vis_chk;
877  exset fs;
878  find(vis,F(w1,w2),fs);
879  mis.remove_all();
880  for(auto item : fs) mis.append(item);
881  } else break;
882  }
883 
884  exmap c2m;
885  for(int i=0; i<ois.nops(); i++) c2m[ois.op(i)] = vis.op(i);
886  for(auto item : mis) MIntegral.append(item);
887  MIntegral.sort();
888  MIntegral.unique();
890 
891  auto rules = Rules;
892  Rules.remove_all();
893  lst rIntegral;
894  for(auto r : rules) {
895  auto ri = r.op(0);
896  bool isMI = false;
897  for(auto item : MIntegral) {
898  if(item.is_equal(ri)) {
899  isMI = true;
900  rIntegral.append(ri);
901  break;
902  }
903  }
904  if(isMI) continue;
905  auto rv = r.op(1);
906  rIntegral.append(rv);
907  Rules.append(ri==rv.subs(c2m));
908  }
909 
910  rIntegral.sort();
911  rIntegral.unique();
912  exset fs;
913  find(rIntegral,F(w1,w2),fs);
914  MIntegral.remove_all();
915  for(auto fi : fs) MIntegral.append(fi);
917  }
918  }
919 
920 }
int * a
Definition: Functions.cpp:234
IBP header file.
class used to wrap error message
Definition: BASIC.h:242
IBP reduction using FIRE program.
Definition: IBP.h:68
static void RRTables(const string &filename, int pnum)
Definition: FIRE.cpp:59
int T2
Definition: IBP.h:77
static int Version
Definition: IBP.h:82
int T1
Definition: IBP.h:75
string Execute
Definition: IBP.h:80
void Import() override
Import tables
Definition: FIRE.cpp:742
int LT1
Definition: IBP.h:76
int PosPref
Definition: IBP.h:74
static void ThieleTables(const string &filename, int si, int ei)
Definition: FIRE.cpp:155
void Export() override
Export start config intgral etc. files.
Definition: FIRE.cpp:262
string opt
Definition: IBP.h:79
int LT2
Definition: IBP.h:78
exmap NVariables
Definition: IBP.h:81
void Run() override
Run FIRE reduction.
Definition: FIRE.cpp:713
bool allIBP
Definition: IBP.h:70
lst Internal
Definition: IBP.h:27
lst MIntegral
Definition: IBP.h:42
map< int, ex > Shift
Definition: IBP.h:36
lst PIntegral
Definition: IBP.h:40
lst ISP
Definition: IBP.h:34
lst Replacement
Definition: IBP.h:29
void Reduce()
ex TO()
Definition: IBP.cpp:60
lst DSP
Definition: IBP.h:33
bool reCut
Definition: IBP.h:37
lst Cut
Definition: IBP.h:32
lst Integral
Definition: IBP.h:31
lst External
Definition: IBP.h:28
lst Propagator
Definition: IBP.h:30
bool IsAlwaysZero
Definition: IBP.h:44
int ProblemNumber
Definition: IBP.h:39
string WorkingDir
Definition: IBP.h:38
bool IsZero(ex sector)
Definition: IBP.cpp:742
lst Rules
Definition: IBP.h:43
lst SECTOR
Definition: IBP.h:35
class to parse for string or file, helpful with Symbol class
Definition: BASIC.h:645
ex Read(const string &instr, bool s2S=true)
Definition: Functions.cpp:111
class extended to GiNaC symbol class, represent a positive symbol
Definition: BASIC.h:113
HepLib namespace.
Definition: BASIC.cpp:17
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
lst gather_symbols(const ex &e)
get all symbols from input expression
Definition: BASIC.cpp:539
map< ex, long long, ex_is_less > fermat_weight
Definition: Init.cpp:152
numeric RationalReconstruct(numeric a, numeric p)
Definition: Rational.cpp:8
ex Thiele(const exvector &keys, const exvector &values, const ex &d)
Definition: Rational.cpp:81
bool file_exists(string fn)
Definition: BASIC.h:289
bool has_w(const ex &e)
Definition: BASIC.cpp:2223
ex w
Definition: Init.cpp:90
const Symbol d
string InstallPrefix
Definition: Init.cpp:159
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:1222
void sort_vec(exvector &ivec, bool less=true)
sort the list in less order, or the reverse
Definition: Sort.cpp:54
void sort_lst(lst &ilst, bool less=true)
sort the list in less order, or the reverse
Definition: Sort.cpp:79
void string_replace_all(string &str, const string &from, const string &to)
Definition: Functions.cpp:148
void garWrite(const string &garfn, const map< string, ex > &resMap)
garWrite to write the string-key map to the archive
Definition: BASIC.cpp:639
void let_op_append(ex &ex_in, const ex item)
append item into expression
Definition: BASIC.cpp:1324
bool dir_exists(string dir)
Definition: BASIC.h:297
ex w1
Definition: BASIC.h:499
ex w2
Definition: BASIC.h:499
void PermutationsR(int n, int m, std::function< void(const int *)> f)
Definition: Functions.cpp:268
ex subs(const ex &e, init_list sl)
Definition: BASIC.h:51