From 56055db8e4780d223f6ddc680fb09ef994691c1d Mon Sep 17 00:00:00 2001 From: Richard Kreckel Date: Thu, 7 May 2015 22:33:13 +0200 Subject: [PATCH 1/1] Fix pow(+(...),2).expand(). Due to a failure to recombine coeffs and rests to expairs, expand((x+sqrt(2)*x)^2) returned x^2+2*x^2+2*sqrt(2)*x^2. The 2*x^2 term was not combined with the x^2 term to 3*x^2 because it was not the canonical expair [[x^2,2]] but rather [[2*x^2,1]]. Thanks to Isuru Fernando for the bugreport. --- check/exam_paranoia.cpp | 13 +++++++++++++ ginac/power.cpp | 8 ++++---- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/check/exam_paranoia.cpp b/check/exam_paranoia.cpp index 6c2f4571..51bd3a55 100644 --- a/check/exam_paranoia.cpp +++ b/check/exam_paranoia.cpp @@ -544,6 +544,18 @@ static unsigned is_polynomial_false_positive() return result; } +// Bug in power::expand reported by Isuru Fernando (fixed 2015-05-07). +static unsigned exam_paranoia21() +{ + symbol x("x"); + ex e = pow(x + sqrt(ex(2))*x, 2).expand(); + if (e.nops() != 2) { + clog << "(x+sqrt(2)*x)^2 was wrongly expanded to " << e << "\n"; + return 1; + } + return 0; +} + unsigned exam_paranoia() { unsigned result = 0; @@ -571,6 +583,7 @@ unsigned exam_paranoia() result += exam_paranoia19(); cout << '.' << flush; result += exam_paranoia20(); cout << '.' << flush; result += is_polynomial_false_positive(); cout << '.' << flush; + result += exam_paranoia21(); cout << '.' << flush; return result; } diff --git a/ginac/power.cpp b/ginac/power.cpp index 2dd64486..b2460fda 100644 --- a/ginac/power.cpp +++ b/ginac/power.cpp @@ -1032,11 +1032,11 @@ ex power::expand_add_2(const add & a, unsigned options) const if (c.is_equal(_ex1)) { if (is_exactly_a(r)) { - sum.push_back(expair(expand_mul(ex_to(r), *_num2_p, options, true), - _ex1)); + sum.push_back(a.combine_ex_with_coeff_to_pair(expand_mul(ex_to(r), *_num2_p, options, true), + _ex1)); } else { - sum.push_back(expair((new power(r,_ex2))->setflag(status_flags::dynallocated), - _ex1)); + sum.push_back(a.combine_ex_with_coeff_to_pair((new power(r,_ex2))->setflag(status_flags::dynallocated), + _ex1)); } } else { if (is_exactly_a(r)) { -- 2.44.0