Main Page | Class Hierarchy | Class List | File List | Class Members | File Members | Related Pages

unstable.cpp

00001 #include "unstable.H"
00002 using namespace std;
00003 
00004 
00005 void UnstableAlgebra::swap_variables_order(long i, 
00006                                            long j, 
00007                                            list< Polynomial<F_2> >& polys){
00008   Tuple< Polynomial<F_2> > dummy;
00009   long a, b;
00010 
00011   GradedAlgebra<F_2>::swap_variables_order(i, j, polys);
00012   dummy.steal(steenrod[i]);
00013   steenrod[i].steal( steenrod[j] );
00014   steenrod[j].steal( dummy );
00015 
00016   for(a=1; a<= var_in_use; a++)
00017     for(b=0; b<= hom_degrees[a]; b++)
00018       steenrod[a][b].swap_variables(i, j);
00019 }
00020 
00021 
00022 void UnstableAlgebra::swap_variables_order(long i, long j){
00023   list< Polynomial<F_2> > empty_list;
00024   
00025   this->swap_variables_order(i,j,empty_list);
00026 }
00027 
00028 void UnstableAlgebra::kill_top_variable(const Polynomial<F_2>& replacement,
00029                                         list< Polynomial<F_2> >& polys){
00030   long a,b;
00031 
00032   GradedAlgebra<F_2>::kill_top_variable(replacement, polys);
00033   steenrod.erase(this->var_in_use + 1);
00034 
00035   for(a=1; a<= this->var_in_use; a++)
00036     //we check if the steenrod operations are
00037     //defined at all for variable a...
00038     if(steenrod[a].size() == hom_degrees[a] + 1)
00039       for(b=0; b<= hom_degrees[a]; b++)
00040         steenrod[a][b].substitute_variable(var_in_use + 1, replacement);
00041 
00042 }
00043 
00044 
00045 void UnstableAlgebra::kill_top_variable(const Polynomial<F_2>& replacement){
00046   list< Polynomial<F_2> > empty_list;
00047   
00048   this->kill_top_variable(replacement,empty_list);
00049 }
00050 
00051 
00052 void UnstableAlgebra::fix_alphabets() {
00053 
00054   GradedAlgebra<F_2>::fix_alphabets();
00055 
00056   long a, b;
00057   for(a=1; a<= var_in_use; a++)
00058     for(b=0; b<= hom_degrees[a]; b++)
00059       steenrod[a][b].alphabet= this;
00060 }
00061 
00062 
00063 //new stuff /////////////////////////////////////////////////////////
00065 void UnstableAlgebra::write_trivial_steenrod_operations(){
00066   long i, n;
00067   Tuple< Polynomial<F_2> > vars= get_variables();
00068 
00069   for(i=1; i<=this->var_in_use; i++){
00070     n= hom_degrees[i];
00071     steenrod[i].resize( n + 1 );
00072     steenrod[i][0]= vars[i]; // Sq^0(x) = x
00073     steenrod[i][n]= vars[i] * vars[i]; //Sq^|x|(x) = x^2
00074   }// for i
00075 }
00076 
00077 
00078 Polynomial<F_2> UnstableAlgebra::Sq(long i, 
00079                                     const Polynomial<F_2>& x) const {
00080 
00081   if(i==0)
00082     return x;
00083 
00084   long n= hom_degree_of(x);
00085   Polynomial<F_2> ans= x;
00086 
00087 
00088   if(i < 0 || i > n || ans.is_zero() ){
00089     ans.sets_to_zero();
00090     return ans;
00091   }
00092   //else...
00093   Polynomial<F_2> P= ans.lt();
00094   ans+= P;
00095   if( !ans.is_zero() ) // x not a power product ?
00096     return Sq(i, ans) + Sq(i, P);
00097   //else, P==x is a power product
00098   PowProd pow= P.lp(); // same as P but viewed as a powprod
00099   long s= pow.nvars();
00100   if(s==0){ // x== 1 ?
00101     ans.sets_to_zero();//since i > 0
00102     return ans;
00103   }
00104   //else ! -- use Cartan's formula
00105   P= Polynomial<F_2>( pow/PowProd(s) ); //so x=P * variable s
00106   P.alphabet= (Alphabet *) this;
00107   long k, min, deg;
00108   deg= hom_degrees.find(s)->second; //deg= degree of variable s
00109   min= deg > i ? i : deg;
00110   ans.sets_to_zero();
00111 
00112   for(k=0; k<= min; k++)
00113     ans+= (steenrod.find(s)->second[k]) * Sq(i-k, P);
00114   
00115   return ans;
00116 }
00117 
00118 Polynomial<F_2> UnstableAlgebra::Q(long i, 
00119                                    const Polynomial<F_2>& x) const {
00120   long n, j;
00121 
00122   if( i < 0 )
00123     return x;
00124   if( i == 0 )
00125     return Sq(1, x);
00126   //set n= 2^i
00127   n= 1;
00128   for(j= 0; j< i; j++)
00129     n*= 2;
00130   return Sq(n, Q(i-1, x)) + Q(i-1, Sq(n, x));
00131 }
00132 
00133 
00134     
00135 // insert the polynomial in the list 'pretty_relations' in
00136 // the first position that keeps this list sorted with the
00137 // degrees nondecreasing. Insert the comment correspondingly
00138 void UnstableAlgebra::insert(const Polynomial<F_2>& P, 
00139                              const string& com, 
00140                              list< Polynomial<F_2> >& thelist){
00141   list< Polynomial<F_2> >::iterator locit; //loc= local
00142   list< string >::iterator locitcom;//ditto
00143 
00144   for(locit= thelist.begin(), locitcom= comments.begin();
00145       locit!= thelist.end();
00146       locit++, locitcom++)
00147     if( hom_degree_of( *locit) >= hom_degree_of(P) )
00148       break;
00149   //now locit and locitcom point at the right position
00150   thelist.insert(locit, P);
00151   comments.insert(locitcom, com);
00152 }
00153 
00154 
00155 
00156 AbstractHomomorphism<F_2> UnstableAlgebra::saturate_and_reduce(){
00157   bool grobner_done;
00158   long nb_relations, current_relation, var;
00159   Polynomial<F_2> rel, P;
00160   list< Polynomial<F_2> > pretty_relations;
00161   list< Polynomial<F_2> >::iterator it;
00162   list< string >::iterator itcom;
00163   AbstractHomomorphism<F_2> ans, temphom;
00164   ostringstream autoname;
00165   long k;
00166 
00167 
00168   if(verbose)
00169     cout << "{\\bf Now saturating & reducing variables and relations}"
00170          << endl << endl;
00171 
00172   grobner_done= false;
00173   ans.make_identity(this->var_in_use);
00174   nb_relations= 0;
00175   current_relation= 1;
00176   //copy the relations in pretty_relations
00177   //fill 'comments' with empty strings
00178   pretty_relations.splice(pretty_relations.begin(), relations.generators );
00179   comments.clear();
00180   for(it= pretty_relations.begin(); it!= pretty_relations.end(); it++)
00181     comments.push_back("");
00182 
00183   //now browse through pretty_relations
00184 
00185   for(it= pretty_relations.begin(), itcom= comments.begin(); 
00186       it!= pretty_relations.end();){
00187       
00188     if( (var= it->has_lonely_variable(rel)) > 0 ){
00189       if(very_verbose)
00190         cout << "relation " << current_relation
00191              << " yields a variable redundancy: $"
00192              << this->nameof(var) << " = " << rel 
00193              << "$" << endl << endl;
00194       it= pretty_relations.erase(it);
00195       itcom= comments.erase(itcom);
00196       kill_variable(var, rel, pretty_relations);
00197       grobner_done= false;
00198       // now write the corresponding homomorphism
00199       rel.swap_variables(var, this->var_in_use + 1); // rel itself must be updated !!
00200       temphom.make_identity(this->var_in_use + 1);
00201       temphom.set_image(this->var_in_use + 1, Polynomial<F_2>( PowProd(var) ) );
00202       temphom.set_image(var, rel);
00203       ans= temphom * ans;
00204     }
00205     else{
00206         
00207       if( !grobner_done ){
00208         find_grobner_basis();
00209         grobner_done= true;
00210       }
00211       rel= reduced_form( *it );
00212       if( !rel.is_zero() ){//not redundant ?
00213         nb_relations++;
00214         if(very_verbose)
00215           cout << "adding relation " << current_relation
00216                << " (total " << nb_relations << " relations added): "
00217                << "$" << rel << "$" << endl << endl;
00218         add_relation(rel);
00219         grobner_done= false;
00220 
00221         //now let's find a name for this relation, if needed
00222         if( *itcom == "" ){//not named yet ?
00223           autoname.str("");
00224           autoname << "(" << nb_relations << ")";
00225           *itcom= autoname.str();
00226         }
00227         //now deal with the steenrod operations
00228         for(k=1; k < hom_degree_of( *it ); k++){
00229           P= Sq(k, *it);
00230           if( !P.is_zero() ){
00231             autoname.str("");
00232             autoname << "Sq^" << k << *itcom;
00233             insert( P, autoname.str(), pretty_relations );
00234           }
00235         }//done with steenrod!
00236         it++;
00237         itcom++;
00238       }
00239       else{//redundant !
00240         if(very_verbose)
00241           cout << "relation " << current_relation << " redundant"
00242                << endl << endl;
00243         it= pretty_relations.erase(it);
00244         itcom= comments.erase(itcom);
00245       }
00246     }
00247     current_relation++;
00248   }
00249   //cut_down_variables();
00250   if(verbose)
00251     cout << "{\\bf Final presentation: } " 
00252          << var_in_use << " variables kept, " 
00253          << nb_relations << " relations kept" 
00254          << endl << endl;
00255   //copy pretty_relations into relations.generators
00256   relations.generators.clear();
00257   relations.generators.splice( relations.generators.begin(), pretty_relations);
00258   return ans;
00259 }
00260 
00261 void UnstableAlgebra::display() const {
00262   list< Polynomial<F_2> >::const_iterator it;
00263   list< string >::const_iterator itcom;
00264   map<long, string>::const_iterator it_gen;
00265   map<long, long>::const_iterator it_deg;
00266 
00267 
00268   cout << "generators:" << endl << endl;
00269   for(it_gen= names.begin(), it_deg= hom_degrees.begin(); 
00270       it_gen!= names.end(); 
00271       it_gen++, it_deg++)
00272     cout << "$" << it_gen->second << "$"
00273          << " of degree "
00274          << it_deg->second << endl << endl;
00275   
00276 
00277   cout << endl << "relations:" << endl;
00278 
00279   for(it= relations.generators.begin(), itcom= comments.begin(); 
00280       it!= relations.generators.end(); it++, itcom++){
00281     cout << *itcom << " :    " << *it << endl << endl;
00282   }
00283 
00284   //steenrod operations
00285   long i, j;
00286 
00287   cout << "Steenrod operations:" << endl << endl;
00288   for(i=1; i<= var_in_use; i++)
00289     for(j=1; j< steenrod.find(i)->second.size()-1; j++)
00290       cout << "$Sq^" << j << "(" << nameof(i) << ") = "
00291          << steenrod.find(i)->second[j] << "$" << endl << endl;
00292 
00293 
00294 
00295 }
00296 
00297 
00298 
00299 bool UnstableAlgebra::is_saturated() const {
00300   list< Polynomial<F_2> >::const_iterator it;
00301   long k;
00302 
00303   for(it= relations.generators.begin();
00304       it!= relations.generators.end();
00305       it++)
00306     for(k=1; k < hom_degree_of( *it ); k++)
00307       if(!reduced_form( Sq(k, *it) ).is_zero() )
00308         return false;
00309 
00310   return true;
00311 
00312 }
00313 
00314 
00315 bool UnstableAlgebra::has_closure_of(const AffineHomomorphism<F_2>& f) const {
00316   long i, k;
00317   Polynomial<F_2> P;
00318 
00319   for(i=1; i<= f.source->variables_in_use(); i++) {
00320     P= f.of_generator(i);
00321     for(k=1; k < this->hom_degree_of(P); k++)
00322       if( !f.maps_onto( Sq(k, P) ) ) {
00323         cout << "no! one has Sq^" << k
00324              << "(" << P << ") = " 
00325              << Sq(k, P) << " which is not in the image"
00326              << endl;
00327         return false;
00328       }
00329   }
00330   return true;
00331 }
00332 
00333 
00334 
00335 
00336 // friend printing /////////////////////////////////////////////////
00338 
00339 ostream& operator<<(ostream& os, const UnstableAlgebra& A){
00340   const GradedAlgebra<F_2> *ptr;
00341 
00342   ptr= &A;
00343   os << *ptr;
00344 
00345   long i, j;
00346 
00347   os << "Steenrod operations:" << endl << endl;
00348   for(i=1; i<= A.variables_in_use(); i++)
00349     for(j=1; j< A.steenrod.find(i)->second.size()-1; j++)
00350       os << "Sq^" << j << "(" << A.nameof(i) << ") = "
00351          << A.steenrod.find(i)->second[j] << endl << endl;
00352 
00353   return os;
00354 }
00355 
00356 ofstream& operator<<(ofstream& file, UnstableAlgebra& A){
00357   GradedAlgebra<F_2> *ptr;
00358 
00359   ptr= &A;
00360   file << *ptr;
00361 
00362   //now write the steenrod operations
00363   long i, j;
00364 
00365   for(i=1; i<= A.variables_in_use(); i++)
00366     for(j=1; j< A.steenrod.find(i)->second.size()-1; j++)
00367       file << A.steenrod[i][j];
00368 
00369 
00370   //and now the comments
00371   list< string >::iterator it;
00372   i= 0;
00373   for(it= A.comments.begin(); it!= A.comments.end(); it++)
00374     i++;
00375   file << i << " ";
00376   for(it= A.comments.begin(); it!= A.comments.end(); it++)
00377     file << *it << " ";
00378 
00379   return file;
00380 }
00381 
00382 void operator>>(ifstream& file, UnstableAlgebra& A){
00383   GradedAlgebra<F_2> *ptr;
00384   
00385   ptr= &A;
00386   file >> *ptr;
00387 
00388   //now steenrod
00389   A.write_trivial_steenrod_operations();
00390 
00391   long i, j;
00392 
00393   for(i=1; i<= A.variables_in_use(); i++)
00394     for(j=1; j< A.steenrod.find(i)->second.size()-1; j++)
00395       file >> A.steenrod[i][j];
00396 
00397   A.fix_alphabets();
00398 
00399   //now comments
00400   string foo;
00401   A.comments.clear();
00402   file >> i;
00403   while( i>0 ){
00404     file >> foo;
00405     A.comments.push_back( foo );
00406     i--;
00407   }
00408 
00409 }

Generated on Wed Jun 18 17:22:42 2008 for Pierre Guillot by  doxygen 1.3.9.1