Added .is_polynomial() method.
authorChris Dams <Chris.Dams@mi.infn.it>
Mon, 27 Mar 2006 19:13:21 +0000 (19:13 +0000)
committerChris Dams <Chris.Dams@mi.infn.it>
Mon, 27 Mar 2006 19:13:21 +0000 (19:13 +0000)
15 files changed:
doc/tutorial/ginac.texi
ginac/basic.cpp
ginac/basic.h
ginac/constant.cpp
ginac/constant.h
ginac/ex.cpp
ginac/ex.h
ginac/expairseq.cpp
ginac/expairseq.h
ginac/numeric.cpp
ginac/numeric.h
ginac/power.cpp
ginac/power.h
ginac/symbol.cpp
ginac/symbol.h

index 23956d77268ab12d447848d62809f5df8cc6940d..93b00e6f71e815e1bcea46df9c2ddfaed234cf75 100644 (file)
@@ -905,7 +905,7 @@ int main()
 
 @node The Class Hierarchy, Symbols, Error handling, Basic Concepts
 @c    node-name, next, previous, up
-@section The Class Hierarchy
+@section The class hierarchy
 
 GiNaC's class hierarchy consists of several classes representing
 mathematical objects, all of which (except for @code{ex} and some
@@ -4172,7 +4172,7 @@ after @code{other}.
 
 @node Numerical Evaluation, Substituting Expressions, Information About Expressions, Methods and Functions
 @c    node-name, next, previous, up
-@section Numerical Evaluation
+@section Numerical evaluation
 @cindex @code{evalf()}
 
 GiNaC keeps algebraic expressions, numbers and constants in their exact form.
@@ -4612,7 +4612,7 @@ and not for locating @code{x+y} within @code{x+y+z}.
 
 @node Applying a Function on Subexpressions, Visitors and Tree Traversal, Pattern Matching and Advanced Substitutions, Methods and Functions
 @c    node-name, next, previous, up
-@section Applying a Function on Subexpressions
+@section Applying a function on subexpressions
 @cindex tree traversal
 @cindex @code{map()}
 
@@ -4757,7 +4757,7 @@ argument. You can not use functions like @samp{diff()}, @samp{op()},
 
 @node Visitors and Tree Traversal, Polynomial Arithmetic, Applying a Function on Subexpressions, Methods and Functions
 @c    node-name, next, previous, up
-@section Visitors and Tree Traversal
+@section Visitors and tree traversal
 @cindex tree traversal
 @cindex @code{visitor} (class)
 @cindex @code{accept()}
@@ -4981,6 +4981,22 @@ lst gather_indices(const ex & e)
 @c    node-name, next, previous, up
 @section Polynomial arithmetic
 
+@subsection Testing whether an expression is a polynomial
+@cindex @code{is_polynomial()}
+
+Testing whether an expression is a polynomial in one or more variables
+can be done with the method
+@example
+bool ex::is_polynomial(const ex & vars) const;
+@end example
+In the case of more than
+one variable, the variables are given as a list.
+
+@example
+(x*y*sin(y)).is_polynomial(x)         // Returns true.
+(x*y*sin(y)).is_polynomial(lst(x,y))  // Returns false.
+@end example
+
 @subsection Expanding and collecting
 @cindex @code{expand()}
 @cindex @code{collect()}
@@ -5987,7 +6003,7 @@ J.Vollinga, S.Weinzierl, hep-ph/0410259
 
 @node Complex Conjugation, Solving Linear Systems of Equations, Multiple polylogarithms, Methods and Functions
 @c    node-name, next, previous, up
-@section Complex Conjugation
+@section Complex conjugation
 @c
 @cindex @code{conjugate()}
 
@@ -6021,7 +6037,7 @@ change this behavior, you have to supply a specialized conjugation method for yo
 
 @node Solving Linear Systems of Equations, Input/Output, Complex Conjugation, Methods and Functions
 @c    node-name, next, previous, up
-@section Solving Linear Systems of Equations
+@section Solving linear systems of equations
 @cindex @code{lsolve()}
 
 The function @code{lsolve()} provides a convenient wrapper around some
index f65e3f0cab5a036a305d97f8e51528eb62ad8630..a3c727bebaaa270404cbfc878bf3533a83706288 100644 (file)
@@ -325,6 +325,12 @@ ex basic::map(map_function & f) const
                return *this;
 }
 
