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
51namespace 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
64 operator* (const framed_multi<Scalar_T,LO,HI,Tune_P>& lhs, const framed_multi<Scalar_T,LO,HI,Tune_P>& rhs) -> const framed_multi<Scalar_T,LO,HI,Tune_P>;
65
67 template< typename Scalar_T, const index_t LO, const index_t HI, typename Tune_P >
68 auto
69 operator^ (const framed_multi<Scalar_T,LO,HI,Tune_P>& lhs, const framed_multi<Scalar_T,LO,HI,Tune_P>& rhs) -> const framed_multi<Scalar_T,LO,HI,Tune_P>;
70
72 template< typename Scalar_T, const index_t LO, const index_t HI, typename Tune_P >
73 auto
74 operator& (const framed_multi<Scalar_T,LO,HI,Tune_P>& lhs, const framed_multi<Scalar_T,LO,HI,Tune_P>& rhs) -> const framed_multi<Scalar_T,LO,HI,Tune_P>;
75
77 template< typename Scalar_T, const index_t LO, const index_t HI, typename Tune_P >
78 auto
79 operator% (const framed_multi<Scalar_T,LO,HI,Tune_P>& lhs, const framed_multi<Scalar_T,LO,HI,Tune_P>& rhs) -> const framed_multi<Scalar_T,LO,HI,Tune_P>;
80
82 template< typename Scalar_T, const index_t LO, const index_t HI, typename Tune_P >
83 auto
84 star(const framed_multi<Scalar_T,LO,HI,Tune_P>& lhs, const framed_multi<Scalar_T,LO,HI,Tune_P>& rhs) -> Scalar_T;
85
87 template< typename Scalar_T, const index_t LO, const index_t HI, typename Tune_P >
88 auto
89 operator/ (const framed_multi<Scalar_T,LO,HI,Tune_P>& lhs, const framed_multi<Scalar_T,LO,HI,Tune_P>& rhs) -> const framed_multi<Scalar_T,LO,HI,Tune_P>;
90
92 template< typename Scalar_T, const index_t LO, const index_t HI, typename Tune_P >
93 auto
94 operator| (const framed_multi<Scalar_T,LO,HI,Tune_P>& lhs, const framed_multi<Scalar_T,LO,HI,Tune_P>& rhs) -> const framed_multi<Scalar_T,LO,HI,Tune_P>;
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
114 exp(const framed_multi<Scalar_T,LO,HI,Tune_P>& val) -> const framed_multi<Scalar_T,LO,HI,Tune_P>;
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<> >
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;
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
329
331 template< typename Scalar_T, const index_t LO, const index_t HI, typename Tune_P >
332 auto
334
336 template< typename Scalar_T, const index_t LO, const index_t HI, typename Tune_P >
337 auto
339}
340
341namespace 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
clifford_algebra<> declares the operations of a Clifford algebra
virtual auto odd() const -> const multivector_t=0
Odd part of multivector, sum of odd grade terms.
virtual auto operator*=(const Scalar_T &scr) -> multivector_t &=0
Product of multivector and scalar.
Specific exception class.
Definition errors.h:57
auto operator()() const -> size_t
static auto classname() -> const std::string
Class name used in messages.
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.
std::pair< index_set< LO, HI >, Scalar_T > var_pair_t
var_term()
Default constructor.
~var_term()=default
Destructor.
A framed_multi<Scalar_T,LO,HI,Tune_P> is a framed approximation to a multivector.
auto divide(const index_set_t ist) const -> const framed_pair_t
Divide multivector into part divisible by index_set and remainder.
auto fast(const index_t level, const bool odd) const -> const matrix_t
Generalized FFT from multivector_t to matrix_t.
friend class framed_multi
typename map_t::const_iterator const_iterator
framed_multi multivector_t
std::vector< Scalar_T > vector_t
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.
std::unordered_map< index_set_t, Scalar_T, index_set_hash< LO, HI > > map_t
index_set< LO, HI > index_set_t
std::pair< const multivector_t, const multivector_t > framed_pair_t
auto centre_pm4_qp4(index_t &p, index_t &q) -> multivector_t &
Subalgebra isomorphism: R_{p,q} to R_{p-4,q+4}.
typename matrix_multi_t::matrix_t matrix_t
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,...
auto fold(const index_set_t frm) const -> multivector_t
Subalgebra isomorphism: fold each term within the given frame.
friend auto star(const multivector_t &lhs, const multivector_t &rhs) -> Scalar_T
class var_term var_term_t
~framed_multi() override=default
Destructor.
static auto random(const index_set_t frm, Scalar_T fill=Scalar_T(1)) -> const multivector_t
Random multivector within a frame.
multivector_t framed_multi_t
auto centre_qp1_pm1(index_t &p, index_t &q) -> multivector_t &
Subalgebra isomorphism: R_{p,q} to R_{q+1,p-1}.
framed_multi(const char *str)
Construct a multivector from a char*: eg: "3+2{1,2}-6.1e-2{2,3}".
auto fast_framed_multi() const -> const framed_multi_t
Use inverse generalized FFT to construct a framed_multi_t.
friend auto exp(const multivector_t &val) -> const multivector_t
auto unfold(const index_set_t frm) const -> multivector_t
Subalgebra isomorphism: unfold each term within the given frame.
static auto classname() -> const std::string
Class name used in messages.
typename map_t::size_type size_type
typename map_t::iterator iterator
std::map< index_set_t, Scalar_T, std::less< const index_set_t > > sorted_map_t
auto centre_pp4_qm4(index_t &p, index_t &q) -> multivector_t &
Subalgebra isomorphism: R_{p,q} to R_{p+4,q-4}.
std::pair< const index_set_t, Scalar_T > term_t
_GLUCAT_CLIFFORD_ALGEBRA_OPERATIONS auto nbr_terms() const -> unsigned long
Number of terms.
auto operator()(index_set_t val) const -> size_t
Index set class based on std::bitset<> in Gnu standard C++ library.
Definition index_set.h:75
A matrix_multi<Scalar_T,LO,HI,Tune_P> is a matrix approximation to a multivector.
ublas::matrix< Scalar_T, orientation_t > matrix_t
#define _GLUCAT_CLIFFORD_ALGEBRA_OPERATIONS
auto operator<<(std::ostream &os, const framed_multi< Scalar_T, LO, HI, Tune_P > &val) -> std::ostream &
Write multivector to output.
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.
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.
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.
auto exp(const framed_multi< Scalar_T, LO, HI, Tune_P > &val) -> const framed_multi< Scalar_T, LO, HI, Tune_P >
Exponential of multivector.
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.
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>>(std::istream &s, framed_multi< Scalar_T, LO, HI, Tune_P > &val) -> std::istream &
Read multivector from input.
int index_t
Size of index_t should be enough to represent LO, HI.
Definition global.h:77
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.
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 star(const Multivector< Scalar_T, LO, HI, Tune_P > &lhs, const RHS< Scalar_T, LO, HI, Tune_P > &rhs) -> Scalar_T
Hestenes scalar product.
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 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.