00001 #ifndef _MULTIPOLY_H_
00002 #define _MULTIPOLY_H_
00003
00004 #include "polynomials.H"
00005 #include "tables.H"
00006 using namespace std;
00007
00009
00017 template <class K>
00018 class multiPolynomial {
00019 public:
00021
00022
00023
00024 Matrix< Polynomial<K> > coords;
00026 multiPolynomial(){
00027 coords.set_sep('|');
00028 }
00029
00030 void resize(long n) {
00031
00032 coords.resize(1,n);
00033 }
00034
00035 long size() const {
00036
00037 return coords.size();
00038 }
00039
00040 void set_alphabet(const Alphabet *alpha) {
00041 long i;
00042
00043 for(i= 0; i< coords.size(); i++)
00044 coords[i].alphabet= (Alphabet *) alpha;
00045 }
00046
00047
00048
00049 bool is_zero() const {
00050 long i;
00051
00052 for(i=0; i< coords.size(); i++)
00053 if(!coords[i].is_zero())
00054 return false;
00055
00056 return true;
00057 }
00058
00059 void sets_to_zero() {
00060 long i;
00061
00062 for(i=0; i< coords.size(); i++)
00063 coords[i].sets_to_zero();
00064 }
00065
00066
00067
00069
00075 multiPolynomial<K> lm() const {
00076 long i;
00077 PowProd max(0), other;
00078 long j= -1;
00079 multiPolynomial<K> ans;
00080
00081 ans.resize( coords.size() );
00082 ans.set_alphabet((Alphabet *) coords[0].alphabet );
00083
00084 for(i= 0; i< coords.size(); i++){
00085 if( !coords[i].is_zero() ){
00086 other= coords[i].lp();
00087 if( max < other || (j==-1 )){
00088 max= other;
00089 j= i;
00090 }
00091 }
00092 }
00093
00094 if(j != -1)
00095 ans[j].add_term(max, 1);
00096
00097 return ans;
00098 }
00099
00101 PowProd lp() const {
00102 long i;
00103 PowProd max(0), other;
00104 long j= -1;
00105
00106 for(i= 0; i< coords.size(); i++){
00107 if( !coords[i].is_zero() ){
00108 other= coords[i].lp();
00109 if( max < other || (j==-1 )){
00110 max= other;
00111 j= i;
00112 }
00113 }
00114 }
00115
00116 return max;
00117
00118 }
00119
00121 K lc() const {
00122 long i;
00123 PowProd max(0), other;
00124 long j= -1;
00125
00126 for(i= 0; i< coords.size(); i++){
00127 if( !coords[i].is_zero() ){
00128 other= coords[i].lp();
00129 if( max < other || (j==-1 )){
00130 max= other;
00131 j= i;
00132 }
00133 }
00134 }
00135 if( j== -1 )
00136 return 0;
00137
00138 return coords[j].coeff_of(max);
00139 }
00140
00141
00142
00144
00150 multiPolynomial<K> lm_POT() const {
00151 long i;
00152 multiPolynomial<K> ans;
00153
00154 ans.coords= coords;
00155 ans.sets_to_zero();
00156
00157 for(i=0; i < coords.size(); i++)
00158 if( !coords[i].is_zero() )
00159 break;
00160
00161 if(i< coords.size())
00162 ans[i].add_term(coords[i].lp(), 1);
00163
00164 return ans;
00165 }
00166
00168 PowProd lp_POT() const {
00169 long i;
00170
00171 for(i=0; i< coords.size(); i++)
00172 if( !coords[i].is_zero() )
00173 return coords[i].lp();
00174
00175 return PowProd(0);
00176 }
00177
00179
00185 K lc_POT() const {
00186 long i;
00187
00188 for(i=0; i< coords.size(); i++)
00189 if( !coords[i].is_zero() )
00190 return coords[i].lc();
00191
00192 return 1;
00193 }
00194
00196
00201 K coeff_of(const multiPolynomial<K>& a) const {
00202 long i;
00203
00204 for(i=0; i< a.size(); i++)
00205 if(!a[i].is_zero())
00206 break;
00207 if( i == a.size() )
00208 return 0;
00209 else
00210 return coords[i].coeff_of( a[i].lp() );
00211 }
00212
00213
00214
00215
00216 Polynomial<K>& operator[](long n) {
00217 return coords(0,n);
00218 }
00219
00220 const Polynomial<K>& operator[](long n) const {
00221 return coords(0,n);
00222 }
00223
00224 multiPolynomial<K>& operator+=(const multiPolynomial<K>& that){
00225
00226 coords+= that.coords;
00227 return *this;
00228 }
00229
00230 multiPolynomial<K> operator+(const multiPolynomial<K>& that) const {
00231 multiPolynomial<K> ans;
00232
00233 ans= *this;
00234 ans+= that;
00235 return ans;
00236 }
00237
00238
00239 multiPolynomial<K>& operator*=(const Polynomial<K>& P) {
00240
00241 coords*= P;
00242 return *this;
00243 }
00244
00245 multiPolynomial<K> operator*(const Polynomial<K>& P) const {
00246 multiPolynomial ans;
00247
00248 ans= *this;
00249 ans*= P;
00250 return ans;
00251 }
00252
00253 multiPolynomial<K>& operator*=(const K& c) {
00254 long i;
00255
00256 for(i=0; i< coords.size(); i++)
00257 coords[i] *= c;
00258
00259 return *this;
00260 }
00261
00262 multiPolynomial<K> operator*(const K& c) const {
00263 multiPolynomial ans;
00264
00265 ans= *this;
00266 ans*= c;
00267 return ans;
00268 }
00269
00270
00279 bool divides(const multiPolynomial<K>& that) const {
00280 long i;
00281
00282 if(this->size() != that.size())
00283 return false;
00284 for(i=0; i< coords.size(); i++)
00285 if(!coords[i].is_zero())
00286 break;
00287 if(i== coords.size() || that.coords[i].is_zero())
00288 return false;
00289 return coords[i].lp().divides( that.coords[i].lp() );
00290 }
00291
00298 Polynomial<K> operator/(const multiPolynomial<K>& that) const {
00299 long i;
00300 PowProd temp;
00301 Polynomial<K> dummy;
00302 dummy.sets_to_zero();
00303
00304 if(this->size() != that.size())
00305 return dummy;
00306 for(i=0; i< coords.size(); i++)
00307 if(!coords[i].is_zero())
00308 break;
00309 if(i== coords.size() || that.coords[i].is_zero())
00310 return dummy;
00311
00312 temp= coords[i].lp();
00313 temp /= that.coords[i].lp();
00314 dummy= Polynomial<K>( temp );
00315 dummy.alphabet= coords[i].alphabet;
00316
00317 return dummy;
00318 }
00319
00320 friend ostream& operator<<(ostream& os, const multiPolynomial<K>& M){
00321
00322 os << M.coords;
00323 return os;
00324 }
00325
00331 friend multiPolynomial<K> S_polynomial_with_coefficients(const multiPolynomial<K>& f,
00332 const multiPolynomial<K>& g,
00333 pair< Polynomial<K>, Polynomial<K> >& coeffs){
00334 PowProd a,b,c;
00335 K lambda, mu;
00336 multiPolynomial<K> A, B, ans;
00337 long i, j;
00338
00339 A= f.lm();
00340 B= g.lm();
00341
00342
00343 for(i= 0; i < A.size(); i++)
00344 if( !A[i].is_zero() )
00345 break;
00346 for(j= 0; j < B.size(); j++)
00347 if( !B[j].is_zero() )
00348 break;
00349
00350 if( (i!=j) || (i==A.size()) || (j==B.size()) ){
00351 coeffs.first.sets_to_zero();
00352 coeffs.second.sets_to_zero();
00353 }
00354 else{
00355 a= A.lp();
00356 b= B.lp();
00357 c= lcm(a,b);
00358 lambda= 1 / f.lc();
00359 mu= -1 / g.lc();
00360 a= c/a;
00361 b= c/b;
00362 coeffs.first= Polynomial<K>(a) * lambda;
00363 coeffs.second= Polynomial<K>(b) * mu;
00364 }
00365
00366
00367
00368 coeffs.first.alphabet= f[0].alphabet;
00369 coeffs.second.alphabet= f[0].alphabet;
00370 ans= f * coeffs.first + g * coeffs.second;
00371
00372 return ans;
00373 }
00374
00375 friend multiPolynomial<K> S_polynomial(const multiPolynomial<K>& f,
00376 const multiPolynomial<K>& g){
00377 pair< Polynomial<K>, Polynomial<K> > coeffs;
00378 PowProd a,b,c;
00379 K lambda, mu;
00380 multiPolynomial<K> A, B, ans;
00381 long i, j;
00382
00383 A= f.lm();
00384 B= g.lm();
00385
00386
00387 for(i= 0; i < A.size(); i++)
00388 if( !A[i].is_zero() )
00389 break;
00390 for(j= 0; j < B.size(); j++)
00391 if( !B[j].is_zero() )
00392 break;
00393
00394 if( (i!=j) || (i==A.size()) || (j==B.size()) ){
00395 coeffs.first.sets_to_zero();
00396 coeffs.second.sets_to_zero();
00397 }
00398 else{
00399 a= A.lp();
00400 b= B.lp();
00401 c= lcm(a,b);
00402 lambda= 1 / f.lc();
00403 mu= -1 / g.lc();
00404 a= c/a;
00405 b= c/b;
00406 coeffs.first= Polynomial<K>(a) * lambda;
00407 coeffs.second= Polynomial<K>(b) * mu;
00408 }
00409
00410
00411
00412 coeffs.first.alphabet= f[0].alphabet;
00413 coeffs.second.alphabet= f[0].alphabet;
00414 ans= f * coeffs.first + g * coeffs.second;
00415
00416 return ans;
00417
00418
00419 }
00420
00421
00422
00423 };
00424
00425 #endif