1 // -*- mode: C++ ; compile-command: "g++ -I.. -g -O2 -c index.cc" -*- 2 #include "giacPCH.h" 3 /* 4 * Copyright (C) 2000,7 B. Parisse, Institut Fourier, 38402 St Martin d'Heres 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 3 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program. If not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 using namespace std; 21 #include "index.h" 22 #include <cmath> 23 #include <stdio.h> 24 #include <stdexcept> 25 #ifdef DEBUG_SUPPORT 26 #include "giacintl.h" 27 #endif 28 29 #ifndef NO_NAMESPACE_GIAC 30 namespace giac { 31 #endif // ndef NO_NAMESPACE_GIAC 32 33 #ifdef NO_STDEXCEPT 34 #undef DEBUG_SUPPORT 35 #endif 36 37 #ifdef DEBUG_SUPPORT 38 void setsizeerr(const std::string & s); 39 #endif 40 mygcd(int a,int b)41 int mygcd(int a,int b){ 42 if (b) 43 return mygcd(b,a%b); 44 else 45 return a<0?-a:a; 46 } 47 swapint(int & a,int & b)48 void swapint(int & a,int & b){ 49 int tmp=a; 50 a=b; 51 b=tmp; 52 } 53 swapdouble(double & a,double & b)54 void swapdouble(double & a,double & b){ 55 double tmp=a; 56 a=b; 57 b=tmp; 58 } 59 index_gcd(const index_t & a,const index_t & b,index_t & res)60 void index_gcd(const index_t & a,const index_t & b,index_t & res){ 61 index_t::const_iterator ita=a.begin(),itaend=a.end(),itb=b.begin(); 62 unsigned s=unsigned(itaend-ita); 63 res.resize(s); 64 index_t::iterator itres=res.begin(); 65 #ifdef DEBUG_SUPPORT 66 if (s!=b.size()) 67 setsizeerr(gettext("Error index.cc index_gcd")); 68 #endif // DEBUG_SUPPORT 69 for (;ita!=itaend;++itb,++itres,++ita) 70 *itres=giacmin(*ita,*itb); 71 } 72 index_gcd(const index_t & a,const index_t & b)73 index_t index_gcd(const index_t & a,const index_t & b){ 74 index_t res; 75 index_gcd(a,b,res); 76 return res; 77 } 78 index_lcm(const index_t & a,const index_t & b)79 index_t index_lcm(const index_t & a,const index_t & b){ 80 index_t::const_iterator ita=a.begin(),itaend=a.end(),itb=b.begin(); 81 unsigned s=unsigned(itaend-ita); 82 index_t res(s); 83 index_t::iterator itres=res.begin(); 84 #ifdef DEBUG_SUPPORT 85 if (s!=b.size()) 86 setsizeerr(gettext("index.cc index_lcm")); 87 #endif // DEBUG_SUPPORT 88 for (;ita!=itaend;++itb,++itres,++ita) 89 *itres=giacmax(*ita,*itb); 90 return res; 91 } 92 index_lcm(const index_m & a,const index_m & b,index_t & res)93 void index_lcm(const index_m & a,const index_m & b,index_t & res){ 94 index_t::const_iterator ita=a.begin(),itaend=a.end(),itb=b.begin(); 95 unsigned s=unsigned(itaend-ita); 96 res.resize(s); 97 index_t::iterator itres=res.begin(); 98 for (;ita!=itaend;++itb,++itres,++ita) 99 *itres=giacmax(*ita,*itb); 100 } 101 102 // index and monomial ordering/operations implementation add(const index_t & a,const index_t & b,index_t & res)103 void add(const index_t & a, const index_t & b,index_t & res){ 104 index_t::const_iterator ita=a.begin(),itaend=a.end(),itb=b.begin(); 105 index_t::iterator itres=res.begin(); 106 for (;ita!=itaend;++itb,++itres,++ita) 107 *itres=(*ita)+(*itb); 108 } 109 add(const index_m & a,const index_m & b,index_t & res)110 void add(const index_m & a, const index_m & b,index_t & res){ 111 index_t::const_iterator ita=a.begin(),itaend=a.end(),itb=b.begin(); 112 index_t::iterator itres=res.begin(); 113 for (;ita!=itaend;++itb,++itres,++ita) 114 *itres=(*ita)+(*itb); 115 } 116 operator +(const index_t & a,const index_t & b)117 index_t operator + (const index_t & a, const index_t & b){ 118 index_t::const_iterator ita=a.begin(),itaend=a.end(),itb=b.begin(); 119 unsigned s=unsigned(itaend-ita); 120 index_t res(s); 121 index_t::iterator itres=res.begin(); 122 #ifdef DEBUG_SUPPORT 123 if (s!=b.size()) 124 setsizeerr(gettext("index.cc operator +")); 125 #endif // DEBUG_SUPPORT 126 for (;ita!=itaend;++itb,++itres,++ita) 127 *itres=(*ita)+(*itb); 128 return res; 129 } 130 operator -(const index_t & a,const index_t & b)131 index_t operator - (const index_t & a, const index_t & b){ 132 index_t res; 133 index_t::const_iterator ita=a.begin(),itaend=a.end(),itb=b.begin(); 134 unsigned s=unsigned(itaend-ita); 135 #ifdef DEBUG_SUPPORT 136 if (s!=b.size()) 137 setsizeerr(gettext("index.cc operator -")); 138 #endif // DEBUG_SUPPORT 139 res.reserve(s); 140 for (;ita!=itaend;++ita,++itb) 141 res.push_back((*ita)-(*itb)); 142 return res; 143 } 144 operator |(const index_t & a,const index_t & b)145 index_t operator | (const index_t & a, const index_t & b){ 146 index_t res; 147 index_t::const_iterator ita=a.begin(),itaend=a.end(),itb=b.begin(); 148 unsigned s=unsigned(itaend-ita); 149 #ifdef DEBUG_SUPPORT 150 if (s!=b.size()) 151 setsizeerr(gettext("index.cc operator |")); 152 #endif // DEBUG_SUPPORT 153 res.reserve(s); 154 for (;ita!=itaend;++ita,++itb) 155 res.push_back((*ita) | (*itb)); 156 return res; 157 } 158 operator -(const index_t & a)159 index_t operator - (const index_t & a){ 160 index_t res; 161 index_t::const_iterator ita=a.begin(),itaend=a.end(); 162 int s=int(itaend-ita); 163 res.reserve(s); 164 for (;ita!=itaend;++ita) 165 res.push_back(-(*ita)); 166 return res; 167 } 168 operator *(const index_t & a,int fois)169 index_t operator * (const index_t & a, int fois){ 170 index_t res; 171 index_t::const_iterator ita=a.begin(),itaend=a.end(); 172 res.reserve(itaend-ita); 173 for (;ita!=itaend;++ita) 174 res.push_back((*ita)*fois); 175 return res; 176 } 177 operator /(const index_t & a,int divisepar)178 index_t operator / (const index_t & a, int divisepar){ 179 index_t res; 180 index_t::const_iterator ita=a.begin(),itaend=a.end(); 181 res.reserve(itaend-ita); 182 for (;ita!=itaend;++ita) 183 res.push_back((*ita)/divisepar); 184 return res; 185 } 186 operator /(const index_t & a,const index_t & b)187 int operator / (const index_t & a, const index_t & b){ 188 index_t::const_iterator ita=a.begin(),itaend=a.end(),itb=b.begin(),itbend=b.end(); 189 #ifdef DEBUG_SUPPORT 190 if (itaend-ita!=signed(b.size())) 191 setsizeerr(gettext("index.cc operator /")); 192 #endif // DEBUG_SUPPORT 193 for (;ita!=itaend;++ita,++itb){ 194 if (*itb) 195 return *ita / *itb; 196 } 197 return 0; 198 } 199 all_sup_equal(const index_t & a,const index_t & b)200 bool all_sup_equal (const index_t & a, const index_t & b){ 201 index_t::const_iterator ita=a.begin(),itaend=a.end(),itb=b.begin(); 202 #ifdef DEBUG_SUPPORT 203 if (itaend-ita!=signed(b.size())) 204 setsizeerr(gettext("index.cc operator >=")); 205 #endif // DEBUG_SUPPORT 206 for (;ita!=itaend;++ita,++itb){ 207 if ((*ita)<(*itb)) 208 return false; 209 } 210 return true; 211 } 212 all_inf_equal(const index_t & a,const index_t & b)213 bool all_inf_equal (const index_t & a, const index_t & b){ 214 index_t::const_iterator ita=a.begin(),itaend=a.end(),itb=b.begin(); 215 #ifdef DEBUG_SUPPORT 216 if (itaend-ita!=signed(b.size())) 217 setsizeerr(gettext("index.cc operator <=")); 218 #endif // DEBUG_SUPPORT 219 for (;ita!=itaend;++ita,++itb){ 220 if ((*ita)>(*itb)) 221 return false; 222 } 223 return true; 224 } 225 add_print_INT_(string & s,int i)226 void add_print_INT_(string & s,int i){ 227 char c[256]; 228 sprint_int(c,i);//my_sprintf(c,"%d",i); 229 s += c; 230 } 231 print_INT_(int i)232 string print_INT_(int i){ 233 char c[256]; 234 sprint_int(c,i);//my_sprintf(c,"%d",i); 235 return c; 236 } 237 hexa_print_INT_(int i)238 string hexa_print_INT_(int i){ 239 char c[256]; 240 my_sprintf(c,"%X",i); 241 return string("0x")+c; 242 } 243 octal_print_INT_(int i)244 string octal_print_INT_(int i){ 245 char c[256]; 246 my_sprintf(c,"%o",i); 247 return string("0o")+c; 248 } 249 binary_print_INT_(int i)250 string binary_print_INT_(int i){ 251 if (i==0) 252 return "0b0"; 253 char c[256]; 254 #if 1 255 unsigned ii=i; 256 int j=sizeinbase2(ii); 257 c[j]=0; 258 for (--j;ii;--j,ii/=2){ 259 c[j]='0'+(ii%2); 260 } 261 #else 262 mpz_t tmp; 263 mpz_init_set_ui(tmp, i); 264 mpz_get_str(c, 2, tmp); 265 mpz_clear(tmp); 266 #endif 267 return string("0b")+c; 268 } 269 270 /* 271 string print_INT_(int i){ 272 if (!i) 273 return string("0"); 274 if (i<0) 275 return string("-")+print_INT_(-i); 276 int length = (int) std::floor(std::log10((double) i)); 277 char s[length+2]; 278 s[length+1]=0; 279 for (;length>-1;--length,i/=10) 280 s[length]=i%10+'0'; 281 return s; 282 } 283 */ 284 print_INT_(const vector<short int> & m)285 string print_INT_(const vector<short int> & m){ 286 vector<short int>::const_iterator it=m.begin(),itend=m.end(); 287 if (it==itend) 288 return ""; 289 string s("["); 290 for (;;){ 291 s += print_INT_(*it); 292 ++it; 293 if (it==itend){ 294 s +=']'; 295 return s; 296 } 297 else 298 s += ','; 299 } 300 } 301 print_INT_(const vector<int> & m)302 string print_INT_(const vector<int> & m){ 303 vector<int>::const_iterator it=m.begin(),itend=m.end(); 304 if (it==itend) 305 return ""; 306 string s("["); 307 for (;;){ 308 s += print_INT_(*it); 309 ++it; 310 if (it==itend) 311 return s+']'; 312 else 313 s += ','; 314 } 315 } 316 317 #ifdef NSPIRE operator <<(nio::ios_base<T> & os,const index_t & m)318 template<class T> nio::ios_base<T> & operator << (nio::ios_base<T> & os, const index_t & m ){ 319 return os << ":index_t: " << print_INT_(m) << " " ; 320 } 321 #else operator <<(ostream & os,const index_t & m)322 ostream & operator << (ostream & os, const index_t & m ){ 323 return os << ":index_t: " << print_INT_(m) << " " ; 324 } 325 #endif 326 dbgprint(const index_t & i)327 void dbgprint(const index_t & i){ 328 COUT << i << endl; 329 } 330 mergeindex(const index_t & i,const index_t & j)331 index_t mergeindex(const index_t & i,const index_t & j){ 332 index_t res(i); 333 index_t::const_iterator it=j.begin(),itend=j.end(); 334 res.reserve(i.size()+(itend-it)); 335 for (;it!=itend;++it) 336 res.push_back(*it); 337 return res; 338 } 339 340 // by convention 0 -> 0 for permutations beginning at index 1 inverse(const vector<int> & p)341 vector<int> inverse(const vector<int> & p){ 342 vector<int> inv(p); 343 int n=int(p.size()); 344 for (int i=0;i<n;i++){ 345 inv[p[i]]=i; // that's the definition of inv!! 346 } 347 return inv; 348 } 349 350 // transposition transposition(int i,int j,int size)351 vector<int> transposition(int i,int j,int size){ 352 if (i>j) 353 return transposition(j,i,size); 354 vector<int> t; 355 for (int k=0;k<i;k++) 356 t.push_back(k); 357 t.push_back(j); 358 for (int k=i+1;k<j;k++) 359 t.push_back(k); 360 t.push_back(i); 361 for (int k=j+1;k<size;k++) 362 t.push_back(k); 363 return t; 364 } 365 has(const index_t & p,int r)366 bool has(const index_t & p,int r){ 367 index_t::const_iterator it=p.begin(),itend=p.end(); 368 for (;it!=itend;++it){ 369 if (*it==r) 370 return true; 371 } 372 return false; 373 } 374 is_zero(const index_t & p)375 bool is_zero(const index_t & p){ 376 index_t::const_iterator it=p.begin(),itend=p.end(); 377 for (;it!=itend;++it){ 378 if (*it) 379 return false; 380 } 381 return true; 382 } 383 384 #if defined(GIAC_NO_OPTIMIZATIONS) || ((defined(VISUALC) || defined(__APPLE__)) && !defined(GIAC_VECTOR)) || defined __clang__ // || defined NSPIRE operator ==(const index_m & i1,const index_m & i2)385 bool operator == (const index_m & i1, const index_m & i2){ 386 if (i1.riptr==i2.riptr) 387 return true; 388 return (i1.riptr->i==i2.riptr->i); 389 } 390 sum_degree_from(const index_m & v1,int start)391 int sum_degree_from(const index_m & v1,int start){ 392 index_t & i1=v1.riptr->i; 393 index_t::const_iterator it = i1.begin()+start,itend = i1.end(); 394 int i=0; 395 for (;it!=itend;++it) 396 i += *it; 397 return i; 398 } 399 400 #else iref() const401 index_t index_m::iref() const { 402 if ( (taille % 2)==0) 403 return riptr->i; 404 return index_t(direct,direct+taille/2); 405 } 406 begin()407 index_t::iterator index_m::begin() { 408 if ( (taille % 2)==0) 409 return riptr->i.begin(); 410 return index_t::iterator((giac::deg_t *) direct); 411 } 412 end()413 index_t::iterator index_m::end() { 414 if ( (taille % 2)==0) 415 return riptr->i.end(); 416 return index_t::iterator((giac::deg_t *) direct + taille/2) ; 417 } 418 begin() const419 index_t::const_iterator index_m::begin() const { 420 if ( (taille % 2)==0) 421 return riptr->i.begin(); 422 return index_t::const_iterator((giac::deg_t *) direct); 423 } 424 end() const425 index_t::const_iterator index_m::end() const { 426 if ( (taille % 2)==0) 427 return riptr->i.end(); 428 return index_t::const_iterator((giac::deg_t *) direct + taille/2 ); 429 } 430 clear()431 void index_m::clear() { 432 if ( (taille % 2)==0) 433 riptr->i.clear(); 434 else 435 taille=1; 436 } 437 reserve(size_t n)438 void index_m::reserve(size_t n) { 439 if (int(n)>POLY_VARS){ 440 if ( taille % 2) 441 // alloc a true vector with correct size, copy into 442 riptr = new ref_index_t(begin(),end()); 443 // taille=0; 444 riptr->i.reserve(n); 445 } 446 } 447 push_back(deg_t x)448 void index_m::push_back(deg_t x){ 449 if ( taille % 2){ 450 int pos = taille /2 ; 451 taille += 2; 452 if (pos<POLY_VARS){ 453 direct[pos]=x; 454 return; 455 } 456 riptr = new ref_index_t(index_t::iterator((giac::deg_t *)direct),index_t::iterator((giac::deg_t *)direct+pos)); 457 // taille = 0; 458 } 459 riptr->i.push_back(x); 460 } 461 size() const462 size_t index_m::size() const { 463 if (taille % 2) 464 return taille/2; 465 else 466 return riptr->i.size(); 467 } 468 set_first_zero() const469 index_m index_m::set_first_zero() const { 470 if ( (taille % 2) == 0){ 471 index_t i(riptr->i); 472 assert(i.size()); 473 i[0]=0; 474 return index_m(i); 475 } 476 index_m copie(*this); 477 copie.direct[0]=0; 478 return copie; 479 } 480 operator ==(const index_m & i1,const index_m & i2)481 bool operator == (const index_m & i1, const index_m & i2){ 482 if (((i1.taille % 2))==0){ 483 if (i1.riptr==i2.riptr) 484 return true; 485 #if 0 // def x86_64 486 const index_t & i1t=i1.riptr->i; 487 const index_t & i2t=i2.riptr->i; 488 int n=i1t.size(); 489 if (n!=i2.size()) return false; 490 const ulonglong * ptr1=(const ulonglong *)&i1t.front(),* ptr1end=ptr1+n/4,*ptr2=(const ulonglong *)&i2t.front(); 491 for (;ptr1!=ptr1end;++ptr2,++ptr1){ 492 if (*ptr1!=*ptr2) 493 return false; 494 } 495 const deg_t * i1ptr=(const deg_t *) ptr1,*i1end=i1ptr+n%4,* i2ptr= (const deg_t *) ptr2; 496 for (;i1ptr!=i1end;++i2ptr,++i1ptr){ 497 if (*i1ptr!=*i2ptr) 498 return false; 499 } 500 return true; 501 #else 502 return (i1.riptr->i==i2.riptr->i); 503 #endif 504 } 505 if (i1.taille!=i2.taille) 506 return false; 507 const deg_t * i1ptr=i1.direct, *i1end=i1ptr+i1.taille/2,* i2ptr=i2.direct; 508 for (;i1ptr!=i1end;++i2ptr,++i1ptr){ 509 if (*i1ptr!=*i2ptr) 510 return false; 511 } 512 return true; 513 } 514 sum_degree_from(const index_m & v1,int start)515 int sum_degree_from(const index_m & v1,int start){ 516 index_t::const_iterator it,itend; 517 if ( (v1.taille % 2)==0){ 518 index_t & i=v1.riptr->i; 519 it = i.begin()+start; 520 itend = i.end(); 521 } 522 else { 523 it = index_t::const_iterator((giac::deg_t *) v1.direct); 524 itend = it + v1.taille/2; 525 it += start; 526 } 527 int i=0; 528 for (;it!=itend;++it) 529 i += *it; 530 return i; 531 } 532 533 #endif // VISUALC 534 is_zero() const535 bool index_m::is_zero() const { 536 index_t::const_iterator it=begin(),itend=end(); 537 for (;it!=itend;++it){ 538 if (*it) 539 return false; 540 } 541 return true; 542 } 543 total_degree() const544 size_t index_m::total_degree() const { 545 size_t i=0; 546 for (index_t::const_iterator it=begin();it!=end();++it) 547 i=i+(*it); 548 return i; 549 } 550 551 operator +(const index_m & a,const index_m & b)552 index_m operator + (const index_m & a, const index_m & b){ 553 const deg_t * ita=&*a.begin(), * itb=&*b.begin(); 554 int s=int(a.size()); 555 const deg_t * itaend=ita+s; 556 #ifdef DEBUG_SUPPORT 557 if (s!=signed(b.size())) 558 setsizeerr(gettext("index.cc index_m operator +")); 559 #endif // DEBUG_SUPPORT 560 index_m res(s); 561 deg_t * it=(deg_t*)&*res.begin(); 562 #if 0 // def x86_64 563 ulonglong * target=(ulonglong *) &*it; 564 const ulonglong * ptr1=(const ulonglong *) &*ita,* ptr1end=ptr1+s/(sizeof(ulonglong)/sizeof(deg_t)); 565 const ulonglong * ptr2=(const ulonglong *) &*itb; 566 for (;ptr1!=ptr1end;++target,++ptr2,++ptr1){ 567 *target=*ptr1+*ptr2; 568 } 569 ita=(const deg_t*)&*ptr1; 570 itb=(const deg_t*)&*ptr2; 571 it=(deg_t*)&*target; 572 #endif 573 for (;ita!=itaend;++it,++itb,++ita) 574 *it = (*ita)+(*itb); 575 return res; 576 } 577 operator -(const index_m & a,const index_m & b)578 index_m operator - (const index_m & a, const index_m & b){ 579 index_t::const_iterator ita=a.begin(); 580 index_t::const_iterator itaend=a.end(); 581 index_t::const_iterator itb=b.begin(); 582 int s=int(itaend-ita); 583 #ifdef DEBUG_SUPPORT 584 if (s!=signed(b.size())) 585 setsizeerr(gettext("index.cc index_m operator -")); 586 #endif // DEBUG_SUPPORT 587 index_m res(s); 588 index_t::iterator it=res.begin(); 589 for (;ita!=itaend;++it,++itb,++ita) 590 *it = (*ita)-(*itb); 591 return res; 592 } 593 operator *(const index_m & a,int fois)594 index_m operator * (const index_m & a, int fois){ 595 index_t::const_iterator ita=a.begin(),itaend=a.end(); 596 index_m res(itaend-ita); 597 index_t::iterator it=res.begin(); 598 for (;ita!=itaend;++it,++ita) 599 *it = (*ita)*fois; 600 return res; 601 } 602 operator /(const index_m & a,int divisepar)603 index_m operator / (const index_m & a, int divisepar){ 604 index_t::const_iterator ita=a.begin(),itaend=a.end(); 605 index_m res(itaend-ita); 606 index_t::iterator it=res.begin(); 607 for (;ita!=itaend;++it,++ita) 608 *it = (*ita)/divisepar; 609 return res; 610 } 611 operator !=(const index_m & i1,const index_m & i2)612 bool operator != (const index_m & i1, const index_m & i2){ 613 return !(i1==i2); 614 } 615 616 // >= and <= are *partial* ordering on index_t 617 // they return TRUE if and only if >= or <= is true for *all* coordinates operator >=(const index_m & a,const index_m & b)618 bool operator >= (const index_m & a, const index_m & b){ 619 index_t::const_iterator ita=a.begin(),itaend=a.end(); 620 index_t::const_iterator itb=b.begin(); 621 #ifdef DEBUG_SUPPORT 622 if (itaend-ita!=signed(b.size())) 623 setsizeerr(gettext("index.cc index_m operator >=")); 624 #endif 625 for (;ita!=itaend;++ita,++itb){ 626 if ((*ita)<(*itb)) 627 return false; 628 } 629 return true; 630 } 631 operator <=(const index_m & a,const index_m & b)632 bool operator <= (const index_m & a, const index_m & b){ 633 index_t::const_iterator ita=a.begin(),itaend=a.end(); 634 index_t::const_iterator itb=b.begin(); 635 #ifdef DEBUG_SUPPORT 636 if (itaend-ita!=signed(b.size())) 637 setsizeerr(gettext("index.cc index_m operator >=")); 638 #endif 639 for (;ita!=itaend;++ita,++itb){ 640 if ((*ita)>(*itb)) 641 return false; 642 } 643 return true; 644 } 645 equal(const index_m & a,const index_t & b)646 bool equal(const index_m & a,const index_t &b){ 647 index_t::const_iterator ita=a.begin(),itaend=a.end(); 648 index_t::const_iterator itb=b.begin(); 649 for (;ita!=itaend;++itb,++ita){ 650 if (*ita!=*itb) 651 return false; 652 } 653 return true; 654 } 655 sum_degree(const index_m & v1)656 int sum_degree(const index_m & v1){ 657 int i=0; 658 index_t::const_iterator it=v1.begin(),itend=v1.end(); 659 for (;it!=itend;++it) 660 i += *it; 661 return i; 662 } 663 i_lex_is_greater(const index_m & v1,const index_m & v2)664 bool i_lex_is_greater(const index_m & v1, const index_m & v2){ 665 index_t::const_iterator it1=v1.begin(); 666 index_t::const_iterator it2=v2.begin(); 667 index_t::const_iterator it1end=v1.end(); 668 #ifdef DEBUG_SUPPORT 669 if (it1end-it1!=signed(v2.size())) 670 setsizeerr(gettext("index.cc index_m i_lex_is_greater")); 671 #endif 672 for (;it1!=it1end;++it1){ 673 if ( (*it1)!=(*it2) ){ 674 if ( (*it1)>(*it2)) 675 return(true); 676 else 677 return(false); 678 } 679 ++it2; 680 } 681 return(true); 682 } 683 lex_is_strictly_greater_deg_t(const std::vector<deg_t> & v1,const std::vector<deg_t> & v2)684 bool lex_is_strictly_greater_deg_t(const std::vector<deg_t> & v1, const std::vector<deg_t> & v2){ 685 assert(v1.size()==v2.size()); 686 std::vector<deg_t>::const_iterator it1=v1.begin(),it1end=v1.end(); 687 std::vector<deg_t>::const_iterator it2=v2.begin(); 688 for (;it1!=it1end;++it2,++it1){ 689 if ( (*it1)!=(*it2) ){ 690 if ( (*it1)>(*it2)) 691 return true; 692 else 693 return false; 694 } 695 } 696 return false; 697 } 698 i_lex_is_strictly_greater(const index_m & v1,const index_m & v2)699 bool i_lex_is_strictly_greater(const index_m & v1, const index_m & v2){ 700 index_t::const_iterator it1=v1.begin(); 701 index_t::const_iterator it2=v2.begin(); 702 index_t::const_iterator it1end=v1.end(); 703 #ifdef DEBUG_SUPPORT 704 if (it1end-it1!=signed(v2.size())) 705 setsizeerr(gettext("index.cc index_m i_lex_is_greater")); 706 #endif 707 for (;it1!=it1end;++it1){ 708 if ( (*it1)!=(*it2) ){ 709 if ( (*it1)>(*it2)) 710 return(true); 711 else 712 return(false); 713 } 714 ++it2; 715 } 716 return(false); 717 } 718 719 /* 720 bool i_revlex_is_greater(const index_m & v1, const index_m & v2){ 721 return revlex_is_greater(*v1.iptr,*v2.iptr); 722 } 723 */ 724 i_total_lex_is_greater(const index_m & v1,const index_m & v2)725 bool i_total_lex_is_greater(const index_m & v1, const index_m & v2){ 726 int d1=sum_degree(v1); 727 int d2=sum_degree(v2); 728 if (d1!=d2){ 729 if (d1>d2) 730 return(true); 731 else 732 return(false); 733 } 734 return(i_lex_is_greater(v1,v2)); 735 } 736 i_total_lex_is_strictly_greater(const index_m & v1,const index_m & v2)737 bool i_total_lex_is_strictly_greater(const index_m & v1, const index_m & v2){ 738 return !i_total_lex_is_greater(v2,v1); 739 } 740 i_total_revlex_is_greater(const index_m & v1,const index_m & v2)741 bool i_total_revlex_is_greater(const index_m & v1, const index_m & v2){ 742 int d1=sum_degree(v1); 743 int d2=sum_degree(v2); 744 if (d1!=d2){ 745 if (d1>d2) 746 return(true); 747 else 748 return(false); 749 } 750 // find order with variables reversed then reverse order 751 // return !i_lex_is_strictly_greater(v1,v2); 752 index_t::const_iterator it1=v1.end()-1; 753 index_t::const_iterator it2=v2.end()-1; 754 index_t::const_iterator it1end=v1.begin()-1; 755 #ifdef DEBUG_SUPPORT 756 if (it1-it1end!=signed(v2.size())) 757 setsizeerr(gettext("index.cc index_m i_total_revlex_is_greater")); 758 #endif 759 for (;it1!=it1end;--it1){ 760 if ( *it1 != *it2 ) 761 return *it1<*it2; 762 --it2; 763 } 764 return true; 765 } 766 767 // revlex on 1st 3 vars, then revlex on remaining vars i_3var_is_greater(const index_m & v1,const index_m & v2)768 bool i_3var_is_greater(const index_m & v1, const index_m & v2){ 769 index_t::const_iterator it1=v1.begin(); 770 index_t::const_iterator it2=v2.begin(); 771 int d1=*it1+*(it1+1)+*(it1+2); 772 int d2=*it2+*(it2+1)+*(it2+2); 773 if (d1!=d2) 774 return d1>=d2; 775 if (*(it1+2)!=*(it2+2)) 776 return *(it1+2)<=*(it2+2); 777 if (*(it1+1)!=*(it2+1)) 778 return *(it1+1)<=*(it2+1); 779 if (*it1!=*it2) v1.dbgprint(); // instantiate 780 d1=sum_degree_from(v1,3); 781 d2=sum_degree_from(v2,3); 782 if (d1!=d2) 783 return d1>=d2; 784 index_t::const_iterator it1end=it1+2; 785 it1 = v1.end()-1; 786 it2 = v2.end()-1; 787 for (;it1!=it1end;--it1,--it2){ 788 if (*it1!=*it2) 789 return *it1<=*it2; 790 } 791 return true; 792 } 793 794 // revlex on 1st 7 vars, then revlex on remaining vars i_7var_is_greater(const index_m & v1,const index_m & v2)795 bool i_7var_is_greater(const index_m & v1, const index_m & v2){ 796 index_t::const_iterator it1=v1.begin(); 797 index_t::const_iterator it2=v2.begin(); 798 int d1=*it1+*(it1+1)+*(it1+2)+*(it1+3)+*(it1+4)+*(it1+5)+*(it1+6); 799 int d2=*it2+*(it2+1)+*(it2+2)+*(it2+3)+*(it2+4)+*(it2+5)+*(it2+6); 800 if (d1!=d2) 801 return d1>=d2; 802 if (*(it1+6)!=*(it2+6)) 803 return *(it1+6)<=*(it2+6); 804 if (*(it1+5)!=*(it2+5)) 805 return *(it1+5)<=*(it2+5); 806 if (*(it1+4)!=*(it2+4)) 807 return *(it1+4)<=*(it2+4); 808 if (*(it1+3)!=*(it2+3)) 809 return *(it1+3)<=*(it2+3); 810 if (*(it1+2)!=*(it2+2)) 811 return *(it1+2)<=*(it2+2); 812 if (*(it1+1)!=*(it2+1)) 813 return *(it1+1)<=*(it2+1); 814 d1=sum_degree_from(v1,7); 815 d2=sum_degree_from(v2,7); 816 if (d1!=d2) 817 return d1>=d2; 818 index_t::const_iterator it1end=it1+6; 819 it1 = v1.end()-1; 820 it2 = v2.end()-1; 821 for (;it1!=it1end;--it1,--it2){ 822 if (*it1!=*it2) 823 return *it1<=*it2; 824 } 825 return true; 826 } 827 828 // revlex on 1st 11 vars, then revlex on remaining vars i_11var_is_greater(const index_m & v1,const index_m & v2)829 bool i_11var_is_greater(const index_m & v1, const index_m & v2){ 830 index_t::const_iterator it1=v1.begin(); 831 index_t::const_iterator it2=v2.begin(); 832 int d1=*it1+*(it1+1)+*(it1+2)+ 833 *(it1+3)+*(it1+4)+*(it1+5)+*(it1+6)+ 834 *(it1+7)+*(it1+8)+*(it1+9)+*(it1+10); 835 int d2=*it2+*(it2+1)+*(it2+2)+ 836 *(it2+3)+*(it2+4)+*(it2+5)+*(it2+6)+ 837 *(it2+7)+*(it2+8)+*(it2+9)+*(it2+10); 838 if (d1!=d2) 839 return d1>=d2; 840 if (*(it1+10)!=*(it2+10)) 841 return *(it1+10)<=*(it2+10); 842 if (*(it1+9)!=*(it2+9)) 843 return *(it1+9)<=*(it2+9); 844 if (*(it1+8)!=*(it2+8)) 845 return *(it1+8)<=*(it2+8); 846 if (*(it1+7)!=*(it2+7)) 847 return *(it1+7)<=*(it2+7); 848 if (*(it1+6)!=*(it2+6)) 849 return *(it1+6)<=*(it2+6); 850 if (*(it1+5)!=*(it2+5)) 851 return *(it1+5)<=*(it2+5); 852 if (*(it1+4)!=*(it2+4)) 853 return *(it1+4)<=*(it2+4); 854 if (*(it1+3)!=*(it2+3)) 855 return *(it1+3)<=*(it2+3); 856 if (*(it1+2)!=*(it2+2)) 857 return *(it1+2)<=*(it2+2); 858 if (*(it1+1)!=*(it2+1)) 859 return *(it1+1)<=*(it2+1); 860 d1=sum_degree_from(v1,11); 861 d2=sum_degree_from(v2,11); 862 if (d1!=d2) 863 return d1>=d2; 864 index_t::const_iterator it1end=it1+10; 865 it1 = v1.end()-1; 866 it2 = v2.end()-1; 867 for (;it1!=it1end;--it1,--it2){ 868 if (*it1!=*it2) 869 return *it1<=*it2; 870 } 871 return true; 872 } 873 nvar_total_degree(const index_m & v1,int n)874 int nvar_total_degree(const index_m & v1,int n){ 875 index_t::const_iterator it1=v1.begin(),it1l=it1+n; 876 int d1; 877 for (d1=0;it1<it1l;++it1){ 878 d1 += *it1; 879 } 880 return d1; 881 } 882 883 // revlex on 1st n vars, then revlex on remaining vars i_nvar_is_greater(const index_m & v1,const index_m & v2,int n,bool sametdeg)884 bool i_nvar_is_greater(const index_m & v1, const index_m & v2,int n,bool sametdeg){ 885 int d1,d2; 886 index_t::const_iterator it1beg=v1.begin(),it1=it1beg,it1end=it1+n; 887 index_t::const_iterator it2=v2.begin(); 888 if (sametdeg){ 889 it1 += n; it2 += n; 890 } 891 else { 892 for (d1=0,d2=0;it1<it1end;++it2,++it1){ 893 d1 += *it1; 894 d2 += *it2; 895 } 896 if (d1!=d2) 897 return d1>=d2; 898 } 899 for (--it2,--it1;it1!=it1beg;--it2,--it1){ 900 if (*it1!=*it2) 901 return *it1<=*it2; 902 } 903 it1end=v1.end(); 904 for (d1=0,d2=0,it1+=n,it2+=n;it1!=it1end;++it2,++it1){ 905 d1 += *it1; 906 d2 += *it2; 907 } 908 if (d1!=d2) 909 return d1>=d2; 910 it1 = it1end-1; 911 it2 = v2.end()-1; 912 it1end=it1beg+n-1; 913 for (;it1!=it1end;--it2,--it1){ 914 if (*it1!=*it2) 915 return *it1<=*it2; 916 } 917 return true; 918 } 919 920 // revlex on 1st 16 vars, then revlex on remaining vars i_16var_is_greater(const index_m & v1,const index_m & v2)921 bool i_16var_is_greater(const index_m & v1, const index_m & v2){ 922 return i_nvar_is_greater(v1,v2,16,false); 923 } 924 925 // revlex on 1st 32 vars, then revlex on remaining vars i_32var_is_greater(const index_m & v1,const index_m & v2)926 bool i_32var_is_greater(const index_m & v1, const index_m & v2){ 927 return i_nvar_is_greater(v1,v2,32,false); 928 } 929 930 // revlex on 1st 64 vars, then revlex on remaining vars i_64var_is_greater(const index_m & v1,const index_m & v2)931 bool i_64var_is_greater(const index_m & v1, const index_m & v2){ 932 return i_nvar_is_greater(v1,v2,64,false); 933 } 934 i_total_revlex_is_strictly_greater(const index_m & v1,const index_m & v2)935 bool i_total_revlex_is_strictly_greater(const index_m & v1, const index_m & v2){ 936 return !i_total_revlex_is_greater(v2,v1); 937 } 938 disjoint(const index_m & a,const index_m & b)939 bool disjoint(const index_m & a,const index_m & b){ 940 index_t::const_iterator it=a.begin(),itend=a.end(),jt=b.begin(); 941 for (;it!=itend;++jt,++it){ 942 if (*it && *jt) 943 return false; 944 } 945 return true; 946 } 947 948 #ifndef NO_NAMESPACE_GIAC 949 } // namespace giac 950 #endif // ndef NO_NAMESPACE_GIAC 951