]> www.ginac.de Git - ginac.git/blobdiff - ginac/power.cpp
- Doxygen'ed a bunch of comments.
[ginac.git] / ginac / power.cpp
index a85bc79f4fb2e366ec30773f83a593d2521cdec2..49ee5c598cce0827006c20d3e6ae269ec9325a65 100644 (file)
@@ -338,18 +338,18 @@ 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;
+    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);
+        basis_is_numerical = 1;
+        num_basis = static_cast<numeric *>(ebasis.bp);
     }
     if (is_exactly_of_type(*eexponent.bp,numeric)) {
-        exponent_is_numerical=1;
-        num_exponent=static_cast<numeric *>(eexponent.bp);
+        exponent_is_numerical = 1;
+        num_exponent = static_cast<numeric *>(eexponent.bp);
     }
 
     // ^(x,0) -> 1 (0^0 also handled here)
@@ -391,10 +391,10 @@ ex power::eval(int level) const
         if (basis_is_crational && exponent_is_crational
             && num_exponent->is_real()
             && !num_exponent->is_integer()) {
-            numeric r, q, n, m;
-            n = num_exponent->numer();
-            m = num_exponent->denom();
-            q = iquo(n, m, r);
+            numeric n = num_exponent->numer();
+            numeric m = num_exponent->denom();
+            numeric r;
+            numeric q = iquo(n, m, r);
             if (r.is_negative()) {
                 r = r.add(m);
                 q = q.sub(_num1());
@@ -402,29 +402,22 @@ ex power::eval(int level) const
             if (q.is_zero())  // the exponent was in the allowed range 0<(n/m)<1
                 return this->hold();
             else {
-                epvector res(2);
+                epvector res;
                 res.push_back(expair(ebasis,r.div(m)));
-                res.push_back(expair(ex(num_basis->power(q)),_ex1()));
-                return (new mul(res))->setflag(status_flags::dynallocated | status_flags::evaluated);
-                /*return mul(num_basis->power(q),
-                           power(ex(*num_basis),ex(r.div(m)))).hold();
-                */
-                /* return (new mul(num_basis->power(q),
-                   power(*num_basis,r.div(m)).hold()))->setflag(status_flags::dynallocated | status_flags::evaluated);
-                */
+                return (new mul(res,ex(num_basis->power(q))))->setflag(status_flags::dynallocated | status_flags::evaluated);
             }
         }
     }
 
     // ^(^(x,c1),c2) -> ^(x,c1*c2)
     // (c1, c2 numeric(), c2 integer or -1 < c1 <= 1,
