- ex::numer() and ex::denom() now make use of the new normal()
authorChristian Bauer <Christian.Bauer@uni-mainz.de>
Thu, 10 Feb 2000 21:56:25 +0000 (21:56 +0000)
committerChristian Bauer <Christian.Bauer@uni-mainz.de>
Thu, 10 Feb 2000 21:56:25 +0000 (21:56 +0000)
- improved power::normal() a bit with respect to negative exponents

ginac/ex.cpp
ginac/ex.h
ginac/normal.cpp

index ec6e96494fb40b6ca6828ed21cf1d0c8f252f202..6c51fe6e02b596686fd01d788cf8cbe89539239a 100644 (file)
@@ -277,78 +277,6 @@ ex ex::coeff(const symbol & s, int n) const
     return bp->coeff(s,n);
 }
 
-ex ex::numer(bool normalize) const
-{
-    ex n;
-    if (normalize)
-        n = normal();
-    else
-        n = *this;
-
-       // number
-       if (is_ex_exactly_of_type(n, numeric))
-               return ex_to_numeric(n).numer();
-
-    // polynomial
-    if (n.info(info_flags::cinteger_polynomial))
-        return n;
-
-    // something^(-int)
-    if (is_ex_exactly_of_type(n, power) && n.op(1).info(info_flags::negint))
-        return _ex1();
-
-    // something^(int) * something^(int) * ...
-    if (!is_ex_exactly_of_type(n, mul))
-        return n;
-    ex res = _ex1();
-    for (unsigned i=0; i<n.nops(); i++) {
-               if (is_ex_exactly_of_type(n.op(i), power) && n.op(i).op(1).info(info_flags::negint)) {
-                       // something^(-int) belongs to the denominator
-               } else if (is_ex_exactly_of_type(n.op(i), numeric)) {
-                       res *= ex_to_numeric(n.op(i)).numer();
-               } else {
-            res *= n.op(i);
-               }
-    }
-    return res;
-}
-
-ex ex::denom(bool normalize) const
-{
-    ex n;
-    if (normalize)
-        n = normal();
-    else
-        n = *this;
-
-       // number
-       if (is_ex_exactly_of_type(n, numeric))
-               return ex_to_numeric(n).denom();
-
-    // polynomial
-    if (n.info(info_flags::cinteger_polynomial))
-        return _ex1();
-
-    // something^(-int)
-    if (is_ex_exactly_of_type(n, power) && n.op(1).info(info_flags::negint))
-        return power(n.op(0), -(n.op(1)));
-
-    // something^(int) * something^(int) * ...
-    if (!is_ex_exactly_of_type(n, mul))
-        return _ex1();
-    ex res = _ex1();
-    for (unsigned i=0; i<n.nops(); i++) {
-        if (is_ex_exactly_of_type(n.op(i), power) && n.op(i).op(1).info(info_flags::negint)) {
-            res *= power(n.op(i), -1);
-               } else if (is_ex_exactly_of_type(n.op(i), numeric)) {
-                       res *= ex_to_numeric(n.op(i)).denom();
-               } else {
-                       // everything else belongs to the numerator
-               }
-    }
-    return res;
-}
-
 ex ex::collect(const symbol & s) const
 {
     GINAC_ASSERT(bp!=0);
index 6bc4879ea427aec76b3f19bd4a5d45389b6fe0ad..9f72ab55fd33f245d8e19fc62c005bbeaee7f842 100644 (file)
@@ -222,8 +222,8 @@ public:
     ex coeff(const symbol & s, int n=1) const;
     ex lcoeff(const symbol & s) const { return coeff(s, degree(s)); }
     ex tcoeff(const symbol & s) const { return coeff(s, ldegree(s)); }
-    ex numer(bool normalize = true) const;
-    ex denom(bool normalize = true) const;
+    ex numer(void) const;
+    ex denom(void) const;
     ex unit(const symbol &x) const;
     ex content(const symbol &x) const;
     numeric integer_content(void) const;
@@ -354,11 +354,11 @@ inline int ldegree(const ex & thisex, const symbol & s)
 inline ex coeff(const ex & thisex, const symbol & s, int n=1)
 { return thisex.coeff(s, n); }
 
-inline ex numer(const ex & thisex, bool normalize = true)
-{ return thisex.numer(normalize); }
+inline ex numer(const ex & thisex)
+{ return thisex.numer(); }
 
-inline ex denom(const ex & thisex, bool normalize = true)
-{ return thisex.denom(normalize); }
+inline ex denom(const ex & thisex)
+{ return thisex.denom(); }
 
 inline ex normal(const ex & thisex, int level=0)
 { return thisex.normal(level); }
index 1c2dc823f7911b76fbd60a5d7fd1ebaa0bd87900..ad49f9ac0cab4ca03292111d115063cbddba9748 100644 (file)
@@ -1557,18 +1557,41 @@ ex mul::normal(lst &sym_lst, lst &repl_lst, int level) const
  *  @see ex::normal */
 ex power::normal(lst &sym_lst, lst &repl_lst, int level) const
 {
-    if (exponent.info(info_flags::posint)) {
-        // Integer powers are distributed
-        ex n = basis.bp->normal(sym_lst, repl_lst, level-1);
-               return (new lst(power(n.op(0), exponent), power(n.op(1), exponent)))->setflag(status_flags::dynallocated);
-       } else if (exponent.info(info_flags::negint)) {
-        // Integer powers are distributed
-        ex n = basis.bp->normal(sym_lst, repl_lst, level-1);
-               return (new lst(power(n.op(1), -exponent), power(n.op(0), -exponent)))->setflag(status_flags::dynallocated);
-    } else {
-        // Non-integer powers are replaced by temporary symbol (after normalizing basis)
-               ex n = basis.bp->normal(sym_lst, repl_lst, level-1);
-               return (new lst(replace_with_symbol(power(n.op(0) / n.op(1), exponent), sym_lst, repl_lst), _ex1()))->setflag(status_flags::dynallocated);
+       // Normalize basis
+    ex n = basis.bp->normal(sym_lst, repl_lst, level-1);
+
+       if (exponent.info(info_flags::integer)) {
+
+           if (exponent.info(info_flags::positive)) {
+
+                       // (a/b)^n -> {a^n, b^n}
+                       return (new lst(power(n.op(0), exponent), power(n.op(1), exponent)))->setflag(status_flags::dynallocated);
+
+               } else if (exponent.info(info_flags::negint)) {
+
+                       // (a/b)^-n -> {b^n, a^n}
+                       return (new lst(power(n.op(1), -exponent), power(n.op(0), -exponent)))->setflag(status_flags::dynallocated);
+               }
+
+       } else {
+               if (exponent.info(info_flags::positive)) {
+
+                       // (a/b)^z -> {sym((a/b)^z), 1}
+                       return (new lst(replace_with_symbol(power(n.op(0) / n.op(1), exponent), sym_lst, repl_lst), _ex1()))->setflag(status_flags::dynallocated);
+
+               } else {
+
+                       if (n.op(1).is_equal(_ex1())) {
+
+                               // a^-x -> {1, sym(a^x)}
+                               return (new lst(_ex1(), replace_with_symbol(power(n.op(0), -exponent), sym_lst, repl_lst)))->setflag(status_flags::dynallocated);
+
+                       } else {
+
+                               // (a/b)^-x -> {(b/a)^x, 1}
+                               return (new lst(replace_with_symbol(power(n.op(1) / n.op(0), -exponent), sym_lst, repl_lst), _ex1()))->setflag(status_flags::dynallocated);
+                       }
+               }
     }
 }
 
@@ -1618,6 +1641,46 @@ ex ex::normal(int level) const
     return e.op(0) / e.op(1);
 }
 
+/** Numerator of an expression. If the expression is not of the normal form
+ *  "numerator/denominator", it is first converted to this form and then the
+ *  numerator is returned.
+ *
+ *  @see ex::normal
+ *  @return numerator */
+ex ex::numer(void) const
+{
+    lst sym_lst, repl_lst;
+
+    ex e = bp->normal(sym_lst, repl_lst, 0);
+       GINAC_ASSERT(is_ex_of_type(e, lst));
+
+       // Re-insert replaced symbols
+    if (sym_lst.nops() > 0)
+        return e.op(0).subs(sym_lst, repl_lst);
+       else
+               return e.op(0);
+}
+
+/** Denominator of an expression. If the expression is not of the normal form
+ *  "numerator/denominator", it is first converted to this form and then the
+ *  denominator is returned.
+ *
+ *  @see ex::normal
+ *  @return denominator */
+ex ex::denom(void) const
+{
+    lst sym_lst, repl_lst;
+
+    ex e = bp->normal(sym_lst, repl_lst, 0);
+       GINAC_ASSERT(is_ex_of_type(e, lst));
+
+       // Re-insert replaced symbols
+    if (sym_lst.nops() > 0)
+        return e.op(1).subs(sym_lst, repl_lst);
+       else
+               return e.op(1);
+}
+
 #ifndef NO_NAMESPACE_GINAC
 } // namespace GiNaC
 #endif // ndef NO_NAMESPACE_GINAC