why does power(add) switch the sign of the add?
Hi, I noticed the following behaviour of power::eval(), for example in ginsh:
(x_1 - x_2 + x_3 - x_4)^2; (x_4-x_1-x_3+x_2)^2
The sign of the sum is switched. Of course, mathematically this is totally correct, but is there any good reason why GiNaC should do it? It seems to go back to the following piece of code in power.cpp, power::eval() --------- // (2*x + 6*y)^(-4) -> 1/16*(x + 3*y)^(-4) if (num_exponent->is_integer() && is_exactly_a<add>(ebasis)) { numeric icont = ebasis.integer_content(); const numeric lead_coeff = ex_to<numeric>(ex_to<add>(ebasis).seq.begin()->coeff).div(icont); const bool canonicalizable = lead_coeff.is_integer();
HERE ============================ const bool unit_normal = lead_coeff.is_pos_integer(); if (canonicalizable && (! unit_normal)) icont = icont.mul(*_num_1_p); HERE ============================
if (canonicalizable && (icont != *_num1_p)) { const add& addref = ex_to<add>(ebasis); add* addp = new add(addref); addp->setflag(status_flags::dynallocated); addp->clearflag(status_flags::hash_calculated); addp->overall_coeff = ex_to<numeric>(addp->overall_coeff).div_dyn(icont); for (epvector::iterator i = addp->seq.begin(); i != addp->seq.end(); ++i) i->coeff = ex_to<numeric>(i->coeff).div_dyn(icont); const numeric c = icont.power(*num_exponent); if (likely(c != *_num1_p)) return (new mul(power(*addp, *num_exponent), c))->setflag(status_flags::dynallocated); else return power(*addp, *num_exponent); } } ------------ Why not leave away this bit of code, improve performance by a tiny little bit, and get somewhat more predictable behaviour of GiNaC? Jan
Hi, Jan,
Why not leave away this bit of code, improve performance by a tiny little bit, and get somewhat more predictable behaviour of GiNaC?
This code is responsible for rewriting rules like (x-y)^3/(y-x)^2 -> x - y, (2*x-2*y)^2*(y-x) -> -4*(x-y)^3, etc. Also GiNaC does not care of term ordering (in Planck we trust). Hope this helps, Alexei
participants (2)
-
Alexei Sheplyakov
-
Jan