From d916416984a857e80962239a0ee93e7216f803bb Mon Sep 17 00:00:00 2001 From: "Vladimir V. Kisil" Date: Wed, 31 Jul 2013 09:48:24 +0100 Subject: [PATCH] More evaluation rules: abs(x^n) => abs(x)^n (x > 0, n is real). A simple test is added as well. Signed-off-by: Vladimir V. Kisil --- check/exam_inifcns.cpp | 27 ++++++++++++++++++++++++++- ginac/inifcns.cpp | 10 ++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/check/exam_inifcns.cpp b/check/exam_inifcns.cpp index ba1ba9a6..994aa344 100644 --- a/check/exam_inifcns.cpp +++ b/check/exam_inifcns.cpp @@ -219,11 +219,35 @@ static unsigned inifcns_consist_zeta() return result; } +static unsigned inifcns_consist_abs() +{ + unsigned result = 0; + realsymbol a("a"), b("b"), x("x"), y("y"); + possymbol p("p"); + + if (!abs(exp(x+I*y)).eval().is_equal(exp(x))) + ++result; + + if (!abs(pow(p,a+I*b)).eval().is_equal(pow(p,a))) + ++result; + + // also checks that abs(p)=p + if (!abs(pow(p,a+I*b)).eval().is_equal(pow(p,a))) + ++result; + + if (!abs(pow(x+I*y,a)).eval().is_equal(pow(abs(x+I*y),a))) + ++result; + + // it is not necessary a simplification if the following is really evaluated + if (!abs(pow(x+I*y,a+I*b)).eval().is_equal(abs(pow(x+I*y,a+I*b)))) + ++result; + +} + static unsigned inifcns_consist_various() { unsigned result = 0; symbol n; - ex e; if ( binomial(n, 0) != 1 ) { clog << "ERROR: binomial(n,0) != 1" << endl; @@ -243,6 +267,7 @@ unsigned exam_inifcns() result += inifcns_consist_gamma(); cout << '.' << flush; result += inifcns_consist_psi(); cout << '.' << flush; result += inifcns_consist_zeta(); cout << '.' << flush; + result += inifcns_consist_abs(); cout << '.' << flush; result += inifcns_consist_various(); cout << '.' << flush; return result; diff --git a/ginac/inifcns.cpp b/ginac/inifcns.cpp index 8103cd86..0cb2abbd 100644 --- a/ginac/inifcns.cpp +++ b/ginac/inifcns.cpp @@ -197,6 +197,16 @@ static ex abs_eval(const ex & arg) if (is_ex_the_function(arg, abs)) return arg; + if (is_ex_the_function(arg, exp)) + return exp(arg.op(0).real_part()); + + if (is_exactly_a(arg)) { + const ex& base = arg.op(0); + const ex& exponent = arg.op(1); + if (base.info(info_flags::positive) || exponent.info(info_flags::real)) + return pow(abs(base), exponent.real_part()); + } + return abs(arg).hold(); } -- 2.44.0