23 for(
auto &kv : repl) {
42 throw Error(
"Initialize: the length of Propagator and Exponent are NOT equal.");
88 if((lst{kv.first, kv.second}).has(
iEpsilon)) {
89 throw Error(
"Initialize: (lst{kv.first, kv.second}).has(iEpsilon) @1");
93 if((lst{kv.first, kv.second}).has(
iEpsilon)) {
94 throw Error(
"Initialize: (lst{kv.first, kv.second}).has(iEpsilon) @2");
98 if((lst{kv.first, kv.second}).has(
iEpsilon)) {
99 throw Error(
"Initialize: (lst{kv.first, kv.second}).has(iEpsilon) @3");
109 for(
auto item : ls) {
110 if(!is_a<symbol>(item))
throw Error(
"SecDec::Initialize failed, NOT a symbol: "+
ex2str(item));
112 for(
auto item : tls) {
113 if(!is_a<symbol>(item))
throw Error(
"SecDec::Initialize failed, NOT a symbol: "+
ex2str(item));
129 ex ad = (4-2*
ep)*ls.nops();
130 if(fp.
isQuasi) ad += (3-2*
ep)*tls.nops();
131 else ad += (2-2*
ep)*tls.nops();
137 for(
int i=0; i<ps.nops(); i++) {
148 for(
auto lsi : tls) {
157 if(ltQ)
a += ns.op(i);
161 pre = pre * pow(
Symbol::set_all(ps.op(i).expand().subs(lsubs).subs(tsubs)), ex(0)-ns.op(i));
165 }
else if(ns.op(i).info(info_flags::negint) || is_zero(ns.op(i))) {
167 if(is_zero(ns.op(i)))
continue;
170 auto p = ps.op(i).expand().subs(lsubs).subs(tsubs).subs(nsubs);
172 p = p.subs(lsubs).subs(tsubs).subs(nsubs);
177 if(!is_a<numeric>(p.coeff(m,2))) {
178 cout <<
ErrColor <<
"not numeric: " << p.coeff(m,2) << endl;
179 cout <<
"nsubs = " << nsubs <<
RESET << endl;
182 numeric nm = ex_to<numeric>(p.coeff(m,2));
183 if(nm.is_zero())
continue;
189 if(!is_a<numeric>(p.coeff(
iEpsilon))) {
190 throw Error(
"Initialize: (!is_a<numeric>(p.coeff(iEpsilon)))");
192 numeric nm = ex_to<numeric>(p.coeff(
iEpsilon));
193 if(!nm.is_zero()) sgn = nm>0 ? -1 : 1;
198 if(!is_a<numeric>(p.coeff(m,2))) {
199 throw Error(
"Initialize: NOT numeric: " +
ex2str(p.coeff(m,2)));
201 numeric nm = ex_to<numeric>(p.coeff(m,2));
202 if(nm.is_zero())
continue;
210 if(is_a<numeric>(p) && ex_to<numeric>(p)>0) sgn = -1;
211 if(
Verbose>0 && (!is_a<numeric>(ns.op(i)) || ns.op(i)>0)) {
212 cout <<
WarnColor <<
" - Warning: Can NOT determine the iEpsilon sign." <<
RESET << endl;
213 cout <<
WarnColor <<
" - " << p <<
" from " << ps.op(i) <<
RESET << endl;
218 if(sgn==-1) asgn *= exp(I * Pi * ns.op(i));
229 for(
int i=0; i<ls.nops(); i++) {
230 auto t2 = rem.coeff(ls.op(i),2);
231 auto t1 = rem.coeff(ls.op(i),1);
232 auto t0 = rem.coeff(ls.op(i),0);
238 rem = expand(t0 - pow(t1,2)/(4*t2));
244 cerr <<
ErrColor <<
"Initialize: u.has(m), " << u <<
", " << m <<
RESET << endl;
250 auto u_nd = numer_denom(u);
251 ex usgn =
FactorOutX(u_nd.op(1)).subs(xtNeg).subs(x(
w)==ex(1)/2).subs(nsubs);
252 if(is_zero(usgn)) usgn =
FactorOutX(u_nd.op(1)).subs(xtNeg).subs(x(
w)==ex(1)/3).subs(nsubs);
253 if(!is_a<numeric>(usgn) || is_zero(usgn))
throw Error(
"Initialize: usgn is zero or non-numeric.");
254 usgn = normal(usgn)>0 ? 1 : -1;
256 uList1.append(usgn*u_nd.op(0));
257 uList2.append(-(4-2*
ep)/2);
258 if((usgn*u_nd.op(0)) != 1) {
259 uList1.append(usgn*u_nd.op(1));
260 uList2.append((4-2*
ep)/2);
269 for(
int i=0; i<tls.nops(); i++) {
270 auto t2 = rem.coeff(tls.op(i),2);
271 auto t1 = rem.coeff(tls.op(i),1);
272 auto t0 = rem.coeff(tls.op(i),0);
278 rem = expand(t0 - pow(t1,2)/(4*t2));
284 cerr <<
ErrColor <<
"Initialize: u.has(m), " << u <<
", " << m <<
RESET << endl;
290 auto u_nd = numer_denom(u);
291 ex usgn =
FactorOutX(u_nd.op(1)).subs(xtNeg).subs(x(
w)==ex(1)/2).subs(nsubs);
292 if(is_zero(usgn)) usgn =
FactorOutX(u_nd.op(1)).subs(xtNeg).subs(x(
w)==ex(1)/3).subs(nsubs);
293 if(!is_a<numeric>(usgn) || is_zero(usgn))
throw Error(
"Initialize: usgn is zero or non-numeric.");
294 usgn = normal(usgn)>0 ? 1 : -1;
296 uList1.append(usgn*u_nd.op(0));
297 if(fp.
isQuasi) uList2.append(-(3-2*
ep)/2);
298 else uList2.append(-(2-2*
ep)/2);
299 if(usgn*u_nd.op(1) != 1) {
300 uList1.append(usgn*u_nd.op(1));
301 if(fp.
isQuasi) uList2.append((3-2*
ep)/2);
302 else uList2.append((2-2*
ep)/2);
307 auto u_nd = numer_denom(u);
308 rem = normal(rem * u);
309 auto rem_nd = numer_denom(rem);
311 ex usgn =
FactorOutX(u_nd.op(1)).subs(xtNeg).subs(x(
w)==ex(1)/2).subs(nsubs);
312 if(!is_a<numeric>(usgn) || is_zero(usgn))
throw Error(
"Initialize: usgn is zero or non-numeric.");
313 usgn = normal(usgn)>0 ? 1 : -1;
314 ex fsgn =
FactorOutX(rem_nd.op(1)).subs(xtNeg).subs(x(
w)==ex(1)/2).subs(nsubs);
315 if(!is_a<numeric>(fsgn) || is_zero(fsgn))
throw Error(
"Initialize: fsgn is zero or non-numeric.");
316 fsgn = normal(fsgn)>0 ? 1 : -1;
319 fList1.append(usgn*u_nd.op(0));
320 fList2.append(
a-ad/2);
321 fList1.append(fsgn*rem_nd.op(0));
322 fList2.append(-
a+ad/2);
323 if(usgn*u_nd.op(1) != 1) {
324 fList1.append(usgn*u_nd.op(1));
325 fList2.append(-
a+ad/2);
327 if(fsgn*rem_nd.op(1) != 1) {
328 fList1.append(fsgn*rem_nd.op(1));
329 fList2.append(
a-ad/2);
332 for(
int i=0; i<uList1.nops(); i++) {
333 fList1.append(uList1[i]);
334 fList2.append(uList2[i]);
338 ret.push_back(lst{fList1, fList2});
341 for(
int i=0; i<xn; i++) {
342 if(ns.op(i).info(info_flags::negint)) {
343 for(
int j=0; j<ex(0)-ns.op(i); j++) {
346 auto plst = ex_to<lst>(fe.op(0));
347 auto nlst = ex_to<lst>(fe.op(1));
350 for(
int ij=0; ij<plst.nops(); ij++) {
351 auto ldeg =
expand_ex(plst.op(ij),x(
w)).ldegree(x(i));
353 plst.let_op(ij) = collect_common_factors(plst.op(ij) / pow(x(i),ldeg));
354 nxi += ldeg * nlst.op(ij);
363 for(
int ij=0; ij<nlst.nops(); ij++) {
364 auto dtmp = ex(0)-nlst.op(ij) *
diff_ex(plst.op(ij),x(i));
365 if(is_zero(dtmp))
continue;
368 if(is_zero(nlst.op(ij)-1)) {
369 plst2.let_op(ij) = dtmp;
371 nlst2.let_op(ij) = nlst.op(ij)-1;
372 int nn = plst.nops();
373 if(!is_zero(nlst.op(nn-1)-1)) {
376 }
else plst2.let_op(nn-1) = plst.op(nn-1) * dtmp;
378 nret.push_back(lst{plst2, nlst2});
381 ret = exvector(std::move(nret));
384 for(
auto &fe : ret) {
386 int nps = fe.op(0).nops();
387 for(
int k=0; k<nps; k++) {
388 auto tmp = fe.op(0).op(k);
389 auto ldeg =
expand_ex(tmp,x(
w)).ldegree(x(i));
391 xpn += ldeg * fe.op(1).op(k);
392 tmp = collect_common_factors(tmp / pow(x(i),ldeg));
394 tmp = tmp.subs(x(i)==0);
400 if(is_a<numeric>(xpn) && xpn<0) {
401 cout <<
"xpn=" << xpn <<
" :> " << i << endl;
403 throw Error(
"Initialize: xpn < 0 found.");
412 pre *= asgn * pow(I,ls.nops()+(fp.
isQuasi ? tls.nops() : 0)) * pow(Pi, ad/2) * tgamma(
a-ad/2);
413 for(
int i=0; i<ns.nops(); i++) {
414 if(is_a<numeric>(ns.op(i)) && ns.op(i)<=0)
continue;
415 pre /= tgamma(ns.op(i));
417 if(tls.nops()>0 && (!fp.
isQuasi)) pre *= exp(I * Pi * tls.nops()*(2-2*
ep)/2);
420 for(
int i=0; i<ns.nops(); i++) {
421 if(is_a<numeric>(ns.op(i)) && ns.op(i)<=1)
continue;
423 for(
auto &fe : ret) {
424 if(is_zero(fe))
continue;
431 for(
auto &fe : ret) {
432 if(is_zero(fe))
continue;
439 auto nnn = fe.op(0).nops();
440 for(
int j=0; j<nnn; j++) {
441 fe.let_op(0).let_op(j) = collect_common_factors(fe.op(0).op(j));
442 fe.let_op(1).let_op(j) = collect_common_factors(fe.op(1).op(j));
447 for(
int i=0; i<ns.nops(); i++) {
448 if(is_a<numeric>(ns.op(i)) && ns.op(i)<=0)
continue;
452 for(
auto &fe : ret) {
453 if(is_zero(fe))
continue;
461 eps_map[epi.op(0)] = epn;
468 for(
int i=0; i<fs.nops(); i++) {
469 if(i==1 || ns.op(i).info(info_flags::integer))
continue;
472 cout <<
"fs = " << fs << endl <<
"ns = " << ns << endl;
473 throw Error(
"Initialize: non-positive u-term found.");
478 if(fp.
isAsy) DoAsy();
488 for(
int di=0; di<xint.
Deltas.nops(); di++) {
489 auto delta = xint.
Deltas.op(di);
490 if(!is_a<lst>(delta) || delta.nops()<1) {
502 if(xint.
isAsy) DoAsy();
509 if(
Verbose>1) cout << endl <<
" Starting @ " <<
now() << endl;
513 if(
FunExp.size()<1)
return;
526 if(
Verbose>1) cout <<
" Finished @ " <<
now() << endl << endl;
531 if(
Verbose>1) cout << endl <<
" Starting @ " <<
now() << endl;
535 if(
FunExp.size()<1)
return;
548 if(
Verbose>1) cout <<
" Finished @ " <<
now() << endl << endl;
553 if(
Verbose>1) cout << endl <<
" Starting @ " <<
now() << endl;
557 if(
FunExp.size()<1)
return;
570 if(
Verbose>1) cout <<
" Finished @ " <<
now() << endl << endl;
class used to wrap error message
SecDec the main class to use Sector Decompostion method.
void KillPowers(int bits=1+2)
Kill Powers will call KillPowerD or KillPower.
void Contours(const string &key="", const string &pkey="")
Contours, note that here we need to provide the specific Parameter.
IntegratorBase * Integrator
void Initialize(FeynmanParameter fpi)
void ChengWu(const ex &ft=0)
ChengWu for SecDec class.
void Integrates(const string &key="", const string &pkey="", int kid=0)
Contours, note that here we need to provide the specific Parameter.
void Evaluate(FeynmanParameter fpi, const string &key="")
void CIPrepares(const string &key="")
Prepare for the Contours and Integrates calls .so will be generated, for more detailed exported funct...
static ex set_all(const ex &expr)
namespace for Numerical integration with Sector Decomposition method
ex FactorOutX(const ex expr)
void Replacement2(exmap &repl)
ex expand_ex(ex const &expr_in, std::function< bool(const ex &)> has_func)
the expand like Mathematica
const char * Color_HighLight
int GiNaC_Parallel_Process
void let_op(ex &ex_in, int index1, int index2, const ex item)
update index1-th.index2-th of expression with item
bool xPositive(ex const expr)
check the expr is xPositive, i.e., each x-monomial item is postive
string now(bool use_date)
date/time string
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
string ex2str(const ex &expr)
convert ex to output string, the defalut printer format will be used
ex subs(const ex &e, init_list sl)
wrap parameters for loop integrals
wrap parameters for generic parameter integrals