HepLib
Loading...
Searching...
No Matches
AsGamma.cpp
Go to the documentation of this file.
1
6#include "HEP.h"
7
8namespace HepLib {
9
10 namespace {
11 inline int perm_sign(int perm[], int n) {
12 int cnt = 0;
13 // 计算逆序对的数量
14 for (int i = 0; i < n; ++i) for (int j = i + 1; j < n; ++j) if (perm[i] > perm[j]) cnt++;
15 return (cnt % 2 == 0) ? 1 : -1;
16 }
17 }
18
19 //-----------------------------------------------------------
20 // AsGamma Class
21 //-----------------------------------------------------------
22 //GINAC_IMPLEMENT_REGISTERED_CLASS_OPT(AsGamma, basic,print_func<print_dflt>(&AsGamma::print).print_func<FormFormat>(&AsGamma::form_print).print_func<FCFormat>(&AsGamma::fc_print))
23 GiNaC::registered_class_info & AsGamma::get_class_info_static() { return reg_info; }
25 AsGamma * AsGamma::duplicate() const { AsGamma * bp = new AsGamma(*this); bp->setflag(GiNaC::status_flags::dynallocated); return bp; }
26 void AsGamma::accept(GiNaC::visitor & v) const { if (visitor *p = dynamic_cast<visitor *>(&v)) p->visit(*this); else inherited::accept(v); }
27 const GiNaC::registered_class_info &AsGamma::get_class_info() const { return get_class_info_static(); }
28 GiNaC::registered_class_info &AsGamma::get_class_info() { return get_class_info_static(); }
29 const char *AsGamma::class_name() const { return get_class_info_static().options.get_name(); }
30 //GINAC_IMPLEMENT_REGISTERED_CLASS END
31
35
36 return_type_t AsGamma::return_type_tinfo() const {
37 return make_return_type_t<clifford>(rl);
38 //return make_return_type_t<AsGamma>(rl);
39 }
40
41 bool AsGamma::match_same_type(const basic & other) const {
42 const AsGamma &o = static_cast<const AsGamma &>(other);
43 return rl == o.rl;
44 }
45
46 unsigned AsGamma::get_rl() {
47 return rl;
48 }
49
50 int AsGamma::compare_same_type(const basic &other) const {
51 if(!is_a<AsGamma>(other)) throw Error("AsGamma::compare_same_type");
52 const AsGamma &o = static_cast<const AsGamma &>(other);
53 if (rl != o.rl) return rl < o.rl ? -1 : 1;
54 int n = pis.size();
55 int no = o.pis.size();
56 if(n!=no) return n>no ? 1 : -1;
57 for(int i=0; i<n; i++) {
58 auto c = pis[i].compare(o.pis[i]);
59 if(c!=0) return c;
60 }
61 return 0;
62 }
63
64 bool AsGamma::is_equal_same_type(const basic & other) const {
65 if(!is_a<AsGamma>(other)) throw Error("AsGamma::is_equal_same_type");
66 const AsGamma &o = static_cast<const AsGamma &>(other);
67 if (rl != o.rl) return false;
68 int n = pis.size();
69 int no = o.pis.size();
70 if(n!=no) return false;
71 for(int i=0; i<n; i++) {
72 if(!pis[i].is_equal(o.pis[i])) return false;
73 }
74 return true;
75 }
76
77 AsGamma::AsGamma(const AsGamma &g, unsigned _rl) : pis(g.pis), rl(_rl) { }
78 AsGamma::AsGamma(const exvector & _pis, int _rl) : pis(_pis), rl(_rl) {
79 lst pis_sort = vec2lst(_pis);
80 int n = pis_sort.nops();
81 for(int i=0; i<n; i++) if(is_a<DGamma>(pis_sort.op(i))) {
82 pis_sort.let_op(i) = pis_sort.op(i).op(0);
83 pis[i] = pis[i].op(0);
84 }
85 pis_sort.sort();
86 for(int i=0; i<n; i++) if(pis_sort[i] != pis[i]) throw Error("Error: Input list is NOT sorted.");
87 }
88 AsGamma::AsGamma(const lst & _pis, int _rl) : pis(lst2vec(_pis)), rl(_rl) {
89 lst pis_sort = _pis;
90 int n = pis_sort.nops();
91 for(int i=0; i<n; i++) if(is_a<DGamma>(pis_sort.op(i))) {
92 pis_sort.let_op(i) = pis_sort.op(i).op(0);
93 pis[i] = pis[i].op(0);
94 }
95 pis_sort.sort();
96 for(int i=0; i<n; i++) if(pis_sort[i] != pis[i]) throw Error("Error: Input list is NOT sorted.");
97 }
98
99 size_t AsGamma::nops() const { return pis.size(); }
100 ex AsGamma::op(size_t i) const {
101 return pis[i];
102 }
103 ex & AsGamma::let_op(size_t i) {
104 ensure_if_modifiable();
105 return pis[i];
106 }
107
108 ex AsGamma::eval() const {
109 if(flags & status_flags::evaluated) return *this;
110 // make sure pis are sorted
111 lst pis_sort = vec2lst(pis);
112 pis_sort.sort();
113 pis_sort.unique();
114 int n = pis.size();
115 int n2 = pis_sort.nops();
116 if(n!=n2) return 0;
117
118 std::map<ex,int,ex_is_less> e2i;
119 for(int i=0; i<n; i++) e2i[pis[i]] = i;
120 int si[n];
121 for(int i=0; i<n; i++) si[i] = e2i[pis_sort.op(i)];
122
123 bool ok = true;
124 for(int i=0; i<n; i++) if(pis_sort.op(i)!=pis[i]) {
125 ok = false;
126 break;
127 }
128 if(ok) return this->hold();
129 else {
130 AsGamma ag(pis_sort);
131 return perm_sign(si, n) * ag;
132 }
133 }
134
135 void AsGamma::print(const print_dflt &c, unsigned level) const {
136 if(pis.size()<1) {
137 c.s << "\u0130";
138 return;
139 }
140 c.s << "\u0263[";
141 bool first = true;
142 for(auto pi : pis) {
143 if(first) first=false;
144 else c.s << ",";
145 c.s << pi;
146 }
147 c.s << "]";
148 }
149
150 void AsGamma::form_print(const FormFormat &c, unsigned level) const {
151 throw Error("AsGamma::form_print unexpected region.");
152 }
153
154 void AsGamma::fc_print(const FCFormat &c, unsigned level) const {
155 throw Error("AsGamma::fc_print unexpected region.");
156 }
157
158 void AsGamma::archive(archive_node & n) const {
159 inherited::archive(n);
160 n.add_unsigned("rl", rl);
161 int nn = pis.size();
162 n.add_ex("size", nn);
163 for(int i=0; i<nn; i++) n.add_ex("pis"+to_string(i), pis[i]);
164 }
165
166 void AsGamma::read_archive(const archive_node& n) {
167 inherited::read_archive(n);
168 n.find_unsigned("rl", rl);
169 ex nex;
170 n.find_ex("size", nex);
171 int nn = ex_to<numeric>(nex).to_int();
172 if(pis.size()!=nn) pis.resize(nn);
173 for(int i=0; i<nn; i++) {
174 n.find_ex("pis"+to_string(i), pis[i]);
175 }
176 }
177
178 ex AsGamma::derivative(const symbol & s) const {
179 return 0;
180 }
181
183 throw Error("AsGamma::conjugate unexpected region.");
184 }
185
186 ex AsGamma::from(const lst & pis_lst, unsigned rl) {
187 lst pis_sort = pis_lst;
188 int n = pis_sort.nops();
189 for(int i=0; i<n; i++) if(is_a<DGamma>(pis_sort.op(i))) pis_sort.let_op(i) = pis_sort.op(i).op(0);
190 lst tmp;
191 for(auto item : pis_sort) {
192 if(is_a<Vector>(item) || is_a<Index>(item)) tmp.append(item);
193 else if(!item.is_equal(1)) throw Error("AsGamma::from only support GAS(1/i/p)."); // 1 just to skip
194 }
195 pis_sort = tmp;
196 pis_sort.sort();
197 n = pis_sort.nops();
198
199 std::map<ex,int,ex_is_less> e2i;
200 for(int i=0; i<n; i++) e2i[pis_lst.op(i)] = i;
201 if(e2i.size()!=n) return 0; // two indices are equal
202 int si[n];
203 for(int i=0; i<n; i++) si[i] = e2i[pis_sort.op(i)];
204
205 AsGamma ag(lst2vec(pis_sort), rl);
206
207 return perm_sign(si, n) * ag;
208 }
209
210 ex AsGamma::to() const {
211 int n = pis.size();
212 if(n==0) return GAS(1, rl);
213 int pn[n];
214 for(int i=0; i<n; i++) pn[i] = i;
215
216 ex res = 0;
217 do {
218 ex gi = 1;
219 for(int i=0; i<n; i++) gi = gi * GAS(pis[pn[i]], rl);
220 res += perm_sign(pn, n) * gi;
221 } while (std::next_permutation(pn, pn+n));
222
223 return res/factorial(n);
224 }
225
226 ex AsGamma::mul_right(const ex & pi_in) const {
227 ex pi = pi_in;
228 if(is_a<DGamma>(pi)) pi = pi.op(0);
229 if(!is_a<Vector>(pi) && !is_a<Index>(pi)) throw Error("AsGamma::mul_right, argument should be DGamma/Index/Vector");
230 lst pis2 = vec2lst(pis);
231 pis2.append(pi);
232 ex res = AsGamma::from(pis2, rl);
233 int n = pis.size();
234 for(int r=0; r<n; r++) {
235 lst pis3;
236 for(int i=0; i<n; i++) {
237 if(i==r) continue;
238 pis3.append(pis[i]);
239 }
240 res += ((n-r-1)%2==0 ? 1 : -1) * SP(pis[r], pi) * AsGamma::from(pis3, rl);
241 }
242 return res;
243 }
244
245 ex AsGamma::mul_left(const ex & pi_in) const {
246 ex pi = pi_in;
247 if(is_a<DGamma>(pi)) pi = pi.op(0);
248 if(!is_a<Vector>(pi) && !is_a<Index>(pi)) throw Error("AsGamma::mul_left, argument should be DGamma/Index/Vector");
249 lst pis2 = vec2lst(pis);
250 pis2.prepend(pi);
251 ex res = AsGamma::from(pis2, rl);
252 int n = pis.size();
253 for(int r=0; r<n; r++) {
254 lst pis3;
255 for(int i=0; i<n; i++) {
256 if(i==r) continue;
257 pis3.append(pis[i]);
258 }
259 res += (r%2==0 ? 1 : -1) * SP(pis[r], pi) * AsGamma::from(pis3, rl);
260 }
261 return res;
262 }
263
264 ex AsGamma_mul_right(const ex & expr, const ex & pi_in) {
265 ex pi = pi_in;
266 if(is_a<DGamma>(pi)) pi = pi.op(0);
267 if(!is_a<Vector>(pi) && !is_a<Index>(pi)) throw Error("AsGamma_mul_left: argument should be DGamma/Index/Vector");
268 auto to_sub = MapFunction([pi_in](const ex & e, MapFunction &self)->ex{
269 if(!AsGamma::has(e)) return e;
270 else if(is_a<AsGamma>(e)) {
271 return ex_to<AsGamma>(e).mul_right(pi_in);
272 } else return e.map(self);
273 });
274 return to_sub(expr);
275 }
276
277 ex AsGamma_mul_left(const ex & expr, const ex & pi_in) {
278 ex pi = pi_in;
279 if(is_a<DGamma>(pi)) pi = pi.op(0);
280 if(!is_a<Vector>(pi) && !is_a<Index>(pi)) throw Error("AsGamma_mul_left: argument should be DGamma/Index/Vector");
281 auto to_sub = MapFunction([pi_in](const ex & e, MapFunction &self)->ex{
282 if(!AsGamma::has(e)) return e;
283 else if(is_a<AsGamma>(e)) {
284 return ex_to<AsGamma>(e).mul_left(pi_in);
285 } else return e.map(self);
286 });
287 return to_sub(expr);
288 }
289
290 ex AsGamma_to(const ex & expr) {
291 auto to_sub = MapFunction([](const ex & e, MapFunction &self)->ex{
292 if(!AsGamma::has(e)) return e;
293 else if(is_a<AsGamma>(e)) {
294 return ex_to<AsGamma>(e).to();
295 } else return e.map(self);
296 });
297 return GMatExpand(to_sub(expr));
298 }
299
300}
301
#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.
int pn
Definition Others.cpp:25
class for AntiSymmetric Gamma object
Definition HEP.h:496
bool match_same_type(const basic &other) const override
Definition AsGamma.cpp:41
void archive(archive_node &n) const override
Definition AsGamma.cpp:158
AsGamma * duplicate() const override
Definition AsGamma.cpp:25
int compare_same_type(const GiNaC::basic &other) const override
Definition AsGamma.cpp:50
ex mul_right(const ex &pi) const
Definition AsGamma.cpp:226
ex conjugate() const override
Definition AsGamma.cpp:182
ex to() const
Definition AsGamma.cpp:210
const char * class_name() const override
Definition AsGamma.cpp:29
ex eval() const override
Definition AsGamma.cpp:108
ex op(size_t i) const override
Definition AsGamma.cpp:100
void read_archive(const archive_node &n) override
Definition AsGamma.cpp:166
ex derivative(const symbol &s) const override
Definition AsGamma.cpp:178
const GiNaC::registered_class_info & get_class_info() const override
Definition AsGamma.cpp:27
exvector pis
Definition HEP.h:523
void form_print(const FormFormat &c, unsigned level=0) const
Definition AsGamma.cpp:150
return_type_t return_type_tinfo() const override
Definition AsGamma.cpp:36
void accept(GiNaC::visitor &v) const override
Definition AsGamma.cpp:26
static ex from(const lst &pis_lst, unsigned rl=0)
Definition AsGamma.cpp:186
void fc_print(const FCFormat &c, unsigned level=0) const
Definition AsGamma.cpp:154
size_t nops() const override
Definition AsGamma.cpp:99
unsigned get_rl()
Definition AsGamma.cpp:46
static GiNaC::registered_class_info & get_class_info_static()
Definition AsGamma.cpp:23
unsigned rl
Definition HEP.h:524
ex mul_left(const ex &pi) const
Definition AsGamma.cpp:245
void print(const print_dflt &c, unsigned level=0) const
Definition AsGamma.cpp:135
bool is_equal_same_type(const basic &other) const override
Definition AsGamma.cpp:64
ex & let_op(size_t i) override
Definition AsGamma.cpp:103
static bool has(const ex &e)
class used to wrap error message
Definition BASIC.h:242
class for FCFormat Output
Definition HEP.h:71
class for FormFormat Output
Definition HEP.h:44
class to wrap map_function of GiNaC
Definition BASIC.h:632
HepLib namespace.
Definition BASIC.cpp:17
ex AsGamma_mul_right(const ex &expr, const ex &pi_in)
Definition AsGamma.cpp:264
ex AsGamma_mul_left(const ex &expr, const ex &pi_in)
Definition AsGamma.cpp:277
ex AsGamma_to(const ex &expr)
Definition AsGamma.cpp:290
ex GAS(const ex &expr, unsigned rl)
function similar to GAD/GSD in FeynClac
Definition DGamma.cpp:281
ex GMatExpand(const ex &expr_in)
Definition Basic.cpp:810
exvector lst2vec(const lst &alst)
convert lst to exvector
Definition BASIC.cpp:911
lst vec2lst(const exvector &ev)
convert exvector to lst
Definition BASIC.cpp:902
ex SP(const ex &a, bool use_map=false)
Definition Pair.cpp:166