HepLib
Loading...
Searching...
No Matches
Basic.cpp
Go to the documentation of this file.
1
6#include "HEP.h"
7#include "flint/ulong_extras.h"
8
9namespace HepLib {
10
11 DEFAULT_CTOR(Index)
12 IMPLEMENT_HAS(Index)
13 IMPLEMENT_ALL(Index)
14
15 DEFAULT_CTOR(Vector)
16 IMPLEMENT_HAS(Vector)
17 IMPLEMENT_ALL(Vector)
18
19 DEFAULT_CTOR(SUNT)
20 IMPLEMENT_HAS(SUNT)
21 IMPLEMENT_ALL(SUNT)
22
23 DEFAULT_CTOR(SUNF)
24 IMPLEMENT_HAS(SUNF)
25 IMPLEMENT_ALL(SUNF)
26
27 DEFAULT_CTOR(SUNF4)
28 IMPLEMENT_HAS(SUNF4)
29 IMPLEMENT_ALL(SUNF4)
30
31 //-----------------------------------------------------------
32 // FormFormat Output
33 //-----------------------------------------------------------
34 FormFormat::FormFormat(ostream &os, unsigned opt) : print_dflt(os, opt) {}
35 FormFormat::FormFormat() : print_dflt(std::cout) {}
36 GINAC_IMPLEMENT_PRINT_CONTEXT(FormFormat, print_dflt)
37
38 const FormFormat & FormFormat::operator << (const basic & v) const {
39 v.print(*this);
40 return *this;
41 }
42 const FormFormat & FormFormat::operator << (const ex & v) const {
43 v.print(*this);
44 return *this;
45 }
46 const FormFormat & FormFormat::operator << (const lst & v) const {
47 v.print(*this);
48 return *this;
49 }
50 const FormFormat & FormFormat::operator<<(std::ostream& (*v)(std::ostream&)) const {
51 s << v;
52 return *this;
53 }
54
55 void FormFormat::power_print(const power & p, const FormFormat & c, unsigned level) {
56 if(p.op(1)==2 && !DGamma::has(p)) {
57 c << "((" << p.op(0) << ")*(" << p.op(0) << "))";
58 } else {
59 c << "((" << p.op(0) << ")^(" << p.op(1) << "))";
60 }
61 }
62
63 //-----------------------------------------------------------
64 // FCFormat Output
65 //-----------------------------------------------------------
66 FCFormat::FCFormat(ostream &os, unsigned opt) : print_dflt(os, opt) {}
67 FCFormat::FCFormat() : print_dflt(std::cout) {}
68 GINAC_IMPLEMENT_PRINT_CONTEXT(FCFormat, print_dflt)
69
70 const FCFormat & FCFormat::operator << (const basic & v) const {
71 v.print(*this);
72 return *this;
73 }
74 const FCFormat & FCFormat::operator << (const ex & v) const {
75 v.print(*this);
76 return *this;
77 }
78 const FCFormat & FCFormat::operator << (const lst & v) const {
79 v.print(*this);
80 return *this;
81 }
82 const FCFormat & FCFormat::operator<<(std::ostream& (*v)(std::ostream&)) const {
83 s << v;
84 return *this;
85 }
86
87 const FCFormat & FCFormat::operator << (const matrix & mat) const {
88 s << "{";
89 int nr = mat.rows();
90 int nc = mat.cols();
91 for(int r=0; r<nr; r++) {
92 s << "{";
93 for(int c=0; c<nc; c++) {
94 mat(r,c).print(*this);
95 if(c+1!=nc) s << ",";
96 }
97 s << "}";
98 if(r+1!=nr) s << ",";
99 }
100 s << "}";
101 return *this;
102 }
103
104 const FCFormat & FCFormat::operator << (const exvector & e) const {
105 auto i = e.begin();
106 auto vend = e.end();
107 if (i==vend) { s << "{}"; return *this; }
108 s << "{";
109 while (true) {
110 i->print(*this);
111 ++i;
112 if(i==vend) break;
113 s << ",";
114 }
115 s << "}";
116 return *this;
117 }
118
119 const FCFormat & FCFormat::operator << (const exset & e) const {
120 auto i = e.begin();
121 auto send = e.end();
122 if (i==send) { s << "{}"; return *this; }
123 s << "{";
124 while (true) {
125 i->print(*this);
126 ++i;
127 if(i==send) break;
128 s << ",";
129 }
130 s << "}";
131 return *this;
132 }
133
134 const FCFormat & FCFormat::operator << (const exmap & e) const {
135 auto i = e.begin();
136 auto mend = e.end();
137 if (i==mend) { s << "{}"; return *this; }
138 s << "{";
139 while (true) {
140 i->first.print(*this);
141 s << "->";
142 i->second.print(*this);
143 ++i;
144 if(i==mend) break;
145 s << ",";
146 }
147 s << "}";
148 return *this;
149 }
150
151 namespace {
152 class ncmul_hack : public ncmul { // due to printseq is protected
153 public:
154 ncmul_hack(ncmul _nm) : ncmul(_nm){ }
155 void print(const FCFormat & c, unsigned level) {
156 printseq(c, '(', '.', ')', precedence(), level);
157 }
158 };
159 ex mat_conj(const ex & e1, const ex & e2, const ex & e3) {
160 return GMat(e1.conjugate(), e3, e2);
161 }
162 }
163 void FCFormat::ncmul_print(const ncmul & nm, const FCFormat & c, unsigned level) {
164 ncmul_hack(nm).print(c, level);
165 }
166
167 //-----------------------------------------------------------
168 // Index Class
169 //-----------------------------------------------------------
170 //GINAC_IMPLEMENT_REGISTERED_CLASS_OPT(Index, basic,print_func<print_context>(&Index::print))
171 GiNaC::registered_class_info & Index::get_class_info_static() { return reg_info; }
173 Index * Index::duplicate() const { Index * bp = new Index(*this); bp->setflag(GiNaC::status_flags::dynallocated); return bp; }
174 void Index::accept(GiNaC::visitor & v) const { if (visitor *p = dynamic_cast<visitor *>(&v)) p->visit(*this); else inherited::accept(v); }
175 const GiNaC::registered_class_info &Index::get_class_info() const { return get_class_info_static(); }
176 GiNaC::registered_class_info &Index::get_class_info() { return get_class_info_static(); }
177 const char *Index::class_name() const { return get_class_info_static().options.get_name(); }
178 //GINAC_IMPLEMENT_REGISTERED_CLASS END
179
180 Index::Index(const string &s, const Type t) : name(s), type(t) { }
181 int Index::compare_same_type(const basic &other) const {
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());
185 if(ret==0) return 0;
186 else if(ret<0) return -1;
187 else return 1;
188 }
189
190 bool Index::is_equal_same_type(const basic & other) const {
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());
194 }
195
196 void Index::print(const print_context &c, unsigned level) const {
197 c.s << name;
198 }
199
201 return Pair(*this, i);
202 }
203
205 return Pair(p, *this);
206 }
207
208 void Index::archive(archive_node & n) const {
209 inherited::archive(n);
210 n.add_string("name", name.get_name());
211 n.add_unsigned("type", type);
212 }
213
214 void Index::read_archive(const archive_node& n) {
215 inherited::read_archive(n);
216 string nstr;
217 unsigned t;
218 n.find_string("name", nstr);
219 name = Symbol(nstr);
220 n.find_unsigned("type", t);
221 type = (Type)t;
222 }
223
224 ex Index::derivative(const symbol & s) const {
225 return 0;
226 }
227
228 bool Index::hasc(const ex & e) {
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;
231 return false;
232 }
233
234 bool Index::hasv(const ex & e) {
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;
237 return false;
238 }
239
240 //-----------------------------------------------------------
241 // Vector Class
242 //-----------------------------------------------------------
243 //GINAC_IMPLEMENT_REGISTERED_CLASS_OPT(Vector, basic,print_func<print_context>(&Vector::print))
244 GiNaC::registered_class_info & Vector::get_class_info_static() { return reg_info; }
246 Vector * Vector::duplicate() const { Vector * bp = new Vector(*this); bp->setflag(GiNaC::status_flags::dynallocated); return bp; }
247 void Vector::accept(GiNaC::visitor & v) const { if (visitor *p = dynamic_cast<visitor *>(&v)) p->visit(*this); else inherited::accept(v); }
248 const GiNaC::registered_class_info &Vector::get_class_info() const { return get_class_info_static(); }
249 GiNaC::registered_class_info &Vector::get_class_info() { return get_class_info_static(); }
250 const char *Vector::class_name() const { return get_class_info_static().options.get_name(); }
251 //GINAC_IMPLEMENT_REGISTERED_CLASS END
252
253 Vector::Vector(const string &s) : name(s) { }
254 int Vector::compare_same_type(const basic &other) const {
255 if(!is_a<Vector>(other)) throw Error("Vector::compare_same_type");
256 const Vector &o = static_cast<const Vector &>(other);
257 auto ret = name.get_name().compare(o.name.get_name());
258 if(ret==0) return 0;
259 else if(ret<0) return -1;
260 else return 1;
261 }
262
263 bool Vector::is_equal_same_type(const basic & other) const {
264 if(!is_a<Vector>(other)) throw Error("Vector::is_equal_same_type");
265 const Vector &o = static_cast<const Vector &>(other);
266 return (name.get_name() == o.name.get_name());
267 }
268
269 void Vector::print(const print_context &c, unsigned level) const {
270 c.s << name;
271 }
272
274 return Pair(*this, p);
275 }
276
278 return Pair(*this, i);
279 }
280
281 void Vector::archive(archive_node & n) const {
282 inherited::archive(n);
283 n.add_string("name", name.get_name());
284 }
285
286 void Vector::read_archive(const archive_node& n) {
287 inherited::read_archive(n);
288 string nstr;
289 unsigned t;
290 n.find_string("name", nstr);
291 name = Symbol(nstr);
292 }
293
294 ex Vector::derivative(const symbol & s) const {
295 return 0;
296 }
297
298 //GINAC_IMPLEMENT_REGISTERED_CLASS_OPT(SUNT, basic,print_func<print_dflt>(&SUNT::print).print_func<FormFormat>(&SUNT::form_print).print_func<FCFormat>(&SUNT::fc_print))
299 GiNaC::registered_class_info & SUNT::get_class_info_static() { return reg_info; }
301 SUNT * SUNT::duplicate() const { SUNT * bp = new SUNT(*this); bp->setflag(GiNaC::status_flags::dynallocated); return bp; }
302 void SUNT::accept(GiNaC::visitor & v) const { if (visitor *p = dynamic_cast<visitor *>(&v)) p->visit(*this); else inherited::accept(v); }
303 const GiNaC::registered_class_info &SUNT::get_class_info() const { return get_class_info_static(); }
304 GiNaC::registered_class_info &SUNT::get_class_info() { return get_class_info_static(); }
305 const char *SUNT::class_name() const { return get_class_info_static().options.get_name(); }
306 //GINAC_IMPLEMENT_REGISTERED_CLASS END
307
308 SUNT::SUNT(ex a, ex i, ex j) : aij{a,i,j} { }
309 int SUNT::compare_same_type(const basic &other) const {
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]);
314 if(c!=0) return c;
315 }
316 return 0;
317 }
318
319 bool SUNT::is_equal_same_type(const basic & other) const {
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;
324 }
325 return true;
326 }
327
328 void SUNT::form_print(const FormFormat &c, unsigned level) const {
329 if(is_a<lst>(aij[0])) {
330 bool first = true;
331 for(auto item : aij[0]) {
332 if(first) { first=false; c << "T(" << item; }
333 else c << "," << item;
334 }
335 } else c << "T(" << aij[0];
336 c << "," << aij[1] << "," << aij[2] << ")";
337 }
338
339 void SUNT::fc_print(const FCFormat &c, unsigned level) const {
340 c << "SUNTF[" << aij[0] << "," << aij[1] << "," << aij[2] << "]";
341 }
342
343 void SUNT::print(const print_dflt &c, unsigned level) const {
344 c.s << "T(" << aij[0] << "," << aij[1] << "," << aij[2] << ")";
345 }
346
347 size_t SUNT::nops() const { return 3; }
348 ex SUNT::op(size_t i) const {
349 return aij[i];
350 }
351 ex & SUNT::let_op(size_t i) {
352 ensure_if_modifiable();
353 return aij[i];
354 }
355
356 void SUNT::archive(archive_node & n) const {
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]);
361 }
362
363 void SUNT::read_archive(const archive_node& n) {
364 inherited::read_archive(n);
365 ex o;
366 n.find_ex("a", o);
367 aij[0] = ex_to<Index>(o);
368 n.find_ex("i", o);
369 aij[1] = ex_to<Index>(o);
370 n.find_ex("j", o);
371 aij[2] = ex_to<Index>(o);
372 }
373
374 ex SUNT::derivative(const symbol & s) const {
375 return 0;
376 }
377
378 ex SUNT::conjugate() const {
379 if(!is_a<lst>(aij[0])) return SUNT(aij[0], aij[2], aij[1]);
380 lst argv = ex_to<lst>(aij[0]);
381 lst as;
382 for(auto it=argv.rbegin(); it!=argv.rend(); ++it) as.append(*it);
383 return SUNT(as, aij[2], aij[1]);
384 }
385
386 //GINAC_IMPLEMENT_REGISTERED_CLASS_OPT(SUNF, basic,print_func<print_dflt>(&SUNF::print).print_func<FormFormat>(&SUNF::form_print).print_func<FCFormat>(&SUNF::fc_print))
387 GiNaC::registered_class_info & SUNF::get_class_info_static() { return reg_info; }
389 SUNF * SUNF::duplicate() const { SUNF * bp = new SUNF(*this); bp->setflag(GiNaC::status_flags::dynallocated); return bp; }
390 void SUNF::accept(GiNaC::visitor & v) const { if (visitor *p = dynamic_cast<visitor *>(&v)) p->visit(*this); else inherited::accept(v); }
391 const GiNaC::registered_class_info &SUNF::get_class_info() const { return get_class_info_static(); }
392 GiNaC::registered_class_info &SUNF::get_class_info() { return get_class_info_static(); }
393 const char *SUNF::class_name() const { return get_class_info_static().options.get_name(); }
394 //GINAC_IMPLEMENT_REGISTERED_CLASS END
395
396 SUNF::SUNF(ex i, ex j, ex k) : ijk{i,j,k} { }
397 int SUNF::compare_same_type(const basic &other) const {
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]);
402 if(c!=0) return c;
403 }
404 return 0;
405 }
406
407 bool SUNF::is_equal_same_type(const basic & other) const {
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;
412 }
413 return true;
414 }
415
416 ex SUNF::eval() const {
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;
419 bool c01 = ex_less(ijk[0],ijk[1]);
420 bool c12 = ex_less(ijk[1],ijk[2]);
421 if(c01 && c12) return this->hold();
422 bool c02 = ex_less(ijk[0],ijk[2]);
423 if(!c01 && c02) return -SUNF(ijk[1],ijk[0],ijk[2]);
424 else if(c02 && !c12) return -SUNF(ijk[0],ijk[2],ijk[1]);
425 else if(!c02 && c01) return SUNF(ijk[2],ijk[0],ijk[1]);
426 else if(c12 && !c02) return SUNF(ijk[1],ijk[2],ijk[0]);
427 else if(!c12 && !c01) return -SUNF(ijk[2],ijk[1],ijk[0]);
428 else return this->hold();
429 }
430
431 void SUNF::print(const print_dflt &c, unsigned) const {
432 c.s << "f(" << ijk[0] << "," << ijk[1] << "," << ijk[2] << ")";
433 }
434
435 void SUNF::form_print(const FormFormat &c, unsigned) const {
436 c << "f(" << ijk[0] << "," << ijk[1] << "," << ijk[2] << ")";
437 }
438
439 void SUNF::fc_print(const FCFormat &c, unsigned) const {
440 c << "SUNF[" << ijk[0] << "," << ijk[1] << "," << ijk[2] << "]";
441 }
442
443 size_t SUNF::nops() const { return 3; }
444 ex SUNF::op(size_t i) const {
445 return ijk[i];
446 }
447 ex & SUNF::let_op(size_t i) {
448 ensure_if_modifiable();
449 return ijk[i];
450 }
451
452 void SUNF::archive(archive_node & n) const {
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]);
457 }
458
459 void SUNF::read_archive(const archive_node& n) {
460 inherited::read_archive(n);
461 ex o;
462 n.find_ex("i", o);
463 ijk[0] = ex_to<Index>(o);
464 n.find_ex("j", o);
465 ijk[1] = ex_to<Index>(o);
466 n.find_ex("k", o);
467 ijk[2] = ex_to<Index>(o);
468 }
469
475 ex SUNF::derivative(const symbol & s) const {
476 return 0;
477 }
478
479 //GINAC_IMPLEMENT_REGISTERED_CLASS_OPT(SUNF4, basic,print_func<print_dflt>(&SUNF4::print).print_func<FormFormat>(&SUNF4::form_print).print_func<FCFormat>(&SUNF4::fc_print))
480 GiNaC::registered_class_info & SUNF4::get_class_info_static() { return reg_info; }
482 SUNF4 * SUNF4::duplicate() const { SUNF4 * bp = new SUNF4(*this); bp->setflag(GiNaC::status_flags::dynallocated); return bp; }
483 void SUNF4::accept(GiNaC::visitor & v) const { if (visitor *p = dynamic_cast<visitor *>(&v)) p->visit(*this); else inherited::accept(v); }
484 const GiNaC::registered_class_info &SUNF4::get_class_info() const { return get_class_info_static(); }
485 GiNaC::registered_class_info &SUNF4::get_class_info() { return get_class_info_static(); }
486 const char *SUNF4::class_name() const { return get_class_info_static().options.get_name(); }
487 //GINAC_IMPLEMENT_REGISTERED_CLASS END
488
489 SUNF4::SUNF4(ex i, ex j, ex k, ex l) : ijkl{i,j,k,l} { }
490 int SUNF4::compare_same_type(const basic &other) const {
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]);
495 if(c!=0) return c;
496 }
497 return 0;
498 }
499
500 bool SUNF4::is_equal_same_type(const basic & other) const {
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;
505 }
506 return true;
507 }
508
513 ex SUNF4::eval() const {
514 if(flags & status_flags::evaluated) return *this;
515 if(ijkl[0].is_equal(ijkl[1]) || ijkl[2].is_equal(ijkl[3])) return 0;
516 bool c01 = ex_less(ijkl[0],ijkl[1]);
517 bool c23 = ex_less(ijkl[2],ijkl[3]);
518 if(c01 && c23) return this->hold(); // 01-23
519 else if(!c01 && c23) return -SUNF4(ijkl[1],ijkl[0],ijkl[2],ijkl[3]);
520 else if(!c01 && !c23) return SUNF4(ijkl[1],ijkl[0],ijkl[3],ijkl[2]);
521 else if(c01 && !c23) return -SUNF4(ijkl[0],ijkl[1],ijkl[3],ijkl[2]);
522 else return this->hold();
523 }
524
530 void SUNF4::print(const print_dflt &c, unsigned o) const {
531 c.s << "f(" << ijkl[0] << "," << ijkl[1] << "," << ijkl[2] << "," << ijkl[3] << ")";
532 }
533
534 void SUNF4::fc_print(const FCFormat &c, unsigned o) const {
535 c << "SUNF[" << ijkl[0] << "," << ijkl[1] << "," << ijkl[2] << "," << ijkl[3] << "]";
536 }
537
543 void SUNF4::form_print(const FormFormat &c, unsigned o) const {
544 c << "f4(" << ijkl[0] << "," << ijkl[1] << "," << ijkl[2] << "," << ijkl[3] << ")";
545 }
546
547 size_t SUNF4::nops() const { return 4; }
548 ex SUNF4::op(size_t i) const {
549 return ijkl[i];
550 }
551 ex & SUNF4::let_op(size_t i) {
552 ensure_if_modifiable();
553 return ijkl[i];
554 }
555
560 void SUNF4::archive(archive_node & n) const {
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]);
566 }
567
572 void SUNF4::read_archive(const archive_node& n) {
573 inherited::read_archive(n);
574 ex o;
575 n.find_ex("i", o);
576 ijkl[0] = ex_to<Index>(o);
577 n.find_ex("j", o);
578 ijkl[1] = ex_to<Index>(o);
579 n.find_ex("k", o);
580 ijkl[2] = ex_to<Index>(o);
581 n.find_ex("l", o);
582 ijkl[3] = ex_to<Index>(o);
583 }
584
590 ex SUNF4::derivative(const symbol & s) const {
591 return 0;
592 }
593
594 ex ncmul_expand(const ex & expr) {
595 MapFunction inner_expand([](const ex & e, MapFunction & self)->ex{
596 if(is_a<add>(e)) {
597 ex res = 0;
598 for(auto ei : e) res += ncmul_expand(ei);
599 return res;
600 } else if(is_a<mul>(e) || is_a<ncmul>(e)) {
601 lst res = lst{ 1 };
602 for(auto ei : e) {
603 ex rei = ncmul_expand(ei);
604 if(!is_a<add>(rei)) rei = lst{ rei };
605 lst ores = res;
606 res = lst{ };
607 for(auto oi : ores) for(auto ri : rei) res.append(oi * ri);
608 }
609 ex ret = 0;
610 for(auto ri : res) ret += ri;
611 return ret;
612 } else return e.map(self);
613 });
614 return inner_expand(expr);
615 }
616
622 ex GMatContract(const ex & expr_in) {
623 if(!expr_in.has(GMat(w1,w2,w3))) return expr_in;
624
625 auto expr = expr_in.subs(pow(GMat(w1,w2,w3),2)==GMat(w1,w2,w3)*GMat(w1,w3,w2));
626 auto cv_lst = collect_lst(expr, GMat(w1, w2, w3));
627 expr = 0;
628 for(auto cv : cv_lst) {
629 auto e = cv.op(1);
630 if(is_zero(e-1) || e.match(GMat(w1, w2, w3))) {
631 if(e.match(GMat(w1, w2, w2))) expr += cv.op(0) * TR(e.op(0));
632 else expr += cv.op(0) * e;
633 continue;
634 } else if(!is_a<mul>(e)) throw Error("GMatContract: collect error: " + ex2str(e));
635
636 lst mats;
637 for(auto item : e) mats.append(item);
638
639 std::map<ex,int,ex_is_less> to_map, from_map;
640 std::set<int> todo;
641 lst mats_idx;
642 for(int i=0; i<mats.nops(); i++) {
643 auto item = mats.op(i);
644 if(item.op(0).return_type()==return_types::commutative || item.op(0).is_equal(GAS(1))) {
645 mats_idx.append(lst{item,i});
646 } else {
647 if(to_map[item.op(1)]!=0 || from_map[item.op(2)]!=0) throw Error("GMatContract: index conflict for "+ex2str(item));
648 to_map[item.op(1)] = i+10; // avoid 0 in map
649 from_map[item.op(2)] = i+10; // avoid 0 in map
650 }
651 todo.insert(i);
652 }
653
654 // update to_map/from_map w.r.t mats_idx
655 bool checked = false;
656 while(true) {
657 lst mats_idx2;
658 bool ok = true; // double check
659 for(int i=0; i<mats_idx.nops(); i++) {
660 auto item = mats_idx.op(i).op(0);
661 int ii = ex_to<numeric>(mats_idx.op(i).op(1)).to_int();
662 if(!checked &&
663 to_map[item.op(1)]==0 && from_map[item.op(2)]==0 &&
664 to_map[item.op(2)]==0 && from_map[item.op(1)]==0) {
665 mats_idx2.append(mats_idx.op(i));
666 continue;
667 }
668 ok = false;
669 checked = false;
670 if(to_map[item.op(1)]==0 && from_map[item.op(2)]==0) {
671 to_map[item.op(1)] = ii+10; // avoid 0 in map
672 from_map[item.op(2)] = ii+10; // avoid 0 in map
673 } else if(to_map[item.op(2)]==0 && from_map[item.op(1)]==0) {
674 to_map[item.op(2)] = ii+10; // avoid 0 in map
675 from_map[item.op(1)] = ii+10; // avoid 0 in map
676 // need to swap the 2nd and 3rd index
677 auto li = get_op(mats, ii, 1);
678 auto ri = get_op(mats, ii, 2);
679 let_op(mats, ii, 1, ri);
680 let_op(mats, ii, 2, li);
681 } else {
682 throw Error("GMatContract: index conflict (2).");
683 }
684 }
685 if(mats_idx2.nops()<1) break;
686 mats_idx = mats_idx2;
687 if(ok) checked=true;
688 }
689
690 ex retMat = 1;
691 while(todo.size()>0) {
692 int c = *(todo.begin());
693 todo.erase(c);
694 ex curMat = mats.op(c).op(0);
695 auto li=mats.op(c).op(1);
696 auto ri=mats.op(c).op(2);
697 while(true) {
698 if(li.is_equal(ri)) {
699 retMat *= TR(curMat);
700 break;
701 }
702 int ti = to_map[ri];
703 int fi = from_map[li];
704 if(ti==0 && fi==0) {
705 retMat *= GMat(curMat, li, ri);
706 break;
707 }
708 if(ti!=0) {
709 auto mat = mats.op(ti-10).op(0);
710 if(curMat.is_equal(GAS(1))) curMat = mat;
711 else if(!mat.is_equal(GAS(1))) curMat = curMat * mat;
712 ri = mats.op(ti-10).op(2);
713 todo.erase(ti-10);
714 continue;
715 }
716 if(fi!=0) {
717 auto mat = mats.op(fi-10).op(0);
718 if(curMat.is_equal(GAS(1))) curMat = mat;
719 else if(!mat.is_equal(GAS(1))) curMat = mat * curMat;
720 li = mats.op(fi-10).op(1);
721 todo.erase(fi-10);
722 continue;
723 }
724 }
725 }
726 expr += cv.op(0) * retMat;
727 }
728
729 return expr;
730 }
731
732 ex Contract(const ex & ei) {
733 lst idx_lst;
734 MapFunction get_idx([&idx_lst](const ex & e, MapFunction & self)->ex{
735 if(!Index::has(e) || !Pair::has(e) || e.match(GMat(w1,w2,w3))) return 1; // skip GMat object
736 else if(is_a<Pair>(e)) {
737 if(is_a<Index>(e.op(0)) || is_a<Index>(e.op(1))) idx_lst.append(e);
738 return 1;
739 } else return e.map(self);
740 });
741 get_idx(ei);
742 idx_lst.sort();
743 idx_lst.unique();
744 if(idx_lst.nops()==0) return ei;
745 auto cvs = collect_lst(ei, idx_lst);
746 ex res = 0;
747 for(auto cv : cvs) {
748 auto c = cv.op(0);
749 auto v = form(cv.op(1)); // contract on itself
750 if(!Index::has(v)) res += c * v;
751 else {
752 if(!is_a<mul>(v)) v = lst{ v };
753 exmap repl;
754 ex r = 1; // uncontracted remained index
755 for(auto vi : v) {
756 if(!is_a<Pair>(vi)) r *= vi; // contract may result in a non-Pair object
757 else if(is_a<Index>(vi.op(1)) && c.has(vi.op(1))) repl[vi.op(1)] = vi.op(0);
758 else if(is_a<Index>(vi.op(0)) && c.has(vi.op(0))) repl[vi.op(0)] = vi.op(1);
759 else r *= vi;
760 }
761 res += r * c.subs(repl);
762 }
763 }
764 return res.subs(SP_map);
765 }
766
767 ex GMatOut(const ex & expr_in) {
768 MapFunction inner_out([&](const ex & e, MapFunction & self)->ex {
769 if(e.match(GMat(w1,w2,w3))) {
770 auto e0 = e.op(0);
771 if(is_a<mul>(e0)) {
772 ex c = 1, v = 1;
773 for(auto item : e0) {
774 if(item.return_type()==return_types::commutative) c *= item;
775 else {
776 if(!v.is_equal(1)) {
777 cout << "c=" << c << ", " << "v=" << v << endl;
778 throw Error("GMatOut: v != 1"); // make sure only one non-commutative object
779 }
780 v = item;
781 }
782 }
783 if(v.is_equal(1)) v = GAS(1);
784 return c * GMatOut(GMat(v, e.op(1), e.op(2)));
785 } else return e;
786 } else return e.map(self);
787 });
788 return inner_out(expr_in);
789 }
790
791 ex GMatExpand(const ex & expr_in) {
792 MapFunction inner_expand([&](const ex & e, MapFunction & self)->ex {
793 if(!e.has(GMat(w1,w2,w3))) return e;
794 else if(e.match(GMat(w1,w2,w3))) {
795 auto e0 = e.op(0);
796 if(is_a<add>(e0)) {
797 ex res = 0;
798 for(auto item : e0) res += GMatExpand(GMat(item, e.op(1), e.op(2)));
799 return res;
800 } else if(is_a<mul>(e0)) {
801 ex c = 1, v = 1;
802 for(auto item : e0) {
803 if(item.return_type()==return_types::commutative) c *= item;
804 else {
805 if(!v.is_equal(1)) {
806 cout << "c=" << c << ", " << "v=" << v << endl;
807 throw Error("GMatExpand: v != 1"); // make sure only one non-commutative object
808 }
809 v = item;
810 }
811 }
812 if(v.is_equal(1)) v = GAS(1);
813 return c * GMatExpand(GMat(v, e.op(1), e.op(2)));
814 } else if(is_a<ncmul>(e0)) { // expand ncmul
815 ex res;
816 bool first = true;
817 for(auto item : e0) {
818 if(first) {
819 res = item;
820 first = false;
821 continue;
822 }
823 ex ncL = res; // previous result
824 if(!is_a<add>(ncL)) ncL = lst{ ncL };
825 ex ncR = item;
826 if(!is_a<add>(ncR)) ncR = lst{ ncR };
827 res = 0; // current result
828 for(auto iL : ncL) for(auto iR : ncR) res += iL * iR;
829 }
830 ex rs = res;
831 res = 0;
832 if(!is_a<add>(rs)) rs = lst{ rs };
833 for(auto item : rs) { // pull out commutative coefficient
834 ex c = 1, v = 1;
835 if(is_a<mul>(item)) {
836 if(item.nops()==1) throw Error("GMatExpand: item.nops == 1"); // make sure
837 for(auto it : item) {
838 if(it.return_type()==return_types::commutative) c *= it;
839 else {
840 if(!v.is_equal(1)) throw Error("GMatExpand: v != 1"); // make sure only one non-commutative object
841 v = it;
842 }
843 }
844 } else v = item;
845
846 while(true) { // recursive replace ɣ.P * ɣ.P -> P^2 and ɣ.mu * ɣ.mu -> d @ v
847 bool to_exit = true;
848 if(is_a<ncmul>(v)) {
849 bool first = true;
850 ex last = 1, vv = 1;
851 for(auto vi : v) {
852 if(first) {
853 first = false;
854 last = vi;
855 } else {
856 if(last==vi && is_a<DGamma>(vi)) {
857 first = true;
858 last = 1;
859 if(is_a<Vector>(vi.op(0))) c *= SP(vi.op(0));
860 else if(is_a<Index>(vi.op(0))) c *= d;
861 else if(vi.op(0).is_equal(1) || vi.op(0).is_equal(5)) c *= 1; // GAS(1)*GAS(1) = GAS(5)*GAS(5) = 1
862 else throw Error("GMatExpand: only GAS(i/p/1/5) supported.");
863 to_exit = false; // need to cycle again
864 } else {
865 if(last!=GAS(1) && !last.is_equal(1)) vv = vv * last;
866 last = vi;
867 }
868 }
869 }
870 if(!last.is_equal(1) && last!=GAS(1)) v = vv * last; // check last item
871 else v = vv;
872 }
873 if(to_exit) break;
874 }
875 if(v.is_equal(1)) v = GAS(1); // identity matrix
876 res += c * GMat(v, e.op(1), e.op(2));
877 }
878 return res;
879 } else return e;
880 } else return e.map(self);
881 });
882 return inner_expand(expr_in);
883 }
884
885 ex GMatShift(const ex & expr, const ex & g, bool to_right) {
886 if(!expr.has(g)) return expr;
887 MapFunction inner_shift([g,to_right](const ex & e, MapFunction & self)->ex{
888 if(!e.has(g) || !e.has(GMat(w1,w2,w3))) return e;
889 else if(e.match(GMat(w1,w2,w3))) {
890 ex eg = e.op(0);
891 if(!is_a<ncmul>(eg)) eg = lst{ eg };
892 int gi = -1;
893 if(to_right) {
894 for(int i=0; i<eg.nops()-1; i++) if(eg.op(i)==g) { gi = i; break; }
895 if(gi==-1 || gi==eg.nops()-1) return e;
896 } else {
897 for(int i=eg.nops()-1; i>=0; i--) if(eg.op(i)==g) { gi = i; break; }
898 if(gi==-1 || gi==0) return e;
899 }
900 int gj = gi + ( to_right ? 1 : -1 );
901 ex rem = 1, rem2 = 1;
902 for(int i=0; i<eg.nops(); i++) {
903 if(i!=gi && i!=gj) {
904 rem *= eg.op(i);
905 rem2 *= eg.op(i);
906 }
907 if(i==gi) {
908 if(to_right) rem2 *= eg.op(gj)*eg.op(gi);
909 else rem2 *= eg.op(gi)*eg.op(gj);
910 }
911 }
912 if(eg.op(gi).is_equal(eg.op(gj))) {
913 ex ip = eg.op(gi).op(0);
914 if(rem.is_equal(1)) rem = GAS(1);
915 ex res = GMat(rem, e.op(1), e.op(2));
916 res = GMatShift(res, g, to_right);
917 ex c;
918 if(is_a<Vector>(ip)) c = SP(ip);
919 else if(is_a<Index>(ip)) c = d;
920 else throw Error("GMatShift: only GAS(i/p) supproted.");
921 return c * res;
922 }
923 if(rem.is_equal(1)) rem = GAS(1);
924 if(rem2.is_equal(1)) rem2 = GAS(1);
925 ex res = 2*SP(eg.op(gi).op(0), eg.op(gj).op(0)) * GMat(rem, e.op(1), e.op(2));
926 res = res - GMat(rem2, e.op(1), e.op(2));
927 return GMatShift(res, g, to_right);
928 } else return e.map(self);
929 });
930 ex res = GMatExpand(Contract(expr)); // add Contract & GMatExpand here
931 res = collect_ex(res, GMat(w1,w2,w3));
932 res = inner_shift(res);
933 return res;
934 }
935
936 ex GMatSimplify(const ex & expr) {
937 ex res = GMatContract(expr);
938 res = GMatShift(res);
939 res = Contract(res);
940 return res;
941 }
942
943 namespace {
944 lst shift_12_right(const ex & e) { // return a list of {coeff, gammas}
945 if(!is_a<ncmul>(e)) throw Error("input is not a ncmul.");
946 if(e.nops()==2) {
947 ex e0 = e.op(0);
948 if(e.op(0)!=e.op(1)) throw Error("2 items are not equal!");
949 else if(is_a<Index>(e0.op(0))) return lst{ lst{ d, 1 }};
950 else if(is_a<Vector>(e0.op(0))) return lst{ lst{ SP(e.op(0).op(0)), 1 }};
951 else {
952 cout << endl << e << endl;
953 throw Error("shift_12_right: only GAS(i/p) supproted.");
954 }
955 }
956 ex rem = 1;
957 int n = e.nops();
958 for(int i=2; i<n; i++) rem *= e.op(i);
959 lst res = shift_12_right(e.op(0)*rem);
960 n = res.nops();
961 for(int i=0; i<n; i++) {
962 res.let_op(i).let_op(0) = -res.op(i).op(0);
963 res.let_op(i).let_op(1) = e.op(1) * res.op(i).op(1);
964 }
965 if(!is_a<Index>(e.op(0).op(0)) && !is_a<Vector>(e.op(0).op(0))) {
966 cout << e << endl;
967 throw Error("shift_12_right: not a Vector or Index");
968 }
969 if(!is_a<Index>(e.op(1).op(0)) && !is_a<Vector>(e.op(1).op(0))) {
970 cout << e << endl;
971 throw Error("shift_12_right: not a Vector or Index");
972 }
973 res.append(lst{ 2*SP(e.op(0).op(0), e.op(1).op(0)), rem });
974 return res;
975 }
976 }
977 ex GMatShift(const ex & expr) {
978 MapFunction inner_shift([](const ex & e, MapFunction & self)->ex{
979 if(!e.has(GMat(w1,w2,w3))) return e;
980 else if(e.match(GMat(w1,w2,w3))) {
981 ex eg = e.op(0);
982 if(!is_a<ncmul>(eg)) eg = lst{ eg };
983
984 int gi = -1, gj = -1;
985 for(int i=0; i<eg.nops(); i++) for(int j=i+1; j<eg.nops(); j++) {
986 if(eg.op(i).is_equal(eg.op(j))) {
987 gi = i;
988 gj = j;
989 goto done;
990 }
991 }
992 return e;
993 done: ;
994
995 ex exL = 1, exM=1, exR = 1;
996 for(int i=0; i<eg.nops(); i++) {
997 if(i<gi) exL *= eg.op(i);
998 else if(i>gj) exR *= eg.op(i);
999 else exM *= eg.op(i);
1000 }
1001 lst cvs = shift_12_right(exM);
1002
1003 ex res = 0;
1004 for(auto cv : cvs) {
1005 ex item = exL*cv.op(1)*exR;
1006 if(item.is_equal(1)) item = GAS(1);
1007 res += cv.op(0)*GMatShift(GMat(item, e.op(1), e.op(2)));
1008 }
1009
1010 return res;
1011 } else return e.map(self);
1012 });
1013 ex res = GMatExpand(Contract(expr)); // add Contract & GMatExpand here
1014 res = collect_ex(res, GMat(w1,w2,w3));
1015 res = inner_shift(res);
1016 return res;
1017 }
1018
1019 namespace {
1020 void GMat_fc_print(const ex &arg1, const ex &arg2, const ex &arg3, const print_context &c0) {
1021 auto c = static_cast<const FCFormat &>(c0);
1022 c << "GMat[" << arg1 << "," << arg2 << "," << arg3 << "]";
1023 }
1024 }
1025
1026 REGISTER_FUNCTION(GMat, do_not_evalf_params().print_func<FCFormat>(&GMat_fc_print).conjugate_func(mat_conj).set_return_type(return_types::commutative))
1027
1028 bool IsZero(const ex & e) {
1029 try {
1030 exset vs;
1031 for(const_preorder_iterator i = e.preorder_begin(); i != e.preorder_end(); ++i) {
1032 if(is_a<symbol>(*i) || is_a<Pair>(*i)) vs.insert(*i);
1033 }
1034
1035 int n = 13;
1036 for(int i=0; i<5; i++) {
1037 exmap nsubs;
1038 for(auto item : vs) {
1039 nsubs[item] = ex(1)/n_nth_prime(n);
1040 n++;
1041 }
1042 ex ret = e.subs(nsubs);
1043 if(!normal(e).is_zero()) return false;
1044 }
1045
1046 auto ret = exnormal(e);
1047 return ret.is_zero();
1048 } catch(...) { }
1049 return is_zero(exnormal(e));
1050 }
1051
1052 ex ToCF(const ex & e) {
1053 ex res = e;
1054 bool todo = true;
1055 while(todo) {
1056 todo = false;
1057 auto cvs = collect_lst(res, lst{NF,TF});
1058 res = 0;
1059 for(auto cv : cvs) {
1060 int degTF = cv.op(1).degree(TF);
1061 int degNF = cv.op(1).ldegree(NF);
1062 if(degTF>0 && degNF<0) {
1063 todo = true;
1064 int n = degTF;
1065 if(degTF+degNF>0) n = -degNF;
1066 res += cv.op(0) * cv.op(1) * pow(TF/NF,-n) * pow(TF*NF-CF,n);
1067 } else if(degTF>0 && degNF>1) {
1068 todo = true;
1069 int n = degTF;
1070 if(degTF>degNF/2) n = degNF/2;
1071 res += cv.op(0) * cv.op(1) * pow(TF*NF*NF,-n) * pow(CF*NF+TF,n);
1072 } else res += cv.op(0) * cv.op(1);
1073 }
1074 }
1075 return res;
1076 }
1077
1078 ex ca_neg_pow_sub(const ex & expr) {
1079 static MapFunction ca_map([](const ex & e, MapFunction & self)->ex {
1080 if(!e.has(CA)) return e;
1081 else if(e.match(pow(CA,w)) && e.op(1).info(info_flags::negint)) return pow(CA-2*CF,-e.op(1));
1082 else return e.map(self);
1083 });
1084 return ca_map(expr);
1085 }
1086
1087 ex ToCACF(const ex & e) { // from FeynCalc
1088 ex res = e.subs(lst{NA==(NF*NF-1),CF==(NF*NF-1)/(2*NF),TF==ex(1)/2});
1089 res = exfactor(res);
1090 // SUNN -> CA
1091 res = res.subs(NF==CA);
1092 // (-1+CA^2)->(-2 CA CF)
1093 res = res.subs(lst{ w*(1-CA)*(1+CA)==-w*2*CA*CF, w*(-1+CA)*(1+CA)==w*2*CA*CF });
1094 res = res.subs(lst{ w1*pow(1-CA,w2)*pow(1+CA,w2)==w1*pow(-2*CA*CF,w2), w1*pow(-1+CA,w2)*pow(1+CA,w2)==w1*pow(2*CA*CF,w2) });
1095 // (((2 - CA^2) CF )/CA ) ->(CF (CA - 4 CF))
1096 res = res.subs(lst{ w*(2-CA*CA)*CF/CA==w*CF*(CA-4*CF), w*(-2+CA*CA)*CF/CA==w*CF*(-CA+4*CF) });
1097 // (1-CA^2) -> (-2 CA CF)
1098 res = res.subs(lst{ w*(1-CA)*(1+CA)==-w*2*CA*CF, w*(-1+CA)*(1+CA)==w*2*CA*CF });
1099 res = res.subs(lst{ w1*pow(1-CA,w2)*pow(1+CA,w2)==-w1*pow(2*CA*CF,w2), w1*pow(-1+CA,w2)*pow(1+CA,w2)==w1*pow(2*CA*CF,w2) });
1100 // (1/CA)^n -> (CA - 2 CF)^n
1101 //res = res.subs(lst{ w/CA==w*(CA-2*CF) });
1102 res = ca_neg_pow_sub(res);
1103 // ((1 - CA^2)*(CA - 2*CF)) -> (-2*CF)
1104 res = res.subs(lst{ w*(1-CA)*(1+CA)*(CA-2*CF)==-2*w*CF, w*(-1+CA)*(1+CA)*(CA-2*CF)==2*w*CF });
1105 // (CA (CA-2 CF)) -> 1
1106 res = res.subs(lst{ w*CA*(CA-2*CF)==w, w*CA*(-CA+2*CF)==-w });
1107 res = res.subs(lst{ w1*pow(CA,w2)*pow(CA-2*CF,w2)==w1, w1*pow(CA,w2)*pow(-CA+2*CF,w2)==w*pow(-1,w2) });
1108 // (CA^2+c)(CA-2CF) -> CA+c(CA-2CF)
1109 res = res.subs(lst{ w0*(CA*CA+w1)*(CA-2*CF)==w0*(CA+w1*(CA-2*CF)), w0*(CA*CA+w1)*(-CA+2*CF)==-w0*(CA+w1*(CA-2*CF)) });
1110 res = res.subs(lst{ w0*(CA*CA+w1)*pow(CA-2*CF,w2)==w0*(CA+w1*(CA-2*CF))*pow(CA-2*CF,w2-1), w0*(CA*CA+w1)*pow(-CA+2*CF,w2)==-w0*(CA+w1*(CA-2*CF))*pow(-CA+2*CF,w2-1) });
1111 return res;
1112 }
1113
1114 ex HomCACF(const ex & e) {
1115 ex res = e.subs(lst{NA==(NF*NF-1),CA==NF,CF==(NF*NF-1)/(2*NF),TF==ex(1)/2});
1116 res = exfactor(res);
1117 if(!is_a<mul>(res)) res = lst{ res };
1118 ex c=1, v=1;
1119 for(auto item : res) {
1120 if(item.has(NF)) c *= item;
1121 else v *= item;
1122 }
1123 c = collect_ex(c, NF);
1124 int deg = c.degree(NF);
1125 int ldeg = -c.ldegree(NF);
1126 if(ldeg>deg) deg = ldeg;
1127 if(deg>0) {
1128 lst vars;
1129 ex eqn = c;
1130 for(int i=0; i<=deg; i++) {
1131 symbol xi;
1132 eqn -= xi * pow(NF,i) * pow((NF*NF-1)/(2*NF), deg-i);
1133 vars.append(xi);
1134 }
1135 eqn = collect_ex(eqn, NF);
1136 int nH = eqn.degree(NF);
1137 int nL = eqn.ldegree(NF);
1138 lst eqns;
1139 for(int i=nL; i<=nH; i++) {
1140 ex cc = eqn.coeff(NF, i);
1141 if(cc.is_zero()) continue;
1142 eqns.append(cc==0);
1143 }
1144 auto sol = lsolve(eqns, vars);
1145 if(sol.nops()!=deg+1) {
1146 cout << "c=" << c << endl;
1147 cout << "sol=" << sol << endl;
1148 throw Error("HomCACF: no solution found!");
1149 }
1150 c = 0;
1151 for(int i=0; i<=deg; i++) c += vars.op(i).subs(sol) * pow(CA,i) * pow(CF, deg-i);
1152 }
1153 return c * v;
1154 }
1155
1156 ex DoColor(const ex & expr, const ex & pref, int method) {
1157 auto cvs = collect_lst(expr, [](const ex &e)->bool{ return Index::hasc(e); });
1158 ex res = 0;
1159 for(auto const & cv : cvs) {
1160 auto cc = cv.op(0);
1161 auto vv = cv.op(1);
1162 if(method==0) vv = HomCACF(form(vv)/pref)*pref;
1163 else vv = ToCACF(form(vv)/pref)*pref;
1164 res += cc * vv;
1165 }
1166 return res;
1167 }
1168}
1169
int * a
#define IMPLEMENT_HAS(classname)
Definition BASIC.h:24
#define DEFAULT_CTOR(classname)
Definition BASIC.h:21
#define IMPLEMENT_ALL(classname)
Definition BASIC.h:30
HEP header file.
static bool has(const ex &e)
class used to wrap error message
Definition BASIC.h:242
class for FCFormat Output
Definition HEP.h:71
static void ncmul_print(const ncmul &p, const FCFormat &c, unsigned level=0)
Definition Basic.cpp:163
FCFormat(ostream &os, unsigned opt=0)
Definition Basic.cpp:66
const FCFormat & operator<<(const T &v) const
Definition HEP.h:77
class for FormFormat Output
Definition HEP.h:44
static void power_print(const power &p, const FormFormat &c, unsigned level=0)
Definition Basic.cpp:55
const FormFormat & operator<<(const T &v) const
Definition HEP.h:50
FormFormat(ostream &os, unsigned opt=0)
Definition Basic.cpp:34
class for index object
Definition HEP.h:104
int compare_same_type(const GiNaC::basic &other) const override
Definition Basic.cpp:181
const char * class_name() const override
Definition Basic.cpp:177
static bool hasv(const ex &e)
Definition Basic.cpp:234
void archive(archive_node &n) const override
Definition Basic.cpp:208
bool is_equal_same_type(const basic &other) const override
Definition Basic.cpp:190
static GiNaC::registered_class_info & get_class_info_static()
Definition Basic.cpp:171
Symbol name
Definition HEP.h:133
Type type
Definition HEP.h:134
void print(const print_context &c, unsigned level=0) const
Definition Basic.cpp:196
void read_archive(const archive_node &n) override
Definition Basic.cpp:214
static bool hasc(const ex &e)
Definition Basic.cpp:228
ex derivative(const symbol &s) const override
Definition Basic.cpp:224
const GiNaC::registered_class_info & get_class_info() const override
Definition Basic.cpp:175
Pair operator()(const Index &i)
Definition Basic.cpp:200
void accept(GiNaC::visitor &v) const override
Definition Basic.cpp:174
Index * duplicate() const override
Definition Basic.cpp:173
static bool has(const ex &e)
class to wrap map_function of GiNaC
Definition BASIC.h:632
class for Pair object
Definition HEP.h:322
static bool has(const ex &e)
class for SUNF4 object
Definition HEP.h:278
void archive(archive_node &n) const override
save to archvie
Definition Basic.cpp:560
static GiNaC::registered_class_info & get_class_info_static()
Definition Basic.cpp:480
void form_print(const FormFormat &c, unsigned level=0) const
print the Form Format
Definition Basic.cpp:543
void accept(GiNaC::visitor &v) const override
Definition Basic.cpp:483
const GiNaC::registered_class_info & get_class_info() const override
Definition Basic.cpp:484
size_t nops() const override
Definition Basic.cpp:547
void fc_print(const FCFormat &c, unsigned level=0) const
Definition Basic.cpp:534
void print(const print_dflt &c, unsigned level=0) const
normal priint
Definition Basic.cpp:530
ex op(size_t i) const override
Definition Basic.cpp:548
ex & let_op(size_t i) override
Definition Basic.cpp:551
SUNF4 * duplicate() const override
Definition Basic.cpp:482
ex ijkl[4]
Definition HEP.h:303
ex eval() const override
automatical evaluation of SUNF4
Definition Basic.cpp:513
ex derivative(const symbol &s) const override
set derivative of SUNF4 to 0
Definition Basic.cpp:590
bool is_equal_same_type(const basic &other) const override
Definition Basic.cpp:500
const char * class_name() const override
Definition Basic.cpp:486
void read_archive(const archive_node &n) override
read from archive
Definition Basic.cpp:572
int compare_same_type(const GiNaC::basic &other) const override
Definition Basic.cpp:490
class for SUNF object
Definition HEP.h:233
void archive(archive_node &n) const override
Definition Basic.cpp:452
void print(const print_dflt &c, unsigned level=0) const
Definition Basic.cpp:431
const char * class_name() const override
Definition Basic.cpp:393
int compare_same_type(const GiNaC::basic &other) const override
Definition Basic.cpp:397
ex derivative(const symbol &s) const override
set derivative of SUNF to 0
Definition Basic.cpp:475
bool is_equal_same_type(const basic &other) const override
Definition Basic.cpp:407
void form_print(const FormFormat &c, unsigned level=0) const
Definition Basic.cpp:435
static GiNaC::registered_class_info & get_class_info_static()
Definition Basic.cpp:387
ex & let_op(size_t i) override
Definition Basic.cpp:447
SUNF * duplicate() const override
Definition Basic.cpp:389
ex eval() const override
Definition Basic.cpp:416
const GiNaC::registered_class_info & get_class_info() const override
Definition Basic.cpp:391
void read_archive(const archive_node &n) override
Definition Basic.cpp:459
size_t nops() const override
Definition Basic.cpp:443
void accept(GiNaC::visitor &v) const override
Definition Basic.cpp:390
void fc_print(const FCFormat &c, unsigned level=0) const
Definition Basic.cpp:439
ex op(size_t i) const override
Definition Basic.cpp:444
ex ijk[3]
Definition HEP.h:258
class for SUNT object
Definition HEP.h:189
static GiNaC::registered_class_info & get_class_info_static()
Definition Basic.cpp:299
bool is_equal_same_type(const basic &other) const override
Definition Basic.cpp:319
ex & let_op(size_t i) override
Definition Basic.cpp:351
void archive(archive_node &n) const override
Definition Basic.cpp:356
size_t nops() const override
Definition Basic.cpp:347
void form_print(const FormFormat &c, unsigned level=0) const
Definition Basic.cpp:328
ex op(size_t i) const override
Definition Basic.cpp:348
const GiNaC::registered_class_info & get_class_info() const override
Definition Basic.cpp:303
void fc_print(const FCFormat &c, unsigned level=0) const
Definition Basic.cpp:339
void print(const print_dflt &c, unsigned level=0) const
Definition Basic.cpp:343
int compare_same_type(const GiNaC::basic &other) const override
Definition Basic.cpp:309
void read_archive(const archive_node &n) override
Definition Basic.cpp:363
SUNT * duplicate() const override
Definition Basic.cpp:301
const char * class_name() const override
Definition Basic.cpp:305
void accept(GiNaC::visitor &v) const override
Definition Basic.cpp:302
ex derivative(const symbol &s) const override
Definition Basic.cpp:374
ex aij[3]
Definition HEP.h:214
ex conjugate() const override
Definition Basic.cpp:378
class extended to GiNaC symbol class, represent a positive symbol
Definition BASIC.h:113
class for vector object
Definition HEP.h:149
Vector * duplicate() const override
Definition Basic.cpp:246
bool is_equal_same_type(const basic &other) const override
Definition Basic.cpp:263
Pair operator()(const Vector &p)
Definition Basic.cpp:273
const char * class_name() const override
Definition Basic.cpp:250
ex derivative(const symbol &s) const override
Definition Basic.cpp:294
void print(const print_context &c, unsigned level=0) const
Definition Basic.cpp:269
static GiNaC::registered_class_info & get_class_info_static()
Definition Basic.cpp:244
int compare_same_type(const GiNaC::basic &other) const override
Definition Basic.cpp:254
void read_archive(const archive_node &n) override
Definition Basic.cpp:286
void accept(GiNaC::visitor &v) const override
Definition Basic.cpp:247
void archive(archive_node &n) const override
Definition Basic.cpp:281
const GiNaC::registered_class_info & get_class_info() const override
Definition Basic.cpp:248
Symbol name
Definition HEP.h:176
HepLib namespace.
Definition BASIC.cpp:17
ex exfactor(const ex &expr_in, int opt)
factorize a expression
Definition BASIC.cpp:1854
const Symbol NA
bool ex_less(const ex &a, const ex &b)
Definition Sort.cpp:10
ex DoColor(const ex &expr, const ex &pref, int method)
Definition Basic.cpp:1156
void let_op(ex &ex_in, int index1, int index2, const ex item)
update index1-th.index2-th of expression with item
Definition BASIC.cpp:1560
ex HomCACF(const ex &e)
Definition Basic.cpp:1114
ex w0
Definition BASIC.h:499
const Symbol NF
ex GMatShift(const ex &expr, const ex &g, bool to_right)
Definition Basic.cpp:885
exmap SP_map
Definition Init.cpp:182
ex collect_ex(ex const &expr_in, std::function< bool(const ex &)> has_func, int opt)
the collect function like Mathematica
Definition BASIC.cpp:1202
ex GMatSimplify(const ex &expr)
Definition Basic.cpp:936
ex GAS(const ex &expr, unsigned rl)
function similar to GAD/GSD in FeynClac
Definition DGamma.cpp:257
ex GMatExpand(const ex &expr_in)
Definition Basic.cpp:791
ex Contract(const ex &ei)
Definition Basic.cpp:732
ex w
Definition Init.cpp:93
const Symbol vs
const Symbol d
ex get_op(const ex ex_in, int index1, int index2)
return index1-th.index2-th of expression
Definition BASIC.cpp:1606
ex ToCACF(const ex &e)
Definition Basic.cpp:1087
ex GMatOut(const ex &expr_in)
Definition Basic.cpp:767
const Symbol CA
const Symbol TF
ex exnormal(const ex &expr, int opt)
normalize a expression
Definition BASIC.cpp:1916
const Symbol CF
const Symbol as
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}, ... }
Definition BASIC.cpp:1222
ex ToCF(const ex &e)
Definition Basic.cpp:1052
string ex2str(const ex &expr)
convert ex to output string, the defalut printer format will be used
Definition BASIC.cpp:715
bool IsZero(const ex &e)
const Symbol nL
const Symbol nH
ex w1
Definition BASIC.h:499
ex w3
Definition BASIC.h:499
ex ncmul_expand(const ex &expr)
Definition Basic.cpp:594
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)
Definition Basic.cpp:1026
ex w2
Definition BASIC.h:499
ex form(const ex &iexpr, int verb)
evalulate expr in form program, see also the form_trace_mode and form_expand_mode
Definition Form.cpp:563
ex GMatContract(const ex &expr_in)
make contract on matrix, i.e., GMat(a,i1,i2)*GMat(b,i2,i3) -> GMat(a*b,i1,i3)
Definition Basic.cpp:622
ex SP(const ex &a, bool use_map=false)
Definition Pair.cpp:166
ex ca_neg_pow_sub(const ex &expr)
Definition Basic.cpp:1078