GiNaCRA
0.6.4
|
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