HepLib
Loading...
Searching...
No Matches
TIR.cpp
Go to the documentation of this file.
1
6#include "HEP.h"
7#include <cmath>
8
9namespace HepLib {
10
11 namespace {
12
13 lst combs(const lst & items, int n) {
14 lst ret;
15 if(n<1 || items.nops()<1) return lst{ret};
16 if(n==1) {
17 for(auto it : items) ret.append(lst{it});
18 return ret;
19 }
20 if(items.nops()==1) {
21 lst comb;
22 for(int i=0; i<n; i++) comb.append(items.op(0));
23 ret.append(comb);
24 return ret;
25 }
26 auto its = items;
27 ex first = its.op(0);
28 its.remove_first();
29 //for(int i=0; i<=n; i++) {
30 for(int i=n; i>=0; i--) {
31 auto rets = combs(its, n-i);
32 for(auto it : rets) {
33 lst item = ex_to<lst>(it);
34 for(int j=0; j<i; j++) item.append(first);
35 ret.append(item);
36 }
37 }
38 return ret;
39 }
40
41 }
42
43 ex UnContract(const ex expr_in, const lst &loop_ps, const lst &ext_ps) {
44 // handle Eps/DGamma/Pair and related power
45 ex expr = GMatExpand(expr_in);
46 int lproj = 0;
47 return MapFunction([&lproj,loop_ps,ext_ps](const ex &e, MapFunction &self)->ex {
48 string prefix = "HIdx";
49 int mode = 0;
50 if(ext_ps.nops()>0) mode = 1;
51 if(!Eps::has(e) && !DGamma::has(e) && (mode==0 || !Pair::has(e))) return e;
52 else if(mode==1 && is_a<Pair>(e) && has_any(e,loop_ps) && has_any(e,ext_ps)) {
53 Index idx(prefix+to_string(++lproj));
54 auto p = ex_to<Pair>(e);
55 return SP(p.op(0), idx, false) * SP(p.op(1), idx, false);
56 } else if(is_a<Eps>(e)) {
57 auto pis0 = ex_to<Eps>(e).pis;
58 ex pis[4];
59 ex cc = 1;
60 for(int i=0; i<4; i++) {
61 pis[i] = pis0[i];
62 if(is_equal_any(pis[i],loop_ps)) {
63 Index idx(prefix+to_string(++lproj));
64 cc *= SP(pis[i], idx, false);
65 pis[i] = idx;
66 } else if(has_any(pis[i],loop_ps)) throw Error("UnContract: Eps still has loops.");
67 }
68 return LC(pis[0], pis[1], pis[2], pis[3]) * cc;
69 } else if(is_a<DGamma>(e)) {
70 auto g = ex_to<DGamma>(e);
71 if(!is_equal_any(g.pi,loop_ps)) return e;
72 else {
73 Index idx(prefix+to_string(++lproj));
74 return DGamma(idx, g.rl) * SP(g.pi, idx, false);
75 }
76 } else if (e.match(TR(w))) {
77 auto ret = self(e.op(0));
78 auto cvs = collect_lst(ret, loop_ps);
79 ret = 0;
80 for(auto const & cv : cvs) {
81 ret += TR(cv.op(0)) * cv.op(1);
82 }
83 return ret;
84 } else if (e.match(GMat(w1,w2,w3))) {
85 auto ret = self(e.op(0));
86 auto cvs = collect_lst(ret, loop_ps);
87 ret = 0;
88 for(auto const & cv : cvs) {
89 ret += GMat(cv.op(0), e.op(1), e.op(2)) * cv.op(1);
90 }
91 return ret;
92 } else if(is_a<add>(e)) {
93 int lpj = lproj;
94 int lpj_max = -100;
95 ex ret = 0;
96 for(auto item : e) {
97 lproj = lpj;
98 ret += self(item);
99 if(lpj_max<lproj) lpj_max = lproj;
100 }
101 lproj = lpj_max;
102 return ret;
103 } else if(is_a<power>(e)) {
104 if(!e.op(1).info(info_flags::posint)) return e; // no need to handle negative powers
105 ex ret = 1;
106 int pn = ex_to<numeric>(e.op(1)).to_int();
107 for(int i=0; i<pn; i++) {
108 ret *= self(e.op(0));
109 }
110 return ret;
111 } else return e.map(self);
112 })(expr);
113 }
114
122 ex TIR(const ex &expr_in, const lst &loop_ps, const lst &ext_ps) {
123 for(auto pi : loop_ps) {
124 if(!is_a<Vector>(pi)) {
125 cout << "loop_ps: " << loop_ps << endl;
126 throw Error("TIR invalid 2nd argument");
127 }
128 }
129 for(auto pi : ext_ps) {
130 if(!is_a<Vector>(pi)) {
131 cout << "ext_ps: " << ext_ps << endl;
132 throw Error("TIR invalid 3rd argument");
133 }
134 }
135
136 Fermat &fermat = Fermat::get();
137 int &v_max = fermat.vmax;
138 static exmap cache_map;
139
140 auto expr = UnContract(expr_in, loop_ps); // UnContract
141 auto cvs = collect_lst(expr, [&loop_ps](const ex & e)->bool{
142 if(!Index::hasv(e)) return false;
143 for(const_preorder_iterator i = e.preorder_begin(); i != e.preorder_end(); ++i) {
144 auto item = *i;
145 if(is_a<Pair>(item) && is_a<Index>(item.op(1)) && loop_ps.has(item.op(0))) return true;
146 }
147 return false;
148 });
149
150 expr = 0;
151 for(auto cv : cvs) {
152 auto const & cc = cv.op(0);
153 auto const & vv = cv.op(1);
154 if(vv.is_equal(1)) {
155 expr += cc * vv;
156 continue;
157 }
158
159 ex map_key = lst{vv, ext_ps};
160 if(using_cache) {
161 auto itr = cache_map.find(map_key);
162 if(itr!=cache_map.end()) {
163 expr += cc * itr->second;
164 continue;
165 }
166 }
167 lst vis, lps;
168 map<ex,int,ex_is_less> pc;
169 if(is_a<mul>(vv)) {
170 for(auto item : vv) {
171 vis.append(item);
172 lps.append(item.op(0));
173 pc[item.op(0)]++;
174 }
175 } else {
176 vis.append(vv);
177 lps.append(vv.op(0));
178 }
179 lps.sort();
180 lps.unique();
181
182 ex res;
183 auto visn = vis.nops();
184 if(lps.nops()<2) {
185 ex eqL=1;
186 lst is, bis;
187 for(auto vi : vis) {
188 eqL *= vi;
189 is.append(vi.op(1));
190 }
191
192 //for(int er=((visn%2==0)?0:1); er<=visn; er+=2) {
193 for(int er=visn; er>=((visn%2==0)?0:1); er-=2) {
194 auto ep_comb = combs(ext_ps, er);
195 for(auto item : ep_comb) {
196 ex bi=1;
197 for(int j=0; j<er; j++) bi *= SP(item.op(j), is.op(j),false); // false needed, is may be in SP_map, and actually should be a dummy index
198 for(int j=er; j<visn; j=j+2) bi *= SP(is.op(j), is.op(j+1),false); // false needed, reason above
199 bi = bi.symmetrize(is);
200 bis.append(bi);
201 }}
202
203 int n = bis.nops();
204 lst mat;
205 for(auto bi : bis) {
206 for(auto bj : bis) mat.append(bi*bj);
207 }
208 for(auto bj : bis) mat.append(eqL*bj);
209
210 // we need to remap the dummy index, to avoid SP_map set the index object to 0
211 if(true) {
212 lst isu = is;
213 isu.sort();
214 isu.unique();
215 exmap i2u, u2i;
216 int c=0;
217 for(auto item : isu) {
218 auto ii = Index("TIR"+to_string(c++));
219 i2u[item] = ii;
220 u2i[ii] = item;
221 }
222 mat = ex_to<lst>(subs(mat,i2u));
223 mat = ex_to<lst>(form(mat).subs(u2i));
224 }
225
226 lst rep_vs;
227 ex tree = mat;
228 for(const_preorder_iterator i = tree.preorder_begin(); i != tree.preorder_end(); ++i) {
229 auto e = (*i);
230 if(is_a<symbol>(e) || is_a<Pair>(e) || is_a<Eps>(e)) {
231 rep_vs.append(e);
232 }
233 }
234 rep_vs.sort();
235 rep_vs.unique();
236 sort_lst(rep_vs);
237
238 exmap v2f;
239 symtab st;
240 int fvi = 0;
241 for(auto vi : rep_vs) {
242 auto name = "v" + to_string(fvi);
243 v2f[vi] = Symbol(name);
244 st[name] = vi;
245 fvi++;
246 }
247
248 stringstream ss;
249 if(fvi>111) {
250 cout << rep_vs << endl;
251 throw Error("Fermat: Too many variables.");
252 }
253 if(fvi>v_max) {
254 for(int i=v_max; i<fvi; i++) ss << "&(J=v" << i << ");" << endl;
255 fermat.Execute(ss.str());
256 ss.clear();
257 ss.str("");
258 v_max = fvi;
259 }
260
261 ss << "Array m[" << n << "," << n+1 << "];" << endl;
262 fermat.Execute(ss.str());
263 ss.clear();
264 ss.str("");
265
266 ss << "[m]:=[(";
267 for(auto item : mat) {
268 ss << item.subs(v2f) << ",";
269 }
270 ss << ")];" << endl;
271 ss << "Redrowech([m]);" << endl;
272 auto tmp = ss.str();
273
274 string_replace_all(tmp,",)]",")]");
275 fermat.Execute(tmp);
276 ss.clear();
277 ss.str("");
278
279 ss << "&(U=1);" << endl; // ugly printing, the whitespace matters
280 ss << "![m" << endl;
281 auto ostr = fermat.Execute(ss.str());
282 ss.clear();
283 ss.str("");
284
285 ss << "&(U=0);" << endl; // disable ugly printing
286 ss << "@([m]);" << endl;
287 ss << "&_G;" << endl;
288 fermat.Execute(ss.str());
289 ss.clear();
290 ss.str("");
291
292 // make sure last char is 0
293 if(ostr[ostr.length()-1]!='0') throw Error("TIR: last char is NOT 0.");
294 ostr = ostr.substr(0, ostr.length()-1);
295 string_trim(ostr);
296
297 ostr.erase(0, ostr.find(":=")+2);
298 string_replace_all(ostr, "[", "{");
299 string_replace_all(ostr, "]", "}");
300 Parser fp(st);
301 auto mat2 = fp.Read(ostr);
302
303 res = 0;
304 for(int i=0; i<n; i++) {
305 if(is_zero(mat2.op(i).op(i)) && !is_zero(mat2.op(i).op(n))) {
306 cout << cv << endl;
307 cout << mat << " :> " << mat2 << endl;
308 throw Error("No Solution in TIR.");
309 }
310 res += bis.op(i) * mat2.op(i).op(n);
311 }
312 res = res.subs(SP_map);
313 } else {
314 int cmin=10000, cmax=-1;
315 ex pmin, pmax;
316 for(auto lpi : lps) {
317 auto cc = pc[lpi];
318 if(cc<cmin) { cmin = cc; pmin = lpi; }
319 if(cc>cmax) { cmax = cc; pmax = lpi; }
320 }
321
322 auto lp0 = pmin;
323 auto ext_ps2 = ext_ps;
324 for(auto lpi : lps) if(!is_zero(lpi-lp0)) ext_ps2.append(lpi);
325 res = TIR(vv, lst{ lp0 }, ext_ps2);
326 res = TIR(res, loop_ps, ext_ps);
327 }
328
329 res = exnormal(res);
330 if(using_cache) cache_map.insert({map_key,res});
331 expr += cc * res;
332 }
333
334 return expr.subs(SP_map);
335 }
336
337}
338
HEP header file.
int pn
Definition Others.cpp:25
class for Dirac Gamma object
Definition HEP.h:437
static bool has(const ex &e)
static bool has(const ex &e)
class used to wrap error message
Definition BASIC.h:245
interface to communicate with Fermat program
Definition BASIC.h:844
static Fermat & get()
Definition Fermat.cpp:7
string Execute(string)
Definition Process.cpp:102
class for index object
Definition HEP.h:104
static bool hasv(const ex &e)
Definition Basic.cpp:240
class to wrap map_function of GiNaC
Definition BASIC.h:679
static bool has(const ex &e)
class to parse for string or file, helpful with Symbol class
Definition BASIC.h:692
ex Read(const string &instr, bool s2S=true)
class extended to GiNaC symbol class, represent a positive symbol
Definition BASIC.h:116
HepLib namespace.
Definition BASIC.cpp:17
bool is_equal_any(ex expr, lst ps)
Definition BASIC.h:64
exmap SP_map
Definition Init.cpp:188
ex GMatExpand(const ex &expr_in)
Definition Basic.cpp:827
bool using_cache
Definition Init.cpp:160
bool has_any(ex expr, lst ps)
Definition BASIC.h:55
ex w
Definition Init.cpp:93
ex exnormal(const ex &expr, int opt)
normalize a expression
Definition BASIC.cpp:1920
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:1223
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)
ex w1
Definition BASIC.h:503
ex w3
Definition BASIC.h:503
ex UnContract(const ex expr, const lst &loop_ps, const lst &ext_ps=lst{})
Definition TIR.cpp:43
ex SP(const ex &a, bool use_map=true)
Definition Pair.cpp:166
ex LC(ex pi1, ex pi2, ex pi3, ex pi4)
function similar to LCD in FeynCalc
Definition Eps.cpp:179
ex w2
Definition BASIC.h:503
void string_trim(string &str)
ex form(const ex &iexpr, int verb)
evalulate expr in form program, see also the form_trace_mode and form_expand_mode
Definition Form.cpp:581
ex TIR(const ex &expr_in, const lst &loop_ps, const lst &ext_ps)
Tensor Index Reduction, note that we only handle numerator.
Definition TIR.cpp:122
ex subs(const ex &e, init_list sl)
Definition BASIC.h:51