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 };
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());
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);
111 WorkingDir = ex_to<Symbol>(s.op(i++)).get_name();
114 Rules = ex_to<lst>(s.op(i++));
116 for(
auto item : shift)
Shift[ex_to<numeric>(item.op(0)).to_int()] = item.op(1);
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"]);
171 ibps.push_back(
this);
173 if(is_mi && rs_mis.first.size()>0) {
174 auto nr =
Rules.nops();
175 for(
int i=0; i<nr; i++) {
176 auto ri =
Rules.op(i);
177 Rules.let_op(i) = (ri.op(0) == ri.op(1).subs(rs_mis.first,
nopat));
180 auto mi2 = mi.subs(rs_mis.first,
nopat);
181 if(mi==mi2)
continue;
182 Rules.append(mi==mi2);
201 map<ex,vector<int>,ex_is_less> pgrp;
202 if(!expr.is_polynomial(xs)) {
203 if(
Verbose>2) cout <<
"SortPermutation: NOT a polynomials, try ALL permutations!" << endl;
204 expr = expr.numer_denom();
205 if(
true || !expr.op(0).is_polynomial(xs) || !expr.op(1).is_polynomial(xs)) {
207 for(
int i=0; i<xs.nops(); i++) {
208 pgrp[-1].push_back(i);
209 xmap[xs.op(i)] = xs.op(i);
212 expr = expr.op(0) * expr.op(1);
219 for(
auto item : cv_lst) cvs.push_back(item);
230 if(is_zero(cc))
continue;
231 if(!first && !is_zero(cc-clast)) {
232 for(
int i=0; i<nxi; i++) {
234 for(
auto item : subkey[i]) xkey[i].append(item);
235 subkey[i].remove_all();
240 for(
int i=0; i<nxi; i++) subkey[i].append(vv.degree(xs.op(i)));
243 for(
int i=0; i<nxi; i++) {
245 for(
auto item : subkey[i]) xkey[i].append(item);
246 subkey[i].remove_all();
250 for(
int i=0; i<nxi; i++) key_xi.push_back(lst{xkey[i], xs.op(i)});
253 for(
int i=0; i<nxi; i++) {
254 auto xi = key_xi[i].op(1);
255 auto xki = key_xi[i].op(0);
257 pgrp[xki].push_back(i);
259 expr = expr.subs(xmap,
nopat);
267 for(
auto pi : pgrp) {
268 int nvi = pi.second.size();
269 for(
int i=1; i<=nvi; i++) npt *= i;
271 for(
long long np=0; np<npt; np++) {
274 for(
auto pi : pgrp) {
279 for(
int i=1; i<=nvi; i++) npti *= i;
286 for(
int j=1; j<nvi; ++j) {
287 std::swap(vip[k%(j+1)], vip[j]);
291 for(
int j=0; j<nvi; j++) xmap_tmp[xs.op(vi[j])] = xs.op(vip[j]);
293 ex expr_tmp = expr.subs(xmap_tmp,
nopat);
294 if(
ex_less(expr_tmp, expr_min)) {
300 for(
auto & kv : xmap) kv.second = kv.second.subs(xmap_min,
nopat);
316 for(
int i=0; i<props.nops(); i++) {
321 if(is_a<numeric>(cc)) {
323 sign *= pow(-1, idx.op(i));
324 props.let_op(i) = ex(0)-props.op(i);
329 cout << endl << ipr << endl;
330 throw Error(
"LoopUF: sign of iEpsilon NOT determined.");
335 if(ipr.degree(lp)==2) {
336 auto cc = ipr.coeff(lp,2);
337 if(is_a<numeric>(cc)) {
339 sign *= pow(-1, idx.op(i));
340 props.let_op(i) = ex(0)-props.op(i);
355 int nps = props.nops();
357 for(
int i=0; i<nps; i++) {
358 if(is_zero(idx.op(i))) {
363 if(!is_zero(idx.op(i)-1)) x2ax[x(nxi)] =
a(idx.op(i)) * x(nxi);
365 ft -= x(nxi) * props.op(i);
369 static map<ex,exmap,ex_is_less> cache_by_prop;
371 exmap & cache = cache_by_prop[lst{props,ibp.
Internal}];
376 for(
int i=0; i<ibp.
Internal.nops(); i++) {
377 auto t2 = ft.coeff(ibp.
Internal.op(i),2);
378 auto t1 = ft.coeff(ibp.
Internal.op(i),1);
381 if(is_zero(t2))
return lst{0,0,1};
393 auto cc = cache[key];
399 ut = ut.subs(x2ax,
nopat);
400 ft = ft.subs(x2ax,
nopat);
401 uf = uf.subs(x2ax,
nopat);
405 ut = (ut.subs(xmap,
nopat));
406 ft = (ft.subs(xmap,
nopat));
407 return lst{ut, ft, sign};
420 lst
UF(
const ex & props,
const ex & ns,
const ex & loops,
const ex & tloops,
const ex & lsubs,
const ex & tsubs) {
425 for(
int i=0; i<ps.nops(); i++) {
430 if(is_a<numeric>(cc)) {
432 sign *= pow(-1, ns.op(i));
433 ps.let_op(i) = ex(0)-ps.op(i);
437 }
else throw Error(
"UF: sign of iEpsilon NOT determined.");
440 for(
auto lp : loops) {
441 if(ipr.degree(lp)==2) {
442 auto cc = ipr.coeff(lp,2);
443 if(is_a<numeric>(cc)) {
445 sign *= pow(-1, ns.op(i));
446 ps.let_op(i) = ex(0)-ps.op(i);
453 ipr = expand(ipr).subs(lsubs).subs(tsubs);
454 for(
auto lp : tloops) {
455 if(ipr.degree(lp)==2) {
456 auto cc = ipr.coeff(lp,2);
457 if(is_a<numeric>(cc)) {
459 sign *= pow(-1, ns.op(i));
460 ps.let_op(i) = ex(0)-ps.op(i);
477 for(
int i=0; i<nps; i++) {
478 if(is_zero(ns.op(i))) {
483 if(!is_zero(ns.op(i)-1)) x2ax[x(nxi)] =
a(ns.op(i)) * x(nxi);
485 ft -= x(nxi) * ps.op(i);
489 static map<ex,exmap,ex_is_less> cache_by_prop;
490 exmap & cache = cache_by_prop[lst{ps,loops,tloops}];
494 ft =
subs(ft, lsubs);
495 for(
int i=0; i<loops.nops(); i++) {
496 auto t2 = ft.coeff(loops.op(i),2);
497 auto t1 = ft.coeff(loops.op(i),1);
498 auto t0 = ft.subs(loops.op(i)==0,
nopat);
500 if(is_zero(t2))
return lst{0,0,0,1};
503 ft =
subs(ft, lsubs);
511 ft =
subs(ft, tsubs);
512 for(
int i=0; i<tloops.nops(); i++) {
513 auto t2 = ft.coeff(tloops.op(i),2);
514 auto t1 = ft.coeff(tloops.op(i),1);
515 auto t0 = ft.subs(tloops.op(i)==0,
nopat);
517 if(is_zero(t2))
return lst{0,0,0,1};
520 ft =
subs(ft, tsubs);
529 auto cc = cache[key];
535 ut1 = ut1.subs(x2ax,
nopat);
536 ut2 = ut2.subs(x2ax,
nopat);
537 ft = ft.subs(x2ax,
nopat);
538 uf = uf.subs(x2ax,
nopat);
542 uf = uf.subs(xmap,
nopat);
545 if(tloops.nops()>1) {
547 auto nzi = tloops.nops();
548 for(
int i=0; i<nzi; i++) zs.append(z(i+1));
550 for(
auto kv : zmap) xmap[kv.first] = kv.second;
553 ut1 = (ut1.subs(xmap,
nopat));
554 ut2 = (ut2.subs(xmap,
nopat));
555 ft = (ft.subs(xmap,
nopat));
556 return lst{ut1, ut2, ft, sign};
566 pair<exmap,lst>
FindRules(vector<IBP*> fs,
bool mi, std::function<lst(
const IBP &,
const ex &)> uf) {
567 vector<pair<IBP*,ex>> ibp_idx_vec;
568 if(mi)
for(
auto fi : fs)
for(
auto item : fi->MIntegral) ibp_idx_vec.push_back(make_pair(fi, item));
569 else for(
auto fi : fs)
for(
auto item : fi->Integral) ibp_idx_vec.push_back(make_pair(fi, F(fi->ProblemNumber,item)));
571 exvector uf_smi_vec =
GiNaC_Parallel(ibp_idx_vec.size(), [&ibp_idx_vec,&uf](
int idx)->ex {
572 auto p = ibp_idx_vec[idx];
573 const IBP & fi = (*p.first);
575 auto ks = uf(fi,mi.subs(F(w1,w2)==w2));
576 int nk = ks.nops()-1;
578 for(int i=0; i<nk; i++) key.append(expand(ks.op(i)));
579 lst pi = fi.Propagator;
580 return lst{ key, lst{ pi, ks.op(nk), mi } };
583 map<ex,lst,ex_is_less> group;
584 int ntotal = uf_smi_vec.size();
587 for(
auto item : uf_smi_vec) {
588 group[item.op(0)].append(item.op(1));
596 for(
auto g : group) {
597 if(g.second.nops()==1) {
599 vs.insert(g.second.op(0));
603 pis.insert(vi.op(0));
604 int_lst.append(vi.op(2));
606 for(
auto ki : ks) group.erase(ki);
609 while(!group.empty()) {
612 for(
auto g : group) {
614 for(
auto gi : g.second) {
615 auto itr = pis.find(gi.op(0));
626 for(
auto gi : g.second) {
629 if(v0.is_equal(vi))
continue;
630 rules[vi] = v0 * c0 / ci;
633 for(
auto ki : ks) group.erase(ki);
634 if(group.empty())
break;
639 for(
auto g : group) {
642 pis.insert(g.second.op(0).op(0));
647 return make_pair(rules,int_lst);
650 static matrix Redrowech(
const matrix & mat) {
651 Fermat &fermat = Fermat::get();
652 int &v_max = fermat.vmax;
656 for(const_preorder_iterator i = tree.preorder_begin(); i != tree.preorder_end(); ++i) {
658 if(is_a<symbol>(e) || e.match(
a(
w))) rep_vs.append(e);
667 for(
auto vi : rep_vs) {
668 auto name =
"v" + to_string(fvi);
669 v2f[vi] = Symbol(name);
676 cout << rep_vs << endl;
677 throw Error(
"Fermat: Too many variables.");
680 for(
int i=v_max; i<fvi; i++) ss <<
"&(J=v" << i <<
");" << endl;
681 fermat.Execute(ss.str());
687 int nrow = mat.rows();
688 int ncol = mat.cols();
690 ss <<
"Array m[" << nrow <<
"," << ncol <<
"];" << endl;
691 fermat.Execute(ss.str());
696 for(
int c=0; c<ncol; c++) {
697 for(
int r=0; r<nrow; r++) {
702 ss <<
"Redrowech([m]);" << endl;
709 ss <<
"&(U=1);" << endl;
711 auto ostr = fermat.Execute(ss.str());
717 ss <<
"&(U=0);" << endl;
718 ss <<
"@([m]);" << endl;
719 ss <<
"&_G;" << endl;
720 fermat.Execute(ss.str());
725 if(ostr[ostr.length()-1]!=
'0')
throw Error(
"Direc::Export, last char is NOT 0.");
726 ostr = ostr.substr(0, ostr.length()-1);
729 ostr.erase(0, ostr.find(
":=")+2);
733 matrix mr(nrow, ncol);
734 auto res = fp.Read(ostr);
735 for(
int r=0; r<nrow; r++) {
736 auto cur = res.op(r);
737 for(
int c=0; c<ncol; c++) mr(r,c) = cur.op(c);
743 auto props = Propagator;
746 int nps = props.nops();
748 for(
int i=0; i<nps; i++) {
749 if(is_zero(sector.op(i)))
continue;
751 ft -= x(nxi) * props.op(i);
757 ft =
subs(ft, Replacement);
758 for(
int i=0; i<Internal.nops(); i++) {
759 auto t2 = ft.coeff(Internal.op(i),2);
760 auto t1 = ft.coeff(Internal.op(i),1);
761 auto t0 = ft.subs(Internal.op(i)==0,
nopat);
763 if(is_zero(t2))
return true;
766 ft =
subs(ft, Replacement);
780 sum += ki * xi *
diff_ex(G,xi);
791 mat(ri,ci) = cv.op(0).coeff(ki);
794 mat(ri,cn) = cv.op(0).subs(ks20,
nopat);
797 auto mat2 = Redrowech(mat);
798 for(
int ri=rn-1; ri>=0; ri--) {
799 for(
int ci=0; ci<cn; ci++) {
800 if(!is_zero(mat2(ri,ci)))
return true;
802 if(!is_zero(mat2(ri,cn)))
return false;
809 for(
auto ii : Internal) InExternal.append(ii);
810 for(
auto ii : External) InExternal.append(ii);
813 for(
auto it : Internal) {
814 for(
auto ii : InExternal) ISP.append(it*ii);
820 int pdim = Propagator.nops();
821 if(ISP.nops() > pdim) {
822 cout <<
"ISP = " << ISP << endl;
823 cout <<
"Propagator = " << Propagator << endl;
824 throw Error(
"IBP::SP2Pn: #(ISP) > #(Propagator).");
829 for(
auto item : ISP) {
831 symbol si(
"sp"+to_string(_pic));
833 sp2s.append(
w*item==
w*si);
834 sp2s.append(item==si);
835 s2sp.append(si==item);
839 for(
int i=0; i<ISP.nops(); i++) {
840 auto eq = expand(Propagator.op(i)).subs(
iEpsilon==0);
842 eq = eq.subs(Replacement);
843 if(eq.has(iWF(
w)))
throw Error(
"IBP::SP2Pn, iWF used in eq.");
844 eqns.append(eq == iWF(i));
846 auto s2p = lsolve(eqns, ss);
847 if(s2p.nops() != ISP.nops()) {
848 cout << ISP << endl << s2p << endl << eqns << endl;
849 throw Error(
"IBP::SP2Pn: lsolve failed.");
854 ex k = r.op(0).subs(s2sp,
nopat);
856 ex chk = v.subs(iWF(
w)==0);
859 for(
int i=0; i<ISP.nops(); i++) {
860 ex t = v.coeff(iWF(i));
864 if(!normal(chk-v).is_zero())
throw Error(
"IBP::SP2Pn check failed.");
870 exmap IBP::Dinv(
const lst & ns) {
872 for(
auto ii : Internal) InExternal.append(ii);
873 for(
auto ii : External) InExternal.append(ii);
874 auto & es = External;
876 int pN = Propagator.nops();
878 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);
879 matrix Gi = G.inverse(solve_algo::gauss);
882 auto sp2pn = SP2Pn();
883 for(
int p1i=0; p1i<eN; p1i++) {
884 for(
int p2i=p1i; p2i<eN; p2i++) {
888 if(p1i==p2i) pf = 1/ex(2);
890 for(
int pi=0; pi<pN; pi++) {
892 ns2.let_op(pi) = ns.op(pi)+1;
893 ex dpi = -ns.op(pi)*
diff_ex(Propagator.op(pi), p1);
894 for(
int i=0; i<eN; i++) {
895 ex idpi =
expand_ex(dpi*es.op(i)).subs(Replacement);
898 if(is_zero(cv.op(1)-1)) res += cv.op(0)*pf*Gi(i,p2i)*F(ProblemNumber, ns2);
900 auto f = sp2pn.find(cv.op(1));
901 if(f==sp2pn.end())
throw Error(
"IBP::DExt, Not found.");
902 auto cps = f->second;
903 res += cv.op(0)*pf*Gi(i,p2i)*cps.op(0)*F(ProblemNumber, ns2);
904 for(
int j=1; j<pN+1; j++) {
905 if(is_zero(cps.op(j)))
continue;
907 ns3.let_op(j-1) = ns2.op(j-1)-1;
908 res += cv.op(0)*pf*Gi(i,p2i)*cps.op(j)*F(ProblemNumber, ns3);
919 ex IBP::D(
const ex & x,
const lst & ns) {
921 for(
auto ii : Internal) InExternal.append(ii);
922 for(
auto ii : External) InExternal.append(ii);
923 int pN = Propagator.nops();
924 auto sp2pn = SP2Pn();
927 for(
int pi=0; pi<pN; pi++) {
929 ns2.let_op(pi) = ns.op(pi)+1;
930 ex Pi = Propagator.op(pi);
931 Pi = Pi.subs(Replacement);
932 ex dpi = -ns.op(pi)*
diff_ex(Pi, x);
935 if(is_zero(cv.op(1)-1)) res += cv.op(0)*F(ProblemNumber, ns2);
937 auto f = sp2pn.find(cv.op(1));
938 if(f==sp2pn.end())
throw Error(
"IBP::DExt, Not found.");
939 auto cps = f->second;
940 res += cv.op(0)*cps.op(0)*F(ProblemNumber, ns2);
941 for(
int j=1; j<pN+1; j++) {
942 if(is_zero(cps.op(j)))
continue;
944 ns3.let_op(j-1) = ns2.op(j-1)-1;
945 res += cv.op(0)*cps.op(j)*F(ProblemNumber, ns3);
953 auto eN = External.nops();
954 for(
int i=0; i<eN; i++) {
955 for(
int j=i; j<eN; j++) {
956 ex
sp = External.op(i) * External.op(j);
957 auto f = dsp.find(
sp);
958 if(f==dsp.end())
throw Error(
"DESS::InitDE, sp NOT found.");
959 auto rsp =
sp.subs(Replacement);
960 if(
sp==rsp)
throw Error(
"DESS::InitDE, sp==rsp, Replacement NOT work.");
961 res += f->second *
diff_ex(rsp, x);
967 void IBP::RM(
bool keep_start_config) {
968 string spn = to_string(ProblemNumber);
969 if(!keep_start_config) {
977 void IBP::rm(
const string & pat) {
978 string spn = to_string(ProblemNumber);
979 string fn = WorkingDir+
"/"+spn+pat;
992 int nps = props.nops();
994 for(
int i=0; i<nps; i++) {
996 ft -= x(nxi) * props.op(i);
1003 for(
int i=0; i<ibp.
Internal.nops(); i++) {
1004 auto t2 = ft.coeff(ibp.
Internal.op(i),2);
1005 auto t1 = ft.coeff(ibp.
Internal.op(i),1);
1008 if(is_zero(t2))
return lst{0,0,1};
1024 map<ex,vector<ex>,ex_is_less> pgrp;
1029 for(
auto item : cv_lst) cvs.push_back(item);
1032 int nxi = xs.nops();
1037 for(
auto cv : cvs) {
1040 if(is_zero(cc))
continue;
1041 if(!first && !is_zero(cc-clast)) {
1042 for(
int i=0; i<nxi; i++) {
1044 for(
auto item : subkey[i]) xkey[i].append(item);
1045 subkey[i].remove_all();
1050 for(
int i=0; i<nxi; i++) subkey[i].append(vv.degree(xs.op(i)));
1053 for(
int i=0; i<nxi; i++) {
1055 for(
auto item : subkey[i]) xkey[i].append(item);
1056 subkey[i].remove_all();
1060 for(
int i=0; i<nxi; i++) key_xi.push_back(lst{xkey[i], xs.op(i)});
1063 for(
int i=0; i<nxi; i++) {
1064 auto xi = key_xi[i].op(1);
1065 auto xki = key_xi[i].op(0);
1066 pgrp[xki].push_back(xi);
1072 for(
auto pi : pgrp) {
1073 int nvi = pi.second.size();
1074 for(
int i=1; i<=nvi; i++) npt *= i;
1076 for(
long long np=0; np<npt; np++) {
1079 for(
auto pi : pgrp) {
1080 auto vi = pi.second;
1081 int nvi = vi.size();
1084 for(
int i=1; i<=nvi; i++) npti *= i;
1085 int ck = npc % npti;
1091 for(
int j=1; j<nvi; ++j) {
1092 std::swap(vip[k%(j+1)], vip[j]);
1096 for(
int j=0; j<nvi; j++)
if(vi[j]!=vip[j]) xmap_tmp[vi[j]] = vip[j];
1098 if(xmap_tmp.size()>0) {
1099 ex expr_tmp = expr.subs(xmap_tmp,
nopat);
1100 if(is_zero(expr-expr_tmp)) {
1101 auto xs_tmp = xs.subs(xmap_tmp,
nopat);
1102 cout << xs_tmp << endl;
bool file_exists(const char *fn)
class used to wrap error message
IBP base class for IBP reduction.
void garImport(string garfn)
pair< exmap, lst > FindRules(bool mi=true)
void garExport(string garfn)
static void ReShare(const vector< IBP * > &fs)
class extended to GiNaC symbol class, represent a positive symbol
do_not_evalf_params().expl_derivative_func(zd1D).derivative_func(zp1D)) REGISTER_FUNCTION(FTX
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.
REGISTER_FUNCTION(Matrix, do_not_evalf_params().print_func< FCFormat >(&Matrix_fc_print).conjugate_func(mat_conj).set_return_type(return_types::commutative)) bool IsZero(const ex &e)
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.
void string_trim(string &str)
ex subs(const ex &e, init_list sl)