00001 #include "derive.H"
00002 using namespace std;
00003
00004
00005 void DerivationAnalyzer::setup(GradedAlgebra<F_2> *thesource){
00006 long i, n;
00007 list< Polynomial<F_2> > pols, total;
00008 list< Polynomial<F_2> >::iterator it;
00009
00010 source= thesource;
00011
00012 n= 1;
00013
00014
00015 for(i=1; i<= source->variables_in_use(); i++){
00016 write_gens( pols, i, 1, source->variables_in_use() );
00017 for(it= pols.begin(); it!= pols.end(); it++, n++)
00018 index_of[ it->lp() ]= n;
00019 total.splice( total.end(), pols);
00020 }
00021
00022 mod_gens.resize(n);
00023 mod_gens[0]= source->one();
00024 for(i= 1, it= total.begin(); i< n; i++, it++)
00025 mod_gens[i]= *it;
00026
00027 d.resize(n);
00028 d[0].resize(n);
00029 d[0].set_alphabet( source );
00030 d[0].sets_to_zero();
00031
00032 cout << "generators: " << mod_gens << endl;
00033
00034
00035 Tuple< Polynomial<F_2> > x= source->get_variables();
00036 sq_inclusion.source= &squares;
00037 sq_inclusion.target= source;
00038 cs_inclusion.source= &constants;
00039 cs_inclusion.target= source;
00040 for(i=1; i<= source->variables_in_use(); i++){
00041 squares.new_variable("s" + source->nameof(i),
00042 2*source->hom_degrees[i] );
00043 constants.new_variable("s" + source->nameof(i),
00044 2*source->hom_degrees[i] );
00045 sq_inclusion.set_image(i, x[i]*x[i] );
00046 cs_inclusion.set_image(i, x[i]*x[i] );
00047 }
00048
00049 cs_inclusion.populate_associated_algebra();
00050
00051
00052
00053
00054 }
00055
00056 void DerivationAnalyzer::write_gens(list< Polynomial<F_2> >& result,
00057 long ext, long first, long last) {
00058 list< Polynomial<F_2> > temp1, temp2;
00059 list< Polynomial<F_2> >::iterator it;
00060
00061
00062
00063 if( (ext < 1) ){
00064 result.clear();
00065 result.push_front( source->one() );
00066 return;
00067 }
00068
00069 if( (ext > last - first + 1) ){
00070 result.clear();
00071 return;
00072 }
00073
00074
00075
00076 write_gens(result, ext, first + 1, last);
00077 write_gens(temp2, ext - 1, first + 1, last);
00078
00079
00080 for(it= temp2.begin(); it != temp2.end(); it++)
00081 result.push_back( *it * Polynomial<F_2>(PowProd( first )) );
00082 return;
00083
00084 }
00085
00086 multiPolynomial<F_2> DerivationAnalyzer::coords_of(PowProd P)
00087
00088 {
00089 PowProd tail(0);
00090 PowProd half;
00091 long i;
00092 multiPolynomial<F_2> ans;
00093 Polynomial<F_2> poly;
00094
00095 for(i= 1; i<= P.nvars(); i++)
00096 if( P.power_of(i) % 2 != 0 )
00097 tail*= PowProd(i);
00098
00099 P /= tail;
00100 half.powers.resize( P.powers.size() );
00101 for(i=0; i< P.powers.size(); i++)
00102 half.powers[i]= P.powers[i] / 2;
00103
00104
00105
00106
00107 ans.resize( mod_gens.size() );
00108 ans.set_alphabet( &squares );
00109 poly= Polynomial<F_2>( half );
00110 poly.alphabet= &squares;
00111 ans[ index_of[tail] ]= poly;
00112 return ans;
00113 }
00114
00115 multiPolynomial<F_2> DerivationAnalyzer::coords_of(const Polynomial<F_2>& P) {
00116 map< PowProd, F_2 >::const_iterator it;
00117 multiPolynomial<F_2> ans;
00118
00119 ans.resize( mod_gens.size() );
00120 ans.set_alphabet( &squares );
00121
00122 for(it= P.coeffs.begin();
00123 it != P.coeffs.end();
00124 it++)
00125 ans+= this->coords_of( it->first );
00126
00127 return ans;
00128 }
00129
00130 void DerivationAnalyzer::constant_subalgebra(string prefix,
00131 long offset){
00132 multiIdeal<F_2> module;
00133 long i, j;
00134 Matrix< Polynomial<F_2> > M, T;
00135 Polynomial<F_2> P, Q, replacement;
00136 list< Polynomial<F_2> >::iterator it;
00137 list< Polynomial<F_2> > solutions;
00138 list< Polynomial<F_2> > homo_solutions;
00139 ostringstream autoname;
00140
00141
00142 for(i=1; i< d.size(); i++) {
00143 module.generators.push_back( d[i] );
00144
00145
00146
00147
00148
00149 if( d[i].is_zero() ) {
00150 solutions.push_back( mod_gens[i] );
00151 }
00152
00153
00154
00155 }
00156
00157
00158 for(it= source->relations.generators.begin();
00159 it != source->relations.generators.end();
00160 it++)
00161 for(i= 0; i< mod_gens.size(); i++){
00162 module.generators.push_back( this->coords_of(mod_gens[i]*(*it) ) );
00163 }
00164
00165 cout << "computing the kernel of the derivation..." << endl;
00166
00167
00168
00169
00170 module.grobnerize_with_coefficients(T);
00171
00172 cout << "for information: T has "
00173 << T.nlines() << " lines " << endl;
00174
00175 module.syzygy(M);
00176 cout << "performing large matrix multiplication... ("
00177 << M.nlines() << " lines)" << endl;
00178 M*= T;
00179
00180 M.resize( M.nlines(), mod_gens.size()-1 );
00181
00182
00183
00184 cout << "finding a minimal presentation" << endl;
00185
00186 Q.alphabet= source;
00187
00188
00189 cout << "nb of generators: " << M.nlines() << endl;
00190
00191 for(i=0; i< M.nlines(); i++){
00192
00193 Q.sets_to_zero();
00194 for(j=1; j < mod_gens.size(); j++)
00195 Q+= sq_inclusion.of(M(i, j-1)) * mod_gens[j];
00196
00197 Q= source->reduced_form(Q);
00198 solutions.push_back(Q);
00199 }
00200
00201
00202 i= 0;
00203
00204 while( !solutions.empty() ) {
00205 i++;
00206
00207 for(it= solutions.begin();
00208 it!= solutions.end();) {
00209 Q= source->hom_part_of( *it, i);
00210 if( !Q.is_zero() ) {
00211 homo_solutions.push_back( Q );
00212 *it += Q;
00213
00214 }
00215 if( it->is_zero() )
00216 it= solutions.erase( it );
00217 else
00218 it++;
00219 }
00220
00221 }
00222
00223 i= 0;
00224
00225 for( it= homo_solutions.begin();
00226 it != homo_solutions.end();
00227 it++) {
00228
00229 if( !cs_inclusion.maps_onto(*it) ){
00230
00231 cout << "adding " << *it << endl;
00232
00233
00234 autoname.str("");
00235 i++;
00236 autoname << prefix << "_" << offset + i;
00237 constants.new_variable( autoname.str(),
00238 source->hom_degree_of(*it) );
00239 cs_inclusion.set_image( constants.variables_in_use(), *it);
00240 cs_inclusion.populate_associated_algebra();
00241 }
00242
00243 }
00244
00245 constants.relations= cs_inclusion.kernel;
00246
00247
00248
00249
00250 }
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276 void MilnorAnalyzer::start(UnstableAlgebra *theA) {
00277 long i, k;
00278 Polynomial<F_2> P, R;
00279 char letter= 'a';
00280 ostringstream autoname;
00281 Tuple< Polynomial<F_2> > x;
00282
00283 A= theA;
00284
00285
00286
00287
00288 cout << "dealing with Sq^1" << endl;
00289 k= 0;
00290
00291
00292
00293 setup_for_Sq1();
00294
00295 autoname << letter;
00296 constant_subalgebra(autoname.str(), 0);
00297
00298
00299 inclusion *= cs_inclusion;
00300 inclusion.populate_associated_algebra();
00301
00302
00303
00304 while( !done() ) {
00305 k++;
00306 letter++;
00307 cout << endl
00308 << "dealing with Q_" << k << "..." << endl;
00309
00310
00311
00312
00313 re_setup(k);
00314
00315 autoname.str("");
00316 autoname << letter;
00317 constant_subalgebra(autoname.str(), 0);
00318 inclusion *= cs_inclusion;
00319 inclusion.populate_associated_algebra();
00320 }
00321
00322 cout << "wooooot !! done !!" << endl;
00323
00324 }
00325
00326
00327 void MilnorAnalyzer::setup_for_Sq1(){
00328 long i, n;
00329 list< Polynomial<F_2> > pols, total;
00330 list< Polynomial<F_2> >::iterator it;
00331 Tuple< Polynomial<F_2> > x;
00332 Polynomial<F_2> P, R;
00333
00334
00335
00336
00337 x= A->get_variables();
00338 inclusion.source= &alg;
00339 inclusion.target= A;
00340 for(i=1; i<= A->variables_in_use(); i++) {
00341 alg.new_variable(A->nameof(i),
00342 A->hom_degrees[i]);
00343 inclusion.set_image(i, x[i]);
00344 }
00345 alg.relations= A->relations;
00346 alg.fix_alphabets();
00347
00348
00349
00350
00351 source= &alg;
00352
00353
00354
00355
00356 n_cs_vars= 0;
00357 for(i=1; i<= source->variables_in_use(); i++) {
00358 P= A->Sq(1, x[i]);
00359 if( A->reduced_form(P).is_zero() ) {
00360 n_cs_vars++;
00361 alg.swap_variables_order(i, n_cs_vars);
00362 inclusion.swap(i, n_cs_vars);
00363 }
00364 }
00365 inclusion.populate_associated_algebra();
00366
00367
00368
00369
00370 x= source->get_variables();
00371 sq_inclusion.source= &squares;
00372 sq_inclusion.target= source;
00373 cs_inclusion.source= &constants;
00374 cs_inclusion.target= source;
00375 for(i=1; i<= n_cs_vars; i++) {
00376 squares.new_variable(source->nameof(i),
00377 source->hom_degrees[i] );
00378 constants.new_variable(source->nameof(i),
00379 source->hom_degrees[i] );
00380 sq_inclusion.set_image(i, x[i] );
00381 cs_inclusion.set_image(i, x[i] );
00382
00383 }
00384 for(i= n_cs_vars+1; i<=source->variables_in_use(); i++){
00385 squares.new_variable("s" + source->nameof(i),
00386 2*source->hom_degrees[i] );
00387 constants.new_variable("s" + source->nameof(i),
00388 2*source->hom_degrees[i] );
00389 sq_inclusion.set_image(i, x[i]*x[i] );
00390 cs_inclusion.set_image(i, x[i]*x[i] );
00391 }
00392
00393
00394 cs_inclusion.populate_associated_algebra();
00395
00396
00397
00398
00399
00400
00401
00402 newvar_squared.clear();
00403 x= squares.get_variables();
00404 for(i= n_cs_vars+1; i<= squares.variables_in_use(); i++)
00405 newvar_squared.set_image(i, x[i]);
00406
00407
00408 n= 1;
00409 for(i=1;
00410 i<= source->variables_in_use() - n_cs_vars;
00411 i++){
00412 write_gens( pols, i, n_cs_vars+1,
00413 source->variables_in_use() );
00414 for(it= pols.begin(); it!= pols.end(); it++, n++)
00415 index_of[ it->lp() ]= n;
00416 total.splice( total.end(), pols);
00417 }
00418
00419 mod_gens.resize(n);
00420 mod_gens[0]= source->one();
00421 for(i= 1, it= total.begin(); i< n; i++, it++)
00422 mod_gens[i]= *it;
00423 cout << "initial generators: " << mod_gens << endl;
00424
00425 d.resize(n);
00426 d[0].resize(n);
00427 d[0].set_alphabet( source );
00428 d[0].sets_to_zero();
00429 for(i=1; i< mod_gens.size(); i++) {
00430 P= A->Sq(1, inclusion.of(mod_gens[i]));
00431 inclusion.maps_onto(P, R);
00432
00433
00434
00435 d[i]= this->coords_of(R);
00436 }
00437
00438
00439
00440 }
00441
00442
00443
00444 void MilnorAnalyzer::re_setup(long k) {
00445 long i;
00446 Tuple< Polynomial<F_2> > x;
00447 Polynomial<F_2> P, R;
00448 GradedAlgebra<F_2> empty;
00449
00450
00451
00452
00453
00454 n_cs_vars= 0;
00455
00456 for(i= n_cs_vars + 1;
00457 i <= constants.variables_in_use(); i++){
00458 P= A->Q(k, inclusion.of_generator(i) );
00459 if( A->reduced_form(P).is_zero() ) {
00460
00461
00462
00463 n_cs_vars++;
00464 constants.swap_variables_order(i, n_cs_vars);
00465 cs_inclusion.swap(i, n_cs_vars);
00466 inclusion.swap(i, n_cs_vars);
00467 }
00468 }
00469
00470
00471
00472 cs_inclusion.populate_associated_algebra();
00473 inclusion.populate_associated_algebra();
00474
00475
00476 squares= empty;
00477 for(i= 1; i <= n_cs_vars; i++)
00478 squares.new_variable( constants.nameof(i),
00479 constants.hom_degrees[i] );
00480 cout << "n_cs_vars= " << n_cs_vars << endl;
00481 cout << "new algebra of squares: "
00482 << squares << endl;
00483
00484
00485 newvar_squared.clear();
00486 x= constants.get_variables();
00487
00488 for(i= squares.variables_in_use() + 1;
00489 i <= constants.variables_in_use();
00490 i++) {
00491
00492 P= cs_inclusion.of( x[i]*x[i] );
00493 cs_inclusion.maps_onto(P, R);
00494
00495
00496
00497
00498 R.alphabet= &squares;
00499 newvar_squared.set_image(i, R);
00500 }
00501
00502 alg= constants;
00503 alg.fix_alphabets();
00504 source= &alg;
00505
00506
00507 inclusion.source= source;
00508
00509
00510 sq_inclusion.target= source;
00511 sq_inclusion.clear();
00512 x= source->get_variables();
00513
00514 for(i=1; i<= squares.variables_in_use(); i++)
00515 sq_inclusion.set_image(i, x[i]);
00516
00517
00518 constants= squares;
00519 constants.fix_alphabets();
00520 cs_inclusion= sq_inclusion;
00521 cs_inclusion.source= &constants;
00522 cs_inclusion.fix_alphabets();
00523 cs_inclusion.populate_associated_algebra();
00524
00525
00526 index_of.clear();
00527 mod_gens.resize(0);
00528
00529 long n;
00530 list< Polynomial<F_2> > pols, total;
00531 list< Polynomial<F_2> >::iterator it;
00532
00533 n= 1;
00534
00535
00536 for(i=1;
00537 i<= source->variables_in_use() - n_cs_vars;
00538 i++){
00539 write_gens( pols, i, n_cs_vars + 1, source->variables_in_use() );
00540 for(it= pols.begin(); it!= pols.end(); it++, n++)
00541 index_of[ it->lp() ]= n;
00542 total.splice( total.end(), pols);
00543 }
00544
00545 mod_gens.resize(n);
00546 mod_gens[0]= source->one();
00547 for(i= 1, it= total.begin(); i< n; i++, it++)
00548 mod_gens[i]= *it;
00549
00550 cout << "generators: " << mod_gens << endl;
00551
00552 d.resize(n);
00553 d[0].resize(n);
00554 d[0].set_alphabet( source );
00555 d[0].sets_to_zero();
00556 for(i=1; i< mod_gens.size(); i++) {
00557 P= A->Q(k, inclusion.of( mod_gens[i] ));
00558 inclusion.maps_onto(P, R);
00559 d[i]= this->coords_of(R);
00560 }
00561
00562 }
00563
00564
00565
00566 multiPolynomial<F_2> MilnorAnalyzer::coords_of(PowProd P) {
00567 PowProd tail(0);
00568 PowProd half, begin;
00569 long i;
00570 multiPolynomial<F_2> ans;
00571 Polynomial<F_2> poly;
00572
00573
00574 begin= P;
00575
00576 if( P.nvars() > n_cs_vars ) {
00577
00578 for(i= n_cs_vars - 1; i >= 0; i--)
00579 if( begin.powers[i] != 0 )
00580 break;
00581 begin.powers.resize(i+1);
00582
00583 }
00584
00585
00586 P/= begin;
00587
00588
00589
00590 for(i= 1; i<= P.nvars(); i++)
00591 if( P.power_of(i) % 2 != 0 )
00592 tail*= PowProd(i);
00593
00594
00595 P /= tail;
00596
00597 half.powers.resize( P.powers.size() );
00598 for(i=0; i< P.powers.size(); i++)
00599 half.powers[i]= P.powers[i] / 2;
00600
00601 poly= newvar_squared.of( Polynomial<F_2>(half) );
00602 poly*= Polynomial<F_2>( begin );
00603
00604
00605
00606
00607 ans.resize( mod_gens.size() );
00608 ans.set_alphabet( &squares );
00609
00610 poly.alphabet= &squares;
00611 ans[ index_of[tail] ]= poly;
00612 return ans;
00613 }
00614
00615 multiPolynomial<F_2> MilnorAnalyzer::coords_of(const Polynomial<F_2>& P) {
00616
00617 return DerivationAnalyzer::coords_of(P);
00618 }
00619
00620 bool MilnorAnalyzer::done() {
00621
00622 constants.even_subalgebra(ans, ans_inclusion);
00623 ans_inclusion= inclusion * ans_inclusion;
00624 ans_inclusion.populate_associated_algebra();
00625
00626 if( A->has_closure_of( ans_inclusion ) ) {
00627 ans.relations= ans_inclusion.kernel;
00628 return true;
00629 }
00630 else
00631 return false;
00632 }
00633