GINAC_ASSERT(is_a<indexed>(*other));
GINAC_ASSERT(is_a<diracgamma>(self->op(0)));
unsigned char rl = ex_to<clifford>(*self).get_representation_label();
+ ex dim = ex_to<idx>(self->op(1)).get_dim();
if (is_a<clifford>(*other)) {
if (ex_to<clifford>(*other).get_representation_label() != rl)
return false;
- ex dim = ex_to<idx>(self->op(1)).get_dim();
-
// gamma~mu gamma.mu = dim ONE
if (other - self == 1) {
*self = dim;
*other = _ex1;
return true;
}
+
+ } else if (is_a<symbol>(other->op(0)) && other->nops() == 2) {
+
+ // x.mu gamma~mu -> x-slash
+ *self = dirac_slash(other->op(0), dim, rl);
+ *other = _ex1;
+ return true;
}
return false;
// Stupid recursive bubble sort because we only want to swap adjacent gammas
exvector::iterator it = v.begin(), next_to_last = v.end() - 1;
- if (is_a<diracgamma5>(it->op(0)))
+ if (is_a<diracgamma5>(it->op(0)) || is_a<diracgammaL>(it->op(0)) || is_a<diracgammaR>(it->op(0)))
++it;
while (it != next_to_last) {
if (it[0].compare(it[1]) > 0) {
return res;
}
+
/** Compute a square-free factorization of a multivariate polynomial in Q[X].
*
* @param a multivariate polynomial over Q[X]
return result * lcm.inverse();
}
+
/** Compute square-free partial fraction decomposition of rational function
* a(x).
*
}
-/** Remove the common factor in the terms of a sum 'e' by calculating the GCD,
- * and multiply it into the expression 'factor' (which needs to be initialized
- * to 1, unless you're accumulating factors). */
-static ex find_common_factor(const ex & e, ex & factor)
-{
- if (is_a<add>(e)) {
-
- unsigned num = e.nops();
- exvector terms; terms.reserve(num);
- lst repl;
- ex gc;
-
- // Find the common GCD
- for (unsigned i=0; i<num; i++) {
- ex x = e.op(i).to_rational(repl);
- if (is_a<add>(x) || is_a<mul>(x)) {
- ex f = 1;
- x = find_common_factor(x, f);
- x *= f;
- }
-
- if (i == 0)
- gc = x;
- else
- gc = gcd(gc, x);
-
- terms.push_back(x);
- }
-
- if (gc.is_equal(_ex1))
- return e;
-
- // The GCD is the factor we pull out
- factor *= gc.subs(repl);
-
- // Now divide all terms by the GCD
- for (unsigned i=0; i<num; i++) {
- ex x;
-
- // Try to avoid divide() because it expands the polynomial
- ex &t = terms[i];
- if (is_a<mul>(t)) {
- for (unsigned j=0; j<t.nops(); j++) {
- if (t.op(j).is_equal(gc)) {
- exvector v; v.reserve(t.nops());
- for (unsigned k=0; k<t.nops(); k++) {
- if (k == j)
- v.push_back(_ex1);
- else
- v.push_back(t.op(k));
- }
- t = (new mul(v))->setflag(status_flags::dynallocated).subs(repl);
- goto term_done;
- }
- }
- }
-
- divide(t, gc, x);
- t = x.subs(repl);
-term_done: ;
- }
- return (new add(terms))->setflag(status_flags::dynallocated);
-
- } else if (is_a<mul>(e)) {
-
- exvector v;
- for (unsigned i=0; i<e.nops(); i++)
- v.push_back(find_common_factor(e.op(i), factor));
- return (new mul(v))->setflag(status_flags::dynallocated);
-
- } else
- return e;
-}
-
-
-/** Collect common factors in sums. This converts expressions like
- * 'a*(b*x+b*y)' to 'a*b*(x+y)'. */
-ex collect_common_factors(const ex & e)
-{
- if (is_a<add>(e) || is_a<mul>(e)) {
-
- ex factor = 1;
- ex r = find_common_factor(e, factor);
- return factor * r;
-
- } else
- return e;
-}
-
-
/*
* Normal form of rational functions
*/
}
+/** Remove the common factor in the terms of a sum 'e' by calculating the GCD,
+ * and multiply it into the expression 'factor' (which needs to be initialized
+ * to 1, unless you're accumulating factors). */
+static ex find_common_factor(const ex & e, ex & factor, lst & repl)
+{
+ if (is_a<add>(e)) {
+
+ unsigned num = e.nops();
+ exvector terms; terms.reserve(num);
+ ex gc;
+
+ // Find the common GCD
+ for (unsigned i=0; i<num; i++) {
+ ex x = e.op(i).to_rational(repl);
+
+ if (is_a<add>(x) || is_a<mul>(x)) {
+ ex f = 1;
+ x = find_common_factor(x, f, repl);
+ x *= f;
+ }
+
+ if (i == 0)
+ gc = x;
+ else
+ gc = gcd(gc, x);
+
+ terms.push_back(x);
+ }
+
+ if (gc.is_equal(_ex1))
+ return e;
+
+ // The GCD is the factor we pull out
+ factor *= gc;
+
+ // Now divide all terms by the GCD
+ for (unsigned i=0; i<num; i++) {
+ ex x;
+
+ // Try to avoid divide() because it expands the polynomial
+ ex &t = terms[i];
+ if (is_a<mul>(t)) {
+ for (unsigned j=0; j<t.nops(); j++) {
+ if (t.op(j).is_equal(gc)) {
+ exvector v; v.reserve(t.nops());
+ for (unsigned k=0; k<t.nops(); k++) {
+ if (k == j)
+ v.push_back(_ex1);
+ else
+ v.push_back(t.op(k));
+ }
+ t = (new mul(v))->setflag(status_flags::dynallocated);
+ goto term_done;
+ }
+ }
+ }
+
+ divide(t, gc, x);
+ t = x;
+term_done: ;
+ }
+ return (new add(terms))->setflag(status_flags::dynallocated);
+
+ } else if (is_a<mul>(e)) {
+
+ unsigned num = e.nops();
+ exvector v; v.reserve(num);
+
+ for (unsigned i=0; i<num; i++)
+ v.push_back(find_common_factor(e.op(i), factor, repl));
+
+ return (new mul(v))->setflag(status_flags::dynallocated);
+
+ } else if (is_a<power>(e)) {
+
+ ex x = e.to_rational(repl);
+ if (is_a<power>(x) && x.op(1).info(info_flags::negative))
+ return replace_with_symbol(x, repl);
+ else
+ return x;
+
+ } else
+ return e;
+}
+
+
+/** Collect common factors in sums. This converts expressions like
+ * 'a*(b*x+b*y)' to 'a*b*(x+y)'. */
+ex collect_common_factors(const ex & e)
+{
+ if (is_a<add>(e) || is_a<mul>(e)) {
+
+ lst repl;
+ ex factor = 1;
+ ex r = find_common_factor(e, factor, repl);
+ return factor.subs(repl) * r.subs(repl);
+
+ } else
+ return e;
+}
+
+
} // namespace GiNaC