- (l)degree(s), coeff(s, n) and collect(s) were extended to accept expressions
authorChristian Bauer <Christian.Bauer@uni-mainz.de>
Fri, 25 Jan 2002 18:33:01 +0000 (18:33 +0000)
committerChristian Bauer <Christian.Bauer@uni-mainz.de>
Fri, 25 Jan 2002 18:33:01 +0000 (18:33 +0000)
  of any class (except add/mul/ncmul/numeric) for "s". They should even work
  if "s" is a "power" object, as long as the exponent is non-integer, but with
  some limitations. For example, you can "collect(a*2^x+b*2^x, 2^x)" to get
  "(a+b)*2^x", but "degree(2^(3*x), 2^x)" yields 0 instead of 3).

12 files changed:
NEWS
ginac/basic.cpp
ginac/constant.cpp
ginac/constant.h
ginac/function.pl
ginac/indexed.cpp
ginac/indexed.h
ginac/numeric.cpp
ginac/numeric.h
ginac/power.cpp
ginac/symbol.cpp
ginac/symbol.h

diff --git a/NEWS b/NEWS
index b5a706a..bd43d5a 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,12 @@
 This file records noteworthy changes.
 
+1.0.5 (<date>)
+* (l)degree(s), coeff(s, n) and collect(s) were extended to accept expressions
+  of any class (except add/mul/ncmul/numeric) for "s". They should even work
+  if "s" is a "power" object, as long as the exponent is non-integer, but with
+  some limitations. For example, you can "collect(a*2^x+b*2^x, 2^x)" to get
+  "(a+b)*2^x", but "degree(2^(3*x), 2^x)" yields 0 instead of 3).
+
 1.0.4 (24 January 2001)
 * Speedup in expand().
 * Faster Bernoulli numbers (Markus Nullmeier).
