From 118e28a1d608c466ebe227f4b5f5239c292f19bc Mon Sep 17 00:00:00 2001 From: Richard Kreckel Date: Tue, 21 Mar 2000 17:07:17 +0000 Subject: [PATCH] - 0^a -> 0^a instead of 0. --- check/exam_powerlaws.cpp | 51 ++++++++++++++++++++++++++++++---------- ginac/power.cpp | 39 ++++++++++++++---------------- 2 files changed, 56 insertions(+), 34 deletions(-) diff --git a/check/exam_powerlaws.cpp b/check/exam_powerlaws.cpp index 74e95de8..aba615fd 100644 --- a/check/exam_powerlaws.cpp +++ b/check/exam_powerlaws.cpp @@ -96,6 +96,7 @@ static unsigned exam_powerlaws1(void) clog << "returned: " << e6 << endl; return 1; } + return 0; } @@ -201,33 +202,33 @@ static unsigned exam_powerlaws3(void) { // numeric evaluation - ex e1=power(numeric(4),numeric(1)/numeric(2)); + ex e1 = power(numeric(4),numeric(1,2)); if (e1 != 2) { clog << "4^(1/2) wrongly returned " << e1 << endl; return 1; } - ex e2=power(numeric(27),numeric(2)/numeric(3)); + ex e2 = power(numeric(27),numeric(2,3)); if (e2 != 9) { clog << "27^(2/3) wrongly returned " << e2 << endl; return 1; } - - ex e3=power(numeric(5),numeric(1)/numeric(2)); + + ex e3 = power(numeric(5),numeric(1,2)); if (!(is_ex_exactly_of_type(e3,power) && e3.op(0).is_equal(numeric(5)) && - e3.op(1).is_equal(numeric(1)/numeric(2)) )) { + e3.op(1).is_equal(numeric(1,2)))) { clog << "5^(1/2) wrongly returned " << e3 << endl; return 1; } - ex e4=power(numeric(5),evalf(numeric(1)/numeric(2))); + ex e4 = power(numeric(5),evalf(numeric(1,2))); if (!(is_ex_exactly_of_type(e4,numeric))) { clog << "5^(0.5) wrongly returned " << e4 << endl; return 1; } - ex e5=power(evalf(numeric(5)),numeric(1)/numeric(2)); + ex e5 = power(evalf(numeric(5)),numeric(1,2)); if (!(is_ex_exactly_of_type(e5,numeric))) { clog << "5.0^(1/2) wrongly returned " << e5 << endl; return 1; @@ -239,24 +240,47 @@ static unsigned exam_powerlaws3(void) static unsigned exam_powerlaws4(void) { // test for mul::eval() - + symbol a("a"); symbol b("b"); symbol c("c"); - ex f1=power(a*b,ex(1)/ex(2)); - ex f2=power(a*b,ex(3)/ex(2)); - ex f3=c; - + ex f1 = power(a*b,ex(1)/ex(2)); + ex f2 = power(a*b,ex(3)/ex(2)); + ex f3 = c; + exvector v; v.push_back(f1); v.push_back(f2); v.push_back(f3); - ex e1=mul(v); + ex e1 = mul(v); if (e1!=a*a*b*b*c) { clog << "(a*b)^(1/2)*(a*b)^(3/2)*c wrongly returned " << e1 << endl; return 1; } + + return 0; +} + +static unsigned exam_powerlaws5(void) +{ + // cabinet of slightly pathological cases + + symbol a("a"); + + ex e1 = pow(1,a); + if (e1 != 1) { + clog << "1^a wrongly returned " << e1 << endl; + return 1; + } + + ex e2 = pow(0,a); + if (!(is_ex_exactly_of_type(e2,power))) { + clog << "0^a was evaluated to " << e2 + << " though nothing is known about a." << endl; + return 1; + } + return 0; } @@ -271,6 +295,7 @@ unsigned exam_powerlaws(void) result += exam_powerlaws2(); cout << '.' << flush; result += exam_powerlaws3(); cout << '.' << flush; result += exam_powerlaws4(); cout << '.' << flush; + result += exam_powerlaws5(); cout << '.' << flush; if (!result) { cout << " passed " << endl; diff --git a/ginac/power.cpp b/ginac/power.cpp index 32038209..bbac8d07 100644 --- a/ginac/power.cpp +++ b/ginac/power.cpp @@ -319,7 +319,7 @@ ex power::eval(int level) const { // simplifications: ^(x,0) -> 1 (0^0 handled here) // ^(x,1) -> x - // ^(0,x) -> 0 (except if the realpart of x is non-positive, in which case an exception is thrown) + // ^(0,c1) -> 0 or exception (depending on real value of c1) // ^(1,x) -> 1 // ^(c1,c2) -> *(c1^n,c1^(c2-n)) (c1, c2 numeric(), 0<(c2-n)<1 except if c1,c2 are rational, but c1^c2 is not) // ^(^(x,c1),c2) -> ^(x,c1*c2) (c1, c2 numeric(), c2 integer or -1 < c1 <= 1, case c1=1 should not happen, see below!) @@ -328,7 +328,7 @@ ex power::eval(int level) const // ^(*(x,c1),c2) -> ^(-x,c2)*c1^c2 (c1, c2 numeric(), c1<0) debugmsg("power eval",LOGLEVEL_MEMBER_FUNCTION); - + if ((level==1) && (flags & status_flags::evaluated)) return *this; else if (level == -max_recursion_level) @@ -336,12 +336,12 @@ ex power::eval(int level) const const ex & ebasis = level==1 ? basis : basis.eval(level-1); const ex & eexponent = level==1 ? exponent : exponent.eval(level-1); - + bool basis_is_numerical = 0; bool exponent_is_numerical = 0; numeric * num_basis; numeric * num_exponent; - + if (is_exactly_of_type(*ebasis.bp,numeric)) { basis_is_numerical = 1; num_basis = static_cast(ebasis.bp); @@ -350,35 +350,32 @@ ex power::eval(int level) const exponent_is_numerical = 1; num_exponent = static_cast(eexponent.bp); } - + // ^(x,0) -> 1 (0^0 also handled here) if (eexponent.is_zero()) if (ebasis.is_zero()) throw (std::domain_error("power::eval(): pow(0,0) is undefined")); else return _ex1(); - + // ^(x,1) -> x if (eexponent.is_equal(_ex1())) return ebasis; - - // ^(0,x) -> 0 (except if the realpart of x is non-positive) - if (ebasis.is_zero()) { - if (exponent_is_numerical) { - if ((num_exponent->real()).is_zero()) - throw (std::domain_error("power::eval(): pow(0,I) is undefined")); - else if ((num_exponent->real()).is_negative()) - throw (std::overflow_error("power::eval(): division by zero")); - else - return _ex0(); - } else + + // ^(0,c1) -> 0 or exception (depending on real value of c1) + if (ebasis.is_zero() && exponent_is_numerical) { + if ((num_exponent->real()).is_zero()) + throw (std::domain_error("power::eval(): pow(0,I) is undefined")); + else if ((num_exponent->real()).is_negative()) + throw (std::overflow_error("power::eval(): division by zero")); + else return _ex0(); } - + // ^(1,x) -> 1 if (ebasis.is_equal(_ex1())) return _ex1(); - + if (basis_is_numerical && exponent_is_numerical) { // ^(c1,c2) -> c1^c2 (c1, c2 numeric(), // except if c1,c2 are rational, but c1^c2 is not) @@ -412,7 +409,7 @@ ex power::eval(int level) const } } } - + // ^(^(x,c1),c2) -> ^(x,c1*c2) // (c1, c2 numeric(), c2 integer or -1 < c1 <= 1, // case c1==1 should not happen, see below!) @@ -434,7 +431,7 @@ ex power::eval(int level) const is_ex_exactly_of_type(ebasis,mul)) { return expand_mul(ex_to_mul(ebasis), *num_exponent); } - + // ^(*(...,x;c1),c2) -> ^(*(...,x;1),c2)*c1^c2 (c1, c2 numeric(), c1>0) // ^(*(...,x,c1),c2) -> ^(*(...,x;-1),c2)*(-c1)^c2 (c1, c2 numeric(), c1<0) if (exponent_is_numerical && is_ex_exactly_of_type(ebasis,mul)) { -- 2.44.0