23 inline string n2s(ex fn) {
24 int n = ex_to<numeric>(fn).to_int();
25 return (n<0 ?
"m" :
"") + to_string(abs(n));
35 unsigned Field2_SERIAL::serial = GiNaC::function::register_new(function_options(
"Field",2).
do_not_evalf_params().overloaded(2));
36 unsigned Field3_SERIAL::serial = GiNaC::function::register_new(function_options(
"Field",3).
do_not_evalf_params().overloaded(2));
37 unsigned Vertex2_SERIAL::serial = GiNaC::function::register_new(function_options(
"Vertex",2).
do_not_evalf_params().overloaded(5));
38 unsigned Vertex3_SERIAL::serial = GiNaC::function::register_new(function_options(
"Vertex",3).
do_not_evalf_params().overloaded(5));
39 unsigned Vertex4_SERIAL::serial = GiNaC::function::register_new(function_options(
"Vertex",4).
do_not_evalf_params().overloaded(5));
40 unsigned Vertex5_SERIAL::serial = GiNaC::function::register_new(function_options(
"Vertex",5).
do_not_evalf_params().overloaded(5));
41 unsigned Vertex6_SERIAL::serial = GiNaC::function::register_new(function_options(
"Vertex",6).
do_not_evalf_params().overloaded(5));
64 auto rc = system(
"rm -f qgraf.dat qgraf.out qgraf.sty qgraf.mod");
66 style.open(
"qgraf.sty", ios::out);
67 style <<
Style << endl;
71 style.open(
"qgraf.mod", ios::out);
72 style <<
Model << endl;
76 ofs.open(
"qgraf.dat", ios::out);
77 ofs <<
"output='qgraf.out';" << endl;
78 ofs <<
"style='qgraf.sty';" << endl;
79 ofs <<
"model='qgraf.mod';" << endl;
80 ofs <<
"in=" <<
In <<
";" << endl;
81 ofs <<
"out=" <<
Out <<
";" << endl;
82 ofs <<
"loops=" <<
Loops <<
";" << endl;
83 ofs <<
"loop_momentum=" <<
LoopPrefix <<
";" << endl;
84 ofs <<
"options=" <<
Options <<
";" << endl;
85 for(
auto vs :
Others) ofs <<
vs <<
";" << endl;
89 else rc = system((
InstallPrefix+
"/bin/qgraf > /dev/null").c_str());
91 ifstream ifs(
"qgraf.out");
92 string ostr((istreambuf_iterator<char>(ifs)), (istreambuf_iterator<char>()));
96 if(access(
"qgraf.dat",F_OK)!=-1) remove(
"qgraf.dat");
97 if(access(
"qgraf.mod",F_OK)!=-1) remove(
"qgraf.mod");
98 if(access(
"qgraf.sty",F_OK)!=-1) remove(
"qgraf.sty");
99 if(access(
"qgraf.out",F_OK)!=-1) remove(
"qgraf.out");
102 const char* rm_chars =
" \t\v\r\n,";
104 ostr.erase(0, ostr.find_first_not_of(rm_chars));
105 ostr.erase(ostr.find_last_not_of(rm_chars)+1);
107 ostr =
"{" + ostr +
"}";
110 ex ret = amp.
Read(ostr);
112 return ex_to<lst>(ret);
121 map<ex,int,ex_is_less> v2id, fid2vid;
125 for(const_preorder_iterator i = amp.preorder_begin(); i != amp.preorder_end(); ++i) {
128 lines.append(lst{ e.op(1), iWF(e.op(1)), lst{e.op(0)}, e.op(2) });
130 lines.append(lst{ iWF(e.op(1)), e.op(1), lst{e.op(0)}, e.op(2) });
132 lines.append(lst{ iWF(e.op(0).op(1)), iWF(e.op(1).op(1)), lst{e.op(0).op(0), e.op(1).op(0)}, e.op(2) });
134 auto itr = v2id.find(e);
135 if(itr==v2id.end()) {
137 v2id.emplace(make_pair(e,cid));
149 if(!e.has(iWF(
w)))
return e;
150 else if(e.match(iWF(
w))) {
151 auto vid = fid2vid[e.op(0)];
152 return lst{vid, vid2fs[vid]};
153 }
else return e.map(
self);
168 for(
auto item : amps) amp_vec.push_back(item);
169 string tex_path = to_string(getpid()) +
"_TeX/";
170 if(!
dir_exists(tex_path)) rc = system((
"mkdir -p "+tex_path).c_str());
174 auto amp = amp_vec[idx];
175 ofstream out(tex_path+to_string(idx)+
".tex");
176 out <<
"\\documentclass[tikz]{standalone}" << endl;
177 out <<
"\\usepackage{tikz-feynman}" << endl;
178 out <<
"\\tikzfeynmanset{compat=1.1.0}" << endl;
179 out <<
"\\begin{document}" << endl;
180 out <<
"\\feynmandiagram{" << endl;
181 auto lines = TopoLines(amp);
184 std::map<ex,int,ex_is_less> vtex_map;
185 for(auto l : lines) {
186 lst ll = lst{l.op(0), l.op(1)};
187 bool isExt = (is_a<numeric>(ll.op(0)) && ll.op(0)<0) || (is_a<numeric>(ll.op(1)) && ll.op(1)<0);
189 bend_map[ll] = bend_map[ll] + 1;
191 auto fidL = (is_a<numeric>(l.op(1)) ? l.op(1) : l.op(1).op(0));
192 out <<
"\"" << fidL <<
"\"";
195 if(InOutTeX[fidL].length()>0) out << InOutTeX[fidL];
198 } else if(vtex_map[l.op(1).op(1)]==0) {
199 out << VerTeX[l.op(1).op(1)];
200 vtex_map[l.op(1).op(1)]=1;
204 auto f = l.op(2).op(0);
205 if(LineTeX[f].length()>0) {
206 if(!isExt) out << LineTeX[f];
208 auto cpos = LineTeX[f].find(
", edge");
209 if(cpos>0) out << LineTeX[f].substr(0,cpos);
210 else out << LineTeX[f];
213 if(bend_map[ll]>2) out <<
",half right";
214 else if(bend_map[ll]>1) out <<
",half left";
215 if(is_zero(l.op(0)-l.op(1))) out <<
",loop,distance=2cm";
218 auto fidR = (is_a<numeric>(l.op(0)) ? l.op(0) : l.op(0).op(0));
219 out <<
" \"" << fidR <<
"\"";
222 if(InOutTeX[fidR].length()>0) out << InOutTeX[fidR];
225 } else if(vtex_map[l.op(0).op(1)]==0) {
226 out << VerTeX[l.op(0).op(1)];
227 vtex_map[l.op(0).op(1)]=1;
232 out <<
"\\end{document}" << endl;
234 auto rc = system((
"cd "+tex_path+
" && echo X | lualatex " + to_string(idx) +
" 1>/dev/null").c_str());
238 ofstream out(tex_path+
"diagram.tex");
239 out <<
"\\let\\mypdfximage\\pdfximage" << endl;
240 out <<
"\\def\\pdfximage{\\immediate\\mypdfximage}" << endl;
241 out <<
"\\documentclass{standalone}" << endl;
242 out <<
"\\usepackage{graphicx}" << endl;
243 out <<
"\\usepackage{adjustbox}" << endl;
244 out <<
"\\begin{document}" << endl;
245 out <<
"\\begin{adjustbox}{valign=T,width=\\textwidth}" << endl;
246 out <<
"\\begin{tabular}{|cc|cc|cc|cc|}" << endl;
247 out <<
"\\hline" << endl;
248 int total = amps.nops();
250 if((total%4)!=0) total = (total/4+1)*4;
251 for(
int i=0 ; i<total; i++) {
253 if((i!=0) && (i+1!=total) && (i%limit)==0) {
254 out <<
"\\end{tabular}" << endl << endl;
255 out <<
"\\begin{tabular}{|cc|cc|cc|cc|}" << endl;
256 out <<
"\\hline" << endl;
259 out <<
"{\\tiny " << i+1 <<
"}&" << endl;
261 out <<
"\\includegraphics[keepaspectratio,";
262 out <<
"height=0.22\\textwidth,";
263 out <<
"width=0.22\\textwidth]";
264 out <<
"{"<<i<<
".pdf}" << endl;
266 if((i+1)%4==0) out <<
"\\\\ \\hline";
269 out <<
"\\end{tabular}" << endl;
270 out <<
"\\end{adjustbox}" << endl;
271 out <<
"\\end{document}" << endl;
273 if(
Debug) rc = system((
"cd "+tex_path+
" && pdflatex diagram && mv diagram.pdf ../"+fn).c_str());
274 else rc = system((
"cd "+tex_path+
" && echo X | pdflatex diagram 1>/dev/null && mv diagram.pdf ../"+fn).c_str());
275 if(!
Debug) rc = system((
"rm -r "+tex_path).c_str());
287 if(prop.nops()<1)
throw Error(
"ShrinkCut: no cut provided!");
290 for(
int i=0; i<tls.nops(); i++) {
291 auto pi = tls.op(i).op(2);
292 if(pi.nops()<2)
continue;
293 if(!is_a<lst>(prop.op(0))) {
294 if(is_zero(pi.op(0)-prop.op(0)) && is_zero(pi.op(1)-prop.op(1))) cls_vec.push_back(i);
296 for(
auto iprop : prop) {
297 if(is_zero(pi.op(0)-iprop.op(0)) && is_zero(pi.op(1)-iprop.op(1))) cls_vec.push_back(i);
301 if(cls_vec.size()<n)
return ret;
303 Combinations(cls_vec.size(), n, [n,&ret,cls_vec,tls](
const int * is)->void {
305 for(int i=0; i<n; i++) cls[i] = cls_vec[is[i]];
310 auto ol = tls2.op(ci);
311 tls2.let_op(ci) = lst{ol.op(0), 0, lst{ol.op(2).op(0)}, ol.op(3)};
312 tls2.append(lst{0, ol.op(1), lst{ol.op(2).op(1)}, ol.op(3)} );
317 int ntls2 = tls2.nops();
320 for(int i=last; i<ntls2; i++) {
321 auto li = tls2.op(i);
322 if(is_zero(li) || li.op(2).nops()<2) continue;
325 tls2.let_op(last) = 0;
328 if(is_zero(lp))
break;
330 for(
int i=0; i<ntls2; i++) {
331 if(is_zero(tls2.op(i)))
continue;
332 if(is_zero(tls2.op(i).op(0)-lp.op(0))) tls2.let_op(i).let_op(0) = lp.op(1);
333 if(is_zero(tls2.op(i).op(1)-lp.op(0))) tls2.let_op(i).let_op(1) = lp.op(1);
338 map<int, lst> con_map;
339 for(
auto li : tls2) {
340 if(is_zero(li))
continue;
343 if(is_a<lst>(fiL)) fiL = fiL.op(0);
345 if(is_a<lst>(fiR)) fiR = fiR.op(0);
347 con_map[ex_to<numeric>(fiL).to_int()].append(fiR);
348 }
else if(fiR>0 && fiL<0) {
349 con_map[ex_to<numeric>(fiR).to_int()].append(fiL);
351 if(fiL>0 && is_zero(fiR)) key = fiL;
352 else if(fiR>0 && is_zero(fiL)) key = fiR;
353 else throw Error(
"ShrinkCut: unexpcected point reached.");
354 val = li.op(2).op(0);
355 con_map[ex_to<numeric>(key).to_int()].append(val);
360 for(
auto kv : con_map) item.append(kv.second.sort());
375 int ntls = tls.nops();
380 for(
int i=last; i<ntls; i++) {
382 if(is_zero(li) || li.op(2).nops()<2)
continue;
384 bool m1 = !(is_zero(cpi.op(0)-prop.op(0)) && is_zero(cpi.op(1)-prop.op(1)));
385 bool m2 = !(is_zero(cpi.op(0)-prop.op(1)) && is_zero(cpi.op(1)-prop.op(0)));
386 if(m1 && m2)
continue;
387 if(is_zero(li.op(0)-li.op(1)))
return true;
390 tls.let_op(last) = 0;
393 if(is_zero(lp))
break;
395 for(
int i=0; i<ntls; i++) {
396 if(is_zero(tls.op(i)))
continue;
397 if(is_zero(tls.op(i).op(0)-lp.op(0))) tls.let_op(i).let_op(0) = lp.op(1);
398 if(is_zero(tls.op(i).op(1)-lp.op(0))) tls.let_op(i).let_op(1) = lp.op(1);
411 auto fi1 = e.op(0).op(1);
412 auto fi2 = e.op(1).op(1);
414 return I *
SP(
TI(fi1),
TI(fi2)) * Matrix(
GAS(mom)+
GAS(1)*m,
DI(fi1),
DI(fi2)) / (
SP(mom)-m*m);
424 auto fi1 = e.op(0).op(1);
425 auto fi2 = e.op(1).op(1);
427 return I * Matrix(
GAS(mom)+
GAS(1)*m,
DI(fi1),
DI(fi2)) / (
SP(mom)-m*m);
437 auto fi1 = e.op(0).op(1);
438 auto fi2 = e.op(1).op(1);
440 return (-I) *
SP(
CI(fi1),
CI(fi2)) * (
SP(
LI(fi1),
LI(fi2)) /
SP(mom) - (1-xi)*
SP(mom,
LI(fi1))*
SP(mom,
LI(fi2))/pow(
SP(mom),2) );
450 auto fi1 = e.op(0).op(1);
451 auto fi2 = e.op(1).op(1);
453 return I * eta_G *
SP(
CI(fi1),
CI(fi2)) /
SP(mom);
464 auto fi1 = e.op(0).op(1);
465 auto fi2 = e.op(1).op(1);
467 return -I/(
SP(mom)-m*m) * (
SP(
LI(fi1),
LI(fi2))-(1-xi)*
SP(
LI(fi1))*
SP(
LI(fi2))/(
SP(mom)-xi*m*m));
478 auto fi1 = e.op(0).op(1);
479 auto fi2 = e.op(1).op(1);
481 return eta_G * I / (
SP(mom)-xi*m*m);
492 auto fi1 = e.op(0).op(1);
493 auto fi2 = e.op(1).op(1);
495 return I / (
SP(mom)-xi*m*m);
505 auto fi1 = e.op(0).op(1);
506 auto fi2 = e.op(1).op(1);
507 auto fi3 = e.op(2).op(1);
518 auto fi1 = e.op(0).op(1);
519 auto fi2 = e.op(1).op(1);
520 auto fi3 = e.op(2).op(1);
521 auto mom1 = e.op(0).op(2);
522 auto mom2 = e.op(1).op(2);
523 auto mom3 = e.op(2).op(2);
538 auto fi1 = e.op(0).op(1);
539 auto fi2 = e.op(1).op(1);
540 auto fi3 = e.op(2).op(1);
541 auto fi4 = e.op(3).op(1);
557 auto fi1 = e.op(0).op(1);
558 auto fi2 = e.op(1).op(1);
559 auto fi3 = e.op(2).op(1);
560 auto mom1 = e.op(0).op(2);
572 auto fi1 = e.op(0).op(1);
573 auto fi2 = e.op(1).op(1);
574 auto fi3 = e.op(2).op(1);
575 return -I*eta_e*eq*Matrix(
GAS(
LI(fi3)),
DI(fi1),
DI(fi2))*
SP(
TI(fi1),
TI(fi2));
586 auto fi1 = e.op(0).op(1);
587 auto fi2 = e.op(1).op(1);
588 auto fi3 = e.op(2).op(1);
589 return -I*eta_e*eq*Matrix(
GAS(
LI(fi3)),
DI(fi1),
DI(fi2));
601 else if(is_a<Index>(e)) {
602 auto idx = ex_to<Index>(e);
603 auto nstr = idx.name.get_name();
604 if(!all && nstr.rfind(
"lim",0)==0)
return e;
605 else if(!all && nstr.rfind(
"dim",0)==0)
return e;
606 else if(!all && nstr.rfind(
"cim",0)==0)
return e;
607 else if(!all && nstr.rfind(
"tim",0)==0)
return e;
608 else if(nstr.rfind(
"li",0)==0 || nstr.rfind(
"di",0)==0 || nstr.rfind(
"ci",0)==0 || nstr.rfind(
"ti",0)==0)
return Index(
"r"+nstr, idx.type);
611 else return e.map(
self);
628 else return -
SP(
LI(qi),
RLI(qi));
639 else return -
SP(
RLI(qi),
LI(qi));
652 else return Matrix(
GAS(p)+m*
GAS(1),
RDI(qi),
DI(qi));
665 else return Matrix(
GAS(p)+m*
GAS(1),
DI(qi),
RDI(qi));
678 else return Matrix(
GAS(p)-m*
GAS(1),
DI(qi),
RDI(qi));
691 else return Matrix(
GAS(p)-m*
GAS(1),
RDI(qi),
DI(qi));
737 if(is_zero(p))
return -
SP(
LI(qi),
RLI(qi));
748 if(is_zero(p))
return -
SP(
RLI(qi),
LI(qi));
753 lst Models::FeynRulesSM(
const lst & amps,
const ex & xi) {
755 for(
auto item : amps) ret.append(FeynRulesSM(item,xi));
758 ex Models::FeynRulesSM(
const ex & amp,
const ex & xi) {
759 if(is_a<lst>(amp))
return FeynRulesSM(ex_to<lst>(amp), xi);
764 static ex CW2 = CW*CW;
765 static ex SW2 = SW*SW;
766 static ex C2W = CW2-SW2;
769 static Symbol Ubar(
"Ubar");
771 static Symbol Dbar(
"Dbar");
773 static Symbol Cbar(
"Cbar");
775 static Symbol Sbar(
"Sbar");
777 static Symbol Tbar(
"Tbar");
779 static Symbol Bbar(
"Bbar");
783 static Symbol ghbar(
"ghbar");
791 static Symbol ghAbar(
"ghAbar");
792 static Symbol ghWm(
"ghWm");
793 static Symbol ghWmbar(
"ghWmbar");
794 static Symbol ghWp(
"ghWp");
795 static Symbol ghWpbar(
"ghWpbar");
797 static Symbol ghZbar(
"ghZbar");
802 static Symbol nebar(
"nebar");
806 static Symbol nmubar(
"nmubar");
807 static Symbol taum(
"taum");
808 static Symbol taup(
"taup");
809 static Symbol ntau(
"ntau");
810 static Symbol ntaubar(
"ntaubar");
813 static Symbol phim(
"phim");
814 static Symbol phip(
"phip");
817 static auto M = [](
const string & si)->ex {
820 static ex MW = M(
"W");
821 static ex MZ = M(
"Z");
822 static ex MH = M(
"H");
826 static ex eta_s = -1;
829 static ex eta_prime = -1;
831 static ex eta_theta = 1;
833 static ex eta_e = -1;
836 static ex GEW = eta_e*eta*eta_theta * EL/SW;
837 static ex EL2 = EL*EL;
838 static ex MW2 = MW*MW;
839 static ex MZ2 = MZ*MZ;
840 static ex MH2 = MH*MH;
841 static ex GEW2 = GEW*GEW;
842 static ex sqrt2 = sqrt(ex(2));
845 T3[
"U"] = T3[
"C"] = T3[
"T"] = ex(1)/2;
846 T3[
"D"] = T3[
"S"] = T3[
"B"] = -ex(1)/2;
847 T3[
"ne"] = T3[
"nmu"] = T3[
"ntau"] = ex(1)/2;
848 T3[
"em"] = T3[
"mum"] = T3[
"taum"] = -ex(1)/2;
849 T3[
"ep"] = T3[
"mup"] = T3[
"taup"] = -ex(1)/2;
852 Q[
"U"] = Q[
"C"] = Q[
"T"] = ex(2)/3;
853 Q[
"D"] = Q[
"S"] = Q[
"B"] = -ex(1)/3;
854 Q[
"ne"] = Q[
"nmu"] = Q[
"ntau"] = 0;
855 Q[
"em"] = Q[
"mum"] = Q[
"taum"] = -1;
856 Q[
"ep"] = Q[
"mup"] = Q[
"taup"] = -1;
858 auto is_qbar_q = [&](
const ex pi1,
const ex pi2)->
bool {
859 return (pi1==Ubar && pi2==U) || (pi1==Dbar && pi2==D) || (pi1==Cbar && pi2==C) || (pi1==Sbar && pi2==S) || (pi1==Tbar && pi2==T) || (pi1==Bbar && pi2==B);
861 auto is_lbar_l = [&](
const ex pi1,
const ex pi2)->
bool {
862 return (pi1==
ep && pi2==em) || (pi1==mup && pi2==mum) || (pi1==taup && pi2==taum);
864 auto is_lbar_n = [&](
const ex pi1,
const ex pi2)->
bool {
865 return (pi1==
ep && pi2==ne) || (pi1==mup && pi2==nmu) || (pi1==taup && pi2==ntau);
867 auto is_nbar_n = [&](
const ex pi1,
const ex pi2)->
bool {
868 return (pi1==nebar && pi2==ne) || (pi1==nmubar && pi2==nmu) || (pi1==ntaubar && pi2==ntau);
870 auto is_nbar_l = [&](
const ex pi1,
const ex pi2)->
bool {
871 return (pi1==nebar && pi2==em) || (pi1==nmubar && pi2==mum) || (pi1==ntaubar && pi2==taum);
873 auto is_uqbar = [&](
const ex pi)->
bool {
874 return (pi==Ubar) || (pi==Cbar) || (pi==Tbar);
876 auto is_uq = [&](
const ex pi)->
bool {
877 return (pi==U) || (pi==C) || (pi==T);
879 auto is_dqbar = [&](
const ex pi)->
bool {
880 return (pi==Dbar) || (pi==Sbar) || (pi==Bbar);
882 auto is_dq = [&](
const ex pi)->
bool {
883 return (pi==D) || (pi==S) || (pi==B);
885 auto is_uqbar_dq = [&](
const ex pi1,
const ex pi2)->
bool {
886 return is_uqbar(pi1) && is_dq(pi2);
888 auto is_dqbar_uq = [&](
const ex pi1,
const ex pi2)->
bool {
889 return is_dqbar(pi1) && is_uq(pi2);
891 auto CKM = [&](
const string & si1,
const string & si2)->ex {
892 return Symbol(
"V"+si1+si2);
895 auto gfV = [&](
const string & si)->ex {
896 return T3[si]/2-Q[si]*SW2;
898 auto gfA = [&](
const string & si)->ex {
905 auto pi = e.op(0).op(0);
907 if(pi==U || pi==D || pi==C || pi==S || pi==T || pi==B) {
923 }
else if(pi==ghWm || pi==ghWp) {
925 }
else if(pi==em || pi==mum || pi==taum) {
927 }
else if(pi==ne || pi==nmu || pi==ntau) {
933 }
else if(pi==phim) {
936 cout << endl << e << endl;
937 throw Error(
"Propagator Not defined!");
940 auto pi1 = e.op(0).op(0);
941 auto pi2 = e.op(1).op(0);
942 auto pi3 = e.op(2).op(0);
943 auto fi1 = e.op(0).op(1);
944 auto fi2 = e.op(1).op(1);
945 auto fi3 = e.op(2).op(1);
946 auto mom1 = e.op(0).op(2);
947 auto mom2 = e.op(1).op(2);
948 auto mom3 = e.op(2).op(2);
958 if(pi1==ghbar && pi2==gh && pi3==g) {
961 }
else if(pi1==g && pi2==g && pi3==g) {
964 }
else if((pi3==g) && is_qbar_q(pi1, pi2)) {
967 }
else if((pi3==A) && is_qbar_q(pi1, pi2)) {
970 }
else if((pi3==A) && is_lbar_l(pi1, pi2)) {
973 }
else if((pi3==Z) && is_qbar_q(pi1, pi2)) {
975 return -I*eta*eta_Z*GEW/CW*(gfV(si)*Matrix(
GAS(
LI(fi3)),
DI(fi1),
DI(fi2))-gfA(si)*Matrix(
GAS(
LI(fi3))*
GAS(5),
DI(fi1),
DI(fi2)))*
SP(
TI(fi1),
TI(fi2));
976 }
else if((pi3==Z) && (is_lbar_l(pi1, pi2) || is_nbar_n(pi1, pi2))) {
978 return -I*eta*eta_Z*GEW/CW*(gfV(si)*Matrix(
GAS(
LI(fi3)),
DI(fi1),
DI(fi2))-gfA(si)*Matrix(
GAS(
LI(fi3))*
GAS(5),
DI(fi1),
DI(fi2)));
979 }
else if(pi1==Wp && pi2==Wm && pi3==A) {
981 return -I*eta_e*EL*(
SP(
LI(fi1),
LI(fi2))*
SP(mom2-mom1,
LI(fi3))+
SP(
LI(fi2),
LI(fi3))*
SP(mom3-mom2,
LI(fi1))+
SP(
LI(fi3),
LI(fi1))*
SP(mom1-mom3,
LI(fi2)));
982 }
else if(pi1==Wp && pi2==Wm && pi3==Z) {
984 return -I*eta*eta_Z*GEW*CW*(
SP(
LI(fi1),
LI(fi2))*
SP(mom2-mom1,
LI(fi3))+
SP(
LI(fi2),
LI(fi3))*
SP(mom3-mom2,
LI(fi1))+
SP(
LI(fi3),
LI(fi1))*
SP(mom1-mom3,
LI(fi2)));
985 }
else if(is_uqbar(pi1) && is_dq(pi2) && pi3==Wp) {
987 auto ckm = CKM(si1, si2);
989 }
else if(is_dqbar(pi1) && is_uq(pi2) && pi3==Wm) {
991 auto ckm = CKM(si1, si2);
993 }
else if( (is_nbar_l(pi1, pi2) && pi3==Wp) || (is_lbar_n(pi1, pi2) && pi3==Wm) ) {
995 return -I*eta*GEW/sqrt2*Matrix(
GAS(
LI(fi3))-
GAS(
LI(fi3))*
GAS(5),
DI(fi1),
DI(fi2))/2;
996 }
else if(is_qbar_q(pi1, pi2) && (pi3==H)) {
998 return -I*GEW/2*M(si)/MW*Matrix(
GAS(1),
DI(fi1),
DI(fi2))*
SP(
TI(fi1),
TI(fi2));
999 }
else if( (is_lbar_l(pi1, pi2) || is_nbar_n(pi1, pi2)) && (pi3==H)) {
1001 return -I*GEW/2*M(si)/MW*Matrix(
GAS(1),
DI(fi1),
DI(fi2));
1002 }
else if(is_qbar_q(pi1, pi2) && (pi3==chi)) {
1004 return -GEW*T3[si]*M(si)/MW*Matrix(
GAS(5),
DI(fi1),
DI(fi2))*
SP(
TI(fi1),
TI(fi2));
1005 }
else if( (is_lbar_l(pi1, pi2) || is_nbar_n(pi1, pi2)) && (pi3==chi)) {
1007 return -GEW*T3[si]*M(si)/MW*Matrix(
GAS(5),
DI(fi1),
DI(fi2));
1008 }
else if(is_uqbar_dq(pi1, pi2) && pi3==phip) {
1010 auto ckm = CKM(si1,si2);
1011 return I*GEW/sqrt2*(M(si1)/MW*Matrix(
GAS(1)-
GAS(5),
DI(fi1),
DI(fi2))/2-M(si2)/MW*Matrix(
GAS(1)+
GAS(5),
DI(fi1),
DI(fi2))/2)*ckm*
SP(
TI(fi1),
TI(fi2));
1012 }
else if(is_dqbar_uq(pi1, pi2) && pi3==phim) {
1014 auto ckm = CKM(si1,si2);
1015 return I*GEW/sqrt2*(M(si2)/MW*Matrix(
GAS(1)+
GAS(5),
DI(fi1),
DI(fi2))/2-M(si1)/MW*Matrix(
GAS(1)-
GAS(5),
DI(fi1),
DI(fi2))/2)*ckm*
SP(
TI(fi1),
TI(fi2));
1016 }
else if(is_nbar_l(pi1, pi2) && pi3==phip) {
1018 return -I*GEW/sqrt2*M(si2)/MW*Matrix(
GAS(1)+
GAS(5),
DI(fi1),
DI(fi2))/2;
1019 }
else if(is_lbar_n(pi1, pi2) && pi3==phim) {
1021 return -I*GEW/sqrt2*M(si1)/MW*Matrix(
GAS(1)-
GAS(5),
DI(fi1),
DI(fi2))/2;
1022 }
else if(pi1==A && pi2==phip && pi3==phim) {
1024 return -I*eta_e*EL*
SP(mom2-mom3,
LI(fi1));
1025 }
else if(pi1==Z && pi2==phip && pi3==phim) {
1027 return -I*eta*eta_Z*GEW*C2W/(2*CW)*
SP(mom2-mom3,
LI(fi1));
1028 }
else if(pi1==Wp && pi2==phim && pi3==H) {
1030 return I/2*eta*GEW*
SP(mom2-mom3,
LI(fi1));
1031 }
else if(pi1==Wm && pi2==phip && pi3==H) {
1033 return -I/2*eta*GEW*
SP(mom2-mom3,
LI(fi1));
1034 }
else if( ((pi1==Wp && pi2==phim) || (pi1==Wm && pi2==phip)) && pi3==chi) {
1036 return -eta*GEW/2*
SP(mom2-mom3,
LI(fi1));
1037 }
else if(pi1==Z && pi2==chi && pi3==H) {
1039 return -eta*eta_Z*GEW/(2*CW)*
SP(mom2-mom3,
LI(fi1));
1040 }
else if( ((pi1==phim && pi2==Wp) || (pi1==phip && pi2==Wm)) && pi3==A) {
1042 return I*eta_e*eta*EL*MW*
SP(
LI(fi2),
LI(fi3));
1043 }
else if( ((pi1==phim && pi2==Wp) || (pi1==phip && pi2==Wm)) && pi3==Z) {
1045 return -I*eta_Z*GEW*MZ*SW2*
SP(
LI(fi2),
LI(fi3));
1046 }
else if(pi1==H && pi2==Wp && pi3==Wm) {
1048 return I*GEW*MW*
SP(
LI(fi2),
LI(fi3));
1049 }
else if(pi1==H && pi2==Z && pi3==Z) {
1051 return I*GEW/CW*MZ*
SP(
LI(fi2),
LI(fi3));
1052 }
else if(pi1==H && pi2==phim && pi3==phip) {
1054 return -I/2*GEW*MH2/MW;
1055 }
else if(pi1==H && pi2==H && pi3==H) {
1057 return -3/ex(2)*I*GEW*MH2/MW;
1058 }
else if(pi1==H && pi2==chi && pi3==chi) {
1060 return -I/2*GEW*MH2/MW;
1061 }
else if(pi1==ghWpbar && pi2==ghWp && pi3==A) {
1063 return I*eta_G*eta_e*EL*
SP(mom1,
LI(fi3));
1064 }
else if(pi1==ghWmbar && pi2==ghWm && pi3==A) {
1066 return -I*eta_G*eta_e*EL*
SP(mom1,
LI(fi3));
1067 }
else if(pi1==ghWpbar && pi2==ghWp && pi3==Z) {
1069 return I*eta_G*eta*eta_Z*GEW*CW*
SP(mom1,
LI(fi3));
1070 }
else if(pi1==ghWmbar && pi2==ghWm && pi3==Z) {
1072 return -I*eta_G*eta*eta_Z*GEW*CW*
SP(mom1,
LI(fi3));
1073 }
else if(pi1==ghWpbar && pi2==ghZ && pi3==Wp) {
1075 return -I*eta_G*eta*eta_Z*GEW*CW*
SP(mom1,
LI(fi3));
1076 }
else if(pi1==ghWmbar && pi2==ghZ && pi3==Wm) {
1078 return I*eta_G*eta*eta_Z*GEW*CW*
SP(mom1,
LI(fi3));
1079 }
else if(pi1==ghWpbar && pi2==ghA && pi3==Wp) {
1081 return -I*eta_G*eta_e*EL*
SP(mom1,
LI(fi3));
1082 }
else if(pi1==ghWmbar && pi2==ghA && pi3==Wm) {
1084 return I*eta_G*eta_e*EL*
SP(mom1,
LI(fi3));
1085 }
else if(pi1==ghZbar && pi2==ghWp && pi3==Wm) {
1087 return -I*eta_G*eta*GEW*CW*
SP(mom1,
LI(fi3));
1088 }
else if(pi1==ghZbar && pi2==ghWm && pi3==Wp) {
1090 return I*eta_G*eta*GEW*CW*
SP(mom1,
LI(fi3));
1091 }
else if(pi1==ghAbar && pi2==ghWp && pi3==Wm) {
1093 return -I*eta_G*eta_e*EL*
SP(mom1,
LI(fi3));
1094 }
else if(pi1==ghAbar && pi2==ghWm && pi3==Wp) {
1096 return I*eta_G*eta_e*EL*
SP(mom1,
LI(fi3));
1097 }
else if(pi1==ghWpbar && pi2==ghWp && pi3==chi) {
1099 return eta_G*GEW/2*xi*MW;
1100 }
else if(pi1==ghWmbar && pi2==ghWm && pi3==chi) {
1102 return -eta_G*GEW/2*xi*MW;
1103 }
else if( ((pi1==ghWpbar && pi2==ghWp) ||(pi1==ghWmbar && pi2==ghWm)) && pi3==H) {
1105 return -I/2*eta_G*GEW*xi*MW;
1106 }
else if(pi1==ghZbar && pi2==ghZ && pi3==H) {
1108 return -eta_G*I*GEW/(2*CW)*xi*MZ;
1109 }
else if( pi1==ghZbar && ((pi2==ghWp && pi3==phim) || (pi2==ghWm && pi3==phip)) ) {
1111 return I/2*eta_G*eta_Z*GEW*xi*MZ;
1112 }
else if( ((pi1==ghWpbar && pi3==phip) || (pi1==ghWmbar && pi3==phim)) && pi2==ghZ) {
1114 return -I*eta_G*eta_Z*GEW*C2W/(2*CW)*xi*MW;
1115 }
else if( ((pi1==ghWpbar && pi3==phip) || (pi1==ghWmbar && pi3==phim)) && pi2==ghA) {
1117 return -I*eta_G*eta_e*eta*EL*xi*MW;
1119 cout << endl << e << endl;
1120 throw Error(
"Vertex Not defined!");
1123 auto pi4 = e.op(3).op(0);
1124 auto fi4 = e.op(3).op(1);
1125 auto mom4 = e.op(3).op(2);
1127 if(pi1==g && pi2==g && pi3==g && pi4==g) {
1130 }
else if(pi1==Wp && pi2==Wm && pi3==A && pi4==A) {
1133 }
else if(pi1==Wp && pi2==Wm && pi3==Z && pi4==Z) {
1136 }
else if(pi1==Wp && pi2==Wm && pi3==A && pi4==Z) {
1139 }
else if(pi1==Wp && pi2==Wp && pi3==Wm && pi4==Wm) {
1142 }
else if(pi1==Wp && pi2==Wm && pi3==H && pi4==H) {
1144 return I/2*GEW2*
SP(
LI(fi1),
LI(fi2));
1145 }
else if(pi1==Wp && pi2==Wm && pi3==chi && pi4==chi) {
1147 return I/2*GEW2*
SP(
LI(fi1),
LI(fi2));
1148 }
else if(pi1==Z && pi2==Z && pi3==H && pi4==H) {
1150 return I/2*GEW2/CW2*
SP(
LI(fi1),
LI(fi2));
1151 }
else if(pi1==Z && pi2==Z && pi3==chi && pi4==chi) {
1153 return I/2*GEW2/CW2*
SP(
LI(fi1),
LI(fi2));
1154 }
else if(pi1==A && pi2==A && pi3==phip && pi4==phim) {
1156 return 2*I*EL2*
SP(
LI(fi1),
LI(fi2));
1157 }
else if(pi1==Z && pi2==Z && pi3==phip && pi4==phim) {
1159 return I/2*pow(GEW*C2W/CW,2)*
SP(
LI(fi1),
LI(fi2));
1160 }
else if(pi1==Wp && pi2==Wm && pi3==phip && pi4==phim) {
1162 return I/2*GEW2*
SP(
LI(fi1),
LI(fi2));
1163 }
else if( ((pi1==Wp && pi3==phim) || (pi1==Wm && pi3==phip)) && pi2==Z && pi4==H) {
1165 return -I*eta_Z*GEW2*SW2/(2*CW)*
SP(
LI(fi1),
LI(fi2));
1166 }
else if(pi1==Wm && pi2==Z && pi3==phip && pi4==chi) {
1168 return -eta_Z*GEW2*SW2/(2*CW)*
SP(
LI(fi1),
LI(fi2));
1169 }
else if(pi1==Wp && pi2==Z && pi3==phim && pi4==chi) {
1171 return eta_Z*GEW2*SW2/(2*CW)*
SP(
LI(fi1),
LI(fi2));
1172 }
else if( ((pi1==Wm && pi3==phip) || (pi1==Wp && pi3==phim)) && pi2==A && pi4==H) {
1174 return I/2*eta_e*eta*EL*GEW*
SP(
LI(fi1),
LI(fi2));
1175 }
else if(pi1==Wp && pi2==A && pi3==phim && pi4==chi) {
1177 return -1/ex(2)*eta_e*eta*EL*GEW*
SP(
LI(fi1),
LI(fi2));
1178 }
else if(pi1==Wm && pi2==A && pi3==phip && pi4==chi) {
1180 return 1/ex(2)*eta_e*eta*EL*GEW*
SP(
LI(fi1),
LI(fi2));
1181 }
else if(pi1==Z && pi2==A && pi3==phip && pi4==phim) {
1183 return I*eta_e*eta*eta_Z*EL*GEW*C2W/CW*
SP(
LI(fi1),
LI(fi2));
1184 }
else if(pi1==phim && pi2==phip && pi3==phim && pi4==phip) {
1186 return -I/2*GEW2*MH2/MW2;
1187 }
else if(pi1==H && pi2==H && pi3==phim && pi4==phip) {
1189 return -I/4*GEW2*MH2/MW2;
1190 }
else if(pi1==chi && pi2==chi && pi3==phim && pi4==phip) {
1192 return -I/4*GEW2*MH2/MW2;
1193 }
else if(pi1==H && pi2==H && pi3==H && pi4==H) {
1195 return -3/ex(4)*I*GEW2*MH2/MW2;
1196 }
else if(pi1==H && pi2==H && pi3==chi && pi4==chi) {
1198 return -I/4*GEW2*MH2/MW2;
1199 }
else if(pi1==chi && pi2==chi && pi3==chi && pi4==chi) {
1201 return -3/ex(4)*I*GEW2*MH2/MW2;
1203 cout << endl << e << endl;
1204 throw Error(
"Vertex Not defined!");
1207 cout << endl << e << endl;
1208 throw Error(
"Vertex Not defined!");
1210 }
else return e.map(
self);
1217 lst Models::FeynRulesQCD(
const lst & amps,
const ex & xi) {
1219 for(
auto item : amps) ret.append(FeynRulesQCD(item,xi));
1222 ex Models::FeynRulesQCD(
const ex & amp,
const ex & xi) {
1223 if(is_a<lst>(amp))
return FeynRulesQCD(ex_to<lst>(amp), xi);
1225 static Symbol A(
"A"), Q(
"Q"), Qbar(
"Qbar"), q(
"q"), qbar(
"qbar"), g(
"g"), gh(
"gh"), ghbar(
"ghbar");
1226 static Symbol m(
"m"), eq(
"eq"), eQ(
"eQ");
1231 if(e.op(0).op(0)==q) {
1232 return QuarkPropagator(e, 0);
1233 }
else if(e.op(0).op(0)==Q) {
1234 return QuarkPropagator(e, m);
1235 }
else if(e.op(0).op(0)==g) {
1236 return GluonPropagator(e, xi);
1237 }
else if(e.op(0).op(0)==gh) {
1238 return GluonGhostPropagator(e, xi);
1240 cout <<
"expr: " << e << endl;
1241 throw Error(
"Propagator Not Found!");
1244 if(e.nops()==3 && ((e.op(0).op(0)==qbar && e.op(1).op(0)==q) || (e.op(0).op(0)==Qbar && e.op(1).op(0)==Q)) && (e.op(2).op(0)==g || e.op(2).op(0)==A) ) {
1246 if(e.op(2).op(0)==g) return QuarkGluonVertex(e);
1248 auto fi1 = e.op(0).op(1);
1249 auto fi2 = e.op(1).op(1);
1250 auto fi3 = e.op(2).op(1);
1251 if(e.op(1).op(0)==q) QuarkAVertex(e, eq);
1252 else if(e.op(1).op(0)==Q) QuarkAVertex(e, eQ);
1253 else throw Error(
"Vertex Error.");
1255 }
else if(e.nops()==3 && e.op(0).op(0)==ghbar && e.op(1).op(0)==gh) {
1257 return GhostGluonVertex(e);
1258 }
else if(e.nops()==3 && e.op(0).op(0)==g && e.op(1).op(0)==g && e.op(2).op(0)==g) {
1260 return Gluon3Vertex(e);
1261 }
else if(e.nops()==4 && e.op(0).op(0)==g && e.op(1).op(0)==g && e.op(2).op(0)==g && e.op(3).op(0)==g) {
1263 return Gluon4Vertex(e);
1265 cout <<
"expr: " << e << endl;
1266 throw Error(
"Vertex Not Found!");
1268 }
else return e.map(
self);
class used to wrap error message
static bool has(const ex &e)
class to wrap map_function of GiNaC
class to parse for string or file, helpful with Symbol class
ex Read(const string &instr, bool s2S=true)
lst Amplitudes(symtab st)
generte the Amplitudes
class extended to GiNaC symbol class, represent a positive symbol
namespace for generating Feynman diagrams or amplitudes.
ex AntiQuarkSumL(int qi, ex p, ex m, bool color)
polarization sum for anti-quark
bool HasLoop(ex amp, lst prop)
check a amplitude has a loop w.r.t. propapagtor
ex AntiGhostSumL(int qi)
polarization sum for anti-ghost, note that we will add extra - here
ex IndexL2R(ex e, bool all)
Change Index from left to right, only affect li/di/ci/ti, external index start with dim/lim/cim/tim w...
ex GluonPropagator(const ex &e, const ex &xi)
Propagator for gluon.
ex LeptonAVertex(const ex &e, const ex &eq, const ex &eta_e)
l-lbar-A vertex
ex Gluon3Vertex(const ex &e, const ex &eta_s)
g-g-g vertex
ex GhostSumL(int qi)
polarization sum for ghost
ex AntiGhostSumR(int qi)
polarization sum for anti-ghost, note that we will add extra - here
void DrawPDF(const lst &s, string fn)
generate Feynman diagrams for the amplitudes, in PDF format
ex QuarkGluonVertex(const ex &e, const ex &eta_s)
q-qbar-g vertex
ex ScalarPropagator(const ex &e, const ex &m, const ex &xi)
Propagator for scalar.
ex J1SumL(int qi, ex p)
polarization sum for total angular momentum
ex LeptonPropagator(const ex &e, const ex &m)
Propagator for lepton.
vector< lst > ShrinkCut(ex amp, lst prop, int n)
cut the amplitude, and return the connected parts, may have many different cuts
ex AntiQuarkSumR(int qi, ex p, ex m, bool color)
polarization sum for anti-quark
ex J1SumR(int qi, ex p)
polarization sum for total angular momentum
ex AZWGhostPropagator(const ex &e, const ex &m, const ex &xi, const ex &eta_G)
Propagator for A/Z/W ghost.
ex Gluon4Vertex(const ex &e, const ex &eta_s)
g-g-g-g vertex
ex IndexCC(ex e, bool all)
ex GhostGluonVertex(const ex &e, const ex &eta_s, const ex &eta_G)
ghbar-gh-g vertex
ex QuarkPropagator(const ex &e, const ex &m)
Propagator for quark.
ex QuarkSumR(int qi, ex p, ex m, bool color)
polarization sum for quark
ex QuarkSumL(int qi, ex p, ex m, bool color)
polarization sum for quark
ex GhostSumR(int qi)
polarization sum for ghost
ex AZWPropagator(const ex &e, const ex &m, const ex &xi)
Propagator for A/Z/W boson.
ex QuarkAVertex(const ex &e, const ex &eq, const ex &eta_e)
qbar-q-A vertex
ex GluonGhostPropagator(const ex &e, const ex &xi, const ex &eta_G)
Propagator for gluon ghost.
lst TopoLines(const ex &)
generate the topological lines for the amplitude
ex GluonSumR(int qi, bool color)
polarization sum for gluon
ex GluonSumL(int qi, bool color)
polarization sum for gluon
do_not_evalf_params().expl_derivative_func(zd1D).derivative_func(zp1D)) REGISTER_FUNCTION(FTX
void Combinations(int n, int m, std::function< void(const int *)> f)
ex GAS(const ex &expr, unsigned rl)
function similar to GAD/GSD in FeynClac
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)
bool isFunction(const ex &e, string func_name)
void string_replace_all(string &str, const string &from, const string &to)
string ex2str(const ex &expr)
convert ex to output string, the defalut printer format will be used
bool dir_exists(string dir)
exvector GiNaC_Parallel(int ntotal, std::function< ex(int)> f, const string &key)
GiNaC Parallel Evaluation using fork.
ex SP(const ex &a, bool use_map=false)