11 inline int perm_sign(
int perm[],
int n) {
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;
37 return make_return_type_t<clifford>(
rl);
51 if(!is_a<AsGamma>(other))
throw Error(
"AsGamma::compare_same_type");
53 if (
rl != o.
rl)
return rl < o.
rl ? -1 : 1;
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]);
65 if(!is_a<AsGamma>(other))
throw Error(
"AsGamma::is_equal_same_type");
67 if (
rl != o.
rl)
return false;
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;
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);
86 for(
int i=0; i<n; i++)
if(pis_sort[i] !=
pis[i])
throw Error(
"Error: Input list is NOT sorted.");
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);
96 for(
int i=0; i<n; i++)
if(pis_sort[i] !=
pis[i])
throw Error(
"Error: Input list is NOT sorted.");
104 ensure_if_modifiable();
109 if(flags & status_flags::evaluated)
return *
this;
115 int n2 = pis_sort.nops();
118 std::map<ex,int,ex_is_less> e2i;
119 for(
int i=0; i<n; i++) e2i[
pis[i]] = i;
121 for(
int i=0; i<n; i++) si[i] = e2i[pis_sort.op(i)];
124 for(
int i=0; i<n; i++)
if(pis_sort.op(i)!=
pis[i]) {
128 if(ok)
return this->hold();
131 return perm_sign(si, n) * ag;
139 if(first) first=
false;
147 throw Error(
"AsGamma::form_print unexpected region.");
151 throw Error(
"AsGamma::fc_print unexpected region.");
155 inherited::archive(n);
156 n.add_unsigned(
"rl",
rl);
158 n.add_ex(
"size", nn);
159 for(
int i=0; i<nn; i++) n.add_ex(
"pis"+to_string(i),
pis[i]);
163 inherited::read_archive(n);
164 n.find_unsigned(
"rl",
rl);
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]);
179 throw Error(
"AsGamma::conjugate unexpected region.");
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);
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).");
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;
199 for(
int i=0; i<n; i++) si[i] = e2i[pis_sort.op(i)];
203 return perm_sign(si, n) * ag;
208 if(n==0)
return GAS(1,
rl);
210 for(
int i=0; i<n; i++) pn[i] = i;
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));
219 return res/factorial(n);
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");
230 for(
int r=0; r<n; r++) {
232 for(
int i=0; i<n; i++) {
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");
249 for(
int r=0; r<n; r++) {
251 for(
int i=0; i<n; i++) {
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");
266 else if(is_a<AsGamma>(e)) {
267 return ex_to<AsGamma>(e).mul_right(pi_in);
268 }
else return e.map(self);
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");
279 else if(is_a<AsGamma>(e)) {
280 return ex_to<AsGamma>(e).mul_left(pi_in);
281 }
else return e.map(self);
289 else if(is_a<AsGamma>(e)) {
290 return ex_to<AsGamma>(e).to();
291 }
else return e.map(self);
#define IMPLEMENT_HAS(classname)
#define DEFAULT_CTOR(classname)
#define IMPLEMENT_ALL(classname)
class for AntiSymmetric Gamma object
bool match_same_type(const basic &other) const override
void archive(archive_node &n) const override
AsGamma * duplicate() const override
int compare_same_type(const GiNaC::basic &other) const override
ex mul_right(const ex &pi) const
ex conjugate() const override
const char * class_name() const override
ex op(size_t i) const override
void read_archive(const archive_node &n) override
ex derivative(const symbol &s) const override
const GiNaC::registered_class_info & get_class_info() const override
void form_print(const FormFormat &c, unsigned level=0) const
return_type_t return_type_tinfo() const override
void accept(GiNaC::visitor &v) const override
static ex from(const lst &pis_lst, unsigned rl=0)
void fc_print(const FCFormat &c, unsigned level=0) const
size_t nops() const override
static GiNaC::registered_class_info & get_class_info_static()
ex mul_left(const ex &pi) const
void print(const print_dflt &c, unsigned level=0) const
bool is_equal_same_type(const basic &other) const override
ex & let_op(size_t i) override
static bool has(const ex &e)
class used to wrap error message
class to wrap map_function of GiNaC
ex AsGamma_mul_right(const ex &expr, const ex &pi_in)
ex AsGamma_mul_left(const ex &expr, const ex &pi_in)
ex AsGamma_to(const ex &expr)
ex GAS(const ex &expr, unsigned rl)
function similar to GAD/GSD in FeynClac
ex GMatExpand(const ex &expr_in)
exvector lst2vec(const lst &alst)
convert lst to exvector
lst vec2lst(const exvector &ev)
convert exvector to lst
ex SP(const ex &a, bool use_map=false)