GiNaCRA  0.6.4
UnivariatePolynomial.h
Go to the documentation of this file.
00001 /*
00002  * GiNaCRA - GiNaC Real Algebra package
00003  * Copyright (C) 2010-2012  Ulrich Loup, Joachim Redies, Sebastian Junges
00004  *
00005  * This file is part of GiNaCRA.
00006  *
00007  * GiNaCRA is free software: you can redistribute it and/or modify
00008  * it under the terms of the GNU General Public License as published by
00009  * the Free Software Foundation, either version 3 of the License, or
00010  * (at your option) any later version.
00011  *
00012  * GiNaCRA is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with GiNaCRA.  If not, see <http://www.gnu.org/licenses/>.
00019  *
00020  */
00021 
00022 
00023 #ifndef GINACRA_UNIVARIATEPOLYNOMIAL_H
00024 #define GINACRA_UNIVARIATEPOLYNOMIAL_H
00025 
00026 #include <ginac/flags.h>
00027 #include <ginac/ginac.h>
00028 #include <stdexcept>
00029 
00030 #include "constants.h"
00031 #include "Polynomial.h"
00032 
00033 using std::ostream;
00034 using std::invalid_argument;
00035 using std::overflow_error;
00036 using std::list;
00037 using GiNaC::symbol;
00038 using GiNaC::print_context;
00039 using GiNaC::X;
00040 
00041 namespace GiNaCRA
00042 {
00051     class UnivariatePolynomial:
00052         public Polynomial
00053     {
00054         public:
00055 
00057             // Con- and destructors //
00059 
00063             UnivariatePolynomial():
00064                 Polynomial( 0 ),
00065                 mVariable( X ),
00066                 mEnabledPolynomialCheck( false )
00067             {}
00068 
00073             UnivariatePolynomial( const numeric& n ):
00074                 Polynomial( X - n ),
00075                 mVariable( X ),
00076                 mEnabledPolynomialCheck( false )
00077             {}
00078 
00085             UnivariatePolynomial( const ex& p, const symbol& s, bool enableCheck = true ) throw ( invalid_argument );
00086 
00091             UnivariatePolynomial( const UnivariatePolynomial& p ):
00092                 Polynomial( p ),
00093                 mVariable( p.mVariable ),
00094                 mEnabledPolynomialCheck( p.mEnabledPolynomialCheck )
00095             {}
00096 
00098             // Selectors //
00100 
00105             const symbol variable() const
00106             {
00107                 return mVariable;
00108             }
00109 
00114             const bool enabledPolynomialCheck() const
00115             {
00116                 return mEnabledPolynomialCheck;
00117             }
00118 
00120             // Operators //
00122 
00123             UnivariatePolynomial inVariable( const symbol& x ) const
00124             {
00125                 return UnivariatePolynomial( this->subs( mVariable == x ), x );
00126             }
00127 
00128             // assignment operators
00129 
00133             const UnivariatePolynomial& operator = ( const UnivariatePolynomial& );
00134 
00138             const UnivariatePolynomial& operator = ( const ex& );
00139 
00141             // Operations //
00143 
00148             ex coeff( int i ) const
00149             {
00150                 return ex::coeff( mVariable, i );
00151             }
00152 
00156             ex lcoeff() const
00157             {
00158                 return ex::lcoeff( mVariable );
00159             }
00160 
00164             ex tcoeff() const
00165             {
00166                 return ex::tcoeff( mVariable );
00167             }
00168 
00172             ex content() const
00173             {
00174                 return ex::content( mVariable );
00175             }
00176 
00181             UnivariatePolynomial diff( unsigned nth = 1 ) const
00182             {
00183                 return UnivariatePolynomial( ex::diff( mVariable, nth ), mVariable, mEnabledPolynomialCheck );
00184             }
00185 
00190             UnivariatePolynomial trunc() const;
00191 
00196             bool isZero() const
00197             {
00198                 return ex::is_zero();
00199             }
00200 
00204             const bool hasZeroRoot() const
00205             {
00206                 return ldegree() > 0;
00207             }
00208 
00212             int degree() const
00213             {
00214                 return ex::degree( mVariable );
00215             }
00216 
00220             int ldegree() const
00221             {
00222                 return ex::ldegree( mVariable );
00223             }
00224 
00228             UnivariatePolynomial primpart() const
00229             {
00230                 return UnivariatePolynomial( ex::primpart( mVariable ), mVariable, mEnabledPolynomialCheck );
00231             }
00232 
00237             UnivariatePolynomial primpart( const ex& content ) const
00238             {
00239                 return UnivariatePolynomial( ex::primpart( mVariable, content ), mVariable, mEnabledPolynomialCheck );
00240             }
00241 
00248             UnivariatePolynomial sepapart() const;
00249 
00253             UnivariatePolynomial nonzeropart() const;
00254 
00259             bool isCompatible( const UnivariatePolynomial& o ) const
00260             {
00261                 return mVariable == o.mVariable;
00262             }
00263 
00268             bool isConstant() const
00269             {
00270                 return ex::degree( mVariable ) == 0;
00271             }
00272 
00277             ex evaluateAt( const ex& a ) const
00278             {
00279                 return UnivariatePolynomial( ex::subs( mVariable == a ), mVariable );
00280             }
00281 
00283             // Arithmetic Operations //
00285 
00291             const UnivariatePolynomial rem( const UnivariatePolynomial& o ) const
00292             {
00293                 return UnivariatePolynomial( GiNaC::rem( *this, o, mVariable ), mVariable );
00294             }
00295 
00301             const UnivariatePolynomial quo( const UnivariatePolynomial& o ) const
00302             {
00303                 return UnivariatePolynomial( GiNaC::quo( *this, o, mVariable ), mVariable, mEnabledPolynomialCheck );
00304             }
00305 
00311             const UnivariatePolynomial add( const UnivariatePolynomial& o ) const
00312             {
00313                 return UnivariatePolynomial( *this + o, mVariable, mEnabledPolynomialCheck );
00314             }
00315 
00321             const UnivariatePolynomial mul( const UnivariatePolynomial& o ) const
00322             {
00323                 return UnivariatePolynomial( *this * o, mVariable, mEnabledPolynomialCheck );
00324             }
00325 
00331             const UnivariatePolynomial sub( const UnivariatePolynomial& o ) const
00332             {
00333                 return UnivariatePolynomial( *this - o, mVariable, mEnabledPolynomialCheck );
00334             }
00335 
00340             UnivariatePolynomial square() const
00341             {
00342                 return UnivariatePolynomial( (*this) * (*this), mVariable, mEnabledPolynomialCheck );
00343             }
00344 
00351             const UnivariatePolynomial gcd( const UnivariatePolynomial& o ) const
00352             {
00353                 return UnivariatePolynomial( GiNaC::gcd( *this, o ), mVariable, mEnabledPolynomialCheck );
00354             }
00355 
00364             const UnivariatePolynomial resultant( const UnivariatePolynomial& o ) const
00365             {
00366                 return UnivariatePolynomial( GiNaC::resultant( *this, o, mVariable ), mVariable );
00367                 //                return UnivariatePolynomial::subresultants( *this, o ).front();
00368             }
00369 
00371             // Relational Operations //
00373 
00378             const bool isEqual( const UnivariatePolynomial& o ) const
00379             {
00380                 return (this->is_equal( o ) && mVariable.is_equal( o.mVariable ));
00381             }
00382 
00384             // Static Methods //
00386 
00396             static list<UnivariatePolynomial> standardSturmSequence( const UnivariatePolynomial& a,
00397                                                                      const UnivariatePolynomial& b )
00398                     throw ( invalid_argument );
00399 
00406             static bool univariatePolynomialIsLess( const UnivariatePolynomial& a, const UnivariatePolynomial& b );
00407 
00416             static bool univariatePolynomialIsLessLowDeg( const UnivariatePolynomial& a, const UnivariatePolynomial& b );
00417 
00426             static bool univariatePolynomialIsLessOddDeg( const UnivariatePolynomial& a, const UnivariatePolynomial& b );
00427 
00436             static bool univariatePolynomialIsLessOddLowDeg( const UnivariatePolynomial& a, const UnivariatePolynomial& b );
00437 
00446             static bool univariatePolynomialIsLessEvenDeg( const UnivariatePolynomial& a, const UnivariatePolynomial& b );
00447 
00456             static bool univariatePolynomialIsLessEvenLowDeg( const UnivariatePolynomial& a, const UnivariatePolynomial& b );
00457 
00461             enum subresultantStrategy
00462             {
00463                 GENERIC_SUBRESULTANTSTRATEGY = 0,    /* * Generic algorithm. */
00464                 LAZARDS_SUBRESULTANTSTRATEGY = 1,    /* * Perform Lazard's optimization. */
00465                 DUCOS_SUBRESULTANTSTRATEGY = 2,    /* * Perform Ducos' optimization. */
00466             };
00467 
00481             static const list<UnivariatePolynomial> subresultants( const UnivariatePolynomial& a,
00482                                                                    const UnivariatePolynomial& b,
00483                                                                    const subresultantStrategy strategy = GENERIC_SUBRESULTANTSTRATEGY );
00484 
00494             static const vector<ex> subresultantCoefficients( const UnivariatePolynomial& a,
00495                                                               const UnivariatePolynomial& b,
00496                                                               const subresultantStrategy strategy = GENERIC_SUBRESULTANTSTRATEGY );
00497 
00507             static const vector<ex> principalSubresultantCoefficients( const UnivariatePolynomial& a,
00508                                                                        const UnivariatePolynomial& b,
00509                                                                        const subresultantStrategy strategy = GENERIC_SUBRESULTANTSTRATEGY );
00510 
00512             // Methods from ex //
00514 
00515             void do_print( const print_context& c, unsigned level = 0 ) const;
00516 
00517         protected:
00518 
00520             // Attributes //
00522 
00523             symbol mVariable;    // the main variable of the univariate polynomial (only changed by using operator=)
00524             bool   mEnabledPolynomialCheck;    // flag to disable (when set to false) the is_polynomial check in the constructors in every method of this object
00525 
00526         private:
00527 
00529             // Auxiliary Methods //
00531 
00532     };    // class UnivariatePolynomial
00533 
00534 }    // namespace GiNaC
00535 
00536 #endif