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;
143 if(first) first=
false;
151 throw Error(
"AsGamma::form_print unexpected region.");
155 throw Error(
"AsGamma::fc_print unexpected region.");
159 inherited::archive(n);
160 n.add_unsigned(
"rl",
rl);
162 n.add_ex(
"size", nn);
163 for(
int i=0; i<nn; i++) n.add_ex(
"pis"+to_string(i),
pis[i]);
167 inherited::read_archive(n);
168 n.find_unsigned(
"rl",
rl);
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]);
183 throw Error(
"AsGamma::conjugate unexpected region.");
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);
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).");
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;
203 for(
int i=0; i<n; i++) si[i] = e2i[pis_sort.op(i)];
207 return perm_sign(si, n) * ag;
212 if(n==0)
return GAS(1,
rl);
214 for(
int i=0; i<n; i++)
pn[i] = i;
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));
223 return res/factorial(n);
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");
234 for(
int r=0; r<n; r++) {
236 for(
int i=0; i<n; i++) {
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");
253 for(
int r=0; r<n; r++) {
255 for(
int i=0; i<n; i++) {
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");
270 else if(is_a<AsGamma>(e)) {
271 return ex_to<AsGamma>(e).mul_right(pi_in);
272 }
else return e.map(self);
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");
283 else if(is_a<AsGamma>(e)) {
284 return ex_to<AsGamma>(e).mul_left(pi_in);
285 }
else return e.map(self);
293 else if(is_a<AsGamma>(e)) {
294 return ex_to<AsGamma>(e).to();
295 }
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)