00001 #ifndef _MULTIGROBNER_H_
00002 #define _MULTIGROBNER_H_
00003
00004 #include "multipoly.H"
00005 #include "matrix.H"
00006 #include <list>
00007 #include <stack>
00008 #include <utility>
00009
00011
00017 template <class K>
00018 multiPolynomial<K> division_remainder_with_coefficients(const multiPolynomial<K>& f,
00019 const list< multiPolynomial<K> >& F,
00020 Matrix< Polynomial<K> >& U){
00021 multiPolynomial<K> h,r;
00022 Polynomial<K> temp;
00023 K c;
00024 multiPolynomial<K> a,b;
00025 typename list< multiPolynomial<K> >::const_iterator it;
00026 long i;
00027
00028
00029 h= f;
00030 r= f;
00031 r.sets_to_zero();
00032
00033 for(it= F.begin(), i=0; it != F.end(); it++, i++);
00034 U.resize(1,i);
00035 for(i=0; i< U.size(); i++){
00036 U[i].sets_to_zero();
00037 U[i].alphabet= (Alphabet *) f[0].alphabet;
00038 }
00039
00040 temp.alphabet= (Alphabet *) f[0].alphabet;
00041
00042 while( !h.is_zero() ){
00043
00044 a=h.lm();
00045 for(it= F.begin(), i=0; it != F.end(); it++, i++){
00046 b= it->lm();
00047 if(b.divides(a))
00048 break;
00049 }
00050 if(it != F.end()){
00051
00052 c= h.coeff_of(a);
00053 c/= it->coeff_of(b);
00054 temp= a / b;
00055 temp*= c;
00056
00057
00058 U[i] += temp;
00059 h += (*it) * temp * (-1);
00060 }
00061 else{
00062 r += a * h.coeff_of(a);
00063 h += a * h.coeff_of(a)*(-1);
00064 }
00065
00066 }
00067
00068
00069
00070 return r;
00071 }
00072
00073 template <class K>
00074 multiPolynomial<K> division_remainder(const multiPolynomial<K>& f,
00075 const list< multiPolynomial<K> >& F){
00076 multiPolynomial<K> h,r;
00077 Polynomial<K> temp;
00078 K c;
00079 multiPolynomial<K> a,b;
00080 typename list< multiPolynomial<K> >::const_iterator it;
00081 long i;
00082
00083
00084 h= f;
00085 r= f;
00086 r.sets_to_zero();
00087 temp.alphabet= (Alphabet *) f[0].alphabet;
00088
00089 while( !h.is_zero() ){
00090
00091 a=h.lm();
00092 for(it= F.begin(), i=0; it != F.end(); it++, i++){
00093 b= it->lm();
00094 if(b.divides(a))
00095 break;
00096 }
00097 if(it != F.end()){
00098
00099 c= h.coeff_of(a);
00100 c/= it->coeff_of(b);
00101 temp= a / b;
00102 temp*= c;
00103
00104
00105 h += (*it) * temp * (-1);
00106 }
00107 else{
00108 r += a * h.coeff_of(a);
00109 h += a * h.coeff_of(a)*(-1);
00110 }
00111
00112 }
00113
00114 return r;
00115 }
00116
00117
00118
00120
00127 template <class K>
00128 class multiIdeal {
00129 private:
00131
00140 list< Matrix< Polynomial<K> > > coeffs;
00141
00142 void insert(const multiPolynomial<K>& mP,
00143 const Matrix< Polynomial<K> >&coords){
00144 long i;
00145 typename list< Matrix< Polynomial<K> > >::iterator it;
00146 Matrix< Polynomial<K> > M, temp;
00147
00148
00149
00150
00151 M= (*coeffs.begin()) * coords[0];
00152
00153 for(it= coeffs.begin(), it++, i=1; i< coords.size(); it++, i++){
00154 M += *it * coords[i];
00155 }
00156
00157 coeffs.push_back(M);
00158 generators.push_back(mP);
00159 }
00160
00162 long simplify(){
00163 long n= coeffs.begin()->ncols();
00164 typename list< multiPolynomial<K> >::iterator it, itprime, gen_begin;
00165 typename list< Matrix< Polynomial<K> > >::iterator itcoeff, c_begin;
00166 long ans= 0;
00167
00168 gen_begin= generators.begin();
00169 c_begin= coeffs.begin();
00170 while(n > 0){
00171 gen_begin++;
00172 c_begin++;
00173 n--;
00174 }
00175
00176
00177
00178
00179 for(it= gen_begin, itcoeff= c_begin;
00180 it!= generators.end();){
00181
00182 for(itprime= generators.begin();
00183 itprime!= generators.end();
00184 itprime++)
00185 if( (itprime != it) && itprime->lm().divides( it->lm() ) )
00186 break;
00187
00188 if( itprime != generators.end() ){
00189 it= generators.erase( it );
00190 itcoeff= coeffs.erase( itcoeff );
00191 ans++;
00192 }
00193 else{
00194 it++;
00195 itcoeff++;
00196 }
00197 }
00198 return ans;
00199 }
00200
00201
00202
00203
00204 public:
00206 list< multiPolynomial<K> > generators;
00207
00208
00209
00210
00211
00213
00224 void grobnerize_with_coefficients(Matrix< Polynomial<K> >& M){
00225 list< pair< multiPolynomial<K>*, multiPolynomial<K>* > > couples;
00226 pair< multiPolynomial<K>*, multiPolynomial<K>* > fg;
00227 pair< Polynomial<K>, Polynomial<K> > S_coeffs;
00228 multiPolynomial<K> Spoly, h;
00229 Polynomial<K> I;
00230 typename list< multiPolynomial<K> >::iterator it, itprime;
00231 Matrix< Polynomial<K> > U, tuple;
00232
00233
00234 long i, j, n, m;
00235 long S_count= 0;
00236
00237
00238
00239 if(generators.begin() == generators.end())
00240 return;
00241
00242 I= Polynomial<K>( PowProd(0) );
00243 I.alphabet= generators.begin()->coords[0].alphabet;
00244
00245
00246
00247
00248 n= 0;
00249 tuple.resize(1, generators.size() );
00250 for(i=0; i< (long) generators.size(); i++){
00251 tuple[i].sets_to_zero();
00252 tuple[i].alphabet= I.alphabet;
00253 }
00254 for(it= generators.begin(); it!= generators.end(); it++){
00255 tuple[n]= I;
00256 if(n>0)
00257 tuple[n-1].sets_to_zero();
00258 n++;
00259 coeffs.push_back( tuple );
00260 }
00261
00262 m= 0;
00263
00264
00265
00266 for(it= generators.begin(); it !=generators.end(); it++)
00267 for(itprime= it, itprime++; itprime != generators.end(); itprime++)
00268 couples.push_back( make_pair( &(*it) , &(*itprime) ) );
00269
00270
00271 while( !couples.empty() ){
00272 S_count++;
00273
00274
00275
00276
00277
00278
00279
00280
00281 if(S_count % 2 == 0){
00282 fg= couples.front();
00283 couples.pop_front();
00284 }
00285 else{
00286 fg= couples.back();
00287 couples.pop_back();
00288 }
00289
00290
00291 Spoly= S_polynomial_with_coefficients( *fg.first , *fg.second, S_coeffs );
00292
00293
00294
00295 if( S_count % 1000 == 0 )
00296 cout << S_count << " S polynomials computed, "
00297 << 100*(S_count)*2/((n+m)*(n+m))
00298 << "% done" << endl;
00299
00300 h= division_remainder_with_coefficients(Spoly, generators, U);
00301
00302
00303 U*= I*(-1);
00304
00305
00306 if( !h.is_zero() ){
00307
00308
00309
00310 for(i=0, it=generators.begin(); it!= generators.end(); i++, it++)
00311 if( &(*it) == fg.first )
00312 break;
00313 for(j=0, it=generators.begin(); it!= generators.end(); j++, it++)
00314 if( &(*it) == fg.second )
00315 break;
00316 U[i]+= S_coeffs.first;
00317 U[j]+= S_coeffs.second;
00318
00319
00320 insert(h, U);
00321
00322 m++;
00323
00324
00325 itprime= generators.end();
00326 itprime--;
00327 for(it= generators.begin(); it != itprime; it++)
00328 couples.push_back( make_pair( &(*it), &(*itprime) ) ) ;
00329
00330 }
00331
00332 }
00333
00334 cout << m << " polynomials added" << endl;
00335
00336 cout << simplify() << " removed" << endl;
00337
00338 M.get_data_from_matrix_list(coeffs);
00339 coeffs.clear();
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360 }
00361
00363
00376 void syzygy(Matrix< Polynomial<K> >& M) const {
00377 typename list< multiPolynomial<K> >::const_iterator it, itprime;
00378 list< Matrix< Polynomial<K> > > answer;
00379 Matrix< Polynomial<K> > tuple;
00380 pair< Polynomial<K>, Polynomial<K> > S_coeffs;
00381 multiPolynomial<K> S;
00382 long i, j;
00383
00384 for(it= generators.begin(), i=0; it!=generators.end(); it++, i++)
00385 for(itprime= it, itprime++, j=i+1;
00386 itprime!= generators.end();
00387 itprime++, j++){
00388 S= S_polynomial_with_coefficients(*it, *itprime, S_coeffs);
00389 division_remainder_with_coefficients(S, generators, tuple);
00390 tuple[i] += S_coeffs.first * (-1);
00391 tuple[j] += S_coeffs.second * (-1);
00392 answer.push_back(tuple);
00393 }
00394
00395 M.get_data_from_matrix_list(answer);
00396 }
00399
00400
00401
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440 };
00441
00442 #endif