-    // case c1=1 should not happen, see below!)
+    // case c1==1 should not happen, see below!)
     if (exponent_is_numerical && is_ex_exactly_of_type(ebasis,power)) {
-        const power & sub_power=ex_to_power(ebasis);
-        const ex & sub_basis=sub_power.basis;
-        const ex & sub_exponent=sub_power.exponent;
+        const power & sub_power = ex_to_power(ebasis);
+        const ex & sub_basis = sub_power.basis;
+        const ex & sub_exponent = sub_power.exponent;
         if (is_ex_exactly_of_type(sub_exponent,numeric)) {
-            const numeric & num_sub_exponent=ex_to_numeric(sub_exponent);
+            const numeric & num_sub_exponent = ex_to_numeric(sub_exponent);
             GINAC_ASSERT(num_sub_exponent!=numeric(1));
             if (num_exponent->is_integer() || abs(num_sub_exponent)<1) {
                 return power(sub_basis,num_sub_exponent.mul(*num_exponent));
@@ -486,13 +479,16 @@ ex power::evalf(int level) const
     ex eexponent;
     
     if (level==1) {
-        ebasis=basis;
-        eexponent=exponent;
+        ebasis = basis;
+        eexponent = exponent;
     } else if (level == -max_recursion_level) {
         throw(std::runtime_error("max recursion level reached"));
     } else {
-        ebasis=basis.evalf(level-1);
-        eexponent=exponent.evalf(level-1);
+        ebasis = basis.evalf(level-1);
+        if (!is_ex_exactly_of_type(eexponent,numeric))
+            eexponent = exponent.evalf(level-1);
+        else
+            eexponent = exponent;
     }
 
     return power(ebasis,eexponent);
@@ -558,8 +554,8 @@ unsigned power::return_type_tinfo(void) const
 
 ex power::expand(unsigned options) const
 {
-    ex expanded_basis=basis.expand(options);
-
+    ex expanded_basis = basis.expand(options);
+    
     if (!is_ex_exactly_of_type(exponent,numeric)||
         !ex_to_numeric(exponent).is_integer()) {
         if (are_ex_trivially_equal(basis,expanded_basis)) {
@@ -569,19 +565,19 @@ ex power::expand(unsigned options) const
                     setflag(status_flags::dynallocated);
         }
     }
-
+    
     // integer numeric exponent
     const numeric & num_exponent=ex_to_numeric(exponent);
     int int_exponent = num_exponent.to_int();
-
+    
     if (int_exponent > 0 && is_ex_exactly_of_type(expanded_basis,add)) {
         return expand_add(ex_to_add(expanded_basis), int_exponent);
     }
-
+    
     if (is_ex_exactly_of_type(expanded_basis,mul)) {
         return expand_mul(ex_to_mul(expanded_basis), num_exponent);
     }
-
+    
     // cannot expand further
     if (are_ex_trivially_equal(basis,expanded_basis)) {
         return this->hold();
@@ -601,15 +597,14 @@ ex power::expand(unsigned options) const
 // non-virtual functions in this class
 //////////
 
+/** expand a^n where a is an add and n is an integer.
+ *  @see power::expand */
 ex power::expand_add(const add & a, int n) const
 {
-    // expand a^n where a is an add and n is an integer
-
-    if (n==2) {
+    if (n==2)
         return expand_add_2(a);
-    }
     
-    int m=a.nops();
+    int m = a.nops();
     exvector sum;
     sum.reserve((n+1)*(m-1));
     intvector k(m-1);
@@ -622,7 +617,7 @@ ex power::expand_add(const add & a, int n) const
         k_cum[l]=0;
         upper_limit[l]=n;
     }
-
+    
     while (1) {
         exvector term;
         term.reserve(m+1);
@@ -638,7 +633,7 @@ ex power::expand_add(const add & a, int n) const
                 term.push_back(power(b,k[l]));
             }
         }
-
+        
         const ex & b=a.op(l);
         GINAC_ASSERT(!is_ex_exactly_of_type(b,add));
         GINAC_ASSERT(!is_ex_exactly_of_type(b,power)||
@@ -649,7 +644,7 @@ ex power::expand_add(const add & a, int n) const
         } else {
             term.push_back(power(b,n-k_cum[m-2]));
         }
-
+        
         numeric f=binomial(numeric(n),numeric(k[0]));
         for (l=1; l<m-1; l++) {
             f=f*binomial(numeric(n-k_cum[l-1]),numeric(k[l]));
@@ -697,10 +692,11 @@ ex power::expand_add(const add & a, int n) const
     return (new add(sum))->setflag(status_flags::dynallocated);
 }
 
+
+/** Special case of power::expand. Expands a^2 where a is an add.
+ *  @see power::expand_add */
 ex power::expand_add_2(const add & a) const
 {
-    // special case: expand a^2 where a is an add
-
     epvector sum;
     unsigned a_nops=a.nops();
     sum.reserve((a_nops*(a_nops+1))/2);
@@ -760,13 +756,12 @@ ex power::expand_add_2(const add & a) const
     return (new add(sum))->setflag(status_flags::dynallocated);
 }
 
+/** Expand m^n where m is a mul and n is and integer
+ *  @see power::expand */
 ex power::expand_mul(const mul & m, const numeric & n) const
 {
-    // expand m^n where m is a mul and n is and integer
-
-    if (n.is_equal(_num0())) {
+    if (n.is_equal(_num0()))
         return _ex1();
-    }
     
     epvector distrseq;
     distrseq.reserve(m.seq.size());
@@ -833,7 +828,7 @@ ex power::expand_noncommutative(const ex & basis, const numeric & exponent,
 
 // protected
 
-unsigned power::precedence=60;
+unsigned power::precedence = 60;
 
 //////////
 // global constants