00001
00002
00003
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
00029
00030
00031
00032
00033
00034
00035
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
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
00139 }
00140
00141
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
00155 E[i] += V*(*j);
00156 }
00157 E[0]*=B[i];
00158
00159 }
00160
00161
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
00170 c++;
00171 }
00172 nz += E[i].size()*(f[i].size());
00173
00174 }
00175
00176
00177 int taille = SizeOfS(n,nu);
00178 assert(taille==c);
00179
00180 R Res;
00181 matrixof::reserve(Res,taille,taille,nz);
00182
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
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
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
00240
00241
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
00253 R Res;
00254 matrixof::reserve(Res,taille,nbrow,0);
00255
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
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
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
00304 int taille = SizeOfS(n,nu);
00305
00306
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
00316 E[i] += V*(*j);
00317 }
00318 U*=D[i];
00319 }
00320 E[0] = U;
00321
00322
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);
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
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
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
00398
00399 int taille = SizeOfS(n,nu);
00400
00401
00402
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
00412 E[i] += V*(*j);
00413 }
00414 U*=D[i];
00415
00416 }
00417 E[0] = U;
00418
00419
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);
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
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
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
00495 int taille = SizeOfS(n,nu);
00496
00497
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
00507 E[i] += V*(*j);
00508 }
00509 U*=D[i];
00510 }
00511 E[0] = U;
00512
00513
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);
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