• Main Page
  • Namespaces
  • Classes
  • Files
  • File List

libalgebra-demo/libalgebra/tensor_basis.h

00001 /* *************************************************************
00002 
00003 Copyright 2010 Terry Lyons, Stephen Buckley, Djalil Chafai, 
00004 Greg Gyurkó and Arend Janssen. 
00005 
00006 Distributed under the terms of the GNU General Public License, 
00007 Version 3. (See accompanying file License.txt)
00008 
00009 ************************************************************* */
00010 
00011 
00012 
00013 
00014 //  tensor_basis.h
00015 
00016 
00017 // Include once wrapper
00018 #ifndef DJC_COROPA_LIBALGEBRA_TENSORBASISH_SEEN
00019 #define DJC_COROPA_LIBALGEBRA_TENSORBASISH_SEEN
00020 
00021 
00022 #include "_tensor_basis.h"
00023 #include "constpower.h"
00024 #include "basis_traits.h"
00025 
00027 
00051 template<typename SCA, DEG n_letters, DEG max_degree>
00052 class tensor_basis
00053 {
00054 public:
00056         typedef _tensor_basis<n_letters, max_degree> KEY;
00058         const KEY empty_key;
00060         typedef std::map<KEY, SCA> MAP;
00061 private:
00063         DEG _size;
00064 public:
00066 
00069         tensor_basis(void)
00070                 : _size ((ConstPower < n_letters, max_degree + 1 > ::ans - 1) / (n_letters - 1)) {}
00071 public:
00073         inline KEY keyofletter(LET letter) const
00074         {
00075                 return KEY(letter);
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.FirstLetter();
00086         }
00088         inline KEY lparent(const KEY& k) const
00089         {
00090                 return k.lparent();
00091         }
00093         inline KEY rparent(const KEY& k) const
00094         {
00095                 return k.rparent();
00096         }
00098         inline DEG degree(const KEY& k) const
00099         {
00100                 return k.size();
00101         }
00103         inline DEG size(void) const
00104         {
00105                 return _size;
00106         }
00108         inline KEY begin(void) const
00109         {
00110                 return empty_key;
00111         }
00113         inline KEY end(void) const
00114         {
00115                 KEY result; // empty key.
00116                 result.push_back(0); // invalid key.    
00117                 return result;
00118         }
00120         inline KEY nextkey(const KEY& k) const
00121         {
00122                 KEY::size_type i;
00123                 for (i = k.size() - 1; i >= 0; --i)
00124                         if (k[i] < n_letters)
00125                         {
00126                                 KEY result(k);
00127                                 result[i] += 1;
00128                                 return result;
00129                         }
00130                 return end();
00131         }
00133         std::string key2string(const KEY& k) const
00134         {
00135                 std::ostringstream oss;
00136 
00137                 if (k.size() > 0)
00138                 {
00139                         oss << k.FirstLetter();
00140                         KEY kk = k.rparent();
00141                         for (unsigned i = 1; i < k.size(); ++i)
00142                         {
00143                                 oss << "," << kk.FirstLetter();
00144                                 kk = kk.rparent();
00145                         }
00146                 }
00147                 return oss.str();
00148         }
00149 };
00150 
00152 
00163 template<typename SCA, typename RAT, DEG n_letters, DEG max_degree>
00164 class free_tensor_basis : public tensor_basis<SCA, n_letters, max_degree>,
00165                                                   public basis_traits<With_Degree, n_letters, max_degree>
00166 {
00167 public:
00169         typedef tensor_basis<SCA, n_letters, max_degree> TBASIS;
00171         typedef RAT RATIONAL;
00173         typedef free_tensor<SCA, RAT, n_letters, max_degree> TENSOR;
00174 public:
00176         free_tensor_basis(void) {}
00177 public:
00179 
00185         static inline TENSOR prod(const KEY& k1, const KEY& k2)
00186         {
00187                 static SCA one(+1);
00188                 TENSOR result;
00189                 if ((max_degree == 0) || (k1.size() + k2.size() <= max_degree))
00190                 {
00191                         KEY concat = k1 * k2;
00192                         result[concat] = one;
00193                 }
00194                 return result;
00195         }
00197         inline friend
00198                 std::ostream& operator<<(std::ostream& os, const std::pair<free_tensor_basis*, KEY>& t)
00199         {
00200                 return os << (t.first)->key2string(t.second);
00201         }
00202 };
00203 
00205 
00216 template<typename SCA, typename RAT, DEG n_letters, DEG max_degree>
00217 class shuffle_tensor_basis : public tensor_basis<SCA, n_letters, max_degree>,
00218                                                          public basis_traits<With_Degree, n_letters, max_degree>
00219 {
00220 public:
00222         typedef tensor_basis<SCA, n_letters, max_degree> TBASIS;
00224         typedef typename TBASIS::KEY KEY;
00226         typedef typename TBASIS::MAP MAP;
00228         typedef RAT RATIONAL;
00230         typedef shuffle_tensor<SCA, RAT, n_letters, max_degree> TENSOR;
00231 public:
00233         shuffle_tensor_basis(void) {}
00234 public:
00236 
00243         inline const TENSOR& prod(const KEY& k1, const KEY& k2) const
00244         {               
00245                 static boost::recursive_mutex table_access;
00246                 // get exclusive recursive access for the thread 
00247                 boost::lock_guard<boost::recursive_mutex> lock(table_access); 
00248 
00249                 typedef std::map<std::pair<KEY, KEY>, TENSOR> TABLE_T;
00250                 static TABLE_T table;
00251                 typename TABLE_T::iterator it;
00252                 std::pair<KEY, KEY> p(std::min(k1, k2), std::max(k1, k2));
00253                 it = table.find(p);
00254                 if (it == table.end())
00255                         return table[p] = _prod(k1, k2);
00256                 else
00257                         return it->second;
00258         }
00260         inline friend
00261                 std::ostream& operator<<(std::ostream& os, const std::pair<shuffle_tensor_basis*, KEY>& t)
00262         {
00263                 return os << (t.first)->key2string(t.second);
00264         }
00265 private:
00266         
00267         inline void tensor_add_mul(const TENSOR& a, const TENSOR& b, TENSOR& ans) const
00268         {
00269                 sparse_vector<typename free_tensor_basis<SCA, RAT, n_letters, max_degree>,MAP>
00270                 ::const_iterator i, j;
00271                 for (i = a.begin(); i != a.end(); ++i)
00272                         for (j = b.begin(); j != b.end(); ++j)
00273                                 ans.add_scal_prod(free_tensor_prod(i->first, j->first),
00274                                         i->second * j->second);
00275         }
00277 
00283         static inline TENSOR free_tensor_prod(const KEY& k1, const KEY& k2)
00284         {
00285                 static SCA one(+1);
00286                 TENSOR result;
00287                 if ((max_degree == 0) || (k1.size() + k2.size() <= max_degree))
00288                 {
00289                         KEY concat = k1 * k2;
00290                         result[concat] = one;
00291                 }
00292                 return result;
00293         }
00294 
00296         inline TENSOR _prod(const KEY& k1, const KEY& k2) const
00297         {
00298                 TENSOR result;
00299                 unsigned i, j;
00300                 static SCA one(+1);
00301 
00302                 if ((max_degree == 0) || (k1.size() + k2.size() <= max_degree))
00303 
00304                 {
00305                         if (k1.size() == 0)
00306                         {
00307                                 result[k2] = one;
00308                                 return result;
00309                         }
00310                         if (k2.size() == 0)
00311                         {
00312                                 result[k1] = one;
00313                                 return result;
00314                         }
00315                         // k1.size() >= 1 and k2.size() >= 1
00316                         tensor_add_mul((TENSOR)k1.lparent(), prod(k1.rparent(), k2), result);
00317                         tensor_add_mul((TENSOR)k2.lparent(), prod(k1, k2.rparent()), result);
00318                 }
00319                 return result;
00320         }
00321 };
00322 //#endif
00323 
00324 
00325 // Include once wrapper
00326 #endif // DJC_COROPA_LIBALGEBRA_TENSORBASISH_SEEN
00327 
00328 //EOF.

Generated on Fri Jan 14 2011 17:50:33 for Rough Differential Equation Solver by  doxygen 1.7.1