GiNaCRA  0.6.4
constants.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_CONSTANTS_H
00024 #define GINACRA_CONSTANTS_H
00025 
00036 #include <numeric> // provides accumulate(..)
00037 #include <sstream>
00038 #include <string>
00039 #include <ginac/ginac.h>
00040 
00041 using std::string;
00042 using std::stringstream;
00043 using std::binary_function;
00044 using std::unary_function;
00045 using std::vector;
00046 using std::list;
00047 using std::pair;
00048 using GiNaC::basic;
00049 using GiNaC::numeric;
00050 using GiNaC::ex;
00051 
00052 namespace GiNaC
00053 {
00056     typedef struct infinitesimal_symbol_struct:
00057         public symbol
00058     {
00059         numeric limit_value;
00060 
00063         infinitesimal_symbol_struct():
00064             symbol(),
00065             limit_value( 0 )
00066         {}
00067 
00071         infinitesimal_symbol_struct( const std::string& name ):
00072             symbol( name ),
00073             limit_value( 0 )
00074         {}
00075 
00080         infinitesimal_symbol_struct( const std::string& name, const numeric& l ):
00081             symbol( name ),
00082             limit_value( l )
00083         {}
00084 
00085         const numeric limit()
00086         {
00087             return limit_value;
00088         }
00089 
00090     } infinitesimal_symbol;
00091 
00092     // infinitesimal elements: epsilon < delta < gamma < zeta
00093     const infinitesimal_symbol EPSILON( "€" );
00094     const infinitesimal_symbol DELTA( "ð" );
00095     const infinitesimal_symbol GAMMA( "đ" );
00096     const infinitesimal_symbol ZETA( "¢" );
00097 
00099     enum sign { NEGATIVE_SIGN = -1, ZERO_SIGN = 0, POSITIVE_SIGN = 1 };
00100 
00102     const symbol X( "X" );
00103 
00105     const numeric ZERO( 0 );
00106 
00109     struct ex_is_lessdeg:
00110         public binary_function<ex, ex, bool>
00111     {
00112         vector<symbol> variables;
00113 
00114         ex_is_lessdeg( const vector<symbol>& variables ):
00115             variables( variables )
00116         {}
00117 
00123         bool operator ()( const ex& a, const ex& b ) const
00124         {
00125             return true;
00126         }
00127 
00128         struct get_degree:
00129             public unary_function<symbol, int>
00130         {
00131             ex p;
00132 
00133             get_degree( const ex& q ):
00134                 p( q )
00135             {}
00136 
00137             int operator ()( const symbol& x )
00138             {
00139                 return p.degree( x );
00140             }
00141         };
00142 
00143         inline list<int> exponents( const ex& p, const vector<symbol>& variables ) const
00144         {
00145             int n = 0;
00146             for( vector<symbol>::const_iterator i = variables.begin(); i != variables.end(); ++i )
00147                 n++;
00148             list<int> exponents( n, 0 );
00149             transform( variables.begin(), variables.end(), exponents.begin(), get_degree( p ));
00150             return exponents;
00151         }
00152     };
00153 
00156     struct ex_is_less_deggrlex:
00157         public ex_is_lessdeg
00158     {
00159         ex_is_less_deggrlex( const vector<symbol>& variables ):
00160             ex_is_lessdeg( variables )
00161         {}
00162 
00168         bool operator ()( const ex& a, const ex& b ) const
00169         {
00170             list<int> e1   = exponents( a, variables );
00171             list<int> e2   = exponents( b, variables );
00172             int       deg1 = accumulate( e1.begin(), e1.end(), 0 );
00173             int       deg2 = accumulate( e2.begin(), e2.end(), 0 );
00174             if( deg1 < deg2 )
00175                 return true;
00176             else if( deg1 > deg2 )
00177                 return false;
00178             else
00179                 // return !lexicographical_compare(e1.begin(), e1.end(), e2.begin(), e2.end()); // for weak ordering!
00180                 return lexicographical_compare( e2.begin(), e2.end(), e1.begin(), e1.end() );
00181         }
00182     };
00183 
00186     struct ex_is_less_degrevlex:
00187         public ex_is_lessdeg
00188     {
00189         ex_is_less_degrevlex( const vector<symbol>& variables ):
00190             ex_is_lessdeg( variables )
00191         {}
00192 
00198         bool operator ()( const ex& a, const ex& b ) const
00199         {
00200             list<int> e1   = exponents( a, variables );
00201             list<int> e2   = exponents( b, variables );
00202             int       deg1 = accumulate( e1.begin(), e1.end(), 0 );
00203             int       deg2 = accumulate( e2.begin(), e2.end(), 0 );
00204             if( deg1 < deg2 )
00205                 return true;
00206             else if( deg1 > deg2 )
00207                 return false;
00208             else
00209                 //          return !lexicographical_compare(e1.rbegin(), e1.rend(), e2.rbegin(), e2.rend()); // for weak ordering!
00210                 return lexicographical_compare( e2.rbegin(), e2.rend(), e1.rbegin(), e1.rend() );
00211         }
00212     };
00213 
00218     struct ex_is_under_the_staircase:
00219         public unary_function<ex, bool>
00220     {
00221         list<ex> corners;
00222 
00223         ex_is_under_the_staircase( const list<ex> corners ):
00224             corners( corners )
00225         {}
00226 
00232         bool operator ()( const ex& monomial ) const
00233         {
00234             for( list<ex>::const_iterator i = corners.begin(); i != corners.end(); ++i )
00235             {
00236                 ex q = 0;
00237                 if( divide( *i, monomial, q ))    // monomial divides *i by q
00238                     return true;
00239             }
00240             return false;
00241         }
00242     };
00243 
00246     template<class monomialOrdering>
00247     struct expair_is_lesseq:
00248         public binary_function<pair<ex, ex>, pair<ex, ex>, bool>
00249     {
00250         vector<symbol> variables;
00251 
00252         expair_is_lesseq( const vector<symbol>& variables ):
00253             variables( variables )
00254         {}
00255 
00261         bool operator ()( const pair<ex, ex>& a, const pair<ex, ex>& b ) const
00262         {
00263             return monomialOrdering( variables )( a.second, b.second );
00264         }
00265 
00266     };
00267 
00268 }    // namespace GiNaC
00269 
00270 #endif // GINACRA_CONSTANTS_H