- 0^a -> 0^a instead of 0.
authorRichard Kreckel <Richard.Kreckel@uni-mainz.de>
Tue, 21 Mar 2000 17:07:17 +0000 (17:07 +0000)
committerRichard Kreckel <Richard.Kreckel@uni-mainz.de>
Tue, 21 Mar 2000 17:07:17 +0000 (17:07 +0000)
check/exam_powerlaws.cpp
ginac/power.cpp

index 74e95de85a40d2f7cc2372727a1a9f5f69c0a268..aba615fd3130891d82681b41103e215d5cd548a0 100644 (file)
@@ -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;
index 32038209f51e69e53c0d93afab773c3ca03b7750..bbac8d07e99975500f9a8bb856f3666eead1cd60 100644 (file)
@@ -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<numeric *>(ebasis.bp);
@@ -350,35 +350,32 @@ ex power::eval(int level) const
         exponent_is_numerical = 1;
         num_exponent = static_cast<numeric *>(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)) {