87If[Length[$ScriptCommandLine]<2, Print["Usage: wolframescript -f "<>ToString[$ScriptCommandLine[[1]]]<>" <n>"];Quit[]];
88current = DirectoryName@If[$FrontEnd===Null,$InputFileName,NotebookFileName[]];
92SetReductionOptions["IBPReducer"->"Blade"];
93ID = ToExpression[$ScriptCommandLine[[2]]];
94PropsInts=Get[FileNameJoin[{current,ToString[ID]<>".m"}]];
96AMFlowInfo["Family"] = Symbol["I"<>ToString[ID]];
97AMFlowInfo["Loop"] = <<Loop>>;
98AMFlowInfo["Leg"] = <<Leg>>;
99AMFlowInfo["Conservation"] = { };
100AMFlowInfo["Replacement"] = <<Replacement>>;
101AMFlowInfo["Propagator"] = PropsInts[[1]]/.<<M2M2>>;
102AMFlowInfo["Numeric"] = <<Numeric>>;
103AMFlowInfo["NThread"] = <<NThread>>;
105integrals = Map[(j[Symbol["I"<>ToString[ID]], Sequence@@#])&, PropsInts[[2]]];
106precision = <<Precision>>;
107epsorder = 2*Length@AMFlowInfo["Loop"]-PropsInts[[3]] + <<Order>>;
108sol = SolveIntegrals[integrals, precision, epsorder];
109Put[sol, FileNameJoin[{current, "sol"<>ToString[ID]<>".m"}]];
134 system((
"mkdir -p "+dir).c_str());
140 cout <<
"Replacing linear propagators ..." << endl;
143 find(res, F(
w1,
w2), pq_fs);
145 for(
auto f : pq_fs) {
146 lst ps = ex_to<lst>(f.op(0));
147 lst ns = ex_to<lst>(f.op(1));
149 for(
int i=0; i<ps.nops(); i++) {
152 if(ps.op(i).has(ip*ip)) {
159 if(!is_a<mul>(pi) || !pi.nops()==2) {
160 cout <<
"prop is NOT the form of a*b" << endl;
166 }
else if(ns.op(i)!=0) {
168 cout <<
"n of qi.pi is NOT -1" << endl;
171 auto pa = pi.op(0), pb = pi.op(1);
174 bool ic = is_complete(ps, sp2x);
175 if(!ic && is_loop(pa)) {
176 ps.let_op(i) = expand(pow(pa,2)).subs(
Replacement);
177 ic = is_complete(ps, sp2x);
179 if(!ic && is_loop(pb)) {
180 ps.let_op(i) = expand(pow(pb,2)).subs(
Replacement);
181 ic = is_complete(ps, sp2x);
184 cout <<
"1st: ic is NOT true!" << endl;
193 }
else if(ns_p.nops()>0) {
194 auto idx =
ex2int(ns_p.op(0));
196 auto pidx = ps.op(idx);
202 ps.let_op(idx) = pab;
203 bool ic = is_complete(ps, sp2x);
204 if(!ic && is_loop(pa)) {
205 ps.let_op(idx) = expand(pow(pa,2)).subs(
Replacement);
206 ic = is_complete(ps, sp2x);
208 if(!ic && is_loop(pb)) {
209 ps.let_op(idx) = expand(pow(pb,2)).subs(
Replacement);
210 ic = is_complete(ps, sp2x);
213 cout <<
"2nd: ic is NOT true!" << endl;
217 auto xps =
subs(ps,sp2x);
218 auto xpidx = pidx.subs(sp2x);
221 cout <<
"xps still has ip" << endl;
222 cout <<
"xps: " << xps << endl;
226 cout <<
"xpidx still has ip" << endl;
227 cout <<
"xpidx: " << xpidx << endl;
232 ex xeq = 0, eq = 0, fres = 0;
234 for(
int ii=0; ii<ps.nops(); ii++) {
236 xeq += yi*xps.op(ii);
239 nn.let_op(ii) = ns.op(ii)-1;
240 fres += yi*F(ps, nn);
244 for(
int ii=0; ii<ps.nops(); ii++) {
246 eqs.append(xeq.coeff(xi)==xpidx.coeff(xi));
248 auto sol = lsolve(eqs,ys);
250 if(sol.nops()<1 || sol.has(x(
w))) {
251 cout <<
"wrong sol: " << sol << endl;
254 auto rem = pidx-eq.subs(sol);
255 fres = fres.subs(sol);
257 fres += rem * F(ps, ns);
263 cout <<
"Failed: chk=" << chk << endl;
265 }
else if(!f.op(0).is_equal(ps)) {
266 pq_f2f[f] = F(ps, ns);
269 cout <<
"Failed: chk=" << chk << endl;
274 cout <<
"Collecting ..." << endl;
277 if(e.match(F(
w1,
w2))) {
278 auto itr = pq_f2f.find(e);
279 if(itr==pq_f2f.end()) {
280 cout <<
"F Not Found" << endl;
284 }
else return e.map(self);
290 find(res, F(
w1,
w2), fs);
291 map<ex,Family,ex_is_less> p2f;
295 auto itr = p2f.find(f.op(0));
296 if(itr == p2f.end()) {
297 itr = p2f.insert({f.op(0), Family(
pn)}).first;
300 itr->second.intg.append(f.op(1));
301 f2f[f] = F(itr->second.pn, f.op(1));
305 if(e.match(F(
w1,
w2))) {
306 auto itr = f2f.find(e);
308 cout <<
"F Not Found" << endl;
312 }
else return e.map(self);
315 cout <<
"Exporting res.txt ..." << endl;
320current = If[$FrontEnd===Null,$InputFileName,NotebookFileName[]]//DirectoryName;
323sols = Flatten@Table[Import[FileNameJoin[{current,"sol"<>ToString[i]<>".m"}]], {i,0,<<NN>>}];
324res = C2M@Import[FileNameJoin[{current, "res.txt"}]];
325res = res/.{F[p_, n_] :> j[Symbol["I"<>ToString[p]], Sequence@@n]} /. Dispatch@sols;
333 int tot = p2f.size(), cur = 0;
336 cout <<
"[ " << cur <<
" / " << tot <<
"] pn = " << kv.second.pn << endl;
337 cout << kv.first << endl;
338 cout << kv.second.intg << endl;