HepLib
Direct.cpp
Go to the documentation of this file.
1 
6 #include "IBP.h"
7 #include <cmath>
8 
9 namespace HepLib {
10 
11  static matrix RowReduce(matrix mat) {
12  Fermat &fermat = Fermat::get();
13  int &v_max = fermat.vmax;
14 
15  lst rep_vs;
16  ex tree = mat;
17  for(const_preorder_iterator i = tree.preorder_begin(); i != tree.preorder_end(); ++i) {
18  auto e = (*i);
19  if(is_a<symbol>(e) || e.match(a(w))) rep_vs.append(e);
20  }
21  rep_vs.sort();
22  rep_vs.unique();
23  //sort_lst(rep_vs);
24 
25  exmap v2f;
26  symtab st;
27  int fvi = 0;
28  for(auto vi : rep_vs) {
29  auto name = "v" + to_string(fvi);
30  v2f[vi] = Symbol(name);
31  st[name] = vi;
32  fvi++;
33  }
34 
35  stringstream ss;
36  if(fvi>111) {
37  cout << rep_vs << endl;
38  throw Error("Fermat: Too many variables.");
39  }
40  if(fvi>v_max) {
41  for(int i=v_max; i<fvi; i++) ss << "&(J=v" << i << ");" << endl;
42  fermat.Execute(ss.str());
43  ss.clear();
44  ss.str("");
45  v_max = fvi;
46  }
47 
48  int nrow = mat.rows();
49  int ncol = mat.cols();
50 
51  ss << "Array m[" << nrow << "," << ncol+1 << "];" << endl;
52  fermat.Execute(ss.str());
53  ss.clear();
54  ss.str("");
55 
56  ss << "[m]:=[(";
57  for(int c=0; c<ncol; c++) {
58  for(int r=0; r<nrow; r++) {
59  ss << mat(r,c).subs(iEpsilon==0).subs(v2f) << ",";
60  }
61  }
62  for(int r=0; r<nrow; r++) ss << "0,";
63  ss << ")];" << endl;
64  ss << "Redrowech([m]);" << endl;
65  auto tmp = ss.str();
66  string_replace_all(tmp,",)]",")]");
67  fermat.Execute(tmp);
68  ss.clear();
69  ss.str("");
70 
71  ss << "&(U=1);" << endl; // ugly printing, the whitespace matters
72  ss << "![m" << endl;
73  auto ostr = fermat.Execute(ss.str());
74  ss.clear();
75  ss.str("");
76  //fermat.Exit();
77 
78  // note the order, before exfactor (normal_fermat will be called again here)
79  ss << "&(U=0);" << endl; // disable ugly printing
80  ss << "@([m]);" << endl;
81  ss << "&_G;" << endl;
82  fermat.Execute(ss.str());
83  ss.clear();
84  ss.str("");
85 
86  // make sure last char is 0
87  if(ostr[ostr.length()-1]!='0') throw Error("Direc::Export, last char is NOT 0.");
88  ostr = ostr.substr(0, ostr.length()-1);
89  string_trim(ostr);
90 
91  ostr.erase(0, ostr.find(":=")+2);
92  string_replace_all(ostr, "[", "{");
93  string_replace_all(ostr, "]", "}");
94  Parser fp(st);
95  matrix mr(nrow, ncol);
96  auto res = fp.Read(ostr);
97  for(int r=0; r<nrow; r++) {
98  auto cur = res.op(r);
99  for(int c=0; c<ncol; c++) mr(r,c) = cur.op(c);
100  }
101  return mr;
102  }
103 
107  void Direct::Export() {
108 
109  if(Integral.nops()<1) return;
110 
111  int pdim = Propagator.nops();
112  lst InExternal;
113  for(auto ii : Internal) InExternal.append(ii);
114  for(auto ii : External) InExternal.append(ii);
115 
116  if(ISP.nops()<1) {
117  for(auto it : Internal) {
118  for(auto ii : InExternal) ISP.append(it*ii);
119  }
120  ISP.sort();
121  ISP.unique();
122  }
123 
124  if(ISP.nops() > pdim) {
125  cout << "ISP = " << ISP << endl;
126  cout << "Propagator = " << Propagator << endl;
127  throw Error("Direct::Export: #(ISP) > #(Propagator).");
128  }
129 
130  lst sp2s, s2sp, ss;
131  int _pic=0;
132  for(auto item : ISP) {
133  _pic++;
134  Symbol si("P"+to_string(_pic));
135  ss.append(si);
136  sp2s.append(w*item==w*si);
137  sp2s.append(item==si);
138  s2sp.append(si==item);
139  }
140 
141  lst leqns;
142  for(int i=0; i<ISP.nops(); i++) { // note NOT pdim
143  auto eq = Propagator.op(i).expand().subs(iEpsilon==0); // drop iEpsilon
144  eq = eq.subs(sp2s);
145  eq = eq.subs(Replacement);
146  if(eq.has(iWF(w))) throw Error("Direct::Export, iWF used in eq.");
147  leqns.append(eq == iWF(i));
148  }
149  auto s2p = lsolve(leqns, ss);
150  if(s2p.nops() != ISP.nops()) throw Error("Direct::Export: lsolve failed.");
151 
152  if(DSP.nops()<1) {
153  for(auto p1 : Internal)
154  for(auto p2 : InExternal)
155  DSP.append(lst{p1,p2});
156  }
157 
158  ibps.remove_all(); // no need
159  lst nsa;
160  for(int i=0; i<pdim; i++) nsa.append(a(i));
161  for(auto sp : DSP) {
162  auto ilp = sp.op(0);
163  auto iep = sp.op(1);
164 
165  ex ibp = 0;
166  symbol ss;
167  for(int i=0; i<pdim; i++) {
168  auto ns = nsa;
169  ns.let_op(i) = nsa.op(i) + 1;
170  auto dp = Propagator.op(i).subs(ilp==ss).diff(ss).subs(ss==ilp);
171  ibp -= (a(i)+Shift[i]) * F(ns) * dp;
172  }
173 
174  ibp = ibp * iep;
175  ibp = ibp.expand();
176  ibp = ibp.subs(sp2s);
177  ibp = ibp.subs(Replacement);
178  ibp = ibp.subs(s2p);
179 
180  ex res = 0;
181  for(int i=0; i<pdim; i++) {
182  auto ci = ibp.coeff(iWF(i), 1);
183  ci = MapFunction([i](const ex &e, MapFunction &self)->ex {
184  if(!e.has(F(w))) return e;
185  else if(e.match(F(w))) {
186  lst tmp = ex_to<lst>(e.op(0));
187  tmp.let_op(i) = tmp.op(i)-1;
188  return F(tmp);
189  } else return e.map(self);
190  })(ci);
191  res += ci;
192  }
193  res += ibp.subs(lst{iWF(w)==0});
194  auto cilp = iep.coeff(ilp);
195  if(!is_zero(cilp)) res += d*cilp*F(nsa);
196  ibps.append(res);
197  }
198 
199  // zero sector
200  for(auto lpi : Internal) {
201  vector<int> ns_vec;
202  lst ns0;
203  for(int i=0; i<pdim; i++) ns0.append(1);
204  for(int i=0; i<pdim; i++) {
205  if(Propagator.op(i).has(lpi)) ns0.let_op(i) = -1;
206  else ns_vec.push_back(i);
207  }
208  for(int n=0; n<std::pow(2,ns_vec.size()); n++) {
209  int cn = n;
210  lst ns1 = ns0;
211  for(int j=0; j<ns_vec.size(); j++) {
212  if((cn%2)==1) ns1.let_op(ns_vec[j]) = -1;
213  cn /= 2;
214  }
215  //Rlst.append(ns1);
216  }
217  }
218 
219  // Lee Zero Sector
220  if(true) {
221  //IsAlwaysZero = true;
222  lst ns0;
223  for(int i=0; i<pdim; i++) ns0.append(1);
224  size_t tot = std::pow(2LL,pdim);
225  for(size_t n=0; n<tot; n++) {
226  int cn = n;
227  lst ns1 = ns0;
228  lst sector = ns0;
229  for(int j=0; j<pdim; j++) {
230  if((cn%2)==1) { ns1.let_op(j) = -1; sector.let_op(j) = 0; }
231  cn /= 2;
232  }
233  //if(IsZero(sector)) Rlst.append(ns1);
234  //else if(IsAlwaysZero) IsAlwaysZero = false;
235  }
236  if(IsAlwaysZero) {
237  lst ws;
238  int pdim = Propagator.nops();
239  for(int i=0; i<pdim; i++) ws.append(wild(i));
240  Rules.append(F(ProblemNumber, ws)==0);
241  return;
242  }
243  }
244 
245  // all sectors
246  auto ibps_o = ibps;
247  ibps.remove_all();
248 cout << ibps_o << endl;
249 exit(0);
250  for(auto ibp : ibps_o) {
251  for(int s=-3; s<=3; s++) {
252  ibps.append(ibp.subs(a(w)==a(w)+s));
253  }
254  }
255 
256  size_t ltot = std::pow(3L,pdim); // see below
257  auto ret = GiNaC_Parallel(ltot, [&](int idx)->ex {
258  lst res;
259  auto li = idx;
260  auto cli = li;
261  vector<int> csec;
262  lst cibps = ibps;
263  for(int i=0; i<pdim; i++) {
264  auto im = (cli % 3)-1;
265  if(im==0) cibps = ex_to<lst>(subs(cibps,a(i)==0));
266  csec.push_back(im);
267  cli /= 3;
268  }
269  cibps.sort();
270  cibps.unique();
271  map<int,exvector> sum_fs;
272 
273  exset fset;
274  find(cibps,F(w),fset);
275 
276  for(auto fi : fset) {
277  int sum = 0;
278  auto ns = fi.op(0).subs(a(w)==0);
279  for(int i=0; i<pdim; i++) {
280  auto ni = ns.op(i);
281  if(csec[i]==-1) sum -= ex2int(ni);
282  else if(csec[i]==1) sum += ex2int(ni);
283  else sum += abs(ex2int(ni));
284  }
285  sum_fs[sum].push_back(fi);
286  }
287 
288  lst sum_tot;
289  for(auto kv : sum_fs) sum_tot.append(lst{kv.first, kv.second.size()});
290  sort_lst(sum_tot,false);
291 
292  matrix mat(cibps.nops(), fset.size());
293  exvector fvec;
294  int ccol = 0;
295  for(auto st : sum_tot) {
296  auto fs = sum_fs[ex2int(st.op(0))];
297  sort_vec(fs);
298  for(int cc=0; cc<fs.size(); cc++) {
299  fvec.push_back(fs[cc]);
300  int row = 0;
301  for(auto ibp : cibps) {
302  mat(row,ccol+cc) = ibp.coeff(fs[cc]);
303  row++;
304  }
305  }
306  ccol += fs.size();
307  }
308 
309  auto mr = RowReduce(mat);
310 
311  for(int r=0; r<mat.rows(); r++) {
312  int c1 = -1, c = -1;
313  for(auto ti : sum_tot) {
314  int ct = ex2int(ti.op(1));
315  for(int k=0; k<ct; k++) {
316  c++;
317  if(mr(r,c).is_zero()) continue;
318  else if(c1==-1) c1=c;
319  else goto next_row;
320  }
321  if(c1!=-1) {
322  ex sol = 0;
323  for(int ci=c1+1; ci<mat.cols(); ci++) sol -= mr(r,ci)/mr(r,c1)*fvec[ci];
324  auto ns0 = fvec[c1].op(0).subs(a(w)==0);
325  exmap aSH;
326  for(int i=0; i<ns0.nops(); i++) {
327  if(csec[i]==0) continue;
328  if(!ns0.op(i).is_zero()) aSH[a(i)]=a(i)-ns0.op(i);
329  }
330  sol = sol.subs(aSH);
331 
332  exset fs;
333  find(sol,F(w),fs);
334  vector<vector<int>> fns;
335  for(auto fi : fs) {
336  fi = fi.subs(a(w)==0);
337  vector<int> ns;
338  for(auto it : fi.op(0)) ns.push_back(0-ex2int(it));
339  fns.push_back(ns);
340  }
341  Condition cond;
342  for(int i=0; i<csec.size(); i++) {
343  if(csec[i]==-1) {
344  int min = 100000;
345  for(auto ns : fns) {
346  if(ns[i]<min) min = ns[i];
347  }
348  cond.cs.push_back(make_pair(-1,min));
349  } else if(csec[i]==1) {
350  int max = -100000;
351  for(auto ns : fns) {
352  if(ns[i]>max) max = ns[i];
353  }
354  cond.cs.push_back(make_pair(1,max));
355  } else {
356  cond.cs.push_back(make_pair(0,ex2int(ns0.op(i))));
357  }
358  }
359 
360  res.append(lst{cond.cs2ex(),sol});
361  goto next_row;
362  }
363  }
364  next_row: ;
365  }
366  return res;
367  }, "IBP");
368 
369  ConSolVec.clear();
370  for(auto its : ret) {
371  for(auto item : its) {
372  Condition cond;
373  cond.ex2cs(item.op(0));
374  ConSolVec.push_back(make_pair(cond,item.op(1)));
375  }}
376 
377  }
378 
379 
380 
381 
382 
386  void Direct::Run() {
387 
388  // improve here, try by level
389  exmap sols;
390  auto intgs = Integral;
391  while(true) {
392  exset fs;
393  for(auto intg : intgs) {
394  if(key_exists(sols, F(intg))) continue;
395  for(auto cs : ConSolVec) {
396  if(cs.first.IsOK(intg)) {
397  exmap as;
398  for(int i=0; i<intg.nops(); i++) as[a(i)] = intg.op(i);
399  try { // improve here
400  //if(numer_denom(cs.second).op(1).subs(as).is_zero()) continue;
401  auto sol = cs.second.subs(as);
402  find(sol, F(w), fs);
403  sols[F(intg)] = sol;
404  break;
405  } catch(...) { }
406  }
407  }
408  }
409  intgs.remove_all();
410  for(auto fi : fs) intgs.append(fi.op(0));
411  if(intgs.nops()<1) break;
412  }
413 
414  // subs by level
415  map<int,exmap> lvl_sol;
416  lst lvls;
417  for(auto sol : sols) {
418  ex sum = 0;
419  for(auto ni : sol.first.op(0)) sum += (ni<0 ? -ni : ni);
420  lvl_sol[ex2int(sum)][sol.first] = sol.second;
421  lvls.append(ex2int(sum));
422  }
423  lvls.sort();
424  lvls.unique();
425  //sort_lst(lvls);
426 
427  for(int i=0; i<lvls.nops(); i++) {
428  int si = ex2int(lvls.op(i));
429  for(auto kv : lvl_sol[si]) {
430  for(int j=0; j<i; j++) {
431  int sj = ex2int(lvls.op(j));
432  lvl_sol[si][kv.first] = kv.second.subs(lvl_sol[sj]);
433  }}
434  }
435 
436  for(auto intg : Integral) {
437  ex fi = F(intg);
438  ex sum = 0;
439  for(auto ni : fi.op(0)) sum += (ni<0 ? -ni : ni);
440  fi = fi.subs(lvl_sol[ex2int(sum)]);
441  Rules.append(F(intg)==fi);
442  }
443 
444  }
445 
449  void Direct::Import() {
450 
451  }
452 
453 }
int * a
Definition: Functions.cpp:234
IBP header file.
vector< pair< int, int > > cs
Definition: IBP.h:148
void ex2cs(ex e)
Definition: IBP.h:163
void Run() override
invoke kira program for reduction
Definition: Direct.cpp:386
void Export() override
Export input data for KIRA.
Definition: Direct.cpp:107
void Import() override
import kira result
Definition: Direct.cpp:449
class used to wrap error message
Definition: BASIC.h:242
static Fermat & get()
Definition: Fermat.cpp:7
lst Internal
Definition: IBP.h:27
map< int, ex > Shift
Definition: IBP.h:36
lst ISP
Definition: IBP.h:34
lst Replacement
Definition: IBP.h:29
lst DSP
Definition: IBP.h:33
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
lst Rules
Definition: IBP.h:43
class to wrap map_function of GiNaC
Definition: BASIC.h:632
class extended to GiNaC symbol class, represent a positive symbol
Definition: BASIC.h:113
ex subs(const exmap &m, unsigned options=0) const override
Definition: BASIC.h:145
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
bool key_exists(const exmap &map, const ex &key)
Definition: BASIC.h:293
ex w
Definition: Init.cpp:90
const Symbol d
const Symbol as
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
exvector GiNaC_Parallel(int ntotal, std::function< ex(int)> f, const string &key)
GiNaC Parallel Evaluation using fork.
Definition: BASIC.cpp:260
void string_trim(string &str)
Definition: Functions.cpp:156
int ex2int(ex num)
ex to integer
Definition: BASIC.cpp:893
ex subs(const ex &e, init_list sl)
Definition: BASIC.h:51