HepLib
Loading...
Searching...
No Matches
Direct.cpp
Go to the documentation of this file.
1
6#include "IBP.h"
7#include <cmath>
8
9namespace 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
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();
248cout << ibps_o << endl;
249exit(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
IBP header file.
void Export() override
Export input data for KIRA.
Definition Direct.cpp:107
class used to wrap error message
Definition BASIC.h:242
static Fermat & get()
Definition Fermat.cpp:7
lst Internal
Definition IBP.h:27
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
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:93
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)
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)
int ex2int(ex num)
ex to integer
Definition BASIC.cpp:893
ex subs(const ex &e, init_list sl)
Definition BASIC.h:51