00001 #ifndef ALREADY_countmon
00002 #define ALREADY_countmon
00003
00004 #include<list>
00005
00006 QQ binomial(int m,int n)
00007 {
00008 QQ res=1;
00009 if(n>m || m<0 || n<0)
00010 return 0;
00011 for(int i=m;i>m-n;i--)
00012 res*=i;
00013 for(int i=1;i<=n;i++)
00014 res/=(QQ)i;
00015 return res;
00016 }
00017
00018 template<typename mon>
00019 QQ countmon(mon * ideal, int d, int nbvar,int nbmon)
00020 {
00021 QQ res=binomial(nbvar+d-1,d), sign=1;
00022 std::list<mon> ppcm,stock;
00023 for(int i=0;i<nbmon;i++)
00024 stock.push_back(ideal[i]);
00025 for (typename std::list<mon>::iterator iterstock=stock.begin();
00026 iterstock!=stock.end();iterstock++)
00027 for(typename std::list<mon>::iterator iter2=stock.begin();
00028 iter2!=stock.end();iter2++)
00029 if (isdivisible<mon>(*iterstock,*iter2,nbvar)
00030 && !(iterstock==iter2))
00031 stock.erase(iter2--);
00032
00033 for(typename std::list<mon>::iterator iter=stock.begin()
00034 ;iter!=stock.end();iter++)
00035 res-=binomial(nbvar+d-iter->GetDegree()-1,d-iter->GetDegree());
00036
00037 for(int i=0;i<nbvar && stock.size()>1;i++)
00038 {
00039
00040 for(typename std::list<mon>::iterator iter1=stock.begin();
00041 iter1!=stock.end();iter1++)
00042 for(typename std::list<mon>::iterator iter2=(++iter1)--;
00043 iter2!=stock.end();iter2++)
00044 {
00045 ppcm.push_back(lcm(*iter1,*iter2));
00046
00047 }
00048 stock=ppcm;
00049
00050 for (typename std::list<mon>::iterator iterstock=stock.begin();
00051 iterstock!=stock.end();iterstock++)
00052 for(typename std::list<mon>::iterator iter2=stock.begin();
00053 iter2!=stock.end();iter2++)
00054 if (isdivisible<mon>(*iterstock,*iter2,nbvar)
00055 && !(iterstock==iter2))
00056 stock.erase(iter2--);
00057
00058 for(typename std::list<mon>::iterator iterstock=stock.begin();
00059 iterstock!=stock.end();iterstock++)
00060 res+=sign*binomial(nbvar+d-iterstock->GetDegree()-1
00061 ,d-iterstock->GetDegree());
00062 sign*=-1;
00063 ppcm.erase(ppcm.begin(),ppcm.end());
00064 }
00065 return res;
00066 }
00067
00068 template<typename Base>
00069 QQ Bindeg(const Base &b,int d)
00070 {
00071 QQ res=0;
00072 for(typename Base::const_iterator iter=b.begin();iter!=b.end();iter++)
00073 {
00074 int count=0;
00075 mon *tmp=(mon*)MAC_REV_MALLOC<mon>(
00076 (iter->taille1+iter->taille2)*sizeof(mon));
00077 res+=countmon(iter->refuse,d,b.nbvar(),iter->taille2);
00078
00079 for(int i=0;i<iter->taille1;i++)
00080 tmp[count++]=iter->accept[i];
00081 for(int i=0;i<iter->taille2;i++)
00082 {
00083 tmp[count++]=iter->refuse[i];
00084 }
00085 res-=countmon(tmp,d,b.nbvar(),count);
00086 MAC_REV_FREE<mon>(tmp,(iter->taille1+iter->taille2)*sizeof(mon));
00087 }
00088 if (res<0) {cout<<"merde "<<res<<endl;exit(-1);};
00089 return res;
00090 }
00091
00092 template<typename Base>
00093 int critere(const Base &b,int d)
00094 {
00095 cout<<"Binddeg "<<d<<" "<<Bindeg(b,d)<<endl;
00096 for(int i=0;i<b.nbvar();i++)
00097 {
00098 QQ tmp=0;
00099 int j;
00100 QQ sign=1;
00101 for(j=0;j<=i;j++)
00102 {
00103 tmp+=sign*binomial(i,j)*Bindeg(b,d-j);
00104 sign*=-1;
00105 }
00106 if (tmp<0) {cout<<"exitcrit"<<endl;return -1;}
00107 if (tmp==0) {cout<<"exitcrite"<<endl;return j-1;}
00108 }
00109 cout<<"exitcrit"<<endl;
00110 return -1;
00111 }
00112
00113 #endif //ALREADY_countmon