00001 #include "powerprod.H"
00002 using namespace std;
00003
00004
00005
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
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
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
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;
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
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;
00222
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
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
00271 for(j=0; j<i; j++)
00272 temp[j]=powers[j] - that.powers[j];
00273
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
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 }
00316
00317
00318 powers[min]= powers[max];
00319 for(k= max-1; powers[k]==0; k--);
00320 powers.resize(k+1);
00321 return;
00322 }
00323
00324
00325 if( min >= powers.size() || powers[min]==0 )
00326 return;
00327
00328
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;
00338 }
00339
00340 void PowProd::shift(long n) {
00341 Tuple<long> temp;
00342 long i;
00343
00344 if(powers.size() == 0)
00345 return;
00346
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 }
00386
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;
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