From a3f9c234d93f7dd4f12b68cce28d4403f0ec45c2 Mon Sep 17 00:00:00 2001 From: Richard Kreckel Date: Sat, 6 Feb 2016 01:35:07 +0100 Subject: [PATCH] speed up multiply_lcm(e, lcm) a bit and comment it a little --- ginac/normal.cpp | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/ginac/normal.cpp b/ginac/normal.cpp index a1e2de48..d7570fd5 100644 --- a/ginac/normal.cpp +++ b/ginac/normal.cpp @@ -270,9 +270,15 @@ static numeric lcm_of_coefficients_denominators(const ex &e) * @param lcm LCM to multiply in */ static ex multiply_lcm(const ex &e, const numeric &lcm) { + if (lcm.is_equal(*_num1_p)) + // e * 1 -> e; + return e; + if (is_exactly_a(e)) { + // (a*b*...)*lcm -> (a*lcma)*(b*lcmb)*...*(lcm/(lcma*lcmb*...)) size_t num = e.nops(); - exvector v; v.reserve(num + 1); + exvector v; + v.reserve(num + 1); numeric lcm_accum = *_num1_p; for (size_t i=0; i(v); } else if (is_exactly_a(e)) { + // (a+b+...)*lcm -> a*lcm+b*lcm+... size_t num = e.nops(); - exvector v; v.reserve(num); + exvector v; + v.reserve(num); for (size_t i=0; i(v); } else if (is_exactly_a(e)) { - if (is_a(e.op(0))) - return e * lcm; - else { + if (!is_a(e.op(0))) { + // (b^e)*lcm -> (b*lcm^(1/e))^e if lcm^(1/e) ∈ ℝ (i.e. not a float) + // but not for symbolic b, as evaluation would undo this again numeric root_of_lcm = lcm.power(ex_to(e.op(1)).inverse()); if (root_of_lcm.is_rational()) return pow(multiply_lcm(e.op(0), root_of_lcm), e.op(1)); - else - return e * lcm; } - } else - return e * lcm; + } + // can't recurse down into e + return dynallocate(e, lcm); } -- 2.49.0