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