17 bool SecDec::KillPowerD(ex fe,
int kpi) {
19 auto nlast = fe.op(0).nops()-1;
20 if(fe.op(0).op(nlast)==iWF(1) && fe.op(1).op(nlast).is_zero()) {
24 ex ft = fe.op(0).op(1);
30 for(
auto ftitem : fts) {
32 for(
int i=0; i<xs.size(); i++) {
33 for(
int j=i+1; j<xs.size(); j++) {
35 for(
auto delta : ex_to<lst>(fe.op(2))) {
36 if(delta.has(xs[i]) && delta.has(xs[j])) {
41 if(!has_xij)
continue;
44 auto ftij = ftitem.subs(lst{xs[i]==xi, xs[j]==xj});
48 for(
auto item : fts2) {
49 if(!item.has(xi) || !item.has(xj))
continue;
50 if(item.match(pow(
w1,
w2))) eqn = item.op(0).expand();
52 if(eqn.degree(xi)!=1 || eqn.degree(xj)!=1)
continue;
53 ex ci = eqn.coeff(xi);
54 ex cj = eqn.coeff(xj);
55 if((ci*xi+cj*xj-eqn).is_zero() && is_a<numeric>(ci*cj) && (ci*cj)<0) {
56 eqn = eqn.subs(lst{xi==xs[i], xj==xs[j]});
70 ex ci = eqn.coeff(xi);
71 ex cj = eqn.coeff(xj);
74 if((ci*xi+cj*xj-eqn).is_zero() && is_a<numeric>(ci * cj) && (ci*cj)<0) {
80 auto f1 = ex_to<lst>(fe.op(0));
81 auto e1 = ex_to<lst>(fe.op(1));
83 for(
int i=0; i<f1.nops(); i++) {
84 f1.let_op(i) = f1.op(i).subs(lst{xi==c1*yj/(1+c1)+yi,xj==yj/(1+c1)}).
subs(lst{yi==xi,yj==xj});
86 if(e1.op(0)==1) f1.let_op(0) = f1.op(0)/(1+c1);
87 else if(e1.op(1)==1) f1.let_op(1) = f1.op(1)/(1+c1);
92 FunExp.push_back(lst{f1,e1,fe.op(2)});
94 auto f2 = ex_to<lst>(fe.op(0));
95 auto e2 = ex_to<lst>(fe.op(1));
97 for(
int i=0; i<f2.nops(); i++) {
98 f2.let_op(i) = f2.op(i).subs(lst{xj==c2*yi/(1+c2)+yj,xi==yi/(1+c2)}).
subs(lst{yi==xi,yj==xj});
100 if(e2.op(0)==1) f2.let_op(0) = f2.op(0)/(1+c2);
101 else if(e2.op(1)==1) f2.let_op(1) = f2.op(1)/(1+c2);
106 FunExp.push_back(lst{f2,e2,fe.op(2)});
108 throw Error(
"KillPowerD: Not Expected Region.");
127 bool SecDec::KillPower(ex fe,
int kpi,
int bits) {
129 auto nlast = fe.op(0).nops()-1;
130 if(is_zero(fe.op(0).op(nlast)-iWF(1)) && fe.op(1).op(nlast).is_zero()) {
134 ex ft = fe.op(0).op(1);
140 if(((bits/2)%2)==1) {
141 for(
auto ftitem : fts) {
143 for(
int i=0; i<xs.size(); i++) {
144 for(
int j=i+1; j<xs.size(); j++) {
146 auto ftij = ftitem.subs(lst{xs[i]==xi, xs[j]==xj});
148 for(
int nn=0; nn<std::pow(2,xs2.size()); nn++) {
151 for(
int ni=0; ni<xs2.size(); ni++) {
152 if(tnn%2==1) xsubs.append(xs2[ni]==1);
153 else xsubs.append(xs2[ni]==0);
159 for(
auto item : fts2) {
160 if(!item.has(xi) || !item.has(xj))
continue;
161 if(item.match(pow(
w1,
w2)) || (item.degree(xi)==1 && item.degree(xj)==1)) {
162 if(item.match(pow(
w1,
w2))) eqn = item.op(0);
164 auto t1 = eqn.subs(lst{xi==1/ex(11), xj==1/ex(19)});
165 if(t1.is_zero()) t1 = eqn.subs(lst{xi==1/ex(3), xj==1/ex(23)});
166 if(t1.is_zero()) t1 = eqn.subs(lst{xi==1/ex(13), xj==1/ex(37)});
169 for(
int ni=0; ni<=
NN; ni++) {
170 for(
int nj=0; nj<=
NN; nj++) {
171 auto t2 = eqn.subs(lst{xi==ni/ex(
NN), xj==nj/ex(
NN)});
182 if(eqn.degree(xi)>1 || eqn.degree(xj)>1 || eqn.coeff(xi).has(xj)) {
183 cout <<
WarnColor <<
PRE <<
"\\--Warning: Not handled with eqn1=" << eqn <<
RESET << endl;
187 eqn = eqn.subs(lst{xi==xs[i], xj==xs[j]});
204 if((eqn-(xi+xj-1)).is_zero() || (eqn+(xi+xj-1)).is_zero()) {
208 for(
int i=0; i<f1.nops(); i++) f1.let_op(i) = f1.op(i).subs(xi==1-xx).subs(xx==xi);
209 FunExp.push_back(lst{f1,e1});
213 ex ci = eqn.coeff(xi);
214 ex cj = eqn.coeff(xj);
217 if((ci*xi+cj*xj-eqn).is_zero() && is_a<numeric>(ci * cj) && (ci*cj)<0) {
224 auto f1 = ex_to<lst>(fe.op(0));
225 auto e1 = ex_to<lst>(fe.op(1));
226 for(
int i=0; i<f1.nops(); i++) f1.let_op(i) = f1.op(i).subs(xi==xx*xj).subs(xx==xi);
229 FunExp.push_back(lst{f1,e1});
231 auto f2 = ex_to<lst>(fe.op(0));
232 auto e2 = ex_to<lst>(fe.op(1));
233 for(
int i=0; i<f2.nops(); i++) f2.let_op(i) = f2.op(i).subs(xj==xx*xi).subs(xx==xj);
236 FunExp.push_back(lst{f2,e2});
251 auto f1 = ex_to<lst>(fe.op(0));
252 auto e1 = ex_to<lst>(fe.op(1));
253 for(
int i=0; i<f1.nops(); i++) f1.let_op(i) = f1.op(i).subs(x1==xx*(c1-c2)/c1+c2/c1).subs(xx==x1);
254 if(e1.op(0)==1) f1.let_op(0) = f1.op(0)*(c1-c2)/c1;
255 else if(e1.op(1)==1) f1.let_op(1) = f1.op(1)*(c1-c2)/c1;
257 f1.append((c1-c2)/c1);
260 FunExp.push_back(lst{f1,e1});
262 auto f2 = ex_to<lst>(fe.op(0));
263 auto e2 = ex_to<lst>(fe.op(1));
264 for(
int i=0; i<f2.nops(); i++) f2.let_op(i) = f2.op(i).subs(x1==xx*c2/c1).subs(xx==x1);
265 if(e2.op(0)==1) f2.let_op(0) = f2.op(0)*c2/c1;
266 else if(e2.op(1)==1) f2.let_op(1) = f2.op(1)*c2/c1;
272 for(
int i=0; i<f2.nops(); i++) f2.let_op(i) = f2.op(i).subs(x2==xx*x1).subs(xx==x2);
275 FunExp.push_back(lst{f2,e2});
277 auto f3 = ex_to<lst>(fe.op(0));
278 auto e3 = ex_to<lst>(fe.op(1));
279 for(
int i=0; i<f3.nops(); i++) f3.let_op(i) = f3.op(i).subs(x1==xx*x2*c2/c1).subs(xx==x1);
280 if(e3.op(0)==1) f3.let_op(0) = f3.op(0)*c2/c1;
281 else if(e3.op(1)==1) f3.let_op(1) = f3.op(1)*c2/c1;
288 FunExp.push_back(lst{f3,e3});
290 }
else if( (eqn-(xi+xj-1)).is_zero() || (eqn+(xi+xj-1)).is_zero() ) {
294 auto f1 = ex_to<lst>(fe.op(0));
295 auto e1 = ex_to<lst>(fe.op(1));
296 for(
int i=0; i<f1.nops(); i++) f1.let_op(i) = f1.op(i).subs(xj==xx+1-xi).subs(xx==xj);
298 for(
int i=0; i<f1.nops(); i++) f1.let_op(i) = f1.op(i).subs(xj==xx*xi).subs(xx==xj);
301 FunExp.push_back(lst{f1,e1});
303 auto f2 = ex_to<lst>(fe.op(0));
304 auto e2 = ex_to<lst>(fe.op(1));
305 for(
int i=0; i<f2.nops(); i++) f2.let_op(i) = f2.op(i).subs(lst{xi==(1+zz)*yy/2,xj==(1-zz)*yy/2}).
subs(lst{yy==xi, zz==xj});
308 FunExp.push_back(lst{f2,e2});
310 auto f3 = ex_to<lst>(fe.op(0));
311 auto e3 = ex_to<lst>(fe.op(1));
312 for(
int i=0; i<f3.nops(); i++) f3.let_op(i) = f3.op(i).subs(lst{xj==(1+zz)*yy/2,xi==(1-zz)*yy/2}).
subs(lst{yy==xi, zz==xj});
315 FunExp.push_back(lst{f3,e3});
319 FunExp.push_back(fe);
328 for(
auto ftitem : fts) {
330 for(
int i=0; i<xs.size(); i++) {
332 auto fti = ftitem.subs(lst{xs[i]==xi});
334 for(
int nn=0; nn<std::pow(2,xs2.size()); nn++) {
337 for(
int ni=0; ni<xs2.size(); ni++) {
338 if(tnn%2==1) xsubs.append(xs2[ni]==1);
339 else xsubs.append(xs2[ni]==0);
342 auto fts2 = XRefined_lst(fti.subs(xsubs));
345 for(
auto item : fts2) {
346 if((item.degree(xi)==1 || item.match(pow(
w1,
w2))) && item.has(xi)) {
347 if(item.match(pow(
w1,
w2))) eqn = item.op(0);
348 else if(xs2.size()<1) eqn = item;
350 auto t1 = eqn.subs(lst{xi==1/ex(11)});
351 if(t1.is_zero()) t1 = eqn.subs(lst{xi==1/ex(3)});
352 if(t1.is_zero()) t1 = eqn.subs(lst{xi==1/ex(13)});
355 for(
int ni=0; ni<=
NN; ni++) {
356 auto t2 = eqn.subs(lst{xi==ni/ex(
NN)});
364 if(
Verbose>0 && eqn.degree(xi)>1) {
365 cout <<
WarnColor <<
PRE <<
"\\--Warning: Not handled with eqn3=" << eqn <<
RESET << endl;
370 eqn = eqn.subs(lst{xi==xs[i]});
384 ex ci = eqn.coeff(xi);
385 ex c0 = eqn.subs(lst{xi==0});
387 if((ci*xi+c0-eqn).is_zero() && is_a<numeric>(ci*c0) && (ci*c0)<0 && abs(c0)<abs(ci)) {
394 auto f1 = ex_to<lst>(fe.op(0));
395 auto e1 = ex_to<lst>(fe.op(1));
396 for(
int i=0; i<f1.nops(); i++) f1.let_op(i) = f1.op(i).subs(xi==xx*cc).subs(xx==1-xi);
397 if(e1.op(0)==1) f1.let_op(0) = f1.op(0)*cc;
398 else if(e1.op(1)==1) f1.let_op(1) = f1.op(1)*cc;
403 FunExp.push_back(lst{f1,e1});
405 auto f2 = ex_to<lst>(fe.op(0));
406 auto e2 = ex_to<lst>(fe.op(1));
407 for(
int i=0; i<f2.nops(); i++) f2.let_op(i) = f2.op(i).subs(xi==(1-cc)*xx+cc).subs(xx==xi);
408 if(e2.op(0)==1) f2.let_op(0) = f2.op(0)*(1-cc);
409 else if(e2.op(1)==1) f2.let_op(1) = f2.op(1)*(1-cc);
414 FunExp.push_back(lst{f2,e2});
417 FunExp.push_back(fe);
425 FunExp.push_back(fe);
433 void SecDec::KillPowers(
int bits) {
438 if(kpi>10 && (kpi % 10)==0) {
439 cout <<
"Warning: kip>10, (kpi=" << kpi <<
") maybe a dead loop!" << endl;
443 for(
auto fe : FunExp) {
444 funexp.push_back(fe);
447 FunExp.shrink_to_fit();
450 for(
auto &fe : funexp) {
452 if(fe.nops()>2) ret = KillPowerD(fe, kpi);
453 else ret = KillPower(fe, kpi, bits);
454 if(ret) repeat =
true;
459 for(
auto &fe : FunExp) {
460 auto nn = fe.op(0).nops()-1;
461 if(is_zero(fe.op(0).op(nn)-iWF(1)) && fe.op(1).op(nn).is_zero()) {
static lst XRefined_lst(ex const &ft)
namespace for Numerical integration with Sector Decomposition method
exvector get_x_from(ex pol)
const char * Color_HighLight
ex NN(ex expr, int digits)
the nuerical evaluation
void let_op_append(ex &ex_in, const ex item)
append item into expression
void let_op_remove_last(ex &ex_in)
remove last from expression
ex subs(const ex &e, init_list sl)