index d77e7dc..fb73096 100644 (file)
@@ -236,19 +236,22 @@ ex basic::map(map_function & f) const
 /** Return degree of highest power in object s. */
 int basic::degree(const ex & s) const
 {
-       return 0;
+       return is_equal(ex_to<basic>(s)) ? 1 : 0;
 }
 
 /** Return degree of lowest power in object s. */
 int basic::ldegree(const ex & s) const
 {
-       return 0;
+       return is_equal(ex_to<basic>(s)) ? 1 : 0;
 }
 
 /** Return coefficient of degree n in object s. */
 ex basic::coeff(const ex & s, int n) const
 {
-       return n==0 ? *this : _ex0;
+       if (is_equal(ex_to<basic>(s)))
+               return n==1 ? _ex1 : _ex0;
+       else
+               return n==0 ? *this : _ex0;
 }
 
 /** Sort expanded expression in terms of powers of some object(s).
index 371902b..5ba8475 100644 (file)
@@ -145,24 +145,6 @@ void constant::print(const print_context & c, unsigned level) const
                c.s << name;
 }
 
-int constant::degree(const ex & s) const
-{
-       return is_equal(ex_to<basic>(s)) ? 1 : 0;
-}
-
-int constant::ldegree(const ex & s) const
-{
-       return is_equal(ex_to<basic>(s)) ? 1 : 0;
-}
-
-ex constant::coeff(const ex & s, int n) const
-{
-       if (is_equal(ex_to<basic>(s)))
-               return n==1 ? _ex1 : _ex0;
-       else
-               return n==0 ? *this : _ex0;
-}
-
 ex constant::evalf(int level) const
 {
        if (ef!=0) {
index 5ffe620..6f3aa0f 100644 (file)
@@ -49,9 +49,6 @@ public:
        // functions overriding virtual functions from base classes
 public:
        void print(const print_context & c, unsigned level = 0) const;
-       int degree(const ex & s) const;
-       int ldegree(const ex & s) const;
-       ex coeff(const ex & s, int n = 1) const;
        ex evalf(int level = 0) const;
 protected:
        ex derivative(const symbol & s) const;
index b827216..ba1b02a 100755 (executable)
@@ -320,9 +320,6 @@ $constructors_interface
 public:
        void print(const print_context & c, unsigned level = 0) const;
        unsigned precedence(void) const {return 70;}
-       int degree(const ex & s) const;
-       int ldegree(const ex & s) const;
-       ex coeff(const ex & s, int n = 1) const;
        ex expand(unsigned options=0) const;
        ex eval(int level=0) const;
        ex evalf(int level=0) const;
@@ -719,24 +716,6 @@ ex function::expand(unsigned options) const
                return (options == 0) ? setflag(status_flags::expanded) : *this;
 }
 
-int function::degree(const ex & s) const
-{
-       return is_equal(ex_to<basic>(s)) ? 1 : 0;
-}
-
-int function::ldegree(const ex & s) const
-{
-       return is_equal(ex_to<basic>(s)) ? 1 : 0;
-}
-
-ex function::coeff(const ex & s, int n) const
-{
-       if (is_equal(ex_to<basic>(s)))
-               return n==1 ? _ex1 : _ex0;
-       else
-               return n==0 ? ex(*this) : _ex0;
-}
-
 ex function::eval(int level) const
 {
        GINAC_ASSERT(serial<registered_functions().size());
index b852416..6c2683c 100644 (file)
@@ -274,24 +274,6 @@ ex indexed::eval(int level) const
        return ex_to<basic>(base).eval_indexed(*this);
 }
 
-int indexed::degree(const ex & s) const
-{
-       return is_equal(ex_to<basic>(s)) ? 1 : 0;
-}
-
-int indexed::ldegree(const ex & s) const
-{
-       return is_equal(ex_to<basic>(s)) ? 1 : 0;
-}
-
-ex indexed::coeff(const ex & s, int n) const
-{
-       if (is_equal(ex_to<basic>(s)))
-               return n==1 ? _ex1 : _ex0;
-       else
-               return n==0 ? ex(*this) : _ex0;
-}
-
 ex indexed::thisexprseq(const exvector & v) const
 {
        return indexed(ex_to<symmetry>(symtree), v);
index 3f1b655..58c8bbd 100644 (file)
@@ -145,9 +145,6 @@ public:
        void print(const print_context & c, unsigned level = 0) const;
        bool info(unsigned inf) const;
        ex eval(int level = 0) const;
-       int degree(const ex & s) const;
-       int ldegree(const ex & s) const;
-       ex coeff(const ex & s, int n = 1) const;
        exvector get_free_indices(void) const;
 
 protected:
index 986070b..f2a834d 100644 (file)
@@ -498,6 +498,21 @@ bool numeric::info(unsigned inf) const
        return false;
 }
 
+int numeric::degree(const ex & s) const
+{
+       return 0;
+}
+
+int numeric::ldegree(const ex & s) const
+{
+       return 0;
+}
+
+ex numeric::coeff(const ex & s, int n) const
+{
+       return n==0 ? *this : _ex0;
+}
+
 /** Disassemble real part and imaginary part to scan for the occurrence of a
  *  single number.  Also handles the imaginary unit.  It ignores the sign on
  *  both this and the argument, which may lead to what might appear as funny
index 8f7a83e..3c7dba2 100644 (file)
@@ -85,6 +85,9 @@ public:
        void print(const print_context & c, unsigned level = 0) const;
        unsigned precedence(void) const {return 30;}
        bool info(unsigned inf) const;
+       int degree(const ex & s) const;
+       int ldegree(const ex & s) const;
+       ex coeff(const ex & s, int n = 1) const;
        bool has(const ex &other) const;
        ex eval(int level = 0) const;
        ex evalf(int level = 0) const;
index 834b3af..4c7519e 100644 (file)
@@ -244,7 +244,9 @@ ex power::map(map_function & f) const
 
 int power::degree(const ex & s) const
 {
-       if (is_ex_exactly_of_type(exponent, numeric) && ex_to<numeric>(exponent).is_integer()) {
+       if (is_equal(ex_to<basic>(s)))
+               return 1;
+       else if (is_ex_exactly_of_type(exponent, numeric) && ex_to<numeric>(exponent).is_integer()) {
                if (basis.is_equal(s))
                        return ex_to<numeric>(exponent).to_int();
                else
@@ -257,7 +259,9 @@ int power::degree(const ex & s) const
 
 int power::ldegree(const ex & s) const 
 {
-       if (is_ex_exactly_of_type(exponent, numeric) && ex_to<numeric>(exponent).is_integer()) {
+       if (is_equal(ex_to<basic>(s)))
+               return 1;
+       else if (is_ex_exactly_of_type(exponent, numeric) && ex_to<numeric>(exponent).is_integer()) {
                if (basis.is_equal(s))
                        return ex_to<numeric>(exponent).to_int();
                else
@@ -270,7 +274,9 @@ int power::ldegree(const ex & s) const
 
 ex power::coeff(const ex & s, int n) const
 {
-       if (!basis.is_equal(s)) {
+       if (is_equal(ex_to<basic>(s)))
+               return n==1 ? _ex1 : _ex0;
+       else if (!basis.is_equal(s)) {
                // basis not equal to s
                if (n == 0)
                        return *this;
index f566e23..94d01e4 100644 (file)
@@ -176,24 +176,6 @@ bool symbol::info(unsigned inf) const
                return inherited::info(inf);
 }
 
-int symbol::degree(const ex & s) const
-{
-       return is_equal(ex_to<basic>(s)) ? 1 : 0;
-}
-
-int symbol::ldegree(const ex & s) const
-{
-       return is_equal(ex_to<basic>(s)) ? 1 : 0;
-}
-
-ex symbol::coeff(const ex & s, int n) const
-{
-       if (is_equal(ex_to<basic>(s)))
-               return n==1 ? _ex1 : _ex0;
-       else
-               return n==0 ? *this : _ex0;
-}
-
 ex symbol::eval(int level) const
 {
        if (level == -max_recursion_level)
index bf83c36..7c96312 100644 (file)
@@ -71,9 +71,6 @@ public:
        basic * duplicate() const;
        void print(const print_context & c, unsigned level = 0) const;
        bool info(unsigned inf) const;
-       int degree(const ex & s) const;
-       int ldegree(const ex & s) const;
-       ex coeff(const ex & s, int n = 1) const;
        ex eval(int level = 0) const;
        ex evalf(int level = 0) const { return *this; } // overwrites basic::evalf() for performance reasons
        ex series(const relational & s, int order, unsigned options = 0) const;