22 matrix pr_mat(nr, nc);
23 for(
int ic=0; ic<nc; ic++) {
24 for(
int ir=0; ir<nr; ir++) {
25 pr_mat(ir,ic) = m(ir,ic)-m(0,ic);
41 ex pol = collect_common_factors(xpol.expand());
44 for(
int i=0; i<pol.nops(); i++) {
45 if(is_a<numeric>(pol.op(i)))
continue;
46 if(pol.op(i).match(x(
w)))
continue;
47 if(pol.op(i).match(pow(x(
w1),
w2)))
continue;
48 if(pol.op(i).match(pow(y(
w1),
w2)))
continue;
49 if(pol.op(i).match(pow(
vs,
w)))
continue;
57 int id = delta ? nx-1 : nx;
60 for(
auto item : xs) lxs.append(item);
62 pol = pol.expand().collect(lxs,
true);
63 int np = is_a<add>(pol) ? pol.nops() : 1;
64 matrix rs_mat(np, nx+1);
66 for(
int n=0; n<np; n++) {
68 rs_mat(n,0) = tmp.degree(
vs);
69 for(
int ix=0; ix<nx; ix++) {
70 rs_mat(n, ix+1) =
collect_ex(tmp, xs[ix]).degree(xs[ix]);
74 int pr =
PRank(rs_mat);
75 if(pr-1 !=
id)
return nlst;
77 matrix rp_mat(np,
id+1);
78 for(
int n=0; n<np; n++) {
79 for(
int ix=0; ix<
id+1; ix++) {
80 rp_mat(n,ix) = rs_mat(n,ix);
83 int rp =
PRank(rp_mat);
86 cout <<
"pr=" << pr <<
", rp=" << rp << endl;
87 throw Error(
"PExpand: projection method does not work.");
92 for(
int i=0; i<
id+1; i++) {
100 ex eqn = rs_mat(pi,0);
101 for(
int i=0; i<id; i++) {
102 eqn +=
vs.op(i) * rs_mat(pi,i+1);
104 eqns.append(eqn==vv);
106 auto lss = lsolve(eqns,
vs);
110 for(
int r=0; r<np; r++) {
111 ex eqn = rs_mat(r,0);
112 for(
int i=0; i<id; i++) {
113 eqn += vs2.op(i) * rs_mat(r,i+1);
115 ex chk = eqn-vs2.op(
id);
116 if(!is_a<numeric>(chk)) {
117 cerr <<
ErrColor <<
"chk is NOT a number: " << chk <<
RESET << endl;
118 throw Error(
"PExpand: chk is NOT a number.");
128 for(
auto vsi : vs2) {
129 if(vsi<min) min = vsi;
131 for(
int i=0; i<vs2.nops(); i++) vs2.let_op(i) = vs2.op(i)-min;
138 for(
auto item : xs) lxs2.append(item);
146 void SecDec::DoAsy() {
151 funexp.push_back(fe);
157 for(
auto fe : funexp) {
159 cerr <<
ErrColor <<
"needs 3 elements: " << fe <<
RESET << endl;
160 throw Error(
"DoAsy: we needs 3 elements.");
162 ex ft = fe.op(0).op(1).subs(
vs==0);
166 for(
int i=0; i<xs.size(); i++) {
167 for(
int j=i+1; j<xs.size(); j++) {
168 bool delta_ij =
false;
169 for(
int di=0; di<fe.op(2).nops(); di++) {
170 if(fe.op(2).op(di).has(xs[i]) && fe.op(2).op(di).has(xs[j])) {
175 if(!delta_ij)
continue;
177 symbol xi(
"xi"), xj(
"xj");
178 auto ftt = ft.subs(lst{xs[i]==xi, xs[j]==xj});
182 for(
auto item : ftt) fts2.append(item);
187 for(
auto item : fts2) {
188 auto tmp =
Factor(item.subs(x(
w)==0));
190 for(
auto it : tmp) tmp_lst.append(it);
197 for(
auto item : fts2) {
199 if(item.match(pow(
w1,
w2))) tmp = item.op(0);
200 if(tmp.degree(xi)==1 && tmp.degree(xj)==1) {
201 ex ci = tmp.coeff(xi);
202 ex cj = tmp.coeff(xj);
203 if((ci*xi+cj*xj-tmp).is_zero() && is_a<numeric>(ci*cj) && (ci*cj)<0) {
204 eqn = tmp.subs(lst{xi==xs[i], xj==xs[j]});
219 ex ci = eqn.coeff(xi);
220 ex cj = eqn.coeff(xj);
228 auto f1 = ex_to<lst>(fe.op(0));
229 auto e1 = ex_to<lst>(fe.op(1));
231 for(
int i=0; i<f1.nops(); i++) {
232 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});
234 if(e1.op(0)==1) f1.let_op(0) = f1.op(0)/(1+c1);
235 else if(e1.op(1)==1) f1.let_op(1) = f1.op(1)/(1+c1);
241 FunExp.push_back(lst{f1,e1,fe.op(2)});
243 auto f2 = ex_to<lst>(fe.op(0));
244 auto e2 = ex_to<lst>(fe.op(1));
246 for(
int i=0; i<f2.nops(); i++) {
247 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});
249 if(e2.op(0)==1) f2.let_op(0) = f2.op(0)/(1+c2);
250 else if(e2.op(1)==1) f2.let_op(1) = f2.op(1)/(1+c2);
255 FunExp.push_back(lst{f2,e2,fe.op(2)});
267 for(
int i=0; i<fe.op(0).nops(); i++) {
268 auto item = fe.op(0).op(i).subs(x(
w)==s*y(
w)).
subs(y(
w)==x(
w));
269 if(!item.has(s))
continue;
271 if(item.ldegree(s)!=item.degree(s)) {
272 cerr <<
ErrColor <<
"Not Homogeneous: " << s <<
RESET << endl;
273 throw Error(
"DoAsy: Not Homogeneous");
275 expn += item.degree(s) * fe.op(1).op(i);
278 if(!normal(expn+xsize).is_zero()) {
279 cout <<
ErrColor <<
"expn=" << expn <<
", xsize=" << xsize <<
RESET << endl;
280 throw Error(
"DoAsy: expn + xsize != 0.");
292 for(
int i=0; i<fe.op(0).nops(); i++) {
293 if(fe.op(1).op(i).info(info_flags::nonnegint))
continue;
294 uf.append(fe.op(0).op(i));
299 for(
auto item : uf) xpol *= item;
305 bool has_delta =
true;
306 auto rs =
PExpand(xpol, has_delta);
308 throw Error(
"PExpand returned with nothing, even without hard region!");
311 cout <<
PRE <<
"\\--Asy Regions:" << (rs.nops()-1) << endl;
313 for(
auto ri : rs) cout <<
" " << ri << endl;
318 auto r0y =
subs(r0,x(
w)==y(
w));
319 for(
int i=1; i<rs.nops(); i++) {
323 for(
int j=0; j<r0.nops(); j++) {
324 srepl.append(r0.op(j)==r0y.op(j) * pow(
vs, ri.op(j)));
328 auto fs =
subs(fe.op(0), srepl);
329 fs =
subs(fs, y(
w)==x(
w));
332 if(!(es.op(0)-1).is_zero()) {
333 cerr <<
ErrColor <<
"op(0) is Not 1: " << es <<
RESET << endl;
334 throw Error(
"DoAsy: op(0) is Not 1");
338 for(
int j=1; j<fs.nops(); j++) {
340 auto tmp = fj.expand();
343 vsp = tmp.ldegree(
vs);
344 }
catch(exception &e) {
345 cout << e.what() << endl;
346 throw Error(
"DoAsy: non-integer exponent.");
348 vs_pow += vsp * es.op(j);
349 tmp = collect_common_factors(tmp)/pow(
vs,vsp);
351 es2.append(es.op(j));
354 for(
auto epi :
eps_lst) eps_map[epi.op(0)] = 0;
357 auto vsn = vsn0 + vs_pow.subs(eps_map);
364 for(
int ife=0; ife<fss.nops(); ife++) {
365 lst fs3 = ex_to<lst>(fss.op(ife));
366 lst es3 = ex_to<lst>(ess.op(ife));
368 for(
int ii=0; ii<fs3.nops(); ii++) {
373 if((es4.op(ii)-1).is_zero()) {
374 fs4.let_op(ii) = dit;
376 fs4.append(es4.op(ii)*dit);
377 es4.let_op(ii) = es4.op(ii)-1;
385 fs3 = ex_to<lst>(
subs(fs3,
vs==0));
386 fs3.prepend(fpre/factorial(di) * pow(
vs,di+vs_pow));
388 FunExp.push_back(lst{fs3,es3,fe.op(2)});
403 if(fe.has(
vz) || !fe.has(
vs))
continue;
407 cout <<
ErrColor <<
"MB: epz found at fe = " << fe <<
RESET << endl;
408 throw Error(
"MB: epz found at fe.");
414 eps_map[epi.op(0)] = epn;
420 for(
int i=2; i<fe.op(0).nops(); i++) {
422 if(i!=1 && fe.op(0).op(i).has(
vz)) {
423 cout <<
"vz Found @ " << i <<
" of " << fe.op(0) << endl;
424 throw Error(
"MB: vz Found.");
427 auto tmp = fe.op(0).op(i).subs(lst{WRA(
w)==0,x(
w)==1,PL(
w)==1}).
subs(eps_map);
428 if(!is_a<numeric>(
NN(tmp,20))) {
430 cout << fe.op(0) << endl;
431 throw Error(
"MB: Extra Variable(^[ep,eps,PL,x]) Found.");
435 ex ft = fe.op(0).op(1);
438 if(!ft.is_polynomial(
vs) || (ft.degree(
vs)-1)!=0) {
439 cout <<
ErrColor <<
"Not supported F-term with s: " << ft <<
RESET << endl;
440 throw Error(
"MB: Not supported F-term with s.");
442 ex expn = ex(0)-fe.op(1).op(1);
444 fe.let_op(0).let_op(0) = fe.op(0).op(0) * tgamma(expn+
vz)*tgamma(ex(0)-
vz)/tgamma(expn)*pow(
vs,
vz);
445 ex
w1 = ft.coeff(
vs);
446 ex
w2 = ft.subs(
vs==0);
451 fe.let_op(0).let_op(1) =
w2;
452 fe.let_op(1).let_op(1) = fe.op(1).op(1)-
vz-
epz;
456 fe.let_op(0).let_op(1) =
w1;
457 fe.let_op(1).let_op(1) =
vz;
463 fe.let_op(0).let_op(1) =
w2;
464 fe.let_op(1).let_op(1) = fe.op(1).op(1)-
vz-
epz;
470 fe.let_op(0).let_op(1) =
w1;
471 fe.let_op(1).let_op(1) =
vz;
473 cout <<
"w1=" <<
w1 << endl;
474 cout <<
"w2=" <<
w2 << endl;
475 throw Error(
"MB: Neither w1 nor w2 is xPositive.");
class used to wrap error message
static vector< vector< int > > RunQHull(const matrix &pts)
static ex PExpand(ex xpol, bool delta=true)
PExpand from asy2.1.1.m.
static int PRank(matrix m)
PRank from FIESTA.
namespace for Numerical integration with Sector Decomposition method
exvector get_xy_from(ex pol)
exvector get_x_from(ex pol)
ex Factor(const ex expr_in)
bool xPositive(ex const expr)
check the expr is xPositive, i.e., each x-monomial item is postive
ex NN(ex expr, int digits)
the nuerical evaluation
ex collect_ex(ex const &expr_in, std::function< bool(const ex &)> has_func, int opt)
the collect function like Mathematica
ex diff_ex(ex const expr, ex const xp, unsigned nth, bool expand)
the differential like Mathematica
void let_op_append(ex &ex_in, const ex item)
append item into expression
ex subs(const ex &e, init_list sl)