1 // -*- mode: C++ ; compile-command: "g++ -I.. -g -O2 -c index.cc" -*- 2 /* 3 * Copyright (C) 2000,2014 B. Parisse, Institut Fourier, 38402 St Martin d'Heres 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 3 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 */ 18 #ifndef _GIAC_INDEX_H_ 19 #define _GIAC_INDEX_H_ 20 #include "first.h" 21 #include "vector.h" 22 #include <iostream> 23 #include <string> 24 #include <cassert> 25 26 ////////////////////////////////////////// 27 /// this commented and the old put back due to build issues... temporary change to get build going 28 //#if defined(VISUALC) && !defined(ConnectivityKit) 29 //#pragma anon_unions 30 //#endif 31 //======================================== 32 #if !defined ConnectivityKit && !defined _MSC_VER && !defined FREERTOS 33 #pragma anon_unions 34 #endif 35 /////////////////////////////////////////// 36 37 #if defined C11_UNORDERED_MAP && (defined __clang__ || !defined __APPLE__) 38 #undef HASH_MAP 39 #undef EXT_HASH_MAP 40 #undef UNORDERED_MAP 41 #define HASH_MAP_NAMESPACE std 42 #define hash_map unordered_map 43 #include <unordered_map> 44 #endif 45 46 #if defined UNORDERED_MAP && !defined(VISUALC) // && !defined(__APPLE__) && !defined(__clang__) 47 #include <tr1/unordered_map> 48 #define HASH_MAP_NAMESPACE std::tr1 49 #define hash_map unordered_map 50 #else // UNORDERED_MAP 51 52 #if defined(VISUALC) || defined(FIR) || defined(__ANDROID__) // || defined(OSX) || defined(IOS)) 53 #undef HASH_MAP 54 #undef EXT_HASH_MAP 55 #endif 56 57 #ifdef HASH_MAP 58 #include <hash_map> 59 #ifndef HASH_MAP_NAMESPACE 60 #ifndef VISUALC 61 #define HASH_MAP_NAMESPACE std 62 #endif // VISUALC 63 #endif // HASH_MAP_NAMESPACE 64 #endif 65 66 #ifdef EXT_HASH_MAP 67 #include <ext/hash_map> 68 #ifndef HASH_MAP_NAMESPACE 69 #define HASH_MAP_NAMESPACE __gnu_cxx 70 #endif 71 #endif 72 73 #endif // UNORDERED_MAP 74 75 #ifndef NO_NAMESPACE_GIAC 76 namespace giac { 77 #endif // ndef NO_NAMESPACE_GIAC 78 79 typedef short int deg_t; 80 typedef std::vector<deg_t> index_t; 81 82 int mygcd(int a,int b); 83 void swapint(int & a,int & b); 84 void swapdouble(double & a,double & b); 85 86 // index type for tensors 87 void add(const index_t & a, const index_t & b,index_t & res); 88 89 index_t operator + (const index_t & a, const index_t & b); 90 index_t operator - (const index_t & a, const index_t & b); 91 index_t operator | (const index_t & a, const index_t & b); 92 index_t operator - (const index_t & a); 93 index_t operator * (const index_t & a, int fois); 94 inline index_t operator * (int fois,const index_t & a){ return a*fois; } 95 index_t operator / (const index_t & a, int divisepar); 96 int operator / (const index_t & a, const index_t & b); 97 // >= and <= are *partial* ordering on index_t 98 // they return TRUE if and only if >= or <= is true for *all* coordinates 99 bool all_sup_equal (const index_t & a, const index_t & b); 100 inline bool operator >= (const index_t & a, const index_t & b){ return all_sup_equal(a,b); } 101 bool all_inf_equal (const index_t & a, const index_t & b); 102 inline bool operator <= (const index_t & a, const index_t & b){ return all_inf_equal(a,b); } 103 void index_gcd(const index_t & a,const index_t & b,index_t & res); 104 index_t index_gcd(const index_t & a,const index_t & b); 105 index_t index_lcm(const index_t & a,const index_t & b); index_min(const index_t & a,const index_t & b)106 inline index_t index_min(const index_t & a,const index_t & b){ return index_gcd(a,b); } index_max(const index_t & a,const index_t & b)107 inline index_t index_max(const index_t & a,const index_t & b){ return index_lcm(a,b); } 108 void dbgprint(const index_t & i); 109 void add_print_INT_(std::string & s,int i); 110 std::string print_INT_(int i); 111 std::string hexa_print_INT_(int i); 112 std::string octal_print_INT_(int i); 113 std::string binary_print_INT_(int i); 114 std::string print_INT_(const std::vector<int> & v); 115 std::string print_INT_(const std::vector<short int> & v); 116 117 template <class T> T pow(const std::vector<T> & x, const index_t & n ); 118 119 // total degree of a std::vector 120 template <class T> T total_degree(const std::vector<T> & v1); 121 122 // two ordering function over indices: lex ordering and total order then lex 123 template <class T> 124 bool lex_is_greater(const std::vector<T> & v1, const std::vector<T> & v2); 125 template <class T> 126 bool total_revlex_is_greater(const std::vector<T> & v1, const std::vector<T> & v2); 127 template <class T> 128 bool total_lex_is_greater(const std::vector<T> & v1, const std::vector<T> & v2); 129 130 index_t mergeindex(const index_t & i,const index_t & j); 131 // permutation inverse 132 std::vector<int> inverse(const std::vector<int> & p); 133 // transposition 134 std::vector<int> transposition(int i,int j,int size); 135 bool has(const index_t & p,int r); 136 // zero? 137 bool is_zero(const index_t & p); 138 pow(const std::vector<T> & x,const index_t & n)139 template <class T> T pow(const std::vector<T> & x, const index_t & n ){ 140 assert(x.size()==n.size()); 141 typename std::vector<T>::const_iterator itx=x.begin(); 142 index_t::const_iterator itn=n.begin(); 143 T res(1); 144 for (;itx!=x.end();++itx,++itn){ 145 res=res*pow(*itx,*itn); 146 } 147 return res; 148 } 149 total_degree(const std::vector<T> & v1)150 template <class T> T total_degree(const std::vector<T> & v1){ 151 T i=0; 152 for (typename std::vector<T>::const_iterator it=v1.begin();it!=v1.end();++it) 153 i=i+(*it); 154 return(i); 155 } 156 157 template <class T> lex_is_greater(const std::vector<T> & v1,const std::vector<T> & v2)158 bool lex_is_greater(const std::vector<T> & v1, const std::vector<T> & v2){ 159 assert(v1.size()==v2.size()); 160 typename std::vector<T>::const_iterator it1=v1.begin(),it1end=v1.end(); 161 typename std::vector<T>::const_iterator it2=v2.begin(); 162 for (;it1!=it1end;++it2,++it1){ 163 if ( (*it1)!=(*it2) ){ 164 if ( (*it1)>(*it2)) 165 return(true); 166 else 167 return(false); 168 } 169 } 170 return(true); 171 } 172 173 template <class T> lex_is_strictly_greater(const std::vector<T> & v1,const std::vector<T> & v2)174 bool lex_is_strictly_greater(const std::vector<T> & v1, const std::vector<T> & v2){ 175 assert(v1.size()==v2.size()); 176 typename std::vector<T>::const_iterator it1=v1.begin(),it1end=v1.end(); 177 typename std::vector<T>::const_iterator it2=v2.begin(); 178 for (;it1!=it1end;++it2,++it1){ 179 if ( (*it1)!=(*it2) ){ 180 if ( (*it1)>(*it2)) 181 return true; 182 else 183 return false; 184 } 185 } 186 return false; 187 } 188 189 bool lex_is_strictly_greater_deg_t(const std::vector<deg_t> & v1, const std::vector<deg_t> & v2); 190 191 template <class T> total_lex_is_greater(const std::vector<T> & v1,const std::vector<T> & v2)192 bool total_lex_is_greater(const std::vector<T> & v1, const std::vector<T> & v2){ 193 T d1=total_degree(v1); 194 T d2=total_degree(v2); 195 if (d1!=d2){ 196 if (d1>d2) 197 return(true); 198 else 199 return(false); 200 } 201 return(lex_is_greater<T>(v1,v2)); 202 } 203 204 template <class T> total_revlex_is_greater(const std::vector<T> & v1,const std::vector<T> & v2)205 bool total_revlex_is_greater(const std::vector<T> & v1, const std::vector<T> & v2){ 206 T d1=total_degree(v1); 207 T d2=total_degree(v2); 208 if (d1!=d2){ 209 if (d1>d2) 210 return(true); 211 else 212 return(false); 213 } 214 // return(!lex_is_strictly_greater<T>(v1,v2)); but starting from end 215 typename std::vector<T>::const_iterator it1=v1.end()-1,it1end=v1.begin()-1; 216 typename std::vector<T>::const_iterator it2=v2.end()-1; 217 for (;it1!=it1end;--it2,--it1){ 218 if ( *it1 != *it2 ) 219 return *it1<*it2; 220 } 221 return true; 222 } 223 224 template <class T> total_revlex_is_strictly_greater(const std::vector<T> & v1,const std::vector<T> & v2)225 bool total_revlex_is_strictly_greater(const std::vector<T> & v1, const std::vector<T> & v2){ 226 return !total_revlex_is_greater<T>(v2,v1); 227 } 228 229 //***************************************** 230 // class for memory efficient indices 231 //***************************************** 232 233 class ref_index_t { 234 public: 235 ref_count_t ref_count; 236 index_t i; ref_index_t()237 ref_index_t():ref_count(1) {} ref_index_t(int s)238 ref_index_t(int s):ref_count(1),i(s) {} ref_index_t(const index_t & I)239 ref_index_t(const index_t & I):ref_count(1),i(I) {} ref_index_t(index_t::const_iterator it,index_t::const_iterator itend)240 ref_index_t(index_t::const_iterator it,index_t::const_iterator itend):ref_count(1),i(it,itend) {} 241 }; 242 243 // direct access to deg_t in index_m 244 const int POLY_VARS_DIRECT=sizeof(ref_index_t *)/sizeof(deg_t); 245 // HAS_POLY_VARS_OTHER defines the number of word (pointer size) for 246 // other deg_t directly encoded. Comment if none 247 #define HAS_POLY_VARS_OTHER 1 248 #if HAS_POLY_VARS_OTHER 249 const int POLY_VARS_OTHER=HAS_POLY_VARS_OTHER*POLY_VARS_DIRECT; 250 #else 251 const int POLY_VARS_OTHER=0; 252 #endif 253 // capacity of deg_t by direct addressing 254 const int POLY_VARS=POLY_VARS_DIRECT+POLY_VARS_OTHER-1; 255 256 #if defined(GIAC_NO_OPTIMIZATIONS) || ((defined(VISUALC) || defined(__APPLE__)) && !defined(GIAC_VECTOR)) || defined __clang__ || defined S390X // || defined(NSPIRE) || defined FXCG 257 class index_m { 258 public: 259 ref_index_t * riptr; 260 // construct index_m(const index_m & im)261 index_m(const index_m & im) { 262 riptr=im.riptr; 263 ++riptr->ref_count; 264 } index_m(const index_t & i)265 index_m(const index_t & i){ 266 riptr=new ref_index_t(i); 267 } index_m()268 index_m(){ riptr=new ref_index_t; } index_m(size_t s)269 index_m(size_t s){ 270 riptr=new ref_index_t(s); 271 } index_m(index_t::const_iterator it,index_t::const_iterator itend)272 index_m(index_t::const_iterator it,index_t::const_iterator itend){ 273 riptr=new ref_index_t(it,itend); 274 } 275 // delete ~index_m()276 ~index_m(){ 277 --riptr->ref_count; 278 if (!riptr->ref_count) 279 delete riptr; 280 } 281 // copy 282 const index_m & operator = (const index_m & other){ 283 --riptr->ref_count; 284 if (!riptr->ref_count) 285 delete riptr; 286 riptr=other.riptr; 287 ++riptr->ref_count; 288 return *this; 289 } 290 291 // members iref()292 index_t iref() const { return riptr->i;} ; begin()293 index_t::iterator begin() { return riptr->i.begin(); } end()294 index_t::iterator end() { return riptr->i.end(); } begin()295 index_t::const_iterator begin() const { return riptr->i.begin(); } end()296 index_t::const_iterator end() const { return riptr->i.end(); } 297 #if !defined(NSPIRE) && !defined(FXCG) && !defined(OSX) && !defined(IOS) && !defined(OSXIOS) rbegin()298 index_t::reverse_iterator rbegin() { return riptr->i.rbegin(); } rend()299 index_t::reverse_iterator rend() { return riptr->i.rend(); } rbegin()300 index_t::const_reverse_iterator rbegin() const { return riptr->i.rbegin(); } rend()301 index_t::const_reverse_iterator rend() const { return riptr->i.rend(); } 302 #endif front()303 deg_t & front() { return *begin(); } front()304 deg_t front() const { return *begin(); } back()305 deg_t & back() { return *(end()-1); } back()306 deg_t back() const { return *(end()-1); } 307 deg_t & operator [] (size_t pos) { return *(begin()+pos); } 308 deg_t operator [] (size_t pos) const { return *(begin()+pos); } clear()309 void clear() { riptr->i.clear(); } reserve(size_t n)310 void reserve(size_t n) { riptr->i.reserve(n); } push_back(deg_t x)311 void push_back(deg_t x) { riptr->i.push_back(x); } size()312 size_t size() const { return riptr->i.size(); } 313 bool is_zero() const ; 314 size_t total_degree() const ; 315 #ifdef KHICAS 316 friend stdostream & operator << (stdostream & os,const index_m & m ){ 317 os << ":index_m:[ " ; 318 for (index_t::const_iterator it=m.begin();it!=m.end();++it) 319 os << *it << " "; 320 os << "] " ; 321 return(os); 322 } 323 #endif 324 #ifdef NSPIRE 325 template<class T> friend nio::ios_base<T> & operator << (nio::ios_base<T> & os,const index_m & m ){ 326 os << ":index_m:[ " ; 327 for (index_t::const_iterator it=m.begin();it!=m.end();++it) 328 os << *it << " "; 329 os << "] " ; 330 return(os); 331 } 332 #else 333 friend std::ostream & operator << (std::ostream & os, const index_m & m ){ 334 os << ":index_m:[ " ; 335 for (index_t::const_iterator it=m.begin();it!=m.end();++it) 336 os << *it << " "; 337 os << "] " ; 338 return(os); 339 } 340 #endif dbgprint()341 void dbgprint() const { 342 COUT << *this << '\n'; 343 } 344 // set first index element to 0 set_first_zero()345 index_m set_first_zero() const { index_t i(riptr->i); i[0]=0; return i; } 346 }; 347 348 #else // VISUALC 349 class index_m { 350 public: 351 union { 352 ref_index_t * riptr; 353 struct { 354 deg_t taille; 355 deg_t direct[POLY_VARS_DIRECT-1]; 356 }; 357 }; 358 #ifdef HAS_POLY_VARS_OTHER 359 deg_t other[POLY_VARS_OTHER]; 360 #endif 361 // construct index_m(const index_m & im)362 index_m(const index_m & im) { 363 if ( im.taille % 2){ 364 * (size_t *) & taille = * (size_t *) &im.taille; 365 #if (HAS_POLY_VARS_OTHER==1) 366 * (size_t *) other = * (size_t *) im.other; 367 #endif 368 #if (HAS_POLY_VARS_OTHER==2) 369 * (size_t *) other = * (size_t *) im.other; 370 * (((size_t *) other)+1) = * (((size_t *) im.other)+1); 371 #endif 372 #if (HAS_POLY_VARS_OTHER>2) 373 size_t * target = (size_t *) other, * end = target + POLY_VARS_OTHER/(sizeof(size_t)/sizeof(deg_t)); 374 const size_t * source = (size_t *) im.other; 375 for (;target!=end;++target,++source) 376 *target=*source; 377 #endif 378 } else { 379 riptr=im.riptr; 380 ++riptr->ref_count; 381 } 382 } index_m(const index_t & i)383 index_m(const index_t & i){ 384 int s=int(i.size()); 385 if (s<=POLY_VARS){ 386 taille=2*s+1; 387 deg_t * target=direct,*end=direct+s; 388 index_t::const_iterator source=i.begin(); 389 for (;target!=end;++source,++target){ 390 *target=*source; 391 } 392 } 393 else { 394 // taille = 0; 395 riptr=new ref_index_t(i); 396 } 397 } index_m()398 index_m(){ taille =1; } index_m(size_t s)399 index_m(size_t s){ 400 if (int(s)<=POLY_VARS){ 401 riptr=0; 402 taille=2*int(s)+1; 403 #if (HAS_POLY_VARS_OTHER==1) 404 * (size_t *) other =0; 405 #endif 406 #if (HAS_POLY_VARS_OTHER==2) 407 * (size_t *) other =0; 408 * (((size_t *) other)+1) =0; 409 #endif 410 #if (HAS_POLY_VARS_OTHER>2) 411 size_t * target = (size_t *) other ; 412 size_t * end = target + POLY_VARS_OTHER/(sizeof(size_t)/sizeof(deg_t)); 413 for (;target!=end;++target) 414 *target = 0; 415 #endif 416 } 417 else { 418 // taille=0; 419 riptr=new ref_index_t(int(s)); 420 } 421 } index_m(index_t::const_iterator it,index_t::const_iterator itend)422 index_m(index_t::const_iterator it,index_t::const_iterator itend){ 423 if (itend-it<=POLY_VARS){ 424 taille=2*int(itend-it)+1; 425 deg_t * target = direct; 426 for (;it!=itend;++it,++target){ 427 *target=*it; 428 } 429 } 430 else { 431 // taille=0; 432 riptr=new ref_index_t(it,itend); 433 } 434 } 435 // ptr[0] must be 2*size+1 index_m(deg_t * ptr)436 index_m(deg_t * ptr){ 437 /* 438 #ifdef DEBUG_SUPPORT 439 if (ptr[0]/2>POLY_VARS) 440 setsizeerr("Error index.h, size too large for direct access"); 441 #endif 442 */ 443 size_t * source = (size_t *) ptr; 444 *(size_t *) &taille = *(size_t *) source; 445 #if (HAS_POLY_VARS_OTHER==1) 446 ++source; 447 * (size_t *) other = *source; 448 #endif 449 #if (HAS_POLY_VARS_OTHER==2) 450 ++source; 451 * (size_t *) other = *source; 452 ++source; 453 * (((size_t *) other)+1) = *source; 454 #endif 455 #if (HAS_POLY_VARS_OTHER>2) 456 size_t * target = (size_t *) other ; 457 size_t * end = target + POLY_VARS_OTHER/(sizeof(size_t)/sizeof(deg_t)); 458 for (++source;target!=end;++source,++target) 459 *target = *source; 460 #endif 461 } 462 // delete ~index_m()463 ~index_m(){ 464 if ( (taille % 2) == 0){ 465 --riptr->ref_count; 466 if (!riptr->ref_count) 467 delete riptr; 468 } 469 } 470 // copy 471 const index_m & operator = (const index_m & other){ 472 if ( (taille % 2) == 0){ 473 --riptr->ref_count; 474 if (!riptr->ref_count) 475 delete riptr; 476 } 477 if ( (other.taille % 2) == 0){ 478 riptr=other.riptr; 479 ++riptr->ref_count; 480 } 481 else { 482 * (size_t *) &taille = * (size_t *) &other.taille; 483 #if (HAS_POLY_VARS_OTHER==1) 484 * (size_t *) this->other = * (size_t *) other.other; 485 #endif 486 #if (HAS_POLY_VARS_OTHER==2) 487 * (size_t *) this->other = * (size_t *) other.other; 488 * (((size_t *) this->other)+1) = * (((size_t *) other.other)+1); 489 #endif 490 #if (HAS_POLY_VARS_OTHER>2) 491 const size_t * source = (size_t * ) other.other; 492 size_t * target = (size_t *) this->other; 493 size_t * end = target + POLY_VARS_OTHER/(sizeof(size_t)/sizeof(deg_t)); 494 for (;target!=end;++source,++target) 495 * target = * source; 496 #endif 497 } 498 return *this; 499 } 500 501 // members 502 index_t iref() const ; 503 index_t::iterator begin() ; 504 index_t::iterator end() ; 505 index_t::const_iterator begin() const; 506 index_t::const_iterator end() const; front()507 deg_t & front() { return *begin(); } front()508 deg_t front() const { return *begin(); } back()509 deg_t & back() { return *(end()-1); } back()510 deg_t back() const { return *(end()-1); } 511 deg_t & operator [] (size_t pos) { return *(begin()+pos); } 512 deg_t operator [] (size_t pos) const { return *(begin()+pos); } 513 void clear() ; 514 void reserve(size_t n); 515 void push_back(deg_t x); 516 size_t size() const ; 517 bool is_zero() const ; 518 size_t total_degree() const ; 519 #ifdef KHICAS 520 friend stdostream & operator << (stdostream & os,const index_m & m ){ 521 os << ":index_m:[ " ; 522 for (index_t::const_iterator it=m.begin();it!=m.end();++it) 523 os << *it << " "; 524 os << "] " ; 525 return(os); 526 } 527 #endif 528 #ifdef NSPIRE 529 template<class T> friend nio::ios_base<T> & operator << (nio::ios_base<T> & os,const index_m & m ){ 530 os << ":index_m:[ " ; 531 for (index_t::const_iterator it=m.begin();it!=m.end();++it) 532 os << *it << " "; 533 os << "] " ; 534 return(os); 535 } 536 #else 537 friend std::ostream & operator << (std::ostream & os, const index_m & m ){ 538 os << ":index_m:[ " ; 539 for (index_t::const_iterator it=m.begin();it!=m.end();++it) 540 os << *it << " "; 541 os << "] " ; 542 return(os); 543 } 544 #endif dbgprint()545 void dbgprint() const { 546 COUT << *this << '\n'; 547 } 548 // set first index element to 0 549 index_m set_first_zero() const; 550 }; 551 #endif // VISUALC 552 553 #ifdef HASH_MAP_NAMESPACE index_hash_function(const index_t & v)554 inline size_t index_hash_function(const index_t & v){ 555 index_t::const_iterator it=v.begin(),itend=v.end(); 556 size_t res=0; 557 if (itend-it>16) 558 itend=it+16; 559 if (itend-it>8){ 560 for (;it!=itend;++it) 561 res = (res << 2) | *it; 562 } 563 else { 564 for (;it!=itend;++it) 565 res = (res << 4) | *it; 566 } 567 return res; 568 } 569 570 /* 571 inline size_t index_hash_function(const vector<int> & v){ 572 vector<int>::const_iterator it=v.begin(),itend=v.end(); 573 if (itend-it>16) 574 itend=it+16; 575 size_t res=0,decal=32/(itend-it); 576 for (;;){ 577 --itend; 578 res = (res << decal) | *itend; 579 if (itend==it) 580 return res; 581 } 582 } 583 */ 584 585 class hash_function_object { 586 public: operator()587 size_t operator () (const index_t & v) const { return index_hash_function(v); } hash_function_object()588 hash_function_object() {}; 589 }; 590 591 typedef HASH_MAP_NAMESPACE::hash_map< index_t,index_m,hash_function_object > hash_index ; 592 593 // extern std::vector<hash_index> global_hash_index; 594 595 #endif 596 597 void add(const index_m & a, const index_m & b,index_t & res); 598 bool equal(const index_m & a,const index_t &b); 599 index_m operator + (const index_m & a, const index_m & b); 600 index_m operator - (const index_m & a, const index_m & b); 601 index_m operator * (const index_m & a, int fois); 602 inline index_m operator * (int fois,const index_m & a){ return a*fois; } 603 index_m operator / (const index_m & a, int divisepar); 604 inline int operator / (const index_m & a,const index_m & b){ return a.iref() / b.iref();} 605 bool operator == (const index_m & i1, const index_m & i2); 606 bool operator != (const index_m & i1, const index_m & i2); 607 bool operator >= (const index_m & a, const index_m & b); 608 bool operator <= (const index_m & a, const index_m & b); 609 int sum_degree(const index_m & v1); 610 int sum_degree_from(const index_m & v1,int start); total_degree(const index_m & v1)611 inline int total_degree(const index_m & v1){ return sum_degree(v1); } 612 bool i_lex_is_greater(const index_m & v1, const index_m & v2); 613 bool i_lex_is_strictly_greater(const index_m & v1, const index_m & v2); 614 bool i_total_revlex_is_greater(const index_m & v1, const index_m & v2); 615 bool i_total_revlex_is_strictly_greater(const index_m & v1, const index_m & v2); 616 bool i_total_lex_is_greater(const index_m & v1, const index_m & v2); 617 bool i_total_lex_is_strictly_greater(const index_m & v1, const index_m & v2); 618 bool i_16var_is_greater(const index_m & v1, const index_m & v2); 619 bool i_32var_is_greater(const index_m & v1, const index_m & v2); 620 bool i_64var_is_greater(const index_m & v1, const index_m & v2); 621 bool i_11var_is_greater(const index_m & v1, const index_m & v2); 622 bool i_7var_is_greater(const index_m & v1, const index_m & v2); 623 bool i_3var_is_greater(const index_m & v1, const index_m & v2); 624 bool i_nvar_is_greater(const index_m & v1, const index_m & v2,int n,bool sametdeg); 625 int nvar_total_degree(const index_m & v1,int n); i_16var_is_strictly_greater(const index_m & v1,const index_m & v2)626 inline bool i_16var_is_strictly_greater(const index_m & v1, const index_m & v2){ return !i_16var_is_greater(v2,v1); } i_32var_is_strictly_greater(const index_m & v1,const index_m & v2)627 inline bool i_32var_is_strictly_greater(const index_m & v1, const index_m & v2){ return !i_32var_is_greater(v2,v1); } i_64var_is_strictly_greater(const index_m & v1,const index_m & v2)628 inline bool i_64var_is_strictly_greater(const index_m & v1, const index_m & v2){ return !i_64var_is_greater(v2,v1); } i_11var_is_strictly_greater(const index_m & v1,const index_m & v2)629 inline bool i_11var_is_strictly_greater(const index_m & v1, const index_m & v2){ return !i_11var_is_greater(v2,v1); } i_7var_is_strictly_greater(const index_m & v1,const index_m & v2)630 inline bool i_7var_is_strictly_greater(const index_m & v1, const index_m & v2){ return !i_7var_is_greater(v2,v1); } i_3var_is_strictly_greater(const index_m & v1,const index_m & v2)631 inline bool i_3var_is_strictly_greater(const index_m & v1, const index_m & v2){ return !i_3var_is_greater(v2,v1); } 632 pow(const std::vector<T> & x,const index_m & n)633 template <class T> T pow(const std::vector<T> & x, const index_m & n ){ 634 assert(x.size()==n.size()); 635 typename std::vector<T>::const_iterator itx=x.begin(); 636 index_t::const_iterator itn=n.begin(); 637 T res(1); 638 for (;itx!=x.end();++itx,++itn){ 639 res=res*pow(*itx,*itn); 640 } 641 return res; 642 } 643 644 void index_lcm(const index_m & a,const index_m & b,index_t & res); 645 bool disjoint(const index_m & a,const index_m & b); 646 647 #ifndef NO_NAMESPACE_GIAC 648 } // namespace giac 649 #endif // ndef NO_NAMESPACE_GIAC 650 651 #if 0 // def NSPIRE 652 namespace std { 653 inline bool operator > (const giac::index_t & a,const giac::index_t & b){ 654 if (a.size()!=b.size()) 655 return a.size()>b.size(); 656 return !giac::all_inf_equal(a,b); 657 } 658 inline bool operator < (const giac::index_t & a,const giac::index_t & b){ 659 if (a.size()!=b.size()) 660 return a.size()<b.size(); 661 return !giac::all_sup_equal(a,b); 662 } 663 } 664 #endif 665 666 #endif // ndef _GIAC_INDEX_H_ 667