// binomial.cc // implementation of class binomial #ifndef BINOMIAL_CC #define BINOMIAL_CC #include #include "binomial__term_ordering.h" ///////////////////////// constructors and destructor ////////////////////// // For a better overview, the constructor code is separated for // NO_SUPPORT_DRIVEN_METHODS and SUPPORT_DRIVEN_METHODS. #ifdef NO_SUPPORT_DRIVEN_METHODS binomial::binomial(const short& number_of_variables) :_number_of_variables(number_of_variables) { exponent_vector=new Integer[_number_of_variables]; } binomial::binomial(const short& number_of_variables,const Integer* exponents) :_number_of_variables(number_of_variables) { // range check for rarely used constructors if(_number_of_variables<=0) { cerr<<"\nWARNING: binomial::binomial(const short&, const Integer*):\n" "argument out of range"<=0) for(short i=0;i<_number_of_variables;i++) exponent_vector[i]=exponents[i]; else for(short i=0;i<_number_of_variables;i++) exponent_vector[i]=-exponents[i]; } binomial::binomial(const binomial& b) :_number_of_variables(b._number_of_variables) { exponent_vector=new Integer[_number_of_variables]; for(short i=0;i<_number_of_variables;i++) exponent_vector[i]=b.exponent_vector[i]; } #endif // NO_SUPPORT_DRIVEN_METHODS #ifdef SUPPORT_DRIVEN_METHODS binomial::binomial(const short& number_of_variables) :_number_of_variables(number_of_variables),head_support(0),tail_support(0) { exponent_vector=new Integer[_number_of_variables]; } binomial::binomial(const short& number_of_variables, const Integer* exponents) :_number_of_variables(number_of_variables),head_support(0),tail_support(0) { // range check for rarely used constructors if(_number_of_variables<=0) { exponent_vector=NULL; // to avoid problems when deleting cerr<<"\nWARNING: binomial::binomial(const short&, const Integer*):\n" "argument out of range"<0) head_support|=(1<=0) sign=1; else sign=-1; for(short i=0;i<_number_of_variables;i++) { #ifdef SUPPORT_VARIABLES_FIRST Integer actual_entry=sign*exponents[i]; exponent_vector[i]=actual_entry; #endif // SUPPORT_VARIABLES_FIRST #ifdef SUPPORT_VARIABLES_LAST short j=_number_of_variables-1-i; Integer actual_entry=sign*exponents[j]; exponent_vector[j]=actual_entry; #endif // SUPPORT_VARIABLES_LAST if(i0) head_support|=(1<comp_value) return(FALSE); return(TRUE); } BOOLEAN binomial::operator>=(const Integer comp_value) const { #ifdef SUPPORT_DRIVEN_METHODS if(comp_value==0) if(tail_support!=0) return(FALSE); #endif for(short i=0;i<_number_of_variables;i++) if(exponent_vector[i]0 and b.exponent_vector[i]>0 // (0 if there are no such quotients). // A negative return value means b=0 or head(b)=1. { #ifdef NO_SUPPORT_DRIVEN_METHODS Integer result=-1; Integer new_result=-1; // -1 stands for infinitely many reductions for(short i=0;i<_number_of_variables;i++) // explicit sign tests for all components { Integer actual_b_component=b.exponent_vector[i]; if(actual_b_component>0) // else variable i is not involved in the head of b { Integer actual_component=exponent_vector[i]; if(actual_component=1 if((new_result_number_of_variables) size_of_support_vectors=_number_of_variables; // number of components of the support vectors #ifdef SUPPORT_VARIABLES_FIRST for(short i=0;i0 ! // (head support contains that of b) if(new_result==0) // exponent_vector[i]=1 if((new_result0) // else variable i is not involved in the head of b { Integer actual_component=exponent_vector[i]; if(actual_component=1 if((new_result0 ! // (head support contains that of b) if(new_result==0) // exponent_vector[_number_of_variables-1-i] // =1 if((new_result0) // else variable number_of_variables-1-i is not involved in the head of b { Integer actual_component=exponent_vector[j]; if(actual_component=1 if((new_result0 // (0 if there are no such quotients). // A negative return value means b=0 or head(b)=1. { #ifdef NO_SUPPORT_DRIVEN_METHODS Integer result=-1; Integer new_result=-1; // -1 stands for infinitely many reductions for(short i=0;i<_number_of_variables;i++) // explicit sign tests for all components { Integer actual_b_component=b.exponent_vector[i]; if(actual_b_component>0) // else variable i is not involved in the head of b { Integer actual_component=-exponent_vector[i]; if(actual_component=1 if((new_result_number_of_variables) size_of_support_vectors=_number_of_variables; // number of components of the support vectors #ifdef SUPPORT_VARIABLES_FIRST for(short i=0;i=1 if((new_result0) // else variable i is not involved in the head of b { Integer actual_component=-exponent_vector[i]; if(actual_component=1 if((new_result=1 if((new_result0) // else variable number_of_variables-1-i is not involved in the head of b { Integer actual_component=-exponent_vector[j]; if(actual_component=1 if((new_result0) head_support|=(1<0) head_support|=(1<0) head_support|=(1<0) head_support|=(1<0) result.head_support|=(1<0) result.head_support|=(1<0) && (b.exponent_vector[i]>0)) return FALSE; return TRUE; #endif // NO_SUPPORT_DRIVEN_METHODS #ifdef SUPPORT_DRIVEN_METHODS if((a.head_support & b.head_support)!=0) // common support variable in the heads return FALSE; // no common support variable in the heads, look at remaining variables short size_of_support_vectors=CHAR_BIT*sizeof(unsigned long); #ifdef SUPPORT_VARIABLES_FIRST for(short i=size_of_support_vectors;i0) && (b.exponent_vector[i]>0)) return FALSE; return TRUE; #endif // SUPPORT_VARIABLES_FIRST #ifdef SUPPORT_VARIABLES_LAST for(short i=a._number_of_variables-1-size_of_support_vectors;i>=0;i--) if((a.exponent_vector[i]>0) && (b.exponent_vector[i]>0)) return FALSE; return TRUE; #endif // SUPPORT_VARIABLES_LAST #endif // SUPPORT_DRIVEN_METHODS } BOOLEAN M(const binomial& a, const binomial& b, const binomial& c) // Returns TRUE iff lcm(head(a),head(c)) divides properly lcm(head(b),head(c)). // This is checked by comparing the positive components of the exponent // vectors. { #ifdef SUPPORT_DRIVEN_METHODS long b_or_c=b.head_support|c.head_support; if((a.head_support|b_or_c) != b_or_c) return FALSE; // The support of lcm(head(a),head(c)) equals the union of the head supports // of a and c. The above condition verifies if the support of // lcm(head(a),head(c)) is contained in the support of lcm(head(b),head(c)) // by checking if head a involves a variable that is not involved in // head(b) or head(c). #endif // SUPPORT_DRIVEN_METHODS BOOLEAN properly=FALSE; for(short i=0;i0) { if(m1>m2) return FALSE; if(m10 || m2>0)) return FALSE; } return TRUE; } BOOLEAN B(const binomial& a, const binomial& b, const binomial& c) // verifies if head(a) divides lcm(head(b),head(c)) and // lcm(head(a),head(b))!=lcm(head(b),head(c))!=lcm(head(a),head(c)) { #ifdef SUPPORT_DRIVEN_METHODS long a_or_b=a.head_support|b.head_support; long a_or_c=a.head_support|c.head_support; long b_or_c=b.head_support|c.head_support; if((a.head_support & b_or_c)!=a.head_support) return FALSE; // The above condition verifies if the support of head(a) is contained in // the support of lcm(head(b),head(c)). if( (a_or_c != b_or_c) && (a_or_b != b_or_c)) // Then the inequality conditions are guaranteed... { for(short i=0;iMAXIMUM(b_exponent,c_exponent)) return FALSE; } return (TRUE); } if(a_or_b != b_or_c) // Then the first inequality conditions is guaranteed... // Verifie only the second. { BOOLEAN not_equal=FALSE; for(short i=0;im) return FALSE; if(MAXIMUM(a_exponent,c_exponent) != m) not_equal=TRUE; } return(not_equal); } if( a_or_c != b_or_c ) // Then the second inequality conditions is guaranteed... // Verifie only the first. { BOOLEAN not_equal=FALSE; for(short i=0;i m) return FALSE; if(MAXIMUM(a_exponent,b_exponent) != m) not_equal=TRUE; } return(not_equal); } #endif // SUPPORT_DRIVEN_METHODS BOOLEAN not_equal_1=FALSE; BOOLEAN not_equal_2=FALSE; for(short i=0;i m) return FALSE; if(MAXIMUM(a_exponent,b_exponent) != m) not_equal_1=TRUE; if(MAXIMUM(a_exponent,c_exponent) != m) not_equal_2=TRUE; } return (not_equal_1 && not_equal_2); } BOOLEAN second_crit(const binomial& a, const binomial& b, const binomial& c) // verifies if head(a) divides lcm(head(b),head(c)) { #ifdef SUPPORT_DRIVEN_METHODS if((a.head_support & (b.head_support|c.head_support))!=a.head_support) return FALSE; // The above condition verifies if the support of head(a) is contained in // the support of lcm(head(b),head(c)) #endif // SUPPORT_DRIVEN_METHODS. for(short i=0;iMAXIMUM(b_exponent,c_exponent)) return FALSE; } return (TRUE); } //////// special routines needed by the IP-algorithms /////////////////////// BOOLEAN binomial::involves_elimination_variables(const term_ordering& w) { // The use of support information would require the distinction of various // cases here (relation between the number of variables to eliminate // and the number of support variables) and be quite difficult. // It is doubtful if this would improve performance. // As this function is not used in Buchbergerīs algorithm (and therefore // rather rarely), I renounce to implement this. for(short i=0;i=0) for(short i=0;i<_number_of_variables;i++) exponent_vector[i]=aux[i]; else for(short i=0;i<_number_of_variables;i++) exponent_vector[i]=-aux[i]; delete[] aux; #ifdef SUPPORT_DRIVEN_METHODS // Recompute head and tail. // Normally, this routine is only called for binomials that do not involve // the variables to eliminate. But if SUPPORT_VARIABLES_LAST is enabled, // the support changes in spite of this. Therefore, the support is // recomputed... For the same reasons as mentionned in the preceeding // routine, the existing support information is not used. head_support=0; tail_support=0; short size_of_support_vectors=CHAR_BIT*sizeof(unsigned long); if(size_of_support_vectors>_number_of_variables) size_of_support_vectors=_number_of_variables; #ifdef SUPPORT_VARIABLES_FIRST for(short i=0;i0) head_support|=(1<0) head_support|=(1<=0) { for(short i=0;i_number_of_variables) size_of_support_vectors=_number_of_variables; #ifdef SUPPORT_VARIABLES_FIRST for(short i=0;i0) head_support|=(1<0) head_support|=(1<_number_of_variables) size_of_support_vectors=_number_of_variables; #ifdef SUPPORT_VARIABLES_FIRST if(i0) // bit i will be 1 in the new head_support, 0 in the new tail_support { head_support|=(1<0) // bit j will be 1 in the new head_support, 0 in the new tail_support { head_support|=(1<=_number_of_variables-size_of_support_vectors) // else i is no support variable { if(exponent_vector[j]>0) // bit _number_of_variables-1-i will be 1 in the new head_support, // 0 in the new tail_support { short k=_number_of_variables-1-i; head_support|=(1<=_number_of_variables-size_of_support_vectors) // else j is no support variable { if(exponent_vector[i]>0) // bit _number_of_variables-1-j will be 1 in the new head_support, // 0 in the new tail_support { short k=_number_of_variables-1-j; head_support|=(1<_number_of_variables) size_of_support_vectors=_number_of_variables; #ifdef SUPPORT_VARIABLES_FIRST if(i0) // variable i will be moved from head to tail { head_support&=~(1<=_number_of_variables-size_of_support_vectors) // else i is no support variable { if(exponent_vector[i]>0) // variable i will be moved from head to tail { short k=_number_of_variables-1-i; head_support&=~(1<