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 c.s << "\u0263[";
137 bool first = true;
138 for(auto pi : pis) {
139 if(first) first=false;
140 else c.s << ",";
141 c.s << pi;
142 }
143 c.s << "]";
144 }
145
146 void AsGamma::form_print(const FormFormat &c, unsigned level) const {
147 throw Error("AsGamma::form_print unexpected region.");
148 }
149
150 void AsGamma::fc_print(const FCFormat &c, unsigned level) const {
151 throw Error("AsGamma::fc_print unexpected region.");
152 }
153
154 void AsGamma::archive(archive_node & n) const {
155 inherited::archive(n);
156 n.add_unsigned("rl", rl);
157 int nn = pis.size();
158 n.add_ex("size", nn);
159 for(int i=0; i<nn; i++) n.add_ex("pis"+to_string(i), pis[i]);
160 }
161
162 void AsGamma::read_archive(const archive_node& n) {
163 inherited::read_archive(n);
164 n.find_unsigned("rl", rl);
165 ex nex;
166 n.find_ex("size", nex);
167 int nn = ex_to<numeric>(nex).to_int();
168 if(pis.size()!=nn) pis.resize(nn);
169 for(int i=0; i<nn; i++) {
170 n.find_ex("pis"+to_string(i), pis[i]);
171 }
172 }
173
174 ex AsGamma::derivative(const symbol & s) const {
175 return 0;
176 }
177
179 throw Error("AsGamma::conjugate unexpected region.");
180 }
181
182 ex AsGamma::from(const lst & pis_lst, unsigned rl) {
183 lst pis_sort = pis_lst;
184 int n = pis_sort.nops();
185 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);
186 lst tmp;
187 for(auto item : pis_sort) {
188 if(is_a<Vector>(item) || is_a<Index>(item)) tmp.append(item);
189 else if(!item.is_equal(1)) throw Error("AsGamma::from only support GAS(1/i/p)."); // 1 just to skip
190 }
191 pis_sort = tmp;
192 pis_sort.sort();
193 n = pis_sort.nops();
194
195 std::map<ex,int,ex_is_less> e2i;
196 for(int i=0; i<n; i++) e2i[pis_lst.op(i)] = i;
197 if(e2i.size()!=n) return 0; // two indices are equal
198 int si[n];
199 for(int i=0; i<n; i++) si[i] = e2i[pis_sort.op(i)];
200
201 AsGamma ag(lst2vec(pis_sort), rl);
202
203 return perm_sign(si, n) * ag;
204 }
205
206 ex AsGamma::to() const {
207 int n = pis.size();
208 if(n==0) return GAS(1, rl);
209 int pn[n];
210 for(int i=0; i<n; i++) pn[i] = i;
211
212 ex res = 0;
213 do {
214 ex gi = 1;
215 for(int i=0; i<n; i++) gi = gi * GAS(pis[pn[i]], rl);
216 res += perm_sign(pn, n) * gi;
217 } while (std::next_permutation(pn, pn+n));
218
219 return res/factorial(n);
220 }
221
222 ex AsGamma::mul_right(const ex & pi_in) const {
223 ex pi = pi_in;
224 if(is_a<DGamma>(pi)) pi = pi.op(0);
225 if(!is_a<Vector>(pi) && !is_a<Index>(pi)) throw Error("AsGamma::mul_right, argument should be DGamma/Index/Vector");
226 lst pis2 = vec2lst(pis);
227 pis2.append(pi);
228 ex res = AsGamma::from(pis2, rl);
229 int n = pis.size();
230 for(int r=0; r<n; r++) {
231 lst pis3;
232 for(int i=0; i<n; i++) {
233 if(i==r) continue;
234 pis3.append(pis[i]);
235 }
236 res += ((n-r-1)%2==0 ? 1 : -1) * SP(pis[r], pi) * AsGamma::from(pis3, rl);
237 }
238 return res;
239 }
240
241 ex AsGamma::mul_left(const ex & pi_in) const {
242 ex pi = pi_in;
243 if(is_a<DGamma>(pi)) pi = pi.op(0);
244 if(!is_a<Vector>(pi) && !is_a<Index>(pi)) throw Error("AsGamma::mul_left, argument should be DGamma/Index/Vector");
245 lst pis2 = vec2lst(pis);
246 pis2.prepend(pi);
247 ex res = AsGamma::from(pis2, rl);
248 int n = pis.size();
249 for(int r=0; r<n; r++) {
250 lst pis3;
251 for(int i=0; i<n; i++) {
252 if(i==r) continue;
253 pis3.append(pis[i]);
254 }
255 res += (r%2==0 ? 1 : -1) * SP(pis[r], pi) * AsGamma::from(pis3, rl);
256 }
257 return res;
258 }
259
260 ex AsGamma_mul_right(const ex & expr, const ex & pi_in) {
261 ex pi = pi_in;
262 if(is_a<DGamma>(pi)) pi = pi.op(0);
263 if(!is_a<Vector>(pi) && !is_a<Index>(pi)) throw Error("AsGamma_mul_left: argument should be DGamma/Index/Vector");
264 auto to_sub = MapFunction([pi_in](const ex & e, MapFunction &self)->ex{
265 if(!AsGamma::has(e)) return e;
266 else if(is_a<AsGamma>(e)) {
267 return ex_to<AsGamma>(e).mul_right(pi_in);
268 } else return e.map(self);
269 });
270 return to_sub(expr);
271 }
272
273 ex AsGamma_mul_left(const ex & expr, const ex & pi_in) {
274 ex pi = pi_in;
275 if(is_a<DGamma>(pi)) pi = pi.op(0);
276 if(!is_a<Vector>(pi) && !is_a<Index>(pi)) throw Error("AsGamma_mul_left: argument should be DGamma/Index/Vector");
277 auto to_sub = MapFunction([pi_in](const ex & e, MapFunction &self)->ex{
278 if(!AsGamma::has(e)) return e;
279 else if(is_a<AsGamma>(e)) {
280 return ex_to<AsGamma>(e).mul_left(pi_in);
281 } else return e.map(self);
282 });
283 return to_sub(expr);
284 }
285
286 ex AsGamma_to(const ex & expr) {
287 auto to_sub = MapFunction([](const ex & e, MapFunction &self)->ex{
288 if(!AsGamma::has(e)) return e;
289 else if(is_a<AsGamma>(e)) {
290 return ex_to<AsGamma>(e).to();
291 } else return e.map(self);
292 });
293 return GMatExpand(to_sub(expr));
294 }
295
296}
297
#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.
class for AntiSymmetric Gamma object
Definition HEP.h:492
bool match_same_type(const basic &other) const override
Definition AsGamma.cpp:41
void archive(archive_node &n) const override
Definition AsGamma.cpp:154
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:222
ex conjugate() const override
Definition AsGamma.cpp:178
ex to() const
Definition AsGamma.cpp:206
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:162
ex derivative(const symbol &s) const override
Definition AsGamma.cpp:174
const GiNaC::registered_class_info & get_class_info() const override
Definition AsGamma.cpp:27
exvector pis
Definition HEP.h:519
void form_print(const FormFormat &c, unsigned level=0) const
Definition AsGamma.cpp:146
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:182
void fc_print(const FCFormat &c, unsigned level=0) const
Definition AsGamma.cpp:150
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:520
ex mul_left(const ex &pi) const
Definition AsGamma.cpp:241
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:260
ex AsGamma_mul_left(const ex &expr, const ex &pi_in)
Definition AsGamma.cpp:273
ex AsGamma_to(const ex &expr)
Definition AsGamma.cpp:286
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:767
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