From: Christian Bauer Date: Wed, 27 Nov 2002 19:16:25 +0000 (+0000) Subject: - collect_common_factors() works better with negative powers X-Git-Tag: release_1-0-13~11 X-Git-Url: https://www.ginac.de/ginac.git//ginac.git?p=ginac.git;a=commitdiff_plain;h=729d30ae80fa9fdcdbafd7a29e8671083130f69c - collect_common_factors() works better with negative powers - simplify_indexed() converts "gamma~mu*p.mu" to "p\" - fixed a bug in canonicalize_clifford() when gammaL/R were in a string --- diff --git a/ginac/clifford.cpp b/ginac/clifford.cpp index 0a10d452..af8b749c 100644 --- a/ginac/clifford.cpp +++ b/ginac/clifford.cpp @@ -208,6 +208,7 @@ bool diracgamma::contract_with(exvector::iterator self, exvector::iterator other GINAC_ASSERT(is_a(*other)); GINAC_ASSERT(is_a(self->op(0))); unsigned char rl = ex_to(*self).get_representation_label(); + ex dim = ex_to(self->op(1)).get_dim(); if (is_a(*other)) { @@ -215,8 +216,6 @@ bool diracgamma::contract_with(exvector::iterator self, exvector::iterator other if (ex_to(*other).get_representation_label() != rl) return false; - ex dim = ex_to(self->op(1)).get_dim(); - // gamma~mu gamma.mu = dim ONE if (other - self == 1) { *self = dim; @@ -278,6 +277,13 @@ bool diracgamma::contract_with(exvector::iterator self, exvector::iterator other *other = _ex1; return true; } + + } else if (is_a(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; @@ -718,7 +724,7 @@ ex canonicalize_clifford(const ex & e) // 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(it->op(0))) + if (is_a(it->op(0)) || is_a(it->op(0)) || is_a(it->op(0))) ++it; while (it != next_to_last) { if (it[0].compare(it[1]) > 0) { diff --git a/ginac/normal.cpp b/ginac/normal.cpp index 67091f50..e1d7349f 100644 --- a/ginac/normal.cpp +++ b/ginac/normal.cpp @@ -1741,6 +1741,7 @@ static exvector sqrfree_yun(const ex &a, const symbol &x) return res; } + /** Compute a square-free factorization of a multivariate polynomial in Q[X]. * * @param a multivariate polynomial over Q[X] @@ -1842,6 +1843,7 @@ ex sqrfree(const ex &a, const lst &l) return result * lcm.inverse(); } + /** Compute square-free partial fraction decomposition of rational function * a(x). * @@ -1912,96 +1914,6 @@ ex sqrfree_parfrac(const ex & a, const symbol & 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(e)) { - - unsigned num = e.nops(); - exvector terms; terms.reserve(num); - lst repl; - ex gc; - - // Find the common GCD - for (unsigned i=0; i(x) || is_a(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(t)) { - for (unsigned j=0; jsetflag(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(e)) { - - exvector v; - for (unsigned i=0; isetflag(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(e) || is_a(e)) { - - ex factor = 1; - ex r = find_common_factor(e, factor); - return factor * r; - - } else - return e; -} - - /* * Normal form of rational functions */ @@ -2503,4 +2415,106 @@ ex expairseq::to_rational(lst &repl_lst) const } +/** 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(e)) { + + unsigned num = e.nops(); + exvector terms; terms.reserve(num); + ex gc; + + // Find the common GCD + for (unsigned i=0; i(x) || is_a(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(t)) { + for (unsigned j=0; jsetflag(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(e)) { + + unsigned num = e.nops(); + exvector v; v.reserve(num); + + for (unsigned i=0; isetflag(status_flags::dynallocated); + + } else if (is_a(e)) { + + ex x = e.to_rational(repl); + if (is_a(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(e) || is_a(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