00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef monomial_basisH_SEEN
00019 #define monomial_basisH_SEEN
00020
00022
00046 template<typename SCA, DEG n_letters, DEG max_degree>
00047 class monomial_basis
00048 {
00049 public:
00051 typedef std::deque<LET> KEY;
00053 const KEY empty_key;
00055 typedef std::map<KEY, SCA> MAP;
00056 private:
00058 DEG _size;
00059 public:
00061 monomial_basis(void)
00062 {
00063
00064
00065 _size = 1;
00066 for (DEG i = 1; i <= max_degree; ++i)
00067 _size += _size * n_letters;
00068 }
00069 public:
00071 inline KEY keyofletter(LET letter) const
00072 {
00073 KEY result;
00074 result.push_back(letter);
00075 return result;
00076 }
00078 inline bool letter(const KEY& k) const
00079 {
00080 return k.size() == 1;
00081 }
00083 inline LET getletter(const KEY& k) const
00084 {
00085 return k[0];
00086 }
00088 inline KEY lparent(const KEY& k) const
00089 {
00090 KEY result;
00091 result.push_back(k[0]);
00092 return result;
00093 }
00095 inline KEY rparent(const KEY& k) const
00096 {
00097 KEY result(k);
00098 result.pop_front();
00099 return result;
00100 }
00102 inline DEG degree(const KEY& k) const
00103 {
00104 return k.size();
00105 }
00107 inline DEG size(void) const
00108 {
00109 return _size;
00110 }
00112 inline DEG keypos(const KEY& k) const
00113 {
00114 DEG pos = 1;
00115 for (DEG i = 0; i < k.size(); ++i)
00116 pos += n_letters * (k[i] - 1);
00117 return pos;
00118 }
00120 inline KEY begin(void) const
00121 {
00122 return empty_key;
00123 }
00125 inline KEY end(void) const
00126 {
00127 KEY result;
00128 result.push_back(0);
00129 return result;
00130 }
00132 inline KEY nextkey(const KEY& k) const
00133 {
00134 KEY::size_type i;
00135 for (i = k.size() - 1; i >= 0; --i)
00136 if (k[i] < n_letters)
00137 {
00138 KEY result(k);
00139 result[i] += 1;
00140 return result;
00141 }
00142 return end();
00143 }
00145 std::string key2string(const KEY& k) const
00146 {
00147 std::ostringstream oss;
00148 KEY::size_type i;
00149 if (!k.empty())
00150 oss << k[0];
00151 for (i = 1; i < k.size(); ++i)
00152 oss << "," << k[i];
00153 return oss.str();
00154 }
00155 };
00156
00158
00169 template<typename SCA, typename RAT, DEG n_letters, DEG max_degree>
00170 class free_monomial_basis : public monomial_basis<SCA, n_letters, max_degree>
00171 {
00172 public:
00174 typedef monomial_basis<SCA, n_letters, max_degree> PBASIS;
00176 typedef typename PBASIS::KEY KEY;
00178 typedef typename PBASIS::MAP MAP;
00180 typedef RAT RATIONAL;
00182 typedef multi_polynomial<SCA, RAT, n_letters, max_degree> MULTIPOLY;
00183 public:
00185 free_monomial_basis(void) {}
00186 public:
00188
00194 inline MULTIPOLY prod(const KEY& k1, const KEY& k2) const
00195 {
00196 static SCA one(+1);
00197 MULTIPOLY result;
00198 if ((max_degree == 0) || (k1.size() + k2.size() <= max_degree))
00199 {
00200 KEY concat(k1);
00201 for (typename KEY::size_type i = 0; i < k2.size(); ++i)
00202 concat.push_back(k2[i]);
00203 result[concat] = one;
00204 }
00205 return result;
00206 }
00208 inline friend
00209 std::ostream& operator<<(std::ostream& os, const std::pair<free_monomial_basis*, KEY>& t)
00210 {
00211 return os << (t.first)->key2string(t.second);
00212 }
00213 };
00214
00215
00216 #endif
00217
00218