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

affhom.H

00001 #ifndef _AFFHOM_H_
00002 #define _AFFHOM_H_
00003 
00004 #include "algebras.H"
00005 using namespace std;
00006 
00007 
00008 
00010 
00018 template <class K>
00019 class AffineHomomorphism : public AbstractHomomorphism<K> {
00020  public:
00021   const AffineAlgebra<K> *source, *target;
00022   Ideal<K> kernel;
00024 
00032   AffineAlgebra<K> assoc_alg;
00033   
00034   // constructors///////////////////////////////////////////////////////
00036 
00037   AffineHomomorphism() : AbstractHomomorphism<K>::AbstractHomomorphism(){
00038     
00039     source= target= 0;
00040   }
00041 
00042   AffineHomomorphism(const AffineAlgebra<K> *thesource, 
00043                      const AffineAlgebra<K> *thetarget) : AbstractHomomorphism<K>::AbstractHomomorphism() {
00044 
00045     source= thesource;
00046     target= thetarget;
00047   }
00048 
00049   //little things /////////////////////////////////////////////////////////
00051 
00053   void make_identity(const AffineAlgebra<K> *ptr){
00054 
00055     source= target= ptr;
00056     AbstractHomomorphism<K>::make_identity(ptr->variables_in_use());
00057     fix_alphabets();
00058   }
00060   void fix_alphabets(){
00061     typename map< long, Polynomial<K> >::iterator it;
00062 
00063     for(it= this->images.begin(); it!= this->images.end(); it++)
00064       it->second.alphabet= (Alphabet *) target;
00065   }
00067 
00074   void remove_extra_data(){
00075     typename map< long, Polynomial<K> >::iterator it, itp;
00076     
00077     //undefine some images:
00078     for(it= this->images.begin(); it!= this->images.end();)
00079       if( it->first > source->variables_in_use() ){
00080         itp= it;
00081         itp++;
00082         this->images.erase(it->first);
00083         it= itp;
00084       }
00085       else
00086         it++;
00087     
00088     //now take care of the kernel
00089     typename list< Polynomial<K> >::iterator itker;
00090 
00091     for(itker= this->kernel.generators.begin();
00092         itker != this->kernel.generators.end();
00093         ){
00094       if( itker->nvars() > source->variables_in_use() ){
00095         itker= this->kernel.generators.erase( itker );
00096       }
00097       else
00098         itker++;
00099     }
00100   }
00102 
00106   bool fill_zeroes() 
00107   {
00108     long i;
00109     bool ans= false;
00110     Polynomial<K> P=target->one();
00111     
00112     P.sets_to_zero();
00113         
00114     for(i=1; i<= source->variables_in_use(); i++)
00115       if( !this->has_image_set(i) ){
00116         ans= true;
00117         this->set_image(i, P);
00118       }
00119     
00120     return ans;
00121   }
00122   
00124 
00127   void get_data_from(const AbstractHomomorphism<K>& f){
00128     AbstractHomomorphism<K> *ptr;
00129 
00130     ptr= (AbstractHomomorphism<K> *) this; //need to proceed this
00131     *ptr = f; //way in order to copy the protected data !!
00132     fix_alphabets();
00133     remove_extra_data();
00134   }
00136 
00142   bool is_well_defined() const {
00143     typename list< Polynomial<K> >::const_iterator it;
00144 
00145     for(it= source->relations.generators.begin();
00146         it != source->relations.generators.end();
00147         it++)
00148       if( !target->reduced_form( this->of(*it) ).is_zero() )
00149         return false;
00150 
00151     return true;
00152   }
00153 
00155 
00171   AffineHomomorphism<K> simple_section() const {
00172     AffineHomomorphism<K> ans;
00173     long i, j;
00174     Tuple< Polynomial<K> > x;
00175 
00176     ans.source= this->target;
00177     ans.target= this->source;
00178     x= source->get_variables();
00179     for(i=1; i<= target->variables_in_use(); i++) {
00180       for(j=1; j<= source->variables_in_use(); j++)
00181         if( source->nameof(j) == target->nameof(i) )
00182           break;
00183       ans.set_image(i, x[j]);
00184     }
00185 
00186     return ans;
00187   }
00188 
00190 
00197   void read_from_GAP_file(ifstream& file) {
00198     long i, j;
00199     Polynomial<K> P= target->one();
00200     K coeff;
00201 
00202     this->images.clear();
00203     for(i=1; i<= source->variables_in_use(); i++){
00204       P.sets_to_zero();
00205       for(j=0; j<= target->variables_in_use(); j++) {
00206         file >> coeff;
00207         P.add_term( PowProd(j), coeff);
00208       }
00209       this->set_image(i, P);
00210     }
00211   }
00212 
00213 
00214 
00215   //methods related to the kernel ////////////////////////////////////
00217 
00219 
00225   void compute_kernel() 
00226   {
00227     AffineAlgebra<K> alg;
00228     long i;
00229     Tuple< Polynomial<K> > vars= source->get_variables();
00230     Polynomial<K> P;
00231         
00232     alg= *source;
00233     alg.relations.generators.clear();
00234     alg.tensor_with(*target);
00235     for(i=1; i<= source->variables_in_use(); i++){
00236       P= this->of_generator(i);
00237       P.shift_variables( source->variables_in_use() );
00238       P*= -1;
00239       alg.add_relation( vars[i] + P);
00240     }
00241     
00242 
00243     alg.find_grobner_basis();
00244     alg.reduce_grobner_basis();
00245 
00246     
00247 
00248     kernel.generators.clear();
00249     typename list< Polynomial<K> >::iterator it;
00250     for(it= alg.relations.generators.begin();
00251         it!= alg.relations.generators.end();
00252         it++)
00253       if( it->nvars() <= source->variables_in_use() ){
00254         P= *it;
00255         P.alphabet= (Alphabet *) source;
00256         kernel.generators.push_back( P );
00257       }
00258   }
00260 
00269   void populate_associated_algebra() 
00270   {
00271     long i;
00272     Tuple< Polynomial<K> > vars= source->get_variables();
00273     Polynomial<K> P;
00274         
00275     assoc_alg= *source;
00276     assoc_alg.relations.generators.clear();
00277     assoc_alg.tensor_with(*target);
00278     for(i=1; i<= source->variables_in_use(); i++){
00279       P= this->of_generator(i);
00280       P.shift_variables( source->variables_in_use() );
00281       P*= -1;
00282       assoc_alg.add_relation( vars[i] + P);
00283     }
00284     
00285 
00286     assoc_alg.find_grobner_basis();
00287 
00288     kernel.generators.clear();
00289     typename list< Polynomial<K> >::iterator it;
00290     for(it= assoc_alg.relations.generators.begin();
00291         it!= assoc_alg.relations.generators.end();
00292         it++)
00293       if( it->nvars() <= source->variables_in_use() ){
00294         P= *it;
00295         P.alphabet= (Alphabet *) source;
00296         kernel.generators.push_back( P );
00297       }
00298   }
00299 
00300   bool maps_onto(const Polynomial<K>& P) const {
00301     Polynomial<K> Q;
00302 
00303     Q= P;
00304     Q.shift_variables( source->variables_in_use() );
00305     Q= assoc_alg.reduced_form( Q );
00306     return ( Q.nvars() <= source->variables_in_use() );
00307   }
00308 
00309   bool maps_onto(const Polynomial<K>& P,
00310                  Polynomial<K>& pre_image) const {
00311 
00312     pre_image= P;
00313     pre_image.shift_variables( source->variables_in_use() );
00314     pre_image= assoc_alg.reduced_form( pre_image );
00315     if(pre_image.nvars() <= source->variables_in_use() ){
00316       pre_image.alphabet= (Alphabet *) source;
00317       return true;
00318     }
00319     else
00320       return false;
00321   }
00322 
00324 
00327   bool factors_through(const Ideal<K>& J) const 
00328   {
00329     list< Polynomial<K> > kernel;
00330     typename list< Polynomial<K> >::const_iterator it;
00331     
00332     for(it= J.generators.begin();
00333         it!= J.generators.end();
00334         it++)
00335       if( !target->reduced_form( this->of(*it) ).is_zero() ) 
00336           return false;
00337           
00338     return true;
00339   }
00340   
00341 
00342   // methods related to the image ///////////////////////////////////
00344 
00346 
00352   bool is_finite() const 
00353   {
00354     AffineAlgebra<K> A;
00355     long i;
00356         
00357 
00358     A= *target;
00359     A.fix_alphabets();
00360         
00361     for(i=1; i<= source->variables_in_use(); i++)
00362       A.add_relation( this->images.find(i)->second );
00363       
00364 
00365     A.find_grobner_basis();
00366     A.reduce_grobner_basis();
00367     
00368     return A.is_finite_dimensional();
00369   }
00371 
00375   bool is_essentially_surjective() const 
00376   {
00377     AffineAlgebra<K> A;
00378     long i;
00379         
00380 
00381     A= *target;
00382     A.fix_alphabets();
00383         
00384     for(i=1; i<= source->variables_in_use(); i++)
00385       A.add_relation( this->images.find(i)->second );
00386       
00387 
00388     A.find_grobner_basis();
00389     A.reduce_grobner_basis();
00390     
00391     
00392     Polynomial<K> P;
00393     
00394     for(i=1; i<= A.variables_in_use(); i++){
00395       P= Polynomial<K>( PowProd(i) );
00396       //      P.alphabet= &A;
00397       if( !A.reduced_form(P).is_zero() ){
00398         //cout << P << " not in the image" << endl;
00399         
00400         return false;
00401       }
00402       
00403     }
00404     
00405     return true;
00406     
00407   }
00409   bool is_essentially_contained_in(const AffineHomomorphism<K>& g) const 
00410   {
00411     AffineAlgebra<K> alg;
00412     long i;
00413     
00414     alg= *target;
00415     for(i=1; i<= source->variables_in_use(); i++)
00416         alg.add_relation( g.of_generator(i) );
00417     alg.fix_alphabets();      
00418     alg.find_grobner_basis();
00419     
00420     for(i=1; i<= source->variables_in_use(); i++)
00421       if( !alg.reduced_form( this->of_generator(i) ).is_zero() )
00422         break;
00423 
00424     return (i == source->variables_in_use()+1 );
00425   }
00426 
00427 
00428   //a bunch of operators ///////////////////////////////////////////
00430   
00431   
00432   AffineHomomorphism<K>& operator*=(const AffineHomomorphism<K>& f){
00433     AbstractHomomorphism<K> *a= this;
00434     const AbstractHomomorphism<K> *b= &f;
00435 
00436     *a *= *b; // *this has now the right "data"
00437     source= f.source;
00438 
00439     return *this;
00440   }
00441 
00442 
00443   AffineHomomorphism<K> operator*(const AffineHomomorphism<K>& f) const {
00444     AffineHomomorphism<K> ans;
00445     const AbstractHomomorphism<K> *a= this;
00446     const AbstractHomomorphism<K> *b= &f;
00447 
00448     ans.source= f.source;
00449     ans.target= this->target;
00450     ans.get_data_from( *a * *b );
00451 
00452     return ans;
00453   }
00454 
00456   friend ostream& operator<<(ostream& os, const AffineHomomorphism<K>& f){
00457     typename map< long, Polynomial<K> >::const_iterator it;
00458     
00459     for(it= f.images.begin(); it!= f.images.end(); it++)
00460       os << f.source->nameof(it->first) 
00461          <<" --> " << it->second 
00462          << endl << endl;
00463     
00464     return os;
00465   }
00466 
00468   friend ofstream& operator<<(ofstream& file, AffineHomomorphism<K>& f){
00469     AbstractHomomorphism<K> *g;
00470     
00471     g=(AbstractHomomorphism<K> *) &f;
00472     file << *g;
00473     return file;
00474   }
00475   
00477   friend void operator>>(ifstream& file, AffineHomomorphism<K>& f){
00478     AbstractHomomorphism<K> *g;
00479     
00480     g=(AbstractHomomorphism<K> *) &f;
00481     file >> *g;
00482     f.fix_alphabets();
00483     
00484   }
00485 
00486 
00487 
00488 
00489 };
00490 
00491 
00492 
00493 
00494 
00495 
00496 
00497 
00498 
00499 
00500 
00501 
00502 #endif

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