From 146be3afbf5f340ea81cda30b35b35c158af31c2 Mon Sep 17 00:00:00 2001 From: Christian Bauer Date: Fri, 25 Jan 2002 18:33:01 +0000 Subject: [PATCH] - (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). --- NEWS | 7 +++++++ ginac/basic.cpp | 9 ++++++--- ginac/constant.cpp | 18 ------------------ ginac/constant.h | 3 --- ginac/function.pl | 21 --------------------- ginac/indexed.cpp | 18 ------------------ ginac/indexed.h | 3 --- ginac/numeric.cpp | 15 +++++++++++++++ ginac/numeric.h | 3 +++ ginac/power.cpp | 12 +++++++++--- ginac/symbol.cpp | 18 ------------------ ginac/symbol.h | 3 --- 12 files changed, 40 insertions(+), 90 deletions(-) diff --git a/NEWS b/NEWS index b5a706a9..bd43d5aa 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,12 @@ This file records noteworthy changes. +1.0.5 () +* (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). diff --git a/ginac/basic.cpp b/ginac/basic.cpp index d77e7dc4..fb73096f 100644 --- a/ginac/basic.cpp +++ b/ginac/basic.cpp @@ -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(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(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(s))) + return n==1 ? _ex1 : _ex0; + else + return n==0 ? *this : _ex0; } /** Sort expanded expression in terms of powers of some object(s). diff --git a/ginac/constant.cpp b/ginac/constant.cpp index 371902bd..5ba84751 100644 --- a/ginac/constant.cpp +++ b/ginac/constant.cpp @@ -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(s)) ? 1 : 0; -} - -int constant::ldegree(const ex & s) const -{ - return is_equal(ex_to(s)) ? 1 : 0; -} - -ex constant::coeff(const ex & s, int n) const -{ - if (is_equal(ex_to(s))) - return n==1 ? _ex1 : _ex0; - else - return n==0 ? *this : _ex0; -} - ex constant::evalf(int level) const { if (ef!=0) { diff --git a/ginac/constant.h b/ginac/constant.h index 5ffe6200..6f3aa0fa 100644 --- a/ginac/constant.h +++ b/ginac/constant.h @@ -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; diff --git a/ginac/function.pl b/ginac/function.pl index b827216f..ba1b02ae 100755 --- a/ginac/function.pl +++ b/ginac/function.pl @@ -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(s)) ? 1 : 0; -} - -int function::ldegree(const ex & s) const -{ - return is_equal(ex_to(s)) ? 1 : 0; -} - -ex function::coeff(const ex & s, int n) const -{ - if (is_equal(ex_to(s))) - return n==1 ? _ex1 : _ex0; - else - return n==0 ? ex(*this) : _ex0; -} - ex function::eval(int level) const { GINAC_ASSERT(serial(base).eval_indexed(*this); } -int indexed::degree(const ex & s) const -{ - return is_equal(ex_to(s)) ? 1 : 0; -} - -int indexed::ldegree(const ex & s) const -{ - return is_equal(ex_to(s)) ? 1 : 0; -} - -ex indexed::coeff(const ex & s, int n) const -{ - if (is_equal(ex_to(s))) - return n==1 ? _ex1 : _ex0; - else - return n==0 ? ex(*this) : _ex0; -} - ex indexed::thisexprseq(const exvector & v) const { return indexed(ex_to(symtree), v); diff --git a/ginac/indexed.h b/ginac/indexed.h index 3f1b655e..58c8bbd4 100644 --- a/ginac/indexed.h +++ b/ginac/indexed.h @@ -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: diff --git a/ginac/numeric.cpp b/ginac/numeric.cpp index 986070b7..f2a834d2 100644 --- a/ginac/numeric.cpp +++ b/ginac/numeric.cpp @@ -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 diff --git a/ginac/numeric.h b/ginac/numeric.h index 8f7a83ed..3c7dba2c 100644 --- a/ginac/numeric.h +++ b/ginac/numeric.h @@ -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; diff --git a/ginac/power.cpp b/ginac/power.cpp index 834b3afd..4c7519ec 100644 --- a/ginac/power.cpp +++ b/ginac/power.cpp @@ -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(exponent).is_integer()) { + if (is_equal(ex_to(s))) + return 1; + else if (is_ex_exactly_of_type(exponent, numeric) && ex_to(exponent).is_integer()) { if (basis.is_equal(s)) return ex_to(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(exponent).is_integer()) { + if (is_equal(ex_to(s))) + return 1; + else if (is_ex_exactly_of_type(exponent, numeric) && ex_to(exponent).is_integer()) { if (basis.is_equal(s)) return ex_to(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(s))) + return n==1 ? _ex1 : _ex0; + else if (!basis.is_equal(s)) { // basis not equal to s if (n == 0) return *this; diff --git a/ginac/symbol.cpp b/ginac/symbol.cpp index f566e233..94d01e4c 100644 --- a/ginac/symbol.cpp +++ b/ginac/symbol.cpp @@ -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(s)) ? 1 : 0; -} - -int symbol::ldegree(const ex & s) const -{ - return is_equal(ex_to(s)) ? 1 : 0; -} - -ex symbol::coeff(const ex & s, int n) const -{ - if (is_equal(ex_to(s))) - return n==1 ? _ex1 : _ex0; - else - return n==0 ? *this : _ex0; -} - ex symbol::eval(int level) const { if (level == -max_recursion_level) diff --git a/ginac/symbol.h b/ginac/symbol.h index bf83c36c..7c96312c 100644 --- a/ginac/symbol.h +++ b/ginac/symbol.h @@ -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; -- 2.45.0