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 Matrix(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 if(!expr_in.has(Matrix(
w1,
w2,
w3)))
return expr_in;
605 for(
auto cv : cv_lst) {
607 if(is_zero(e-1) || e.match(Matrix(
w1,
w2,
w3))) {
608 expr += cv.op(0) * e;
610 }
else if(!is_a<mul>(e))
throw Error(
"MatrixContract: collect error: " +
ex2str(e));
613 for(
auto item : e) mats.append(item);
615 std::map<ex,int,ex_is_less> to_map, from_map;
618 for(
int i=0; i<mats.nops(); i++) {
619 auto item = mats.op(i);
620 if(item.op(0).return_type()==return_types::commutative || item.op(0).is_equal(
GAS(1)) || item.op(0).is_equal(color_ONE())) {
621 mats_idx.append(lst{item,i});
623 if(to_map[item.op(1)]!=0 || from_map[item.op(2)]!=0)
throw Error(
"MatrixContract: index conflict for "+
ex2str(item));
624 to_map[item.op(1)] = i+10;
625 from_map[item.op(2)] = i+10;
631 bool checked =
false;
635 for(
int i=0; i<mats_idx.nops(); i++) {
636 auto item = mats_idx.op(i).op(0);
637 int ii = ex_to<numeric>(mats_idx.op(i).op(1)).to_int();
639 to_map[item.op(1)]==0 && from_map[item.op(2)]==0 &&
640 to_map[item.op(2)]==0 && from_map[item.op(1)]==0) {
641 mats_idx2.append(mats_idx.op(i));
646 if(to_map[item.op(1)]==0 && from_map[item.op(2)]==0) {
647 to_map[item.op(1)] = ii+10;
648 from_map[item.op(2)] = ii+10;
649 }
else if(to_map[item.op(2)]==0 && from_map[item.op(1)]==0) {
650 to_map[item.op(2)] = ii+10;
651 from_map[item.op(1)] = ii+10;
653 auto li =
get_op(mats, ii, 1);
654 auto ri =
get_op(mats, ii, 2);
658 throw Error(
"MatrixContract: index conflict (2).");
661 if(mats_idx2.nops()<1)
break;
662 mats_idx = mats_idx2;
667 while(todo.size()>0) {
668 int c = *(todo.begin());
670 ex curMat = mats.op(c).op(0);
671 auto li=mats.op(c).op(1);
672 auto ri=mats.op(c).op(2);
675 retMat *= TR(curMat);
679 int fi = from_map[li];
681 retMat *= Matrix(curMat, li, ri);
685 auto mat = mats.op(ti-10).op(0);
686 if(is_zero(curMat-
GAS(1))) curMat = mat;
687 else if(!is_zero(mat-
GAS(1))) curMat = curMat * mat;
688 ri = mats.op(ti-10).op(2);
693 auto mat = mats.op(fi-10).op(0);
694 if(is_zero(curMat-
GAS(1))) curMat = mat;
695 else if(!is_zero(mat-
GAS(1))) curMat = mat * curMat;
696 li = mats.op(fi-10).op(1);
702 expr += cv.op(0) * retMat;
709 void Matrix_fc_print(
const ex &arg1,
const ex &arg2,
const ex &arg3,
const print_context &c0) {
710 auto c =
static_cast<const FCFormat &
>(c0);
711 c <<
"Matrix[" << arg1 <<
"," << arg2 <<
"," << arg3 <<
"]";
717 bool IsZero(
const ex & e) {
720 for(const_preorder_iterator i = e.preorder_begin(); i != e.preorder_end(); ++i) {
721 if(is_a<symbol>(*i) || is_a<Pair>(*i))
vs.insert(*i);
725 for(
int i=0; i<5; i++) {
727 for(
auto item :
vs) {
728 nsubs[item] = ex(1)/n_nth_prime(n);
731 ex ret = e.subs(nsubs);
732 if(!normal(e).is_zero())
return false;
736 return ret.is_zero();
749 int degTF = cv.op(1).degree(
TF);
750 int degNF = cv.op(1).ldegree(
NF);
751 if(degTF>0 && degNF<0) {
754 if(degTF+degNF>0) n = -degNF;
755 res += cv.op(0) * cv.op(1) * pow(
TF/
NF,-n) * pow(
TF*
NF-
CF,n);
756 }
else if(degTF>0 && degNF>1) {
759 if(degTF>degNF/2) n = degNF/2;
760 res += cv.op(0) * cv.op(1) * pow(
TF*
NF*
NF,-n) * pow(
CF*
NF+
TF,n);
761 }
else res += cv.op(0) * cv.op(1);
769 if(!e.has(
CA))
return e;
770 else if(e.match(pow(
CA,
w)) && e.op(1).info(info_flags::negint))
return pow(
CA-2*
CF,-e.op(1));
771 else return e.map(
self);
780 res = res.subs(
NF==
CA);
806 if(!is_a<mul>(res)) res = lst{ res };
808 for(
auto item : res) {
809 if(item.has(
NF)) c *= item;
813 int deg = c.degree(
NF);
814 int ldeg = -c.ldegree(
NF);
815 if(ldeg>deg) deg = ldeg;
819 for(
int i=0; i<=deg; i++) {
821 eqn -= xi * pow(
NF,i) * pow((
NF*
NF-1)/(2*
NF), deg-i);
825 int nH = eqn.degree(
NF);
826 int nL = eqn.ldegree(
NF);
828 for(
int i=
nL; i<=
nH; i++) {
829 ex cc = eqn.coeff(
NF, i);
830 if(cc.is_zero())
continue;
833 auto sol = lsolve(eqns, vars);
834 if(sol.nops()!=deg+1) {
835 cout <<
"c=" << c << endl;
836 cout <<
"sol=" << sol << endl;
837 throw Error(
"HomCACF: no solution found!");
840 for(
int i=0; i<=deg; i++) c += vars.op(i).subs(sol) * pow(
CA,i) * pow(
CF, deg-i);
845 ex
DoColor(
const ex & expr,
const ex & pref,
int method) {
848 for(
auto const & cv : cvs) {
#define IMPLEMENT_HAS(classname)
#define DEFAULT_CTOR(classname)
#define IMPLEMENT_ALL(classname)
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
class to wrap map_function of GiNaC
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
do_not_evalf_params().expl_derivative_func(zd1D).derivative_func(zp1D)) REGISTER_FUNCTION(FTX
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 MatrixContract(const ex &expr_in)
make contract on matrix, i.e., Matrix(a,i1,i2)*Matrix(b,i2,i3) -> Matrix(a*b,i1,i3)
ex collect_ex(ex const &expr_in, std::function< bool(const ex &)> has_func, int opt)
the collect function like Mathematica
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)
ex get_op(const ex ex_in, int index1, int index2)
return index1-th.index2-th of expression
ex exnormal(const ex &expr, int opt)
normalize a expression
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 exfactor(const ex &expr, int opt)
factorize a expression
ex form(const ex &iexpr, int verb)
evalulate expr in form program, see also the form_trace_mode and form_expand_mode
ex ca_neg_pow_sub(const ex &expr)