hom.cpp

00001 #include <fstream>
00002 #include <iostream>
00003 #include "algebras.H"
00004 #include "homfinder.H"
00005 #include "cmdline.H"
00006 using namespace std;
00007 
00017 int main(int argc, char** argv)
00018 {
00020   // initialization   /////////////////////////////
00022 
00023   // read the descriptions of the formal ring of sw classes and the
00024   // cohomology ring from files, according to the command line
00025 
00026   CommandLine::init(argc, argv);
00027   string name= CommandLine::parameters[0];
00028   string source= name + ".W";
00029   string target= name + ".cohomology.mod2";
00030 
00031   UnstableAlgebra A;            // the source: W_F^*(G)
00032   GradedAlgebra<F_2>  B;        // the target: H^*(G)
00033 
00034   ifstream my_source(source.c_str());
00035   if(my_source.fail()){
00036     cout << "could not read file" << source << endl;
00037     return 10;
00038   }
00039   else
00040     my_source >> A;
00041   my_source.close();
00042 
00043   ifstream my_target(target.c_str());
00044   if(my_target.fail()){ 
00045     cout << "could not read file" << target << endl;
00046     return 10;
00047   }
00048   else
00049     my_target >> B;
00050   my_target.close();
00051 
00052   // create a HomFinder, a class with methods which help find the
00053   // homomorphisms between A and B
00054   HomFinder myfinder(&A, &B);
00055 
00056   // set the "verbosity" (amount of information printed) according to
00057   // the options on the command line
00058   myfinder.very_verbose= myfinder.verbose= true;
00059 
00060   if(CommandLine::has_tag("-quiet")) 
00061     myfinder.very_verbose= false;
00062   if(CommandLine::has_tag("-silent"))
00063     myfinder.very_verbose= myfinder.verbose= false;
00064 
00065   // put A and B in the right form
00066   A.find_grobner_basis();
00067   A.find_redundancies();
00068   B.find_grobner_basis();
00069 
00070   if(myfinder.very_verbose)  
00071     cout << "Here's the formal ring of SW classes: "
00072          << endl << "(with a minimal set of relations"
00073          << " extracted from a reduced Grobner basis)"
00074          << endl << A << endl
00075          << "and here is the cohomology: " << endl
00076          << "(with a Grobner basis)" << endl
00077          << B << endl;
00078 
00080   // Step 1: variables of degree 1 //////////////
00082 
00083   // this sets up many things: the variables are sorted into the
00084   // t_i's, the q_i's and p_i's, for example -- see the
00085   // documentation. Eventually Step 1 is completed, that is we have a
00086   // list of all consistent choices for the degree 1 variables.
00087   myfinder.init();
00088     
00090   // Step 2: the q_i's //////////////////////////
00092   
00093   if(myfinder.verbose)
00094     cout << endl << "*** Step 2:" << endl;
00095 
00096   // Normal procedure: this step is lengthy. When we've completed it,
00097   // we save the results to a file so that a subsequent run can look
00098   // for the solutions rather than start from scratch.
00099   string sol_file= name + ".solutions";  
00100   ifstream my_in(sol_file.c_str());
00101   
00102   if(my_in.fail()){
00103     // the "start" method does all the work. See documentation.
00104     myfinder.start();
00105     ofstream my_out(sol_file.c_str());
00106     myfinder.write_solutions_to(my_out); 
00107   }
00108   else{
00109     if(myfinder.verbose)
00110       cout << "found solution file " << sol_file
00111            << endl;
00112     myfinder.read_solutions_from(my_in);
00113   }
00114 
00115   if(myfinder.verbose)
00116     cout << "Total: "
00117          << myfinder.solution_count
00118          << " possibilities after Steps 1 & 2"
00119          << endl;
00120 
00122   // Step 3 and Test 1 ///////////////////////////
00124 
00125   if(CommandLine::has_tag("-brute")){
00126 
00127     if(myfinder.verbose)
00128       cout << endl << "*** Step 3 (exhaustive version) & Test 1" << endl;
00129     // find the possibilities for the polynomial variables, and keep
00130     // only those which turn B into a finitely generated A-module
00131     myfinder.define_polynomial_variables_brutally();
00132 
00133   }
00134   else{
00135       
00136     if(myfinder.verbose)
00137       cout << endl << "*** Step 3 & Test 1" << endl;
00138     // find the possibilities for the polynomial variables, and keep
00139     // only those which turn B into a finitely generated A-module
00140     myfinder.define_polynomial_variables();
00141   }
00142 
00144   // Test 2 //////////////////////////////////////
00146   if(CommandLine::has_tag("-brute")){
00147 
00148       if(myfinder.verbose)
00149         cout << endl << "*** Test 2 skipped, just computing all kernels" 
00150              << endl;
00151       
00152       myfinder.compute_all_kernels();
00153     }
00154     else{
00155 
00156       if(myfinder.verbose)
00157         cout << endl << "*** Test 2" << endl;
00158       
00159       if( !myfinder.polynomial_test() ){
00160         cout << "Test 2 failed, giving up!" << endl;
00161         return 2;
00162       }
00163       else
00164         if(myfinder.verbose)
00165           cout << "Passed !" << endl;
00166     }
00167     
00169   // Count equivalence classes ///////////////////
00171 
00172   //we shall use this over and over
00173   list< AffineHomomorphism<F_2> > backup= myfinder.solutions;
00174   //keep only one solution in each equivalence class:
00175   if(myfinder.verbose)
00176     cout << endl << "*** We count the equivalence classes so far:" << endl;
00177 
00178   myfinder.identify();
00179 
00180   if(myfinder.verbose)
00181     cout << myfinder.solution_count << " classes" << endl;
00182 
00184   // Test 3: Steenrod ////////////////////////////
00186 
00187 
00188   if( myfinder.solution_count > 1){ //more than one ?
00189   
00190     if(myfinder.verbose)  
00191       cout << "*** Test 3" << endl;
00192     
00193     myfinder.test_steenrod();
00194 
00195     if(myfinder.verbose)
00196       cout << "Done, " << myfinder.solution_count 
00197            << " classes kept" << endl;
00198   }
00199 
00201   // Test 4: restrictions to elemabs //////////////
00203 
00204   if( myfinder.solution_count > 1){ //more than one ?
00205 
00206     if(myfinder.verbose)  
00207       cout << "*** Test 4" << endl;
00208     
00209     string res_name= name + ".W.res.elemab";
00210     ifstream res_file(res_name.c_str());
00211     
00212     myfinder.restrict_to_elemab( res_file );
00213 
00214     if(myfinder.verbose)  
00215       cout << "Done, " << myfinder.solution_count
00216            << " classes kept" << endl;
00217   }
00218 
00220   // Conclusions ///////////////////////////////////
00222 
00223   if( myfinder.solution_count > 1){ //more than one ?
00224     cout << endl << myfinder.solution_count
00225          << " equivalence classes, giving up!"
00226          << endl;
00227       return 1;
00228     }
00229 
00230   //we look at the solutions in 'backup' and select
00231   //the ones which are in the equivalence class
00232   //which we have now isolated (in many cases, all
00233   //the homomorphisms in backup are equivalent anyway)
00234   AffineHomomorphism<F_2> f= *myfinder.solutions.begin();
00235   myfinder.get_equivalence_class(backup, f);
00236   // now we extend these (getting f+ from f)
00237   long new_vars;
00238   new_vars= myfinder.extend_all();
00239   //let's see if we have added any:
00240   if( new_vars > 0 ) {
00241 
00242     if(myfinder.verbose)
00243       cout << endl << "*** There are variables which are not SW classes, "
00244            << endl << "we check if the extended homomorphisms are equivalent"
00245            << endl;
00246 
00247     myfinder.identify();
00248 
00249     if( myfinder.solution_count > 1){ //more than one ?
00250       cout << endl << myfinder.solution_count
00251            << " equivalence classes, giving up!"
00252            << endl;
00253       return 3;
00254     }
00255   }
00256   //if new_vars is 0, we have added nothing to the solution
00257   //homomorphisms, so that they are all equivalent, as we already
00258   //know. In this case myfinder.solutions is a whole list, whereas if
00259   //new_vars > 0 we have reduced it to a single solution.
00260  
00262   // add the relations to A and save to disk /////
00264   if(myfinder.verbose)
00265     cout << endl << "*** Done ! solution completely determined !"
00266          << endl;
00267 
00268 
00269   AbstractHomomorphism<F_2> reduc;
00270   list< Polynomial<F_2> >::iterator gen;
00271 
00272   f= *myfinder.solutions.begin(); // this is the solution !
00273 
00274   if(myfinder.verbose)
00275     cout << f << endl;
00276 
00277   for(gen= f.kernel.generators.begin();
00278       gen != f.kernel.generators.end();
00279       gen++)
00280     A.add_relation(*gen);
00281 
00282   A.split_and_sort_relations();
00283 
00284 
00285   if(new_vars == 0){ //no new variables added ?
00286     reduc= A.saturate_and_reduce(); //still have steenrod info
00287     if(myfinder.verbose)
00288       A.display();
00289   } 
00290   else{
00291     reduc= A.find_redundancies();
00292     A.write_trivial_steenrod_operations();
00293     //we set to zero the unknown steenrod operations
00294     if(myfinder.verbose)
00295       cout << A << endl;
00296 
00297   }
00298 
00299   string output_name= name + ".final";
00300   ofstream output(output_name.c_str());
00301 
00302   output << A;
00303   output << reduc;
00304   output << f;
00305 
00306   return 0;
00307 }
00308 
00309  
00310 
00311 
00312 
00313 
00314 

Generated on Fri Jun 13 15:48:17 2008 for Pierre Guillot by  doxygen 1.3.9.1