+/** Check whether this is a polynomial in the given variables. */
+bool basic::is_polynomial(const ex & var) const
+{
+       return !has(var) || is_equal(ex_to<basic>(var));
+}
+
 /** Return degree of highest power in object s. */
 int basic::degree(const ex & s) const
 {
index fc825226538a1ff5672ddac9cf991eea1932a850..6b117cc9dc1b289b1cdc9cef023f696c449f2fcd 100644 (file)
@@ -180,6 +180,7 @@ public:
        }
 
        // degree/coeff
+       virtual bool is_polynomial(const ex & var) const;
        virtual int degree(const ex & s) const;
        virtual int ldegree(const ex & s) const;
        virtual ex coeff(const ex & s, int n = 1) const;
index 86fb55b7b462b0ec4c418185e2f1f270587caf10..5cfecc96a6dde2e9c68483f4a1a0bef20dd6d64c 100644 (file)
@@ -146,6 +146,11 @@ ex constant::evalf(int level) const
        return *this;
 }
 
+bool constant::is_polynomial(const ex & var) const
+{
+       return true;
+}
+
 // protected
 
 /** Implementation of ex::diff() for a constant always returns 0.
index 331ad209e74e7c377fbcf22ec4d8fb4662474f58..9922637602b999d91a306b6d50f133038d10dcb5 100644 (file)
@@ -49,6 +49,7 @@ public:
        // functions overriding virtual functions from base classes
 public:
        ex evalf(int level = 0) const;
+       bool is_polynomial(const ex & var) const;
 protected:
        ex derivative(const symbol & s) const;
        bool is_equal_same_type(const basic & other) const;
index a5ede054b13eeb35ebb3b50fc90d4b3166a04a94..f1835377d2fbd9b6e0e83c289feea3c8361e36ef 100644 (file)
@@ -240,6 +240,20 @@ ex ex::rhs() const
        return bp->op(1);
 }
 
+/** Check whether expression is a polynomial. */
+bool ex::is_polynomial(const ex & vars) const
+{
+       if (is_a<lst>(vars)) {
+               const lst & varlst = ex_to<lst>(vars);
+               for (lst::const_iterator i=varlst.begin(); i!=varlst.end(); ++i)
+                       if (!bp->is_polynomial(*i))
+                               return false;
+               return true;
+       }
+       else
+               return bp->is_polynomial(vars);
+}
+
 // private
 
 /** Make this ex writable (if more than one ex handle the same basic) by 
index 697f3b4e3aae72ec2c61a228814dd07030300035..c23336ba5fdb56b56df9400068622dc614cbec9c 100644 (file)
@@ -159,6 +159,7 @@ public:
        void traverse(visitor & v) const { traverse_preorder(v); }
 
        // degree/coeff
+       bool is_polynomial(const ex & vars) const;
        int degree(const ex & s) const { return bp->degree(s); }
        int ldegree(const ex & s) const { return bp->ldegree(s); }
        ex coeff(const ex & s, int n = 1) const { return bp->coeff(s, n); }
@@ -690,6 +691,9 @@ inline bool has(const ex & thisex, const ex & pattern, unsigned options = 0)
 inline bool find(const ex & thisex, const ex & pattern, lst & found)
 { return thisex.find(pattern, found); }
 
+inline bool is_polynomial(const ex & thisex, const ex & vars)
+{ return thisex.is_polynomial(vars); }
+
 inline int degree(const ex & thisex, const ex & s)
 { return thisex.degree(s); }
 
index 458b440de0f4a28421d8d636f7598a6041eec9c9..5652d89c30b4b3772e10af0089fca66e77a6ce8c 100644 (file)
@@ -27,6 +27,7 @@
 
 #include "expairseq.h"
 #include "lst.h"
+#include "add.h"
 #include "mul.h"
 #include "power.h"
 #include "relational.h"
@@ -347,6 +348,17 @@ ex expairseq::conjugate() const
        return result;
 }
 
+bool expairseq::is_polynomial(const ex & var) const
+{
+       if (!is_exactly_a<add>(*this) && !is_exactly_a<mul>(*this))
+               return basic::is_polynomial(var);
+       for (epvector::const_iterator i=seq.begin(); i!=seq.end(); ++i) {
+               if (!(i->rest).is_polynomial(var))
+                       return false;
+       }
+       return true;
+}
+
 bool expairseq::match(const ex & pattern, lst & repl_lst) const
 {
        // This differs from basic::match() because we want "a+b+c+d" to
index acc2ce1e397307b7b172e8ba2d3dc5c8ba4b51a4..4cfc057961e53d9356c8e811092f19de04f249b0 100644 (file)
@@ -86,6 +86,7 @@ public:
        bool match(const ex & pattern, lst & repl_lst) const;
        ex subs(const exmap & m, unsigned options = 0) const;
        ex conjugate() const;
+       bool is_polynomial(const ex & var) const;
 protected:
        bool is_equal_same_type(const basic & other) const;
        unsigned return_type() const;
index b8170e716ff3220685cb490d1a9ccf6473c23947..278741f1e43aec63aa875dd56dd8092687ff58b6 100644 (file)
@@ -603,6 +603,11 @@ bool numeric::info(unsigned inf) const
        return false;
 }
 
+bool numeric::is_polynomial(const ex & var) const
+{
+       return true;
+}
+
 int numeric::degree(const ex & s) const
 {
        return 0;
index f0e3362f8965aec7bcd5aaf199e6d65f1f3362d7..ff460638e0ed3c402b3499040200d534880e4d89 100644 (file)
@@ -105,6 +105,7 @@ public:
 public:
        unsigned precedence() const {return 30;}
        bool info(unsigned inf) const;
+       bool is_polynomial(const ex & var) const;
        int degree(const ex & s) const;
        int ldegree(const ex & s) const;
        ex coeff(const ex & s, int n = 1) const;
index 6f6f178de07729254e28e6530455446ed3103abf..95a01acec2b5d31c4312ced86020990d99dc4fd7 100644 (file)
@@ -258,6 +258,15 @@ ex power::map(map_function & f) const
                return *this;
 }
 
+bool power::is_polynomial(const ex & var) const
+{
+       if (exponent.has(var))
+               return false;
+       if (!exponent.info(info_flags::nonnegint))
+               return false;
+       return basis.is_polynomial(var);
+}
+
 int power::degree(const ex & s) const
 {
        if (is_equal(ex_to<basic>(s)))
index 48ca5b5d67922907612a15de8c8606f681c3b572..c76452476bbedc29f8b4fc32ed78cc554ecc6666 100644 (file)
@@ -54,6 +54,7 @@ public:
        size_t nops() const;
        ex op(size_t i) const;
        ex map(map_function & f) const;
+       bool is_polynomial(const ex & var) const;
        int degree(const ex & s) const;
        int ldegree(const ex & s) const;
        ex coeff(const ex & s, int n = 1) const;
index 6b37ee123e30d45082eb90b618e2253944141230..10b38a8eb71f8750e4671a2742db328bf9d62da8 100644 (file)
@@ -226,6 +226,11 @@ ex symbol::conjugate() const
        }
 }
 
+bool symbol::is_polynomial(const ex & var) const
+{
+       return true;
+}
+
 // protected
 
 /** Implementation of ex::diff() for single differentiation of a symbol.
index 3b187d617bf9d71f90159fe18ab0df53549b4595..b7c17a8000ecd3eff0b271eae6a3b1ce60bac524 100644 (file)
@@ -75,6 +75,7 @@ public:
        unsigned return_type() const { return ret_type; }
        tinfo_t return_type_tinfo() const { return ret_type_tinfo; }
        ex conjugate() const;
+       bool is_polynomial(const ex & var) const;
 protected:
        ex derivative(const symbol & s) const;
        bool is_equal_same_type(const basic & other) const;