13 lst combs(
const lst & items,
int n) {
15 if(n<1 || items.nops()<1)
return lst{ret};
17 for(
auto it : items) ret.append(lst{it});
22 for(
int i=0; i<n; i++) comb.append(items.op(0));
30 for(
int i=n; i>=0; i--) {
31 auto rets = combs(its, n-i);
33 lst item = ex_to<lst>(it);
34 for(
int j=0; j<i; j++) item.append(first);
43 ex
UnContract(
const ex expr_in,
const lst &loop_ps,
const lst &ext_ps) {
48 string prefix =
"HIdx";
50 if(ext_ps.nops()>0) mode = 1;
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;
60 for(
int i=0; i<4; i++) {
63 Index idx(prefix+to_string(++lproj));
64 cc *=
SP(pis[i], idx,
false);
66 }
else if(
has_any(pis[i],loop_ps))
throw Error(
"UnContract: Eps still has loops.");
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);
73 Index idx(prefix+to_string(++lproj));
74 return DGamma(idx, g.rl) *
SP(g.pi, idx,
false);
76 }
else if (e.match(TR(
w))) {
77 auto ret = self(e.op(0));
80 for(
auto const & cv : cvs) {
81 ret += TR(cv.op(0)) * cv.op(1);
84 }
else if (e.match(GMat(
w1,
w2,
w3))) {
85 auto ret = self(e.op(0));
88 for(
auto const & cv : cvs) {
89 ret += GMat(cv.op(0), e.op(1), e.op(2)) * cv.op(1);
92 }
else if(is_a<add>(e)) {
99 if(lpj_max<lproj) lpj_max = lproj;
103 }
else if(is_a<power>(e)) {
104 if(!e.op(1).info(info_flags::posint))
return e;
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));
111 }
else return e.map(self);
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");
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");
137 int &v_max = fermat.
vmax;
138 static exmap cache_map;
141 auto cvs =
collect_lst(expr, [&loop_ps](
const ex & e)->
bool{
143 for(const_preorder_iterator i = e.preorder_begin(); i != e.preorder_end(); ++i) {
145 if(is_a<Pair>(item) && is_a<Index>(item.op(1)) && loop_ps.has(item.op(0)))
return true;
152 auto const & cc = cv.op(0);
153 auto const & vv = cv.op(1);
159 ex map_key = lst{vv, ext_ps};
161 auto itr = cache_map.find(map_key);
162 if(itr!=cache_map.end()) {
163 expr += cc * itr->second;
168 map<ex,int,ex_is_less> pc;
170 for(
auto item : vv) {
172 lps.append(item.op(0));
177 lps.append(vv.op(0));
183 auto visn = vis.nops();
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) {
197 for(
int j=0; j<er; j++) bi *=
SP(item.op(j), is.op(j),
false);
198 for(
int j=er; j<visn; j=j+2) bi *=
SP(is.op(j), is.op(j+1),
false);
199 bi = bi.symmetrize(is);
206 for(
auto bj : bis) mat.append(bi*bj);
208 for(
auto bj : bis) mat.append(eqL*bj);
217 for(
auto item : isu) {
218 auto ii =
Index(
"TIR"+to_string(c++));
222 mat = ex_to<lst>(
subs(mat,i2u));
223 mat = ex_to<lst>(
form(mat).
subs(u2i));
228 for(const_preorder_iterator i = tree.preorder_begin(); i != tree.preorder_end(); ++i) {
230 if(is_a<symbol>(e) || is_a<Pair>(e) || is_a<Eps>(e)) {
241 for(
auto vi : rep_vs) {
242 auto name =
"v" + to_string(fvi);
250 cout << rep_vs << endl;
251 throw Error(
"Fermat: Too many variables.");
254 for(
int i=v_max; i<fvi; i++) ss <<
"&(J=v" << i <<
");" << endl;
261 ss <<
"Array m[" << n <<
"," << n+1 <<
"];" << endl;
267 for(
auto item : mat) {
268 ss << item.subs(v2f) <<
",";
271 ss <<
"Redrowech([m]);" << endl;
279 ss <<
"&(U=1);" << endl;
281 auto ostr = fermat.
Execute(ss.str());
285 ss <<
"&(U=0);" << endl;
286 ss <<
"@([m]);" << endl;
287 ss <<
"&_G;" << endl;
293 if(ostr[ostr.length()-1]!=
'0')
throw Error(
"TIR: last char is NOT 0.");
294 ostr = ostr.substr(0, ostr.length()-1);
297 ostr.erase(0, ostr.find(
":=")+2);
301 auto mat2 = fp.
Read(ostr);
304 for(
int i=0; i<n; i++) {
305 if(is_zero(mat2.op(i).op(i)) && !is_zero(mat2.op(i).op(n))) {
307 cout << mat <<
" :> " << mat2 << endl;
308 throw Error(
"No Solution in TIR.");
310 res += bis.op(i) * mat2.op(i).op(n);
314 int cmin=10000, cmax=-1;
316 for(
auto lpi : lps) {
318 if(cc<cmin) { cmin = cc; pmin = lpi; }
319 if(cc>cmax) { cmax = cc; pmax = lpi; }
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);
class for Dirac Gamma object
static bool has(const ex &e)
static bool has(const ex &e)
class used to wrap error message
interface to communicate with Fermat program
static bool hasv(const ex &e)
class to wrap map_function of GiNaC
static bool has(const ex &e)
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
bool is_equal_any(ex expr, lst ps)
ex GMatExpand(const ex &expr_in)
bool has_any(ex expr, lst ps)
ex exnormal(const ex &expr, int opt)
normalize a expression
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_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)
ex UnContract(const ex expr, const lst &loop_ps, const lst &ext_ps=lst{})
ex SP(const ex &a, bool use_map=true)
ex LC(ex pi1, ex pi2, ex pi3, ex pi4)
function similar to LCD in FeynCalc
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
ex TIR(const ex &expr_in, const lst &loop_ps, const lst &ext_ps)
Tensor Index Reduction, note that we only handle numerator.
ex subs(const ex &e, init_list sl)