Main Page | Class Hierarchy | Class List | File List | Class Members | File Members | Related Pages

powerprod.cpp

00001 #include "powerprod.H"
00002 using namespace std;
00003 
00004 
00005 // methods for the PowProd class
00006 
00007 AutoAlphabet PowProd::default_alphabet;
00008 Alphabet* PowProd::alphabet = &PowProd::default_alphabet;
00009 int PowProd::order = LEX;
00010 
00011 PowProd::PowProd(){}
00012 
00013 PowProd::PowProd(long var_num){
00014   long i;
00015 
00016   if(var_num > 0){
00017     powers.resize(var_num);
00018     for(i=0; i < var_num -1; i++)
00019       powers[i]=0;
00020     powers[var_num -1]=1;
00021   }
00022 }
00023 
00024 
00025 PowProd::PowProd(long var_num, long thepower){
00026   long i;
00027 
00028   if(var_num > 0 && thepower > 0){
00029     powers.resize(var_num);
00030     for(i=0; i < var_num -1; i++)
00031       powers[i]=0;
00032     powers[var_num -1]= thepower;
00033   }
00034 }
00035 
00036 
00037 
00038 PowProd::PowProd(const PowProd& that){
00039   powers=that.powers;
00040 }
00041 
00042 long PowProd::nvars() const {
00043   return powers.size();
00044 }
00045 
00046 long PowProd::degree() const {
00047   long n=0;
00048 
00049   for(long i=0; i < powers.size(); i++)
00050     n += powers[i];
00051 
00052   return n;
00053 }
00054 
00055 long PowProd::power_of(long i) const {
00056   if( (i > powers.size()) || (i<1) )
00057     return 0;
00058   else
00059     return powers[i-1];
00060 }
00061 
00062 PowProd& PowProd::operator=(const PowProd& that){
00063   powers=that.powers;
00064   return *this;
00065 }
00066 
00067 PowProd& PowProd::operator*=(const PowProd& that){
00068   long n, i;
00069 
00070   if( that.powers.size() <= powers.size() ) {
00071     for(i=0; i < that.powers.size(); i++)
00072       powers[i] += that.powers[i];
00073   }
00074   else {
00075     n= powers.size();
00076     powers.resize( that.powers.size() );
00077     for(i=0; i < n; i++)
00078       powers[i] += that.powers[i];
00079     for( ; i < powers.size(); i++)
00080       powers[i]=that.powers[i];
00081   }
00082   return *this;
00083 }
00084 
00085 PowProd PowProd::operator*( const PowProd& that) const {
00086   PowProd ans;
00087   // we try to avoid resizing ans too many times:
00088   if(powers.size() >= that.powers.size()){
00089     ans= (*this);
00090     ans *= that;
00091   }
00092   else{
00093     ans= that;
00094     ans *= (*this);
00095   }
00096   return ans;
00097 }
00098 
00099 bool PowProd::lex_lessthan(const PowProd& that) const {
00100   long n,m;
00101 
00102   n= powers.size();
00103   m= that.powers.size();
00104 
00105   if( n != m )
00106     return n < m;
00107   else{
00108     do {n--;}
00109     while( (n >= 0) && (powers[n]==that.powers[n]) );
00110     if( n < 0 )
00111       return false;
00112     else
00113       return (powers[n] < that.powers[n]);
00114   }
00115 }
00116 
00117 bool PowProd::lexsv_lessthan(const PowProd& that, long sv) const {
00118   long i,j;
00119   PowProd a,b;
00120 
00121   i= power_of(sv);
00122   j= that.power_of(sv);
00123   if( i != j )
00124     return i<j;
00125   //else...
00126   a= *this;
00127   b= that;
00128   if( sv <= powers.size() )
00129     a.powers[sv-1]= 0;
00130   if( sv <= that.powers.size() )
00131     b.powers[sv-1]= 0;
00132   return a.lex_lessthan(b);
00133 }
00134 
00135 
00136 
00137 bool PowProd::deglex_lessthan(const PowProd& that) const {
00138   long n,m;
00139 
00140   n= degree();
00141   m= that.degree();
00142 
00143   if( n != m )
00144     return n < m;
00145   else
00146     return this->lex_lessthan(that);
00147 }
00148 
00149 bool PowProd::deglexsv_lessthan(const PowProd& that, long sv) const {
00150   long i,j;
00151   PowProd a,b;
00152 
00153   i= power_of(sv);
00154   j= that.power_of(sv);
00155 
00156   if( i != j )
00157     return i<j;
00158   //else...
00159   a= *this;
00160   b= that;
00161   if( sv <= powers.size() )
00162     a.powers[sv-1]= 0;
00163   if( sv <= that.powers.size() )
00164     b.powers[sv-1]= 0;
00165   return a.deglex_lessthan(b);
00166 }
00167 
00168 bool PowProd::degrevlex_lessthan(const PowProd& that) const {
00169   long n,m,i;
00170 
00171   n= degree();
00172   m= that.degree();
00173 
00174   if( n != m )
00175     return n < m;
00176   else{
00177     n=powers.size();
00178     m=that.powers.size();
00179     n= (n < m) ? n : m;
00180     for(i=0; i < n; i++){
00181       if(powers[i]!=that.powers[i])
00182         break;
00183     }
00184     if(i==n)
00185       return false; // this==that in this case
00186     else
00187       return powers[i] > that.powers[i];
00188   }
00189 }
00190 
00191 bool PowProd::degrevlexsv_lessthan(const PowProd& that, long sv) const {
00192   long i,j;
00193   PowProd a,b;
00194 
00195   i= power_of(sv);
00196   j= that.power_of(sv);
00197   if( i != j )
00198     return i<j;
00199   //else...
00200   a= *this;
00201   b= that;
00202   if( sv <= powers.size() )
00203     a.powers[sv-1]= 0;
00204   if( sv <= that.powers.size() )
00205     b.powers[sv-1]= 0;
00206   return a.degrevlex_lessthan(b);
00207 }
00208 
00209 
00210 
00211 
00212 bool PowProd::operator<(const PowProd& that) const {
00213   switch(order){
00214   case LEX:
00215     return this->lex_lessthan(that);
00216   case DEGLEX:
00217     return this->deglex_lessthan(that);
00218   case DEGREVLEX:
00219     return this->degrevlex_lessthan(that);
00220   }
00221   return false; // in case order has a funny value
00222   // also keeps the compiler happy.
00223 }
00224 
00225 void PowProd::use_order(int theorder){
00226   order=theorder;
00227 }
00228 
00229 int PowProd::current_order(){
00230   return order;
00231 }
00232 
00233 bool PowProd::operator==(const PowProd& that) const {
00234   return powers == that.powers;
00235 }
00236 
00237 
00238 bool PowProd::divides(const PowProd& that) const {
00239   bool ans;
00240 
00241   if(powers.size() > that.powers.size())
00242     return false;
00243   else{
00244     ans=true;
00245     for(long i=0; i < powers.size(); i++)
00246       if( powers[i] > that.powers[i]){
00247         ans=false;
00248         break;
00249       }
00250   }
00251   return ans;
00252 }
00253 
00254 PowProd& PowProd::operator/=(const PowProd& that){
00255   Tuple<long> temp;
00256   long i,j;
00257   // set i=nb of substractions
00258   if(powers.size() > that.powers.size()){
00259     i=that.powers.size();
00260     temp= powers;
00261   }
00262   else{
00263     for(i=powers.size() -1; i>=0;i--){
00264       if(powers[i]!=that.powers[i])
00265         break;
00266     }
00267     i++;
00268     temp.resize(i);
00269   }
00270   //compute the answer
00271   for(j=0; j<i; j++)
00272     temp[j]=powers[j] - that.powers[j];
00273   //return
00274   powers= temp;
00275   return *this;
00276 }
00277 
00278 PowProd PowProd::operator/(const PowProd& that) const {
00279   PowProd ans;
00280 
00281   ans= *this;
00282   ans /= that;
00283   return ans;
00284 }
00285 
00286 bool PowProd::prime_to(const PowProd& that) const {
00287   long i,min;
00288 
00289   min= powers.size() > that.powers.size() ? that.powers.size() : powers.size();
00290 
00291   for(i=0; i<min; i++)
00292     if( (powers[i] != 0 ) && (that.powers[i] != 0 ) )
00293       return false;
00294 
00295   return true;
00296 
00297 }
00298 
00299 
00300 
00301 void PowProd::swap(long i, long j){
00302   long max, min, k, dummy, ii, jj;
00303 
00304   ii=i-1;
00305   jj=j-1;
00306   max= i > j ? ii : jj;
00307   min= i > j ? jj : ii;
00308   // easy case: everything in scope, size will not change
00309   if( max < powers.size() ){
00310     if( (max < powers.size()-1) || powers[min] !=0 ){
00311       dummy= powers[ii];
00312       powers[ii]= powers[jj];
00313       powers[jj]= dummy;
00314       return;
00315     }// if not, we need to reduce the size
00316     // in this case max= powersize -1, powers[max] is 
00317     // nonzero, powers[min] is zero, so min < max
00318     powers[min]= powers[max];
00319     for(k= max-1; powers[k]==0; k--);
00320     powers.resize(k+1);
00321     return;
00322   }
00323   // if none of this happened, we have max >= powersize
00324   // check if eveything is out of scope
00325     if( min >= powers.size() || powers[min]==0 )
00326       return; // in this case the swap involves variables
00327               // which are not there in the powprod: we return.
00328     // final case: we resize
00329     k= powers.size();
00330     powers.resize(max+1);
00331     for(; k<= max; k++)
00332       powers[k]=0;
00333     
00334     dummy= powers[ii];
00335     powers[ii]= powers[jj];
00336     powers[jj]= dummy;
00337     return; //phew !
00338 }
00339 
00340 void PowProd::shift(long n) {
00341   Tuple<long> temp;
00342   long i;
00343 
00344   if(powers.size() == 0) // empty?
00345     return;
00346   //else...
00347   temp.resize( powers.size() + n );
00348   for(i=0; i < n; i++)
00349     temp[i]=0;
00350   for(i=0; i < powers.size(); i++)
00351     temp[n + i]= powers[i];
00352   powers= temp;
00353 }
00354 
00355 
00356 
00357 Alphabet* PowProd::get_current_alphabet() {
00358   return PowProd::alphabet;
00359 }
00360 
00361 Alphabet* PowProd::get_default_alphabet() {
00362   return &PowProd::default_alphabet;
00363 }
00364 
00365 
00366 void PowProd::set_alphabet(Alphabet *thealphabet){
00367   PowProd::alphabet= thealphabet;
00368 }
00369 
00370 
00371 
00372 
00373 PowProd lcm(const PowProd& a, const PowProd& b){
00374   long i,n,m;
00375   PowProd ans;
00376 
00377   n= a.powers.size();
00378   m= b.powers.size();
00379   if(n>m){
00380     ans.powers= a.powers;
00381   }
00382   else{
00383     m= n;
00384     ans.powers= b.powers;
00385   }// now m=min
00386   //  ans.powers.resize(n); ????? what was this ????
00387   for(i=0; i<m; i++)
00388     ans.powers[i]= a.powers[i] > b.powers[i] ? a.powers[i] : b.powers[i];
00389   return ans;
00390 }
00391 
00392 bool powprod_compare(const PowProd& one, const PowProd& two, int theorder, long priority){
00393   switch(theorder){
00394   case LEX:
00395     return one.lex_lessthan(two);
00396   case LEXSV:
00397     return one.lexsv_lessthan(two, priority);
00398   case DEGLEX:
00399     return one.deglex_lessthan(two);
00400   case DEGLEXSV:
00401     return one.deglexsv_lessthan(two, priority);
00402   case DEGREVLEX:
00403     return one.degrevlex_lessthan(two);
00404   case DEGREVLEXSV:
00405     return one.degrevlexsv_lessthan(two, priority);
00406   }
00407   return false; // in case order has a funny value
00408 
00409 
00410 }
00411 
00412 
00413 
00414 
00415 ostream& operator<<(ostream& os, const PowProd& P){
00416   long i;
00417 
00418   if(P.nvars() == 0){
00419     os << "I";
00420     return os;
00421   }
00422 
00423   for(i=0; i < P.nvars(); i++){
00424     if(P.powers[i] != 0){
00425       os << PowProd::alphabet->nameof(i+1);
00426       if(P.powers[i] > 1) 
00427         os << "^" << P.powers[i];
00428     }
00429   }
00430   return os;
00431 }
00432 
00433 
00434 ofstream& operator<<(ofstream& file, PowProd& x){
00435 
00436   file << x.powers;
00437   return file;
00438 }
00439 
00440 void operator>>(ifstream& file, PowProd& x){
00441 
00442   file >> x.powers;
00443 }
00444 
00445 
00446 

Generated on Wed Jun 18 17:22:41 2008 for Pierre Guillot by  doxygen 1.3.9.1