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

multipoly.H

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   // note that a Matrix is a Tuple, so we can
00022   // use coords[i] instead of coords(0,i) for
00023   // example.
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   //is zero or not ?
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 )                // was all 0 ?
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; //this resizes and sets the alphabets
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()) //found a nonzero poly ?
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() ) //zero ?
00208       return 0;
00209     else
00210       return coords[i].coeff_of( a[i].lp() );
00211   }
00212 
00213 
00214 
00215   //operators
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     //do A and B have their non zero entries
00342     //in the same position ?
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     // ans = f*a*lambda + g*b*mu
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     //do A and B have their non zero entries
00386     //in the same position ?
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     // ans = f*a*lambda + g*b*mu
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

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