00001 #ifndef _ABSHOM_H_
00002 #define _ABSHOM_H_
00003
00004 #include <iostream>
00005 #include <map>
00006 #include <algebras.H>
00007 using namespace std;
00008
00009
00011
00021 template <class K>
00022 class AbstractHomomorphism {
00023 protected:
00025 map <long, Polynomial<K> > images;
00027
00038 long highest_var;
00039 public:
00040 AbstractHomomorphism(){
00041
00042 highest_var= 0;
00043 }
00045 void clear(){
00046
00047 images.clear();
00048 highest_var= 0;
00049 }
00050
00051 Polynomial<K> of_generator(long var) const
00052 {
00053 return images.find(var)->second;
00054 }
00055
00056
00058 void set_image(long var, const Polynomial<K>& P){
00059 long n;
00060
00061 images[var]= P;
00062 n= P.nvars();
00063 if( n > highest_var)
00064 highest_var= n;
00065 }
00067 bool has_image_set(long var) const {
00068
00069 return (images.count(var) > 0);
00070 }
00072 void make_identity(long n){
00073
00074 images.clear();
00075
00076 for(long i=1; i<=n; i++)
00077 images[i]= Polynomial<K>( PowProd(i) );
00078
00079 highest_var= n;
00080 }
00082 void swap(long i, long j){
00083 Polynomial<K> dummy;
00084
00085 dummy= images[i];
00086 images[i]= images[j];
00087 images[j]= dummy;
00088 }
00089
00091
00096 Polynomial<K> of(const Polynomial<K>& P) const {
00097 Polynomial<K> ans, temp;
00098 long d;
00099
00100 ans= P;
00101 if(images.empty()){
00102 ans.sets_to_zero();
00103 return ans;
00104 }
00105
00106 ans.alphabet= images.begin()->second.alphabet;
00107
00108 ans.shift_variables(highest_var);
00109 d= P.nvars();
00110 for(long i= 1; i <= d; i++)
00111 if(P.involves_variable(i)){
00112 if(images.count(i) > 0)
00113 temp= images.find(i)->second;
00114 else
00115 temp.sets_to_zero();
00116
00117 ans.substitute_variable(i + highest_var, temp);
00118 }
00119 return ans;
00120 }
00121
00123 AbstractHomomorphism<K>& operator*=(const AbstractHomomorphism<K>& f){
00124 typename map< long, Polynomial<K> >::const_iterator it;
00125 AbstractHomomorphism ans;
00126
00127 for(it= f.images.begin(); it!= f.images.end(); it++)
00128 ans.set_image( it->first, this->of( it->second ) );
00129
00130 *this= ans;
00131
00132 return *this;
00133 }
00135 AbstractHomomorphism<K> operator*(const AbstractHomomorphism<K>& f) const {
00136 typename map< long, Polynomial<K> >::const_iterator it;
00137 AbstractHomomorphism ans;
00138
00139 for(it= f.images.begin(); it!= f.images.end(); it++)
00140 ans.set_image( it->first, this->of( it->second ) );
00141
00142 return ans;
00143 }
00145 friend ostream& operator<<(ostream& os, const AbstractHomomorphism<K>& f){
00146 typename map< long, Polynomial<K> >::const_iterator it;
00147
00148 for(it= f.images.begin(); it!= f.images.end(); it++)
00149 os << "variable " << it->first <<" --> " << it->second << endl;
00150
00151 return os;
00152 }
00153
00154
00156 friend ofstream& operator<<(ofstream& file, AbstractHomomorphism<K>& f){
00157 typename map< long, Polynomial<K> >::iterator it;
00158
00159 for(it= f.images.begin(); it!= f.images.end(); it++){
00160 file << it->first << " ";
00161 file << it->second;
00162 file << " ";
00163 }
00164
00165 file << 0 << " ";
00166 return file;
00167 }
00168
00170 friend void operator>>(ifstream& file, AbstractHomomorphism<K>& f){
00171 long index;
00172 Polynomial<K> P;
00173
00174 f.clear();
00175
00176 file >> index;
00177
00178 while(index != 0){
00179 file >> P;
00180 f.set_image(index, P);
00181 file >> index;
00182 }
00183
00184 }
00185
00186
00187
00188
00189 };
00190
00191
00192
00193
00194
00195
00196
00197 #endif