16 static void a_print(
const ex & ex_in,
const print_context & c) {
17 c.s <<
"a[" << ex_in <<
"]";
34 ar.archive_ex(
Cut,
"Cut");
35 ar.archive_ex(
DSP,
"DSP");
36 ar.archive_ex(
ISP,
"ISP");
37 ar.archive_ex(
SECTOR,
"SECTOR");
39 ar.archive_ex(
Shift.size(),
"NShift");
41 for(
auto kv :
Shift) {
42 ar.archive_ex(kv.first, (
"ShiftK-"+to_string(i)).c_str());
43 ar.archive_ex(kv.second, (
"ShiftV-"+to_string(i)).c_str());
47 ar.archive_ex(
reCut,
"reCut");
52 ar.archive_ex(
Rules,
"Rules");
62 for(
auto kv :
Shift) shift.append(lst{kv.first, kv.second});
64 return lst{ Internal, External, Replacement, Propagator, Cut, DSP, ISP, SECTOR, shift, reCut, ProblemNumber,
Symbol(WorkingDir), PIntegral, MIntegral, Rules, IsAlwaysZero };
67 void IBP::garImport(
string garfn) {
73 Internal = ex_to<lst>(ar.unarchive_ex(
"Internal"));
74 External = ex_to<lst>(ar.unarchive_ex(
"External"));
75 Replacement = ex_to<lst>(ar.unarchive_ex(
"Replacement"));
76 Propagator = ex_to<lst>(ar.unarchive_ex(
"Propagator"));
77 Cut = ex_to<lst>(ar.unarchive_ex(
"Cut"));
78 DSP = ex_to<lst>(ar.unarchive_ex(
"DSP"));
79 ISP = ex_to<lst>(ar.unarchive_ex(
"ISP"));
80 SECTOR = ex_to<lst>(ar.unarchive_ex(
"SECTOR"));
82 int n = ex_to<numeric>(ar.unarchive_ex(
"NShift")).to_int();
83 for(
int i=0; i<n; i++) {
84 int key = ex_to<numeric>(ar.unarchive_ex((
"ShiftK-"+to_string(i)).c_str())).to_int();
85 ex val = ar.unarchive_ex((
"ShiftV-"+to_string(i)).c_str());
89 reCut = !(ar.unarchive_ex(
"reCut").is_zero());
90 ProblemNumber = ex_to<numeric>(ar.unarchive_ex(
"ProblemNumber")).to_int();
91 WorkingDir = ex_to<Symbol>(ar.unarchive_ex(
"WorkingDir")).get_name();
92 PIntegral = ex_to<lst>(ar.unarchive_ex(
"PIntegral"));
93 MIntegral = ex_to<lst>(ar.unarchive_ex(
"MIntegral"));
94 Rules = ex_to<lst>(ar.unarchive_ex(
"Rules"));
95 IsAlwaysZero = !(ar.unarchive_ex(
"IsAlwaysZero").is_zero());
98 void IBP::FROM(ex s) {
100 Internal = ex_to<lst>(s.op(i++));
101 External = ex_to<lst>(s.op(i++));
102 Replacement = ex_to<lst>(s.op(i++));
103 Propagator = ex_to<lst>(s.op(i++));
104 Cut = ex_to<lst>(s.op(i++));
105 DSP = ex_to<lst>(s.op(i++));
106 ISP = ex_to<lst>(s.op(i++));
107 if(s.nops()>15) SECTOR = ex_to<lst>(s.op(i++));
108 lst shift = ex_to<lst>(s.op(i++));
109 reCut = s.op(i++).is_equal(1);
110 ProblemNumber = ex_to<numeric>(s.op(i++)).to_int();
111 WorkingDir = ex_to<Symbol>(s.op(i++)).get_name();
112 PIntegral = ex_to<lst>(s.op(i++));
113 MIntegral = ex_to<lst>(s.op(i++));
114 Rules = ex_to<lst>(s.op(i++));
115 IsAlwaysZero = s.op(i++).is_equal(1);
116 for(
auto item : shift) Shift[ex_to<numeric>(item.op(0)).to_int()] = item.op(1);
119 void IBP::ReShare(
const vector<IBP*> & fs) {
120 string garfn = to_string(getpid())+
".ReShare.gar";
123 for(
int i=0; i<fs.size(); i++) {
124 string si = to_string(i);
125 ar.archive_ex(fs[i]->Internal, (si+
"-1").c_str());
126 ar.archive_ex(fs[i]->External, (si+
"-2").c_str());
127 ar.archive_ex(fs[i]->Replacement, (si+
"-3").c_str());
128 ar.archive_ex(fs[i]->Propagator, (si+
"-4").c_str());
129 ar.archive_ex(fs[i]->DSP, (si+
"-5").c_str());
130 ar.archive_ex(fs[i]->ISP, (si+
"-6").c_str());
131 ar.archive_ex(fs[i]->SECTOR,(si+
"-7").c_str());
132 ar.archive_ex(fs[i]->PIntegral, (si+
"-8").c_str());
133 ar.archive_ex(fs[i]->MIntegral, (si+
"-9").c_str());
134 ar.archive_ex(fs[i]->Rules, (si+
"-10").c_str());
146 map<string, ex> dict;
147 for(
int i=0; i<ar.num_expressions(); i++) {
149 ex res = ar.unarchive_ex(name, i);
153 for(
int i=0; i<fs.size(); i++) {
154 string si = to_string(i);
155 fs[i]->Internal = ex_to<lst>(dict[si+
"-1"]);
156 fs[i]->External = ex_to<lst>(dict[si+
"-2"]);
157 fs[i]->Replacement = ex_to<lst>(dict[si+
"-3"]);
158 fs[i]->Propagator = ex_to<lst>(dict[si+
"-4"]);
159 fs[i]->DSP = ex_to<lst>(dict[si+
"-5"]);
160 fs[i]->ISP = ex_to<lst>(dict[si+
"-6"]);
161 fs[i]->SECTOR = ex_to<lst>(dict[si+
"-7"]);
162 fs[i]->PIntegral = ex_to<lst>(dict[si+
"-8"]);
163 fs[i]->MIntegral = ex_to<lst>(dict[si+
"-9"]);
164 fs[i]->Rules = ex_to<lst>(dict[si+
"-10"]);
169 pair<exmap,lst> IBP::FindRules(
bool is_mi) {
170 if(!
has_w(Replacement)) {
172 for(
auto item : Replacement) {
174 repl.append(
w*item.op(0) ==
w*item.op(1));
179 ibps.push_back(
this);
181 if(is_mi && rs_mis.first.size()>0) {
182 auto nr = Rules.nops();
183 for(
int i=0; i<nr; i++) {
184 auto ri = Rules.op(i);
185 Rules.let_op(i) = (ri.op(0) == ri.op(1).subs(rs_mis.first,
nopat));
187 for(
auto mi : MIntegral) {
188 auto mi2 = mi.subs(rs_mis.first,
nopat);
189 if(mi==mi2)
continue;
190 Rules.append(mi==mi2);
192 MIntegral = rs_mis.second;
209 map<ex,vector<int>,ex_is_less> pgrp;
210 if(!expr.is_polynomial(xs)) {
211 if(
Verbose>2) cout <<
"SortPermutation: NOT a polynomials, try ALL permutations!" << endl;
212 expr = expr.numer_denom();
213 if(
true || !expr.op(0).is_polynomial(xs) || !expr.op(1).is_polynomial(xs)) {
215 for(
int i=0; i<xs.nops(); i++) {
216 pgrp[-1].push_back(i);
217 xmap[xs.op(i)] = xs.op(i);
220 expr = expr.op(0) * expr.op(1);
227 for(
auto item : cv_lst) cvs.push_back(item);
238 if(is_zero(cc))
continue;
239 if(!first && !is_zero(cc-clast)) {
240 for(
int i=0; i<nxi; i++) {
242 for(
auto item : subkey[i]) xkey[i].append(item);
243 subkey[i].remove_all();
248 for(
int i=0; i<nxi; i++) subkey[i].append(vv.degree(xs.op(i)));
251 for(
int i=0; i<nxi; i++) {
253 for(
auto item : subkey[i]) xkey[i].append(item);
254 subkey[i].remove_all();
258 for(
int i=0; i<nxi; i++) key_xi.push_back(lst{xkey[i], xs.op(i)});
261 for(
int i=0; i<nxi; i++) {
262 auto xi = key_xi[i].op(1);
263 auto xki = key_xi[i].op(0);
265 pgrp[xki].push_back(i);
267 expr = expr.subs(xmap,
nopat);
275 for(
auto pi : pgrp) {
276 int nvi = pi.second.size();
277 for(
int i=1; i<=nvi; i++) npt *= i;
279 for(
long long np=0; np<npt; np++) {
282 for(
auto pi : pgrp) {
287 for(
int i=1; i<=nvi; i++) npti *= i;
294 for(
int j=1; j<nvi; ++j) {
295 std::swap(vip[k%(j+1)], vip[j]);
299 for(
int j=0; j<nvi; j++) xmap_tmp[xs.op(vi[j])] = xs.op(vip[j]);
301 ex expr_tmp = expr.subs(xmap_tmp,nopat);
302 if(
ex_less(expr_tmp, expr_min)) {
308 for(
auto & kv : xmap) kv.second = kv.second.
subs(xmap_min,
nopat);
324 for(
int i=0; i<props.nops(); i++) {
329 if(is_a<numeric>(cc)) {
331 sign *= pow(-1, idx.op(i));
332 props.let_op(i) = ex(0)-props.op(i);
337 cout << endl << ipr << endl;
338 throw Error(
"LoopUF: sign of iEpsilon NOT determined.");
343 if(ipr.degree(lp)==2) {
344 auto cc = ipr.coeff(lp,2);
345 if(is_a<numeric>(cc)) {
347 sign *= pow(-1, idx.op(i));
348 props.let_op(i) = ex(0)-props.op(i);
363 int nps = props.nops();
365 for(
int i=0; i<nps; i++) {
366 if(is_zero(idx.op(i))) {
371 if(!is_zero(idx.op(i)-1)) x2ax[x(nxi)] =
a(idx.op(i)) * x(nxi);
373 ft -= x(nxi) * props.op(i);
377 static map<ex,exmap,ex_is_less> cache_by_prop;
379 exmap & cache = cache_by_prop[lst{props,ibp.
Internal}];
384 for(
int i=0; i<ibp.
Internal.nops(); i++) {
385 auto t2 = ft.coeff(ibp.
Internal.op(i),2);
386 auto t1 = ft.coeff(ibp.
Internal.op(i),1);
389 if(is_zero(t2))
return lst{0,0,1};
401 auto cc = cache[key];
407 ut = ut.subs(x2ax,
nopat);
408 ft = ft.subs(x2ax,
nopat);
409 uf = uf.subs(x2ax,
nopat);
413 ut = (ut.subs(xmap,
nopat));
414 ft = (ft.subs(xmap,
nopat));
415 return lst{ut, ft, sign};
428 lst
UF(
const ex & props,
const ex & ns,
const ex & loops,
const ex & tloops,
const ex & lsubs,
const ex & tsubs) {
433 for(
int i=0; i<ps.nops(); i++) {
438 if(is_a<numeric>(cc)) {
440 sign *= pow(-1, ns.op(i));
441 ps.let_op(i) = ex(0)-ps.op(i);
445 }
else throw Error(
"UF: sign of iEpsilon NOT determined.");
448 for(
auto lp : loops) {
449 if(ipr.degree(lp)==2) {
450 auto cc = ipr.coeff(lp,2);
451 if(is_a<numeric>(cc)) {
453 sign *= pow(-1, ns.op(i));
454 ps.let_op(i) = ex(0)-ps.op(i);
461 ipr = expand(ipr).subs(lsubs).subs(tsubs);
462 for(
auto lp : tloops) {
463 if(ipr.degree(lp)==2) {
464 auto cc = ipr.coeff(lp,2);
465 if(is_a<numeric>(cc)) {
467 sign *= pow(-1, ns.op(i));
468 ps.let_op(i) = ex(0)-ps.op(i);
485 for(
int i=0; i<nps; i++) {
486 if(is_zero(ns.op(i))) {
491 if(!is_zero(ns.op(i)-1)) x2ax[x(nxi)] =
a(ns.op(i)) * x(nxi);
493 ft -= x(nxi) * ps.op(i);
497 static map<ex,exmap,ex_is_less> cache_by_prop;
498 exmap & cache = cache_by_prop[lst{ps,loops,tloops}];
502 ft =
subs(ft, lsubs);
503 for(
int i=0; i<loops.nops(); i++) {
504 auto t2 = ft.coeff(loops.op(i),2);
505 auto t1 = ft.coeff(loops.op(i),1);
506 auto t0 = ft.subs(loops.op(i)==0,
nopat);
508 if(is_zero(t2))
return lst{0,0,0,1};
511 ft =
subs(ft, lsubs);
519 ft =
subs(ft, tsubs);
520 for(
int i=0; i<tloops.nops(); i++) {
521 auto t2 = ft.coeff(tloops.op(i),2);
522 auto t1 = ft.coeff(tloops.op(i),1);
523 auto t0 = ft.subs(tloops.op(i)==0,
nopat);
525 if(is_zero(t2))
return lst{0,0,0,1};
528 ft =
subs(ft, tsubs);
537 auto cc = cache[key];
543 ut1 = ut1.subs(x2ax,
nopat);
544 ut2 = ut2.subs(x2ax,
nopat);
545 ft = ft.subs(x2ax,
nopat);
546 uf = uf.subs(x2ax,
nopat);
550 uf = uf.subs(xmap,
nopat);
553 if(tloops.nops()>1) {
555 auto nzi = tloops.nops();
556 for(
int i=0; i<nzi; i++) zs.append(z(i+1));
558 for(
auto kv : zmap) xmap[kv.first] = kv.second;
561 ut1 = (ut1.subs(xmap,
nopat));
562 ut2 = (ut2.subs(xmap,
nopat));
563 ft = (ft.subs(xmap,
nopat));
564 return lst{ut1, ut2, ft, sign};
574 pair<exmap,lst>
FindRules(vector<IBP*> fs,
bool mi, std::function<lst(
const IBP &,
const ex &)> uf) {
575 vector<pair<IBP*,ex>> ibp_idx_vec;
577 for(
auto & fi : fs) {
578 if(!
has_w(fi->Replacement)) {
580 for(
auto item : fi->Replacement) {
582 repl.append(
w*item.op(0) ==
w*item.op(1));
584 fi->Replacement = repl;
588 if(mi)
for(
auto fi : fs)
for(
auto item : fi->MIntegral) ibp_idx_vec.push_back(make_pair(fi, item));
589 else for(
auto fi : fs)
for(
auto item : fi->Integral) ibp_idx_vec.push_back(make_pair(fi, F(fi->ProblemNumber,item)));
591 exvector uf_smi_vec =
GiNaC_Parallel(ibp_idx_vec.size(), [&ibp_idx_vec,&uf](
int idx)->ex {
592 auto p = ibp_idx_vec[idx];
593 const IBP & fi = (*p.first);
595 auto ks = uf(fi,mi.subs(F(w1,w2)==w2));
596 int nk = ks.nops()-1;
598 for(int i=0; i<nk; i++) key.append(expand(ks.op(i)));
599 lst pi = fi.Propagator;
600 return lst{ key, lst{ pi, ks.op(nk), mi } };
603 map<ex,lst,ex_is_less> group;
604 int ntotal = uf_smi_vec.size();
607 for(
auto item : uf_smi_vec) {
608 group[item.op(0)].append(item.op(1));
616 for(
auto g : group) {
617 if(g.second.nops()==1) {
619 vs.insert(g.second.op(0));
623 pis.insert(vi.op(0));
624 int_lst.append(vi.op(2));
626 for(
auto ki : ks) group.erase(ki);
629 while(!group.empty()) {
632 for(
auto g : group) {
634 for(
auto gi : g.second) {
635 auto itr = pis.find(gi.op(0));
646 for(
auto gi : g.second) {
649 if(v0.is_equal(vi))
continue;
650 rules[vi] = v0 * c0 / ci;
653 for(
auto ki : ks) group.erase(ki);
654 if(group.empty())
break;
659 for(
auto g : group) {
662 pis.insert(g.second.op(0).op(0));
666 if(!In_GiNaC_Parallel && Verbose>2) cout <<
PRE <<
"\\--FindRules: " <<
WHITE << ntotal <<
" :> " << int_lst.nops() <<
RESET <<
" @ " <<
now(
false) << endl;
667 return make_pair(rules,int_lst);
670 static matrix Redrowech(
const matrix & mat) {
671 Fermat &fermat = Fermat::get();
672 int &v_max = fermat.vmax;
676 for(const_preorder_iterator i = tree.preorder_begin(); i != tree.preorder_end(); ++i) {
678 if(is_a<symbol>(e) || e.match(
a(w))) rep_vs.append(e);
687 for(
auto vi : rep_vs) {
688 auto name =
"v" + to_string(fvi);
689 v2f[vi] = Symbol(name);
696 cout << rep_vs << endl;
697 throw Error(
"Fermat: Too many variables.");
700 for(
int i=v_max; i<fvi; i++) ss <<
"&(J=v" << i <<
");" << endl;
701 fermat.Execute(ss.str());
707 int nrow = mat.rows();
708 int ncol = mat.cols();
710 ss <<
"Array m[" << nrow <<
"," << ncol <<
"];" << endl;
711 fermat.Execute(ss.str());
716 for(
int c=0; c<ncol; c++) {
717 for(
int r=0; r<nrow; r++) {
718 ss << mat(r,c).subs(iEpsilon==0,nopat).subs(v2f,nopat) <<
",";
722 ss <<
"Redrowech([m]);" << endl;
729 ss <<
"&(U=1);" << endl;
731 auto ostr = fermat.Execute(ss.str());
737 ss <<
"&(U=0);" << endl;
738 ss <<
"@([m]);" << endl;
739 ss <<
"&_G;" << endl;
740 fermat.Execute(ss.str());
745 if(ostr[ostr.length()-1]!=
'0')
throw Error(
"Direc::Export, last char is NOT 0.");
746 ostr = ostr.substr(0, ostr.length()-1);
749 ostr.erase(0, ostr.find(
":=")+2);
753 matrix mr(nrow, ncol);
754 auto res = fp.Read(ostr);
755 for(
int r=0; r<nrow; r++) {
756 auto cur = res.op(r);
757 for(
int c=0; c<ncol; c++) mr(r,c) = cur.op(c);
762 bool IBP::IsZero(ex sector) {
763 auto props = Propagator;
766 int nps = props.nops();
768 for(
int i=0; i<nps; i++) {
769 if(is_zero(sector.op(i)))
continue;
771 ft -= x(nxi) * props.op(i);
777 ft =
subs(ft, Replacement);
778 for(
int i=0; i<Internal.nops(); i++) {
779 auto t2 = ft.coeff(Internal.op(i),2);
780 auto t1 = ft.coeff(Internal.op(i),1);
781 auto t0 = ft.subs(Internal.op(i)==0,
nopat);
783 if(is_zero(t2))
return true;
786 ft =
subs(ft, Replacement);
800 sum += ki * xi *
diff_ex(G,xi);
811 mat(ri,ci) = cv.op(0).coeff(ki);
814 mat(ri,cn) = cv.op(0).subs(ks20,
nopat);
817 auto mat2 = Redrowech(mat);
818 for(
int ri=rn-1; ri>=0; ri--) {
819 for(
int ci=0; ci<cn; ci++) {
820 if(!is_zero(mat2(ri,ci)))
return true;
822 if(!is_zero(mat2(ri,cn)))
return false;
829 for(
auto ii : Internal) InExternal.append(ii);
830 for(
auto ii : External) InExternal.append(ii);
833 for(
auto it : Internal) {
834 for(
auto ii : InExternal) ISP.append(it*ii);
840 int pdim = Propagator.nops();
841 if(ISP.nops() > pdim) {
842 cout <<
"ISP = " << ISP << endl;
843 cout <<
"Propagator = " << Propagator << endl;
844 throw Error(
"IBP::SP2Pn: #(ISP) > #(Propagator).");
849 for(
auto item : ISP) {
851 symbol si(
"sp"+to_string(_pic));
853 sp2s.append(
w*item==
w*si);
854 sp2s.append(item==si);
855 s2sp.append(si==item);
859 for(
int i=0; i<ISP.nops(); i++) {
860 auto eq = expand(Propagator.op(i)).subs(
iEpsilon==0);
862 eq = eq.subs(Replacement);
863 if(eq.has(iWF(
w)))
throw Error(
"IBP::SP2Pn, iWF used in eq.");
864 eqns.append(eq == iWF(i));
866 auto s2p = lsolve(eqns, ss);
867 if(s2p.nops() != ISP.nops()) {
868 cout << ISP << endl << s2p << endl << eqns << endl;
869 throw Error(
"IBP::SP2Pn: lsolve failed.");
874 ex k = r.op(0).subs(s2sp,
nopat);
876 ex chk = v.subs(iWF(
w)==0);
879 for(
int i=0; i<ISP.nops(); i++) {
880 ex t = v.coeff(iWF(i));
884 if(!normal(chk-v).is_zero())
throw Error(
"IBP::SP2Pn check failed.");
890 exmap IBP::Dinv(
const lst & ns) {
892 for(
auto ii : Internal) InExternal.append(ii);
893 for(
auto ii : External) InExternal.append(ii);
894 auto & es = External;
896 int pN = Propagator.nops();
898 for(
int r=0; r<eN; r++)
for(
int c=0; c<eN; c++) G(r,c) = (es.op(r)*es.op(c)).
subs(Replacement);
899 matrix Gi = G.inverse(solve_algo::gauss);
902 auto sp2pn = SP2Pn();
903 for(
int p1i=0; p1i<eN; p1i++) {
904 for(
int p2i=p1i; p2i<eN; p2i++) {
908 if(p1i==p2i) pf = 1/ex(2);
910 for(
int pi=0; pi<pN; pi++) {
912 ns2.let_op(pi) = ns.op(pi)+1;
913 ex dpi = -ns.op(pi)*
diff_ex(Propagator.op(pi), p1);
914 for(
int i=0; i<eN; i++) {
915 ex idpi =
expand_ex(dpi*es.op(i)).subs(Replacement);
918 if(is_zero(cv.op(1)-1)) res += cv.op(0)*pf*Gi(i,p2i)*F(ProblemNumber, ns2);
920 auto f = sp2pn.find(cv.op(1));
921 if(f==sp2pn.end())
throw Error(
"IBP::DExt, Not found.");
922 auto cps = f->second;
923 res += cv.op(0)*pf*Gi(i,p2i)*cps.op(0)*F(ProblemNumber, ns2);
924 for(
int j=1; j<pN+1; j++) {
925 if(is_zero(cps.op(j)))
continue;
927 ns3.let_op(j-1) = ns2.op(j-1)-1;
928 res += cv.op(0)*pf*Gi(i,p2i)*cps.op(j)*F(ProblemNumber, ns3);
939 ex IBP::D(
const ex & x,
const lst & ns) {
941 for(
auto ii : Internal) InExternal.append(ii);
942 for(
auto ii : External) InExternal.append(ii);
943 int pN = Propagator.nops();
944 auto sp2pn = SP2Pn();
947 for(
int pi=0; pi<pN; pi++) {
949 ns2.let_op(pi) = ns.op(pi)+1;
950 ex Pi = Propagator.op(pi);
951 Pi = Pi.subs(Replacement);
952 ex dpi = -ns.op(pi)*
diff_ex(Pi, x);
955 if(is_zero(cv.op(1)-1)) res += cv.op(0)*F(ProblemNumber, ns2);
957 auto f = sp2pn.find(cv.op(1));
958 if(f==sp2pn.end())
throw Error(
"IBP::DExt, Not found.");
959 auto cps = f->second;
960 res += cv.op(0)*cps.op(0)*F(ProblemNumber, ns2);
961 for(
int j=1; j<pN+1; j++) {
962 if(is_zero(cps.op(j)))
continue;
964 ns3.let_op(j-1) = ns2.op(j-1)-1;
965 res += cv.op(0)*cps.op(j)*F(ProblemNumber, ns3);
973 auto eN = External.nops();
974 for(
int i=0; i<eN; i++) {
975 for(
int j=i; j<eN; j++) {
976 ex
sp = External.op(i) * External.op(j);
977 auto f = dsp.find(
sp);
978 if(f==dsp.end())
throw Error(
"DESS::InitDE, sp NOT found.");
979 auto rsp =
sp.subs(Replacement);
980 if(
sp==rsp)
throw Error(
"DESS::InitDE, sp==rsp, Replacement NOT work.");
981 res += f->second *
diff_ex(rsp, x);
987 void IBP::RM(
bool keep_start_config) {
988 string spn = to_string(ProblemNumber);
989 if(!keep_start_config) {
997 void IBP::rm(
const string & pat) {
998 string spn = to_string(ProblemNumber);
999 string fn = WorkingDir+
"/"+spn+pat;
1012 int nps = props.nops();
1014 for(
int i=0; i<nps; i++) {
1016 ft -= x(nxi) * props.op(i);
1023 for(
int i=0; i<ibp.
Internal.nops(); i++) {
1024 auto t2 = ft.coeff(ibp.
Internal.op(i),2);
1025 auto t1 = ft.coeff(ibp.
Internal.op(i),1);
1028 if(is_zero(t2))
return lst{0,0,1};
1044 map<ex,vector<ex>,ex_is_less> pgrp;
1049 for(
auto item : cv_lst) cvs.push_back(item);
1052 int nxi = xs.nops();
1057 for(
auto cv : cvs) {
1060 if(is_zero(cc))
continue;
1061 if(!first && !is_zero(cc-clast)) {
1062 for(
int i=0; i<nxi; i++) {
1064 for(
auto item : subkey[i]) xkey[i].append(item);
1065 subkey[i].remove_all();
1070 for(
int i=0; i<nxi; i++) subkey[i].append(vv.degree(xs.op(i)));
1073 for(
int i=0; i<nxi; i++) {
1075 for(
auto item : subkey[i]) xkey[i].append(item);
1076 subkey[i].remove_all();
1080 for(
int i=0; i<nxi; i++) key_xi.push_back(lst{xkey[i], xs.op(i)});
1083 for(
int i=0; i<nxi; i++) {
1084 auto xi = key_xi[i].op(1);
1085 auto xki = key_xi[i].op(0);
1086 pgrp[xki].push_back(xi);
1092 for(
auto pi : pgrp) {
1093 int nvi = pi.second.size();
1094 for(
int i=1; i<=nvi; i++) npt *= i;
1096 for(
long long np=0; np<npt; np++) {
1099 for(
auto pi : pgrp) {
1100 auto vi = pi.second;
1101 int nvi = vi.size();
1104 for(
int i=1; i<=nvi; i++) npti *= i;
1105 int ck = npc % npti;
1111 for(
int j=1; j<nvi; ++j) {
1112 std::swap(vip[k%(j+1)], vip[j]);
1116 for(
int j=0; j<nvi; j++)
if(vi[j]!=vip[j]) xmap_tmp[vi[j]] = vip[j];
1118 if(xmap_tmp.size()>0) {
1119 ex expr_tmp = expr.subs(xmap_tmp,nopat);
1120 if(is_zero(expr-expr_tmp)) {
1121 auto xs_tmp = xs.subs(xmap_tmp,nopat);
1122 cout << xs_tmp << endl;
bool file_exists(const char *fn)
class used to wrap error message
IBP base class for IBP reduction.
void garExport(string garfn)
class extended to GiNaC symbol class, represent a positive symbol
ex expand_ex(ex const &expr_in, std::function< bool(const ex &)> has_func)
the expand like Mathematica
bool ex_less(const ex &a, const ex &b)
ex sp(const ex &a, const ex &b)
translated the vector dot a.b to a*b, useful in SecDec
void GPermutation(const ex &uf, const lst &xs)
ex GPolynomial(const IBP &ibp)
ex collect_ex(ex const &expr_in, std::function< bool(const ex &)> has_func, int opt)
the collect function like Mathematica
lst LoopUF(const IBP &ibp, const ex &idx)
UF function.
pair< exmap, lst > FindRules(vector< IBP * > fs, bool mi, std::function< lst(const IBP &, const ex &)> uf)
Find Rules for Integral or Master Integral.
lst UF(const ex &props, const ex &ns, const ex &loops, const ex &tloops, const ex &lsubs, const ex &tsubs)
UF function, from FIRE.m.
string now(bool use_date)
date/time string
exmap SortPermutation(const ex &in_expr, const lst &xs)
Sort for all permuations, and return xs w.r.t. 1st permutation.
ex exnormal(const ex &expr, int opt)
normalize a expression
ex normal_flint(const ex &expr, int opt=o_flint)
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
ex diff_ex(ex const expr, ex const xp, unsigned nth, bool expand)
the differential like Mathematica
void sort_lst(lst &ilst, bool less=true)
sort the list in less order, or the reverse
bool file_remove(string fn)
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.
REGISTER_FUNCTION(GMat, do_not_evalf_params().print_func< FCFormat >(&GMat_fc_print).conjugate_func(mat_conj).set_return_type(return_types::commutative)) bool IsZero(const ex &e)
void string_trim(string &str)
ex subs(const ex &e, init_list sl)