glucat  0.8.2
framed_multi.h
Go to the documentation of this file.
1 #ifndef _GLUCAT_FRAMED_MULTI_H
2 #define _GLUCAT_FRAMED_MULTI_H
3 /***************************************************************************
4  GluCat : Generic library of universal Clifford algebra templates
5  framed_multi.h : Declare a class for the framed representation of a multivector
6  -------------------
7  begin : Sun 2001-12-09
8  copyright : (C) 2001-2016 by Paul C. Leopardi
9  ***************************************************************************
10 
11  This library is free software: you can redistribute it and/or modify
12  it under the terms of the GNU Lesser General Public License as published
13  by the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  This library is distributed in the hope that it will be useful,
17  but WITHOUT ANY WARRANTY; without even the implied warranty of
18  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  GNU Lesser General Public License for more details.
20 
21  You should have received a copy of the GNU Lesser General Public License
22  along with this library. If not, see <http://www.gnu.org/licenses/>.
23 
24  ***************************************************************************
25  This library is based on a prototype written by Arvind Raja and was
26  licensed under the LGPL with permission of the author. See Arvind Raja,
27  "Object-oriented implementations of Clifford algebras in C++: a prototype",
28  in Ablamowicz, Lounesto and Parra (eds.)
29  "Clifford algebras with numeric and symbolic computations", Birkhauser, 1996.
30  ***************************************************************************
31  See also Arvind Raja's original header comments in glucat.h
32  ***************************************************************************/
33 
34 #include "glucat/global.h"
35 #include "glucat/errors.h"
37 
38 #if defined(_GLUCAT_USE_BOOST_POOL_ALLOC)
39 // Use the Boost pool allocator
40 #include <boost/pool/poolfwd.hpp>
41 #endif
42 
43 #include <string>
44 #include <utility>
45 #include <map>
46 #include <vector>
47 
48 // Use the appropriate type of map
49 
50 #if defined(_GLUCAT_USE_STD_UNORDERED_MAP)
51 # include <unordered_map>
52 #endif
53 
54 #if defined(_GLUCAT_USE_STD_UNORDERED_MAP)
55 # define _GLUCAT_MAP_IS_HASH
56 #else
57 # define _GLUCAT_MAP_IS_ORDERED
58 #endif
59 
60 namespace glucat
61 {
62  // Forward declarations for friends
63 
64  template< typename Scalar_T, const index_t LO, const index_t HI >
65  class framed_multi; // forward
66 
67  template< typename Scalar_T, const index_t LO, const index_t HI >
68  class matrix_multi; // forward
69 
71  template< typename Scalar_T, const index_t LO, const index_t HI >
74 
76  template< typename Scalar_T, const index_t LO, const index_t HI >
79 
81  template< typename Scalar_T, const index_t LO, const index_t HI >
84 
86  template< typename Scalar_T, const index_t LO, const index_t HI >
89 
91  template< typename Scalar_T, const index_t LO, const index_t HI >
92  Scalar_T
94 
96  template< typename Scalar_T, const index_t LO, const index_t HI >
99 
101  template< typename Scalar_T, const index_t LO, const index_t HI >
104 
106  template< typename Scalar_T, const index_t LO, const index_t HI >
107  std::istream&
108  operator>> (std::istream& s, framed_multi<Scalar_T,LO,HI>& val);
109 
111  template< typename Scalar_T, const index_t LO, const index_t HI >
112  std::ostream&
113  operator<< (std::ostream& os, const framed_multi<Scalar_T,LO,HI>& val);
114 
116  template< typename Scalar_T, const index_t LO, const index_t HI >
117  std::ostream&
118  operator<< (std::ostream& os, const std::pair< const index_set<LO,HI>, Scalar_T >& term);
119 
121  template< typename Scalar_T, const index_t LO, const index_t HI >
123  exp(const framed_multi<Scalar_T,LO,HI>& val);
124 
125  template< const index_t LO, const index_t HI>
127  {
128  public:
130  inline size_t operator()(index_set_t val) const { return val.hash_fn(); }
131  };
132 
134  template< typename Scalar_T = double, const index_t LO = DEFAULT_LO, const index_t HI = DEFAULT_HI >
135  class framed_multi :
136  public clifford_algebra< Scalar_T, index_set<LO,HI>, framed_multi<Scalar_T,LO,HI> >,
137 #if defined(_GLUCAT_USE_STD_UNORDERED_MAP)
138  private std::unordered_map< index_set<LO,HI>, Scalar_T, index_set_hash<LO,HI> >
139 #else
140  private std::map< index_set<LO,HI>, Scalar_T,
141  std::less< const index_set<LO,HI> >
142 #if defined(_GLUCAT_USE_BOOST_POOL_ALLOC)
143  , boost::fast_pool_allocator< std::pair<const index_set<LO,HI>, Scalar_T> >
144 #endif
145  >
146 #endif
147  {
148  public:
150  typedef multivector_t framed_multi_t;
151  typedef Scalar_T scalar_t;
153  typedef std::pair<const index_set_t, Scalar_T> term_t;
154  typedef std::vector<Scalar_T> vector_t;
157  template< typename Other_Scalar_T, const index_t Other_LO, const index_t Other_HI >
158  friend class matrix_multi;
159  template< typename Other_Scalar_T, const index_t Other_LO, const index_t Other_HI >
160  friend class framed_multi;
161 
162  private:
163  class var_term; // forward
164  typedef class var_term var_term_t;
166  typedef std::map< index_set_t, Scalar_T,
167  std::less<const index_set_t>
168 #if defined(_GLUCAT_USE_BOOST_POOL_ALLOC)
169  , boost::fast_pool_allocator<term_t>
170 #endif
171  >
173 #if defined(_GLUCAT_USE_STD_UNORDERED_MAP)
174  typedef std::unordered_map< index_set_t, Scalar_T, index_set_hash<LO,HI> >
176 #else
177  typedef sorted_map_t map_t;
178 #endif
179 
181  {
182  public:
183  hash_size_t(size_t hash_size)
184  : n(hash_size)
185  { };
186  size_t operator()() const
187  { return n; }
188  private:
189  size_t n;
190  };
191 
192  typedef std::pair< const multivector_t, const multivector_t >
194  typedef typename map_t::size_type size_type;
195  typedef typename map_t::iterator iterator;
196  typedef typename map_t::const_iterator const_iterator;
197 
198  public:
200  static const std::string classname();
204  framed_multi();
205 
206  private:
208  framed_multi(const hash_size_t& hash_size);
209  public:
211  template< typename Other_Scalar_T >
214  template< typename Other_Scalar_T >
216  const index_set_t frm, const bool prechecked = false);
218  framed_multi(const framed_multi_t& val,
219  const index_set_t frm, const bool prechecked = false);
221  framed_multi(const index_set_t ist, const Scalar_T& crd = Scalar_T(1));
223  framed_multi(const index_set_t ist, const Scalar_T& crd,
224  const index_set_t frm, const bool prechecked = false);
226  framed_multi(const Scalar_T& scr, const index_set_t frm = index_set_t());
228  framed_multi(const int scr, const index_set_t frm = index_set_t());
230  framed_multi(const vector_t& vec,
231  const index_set_t frm, const bool prechecked = false);
233  framed_multi(const std::string& str);
235  framed_multi(const std::string& str,
236  const index_set_t frm, const bool prechecked = false);
238  framed_multi(const char* str)
239  { *this = framed_multi(std::string(str)); };
241  framed_multi(const char* str,
242  const index_set_t frm, const bool prechecked = false)
243  { *this = framed_multi(std::string(str), frm, prechecked); };
245  template< typename Other_Scalar_T >
248  template< typename Other_Scalar_T >
249  const matrix_multi<Other_Scalar_T,LO,HI> fast_matrix_multi(const index_set_t frm) const;
251  const framed_multi_t fast_framed_multi() const;
252 
254 
256  unsigned long nbr_terms() const;
257 
259  static const framed_multi_t random(const index_set_t frm, Scalar_T fill = Scalar_T(1));
260 
261  // Friend declarations
262 
263  friend const framed_multi_t
264  operator* <>(const framed_multi_t& lhs, const framed_multi_t& rhs);
265  friend const framed_multi_t
266  operator^ <>(const framed_multi_t& lhs, const framed_multi_t& rhs);
267  friend const framed_multi_t
268  operator& <>(const framed_multi_t& lhs, const framed_multi_t& rhs);
269  friend const framed_multi_t
270  operator% <>(const framed_multi_t& lhs, const framed_multi_t& rhs);
271  friend Scalar_T
272  star <>(const framed_multi_t& lhs, const framed_multi_t& rhs);
273  friend const framed_multi_t
274  operator/ <>(const framed_multi_t& lhs, const framed_multi_t& rhs);
275  friend const framed_multi_t
276  operator| <>(const framed_multi_t& lhs, const framed_multi_t& rhs);
277 
278  friend std::istream&
279  operator>> <>(std::istream& s, multivector_t& val);
280  friend std::ostream&
281  operator<< <>(std::ostream& os, const multivector_t& val);
282  friend std::ostream&
283  operator<< <>(std::ostream& os, const term_t& term);
284 
285  friend const framed_multi_t
286  exp <>(const framed_multi_t& val);
287 
289  multivector_t& operator+= (const term_t& term);
290 
291  private:
293  multivector_t fold(const index_set_t frm) const;
295  multivector_t unfold(const index_set_t frm) const;
297  multivector_t& centre_pm4_qp4(index_t& p, index_t& q);
299  multivector_t& centre_pp4_qm4(index_t& p, index_t& q);
301  multivector_t& centre_qp1_pm1(index_t& p, index_t& q);
303  const framed_pair_t divide(const index_set_t ist) const;
305  const matrix_t fast(const index_t level, const bool odd) const;
306 
308  class var_term :
309  public std::pair<index_set<LO,HI>, Scalar_T>
310  {
311  public:
312  typedef std::pair<index_set<LO,HI>, Scalar_T> var_pair_t;
313 
315  static const std::string classname()
316  { return "var_term"; };
318  ~var_term() {};
321  : var_pair_t(index_set_t(), Scalar_T(1))
322  { };
324  var_term(const index_set_t ist, const Scalar_T& crd = Scalar_T(1))
325  : var_pair_t(ist, crd)
326  { };
328  var_term_t& operator*= (const term_t& rhs)
329  {
330  this->second *= rhs.second * this->first.sign_of_mult(rhs.first);
331  this->first ^= rhs.first;
332  return *this;
333  }
334  };
335  };
336 
337  // Non-members
338 
340  template< typename Scalar_T, const index_t LO, const index_t HI >
341  inline
342  static
343  Scalar_T
344  crd_of_mult(const std::pair<const index_set<LO,HI>, Scalar_T>& lhs,
345  const std::pair<const index_set<LO,HI>, Scalar_T>& rhs);
346 
348  template< typename Scalar_T, const index_t LO, const index_t HI >
349  const std::pair<const index_set<LO,HI>, Scalar_T>
350  operator*
351  (const std::pair<const index_set<LO,HI>, Scalar_T>& lhs,
352  const std::pair<const index_set<LO,HI>, Scalar_T>& rhs);
353 
355  template< typename Scalar_T, const index_t LO, const index_t HI >
357  sqrt(const framed_multi<Scalar_T,LO,HI>& val, const framed_multi<Scalar_T,LO,HI>& i, bool prechecked);
358 
360  template< typename Scalar_T, const index_t LO, const index_t HI >
362  exp(const framed_multi<Scalar_T,LO,HI>& val);
363 
365  template< typename Scalar_T, const index_t LO, const index_t HI >
367  log(const framed_multi<Scalar_T,LO,HI>& val, const framed_multi<Scalar_T,LO,HI>& i, bool prechecked);
368 }
369 
370 namespace std
371 {
373  template <typename Scalar_T, const glucat::index_t LO, const glucat::index_t HI>
374  struct numeric_limits< glucat::framed_multi<Scalar_T,LO,HI> > :
375  public numeric_limits<Scalar_T>
376  { };
377 }
378 #endif // _GLUCAT_FRAMED_MULTI_H
index_set< LO, HI > index_set_t
Definition: framed_multi.h:152
static Scalar_T crd_of_mult(const std::pair< const index_set< LO, HI >, Scalar_T > &lhs, const std::pair< const index_set< LO, HI >, Scalar_T > &rhs)
Coordinate of product of terms.
static Multivector_T fast(const Matrix_T &X, index_t level)
Inverse generalized Fast Fourier Transform.
Scalar_T star(const Multivector< Scalar_T, LO, HI > &lhs, const RHS< Scalar_T, LO, HI > &rhs)
Hestenes scalar product.
class var_term var_term_t
Definition: framed_multi.h:164
const Multivector< Scalar_T, LO, HI > sqrt(const Multivector< Scalar_T, LO, HI > &val, const Multivector< Scalar_T, LO, HI > &i, const bool prechecked=false)
Square root of multivector with specified complexifier.
matrix_multi_t::matrix_t matrix_t
Definition: framed_multi.h:165
map_t::size_type size_type
Definition: framed_multi.h:194
const Multivector< Scalar_T, LO, HI > operator/(const Multivector< Scalar_T, LO, HI > &lhs, const Scalar_T &scr)
Quotient of multivector and scalar.
~framed_multi()
Destructor.
Definition: framed_multi.h:202
const Multivector< Scalar_T, LO, HI > operator*(const Multivector< Scalar_T, LO, HI > &lhs, const Scalar_T &scr)
Product of multivector and scalar.
A framed_multi<Scalar_T,LO,HI> is a framed approximation to a multivector.
Definition: framed_multi.h:65
framed_multi multivector_t
Definition: framed_multi.h:149
const Multivector< Scalar_T, LO, HI > log(const Multivector< Scalar_T, LO, HI > &val, const Multivector< Scalar_T, LO, HI > &i, const bool prechecked=false)
Natural logarithm of multivector with specified complexifier.
map_t::const_iterator const_iterator
Definition: framed_multi.h:196
clifford_algebra<> declares the operations of a Clifford algebra
std::vector< Scalar_T > vector_t
Definition: framed_multi.h:154
const Multivector< Scalar_T, LO, HI > operator&(const Multivector< Scalar_T, LO, HI > &lhs, const RHS< Scalar_T, LO, HI > &rhs)
Inner product.
map_t::iterator iterator
Definition: framed_multi.h:195
size_t operator()(index_set_t val) const
Definition: framed_multi.h:130
const Multivector< Scalar_T, LO, HI > odd(const Multivector< Scalar_T, LO, HI > &val)
Odd part.
index_set< LO, HI > index_set_t
Definition: framed_multi.h:129
var_term()
Default constructor.
Definition: framed_multi.h:320
std::pair< const multivector_t, const multivector_t > framed_pair_t
Definition: framed_multi.h:193
A matrix_multi<Scalar_T,LO,HI> is a matrix approximation to a multivector.
Definition: framed_multi.h:68
const Multivector< Scalar_T, LO, HI > operator^(const Multivector< Scalar_T, LO, HI > &lhs, const RHS< Scalar_T, LO, HI > &rhs)
Outer product.
const framed_multi< Scalar_T, LO, HI > exp(const framed_multi< Scalar_T, LO, HI > &val)
Exponential of multivector.
std::unordered_map< index_set_t, Scalar_T, index_set_hash< LO, HI > > map_t
Definition: framed_multi.h:175
static const std::string classname()
Class name used in messages.
Definition: framed_multi.h:315
std::pair< const index_set_t, Scalar_T > term_t
Definition: framed_multi.h:153
var_term(const index_set_t ist, const Scalar_T &crd=Scalar_T(1))
Construct a variable term from an index set and a scalar coordinate.
Definition: framed_multi.h:324
const Multivector< Scalar_T, LO, HI > operator%(const Multivector< Scalar_T, LO, HI > &lhs, const RHS< Scalar_T, LO, HI > &rhs)
Left contraction.
ublas::compressed_matrix< Scalar_T, orientation_t > matrix_t
Definition: matrix_multi.h:157
Specific exception class.
Definition: errors.h:57
framed_multi(const char *str, const index_set_t frm, const bool prechecked=false)
Construct a multivector, within a given frame, from a char*: eg: "3+2{1,2}-6.1e-2{2,3}".
Definition: framed_multi.h:241
error< multivector_t > error_t
Definition: framed_multi.h:155
Index set class based on std::bitset<> in Gnu standard C++ library.
Definition: index_set.h:45
size_t hash_fn() const
Hash function.
const Multivector< Scalar_T, LO, HI > operator|(const Multivector< Scalar_T, LO, HI > &lhs, const RHS< Scalar_T, LO, HI > &rhs)
Transformation via twisted adjoint action.
std::pair< index_set< LO, HI >, Scalar_T > var_pair_t
Definition: framed_multi.h:312
framed_multi(const char *str)
Construct a multivector from a char*: eg: "3+2{1,2}-6.1e-2{2,3}".
Definition: framed_multi.h:238
matrix_multi< Scalar_T, LO, HI > matrix_multi_t
Definition: framed_multi.h:156
int index_t
Size of index_t should be enough to represent LO, HI.
Definition: global.h:77
std::istream & operator>>(std::istream &s, framed_multi< Scalar_T, LO, HI > &val)
Read multivector from input.
multivector_t framed_multi_t
Definition: framed_multi.h:150
#define _GLUCAT_CLIFFORD_ALGEBRA_OPERATIONS
std::map< index_set_t, Scalar_T, std::less< const index_set_t > > sorted_map_t
Definition: framed_multi.h:172