7#include "flint/ulong_extras.h"
36 GINAC_IMPLEMENT_PRINT_CONTEXT(FormFormat, print_dflt)
57 c <<
"((" << p.op(0) <<
")*(" << p.op(0) <<
"))";
59 c <<
"((" << p.op(0) <<
")^(" << p.op(1) <<
"))";
68 GINAC_IMPLEMENT_PRINT_CONTEXT(FCFormat, print_dflt)
91 for(
int r=0; r<nr; r++) {
93 for(
int c=0; c<nc; c++) {
94 mat(r,c).print(*
this);
107 if (i==vend) { s <<
"{}";
return *
this; }
122 if (i==send) { s <<
"{}";
return *
this; }
137 if (i==mend) { s <<
"{}";
return *
this; }
140 i->first.print(*
this);
142 i->second.print(*
this);
152 class ncmul_hack :
public ncmul {
154 ncmul_hack(ncmul _nm) : ncmul(_nm){ }
155 void print(
const FCFormat & c,
unsigned level) {
156 printseq(c,
'(',
'.',
')', precedence(), level);
159 ex mat_conj(
const ex & e1,
const ex & e2,
const ex & e3) {
160 return GMat(e1.conjugate(), e3, e2);
164 ncmul_hack(nm).print(c, level);
182 if(!is_a<Index>(other))
throw Error(
"Index::compare_same_type");
183 const Index &o =
static_cast<const Index &
>(other);
184 auto ret =
name.get_name().compare(o.
name.get_name());
186 else if(ret<0)
return -1;
191 if(!is_a<Index>(other))
throw Error(
"Index::is_equal_same_type");
192 const Index &o =
static_cast<const Index &
>(other);
193 return (
name.get_name() == o.
name.get_name());
201 return Pair(*
this, i);
205 return Pair(p, *
this);
209 inherited::archive(n);
210 n.add_string(
"name",
name.get_name());
211 n.add_unsigned(
"type",
type);
215 inherited::read_archive(n);
218 n.find_string(
"name", nstr);
220 n.find_unsigned(
"type", t);
229 for(const_preorder_iterator i = e.preorder_begin(); i != e.preorder_end(); ++i)
230 if(is_a<Index>(*i) && ex_to<Index>(*i).type!=
Index::Type::VD)
return true;
235 for(const_preorder_iterator i = e.preorder_begin(); i != e.preorder_end(); ++i)
236 if(is_a<Index>(*i) && ex_to<Index>(*i).type==
Index::Type::VD)
return true;
255 if(!is_a<Vector>(other))
throw Error(
"Vector::compare_same_type");
257 auto ret =
name.get_name().compare(o.
name.get_name());
259 else if(ret<0)
return -1;
264 if(!is_a<Vector>(other))
throw Error(
"Vector::is_equal_same_type");
266 return (
name.get_name() == o.
name.get_name());
274 return Pair(*
this, p);
278 return Pair(*
this, i);
282 inherited::archive(n);
283 n.add_string(
"name",
name.get_name());
287 inherited::read_archive(n);
290 n.find_string(
"name", nstr);
310 if(!is_a<SUNT>(other))
throw Error(
"SUNT::compare_same_type");
311 const SUNT &o =
static_cast<const SUNT &
>(other);
312 for(
int i=0; i<3; i++) {
313 auto c =
aij[i].compare(o.
aij[i]);
320 if(!is_a<SUNT>(other))
throw Error(
"SUNT::is_equal_same_type");
321 const SUNT &o =
static_cast<const SUNT &
>(other);
322 for(
int i=0; i<3; i++) {
323 if(!
aij[i].is_equal(o.
aij[i]))
return false;
329 if(is_a<lst>(
aij[0])) {
331 for(
auto item :
aij[0]) {
332 if(first) { first=
false; c <<
"T(" << item; }
333 else c <<
"," << item;
335 }
else c <<
"T(" <<
aij[0];
336 c <<
"," <<
aij[1] <<
"," <<
aij[2] <<
")";
340 c <<
"SUNTF[" <<
aij[0] <<
"," <<
aij[1] <<
"," <<
aij[2] <<
"]";
344 c.s <<
"T(" <<
aij[0] <<
"," <<
aij[1] <<
"," <<
aij[2] <<
")";
352 ensure_if_modifiable();
357 inherited::archive(n);
358 n.add_ex(
"a",
aij[0]);
359 n.add_ex(
"i",
aij[1]);
360 n.add_ex(
"j",
aij[2]);
364 inherited::read_archive(n);
367 aij[0] = ex_to<Index>(o);
369 aij[1] = ex_to<Index>(o);
371 aij[2] = ex_to<Index>(o);
380 lst argv = ex_to<lst>(
aij[0]);
382 for(
auto it=argv.rbegin(); it!=argv.rend(); ++it)
as.append(*it);
398 if(!is_a<SUNF>(other))
throw Error(
"SUNF::compare_same_type");
399 const SUNF &o =
static_cast<const SUNF &
>(other);
400 for(
int i=0; i<3; i++) {
401 auto c =
ijk[i].compare(o.
ijk[i]);
408 if(!is_a<SUNF>(other))
throw Error(
"SUNF::is_equal_same_type");
409 const SUNF &o =
static_cast<const SUNF &
>(other);
410 for(
int i=0; i<3; i++) {
411 if(!
ijk[i].is_equal(o.
ijk[i]))
return false;
417 if(flags & status_flags::evaluated)
return *
this;
418 if(
ijk[0].is_equal(
ijk[1]) ||
ijk[1].is_equal(
ijk[2]) ||
ijk[0].is_equal(
ijk[2]))
return 0;
421 if(c01 && c12)
return this->hold();
428 else return this->hold();
432 c.s <<
"f(" <<
ijk[0] <<
"," <<
ijk[1] <<
"," <<
ijk[2] <<
")";
436 c <<
"f(" <<
ijk[0] <<
"," <<
ijk[1] <<
"," <<
ijk[2] <<
")";
440 c <<
"SUNF[" <<
ijk[0] <<
"," <<
ijk[1] <<
"," <<
ijk[2] <<
"]";
448 ensure_if_modifiable();
453 inherited::archive(n);
454 n.add_ex(
"i",
ijk[0]);
455 n.add_ex(
"j",
ijk[1]);
456 n.add_ex(
"k",
ijk[2]);
460 inherited::read_archive(n);
463 ijk[0] = ex_to<Index>(o);
465 ijk[1] = ex_to<Index>(o);
467 ijk[2] = ex_to<Index>(o);
491 if(!is_a<SUNF4>(other))
throw Error(
"SUNF4::compare_same_type");
492 const SUNF4 &o =
static_cast<const SUNF4 &
>(other);
493 for(
int i=0; i<4; i++) {
494 auto c =
ijkl[i].compare(o.
ijkl[i]);
501 if(!is_a<SUNF4>(other))
throw Error(
"SUNF4::is_equal_same_type");
502 const SUNF4 &o =
static_cast<const SUNF4 &
>(other);
503 for(
int i=0; i<4; i++) {
504 if(!
ijkl[i].is_equal(o.
ijkl[i]))
return false;
514 if(flags & status_flags::evaluated)
return *
this;
518 if(c01 && c23)
return this->hold();
522 else return this->hold();
531 c.s <<
"f(" <<
ijkl[0] <<
"," <<
ijkl[1] <<
"," <<
ijkl[2] <<
"," <<
ijkl[3] <<
")";
535 c <<
"SUNF[" <<
ijkl[0] <<
"," <<
ijkl[1] <<
"," <<
ijkl[2] <<
"," <<
ijkl[3] <<
"]";
544 c <<
"f4(" <<
ijkl[0] <<
"," <<
ijkl[1] <<
"," <<
ijkl[2] <<
"," <<
ijkl[3] <<
")";
552 ensure_if_modifiable();
561 inherited::archive(n);
562 n.add_ex(
"i",
ijkl[0]);
563 n.add_ex(
"j",
ijkl[1]);
564 n.add_ex(
"k",
ijkl[2]);
565 n.add_ex(
"l",
ijkl[3]);
573 inherited::read_archive(n);
576 ijkl[0] = ex_to<Index>(o);
578 ijkl[1] = ex_to<Index>(o);
580 ijkl[2] = ex_to<Index>(o);
582 ijkl[3] = ex_to<Index>(o);
600 }
else if(is_a<mul>(e) || is_a<ncmul>(e)) {
604 if(!is_a<add>(rei)) rei = lst{ rei };
607 for(
auto oi : ores)
for(
auto ri : rei) res.append(oi * ri);
610 for(
auto ri : res) ret += ri;
612 }
else return e.map(self);
614 return inner_expand(expr);
624 if(!expr_in.has(GMat(
w1,
w2,
w3)))
return expr_in;
627 expr = expr.subs(GMat(
w1,
w2,
w2)==TR(
w1));
631 for(
auto cv : cv_lst) {
633 if(is_zero(e-1) || e.match(GMat(
w1,
w2,
w3))) {
634 if(e.match(GMat(
w1,
w2,
w2))) expr += cv.op(0) * TR(e.op(0));
635 else expr += cv.op(0) * e;
637 }
else if(!is_a<mul>(e))
throw Error(
"GMatContract: collect error: " +
ex2str(e));
640 for(
auto item : e) mats.append(item);
642 std::map<ex,int,ex_is_less> to_map, from_map;
647 for(
int i=0; i<mats.nops(); i++) {
648 auto item = mats.op(i);
649 if(item.op(0).return_type()==return_types::commutative || item.op(0).is_equal(
GAS(1))) {
650 mats_idx.append(lst{item,i});
652 if(!item.match(GMat(
w1,
w2,
w3))) {
653 cout <<
"item in GMatContract: " << item << endl;
654 throw Error(
"GMatContract faild!");
656 if(to_map[item.op(1)]!=0 || from_map[item.op(2)]!=0) {
657 if(!auto_tr)
throw Error(
"GMatContract: index conflict for mats: "+
ex2str(mats));
659 mats2.append(
GMatT(item));
660 for(
int j=0; j<mats.nops(); j++)
if(j!=i) mats2.append(mats.op(j));
664 mats_idx.remove_all();
667 to_map[item.op(1)] = i+10;
668 from_map[item.op(2)] = i+10;
674 bool checked =
false;
678 for(
int i=0; i<mats_idx.nops(); i++) {
679 auto item = mats_idx.op(i).op(0);
680 int ii = ex_to<numeric>(mats_idx.op(i).op(1)).to_int();
682 to_map[item.op(1)]==0 && from_map[item.op(2)]==0 &&
683 to_map[item.op(2)]==0 && from_map[item.op(1)]==0) {
684 mats_idx2.append(mats_idx.op(i));
689 if(to_map[item.op(1)]==0 && from_map[item.op(2)]==0) {
690 to_map[item.op(1)] = ii+10;
691 from_map[item.op(2)] = ii+10;
692 }
else if(to_map[item.op(2)]==0 && from_map[item.op(1)]==0) {
693 to_map[item.op(2)] = ii+10;
694 from_map[item.op(1)] = ii+10;
696 auto li =
get_op(mats, ii, 1);
697 auto ri =
get_op(mats, ii, 2);
701 throw Error(
"GMatContract: index conflict (2).");
704 if(mats_idx2.nops()<1)
break;
705 mats_idx = mats_idx2;
710 while(todo.size()>0) {
711 int c = *(todo.begin());
713 ex curMat = mats.op(c).op(0);
714 auto li=mats.op(c).op(1);
715 auto ri=mats.op(c).op(2);
717 if(li.is_equal(ri)) {
718 retMat *= TR(curMat);
722 int fi = from_map[li];
724 retMat *= GMat(curMat, li, ri);
728 auto mat = mats.op(ti-10).op(0);
729 if(curMat.is_equal(
GAS(1))) curMat = mat;
730 else if(!mat.is_equal(
GAS(1))) curMat = curMat * mat;
731 ri = mats.op(ti-10).op(2);
736 auto mat = mats.op(fi-10).op(0);
737 if(curMat.is_equal(
GAS(1))) curMat = mat;
738 else if(!mat.is_equal(
GAS(1))) curMat = mat * curMat;
739 li = mats.op(fi-10).op(1);
745 expr += cv.op(0) * retMat;
755 else if(is_a<Pair>(e)) {
756 if(is_a<Index>(e.op(0)) || is_a<Index>(e.op(1))) idx_lst.append(e);
758 }
else return e.map(self);
763 if(idx_lst.nops()==0)
return ei;
768 auto v =
form(cv.op(1));
771 if(!is_a<mul>(v)) v = lst{ v };
775 if(!is_a<Pair>(vi)) r *= vi;
776 else if(is_a<Index>(vi.op(1)) && c.has(vi.op(1))) repl[vi.op(1)] = vi.op(0);
777 else if(is_a<Index>(vi.op(0)) && c.has(vi.op(0))) repl[vi.op(0)] = vi.op(1);
780 res += r * c.subs(repl);
788 if(e.match(GMat(
w1,
w2,
w3))) {
792 for(
auto item : e0) {
793 if(item.return_type()==return_types::commutative) c *= item;
796 cout <<
"c=" << c <<
", " <<
"v=" << v << endl;
797 throw Error(
"GMatOut: v != 1");
802 if(v.is_equal(1)) v =
GAS(1);
803 return c *
GMatOut(GMat(v, e.op(1), e.op(2)));
805 }
else return e.map(self);
807 return inner_out(expr_in);
812 if(!e.has(GMat(
w1,
w2,
w3)))
return e;
813 else if(e.match(GMat(
w1,
w2,
w3))) {
817 for(
auto item : e0) res +=
GMatExpand(GMat(item, e.op(1), e.op(2)));
819 }
else if(is_a<mul>(e0)) {
821 for(
auto item : e0) {
822 if(item.return_type()==return_types::commutative) c *= item;
825 cout <<
"c=" << c <<
", " <<
"v=" << v << endl;
826 throw Error(
"GMatExpand: v != 1");
831 if(v.is_equal(1)) v =
GAS(1);
832 return c *
GMatExpand(GMat(v, e.op(1), e.op(2)));
833 }
else if(is_a<ncmul>(e0)) {
836 for(
auto item : e0) {
843 if(!is_a<add>(ncL)) ncL = lst{ ncL };
845 if(!is_a<add>(ncR)) ncR = lst{ ncR };
847 for(
auto iL : ncL)
for(
auto iR : ncR) res += iL * iR;
851 if(!is_a<add>(rs)) rs = lst{ rs };
852 for(
auto item : rs) {
854 if(is_a<mul>(item)) {
855 if(item.nops()==1)
throw Error(
"GMatExpand: item.nops == 1");
856 for(
auto it : item) {
857 if(it.return_type()==return_types::commutative) c *= it;
859 if(!v.is_equal(1))
throw Error(
"GMatExpand: v != 1");
875 if(last==vi && is_a<DGamma>(vi)) {
878 if(is_a<Vector>(vi.op(0))) c *=
SP(vi.op(0));
879 else if(is_a<Index>(vi.op(0))) c *=
d;
880 else if(vi.op(0).is_equal(1) || vi.op(0).is_equal(5)) c *= 1;
881 else throw Error(
"GMatExpand: only GAS(i/p/1/5) supported.");
884 if(last!=
GAS(1) && !last.is_equal(1)) vv = vv * last;
889 if(!last.is_equal(1) && last!=
GAS(1)) v = vv * last;
894 if(v.is_equal(1)) v =
GAS(1);
895 res += c * GMat(v, e.op(1), e.op(2));
899 }
else return e.map(self);
901 return inner_expand(expr_in);
904 ex
GMatShift(
const ex & expr,
const ex & g,
bool to_right) {
905 if(!expr.has(g))
return expr;
907 if(!e.has(g) || !e.has(GMat(
w1,
w2,
w3)))
return e;
908 else if(e.match(GMat(
w1,
w2,
w3))) {
910 if(!is_a<ncmul>(eg)) eg = lst{ eg };
913 for(
int i=0; i<eg.nops()-1; i++)
if(eg.op(i)==g) { gi = i; break; }
916 for(
int i=eg.nops()-1; i>0; i--)
if(eg.op(i)==g) { gi = i;
break; }
919 int gj = gi + ( to_right ? 1 : -1 );
920 ex rem = 1, rem2 = 1;
921 for(
int i=0; i<eg.nops(); i++) {
927 if(to_right) rem2 *= eg.op(gj)*eg.op(gi);
928 else rem2 *= eg.op(gi)*eg.op(gj);
931 if(eg.op(gi).is_equal(eg.op(gj))) {
932 ex ip = eg.op(gi).op(0);
933 if(rem.is_equal(1)) rem =
GAS(1);
934 ex res = GMat(rem, e.op(1), e.op(2));
937 if(is_a<Vector>(ip)) c =
SP(ip);
938 else if(is_a<Index>(ip)) c =
d;
939 else if(eg.op(gi).is_equal(
GAS(5))) c = 1;
940 else throw Error(
"GMatShift: only GAS(i/p/5) supproted.");
943 if(rem.is_equal(1)) rem =
GAS(1);
944 if(rem2.is_equal(1)) rem2 =
GAS(1);
946 if(!eg.op(gi).is_equal(
GAS(5)) && !eg.op(gj).is_equal(
GAS(5))) {
947 res = 2*
SP(eg.op(gi).op(0), eg.op(gj).op(0)) * GMat(rem, e.op(1), e.op(2));
949 res = res - GMat(rem2, e.op(1), e.op(2));
951 }
else return e.map(self);
955 res = inner_shift(res);
968 lst shift_1st_to_right(
const ex & e) {
969 if(!is_a<ncmul>(e))
throw Error(
"input is not a ncmul.");
972 if(e.op(0)!=e.op(1))
throw Error(
"shift_1st_to_right: the 2 items are not equal!");
973 else if(is_a<Index>(e0.op(0)))
return lst{ lst{
d, 1 }};
974 else if(is_a<Vector>(e0.op(0)))
return lst{ lst{
SP(e.op(0).op(0)), 1 }};
975 else if(e0.is_equal(
GAS(5)))
return lst{ lst{ 1, 1 }};
977 cout << endl << e << endl;
978 throw Error(
"shift_1st_to_right: only GAS(i/p/5) supproted.");
983 for(
int i=2; i<n; i++) rem *= e.op(i);
984 lst res = shift_1st_to_right(e.op(0)*rem);
986 for(
int i=0; i<n; i++) {
987 res.let_op(i).let_op(0) = -res.op(i).op(0);
988 res.let_op(i).let_op(1) = e.op(1) * res.op(i).op(1);
990 if(!e.op(0).is_equal(
GAS(5)) && !e.op(1).is_equal(
GAS(5))) {
991 if(!is_a<Index>(e.op(0).op(0)) && !is_a<Vector>(e.op(0).op(0))) {
993 throw Error(
"shift_12_right: not a Vector or Index");
995 if(!is_a<Index>(e.op(1).op(0)) && !is_a<Vector>(e.op(1).op(0))) {
997 throw Error(
"shift_12_right: not a Vector or Index");
999 res.append(lst{ 2*
SP(e.op(0).op(0), e.op(1).op(0)), rem });
1006 if(!e.has(GMat(
w1,
w2,
w3)))
return e;
1007 else if(e.match(GMat(
w1,
w2,
w3))) {
1009 if(!is_a<ncmul>(eg)) eg = lst{ eg };
1011 int gi = -1, gj = -1;
1012 for(
int i=0; i<eg.nops(); i++)
for(
int j=i+1; j<eg.nops(); j++) {
1013 if(eg.op(i).is_equal(eg.op(j))) {
1022 ex exL = 1, exM=1, exR = 1;
1023 for(
int i=0; i<eg.nops(); i++) {
1024 if(i<gi) exL *= eg.op(i);
1025 else if(i>gj) exR *= eg.op(i);
1026 else exM *= eg.op(i);
1028 lst cvs = shift_1st_to_right(exM);
1031 for(
auto cv : cvs) {
1032 ex item = exL*cv.op(1)*exR;
1033 if(item.is_equal(1)) item =
GAS(1);
1034 res += cv.op(0)*
GMatShift(GMat(item, e.op(1), e.op(2)));
1038 }
else return e.map(self);
1042 res = inner_shift(res);
1050 else if(e.match(GMat(
w1,
w2,
w3)) || e.match(TR(
w))) {
1051 ex eg = e.op(0), cc = 1;
1052 if(is_a<mul>(e.op(0))) {
1054 for(
auto item : e.op(0)) {
1055 if(item.return_type()==return_types::noncommutative) {
1056 if(eg.is_equal(1)) eg = item;
1057 else throw Error(
"GMatECC:: 2 more noncommutative objects found.");
1060 if(eg.is_equal(1))
throw Error(
"GMatECC:: eg is 1, NOT expected.");
1062 if(!is_a<ncmul>(eg)) eg = lst{ eg };
1064 for(
int i=0; i<eg.nops(); i++)
if(eg.op(i)==
DGamma::C) { ci = i;
break; }
1065 if(ci==-1)
return e;
1067 for(
int i=ci+1; i<eg.nops(); i++)
if(eg.op(i)==
DGamma::C) { cj = i;
break; }
1068 if(cj==-1)
return e;
1070 for(
int i=cj+1; i<eg.nops(); i++)
if(eg.op(i)==
DGamma::C) { cnt++; }
1072 for(
int i=0; i<ci; i++) res *= eg.op(i);
1074 for(
int i=ci+1; i<cj; i++) m *= eg.op(i);
1077 for(
int i=cj+1; i<eg.nops(); i++) res *= eg.op(i);
1078 if(e.nops()==3) res = cc * GMat(res, e.op(1), e.op(2));
1079 else res = cc * TR(res);
1080 return cnt<2 ? res : self(res);
1081 }
else return e.map(self);
1084 res = inner_ecc(res);
1085 if(res.has(TR(
w))) {
1087 if(!e.has(TR(
w)))
return e;
1088 else if(e.match(TR(
w))) {
1091 for(
auto item :
gs) {
1092 auto gi = ex_to<DGamma>(item);
1093 if(!item.is_equal(
DGamma::C) && !gi.isTr) {
1100 }
else return e.map(self);
1108 if(!e.has(GMat(
w1,
w2,
w3)))
return e;
1109 else if(e.match(GMat(
w1,
w2,
w3))) {
1111 }
else return e.map(self);
1114 res = inner_transpose(res);
1119 void GMat_fc_print(
const ex &arg1,
const ex &arg2,
const ex &arg3,
const print_context &c0) {
1120 auto c =
static_cast<const FCFormat &
>(c0);
1121 c <<
"GMat[" << arg1 <<
"," << arg2 <<
"," << arg3 <<
"]";
1125 REGISTER_FUNCTION(GMat, do_not_evalf_params().print_func<FCFormat>(&GMat_fc_print).conjugate_func(mat_conj).set_return_type(return_types::commutative))
1127 bool IsZero(
const ex & e) {
1130 for(const_preorder_iterator i = e.preorder_begin(); i != e.preorder_end(); ++i) {
1131 if(is_a<symbol>(*i) || is_a<Pair>(*i))
vs.insert(*i);
1135 for(
int i=0; i<5; i++) {
1137 for(
auto item :
vs) {
1138 nsubs[item] = ex(1)/n_nth_prime(n);
1141 ex ret = e.subs(nsubs);
1142 if(!normal(e).is_zero())
return false;
1146 return ret.is_zero();
1158 for(
auto cv : cvs) {
1159 int degTF = cv.op(1).degree(
TF);
1160 int degNF = cv.op(1).ldegree(
NF);
1161 if(degTF>0 && degNF<0) {
1164 if(degTF+degNF>0) n = -degNF;
1165 res += cv.op(0) * cv.op(1) * pow(
TF/
NF,-n) * pow(
TF*
NF-
CF,n);
1166 }
else if(degTF>0 && degNF>1) {
1169 if(degTF>degNF/2) n = degNF/2;
1170 res += cv.op(0) * cv.op(1) * pow(
TF*
NF*
NF,-n) * pow(
CF*
NF+
TF,n);
1171 }
else res += cv.op(0) * cv.op(1);
1179 if(!e.has(
CA))
return e;
1180 else if(e.match(pow(
CA,
w)) && e.op(1).info(info_flags::negint))
return pow(
CA-2*
CF,-e.op(1));
1181 else return e.map(self);
1183 return ca_map(expr);
1190 res = res.subs(
NF==
CA);
1216 if(!is_a<mul>(res)) res = lst{ res };
1218 for(
auto item : res) {
1219 if(item.has(
NF)) c *= item;
1223 int deg = c.degree(
NF);
1224 int ldeg = -c.ldegree(
NF);
1225 if(ldeg>deg) deg = ldeg;
1229 for(
int i=0; i<=deg; i++) {
1231 eqn -= xi * pow(
NF,i) * pow((
NF*
NF-1)/(2*
NF), deg-i);
1235 int nH = eqn.degree(
NF);
1236 int nL = eqn.ldegree(
NF);
1238 for(
int i=
nL; i<=
nH; i++) {
1239 ex cc = eqn.coeff(
NF, i);
1240 if(cc.is_zero())
continue;
1243 auto sol = lsolve(eqns, vars);
1244 if(sol.nops()!=deg+1) {
1245 cout <<
"c=" << c << endl;
1246 cout <<
"sol=" << sol << endl;
1247 throw Error(
"HomCACF: no solution found!");
1250 for(
int i=0; i<=deg; i++) c += vars.op(i).subs(sol) * pow(
CA,i) * pow(
CF, deg-i);
1255 ex
DoColor(
const ex & expr,
const ex & pref,
int method) {
1258 for(
auto const & cv : cvs) {
#define IMPLEMENT_HAS(classname)
#define DEFAULT_CTOR(classname)
#define IMPLEMENT_ALL(classname)
static lst all(const ex &e)
static bool has(const ex &e)
class used to wrap error message
int compare_same_type(const GiNaC::basic &other) const override
const char * class_name() const override
static bool hasv(const ex &e)
void archive(archive_node &n) const override
bool is_equal_same_type(const basic &other) const override
static GiNaC::registered_class_info & get_class_info_static()
void print(const print_context &c, unsigned level=0) const
void read_archive(const archive_node &n) override
static bool hasc(const ex &e)
ex derivative(const symbol &s) const override
const GiNaC::registered_class_info & get_class_info() const override
Pair operator()(const Index &i)
void accept(GiNaC::visitor &v) const override
Index * duplicate() const override
static bool has(const ex &e)
class to wrap map_function of GiNaC
static bool has(const ex &e)
void archive(archive_node &n) const override
save to archvie
static GiNaC::registered_class_info & get_class_info_static()
void form_print(const FormFormat &c, unsigned level=0) const
print the Form Format
void accept(GiNaC::visitor &v) const override
const GiNaC::registered_class_info & get_class_info() const override
size_t nops() const override
void fc_print(const FCFormat &c, unsigned level=0) const
void print(const print_dflt &c, unsigned level=0) const
normal priint
ex op(size_t i) const override
ex & let_op(size_t i) override
SUNF4 * duplicate() const override
ex eval() const override
automatical evaluation of SUNF4
ex derivative(const symbol &s) const override
set derivative of SUNF4 to 0
bool is_equal_same_type(const basic &other) const override
const char * class_name() const override
void read_archive(const archive_node &n) override
read from archive
int compare_same_type(const GiNaC::basic &other) const override
void archive(archive_node &n) const override
void print(const print_dflt &c, unsigned level=0) const
const char * class_name() const override
int compare_same_type(const GiNaC::basic &other) const override
ex derivative(const symbol &s) const override
set derivative of SUNF to 0
bool is_equal_same_type(const basic &other) const override
void form_print(const FormFormat &c, unsigned level=0) const
static GiNaC::registered_class_info & get_class_info_static()
ex & let_op(size_t i) override
SUNF * duplicate() const override
const GiNaC::registered_class_info & get_class_info() const override
void read_archive(const archive_node &n) override
size_t nops() const override
void accept(GiNaC::visitor &v) const override
void fc_print(const FCFormat &c, unsigned level=0) const
ex op(size_t i) const override
static GiNaC::registered_class_info & get_class_info_static()
bool is_equal_same_type(const basic &other) const override
ex & let_op(size_t i) override
void archive(archive_node &n) const override
size_t nops() const override
void form_print(const FormFormat &c, unsigned level=0) const
ex op(size_t i) const override
const GiNaC::registered_class_info & get_class_info() const override
void fc_print(const FCFormat &c, unsigned level=0) const
void print(const print_dflt &c, unsigned level=0) const
int compare_same_type(const GiNaC::basic &other) const override
void read_archive(const archive_node &n) override
SUNT * duplicate() const override
const char * class_name() const override
void accept(GiNaC::visitor &v) const override
ex derivative(const symbol &s) const override
ex conjugate() const override
class extended to GiNaC symbol class, represent a positive symbol
Vector * duplicate() const override
bool is_equal_same_type(const basic &other) const override
Pair operator()(const Vector &p)
const char * class_name() const override
ex derivative(const symbol &s) const override
void print(const print_context &c, unsigned level=0) const
static GiNaC::registered_class_info & get_class_info_static()
int compare_same_type(const GiNaC::basic &other) const override
void read_archive(const archive_node &n) override
void accept(GiNaC::visitor &v) const override
void archive(archive_node &n) const override
const GiNaC::registered_class_info & get_class_info() const override
ex exfactor(const ex &expr_in, int opt)
factorize a expression
bool ex_less(const ex &a, const ex &b)
ex DoColor(const ex &expr, const ex &pref, int method)
void let_op(ex &ex_in, int index1, int index2, const ex item)
update index1-th.index2-th of expression with item
ex GMatShift(const ex &expr, const ex &g, bool to_right)
ex collect_ex(ex const &expr_in, std::function< bool(const ex &)> has_func, int opt)
the collect function like Mathematica
ex GMatSimplify(const ex &expr)
ex GAS(const ex &expr, unsigned rl)
function similar to GAD/GSD in FeynClac
ex GMatExpand(const ex &expr_in)
ex GMatContract(const ex &expr_in, bool auto_tr)
make contract on matrix, i.e., GMat(a,i1,i2)*GMat(b,i2,i3) -> GMat(a*b,i1,i3)
ex Contract(const ex &ei)
ex get_op(const ex ex_in, int index1, int index2)
return index1-th.index2-th of expression
ex GMatOut(const ex &expr_in)
ex exnormal(const ex &expr, int opt)
normalize a expression
ex gamma_transpose(const ex &expr)
make the transpose operaton M --> M^T
ex charge_conjugate(const ex &expr)
make the charge conjugate operaton, M -> C^{-1} . M^T . C w.r.t. a GMat object
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}, ... }
string ex2str(const ex &expr)
convert ex to output string, the defalut printer format will be used
ex ncmul_expand(const ex &expr)
REGISTER_FUNCTION(GMat, do_not_evalf_params().print_func< FCFormat >(&GMat_fc_print).conjugate_func(mat_conj).set_return_type(return_types::commutative)) bool IsZero(const ex &e)
ex GMatECC(const ex &expr)
ex form(const ex &iexpr, int verb)
evalulate expr in form program, see also the form_trace_mode and form_expand_mode
ex SP(const ex &a, bool use_map=false)
ex ca_neg_pow_sub(const ex &expr)