14 string UKIRA::Fout(
const ex & expr) {
17 if(is_a<lst>(f)) f = F(f);
18 else if(expr.match(F(
w1,
w2))) f = F(f.op(1));
27 if(expr.match(F(
w1,
w2))) idx = expr.op(1);
28 else if(expr.match(F(
w))) idx = expr.op(0);
30 return to_string(i2w[idx]);
37 ex UKIRA::Fin(
const string & expr) {
44 auto cpos = expr.find(
"*");
45 if(cpos==string::npos) {
46 if(expr==
"0")
return 0;
47 throw Error(
"UKIRA::Fin with 0 or * NOT Found.");
49 auto wstr = expr.substr(0,cpos);
50 unsigned long long weight = stoull(wstr,NULL,0);
51 auto oex =
str2ex(expr.substr(cpos+1,string::npos));
65 for(
auto ii :
Internal) InExternal.append(ii);
66 for(
auto ii :
External) InExternal.append(ii);
70 for(
auto ii : InExternal)
ISP.append(it*ii);
76 if(
ISP.nops() > pdim) {
77 cout <<
"ISP = " <<
ISP << endl;
79 throw Error(
"UKIRA::Export: #(ISP) > #(Propagator).");
84 for(
auto item :
ISP) {
86 Symbol si(
"P"+to_string(_pic));
88 sp2s.append(
w*item==
w*si);
89 sp2s.append(item==si);
90 s2sp.append(si==item);
97 repl.append(
w*item.op(0) ==
w*item.op(1));
103 for(
int i=0; i<
ISP.nops(); i++) {
107 if(eq.has(iWF(
w)))
throw Error(
"UKIRA::Export, iWF used in eq.");
108 leqns.append(eq == iWF(i));
110 auto s2p = lsolve(leqns, ss);
111 if(s2p.nops() !=
ISP.nops())
throw Error(
"UKIRA::Export: lsolve failed.");
115 for(
auto p2 : InExternal)
116 DSP.append(lst{p1,p2});
121 for(
int i=0; i<pdim; i++) nsa.append(
a(i));
128 for(
int i=0; i<pdim; i++) {
130 ns.let_op(i) = nsa.op(i) + 1;
131 auto dp =
Propagator.op(i).subs(ilp==ss).diff(ss).subs(ss==ilp);
132 ibp -= (
a(i)+
Shift[i+1]) * F(ns) * dp;
137 ibp = ibp.subs(sp2s);
142 for(
int i=0; i<pdim; i++) {
143 auto ci = ibp.coeff(iWF(i), 1);
145 if(!e.has(F(
w)))
return e;
146 else if(e.match(F(
w))) {
147 lst tmp = ex_to<lst>(e.op(0));
148 tmp.let_op(i) = tmp.op(i)-1;
150 }
else return e.map(
self);
154 res += ibp.subs(lst{iWF(
w)==0});
155 auto cilp = iep.coeff(ilp);
156 if(!is_zero(cilp)) res +=
d*cilp*F(nsa);
161 int rmax = -1, smax = -1;
162 int rrmax[pdim], ssmax[pdim];
163 for(
int i=0; i<pdim; i++) rrmax[i] = ssmax[i] = -1;
165 if(integral.nops()!=pdim)
throw Error(
"UKIRA::Export, integral dimension not match propagators.");
168 for(
int i=0; i<pdim; i++) {
169 auto item =
ex2int(integral.op(i));
171 if(rrmax[i]<item) rrmax[i] = item;
175 if(ssmax[i]<item) ssmax[i] = item;
179 if(rmax<rr) rmax = rr;
180 if(smax<ss) smax = ss;
184 int _rrmax = -1, _ssmax = -1;
185 for(
int i=0; i<pdim; i++) {
186 if(_rrmax<rrmax[i]) _rrmax = rrmax[i];
187 if(_ssmax<ssmax[i]) _ssmax = ssmax[i];
189 for(
int i=0; i<pdim; i++) {
190 rrmax[i] = _rrmax +
rap;
191 ssmax[i] = _ssmax +
sap;
196 for(
int i=0; i<pdim; i++) {
206 for(
int i=0; i<pdim; i++)
as[i] = -ssmax[i];
207 vector<vector<int>> asvec;
209 for(
int i=0; i<pdim; i++) {
210 if(
as[i]+1>rrmax[i]) {
211 if(i+1 == pdim)
goto done;
218 int _rmax = 0, _smax = 0;
219 for(
int i=0; i<pdim; i++) {
220 if(
as[i]>0) _rmax +=
as[i];
223 if(_rmax>rmax || _smax>smax)
continue;
225 for(
int i=0; i<pdim; i++) asv.push_back(
as[i]);
226 asvec.push_back(asv);
230 int nCut =
Cut.nops();
231 bool hasCut = (nCut>1);
233 for(
int i=0; i<nCut; i++) iCut[i] = ex_to<numeric>(
Cut.op(i)).to_int();
235 GiNaC_Parallel(asvec.size(), [
this,&asvec,pdim,hasCut,nCut,&iCut](
int idx)->ex {
236 auto as = asvec[idx];
238 for(int i=0; i<pdim; i++) sol[a(i)]=as[i];
240 for(auto item : ibps) {
241 auto ii = item.subs(sol);
242 if(ii.is_zero()) continue;
248 lst ns = ex_to<lst>(fi.op(0));
249 for(int nc=0; nc<nCut; nc++) {
259 if(ii.is_zero()) continue;
262 for(auto li : Internal) {
264 lst ns = ex_to<lst>(fi.op(0));
266 for(int i=0; i<pdim; i++) {
267 if(is_zero(Shift[i+1]) && ns.op(i)<=0) continue;
268 if(Propagator.op(i).has(li)) {
277 if(ii.is_zero()) continue;
285 for(
auto ilst : eqns_result) {
286 if(ilst.nops()<1)
continue;
287 for(
auto eqn : ilst) eqns.append(eqn);
292 for(
auto eqn : eqns) find(eqn, F(
w), fs);
293 for(
auto intg : Integral) fs.insert(F(intg));
294 for(
auto intg : PIntegral) fs.insert(F(intg));
298 int sid=0, rsum=0, ssum=0;
299 auto idx_lst = fi.op(0);
300 for(
int i=0; i<idx_lst.nops(); i++) {
301 auto idx = ex_to<numeric>(idx_lst.op(i)).to_int();
302 if(idx!=0) sid += std::pow(2,idx_lst.nops()-i-1);
314 item.append(rsum+ssum);
317 for(
auto ii : ss) item.append(-ii);
318 for(
auto ii : rs) item.append(ii);
319 }
else if(sort_option==1) {
320 item.append(rsum+ssum);
324 for(
auto ii : ss) item.append(ii);
325 for(
auto ii : rs) item.append(ii);
326 }
else if(sort_option==2) {
327 item.append(rsum+ssum);
331 for(
auto ii : rs) item.append(ii);
332 for(
auto ii : ss) item.append(ii);
333 }
else if(sort_option==-1) {
334 item.append(rsum+ssum);
338 for(
auto ii : ss) item.append(-ii);
339 for(
auto ii : rs) item.append(ii);
340 }
else if(sort_option==-2) {
341 item.append(rsum+ssum);
345 for(
auto ii : rs) item.append(ii);
346 for(
auto ii : ss) item.append(-ii);
349 intg_vec.push_back(item);
353 unsigned long long int64 = 100000000000000;
354 for(
auto intg : intg_vec) {
356 unsigned long long weight = int64;
357 auto idx = intg.op(intg.nops()-1).op(0);
358 for(
int nc=0; nc<nCut; nc++) {
361 weight += 100000000000000;
370 if(WorkingDir.length()<1) WorkingDir = to_string(getpid())+
"IBP";
371 string job_dir = WorkingDir +
"/" + to_string(ProblemNumber);
372 system((
"rm -rf "+job_dir).c_str());
373 if(!
dir_exists(job_dir)) system((
"mkdir -p "+job_dir).c_str());
376 for(
auto eqn : eqns) {
377 if(is_zero(eqn))
continue;
380 oss << Fout(cv.op(1)) <<
" * (" << cv.op(0) <<
")" << endl;
385 ofstream eqn_out(job_dir+
"/equations");
386 string ostr = oss.str();
389 eqn_out << ostr << endl;
394 oss <<
"jobs:" << endl;
395 oss <<
" - reduce_user_defined_system:" << endl;
396 oss <<
" input_system: " << endl;
397 oss <<
" config: false" << endl;
398 oss <<
" files: [equations]" << endl;
399 if(PIntegral.nops()>0) {
401 int nn = PIntegral.nops();
402 for(
int i=0; i<nn; i++) oss2 << Fout(PIntegral.op(i)) << endl;
403 ofstream pref_out(job_dir+
"/preferred");
404 pref_out << oss2.str() << endl;
406 oss <<
" preferred_masters: preferred" << endl;
408 oss <<
" - kira2file:" << endl;
409 oss <<
" target:" << endl;
410 if(!using_uw) oss <<
" - [F,integrals]" << endl;
411 else oss <<
" - [Tuserweight,integrals]" << endl;
412 ofstream job_out(job_dir+
"/jobs");
413 job_out << oss.str() << endl;
418 for(
auto integral : Integral) oss << Fout(integral) << endl;
419 ofstream intg_out(job_dir+
"/integrals");
420 intg_out << oss.str() << endl;
428 string job_dir = WorkingDir +
"/" + to_string(ProblemNumber);
430 cmd <<
"cd " << job_dir <<
" && kira " << KArgs <<
" --silent jobs >/dev/null 2>&1";
431 system(cmd.str().c_str());
437 void UKIRA::Import() {
438 string job_dir = WorkingDir +
"/" + to_string(ProblemNumber);
440 if(!using_uw) fn << job_dir <<
"/results/F/kira_integrals.kira";
441 else fn << job_dir <<
"/results/Tuserweight/kira_integrals.kira";
445 map<ex,int,ex_is_less> flags;
447 for(
auto intg : Integral) flags[F(ProblemNumber,intg)] = 1;
449 for(
auto line : strvec) {
452 Rules.append(exL==exR);
457 }
else if(is_zero(exL)) {
459 if(!exL.match(F(
w1,
w2))) {
460 cout << line << endl;
461 throw Error(
"UKIRA::Import error found.");
468 Rules.append(exL==exR);
472 MIntegral.remove_all();
473 for(
auto kv : flags) {
474 if(kv.second!=0) MIntegral.append(kv.first);
477 find(exRs,F(
w1,
w2),miset);
478 for(
auto mi : miset) MIntegral.append(mi);
class used to wrap error message
class to wrap map_function of GiNaC
class extended to GiNaC symbol class, represent a positive symbol
void Export() override
Export input data for KIRA.
ex sp(const ex &a, const ex &b)
translated the vector dot a.b to a*b, useful in SecDec
ex str2ex(const string &expr, symtab stab)
convert string to ex expression, using Parser internally
vector< string > file2strvec(string filename, bool skip_empty)
read file content to string vector
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_vec(exvector &ivec, bool less=true)
sort the list in less order, or the reverse
void string_replace_all(string &str, const string &from, const string &to)
string ex2str(const ex &expr)
convert ex to output string, the defalut printer format will be used
bool dir_exists(string dir)
exvector GiNaC_Parallel(int ntotal, std::function< ex(int)> f, const string &key)
GiNaC Parallel Evaluation using fork.
int ex2int(ex num)
ex to integer