source: git/IntegerProgramming/binomial.cc @ 4b2690

spielwiese
Last change on this file since 4b2690 was 10b7a4, checked in by Hans Schönemann <hannes@…>, 16 years ago
*sage/hannes: gcc 4.3 git-svn-id: file:///usr/local/Singular/svn/trunk@10499 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 42.6 KB
Line 
1// binomial.cc
2
3// implementation of class binomial
4
5#ifndef BINOMIAL_CC
6#define BINOMIAL_CC
7
8#include <climits>
9#include "binomial__term_ordering.h"
10
11///////////////////////// constructors and destructor //////////////////////
12
13// For a better overview, the constructor code is separated for
14// NO_SUPPORT_DRIVEN_METHODS and SUPPORT_DRIVEN_METHODS.
15
16#ifdef NO_SUPPORT_DRIVEN_METHODS
17
18binomial::binomial(const short& number_of_variables)
19    :_number_of_variables(number_of_variables)
20{
21  exponent_vector=new Integer[_number_of_variables];
22}
23
24
25
26
27binomial::binomial(const short& number_of_variables,const Integer* exponents)
28    :_number_of_variables(number_of_variables)
29{
30
31  // range check for rarely used constructors
32  if(_number_of_variables<=0)
33  {
34    cerr<<"\nWARNING: binomial::binomial(const short&, const Integer*):\n"
35      "argument out of range"<<endl;
36    exponent_vector=NULL;
37    // to avoid problems when deleting
38    return;
39  }
40
41  // initialization
42  exponent_vector=new Integer[_number_of_variables];
43  for(short i=0;i<_number_of_variables;i++)
44    exponent_vector[i]=exponents[i];
45}
46
47
48
49
50binomial::binomial(const short& number_of_variables,const Integer* exponents,
51                   const term_ordering& w)
52    :_number_of_variables(number_of_variables)
53{
54
55  // range check for rarely used constructors
56  if(_number_of_variables<=0)
57  {
58    cerr<<"\nWARNING: binomial::binomial(const short&, const Integer*):\n"
59      "argument out of range"<<endl;
60    exponent_vector=NULL;
61    // to avoid problems when deleting
62    return;
63  }
64
65  exponent_vector=new Integer[_number_of_variables];
66
67  // determine head and tail
68  if(w.compare_to_zero(exponents)>=0)
69    for(short i=0;i<_number_of_variables;i++)
70      exponent_vector[i]=exponents[i];
71  else
72    for(short i=0;i<_number_of_variables;i++)
73      exponent_vector[i]=-exponents[i];
74
75}
76
77
78
79
80binomial::binomial(const binomial& b)
81    :_number_of_variables(b._number_of_variables)
82{
83  exponent_vector=new Integer[_number_of_variables];
84  for(short i=0;i<_number_of_variables;i++)
85    exponent_vector[i]=b.exponent_vector[i];
86}
87
88
89
90
91#endif  // NO_SUPPORT_DRIVEN_METHODS
92
93
94
95
96#ifdef SUPPORT_DRIVEN_METHODS
97
98
99
100
101binomial::binomial(const short& number_of_variables)
102    :_number_of_variables(number_of_variables),head_support(0),tail_support(0)
103{
104  exponent_vector=new Integer[_number_of_variables];
105}
106
107
108
109
110binomial::binomial(const short& number_of_variables, const Integer* exponents)
111    :_number_of_variables(number_of_variables),head_support(0),tail_support(0)
112{
113
114  // range check for rarely used constructors
115  if(_number_of_variables<=0)
116  {
117    exponent_vector=NULL;
118    // to avoid problems when deleting
119    cerr<<"\nWARNING: binomial::binomial(const short&, const Integer*):\n"
120      "argument out of range"<<endl;
121    return;
122  }
123
124  exponent_vector=new Integer[_number_of_variables];
125
126  short size_of_support_vectors=CHAR_BIT*sizeof(unsigned long);
127  // number of bits of a long int
128
129
130  for(short i=0;i<_number_of_variables;i++)
131  {
132
133#ifdef SUPPORT_VARIABLES_FIRST
134
135    Integer actual_entry=exponents[i];
136    exponent_vector[i]=actual_entry;
137
138#endif  // SUPPORT_VARIABLES_FIRST
139
140#ifdef SUPPORT_VARIABLES_LAST
141
142    short j=_number_of_variables-1-i;
143    Integer actual_entry=exponents[j];
144    exponent_vector[j]=actual_entry;
145
146#endif  // SUPPORT_VARIABLES_LAST
147
148    if(i<size_of_support_vectors)
149      // variable i is considered in the support vectors
150      if(actual_entry>0)
151        head_support|=(1<<i);
152        // bit i of head_support is set to 1 (counting from 0)
153      else
154        if(actual_entry<0)
155          tail_support|=(1<<i);
156    // bit i of tail_support is set to 1
157  }
158
159}
160
161
162
163
164binomial::binomial(const short& number_of_variables, const Integer* exponents,
165                   const term_ordering& w)
166    :_number_of_variables(number_of_variables),head_support(0),tail_support(0)
167{
168  // range check for rarely used constructors
169  if(_number_of_variables<=0)
170  {
171    cerr<<"\nWARNING: binomial::binomial(const short&, const Integer*):\n"
172      "argument out of range"<<endl;
173    exponent_vector=NULL;
174    // to avoid problems when deleting
175    return;
176  }
177
178
179  exponent_vector=new Integer[_number_of_variables];
180
181  short size_of_support_vectors=CHAR_BIT*sizeof(unsigned long);
182  // number of bits of a long int
183
184  // determine head and tail
185  short sign;
186  if(w.compare_to_zero(exponents)>=0)
187    sign=1;
188  else
189    sign=-1;
190
191
192  for(short i=0;i<_number_of_variables;i++)
193  {
194
195#ifdef SUPPORT_VARIABLES_FIRST
196
197    Integer actual_entry=sign*exponents[i];
198    exponent_vector[i]=actual_entry;
199
200#endif  // SUPPORT_VARIABLES_FIRST
201
202#ifdef SUPPORT_VARIABLES_LAST
203
204    short j=_number_of_variables-1-i;
205    Integer actual_entry=sign*exponents[j];
206    exponent_vector[j]=actual_entry;
207
208#endif  // SUPPORT_VARIABLES_LAST
209
210    if(i<size_of_support_vectors)
211      // variable i is considered in the support vectors
212      if(actual_entry>0)
213        head_support|=(1<<i);
214        // bit i of head_support is set to 1 (counting from 0)
215      else
216        if(actual_entry<0)
217          tail_support|=(1<<i);
218    // bit i of tail_support is set to 1
219  }
220
221}
222
223
224
225
226binomial::binomial(const binomial& b)
227    :_number_of_variables(b._number_of_variables),
228     head_support(b.head_support),tail_support(b.tail_support)
229{
230  exponent_vector=new Integer[_number_of_variables];
231  for(short i=0;i<_number_of_variables;i++)
232    exponent_vector[i]=b.exponent_vector[i];
233}
234
235
236
237
238#endif  // SUPPORT_DRIVEN_METHODS
239
240
241
242
243binomial::~binomial()
244{
245  delete[] exponent_vector;
246}
247
248
249
250
251/////////////////// object information /////////////////////////////////////
252
253
254
255
256short binomial::number_of_variables() const
257{
258  return _number_of_variables;
259}
260
261
262
263
264short binomial::error_status() const
265{
266  if(_number_of_variables<0)
267    return _number_of_variables;
268  return 0;
269}
270
271
272
273
274//////////////////// assignment and access operators ////////////////////////
275
276
277
278
279binomial& binomial::operator=(const binomial& b)
280{
281
282  if(&b==this)
283    return *this;
284
285
286#ifdef SUPPORT_DRIVEN_METHODS
287
288  head_support=b.head_support;
289  tail_support=b.tail_support;
290
291#endif  // SUPPORT_DRIVEN_METHODS
292
293  if(_number_of_variables!=b._number_of_variables)
294  {
295    delete[] exponent_vector;
296    _number_of_variables=b._number_of_variables;
297
298    if(_number_of_variables<=0)
299    {
300      cerr<<"\nWARNING: binomial& binomial::operator=(const binomial&):\n"
301        "assigment from corrupt binomial"<<endl;
302      exponent_vector=NULL;
303      return (*this);
304    }
305
306    exponent_vector=new Integer[_number_of_variables];
307  }
308
309  for(short i=0;i<_number_of_variables;i++)
310    exponent_vector[i]=b.exponent_vector[i];
311
312  return(*this);
313}
314
315
316
317
318Integer binomial::operator[](const short& i) const
319{
320  return exponent_vector[i];
321}
322
323
324
325
326//////////////////// comparison operators ///////////////////////////////////
327
328
329
330
331BOOLEAN binomial::operator==(const binomial& b) const
332{
333  if(this == &b)
334    return(TRUE);
335
336#ifdef SUPPORT_DRIVEN_METHODS
337
338  if(head_support!=b.head_support)
339    return(FALSE);
340  if(tail_support!=b.tail_support)
341    return(FALSE);
342
343#endif  // SUPPORT_DRIVEN_METHODS
344
345  for(short i=0;i<_number_of_variables;i++)
346    if(exponent_vector[i]!=b.exponent_vector[i])
347      return(FALSE);
348  return(TRUE);
349}
350
351
352
353
354BOOLEAN binomial::operator!=(const binomial& b) const
355{
356  if(this == &b)
357    return(FALSE);
358
359#ifdef SUPPORT_DRIVEN_METHODS
360
361  if(head_support!=b.head_support)
362    return(TRUE);
363  if(tail_support!=b.tail_support)
364    return(TRUE);
365
366#endif  // SUPPORT_DRIVEN_METHODS
367
368  for(short i=0;i<_number_of_variables;i++)
369    if(exponent_vector[i]!=b.exponent_vector[i])
370      return(TRUE);
371  return(FALSE);
372}
373
374
375
376
377// operators for efficient comparisons with the zero binomial (comp_value=0)
378
379BOOLEAN binomial::operator==(const Integer comp_value) const
380{
381
382#ifdef SUPPORT_DRIVEN_METHODS
383
384  if(comp_value==0)
385  {
386    if(head_support!=0)
387      return(FALSE);
388    if(tail_support!=0)
389      return(FALSE);
390  }
391
392#endif  // SUPPORT_DRIVEN_METHODS
393
394  for(short i=0;i<_number_of_variables;i++)
395    if(exponent_vector[i]!=comp_value)
396      return(FALSE);
397  return(TRUE);
398}
399
400
401
402
403BOOLEAN binomial::operator!=(const Integer comp_value) const
404{
405
406#ifdef SUPPORT_DRIVEN_METHODS
407
408  if(comp_value==0)
409  {
410    if(head_support!=0)
411      return(TRUE);
412    if(tail_support!=0)
413      return(TRUE);
414  }
415
416#endif  // SUPPORT_DRIVEN_METHODS
417
418  for(short i=0;i<_number_of_variables;i++)
419    if(exponent_vector[i]!=comp_value)
420      return(TRUE);
421  return(FALSE);
422}
423
424
425
426
427BOOLEAN binomial::operator<=(const Integer comp_value) const
428{
429
430#ifdef SUPPORT_DRIVEN_METHODS
431
432  if(comp_value==0)
433    if(head_support!=0)
434      return(FALSE);
435
436#endif  // SUPPORT_DRIVEN_METHODS
437
438  for(short i=0;i<_number_of_variables;i++)
439    if(exponent_vector[i]>comp_value)
440      return(FALSE);
441  return(TRUE);
442}
443
444
445
446
447BOOLEAN binomial::operator>=(const Integer comp_value) const
448{
449
450#ifdef SUPPORT_DRIVEN_METHODS
451
452  if(comp_value==0)
453    if(tail_support!=0)
454      return(FALSE);
455
456#endif
457
458  for(short i=0;i<_number_of_variables;i++)
459    if(exponent_vector[i]<comp_value)
460      return(FALSE);
461  return(TRUE);
462}
463
464
465
466
467////////////// basic routines for Buchbergers's algorithm //////////////////
468
469
470
471
472Integer binomial::head_reductions_by(const binomial& b) const
473// Returns the number of possible reductions of the actual binomialŽs head
474// by the binomial b. This is the minimum of the quotients
475// exponent_vector[i]/b.exponent_vector[i]
476// where exponent_vector[i]>0 and b.exponent_vector[i]>0
477// (0 if there are no such quotients).
478// A negative return value means b=0 or head(b)=1.
479{
480
481
482#ifdef NO_SUPPORT_DRIVEN_METHODS
483
484  Integer result=-1;
485  Integer new_result=-1;
486  // -1 stands for infinitely many reductions
487
488  for(short i=0;i<_number_of_variables;i++)
489    // explicit sign tests for all components
490  {
491    Integer actual_b_component=b.exponent_vector[i];
492
493    if(actual_b_component>0)
494      // else variable i is not involved in the head of b
495    {
496      Integer actual_component=exponent_vector[i];
497
498      if(actual_component<actual_b_component)
499        return 0;
500
501      new_result=(Integer) (actual_component/actual_b_component);
502
503      // new_result>=1
504      if((new_result<result) || (result==-1))
505        // new (or first) minimum
506        result=new_result;
507    }
508 }
509
510#endif  // NO_SUPPORT_DRIVEN_METHODS
511
512
513#ifdef SUPPORT_DRIVEN_METHODS
514
515  if((head_support&b.head_support)!=b.head_support)
516    // head support of b not contained in head support, no reduction possible
517    return 0;
518
519
520  Integer result=-1;
521  Integer new_result=-1;
522  // -1 stands for infinitely many reductions
523
524
525  short size_of_support_vectors=CHAR_BIT*sizeof(long);
526  // number of bits of a long int
527  if(size_of_support_vectors>_number_of_variables)
528    size_of_support_vectors=_number_of_variables;
529    // number of components of the support vectors
530
531
532#ifdef SUPPORT_VARIABLES_FIRST
533
534  for(short i=0;i<size_of_support_vectors;i++)
535    // test support variables
536
537    if(b.head_support&(1<<i))
538      // bit i of b.head_support is 1
539    {
540      new_result=(Integer) (exponent_vector[i]/b.exponent_vector[i]);
541      // remember that exponent_vector[i]>0 !
542      // (head support contains that of b)
543
544      if(new_result==0)
545        // exponent_vector[i]<b.exponent_vector[i]
546        return 0;
547
548      // new_result>=1
549      if((new_result<result) || (result==-1))
550        // new (or first) minimum
551        result=new_result;
552    }
553
554
555  for(short i=size_of_support_vectors;i<_number_of_variables;i++)
556    // test non-support variables
557    // from now on we need explicit sign tests
558  {
559    Integer actual_b_component=b.exponent_vector[i];
560
561    if(actual_b_component>0)
562      // else variable i is not involved in the head of b
563    {
564      Integer actual_component=exponent_vector[i];
565
566      if(actual_component<actual_b_component)
567        return 0;
568
569      new_result=(Integer) (actual_component/actual_b_component);
570
571      // new_result>=1
572      if((new_result<result) || (result==-1))
573        // new (or first) minimum
574        result=new_result;
575    }
576  }
577
578#endif  // SUPPORT_VARIABLES_FIRST
579
580
581#ifdef SUPPORT_VARIABLES_LAST
582
583  for(short i=0;i<size_of_support_vectors;i++)
584    // test support variables
585
586    if(b.head_support&(1<<i))
587      // bit i of b.head_support is 1
588    {
589      short j=_number_of_variables-1-i;
590      new_result=(Integer) (exponent_vector[j]/ b.exponent_vector[j]);
591      // remember that exponent_vector[_number_of_variables-1-i]>0 !
592      // (head support contains that of b)
593
594      if(new_result==0)
595        // exponent_vector[_number_of_variables-1-i]
596        // <b.exponent_vector[_number_of_variables-1-i]
597        return 0;
598
599      // new_result>=1
600      if((new_result<result) || (result==-1))
601        // new (or first) minimum
602        result=new_result;
603    }
604
605
606  for(short i=size_of_support_vectors;i<_number_of_variables;i++)
607    // test non-support variables
608    // from now on we need explicit sign tests
609  {
610    short j=_number_of_variables-1-i;
611    Integer actual_b_component=b.exponent_vector[j];
612
613    if(actual_b_component>0)
614      // else variable number_of_variables-1-i is not involved in the head of b
615    {
616      Integer actual_component=exponent_vector[j];
617
618      if(actual_component<actual_b_component)
619        return 0;
620
621      new_result=(Integer) (actual_component/actual_b_component);
622
623      // new_result>=1
624      if((new_result<result) || (result==-1))
625        // new (or first) minimum
626        result=new_result;
627    }
628  }
629
630#endif  // SUPPORT_VARIABLES_LAST
631
632
633#endif  // SUPPORT_DRIVEN_METHODS
634
635
636  return(result);
637}
638
639
640
641
642Integer binomial::tail_reductions_by(const binomial& b) const
643// Returns the number of possible reductions of the actual binomialŽs tail
644// by the binomial b. This is the minimum of the quotients
645// - exponent_vector[i]/b.exponent_vector[i]
646// where exponent_vector[i]<0 and b.exponent_vector[i]>0
647// (0 if there are no such quotients).
648// A negative return value means b=0 or head(b)=1.
649{
650
651
652#ifdef NO_SUPPORT_DRIVEN_METHODS
653
654  Integer result=-1;
655  Integer new_result=-1;
656  // -1 stands for infinitely many reductions
657
658  for(short i=0;i<_number_of_variables;i++)
659    // explicit sign tests for all components
660  {
661    Integer actual_b_component=b.exponent_vector[i];
662
663    if(actual_b_component>0)
664      // else variable i is not involved in the head of b
665    {
666      Integer actual_component=-exponent_vector[i];
667
668      if(actual_component<actual_b_component)
669        return 0;
670
671      new_result=(Integer) (actual_component/actual_b_component);
672
673      // new_result>=1
674      if((new_result<result) || (result==-1))
675        // new (or first) minimum
676        result=new_result;
677    }
678 }
679
680#endif  // NO_SUPPORT_DRIVEN_METHODS
681
682
683#ifdef SUPPORT_DRIVEN_METHODS
684
685  if((tail_support&b.head_support)!=b.head_support)
686    // head support of b not contained in tail support, no reduction possible
687    return 0;
688
689
690  Integer result=-1;
691  Integer new_result=-1;
692  // -1 stands for infinitely many reductions
693
694
695  short size_of_support_vectors=CHAR_BIT*sizeof(long);
696  // number of bits of a long int
697  if(size_of_support_vectors>_number_of_variables)
698    size_of_support_vectors=_number_of_variables;
699    // number of components of the support vectors
700
701
702#ifdef SUPPORT_VARIABLES_FIRST
703
704  for(short i=0;i<size_of_support_vectors;i++)
705    // test support variables
706
707    if(b.head_support&(1<<i))
708      // bit i of b.head_support is 1
709    {
710      new_result=(Integer) (-exponent_vector[i]/b.exponent_vector[i]);
711      // remember that exponent_vector[i]<0 !
712      // (tail support contains the head support of b)
713
714      if(new_result==0)
715        // -exponent_vector[i]<b.exponent_vector[i]
716        return 0;
717
718      // new_result>=1
719      if((new_result<result) || (result==-1))
720        // new (or first) minimum
721        result=new_result;
722    }
723
724
725  for(short i=size_of_support_vectors;i<_number_of_variables;i++)
726    // test non-support variables
727    // from now on we need explicit sign tests
728  {
729    Integer actual_b_component=b.exponent_vector[i];
730
731    if(actual_b_component>0)
732      // else variable i is not involved in the head of b
733    {
734      Integer actual_component=-exponent_vector[i];
735
736      if(actual_component<actual_b_component)
737        return 0;
738
739      new_result=(Integer) (actual_component/actual_b_component);
740
741      // new_result>=1
742      if((new_result<result) || (result==-1))
743        // new (or first) minimum
744        result=new_result;
745    }
746  }
747
748#endif  // SUPPORT_VARIABLES_FIRST
749
750
751#ifdef SUPPORT_VARIABLES_LAST
752
753  for(short i=0;i<size_of_support_vectors;i++)
754    // test support variables
755
756    if(b.head_support&(1<<i))
757      // bit i of b.head_support is 1
758    {
759      short j=_number_of_variables-1-i;
760      new_result=(Integer) (-exponent_vector[j] / b.exponent_vector[j]);
761      // remember that exponent_vector[_number_of_variables-1-i]<0 !
762      // (tail support contains the head support of b)
763
764      if(new_result==0)
765        // -exponent_vector[_number_of_variables-1-i]
766        // <b.exponent_vector[_number_of_variables-1-i]
767        return 0;
768
769      // new_result>=1
770      if((new_result<result) || (result==-1))
771        // new (or first) minimum
772        result=new_result;
773    }
774
775
776  for(short i=size_of_support_vectors;i<_number_of_variables;i++)
777    // test non-support variables
778    // from now on we need explicit sign tests
779  {
780    short j=_number_of_variables-1-i;
781    Integer actual_b_component=b.exponent_vector[j];
782
783    if(actual_b_component>0)
784      // else variable number_of_variables-1-i is not involved in the head of b
785    {
786      Integer actual_component=-exponent_vector[j];
787
788      if(actual_component<actual_b_component)
789        return 0;
790
791      new_result=(Integer) (actual_component/actual_b_component);
792
793      // new_result>=1
794      if((new_result<result) || (result==-1))
795        // new (or first) minimum
796        result=new_result;
797    }
798  }
799
800#endif  // SUPPORT_VARIABLES_LAST
801
802
803#endif  // SUPPORT_DRIVEN_METHODS
804
805
806  return(result);
807}
808
809
810
811
812int binomial::reduce_head_by(const binomial& b, const term_ordering& w)
813{
814  Integer reduction_number=head_reductions_by(b);
815  if(reduction_number<=0)
816    return 0;
817
818  for(short i=0;i<_number_of_variables;i++)
819    exponent_vector[i]-=(reduction_number * b.exponent_vector[i]);
820  // multiple reduction
821  // reduction corresponds to subtraction of vectors
822
823  short sign=w.compare_to_zero(exponent_vector);
824
825
826#ifdef NO_SUPPORT_DRIVEN_METHODS
827
828  if(sign==0)
829    // binomial reduced to zero
830    return 2;
831
832  for(short i=0;i<_number_of_variables;i++)
833    exponent_vector[i]*=sign;
834
835#endif  // NO_SUPPORT_DRIVEN_METHODS
836
837
838#ifdef SUPPORT_DRIVEN_METHODS
839
840  head_support=0;
841  tail_support=0;
842
843  if(sign==0)
844    // binomial reduced to zero
845    return 2;
846
847  short size_of_support_vectors=CHAR_BIT*sizeof(unsigned long);
848
849
850  // recompute the support vectors
851
852#ifdef SUPPORT_VARIABLES_FIRST
853
854  for(short i=0;i<_number_of_variables;i++)
855  {
856
857    Integer& actual_entry=exponent_vector[i];
858    // to avoid unnecessary pointer arithmetic
859
860    actual_entry*=sign;
861
862    if(i<size_of_support_vectors)
863      if(actual_entry>0)
864        head_support|=(1<<i);
865      else
866        if(actual_entry<0)
867          tail_support|=(1<<i);
868  }
869
870#endif  // SUPPORT_VARIABLES_FIRST
871
872
873#ifdef SUPPORT_VARIABLES_LAST
874
875  for(short i=0;i<_number_of_variables;i++)
876  {
877    Integer& actual_entry=exponent_vector[_number_of_variables-1-i];
878    // to avoid unneccessary pointer arithmetic
879
880    actual_entry*=sign;
881
882    if(i<size_of_support_vectors)
883      if(actual_entry>0)
884        head_support|=(1<<i);
885      else
886        if(actual_entry<0)
887          tail_support|=(1<<i);
888  }
889
890#endif  // SUPPORT_VARIABLES_LAST
891
892
893#endif  // SUPPORT_DRIVEN_METHODS
894
895  return 1;
896}
897
898
899
900
901int binomial::reduce_tail_by(const binomial& b, const term_ordering& w)
902{
903  Integer reduction_number=tail_reductions_by(b);
904  if(reduction_number<=0)
905    return 0;
906
907  for(short i=0;i<_number_of_variables;i++)
908    exponent_vector[i]+=(reduction_number * b.exponent_vector[i]);
909  // multiple reduction
910  // reduction corresponds to addition of vectors
911
912  // a tail reduction does not require a sign check
913
914
915#ifdef SUPPORT_DRIVEN_METHODS
916
917  head_support=0;
918  tail_support=0;
919
920  short size_of_support_vectors=CHAR_BIT*sizeof(unsigned long);
921
922
923  // recompute the support vectors
924
925#ifdef SUPPORT_VARIABLES_FIRST
926
927  for(short i=0;i<_number_of_variables;i++)
928  {
929
930    Integer& actual_entry=exponent_vector[i];
931    // to avoid unnecessary pointer arithmetic
932
933    if(i<size_of_support_vectors)
934      if(actual_entry>0)
935        head_support|=(1<<i);
936      else
937        if(actual_entry<0)
938          tail_support|=(1<<i);
939  }
940
941#endif  // SUPPORT_VARIABLES_FIRST
942
943
944#ifdef SUPPORT_VARIABLES_LAST
945
946  for(short i=0;i<_number_of_variables;i++)
947  {
948    Integer& actual_entry=exponent_vector[_number_of_variables-1-i];
949    // to avoid unneccessary pointer arithmetic
950
951    if(i<size_of_support_vectors)
952      if(actual_entry>0)
953        head_support|=(1<<i);
954      else
955        if(actual_entry<0)
956          tail_support|=(1<<i);
957  }
958
959#endif  // SUPPORT_VARIABLES_LAST
960
961
962#endif  // SUPPORT_DRIVEN_METHODS
963
964  return 1;
965}
966
967
968
969
970binomial& S_binomial(const binomial& a, const binomial& b,
971                     const term_ordering& w)
972{
973  binomial* S_bin=new binomial(a._number_of_variables);
974  binomial& result=*S_bin;
975  // Note that we allocate memory for the result binomial. We often use
976  // pointers or references as argument and return types because the
977  // generating binomials of an ideal are kept in lists. For the performance
978  // of Buchberger's algorithm it it very important to avoid local copies
979  // of binomials, so a lot of attention is paid on the choice of argument
980  // and return types. As this choice is done in order to improve performance,
981  // it might be a bad choice with respect to code reuse (there are some
982  // dangerous constructions).
983
984  for(short i=0;i<result._number_of_variables;i++)
985    result.exponent_vector[i]=a.exponent_vector[i]-b.exponent_vector[i];
986  // The S-binomial corresponds to the vector difference.
987
988  // compute head and tail
989  short sign=w.compare_to_zero(result.exponent_vector);
990
991
992#ifdef NO_SUPPORT_DRIVEN_METHODS
993
994  if(sign==0)
995    // binomial reduced to zero
996    return result;
997
998  for(short i=0;i<result._number_of_variables;i++)
999    result.exponent_vector[i]*=sign;
1000
1001#endif  // NO_SUPPORT_DRIVEN_METHODS
1002
1003
1004#ifdef SUPPORT_DRIVEN_METHODS
1005
1006  result.head_support=0;
1007  result.tail_support=0;
1008
1009  if(sign==0)
1010    // binomial reduced to zero
1011    return result;
1012
1013  short size_of_support_vectors=CHAR_BIT*sizeof(unsigned long);
1014
1015
1016  // recompute the support vectors
1017
1018#ifdef SUPPORT_VARIABLES_FIRST
1019
1020  for(short i=0;i<result._number_of_variables;i++)
1021  {
1022
1023    Integer& actual_entry=result.exponent_vector[i];
1024    // to avoid unnecessary pointer arithmetic
1025
1026    actual_entry*=sign;
1027
1028    if(i<size_of_support_vectors)
1029      if(actual_entry>0)
1030        result.head_support|=(1<<i);
1031      else
1032        if(actual_entry<0)
1033          result.tail_support|=(1<<i);
1034  }
1035
1036#endif  // SUPPORT_VARIABLES_FIRST
1037
1038
1039#ifdef SUPPORT_VARIABLES_LAST
1040
1041  for(short i=0;i<result._number_of_variables;i++)
1042  {
1043    Integer& actual_entry=result.exponent_vector
1044      [result._number_of_variables-1-i];
1045    // to avoid unneccessary pointer arithmetic
1046
1047    actual_entry*=sign;
1048
1049    if(i<size_of_support_vectors)
1050      if(actual_entry>0)
1051        result.head_support|=(1<<i);
1052      else
1053        if(actual_entry<0)
1054          result.tail_support|=(1<<i);
1055  }
1056
1057#endif  // SUPPORT_VARIABLES_LAST
1058
1059
1060#endif  // SUPPORT_DRIVEN_METHODS
1061
1062
1063  return result;
1064}
1065
1066
1067
1068
1069///////////// criteria for unnecessary S-pairs ///////////////////////////////
1070
1071// The criteria are programmed in a way that tries to minimize pointer
1072// arithmetic. Therefore the code may appear a little bit inflated.
1073
1074
1075
1076
1077BOOLEAN relatively_prime(const binomial& a, const binomial& b)
1078{
1079
1080#ifdef NO_SUPPORT_DRIVEN_METHODS
1081
1082  // look at all variables
1083  for(short i=0;i<a._number_of_variables;i++)
1084    if((a.exponent_vector[i]>0) && (b.exponent_vector[i]>0))
1085      return FALSE;
1086
1087  return TRUE;
1088
1089#endif  // NO_SUPPORT_DRIVEN_METHODS
1090
1091
1092#ifdef SUPPORT_DRIVEN_METHODS
1093
1094  if((a.head_support & b.head_support)!=0)
1095  // common support variable in the heads
1096    return FALSE;
1097
1098  // no common support variable in the heads, look at remaining variables
1099  short size_of_support_vectors=CHAR_BIT*sizeof(unsigned long);
1100
1101
1102#ifdef SUPPORT_VARIABLES_FIRST
1103
1104  for(short i=size_of_support_vectors;i<a._number_of_variables;i++)
1105    if((a.exponent_vector[i]>0) && (b.exponent_vector[i]>0))
1106      return FALSE;
1107
1108  return TRUE;
1109
1110#endif  // SUPPORT_VARIABLES_FIRST
1111
1112
1113#ifdef SUPPORT_VARIABLES_LAST
1114
1115  for(short i=a._number_of_variables-1-size_of_support_vectors;i>=0;i--)
1116    if((a.exponent_vector[i]>0) && (b.exponent_vector[i]>0))
1117      return FALSE;
1118
1119  return TRUE;
1120
1121#endif  // SUPPORT_VARIABLES_LAST
1122
1123
1124#endif  // SUPPORT_DRIVEN_METHODS
1125
1126}
1127
1128
1129
1130
1131BOOLEAN M(const binomial& a, const binomial& b, const binomial& c)
1132// Returns TRUE iff lcm(head(a),head(c)) divides properly lcm(head(b),head(c)).
1133// This is checked by comparing the positive components of the exponent
1134// vectors.
1135{
1136
1137
1138#ifdef SUPPORT_DRIVEN_METHODS
1139
1140  long b_or_c=b.head_support|c.head_support;
1141
1142  if((a.head_support|b_or_c) != b_or_c)
1143    return FALSE;
1144  // The support of lcm(head(a),head(c)) equals the union of the head supports
1145  // of a and c. The above condition verifies if the support of
1146  // lcm(head(a),head(c)) is contained in the support of lcm(head(b),head(c))
1147  // by checking if head a involves a variable that is not involved in
1148  // head(b) or head(c).
1149
1150#endif  // SUPPORT_DRIVEN_METHODS
1151
1152
1153  BOOLEAN properly=FALSE;
1154
1155  for(short i=0;i<a._number_of_variables;i++)
1156  {
1157    Integer a_exponent=a.exponent_vector[i];
1158    Integer b_exponent=b.exponent_vector[i];
1159    Integer c_exponent=c.exponent_vector[i];
1160    Integer m1=MAXIMUM(a_exponent,c_exponent);
1161    Integer m2=MAXIMUM(b_exponent,c_exponent);
1162
1163    if(m1>0)
1164    {
1165      if(m1>m2)
1166        return FALSE;
1167      if(m1<m2)
1168        properly=TRUE;
1169    }
1170  }
1171
1172  return properly;
1173}
1174
1175
1176
1177
1178BOOLEAN F(const binomial& a, const binomial& b, const binomial& c)
1179// verifies if lcm(head(a),head(c))=lcm(head(b),head(c))
1180{
1181
1182#ifdef SUPPORT_DRIVEN_METHODS
1183
1184  if((a.head_support|c.head_support)!=(b.head_support|c.head_support))
1185    return FALSE;
1186  // The above condition verifies if the support of lcm(head(a),head(c))
1187  // equals the support of lcm(head(b),head(c)).
1188
1189#endif  // SUPPORT_DRIVEN_METHODS
1190
1191  for(short i=0;i<a._number_of_variables;i++)
1192  {
1193    Integer a_exponent=a.exponent_vector[i];
1194    Integer b_exponent=b.exponent_vector[i];
1195    Integer c_exponent=c.exponent_vector[i];
1196    Integer m1=MAXIMUM(a_exponent,c_exponent);
1197    Integer m2=MAXIMUM(b_exponent,c_exponent);
1198
1199    if((m1!=m2) && (m1>0 || m2>0))
1200      return FALSE;
1201  }
1202
1203  return TRUE;
1204}
1205
1206
1207
1208
1209BOOLEAN B(const binomial& a, const binomial& b, const binomial& c)
1210// verifies if head(a) divides lcm(head(b),head(c)) and
1211// lcm(head(a),head(b))!=lcm(head(b),head(c))!=lcm(head(a),head(c))
1212{
1213
1214#ifdef SUPPORT_DRIVEN_METHODS
1215
1216  long a_or_b=a.head_support|b.head_support;
1217  long a_or_c=a.head_support|c.head_support;
1218  long b_or_c=b.head_support|c.head_support;
1219
1220  if((a.head_support & b_or_c)!=a.head_support)
1221    return FALSE;
1222  // The above condition verifies if the support of head(a) is contained in
1223  // the support of lcm(head(b),head(c)).
1224
1225  if( (a_or_c != b_or_c) && (a_or_b != b_or_c))
1226    // Then the inequality conditions are guaranteed...
1227  {
1228    for(short i=0;i<a._number_of_variables;i++)
1229    {
1230      Integer b_exponent=b.exponent_vector[i];
1231      Integer c_exponent=c.exponent_vector[i];
1232
1233      if(a.exponent_vector[i]>MAXIMUM(b_exponent,c_exponent))
1234        return FALSE;
1235    }
1236
1237    return (TRUE);
1238  }
1239
1240
1241  if(a_or_b != b_or_c)
1242    // Then the first inequality conditions is guaranteed...
1243    // Verifie only the second.
1244  {
1245    BOOLEAN not_equal=FALSE;
1246
1247    for(short i=0;i<a._number_of_variables;i++)
1248    {
1249      Integer a_exponent=a.exponent_vector[i];
1250      Integer b_exponent=b.exponent_vector[i];
1251      Integer c_exponent=c.exponent_vector[i];
1252      Integer m=MAXIMUM(b_exponent, c_exponent);
1253
1254      if(a_exponent>m)
1255        return FALSE;
1256
1257      if(MAXIMUM(a_exponent,c_exponent) != m)
1258         not_equal=TRUE;
1259    }
1260    return(not_equal);
1261  }
1262
1263
1264  if( a_or_c != b_or_c )
1265    // Then the second inequality conditions is guaranteed...
1266    // Verifie only the first.
1267  {
1268    BOOLEAN not_equal=FALSE;
1269
1270    for(short i=0;i<a._number_of_variables;i++)
1271    {
1272      Integer a_exponent=a.exponent_vector[i];
1273      Integer b_exponent=b.exponent_vector[i];
1274      Integer c_exponent=c.exponent_vector[i];
1275      Integer m=MAXIMUM(b_exponent, c_exponent);
1276
1277      if(a_exponent > m)
1278        return FALSE;
1279
1280      if(MAXIMUM(a_exponent,b_exponent) != m)
1281        not_equal=TRUE;
1282    }
1283    return(not_equal);
1284  }
1285
1286#endif  // SUPPORT_DRIVEN_METHODS
1287
1288
1289  BOOLEAN not_equal_1=FALSE;
1290  BOOLEAN not_equal_2=FALSE;
1291
1292  for(short i=0;i<a._number_of_variables;i++)
1293  {
1294    Integer a_exponent=a.exponent_vector[i];
1295    Integer b_exponent=b.exponent_vector[i];
1296    Integer c_exponent=c.exponent_vector[i];
1297    Integer m=MAXIMUM(b_exponent, c_exponent);
1298
1299    if(a_exponent > m)
1300      return FALSE;
1301
1302    if(MAXIMUM(a_exponent,b_exponent) != m)
1303      not_equal_1=TRUE;
1304    if(MAXIMUM(a_exponent,c_exponent) != m)
1305      not_equal_2=TRUE;
1306  }
1307
1308  return (not_equal_1 && not_equal_2);
1309
1310}
1311
1312
1313
1314
1315BOOLEAN second_crit(const binomial& a, const binomial& b,
1316                    const binomial& c)
1317// verifies if head(a) divides lcm(head(b),head(c))
1318{
1319
1320#ifdef SUPPORT_DRIVEN_METHODS
1321
1322  if((a.head_support & (b.head_support|c.head_support))!=a.head_support)
1323    return FALSE;
1324  // The above condition verifies if the support of head(a) is contained in
1325  // the support of lcm(head(b),head(c))
1326
1327#endif  // SUPPORT_DRIVEN_METHODS.
1328
1329  for(short i=0;i<a._number_of_variables;i++)
1330  {
1331    Integer b_exponent=b.exponent_vector[i];
1332    Integer c_exponent=c.exponent_vector[i];
1333
1334    if(a.exponent_vector[i]>MAXIMUM(b_exponent,c_exponent))
1335      return FALSE;
1336  }
1337
1338  return (TRUE);
1339}
1340
1341
1342
1343
1344//////// special routines needed by the IP-algorithms ///////////////////////
1345
1346
1347
1348
1349BOOLEAN binomial::involves_elimination_variables(const term_ordering& w)
1350{
1351// The use of support information would require the distinction of various
1352// cases here (relation between the number of variables to eliminate
1353// and the number of support variables) and be quite difficult.
1354// It is doubtful if this would improve performance.
1355// As this function is not used in BuchbergerŽs algorithm (and therefore
1356// rather rarely), I renounce to implement this.
1357
1358  for(short i=0;i<w.number_of_elimination_variables();i++)
1359    // elimination variables are always the last ones
1360    if(exponent_vector[_number_of_variables-1-i]!=0)
1361      return TRUE;
1362
1363  return FALSE;
1364}
1365
1366
1367
1368
1369BOOLEAN binomial::drop_elimination_variables(const term_ordering& w)
1370{
1371  _number_of_variables-=w.number_of_elimination_variables();
1372  // dangerous (no compatibility check)!!
1373
1374  // copy components of interest to save memory
1375  // the leading term has to be recomputed!!
1376
1377  Integer *aux=exponent_vector;
1378  exponent_vector=new Integer[_number_of_variables];
1379
1380  if(w.weight(aux)>=0)
1381    for(short i=0;i<_number_of_variables;i++)
1382      exponent_vector[i]=aux[i];
1383  else
1384    for(short i=0;i<_number_of_variables;i++)
1385      exponent_vector[i]=-aux[i];
1386
1387  delete[] aux;
1388
1389
1390#ifdef SUPPORT_DRIVEN_METHODS
1391
1392  // Recompute head and tail.
1393  // Normally, this routine is only called for binomials that do not involve
1394  // the variables to eliminate. But if SUPPORT_VARIABLES_LAST is enabled,
1395  // the support changes in spite of this. Therefore, the support is
1396  // recomputed... For the same reasons as mentionned in the preceeding
1397  // routine, the existing support information is not used.
1398
1399  head_support=0;
1400  tail_support=0;
1401  short size_of_support_vectors=CHAR_BIT*sizeof(unsigned long);
1402  if(size_of_support_vectors>_number_of_variables)
1403    size_of_support_vectors=_number_of_variables;
1404
1405
1406#ifdef SUPPORT_VARIABLES_FIRST
1407
1408  for(short i=0;i<size_of_support_vectors;i++)
1409  {
1410    Integer actual_entry=exponent_vector[i];
1411    if(actual_entry>0)
1412      head_support|=(1<<i);
1413    else
1414      if(actual_entry[i]<0)
1415        tail_support|=(1<<i);
1416  }
1417
1418#endif  // SUPPORT_VARIABLES_FIRST
1419
1420
1421#ifdef SUPPORT_VARIABLES_LAST
1422
1423  for(short i=0;i<size_of_support_vectors;i++)
1424  {
1425    Integer actual_entry=exponent_vector[_number_of_variables-1-i];
1426    if(actual_entry>0)
1427      head_support|=(1<<i);
1428    else
1429      if(actual_entry<0)
1430        tail_support|=(1<<i);
1431  }
1432
1433#endif  // SUPPORT_VARIABLES_LAST
1434
1435
1436#endif  // SUPPORT_DRIVEN_METHODS
1437  return TRUE;
1438
1439}
1440
1441
1442
1443
1444BOOLEAN binomial::drop_last_weighted_variable(const term_ordering& w)
1445{
1446  _number_of_variables--;
1447  // dangerous!!
1448
1449  // copy components of interest to save memory
1450  // the leading term has to be recomputed!!
1451
1452  Integer *aux=exponent_vector;
1453  exponent_vector=new Integer[_number_of_variables];
1454
1455  short last_weighted_variable=w.number_of_weighted_variables()-1;
1456  aux[last_weighted_variable]=0;
1457  // set last component to zero, so it cannot influence the weight
1458
1459  if(w.weight(aux)>=0)
1460  {
1461    for(short i=0;i<last_weighted_variable;i++)
1462      exponent_vector[i]=aux[i];
1463    for(short i=last_weighted_variable;i<_number_of_variables;i++)
1464      exponent_vector[i]=aux[i+1];
1465  }
1466  else
1467  {
1468    for(short i=0;i<last_weighted_variable;i++)
1469      exponent_vector[i]=-aux[i];
1470     for(short i=last_weighted_variable;i<_number_of_variables;i++)
1471      exponent_vector[i]=-aux[i+1];
1472  }
1473
1474  delete[] aux;
1475
1476
1477#ifdef SUPPORT_DRIVEN_METHODS
1478
1479  // Recompute head and tail.
1480  // Normally, this routine is only called for binomials that do not involve
1481  // the variable to be dropped. But if SUPPORT_VARIABLES_LAST is enabled,
1482  // the support changes in spite of this. Therefore, the support is
1483  // recomputed... For the same reasons as mentionned in the preceeding
1484  // routines, the existing support information is not used.
1485
1486  head_support=0;
1487  tail_support=0;
1488  short size_of_support_vectors=CHAR_BIT*sizeof(unsigned long);
1489  if(size_of_support_vectors>_number_of_variables)
1490    size_of_support_vectors=_number_of_variables;
1491
1492
1493#ifdef SUPPORT_VARIABLES_FIRST
1494
1495  for(short i=0;i<size_of_support_vectors;i++)
1496  {
1497    Integer actual_entry=exponent_vector[i];
1498    if(actual_entry>0)
1499      head_support|=(1<<i);
1500    else
1501      if(actual_entry<0)
1502        tail_support|=(1<<i);
1503  }
1504
1505#endif  // SUPPORT_VARIABLES_FIRST
1506
1507
1508#ifdef SUPPORT_VARIABLES_LAST
1509
1510  for(short i=0;i<size_of_support_vectors;i++)
1511  {
1512    Integer actual_entry=exponent_vector[_number_of_variables-1-i];
1513    if(actual_entry>0)
1514      head_support|=(1<<i);
1515    else
1516      if(actual_entry<0)
1517        tail_support|=(1<<i);
1518  }
1519
1520#endif  // SUPPORT_VARIABLES_LAST
1521
1522#endif  // SUPPORT_DRIVEN_METHODS
1523  return TRUE;
1524}
1525
1526
1527
1528
1529int binomial::adapt_to_term_ordering(const term_ordering& w)
1530{
1531
1532  if(w.compare_to_zero(exponent_vector)<0)
1533  {
1534    // then exchange head and tail
1535    for(short i=0;i<_number_of_variables;i++)
1536      exponent_vector[i]*=(-1);
1537
1538
1539#ifdef SUPPORT_DRIVEN_METHODS
1540
1541    unsigned long swap=head_support;
1542    head_support=tail_support;
1543    tail_support=swap;
1544
1545#endif
1546
1547
1548    return -1;
1549    // binomial changed
1550  }
1551
1552  else
1553    return 1;
1554    // binomial unchanged
1555}
1556
1557
1558
1559
1560binomial& binomial::swap_variables(const short& i, const short& j)
1561{
1562
1563
1564#ifdef SUPPORT_DRIVEN_METHODS
1565
1566  // First adjust head_support and tail_support.
1567
1568  short size_of_support_vectors=CHAR_BIT*sizeof(unsigned long);
1569  if(size_of_support_vectors>_number_of_variables)
1570    size_of_support_vectors=_number_of_variables;
1571
1572
1573#ifdef SUPPORT_VARIABLES_FIRST
1574
1575  if(i<size_of_support_vectors)
1576    // else i is no support variable
1577  {
1578    if(exponent_vector[j]>0)
1579    // bit i will be 1 in the new head_support, 0 in the new tail_support
1580    {
1581      head_support|=(1<<i);
1582      // bit i is set to 1
1583
1584      tail_support&=~(1<<i);
1585      // bit i is set to 0
1586      // (in the complement ~(1<<i) all bits are 1 except from bit i)
1587    }
1588
1589    if(exponent_vector[j]==0)
1590    // bit i will be 0 in the new head_support, 0 in the new tail_support
1591    {
1592      head_support&=~(1<<i);
1593      // bit i is set to 0
1594
1595      tail_support&=~(1<<i);
1596      // bit i is set to 0
1597    }
1598
1599    if(exponent_vector[j]<0)
1600    // bit i will be 0 in the new head_support, 1 in the new tail_support
1601    {
1602      head_support&=~(1<<i);
1603      // bit i is set to 0
1604
1605      tail_support|=(1<<i);
1606      // bit i is set to 1
1607    }
1608  }
1609
1610
1611  if(j<size_of_support_vectors)
1612    // else j is no support variable
1613  {
1614    if(exponent_vector[i]>0)
1615    // bit j will be 1 in the new head_support, 0 in the new tail_support
1616    {
1617      head_support|=(1<<j);
1618      // bit j is set to 1
1619
1620      tail_support&=~(1<<j);
1621      // bit j is set to 0
1622      // (in the complement ~(1<<j) all bits are 1 except from bit j)
1623    }
1624
1625    if(exponent_vector[i]==0)
1626    // bit j will be 0 in the new head_support, 0 in the new tail_support
1627    {
1628      head_support&=~(1<<j);
1629      // bit j is set to 0
1630
1631      tail_support&=~(1<<j);
1632      // bit j is set to 0
1633    }
1634
1635    if(exponent_vector[i]<0)
1636    // bit j will be 0 in the new head_support, 1 in the new tail_support
1637    {
1638      head_support&=~(1<<j);
1639      // bit j is set to 0
1640
1641      tail_support|=(1<<j);
1642      // bit j is set to 1
1643    }
1644  }
1645
1646#endif  // SUPPORT_VARIABLES_FIRST
1647
1648
1649#ifdef SUPPORT_VARIABLES_LAST
1650
1651  // Using SUPPORT_VARIABLES_LAST, bit k of the support vectors
1652  // corresponds to exponent_vector[_number_of_variables-1-k],
1653  // hence bit _number_of_variables-1-i to exponent_vector[i].
1654
1655  if(i>=_number_of_variables-size_of_support_vectors)
1656    // else i is no support variable
1657  {
1658    if(exponent_vector[j]>0)
1659    // bit _number_of_variables-1-i will be 1 in the new head_support,
1660    // 0 in the new tail_support
1661    {
1662      short k=_number_of_variables-1-i;
1663
1664      head_support|=(1<<k);
1665      // bit _number_of_variables-1-i is set to 1
1666
1667      tail_support&=~(1<<k);
1668      // bit _number_of_variables-1-i is set to 0
1669      // (in the complement ~(1<<(_number_of_variables-1-i)) all bits are 1
1670      // except from bit _number_of_variables-1-i)
1671    }
1672
1673    if(exponent_vector[j]==0)
1674    // bit _number_of_variables-1-i will be 0 in the new head_support,
1675    // 0 in the new tail_support
1676    {
1677      short k=_number_of_variables-1-i;
1678
1679      head_support&=~(1<<k);
1680      // bit _number_of_variables-1-i is set to 0
1681
1682      tail_support&=~(1<<k);
1683      // bit _number_of_variables-1-i is set to 0
1684    }
1685
1686    if(exponent_vector[j]<0)
1687    // bit _number_of_variables-1-i will be 0 in the new head_support,
1688     // 1 in the new tail_support
1689    {
1690      short k=_number_of_variables-1-i;
1691
1692      head_support&=~(1<<k);
1693      // bit _number_of_variables-1-i is set to 0
1694
1695      tail_support|=(1<<k);
1696      // bit _number_of_variables-1-i is set to 1
1697    }
1698  }
1699
1700
1701  if(j>=_number_of_variables-size_of_support_vectors)
1702      // else j is no support variable
1703  {
1704   if(exponent_vector[i]>0)
1705    // bit _number_of_variables-1-j will be 1 in the new head_support,
1706    // 0 in the new tail_support
1707    {
1708      short k=_number_of_variables-1-j;
1709
1710      head_support|=(1<<k);
1711      // bit _number_of_variables-1-j is set to 1
1712
1713      tail_support&=~(1<<k);
1714      // bit _number_of_variables-1-j is set to 0
1715      // (in the complement ~(1<<(_number_of_variables-1-j)) all bits are 1
1716      // except from bit _number_of_variables-1-j)
1717    }
1718
1719    if(exponent_vector[i]==0)
1720    // bit _number_of_variables-1-j will be 0 in the new head_support,
1721    // 0 in the new tail_support
1722    {
1723      short k=_number_of_variables-1-j;
1724
1725      head_support&=~(1<<k);
1726      // bit _number_of_variables-1-j is set to 0
1727
1728      tail_support&=~(1<<k);
1729      // bit _number_of_variables-1-j is set to 0
1730    }
1731
1732    if(exponent_vector[i]<0)
1733    // bit _number_of_variables-1-j will be 0 in the new head_support,
1734     // 1 in the new tail_support
1735    {
1736      short k=_number_of_variables-1-j;
1737
1738      head_support&=~(1<<k);
1739      // bit _number_of_variables-1-j is set to 0
1740
1741      tail_support|=(1<<k);
1742      // bit _number_of_variables-1-j is set to 1
1743    }
1744  }
1745
1746#endif  // SUPPORT_VARIABLES_LAST
1747
1748#endif  // SUPPORT_DRIVEN_METHODS
1749
1750
1751// Now swap the components.
1752
1753  Integer swap=exponent_vector[j];
1754  exponent_vector[j]=exponent_vector[i];
1755  exponent_vector[i]=swap;
1756
1757  return *this;
1758
1759}
1760
1761binomial& binomial::flip_variable(const short& i)
1762{
1763
1764  if(exponent_vector[i]==0)
1765    // binomial does not involve variable to flip
1766    return *this;
1767
1768
1769#ifdef SUPPORT_DRIVEN_METHODS
1770
1771// First adjust head_support and tail_support.
1772
1773  short size_of_support_vectors=CHAR_BIT*sizeof(unsigned long);
1774  if(size_of_support_vectors>_number_of_variables)
1775    size_of_support_vectors=_number_of_variables;
1776
1777
1778#ifdef SUPPORT_VARIABLES_FIRST
1779
1780  if(i<size_of_support_vectors)
1781    // else i is no support variable
1782  {
1783    if(exponent_vector[i]>0)
1784      // variable i will be moved from head to tail
1785    {
1786      head_support&=~(1<<i);
1787      // bit i is set to 0
1788
1789      tail_support|=(1<<i);
1790      // bit i is set to 1
1791    }
1792
1793    else
1794      // variable i will be moved from tail to head
1795      // remember that exponent_vector[i]!=0
1796    {
1797      tail_support&=~(1<<i);
1798      // bit i is set to 0
1799
1800      head_support|=(1<<i);
1801      // bit i is set to 1
1802    }
1803  }
1804#endif  // SUPPORT_VARIABLES_FIRST
1805
1806#ifdef SUPPORT_VARIABLES_LAST
1807
1808  // Using SUPPORT_VARIABLES_LAST, bit k of the support vectors
1809  // corresponds to exponent_vector[_number_of_variables-1-k],
1810  // hence bit _number_of_variables-1-i to exponent_vector[i].
1811
1812  if(i>=_number_of_variables-size_of_support_vectors)
1813    // else i is no support variable
1814  {
1815    if(exponent_vector[i]>0)
1816    // variable i will be moved from head to tail
1817    {
1818      short k=_number_of_variables-1-i;
1819
1820      head_support&=~(1<<k);
1821      // bit _number_of_variables-1-i is set to 0
1822
1823      tail_support|=(1<<k);
1824      // bit _number_of_variables-1-i is set to 1
1825
1826     }
1827
1828    else
1829    // variable i will be moved from tail to head
1830    {
1831      short k=_number_of_variables-1-i;
1832
1833      tail_support&=~(1<<k);
1834      // bit _number_of_variables-1-i is set to 0
1835
1836      head_support|=(1<<k);
1837      // bit _number_of_variables-1-i is set to 1
1838
1839    }
1840  }
1841#endif  // SUPPORT_VARIABLES_LAST
1842
1843
1844#endif  // SUPPORT_DRIVEN_METHODS
1845
1846  // Now flip the variable.
1847
1848  exponent_vector[i]*=-1;
1849
1850}
1851
1852////////////////////////// output /////////////////////////////////////////
1853
1854void binomial::print() const
1855{
1856  printf("(");
1857  for(short i=0;i<_number_of_variables-1;i++)
1858    printf("%6d,",exponent_vector[i]);
1859  printf("%6d)\n",exponent_vector[_number_of_variables-1]);
1860}
1861
1862void binomial::print_all() const
1863{
1864  print();
1865
1866#ifdef SUPPORT_DRIVEN_METHODS
1867
1868  printf("head: %ld, tail %ld\n",head_support,tail_support);
1869
1870#endif  // SUPPORT_DRIVEN_METHODS
1871}
1872
1873void binomial::print(FILE* output) const
1874{
1875  fprintf(output,"(");
1876  for(short i=0;i<_number_of_variables-1;i++)
1877    fprintf(output,"%6d,",exponent_vector[i]);
1878  fprintf(output,"%6d)\n",exponent_vector[_number_of_variables-1]);
1879}
1880
1881void binomial::print_all(FILE* output) const
1882{
1883  print(output);
1884
1885#ifdef SUPPORT_DRIVEN_METHODS
1886
1887  fprintf(output,"head: %ld, tail %ld\n",head_support,tail_support);
1888
1889#endif  // SUPPORT_DRIVEN_METHODS
1890}
1891
1892void binomial::print(ofstream& output) const
1893{
1894  output<<"(";
1895  for(short i=0;i<_number_of_variables-1;i++)
1896    output<<setw(6)<<exponent_vector[i]<<",";
1897  output<<setw(6)<<exponent_vector[_number_of_variables-1]<<")"<<endl;
1898}
1899
1900void binomial::print_all(ofstream& output) const
1901{
1902  print(output);
1903
1904#ifdef SUPPORT_DRIVEN_METHODS
1905
1906  output<<"head: "<<setw(16)<<head_support<<", tail: "<<setw(16)
1907        <<tail_support<<endl;
1908
1909#endif  // SUPPORT_DRIVEN_METHODS
1910}
1911
1912void binomial::format_print(ofstream& output) const
1913{
1914  for(short i=0;i<_number_of_variables;i++)
1915    output<<setw(6)<<exponent_vector[i];
1916  output<<endl;
1917}
1918
1919#endif  // BINOMIAL_CC
Note: See TracBrowser for help on using the repository browser.