synaps/mpol/macaulay.h

Go to the documentation of this file.
00001 /*********************************************************************
00002 *      This file is part of the source code of SYNAPS kernel.        *
00003 *   Author(s): B. Mourrain, GALAAD, INRIA                            *
00004 **********************************************************************/
00005 #ifndef SYNAPS_RESULTANT_MACAULAY_H
00006 #define SYNAPS_RESULTANT_MACAULAY_H
00007 //----------------------------------------------------------------------
00008 #include <synaps/init.h>
00009 #include <synaps/linalg/VECTOR.m>
00010 #include <synaps/linalg/rep2d.h>
00011 #include <synaps/linalg/MATRIX.m>
00012 #include <synaps/mpol/MPol.h>
00013 #include <synaps/mpol/matrixof.h>
00014 #include <synaps/mpol/MPOLDST.m>
00015 #include <map>
00016 #include <synaps/arithm/binomial.h>
00017 __BEGIN_NAMESPACE_SYNAPS
00018 //====================================================================
00023 //--------------------------------------------------------------------
00025 unsigned int SizeOfS(unsigned int n, unsigned int k) 
00026 {
00028   //  double factn = 1;
00029   //  double factnu=1;
00030   //  double factnun=1;
00031   //  for (unsigned int i = 0; i < n;i++) factn *= (n-i);
00032   //  for (unsigned int i = k+n; i >1;i--) factnun *= i; 
00033   //  for (unsigned int i = 0; i < k;i++) factnu*=(k-i);
00034   //   return (int) (factnun/(factn*factnu));
00035   /* peut eviter un depassement de capacite dans le calcul des factorielles */
00036   return binomial<int>(n+k,k); 
00037 }
00038 //----------------------------------------------------------------------
00043 template<class POL>
00044 int choose(int k, int n, POL & ML){
00045 
00046   typedef typename POL::monom_t MON;
00047   
00048   MON m;
00049   POL P, Sigma(1);
00050 
00051   for(int i=0;i<n;i++) Sigma +=MON(i,1);
00052   ML = POL(1);
00053   for(int j=1; j<=k; j++) {
00054     
00055     ML *= Sigma;
00056   }
00057   
00058   int c=0;
00059   for (typename POL::iterator i = ML.begin(); i!=ML.end(); i++)
00060     {
00061       c++;
00062       i->setcoeff(1.);
00063     }
00064   return c;
00065 }
00066 
00071 template<class POL>
00072 POL HomChoose(int k, int n){
00073 
00074   typedef typename POL::monom_t MON;
00075   
00076   MON m;
00077   POL ML, P, Sigma =POL(0);
00078 
00079   for(int i=0;i<n;i++) 
00080     {
00081       Sigma += POL(MON(i,1));
00082     }
00083   ML = POL(1);
00084   for(int j=0; j<k; j++) 
00085     ML *= Sigma;
00086   
00087   for (typename POL::iterator i = ML.begin(); i!=ML.end(); i++)
00088     {
00089       i->setcoeff(1.);
00090     }
00091   return ML;
00092 }
00093 
00094 
00095 //----------------------------------------------------------------------
00110 template<class R, class L>
00111 R macaulay(const L & f, char z='N'){
00112 
00113   typedef typename L::value_type POL;
00114   typedef typename POL::monom_t MON;
00115   typedef typename POL::order_t O;
00116 
00117   int d[f.size()], n = f.size()-1, nu = 0;
00118   POL F;
00119 
00120   // Calcul de mu et des differents degres di
00121   typename L::const_iterator fi;int i;
00122   for(i=0, fi=f.begin(); i<=n; i++, fi++)
00123   {
00124     d[i] = std::max(MPOLDST::degree(*fi),1);
00125     nu += d[i];
00126   }
00127   nu -= n; 
00128 
00129   MON* xdi = new MON[n+1];
00130   POL* B   = new POL[n+1];
00131 
00132   xdi[0]= MON(1);
00133   B[0]  = POL(1);
00134   for(int j=1; j<=n; j++){
00135     xdi[j] = MON(j-1,d[j]);
00136     B[j]=0;
00137     for(int i=0;i<d[j];i++) {B[j]+=POL(MON(j-1,i));}
00138     //cout<<"B "<< B[j]<<endl;
00139   }
00140 
00141   // Construction des bases locales 
00142   POL* E= new POL[n+1];
00143   E[0]=1;
00144 
00145   POL U(1), V(1);
00146   int mu;
00147     
00148   for(int i=n;i>0;i--){
00149 
00150     mu = nu-d[i];
00151     for (typename POL::const_iterator j = E[0].begin(); j!=E[0].end(); j++)
00152     {
00153       choose(mu- degree(*j),i,V);
00154       //XXX A Ameliorer
00155       E[i] += V*(*j);
00156     }
00157     E[0]*=B[i];
00158     //cout<<"E "<< E[i]<<endl;
00159   } 
00160     //cout<<"E "<< E[0]<<endl;
00161   //Index des monomes
00162   std::map<MON,int,O> index;
00163   int c =0, nz=0;
00164   MON m;
00165   for(int i=0; i <=n;i++){
00166     for (typename POL::reverse_iterator j = E[i].rbegin(); j!=E[i].rend();j++){
00167       m = (*j)*xdi[i];
00168       index[m]=c;
00169       //cout <<"index "<<m<<" "<<index[m]<<endl;
00170       c++;
00171     }
00172     nz += E[i].size()*(f[i].size());
00173     
00174   }
00175   
00176   //Construction de la matrice de Macaulay
00177   int taille = SizeOfS(n,nu);
00178   assert(taille==c);
00179 
00180   R Res;
00181   matrixof::reserve(Res,taille,taille,nz);
00182   // if(!Res) Error(cout<<"Not enough memory for a matrix"<<i<<"*"<<j<<endl);
00183   int v=0; 
00184   POL P;
00185   
00186   if(z =='T')
00187     for(i=0, fi=f.begin(); i <= n; i++, fi++){
00188       for (typename POL::reverse_iterator j=E[i].rbegin();j!=E[i].rend();j++){
00189         P = (*fi)*(*j);
00190         for (typename POL::const_iterator k = P.begin(); k!=P.end(); k++){
00191           matrixof::assigncoeff(Res,v,index[*k],k->coeff());
00192         }
00193         v++;
00194       }
00195     }
00196   else
00197     for(i=0, fi=f.begin(); i <= n; i++, fi++){
00198       for (typename POL::reverse_iterator j=E[i].rbegin();j!=E[i].rend();j++){
00199         P = (*fi)*(*j);
00200         for (typename POL::const_iterator k = P.begin(); k!=P.end(); k++){
00201           //cout <<"I    "<<*k<<" "<<index[*k]<<endl;
00202           matrixof::assigncoeff(Res,index[*k],v,k->coeff());
00203         }
00204         v++;
00205       }
00206     } 
00207   return Res;
00208 };
00209 
00210 //----------------------------------------------------------------------
00222 template<class R, class L>
00223 R macaulay(const L & f, unsigned int nu, unsigned int nv, char z='T'){
00224 
00225   typedef typename L::value_type POL;
00226   typedef typename POL::monom_t MON;
00227   typedef typename POL::order_t O;
00228 
00229   int n=f.size()-1;
00230 
00231   // Construction des bases locales 
00232   POL* E= new POL[n+1];
00233   int c=0,taille=0;
00234   for (typename L::const_iterator j = f.begin(); j !=f.end(); ++j) 
00235     {
00236       Choose(nu- Degree(*j),nv,E[c]);
00237       taille+=E[c].size();c++;
00238     }
00239   //XXX A Ameliorer     
00240 
00241   //Index des monomes
00242   std::map<MON,int,O> index;
00243   POL S;  Choose(nu,nv,S);
00244   
00245   int nbrow =0;
00246   for (typename POL::reverse_iterator j = S.rbegin(); j!=S.rend(); j++)
00247     {
00248       index[*j]=nbrow; nbrow++;
00249     }
00250   
00251   
00252   //Construction de la matrice de Macaulay
00253   R Res;
00254   matrixof::reserve(Res,taille,nbrow,0);
00255   // if(!Res) Error(cout<<"Not enough memory for a matrix"<<i<<"*"<<j<<endl);
00256   int v=0;
00257   POL P;typename L::const_iterator fi=f.begin();
00258   for(int i=0; i <= n; i++,fi++) {
00259     for (typename POL::reverse_iterator j = E[i].rbegin(); j!=E[i].rend();j++)
00260       {
00261         P = (*fi)*(*j);
00262         for (typename POL::const_iterator k = P.begin(); k!=P.end(); k++)
00263           matrixof::assigncoeff(Res,v, index[*k],k->GetCoeff());
00264         v++;
00265       }
00266   }
00267   return Res;
00268 };
00269 //----------------------------------------------------------------------------
00270 #ifdef Sparse
00271 struct compcol_mat_double;
00272 // Sylvester-like matrix under the specialized form @MatSps<compcol_mat_double> >@
00273 template <class POL>
00274 MatRef<compcol_mat_double>
00275 macaulay(const VectStd<array1d<POL> > & f, compcol_mat_double S) {
00276 
00277   typedef typename POL::monom_t MON;
00278   compcol_mat_double *Res;
00279   int nz=0;
00280   typedef typename compcol_mat_double::coeff_t C;
00281   C zero = C(0);
00282 
00283   int d[f.size()], n = (f.size()-1), nu = 0;
00284   POL F;
00285 
00286   // Calcul de mu et des differents degres di
00287   for(int i=0; i<=n; i++){
00288     d[i] = MPOLY::degree(f[i]);
00289     nu += d[i];
00290    }
00291   nu -= n; 
00292 
00293   MON* xdi = new MON[n+1];
00294   POL* D = new POL[n+1];
00295 
00296   xdi[0]= MON(1.0);
00297   D[0] = POL(xdi[0]);
00298   for(int j=1; j<=n; j++){
00299     xdi[j] = MON(j,d[j]);
00300     for(int i=0;i<d[j];i++) D[j]+= MON(j,i);
00301   }
00302 
00303   // Construction de l'ensemble des monomes de degre mu
00304   int taille = SizeOfS(n,nu);
00305  
00306   // Construction des bases locales 
00307   POL* E= new POL[n+1];
00308   POL U(1.),V(1.);
00309   int mu=nu;
00310 
00311   for(int i=n;i>0;i--){
00312     mu = nu-d[i];
00313     for (typename POL::const_iterator j = U.begin(); j!=U.end(); j++){
00314       Choose(mu-j->GetDegree(),i,V);
00315       //XXX A Ameliorer
00316       E[i] += V*(*j);
00317     }
00318     U*=D[i];
00319   }
00320   E[0] = U;
00321 
00322   //Index des monomes
00323   map<MON,int> index;
00324   int c =0,nbcol=0;
00325   MON m;
00326   for(int i=0; i <=n;i++){
00327     for (typename POL::const_iterator j = E[i].begin(); j!=E[i].end(); j++){
00328       m = (*j)*xdi[i];
00329       index[m]=c;
00330       c++;nbcol++;
00331     }
00332     nz+=NbCoef(f[i])*(nbcol); // Calcul du nombre de non-zero
00333     nbcol=0;
00334   }
00335 
00336   int * col = new int[taille+1];
00337   int * r = new int[nz];
00338   C * val = new C[nz];
00339   col[0] = 0;
00340 
00341   int u,t=0,l=0, v=0;
00342   POL P;
00343   for(int i=0; i <= n; i++){
00344     for (typename POL::const_iterator j = E[i].begin(); j!=E[i].end(); j++){
00345       P = f[i]*(*j);
00346       for (typename POL::const_iterator k = P.begin(); k!=P.end(); k++) {
00347         if (k->GetCoeff()!=zero) {
00348           val[t]=k->GetCoeff(); 
00349           r[t]=index[*k];
00350           if ((t!=0) && (l!=v)) {
00351             l++;
00352             col[l] = t;}
00353           t++;  
00354         }
00355       }
00356       v++;
00357     }
00358   }
00359   col[taille] = nz;
00360 
00361   Res = new compcol_mat_double(taille, taille, nz, val, r, col, 0);
00362 
00363   return MatRef<compcol_mat_double>(Res);
00364 }
00365 
00366 //--------------------------------------------------------------------------
00367 // Transposed Sylvester-like matrix under the specialized form @MatSps<compcol_mat_double> >@
00368 template <class POL>
00369 MatRef<compcol_mat_double>
00370 macaulay_T(const VectStd<array1d<POL> > & f, compcol_mat_double S) {
00371   typedef typename POL::monom_t MON;
00372   compcol_mat_double *Res;
00373   int nz=0;
00374   typedef typename compcol_mat_double::coeff_t C;
00375   C zero = C(0);
00376 
00377   int d[f.size()], n = (f.size()-1), nu = 0;
00378   POL F;
00379 
00380   // Calcul de mu et des differents degres di
00381   for(int i=0; i<=n; i++){
00382     d[i] = MPOLY::degree(f[i]);
00383     nu += d[i];
00384    }
00385   nu -= n; 
00386 
00387   MON* xdi = new MON[n+1];
00388   POL* D = new POL[n+1];
00389 
00390   xdi[0]= MON(1.0);
00391   D[0] = POL(xdi[0]);
00392   for(int j=1; j<=n; j++){
00393     xdi[j] = MON(j,d[j]);
00394     for(int i=0;i<d[j];i++) D[j]+= MON(j,i);
00395   }
00396 
00397   // Construction de l'ensemble des monomes de degre mu
00398   // 
00399   int taille = SizeOfS(n,nu);
00400 
00401 
00402   // Construction des bases locales 
00403   POL* E= new POL[n+1];
00404   POL U(1.),V(1.);
00405   int mu=nu;
00406 
00407   for(int i=n;i>0;i--){
00408     mu = nu-d[i];
00409     for (typename POL::const_iterator j = U.begin(); j!=U.end(); j++){
00410       Choose(mu-j->GetDegree(),i,V);
00411       //XXX A Ameliorer
00412       E[i] += V*(*j);
00413     }
00414     U*=D[i];
00415 
00416   }
00417   E[0] = U;
00418 
00419   //Index des monomes
00420   map<MON,int> index;
00421   int c =0,nbcol=0;
00422   MON m;
00423   for(int i=0; i <=n;i++){
00424     for (typename POL::const_iterator j = E[i].begin(); j!=E[i].end(); j++){
00425       m = (*j)*xdi[i];
00426       index[m]=c;
00427       c++;nbcol++;
00428     }
00429     nz+=NbCoef(f[i])*(nbcol); // Calcul du nombre de non-zero
00430     nbcol=0;
00431   }
00432 
00433   int * col = new int[taille+1];
00434   int * r = new int[nz];
00435   C * val = new C[nz];
00436   col[0] = 0;
00437 
00438   int t=0,l=0, v=0;
00439   POL P;
00440   for(int i=0; i <= n; i++){
00441     for (typename POL::const_iterator j = E[i].begin(); j!=E[i].end(); j++){
00442       P = f[i]*(*j);
00443       for (typename POL::const_iterator k = P.begin(); k!=P.end(); k++) {
00444         if (k->GetCoeff()!=zero) {
00445           val[t]=k->GetCoeff(); 
00446           r[t]=index[*k];
00447           if ((t!=0) && (l!=v)) {
00448             l++;
00449             col[l] = t;}
00450           t++;  
00451         }
00452       }
00453       v++;
00454     }
00455   }
00456 
00457   col[taille] = nz;
00458 
00459   Res = new compcol_mat_double(taille, taille, nz, val, r, col);
00460   MatSps<compcol_mat_double>::transpose(*Res);
00461 
00462   return MatRef<compcol_mat_double>(Res);
00463 }
00464 
00465 // Sylvester-like matrix under the specialized form @MatSps<umfpack<C> >@
00466 template <class POL, class C>
00467 MatRef<umfpack<C> >
00468 macaulay(const VectStd<array1d<POL> > & f, umfpack<C> S, char tt='N') {
00469   typedef typename POL::monom_t MON;
00470   typedef double C;
00471   umfpack<C> *Res;
00472   int nz=0;
00473   C zero = C(0);
00474   int d[f.size()], n = (f.size()-1), nu = 0;
00475   POL F;
00476 
00477   // Calcul de mu et des differents degres di
00478   for(int i=0; i<=n; i++){
00479     d[i] = MPOLY::degree(f[i]);
00480     nu += d[i];
00481    }
00482   nu -= n; 
00483 
00484   MON* xdi = new MON[n+1];
00485   POL* D = new POL[n+1];
00486 
00487   xdi[0]= MON(C(1.0));
00488   D[0] = POL(xdi[0]);
00489   for(int j=1; j<=n; j++){
00490     xdi[j] = MON(j,d[j]);
00491     for(int i=0;i<d[j];i++) D[j]+= MON(j,i);
00492   }
00493 
00494   // Construction de l'ensemble des monomes de degre mu
00495   int taille = SizeOfS(n,nu);
00496 
00497   // Construction des bases locales 
00498   POL* E= new POL[n+1];
00499   POL U(C(1.)),V(C(1.));
00500   int mu=nu;
00501 
00502   for(int i=n;i>0;i--){
00503     mu = nu-d[i];
00504     for (typename POL::const_iterator j = U.begin(); j!=U.end(); j++){
00505       Choose(mu-j->GetDegree(),i,V);
00506       //XXX A Ameliorer
00507       E[i] += V*(*j);
00508     }
00509     U*=D[i];
00510   }
00511   E[0] = U;
00512 
00513   //Index des monomes
00514   map<MON,int> index;
00515   int c =0,nbcol=0;
00516   MON m;
00517   for(int i=0; i <=n;i++){
00518     for (typename POL::const_iterator j = E[i].begin(); j!=E[i].end(); j++){
00519       m = (*j)*xdi[i];
00520       index[m]=c;
00521       c++;nbcol++;
00522     }
00523     nz+=NbCoef(f[i])*(nbcol); // Calcul du nombre de non-zero
00524     nbcol=0;
00525   }
00526 
00527   Res = new umfpack<C>(taille, taille, nz);
00528   int t=0,v=0;
00529   POL P;
00530   if(tt =='N')
00531     for(int i=0; i <= n; i++){
00532       for (typename POL::const_iterator j = E[i].begin(); j!=E[i].end(); j++){
00533         P = f[i]*(*j);
00534         for (typename POL::const_iterator k = P.begin(); k!=P.end(); k++) {
00535           if (k->GetCoeff()!=zero) {
00536             Res->tab_[t]=k->GetCoeff(); 
00537             Res->index_[t]=index[*k];
00538             Res->index_[t+nz] = v;
00539             t++;
00540           }
00541         }
00542         v++;
00543       }
00544     }
00545  else
00546    for(int i=0; i <= n; i++){
00547      for (typename POL::const_iterator j = E[i].begin(); j!=E[i].end(); j++){
00548        P = f[i]*(*j);
00549        for (typename POL::const_iterator k = P.begin(); k!=P.end(); k++) {
00550          if (k->GetCoeff()!=zero) {
00551            Res->tab_[t]=k->GetCoeff(); 
00552            Res->index_[t]=v;
00553            Res->index_[t+nz] = index[*k];
00554            t++;
00555          }
00556        }
00557        v++;
00558      }
00559    }
00560 
00561   return MatRef<umfpack<C> >(Res);
00562 }
00563 template <class POL, class C>
00564 MatRef<umfpack<C> >
00565 macaulay_T(const VectStd<array1d<POL> > & f, umfpack<C> S) {
00566   return macaulay(f, umfpack<C>(), 'Y');
00567 }
00568 
00569 #endif //Sparse
00570 //-------------------------------------------------------------------------
00571 
00572 __END_NAMESPACE_SYNAPS
00573 
00574 #endif // SYNAPS_RESULTANT_MACAULAY_H

SYNAPS DOCUMENTATION
logo