glucat  0.12.0
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-2021 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"
36 #include "glucat/index_set.h"
38 #include "glucat/tuning.h"
39 
40 #if defined(_GLUCAT_USE_BOOST_POOL_ALLOC)
41 // Use the Boost pool allocator
42 #include <boost/pool/poolfwd.hpp>
43 #endif
44 
45 #include <string>
46 #include <utility>
47 #include <map>
48 #include <unordered_map>
49 #include <vector>
50 
51 namespace glucat
52 {
53  // Forward declarations for friends
54 
55  template< typename Scalar_T, const index_t LO, const index_t HI, typename Tune_P >
56  class framed_multi; // forward
57 
58  template< typename Scalar_T, const index_t LO, const index_t HI, typename Tune_P >
59  class matrix_multi; // forward
60 
62  template< typename Scalar_T, const index_t LO, const index_t HI, typename Tune_P >
63  auto
65 
67  template< typename Scalar_T, const index_t LO, const index_t HI, typename Tune_P >
68  auto
70 
72  template< typename Scalar_T, const index_t LO, const index_t HI, typename Tune_P >
73  auto
75 
77  template< typename Scalar_T, const index_t LO, const index_t HI, typename Tune_P >
78  auto
80 
82  template< typename Scalar_T, const index_t LO, const index_t HI, typename Tune_P >
83  auto
85 
87  template< typename Scalar_T, const index_t LO, const index_t HI, typename Tune_P >
88  auto
90 
92  template< typename Scalar_T, const index_t LO, const index_t HI, typename Tune_P >
93  auto
95 
97  template< typename Scalar_T, const index_t LO, const index_t HI, typename Tune_P >
98  auto
99  operator>> (std::istream& s, framed_multi<Scalar_T,LO,HI,Tune_P>& val) -> std::istream&;
100 
102  template< typename Scalar_T, const index_t LO, const index_t HI, typename Tune_P >
103  auto
104  operator<< (std::ostream& os, const framed_multi<Scalar_T,LO,HI,Tune_P>& val) -> std::ostream&;
105 
107  template< typename Scalar_T, const index_t LO, const index_t HI >
108  auto
109  operator<< (std::ostream& os, const std::pair< const index_set<LO,HI>, Scalar_T >& term) -> std::ostream&;
110 
112  template< typename Scalar_T, const index_t LO, const index_t HI, typename Tune_P >
113  auto
115 
116  template< const index_t LO, const index_t HI>
118  {
119  public:
121  inline auto operator()(index_set_t val) const -> size_t { return val.hash_fn(); }
122  };
123 
125  template< typename Scalar_T = double, const index_t LO = DEFAULT_LO, const index_t HI = DEFAULT_HI, typename Tune_P = tuning<> >
126  class framed_multi :
127  public clifford_algebra< Scalar_T, index_set<LO,HI>, framed_multi<Scalar_T,LO,HI,Tune_P> >,
128  private std::unordered_map< index_set<LO,HI>, Scalar_T, index_set_hash<LO,HI> >
129  {
130  public:
133  using scalar_t = Scalar_T;
134  using tune_p = Tune_P;
136  using term_t = std::pair<const index_set_t, Scalar_T>;
137  using vector_t = std::vector<Scalar_T>;
140  template< typename Other_Scalar_T, const index_t Other_LO, const index_t Other_HI, typename Other_Tune_P >
141  friend class matrix_multi;
142  template< typename Other_Scalar_T, const index_t Other_LO, const index_t Other_HI, typename Other_Tune_P >
143  friend class framed_multi;
144 
145  private:
146  class var_term; // forward
147  using var_term_t = class var_term;
149  using sorted_map_t = std::map< index_set_t, Scalar_T, std::less<const index_set_t> >;
150  using map_t = std::unordered_map<index_set_t, Scalar_T, index_set_hash<LO, HI>>;
151 
153  {
154  public:
155  hash_size_t(size_t hash_size)
156  : n(hash_size)
157  { };
158  auto operator()() const -> size_t
159  { return n; }
160  private:
161  size_t n;
162  };
163 
164  using framed_pair_t = std::pair<const multivector_t, const multivector_t>;
165  using size_type = typename map_t::size_type;
166  using iterator = typename map_t::iterator;
167  using const_iterator = typename map_t::const_iterator;
168 
169  public:
171  static auto classname() -> const std::string;
173  ~framed_multi() override = default;
175  framed_multi();
176 
177  private:
179  framed_multi(const hash_size_t& hash_size);
180  public:
182  template< typename Other_Scalar_T >
185  template< typename Other_Scalar_T >
187  const index_set_t frm, const bool prechecked = false);
189  framed_multi(const framed_multi_t& val,
190  const index_set_t frm, const bool prechecked = false);
192  framed_multi(const index_set_t ist, const Scalar_T& crd = Scalar_T(1));
194  framed_multi(const index_set_t ist, const Scalar_T& crd,
195  const index_set_t frm, const bool prechecked = false);
197  framed_multi(const Scalar_T& scr, const index_set_t frm = index_set_t());
199  framed_multi(const int scr, const index_set_t frm = index_set_t());
201  framed_multi(const vector_t& vec,
202  const index_set_t frm, const bool prechecked = false);
204  framed_multi(const std::string& str);
206  framed_multi(const std::string& str,
207  const index_set_t frm, const bool prechecked = false);
209  framed_multi(const char* str)
210  { *this = framed_multi(std::string(str)); };
212  framed_multi(const char* str,
213  const index_set_t frm, const bool prechecked = false)
214  { *this = framed_multi(std::string(str), frm, prechecked); };
216  template< typename Other_Scalar_T >
219  template< typename Other_Scalar_T >
222  auto fast_framed_multi() const -> const framed_multi_t;
223 
225 
227  auto nbr_terms() const -> unsigned long;
228 
230  static auto random(const index_set_t frm, Scalar_T fill = Scalar_T(1)) -> const multivector_t;
231 
232  // Friend declarations
233 
234  friend auto
235  operator* <>(const multivector_t& lhs, const multivector_t& rhs) -> const multivector_t;
236  friend auto
237  operator^ <>(const multivector_t& lhs, const multivector_t& rhs) -> const multivector_t;
238  friend auto
239  operator& <>(const multivector_t& lhs, const multivector_t& rhs) -> const multivector_t;
240  friend auto
241  operator% <>(const multivector_t& lhs, const multivector_t& rhs) -> const multivector_t;
242  friend auto
243  star <>(const multivector_t& lhs, const multivector_t& rhs) -> Scalar_T;
244  friend auto
245  operator/ <>(const multivector_t& lhs, const multivector_t& rhs) -> const multivector_t;
246  friend auto
247  operator| <>(const multivector_t& lhs, const multivector_t& rhs) -> const multivector_t;
248 
249  friend auto
250  operator>> <>(std::istream& s, multivector_t& val) -> std::istream&;
251  friend auto
252  operator<< <>(std::ostream& os, const multivector_t& val) -> std::ostream&;
253  friend auto
254  operator<< <>(std::ostream& os, const term_t& term) -> std::ostream&;
255 
256  friend auto
257  exp <>(const multivector_t& val) -> const multivector_t;
258 
260  auto operator+= (const term_t& term) -> multivector_t&;
261 
262  private:
264  auto fold(const index_set_t frm) const -> multivector_t;
266  auto unfold(const index_set_t frm) const -> multivector_t;
268  auto centre_pm4_qp4(index_t& p, index_t& q) -> multivector_t&;
270  auto centre_pp4_qm4(index_t& p, index_t& q) -> multivector_t&;
272  auto centre_qp1_pm1(index_t& p, index_t& q) -> multivector_t&;
274  auto divide(const index_set_t ist) const -> const framed_pair_t;
276  auto fast(const index_t level, const bool odd) const -> const matrix_t;
277 
279  class var_term :
280  public std::pair<index_set<LO,HI>, Scalar_T>
281  {
282  public:
283  using var_pair_t = std::pair<index_set<LO, HI>, Scalar_T>;
284 
286  static auto classname() -> const std::string
287  { return "var_term"; };
289  ~var_term() = default;
292  : var_pair_t(index_set_t(), Scalar_T(1))
293  { };
295  var_term(const index_set_t ist, const Scalar_T& crd = Scalar_T(1))
296  : var_pair_t(ist, crd)
297  { };
299  auto operator*= (const term_t& rhs) -> var_term_t&
300  {
301  this->second *= rhs.second * this->first.sign_of_mult(rhs.first);
302  this->first ^= rhs.first;
303  return *this;
304  }
305  };
306  };
307 
308  // Non-members
309 
311  template< typename Scalar_T, const index_t LO, const index_t HI >
312  inline
313  static
314  auto
315  crd_of_mult(const std::pair<const index_set<LO,HI>, Scalar_T>& lhs,
316  const std::pair<const index_set<LO,HI>, Scalar_T>& rhs) -> Scalar_T;
317 
319  template< typename Scalar_T, const index_t LO, const index_t HI >
320  auto
321  operator*
322  (const std::pair<const index_set<LO,HI>, Scalar_T>& lhs,
323  const std::pair<const index_set<LO,HI>, Scalar_T>& rhs) -> const std::pair<const index_set<LO,HI>, Scalar_T>;
324 
326  template< typename Scalar_T, const index_t LO, const index_t HI, typename Tune_P >
327  auto
328  sqrt(const framed_multi<Scalar_T,LO,HI,Tune_P>& val, const framed_multi<Scalar_T,LO,HI,Tune_P>& i, bool prechecked) -> const framed_multi<Scalar_T,LO,HI,Tune_P>;
329 
331  template< typename Scalar_T, const index_t LO, const index_t HI, typename Tune_P >
332  auto
333  exp(const framed_multi<Scalar_T,LO,HI,Tune_P>& val) -> const framed_multi<Scalar_T,LO,HI,Tune_P>;
334 
336  template< typename Scalar_T, const index_t LO, const index_t HI, typename Tune_P >
337  auto
338  log(const framed_multi<Scalar_T,LO,HI,Tune_P>& val, const framed_multi<Scalar_T,LO,HI,Tune_P>& i, bool prechecked) -> const framed_multi<Scalar_T,LO,HI,Tune_P>;
339 }
340 
341 namespace std
342 {
344  template < typename Scalar_T, const glucat::index_t LO, const glucat::index_t HI, typename Tune_P >
345  struct numeric_limits< glucat::framed_multi<Scalar_T,LO,HI,Tune_P> > :
346  public numeric_limits<Scalar_T>
347  { };
348 }
349 #endif // _GLUCAT_FRAMED_MULTI_H
virtual auto operator*=(const Scalar_T &scr) -> multivector_t &=0
Product of multivector and scalar.
std::pair< const multivector_t, const multivector_t > framed_pair_t
Definition: framed_multi.h:164
auto operator%(const Multivector< Scalar_T, LO, HI, Tune_P > &lhs, const RHS< Scalar_T, LO, HI, Tune_P > &rhs) -> const Multivector< Scalar_T, LO, HI, Tune_P >
Left contraction.
auto operator^(const Multivector< Scalar_T, LO, HI, Tune_P > &lhs, const RHS< Scalar_T, LO, HI, Tune_P > &rhs) -> const Multivector< Scalar_T, LO, HI, Tune_P >
Outer product.
auto unfold(const index_set_t frm) const -> multivector_t
Subalgebra isomorphism: unfold each term within the given frame.
~framed_multi() override=default
Destructor.
auto exp(const framed_multi< Scalar_T, LO, HI, Tune_P > &val) -> const framed_multi< Scalar_T, LO, HI, Tune_P >
Exponential of multivector.
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:212
A framed_multi<Scalar_T,LO,HI,Tune_P> is a framed approximation to a multivector. ...
Definition: framed_multi.h:56
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:295
std::pair< index_set< LO, HI >, Scalar_T > var_pair_t
Definition: framed_multi.h:283
auto fold(const index_set_t frm) const -> multivector_t
Subalgebra isomorphism: fold each term within the given frame.
auto centre_pm4_qp4(index_t &p, index_t &q) -> multivector_t &
Subalgebra isomorphism: R_{p,q} to R_{p-4,q+4}.
auto operator()(index_set_t val) const -> size_t
Definition: framed_multi.h:121
index_set< LO, HI > index_set_t
Definition: framed_multi.h:135
auto star(const Multivector< Scalar_T, LO, HI, Tune_P > &lhs, const RHS< Scalar_T, LO, HI, Tune_P > &rhs) -> Scalar_T
Hestenes scalar product.
typename matrix_multi_t::matrix_t matrix_t
Definition: framed_multi.h:148
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:209
auto log(const Multivector< Scalar_T, LO, HI, Tune_P > &val, const Multivector< Scalar_T, LO, HI, Tune_P > &i, const bool prechecked=false) -> const Multivector< Scalar_T, LO, HI, Tune_P >
Natural logarithm of multivector with specified complexifier.
auto fast_framed_multi() const -> const framed_multi_t
Use inverse generalized FFT to construct a framed_multi_t.
A matrix_multi<Scalar_T,LO,HI,Tune_P> is a matrix approximation to a multivector. ...
Definition: framed_multi.h:59
ublas::matrix< Scalar_T, orientation_t > matrix_t
Definition: matrix_multi.h:158
std::map< index_set_t, Scalar_T, std::less< const index_set_t > > sorted_map_t
Definition: framed_multi.h:149
auto operator>>(std::istream &s, framed_multi< Scalar_T, LO, HI, Tune_P > &val) -> std::istream &
Read multivector from input.
class var_term var_term_t
Definition: framed_multi.h:147
var_term()
Default constructor.
Definition: framed_multi.h:291
static auto 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) -> Scalar_T
Coordinate of product of terms.
std::vector< Scalar_T > vector_t
Definition: framed_multi.h:137
multivector_t framed_multi_t
Definition: framed_multi.h:132
typename map_t::const_iterator const_iterator
Definition: framed_multi.h:167
std::unordered_map< index_set_t, Scalar_T, index_set_hash< LO, HI > > map_t
Definition: framed_multi.h:150
friend auto exp(const multivector_t &val) -> const multivector_t
auto operator &(const Multivector< Scalar_T, LO, HI, Tune_P > &lhs, const RHS< Scalar_T, LO, HI, Tune_P > &rhs) -> const Multivector< Scalar_T, LO, HI, Tune_P >
Inner product.
_GLUCAT_CLIFFORD_ALGEBRA_OPERATIONS auto nbr_terms() const -> unsigned long
Number of terms.
auto centre_qp1_pm1(index_t &p, index_t &q) -> multivector_t &
Subalgebra isomorphism: R_{p,q} to R_{q+1,p-1}.
auto operator*(const Multivector< Scalar_T, LO, HI, Tune_P > &lhs, const Scalar_T &scr) -> const Multivector< Scalar_T, LO, HI, Tune_P >
Product of multivector and scalar.
virtual auto odd() const -> const multivector_t=0
Odd part of multivector, sum of odd grade terms.
auto operator()() const -> size_t
Definition: framed_multi.h:158
auto centre_pp4_qm4(index_t &p, index_t &q) -> multivector_t &
Subalgebra isomorphism: R_{p,q} to R_{p+4,q-4}.
Specific exception class.
Definition: errors.h:56
auto divide(const index_set_t ist) const -> const framed_pair_t
Divide multivector into part divisible by index_set and remainder.
framed_multi()
Default constructor.
auto fast_matrix_multi(const index_set_t frm) const -> const matrix_multi< Other_Scalar_T, LO, HI, Tune_P >
Use generalized FFT to construct a matrix_multi_t.
friend auto star(const multivector_t &lhs, const multivector_t &rhs) -> Scalar_T
int index_t
Size of index_t should be enough to represent LO, HI.
Definition: global.h:77
auto sqrt(const Multivector< Scalar_T, LO, HI, Tune_P > &val, const Multivector< Scalar_T, LO, HI, Tune_P > &i, const bool prechecked=false) -> const Multivector< Scalar_T, LO, HI, Tune_P >
Square root of multivector with specified complexifier.
Index set class based on std::bitset<> in Gnu standard C++ library.
Definition: index_set.h:45
typename map_t::iterator iterator
Definition: framed_multi.h:166
static auto classname() -> const std::string
Class name used in messages.
Definition: framed_multi.h:286
auto operator/(const Multivector< Scalar_T, LO, HI, Tune_P > &lhs, const Scalar_T &scr) -> const Multivector< Scalar_T, LO, HI, Tune_P >
Quotient of multivector and scalar.
static auto classname() -> const std::string
Class name used in messages.
auto fast(const index_t level, const bool odd) const -> const matrix_t
Generalized FFT from multivector_t to matrix_t.
static auto random(const index_set_t frm, Scalar_T fill=Scalar_T(1)) -> const multivector_t
Random multivector within a frame.
typename map_t::size_type size_type
Definition: framed_multi.h:165
framed_multi multivector_t
Definition: framed_multi.h:131
std::pair< const index_set_t, Scalar_T > term_t
Definition: framed_multi.h:136
#define _GLUCAT_CLIFFORD_ALGEBRA_OPERATIONS
auto operator|(const Multivector< Scalar_T, LO, HI, Tune_P > &lhs, const RHS< Scalar_T, LO, HI, Tune_P > &rhs) -> const Multivector< Scalar_T, LO, HI, Tune_P >
Transformation via twisted adjoint action.