glucat  0.12.0
matrix_multi.h
Go to the documentation of this file.
1 #ifndef _GLUCAT_MATRIX_MULTI_H
2 #define _GLUCAT_MATRIX_MULTI_H
3 /***************************************************************************
4  GluCat : Generic library of universal Clifford algebra templates
5  matrix_multi.h : Declare a class for the matrix 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 #include "glucat/framed_multi.h"
40 
41 #include <boost/numeric/ublas/fwd.hpp>
42 
43 #include <fstream>
44 #include <string>
45 #include <utility>
46 #include <vector>
47 
48 namespace glucat
49 {
50  namespace ublas = boost::numeric::ublas;
51 
52  // Forward declarations for friends
53 
54  template< typename Scalar_T, const index_t LO, const index_t HI, typename Tune_P >
55  class framed_multi; // forward
56 
57  template< typename Scalar_T, const index_t LO, const index_t HI, typename Tune_P >
58  class matrix_multi; // forward
59 
61  template< typename Scalar_T, const index_t LO, const index_t HI, typename Tune_P >
62  auto
63  operator* (const matrix_multi<Scalar_T,LO,HI,Tune_P>& lhs, const matrix_multi<Scalar_T,LO,HI,Tune_P>& rhs) -> const matrix_multi<Scalar_T,LO,HI,Tune_P>;
64 
66  template< typename Scalar_T, const index_t LO, const index_t HI, typename Tune_P >
67  auto
68  operator^ (const matrix_multi<Scalar_T,LO,HI,Tune_P>& lhs, const matrix_multi<Scalar_T,LO,HI,Tune_P>& rhs) -> const matrix_multi<Scalar_T,LO,HI,Tune_P>;
69 
71  template< typename Scalar_T, const index_t LO, const index_t HI, typename Tune_P >
72  auto
73  operator& (const matrix_multi<Scalar_T,LO,HI,Tune_P>& lhs, const matrix_multi<Scalar_T,LO,HI,Tune_P>& rhs) -> const matrix_multi<Scalar_T,LO,HI,Tune_P>;
74 
76  template< typename Scalar_T, const index_t LO, const index_t HI, typename Tune_P >
77  auto
78  operator% (const matrix_multi<Scalar_T,LO,HI,Tune_P>& lhs, const matrix_multi<Scalar_T,LO,HI,Tune_P>& rhs) -> const matrix_multi<Scalar_T,LO,HI,Tune_P>;
79 
81  template< typename Scalar_T, const index_t LO, const index_t HI, typename Tune_P >
82  auto
83  star(const matrix_multi<Scalar_T,LO,HI,Tune_P>& lhs, const matrix_multi<Scalar_T,LO,HI,Tune_P>& rhs) -> Scalar_T;
84 
86  template< typename Scalar_T, const index_t LO, const index_t HI, typename Tune_P >
87  auto
88  operator/ (const matrix_multi<Scalar_T,LO,HI,Tune_P>& lhs, const matrix_multi<Scalar_T,LO,HI,Tune_P>& rhs) -> const matrix_multi<Scalar_T,LO,HI,Tune_P>;
89 
91  template< typename Scalar_T, const index_t LO, const index_t HI, typename Tune_P >
92  auto
93  operator| (const matrix_multi<Scalar_T,LO,HI,Tune_P>& lhs, const matrix_multi<Scalar_T,LO,HI,Tune_P>& rhs) -> const matrix_multi<Scalar_T,LO,HI,Tune_P>;
94 
96  template< typename Scalar_T, const index_t LO, const index_t HI, typename Tune_P >
97  auto
98  operator>> (std::istream& s, matrix_multi<Scalar_T,LO,HI,Tune_P>& val) -> std::istream&;
99 
101  template< typename Scalar_T, const index_t LO, const index_t HI, typename Tune_P >
102  auto
103  operator<< (std::ostream& os, const matrix_multi<Scalar_T,LO,HI,Tune_P>& val) -> std::ostream&;
104 
106  template< typename Scalar_T, const index_t LO, const index_t HI, typename Tune_P >
107  auto
108  reframe (const matrix_multi<Scalar_T,LO,HI,Tune_P>& lhs, const matrix_multi<Scalar_T,LO,HI,Tune_P>& rhs,
109  matrix_multi<Scalar_T,LO,HI,Tune_P>& lhs_reframed, matrix_multi<Scalar_T,LO,HI,Tune_P>& rhs_reframed) -> const index_set<LO,HI>;
110 
112  template< typename Scalar_T, const index_t LO, const index_t HI, typename Tune_P >
113  auto
114  sqrt(const matrix_multi<Scalar_T,LO,HI,Tune_P>& val, const matrix_multi<Scalar_T,LO,HI,Tune_P>& i, bool prechecked) -> const matrix_multi<Scalar_T,LO,HI,Tune_P>;
115 
117  template< typename Scalar_T, const index_t LO, const index_t HI, typename Tune_P >
118  auto
119  matrix_sqrt(const matrix_multi<Scalar_T,LO,HI,Tune_P>& val,
120  const matrix_multi<Scalar_T,LO,HI,Tune_P>& i,
121  const index_t level) -> const matrix_multi<Scalar_T,LO,HI,Tune_P>;
122 
124  template< typename Scalar_T, const index_t LO, const index_t HI, typename Tune_P >
125  auto
126  log(const matrix_multi<Scalar_T,LO,HI,Tune_P>& val, const matrix_multi<Scalar_T,LO,HI,Tune_P>& i, bool prechecked) -> const matrix_multi<Scalar_T,LO,HI,Tune_P>;
127 
129  template< typename Scalar_T, const index_t LO, const index_t HI, typename Tune_P >
130  auto
131  matrix_log( const matrix_multi<Scalar_T,LO,HI,Tune_P>& val,
132  const matrix_multi<Scalar_T,LO,HI,Tune_P>& i,
133  const index_t level) -> const matrix_multi<Scalar_T,LO,HI,Tune_P>;
134 
136  template< typename Scalar_T = double, const index_t LO = DEFAULT_LO, const index_t HI = DEFAULT_HI, typename Tune_P = tuning<> >
137  class matrix_multi :
138  public clifford_algebra< Scalar_T, index_set<LO,HI>, matrix_multi<Scalar_T,LO,HI,Tune_P> >
139  {
140  public:
143  using scalar_t = Scalar_T;
144  using tune_p = Tune_P;
146  using term_t = std::pair<const index_set_t, Scalar_T>;
147  using vector_t = std::vector<Scalar_T>;
150  template< typename Other_Scalar_T, const index_t Other_LO, const index_t Other_HI, typename Other_Tune_P >
151  friend class framed_multi;
152  template< typename Other_Scalar_T, const index_t Other_LO, const index_t Other_HI, typename Other_Tune_P >
153  friend class matrix_multi;
154 
155  private:
156  using orientation_t = ublas::row_major;
157  using basis_matrix_t = ublas::compressed_matrix<int, orientation_t>;
158  using matrix_t = ublas::matrix<Scalar_T, orientation_t>;
159  using matrix_index_t = typename matrix_t::size_type;
160 
161  public:
163  static auto classname() -> const std::string;
165  ~matrix_multi() override = default;
167  matrix_multi();
169  template< typename Other_Scalar_T >
172  template< typename Other_Scalar_T >
174  const index_set_t frm, const bool prechecked = false);
176  matrix_multi(const multivector_t& val,
177  const index_set_t frm, const bool prechecked = false);
179  matrix_multi(const index_set_t ist, const Scalar_T& crd = Scalar_T(1));
181  matrix_multi(const index_set_t ist, const Scalar_T& crd,
182  const index_set_t frm, const bool prechecked = false);
184  matrix_multi(const Scalar_T& scr, const index_set_t frm = index_set_t());
186  matrix_multi(const int scr, const index_set_t frm = index_set_t());
188  matrix_multi(const vector_t& vec,
189  const index_set_t frm, const bool prechecked = false);
191  matrix_multi(const std::string& str);
193  matrix_multi(const std::string& str,
194  const index_set_t frm, const bool prechecked = false);
196  matrix_multi(const char* str)
197  { *this = matrix_multi(std::string(str)); };
199  matrix_multi(const char* str,
200  const index_set_t frm, const bool prechecked = false)
201  { *this = matrix_multi(std::string(str), frm, prechecked); };
203  template< typename Other_Scalar_T >
206  template< typename Other_Scalar_T >
208  const index_set_t frm, const bool prechecked = false);
210  auto fast_matrix_multi(const index_set_t frm) const -> const matrix_multi_t;
212  template< typename Other_Scalar_T >
213  auto fast_framed_multi() const -> const framed_multi<Other_Scalar_T,LO,HI,Tune_P>;
214 
215  private:
217  template< typename Matrix_T >
218  matrix_multi(const Matrix_T& mtx, const index_set_t frm);
220  matrix_multi(const matrix_t& mtx, const index_set_t frm);
222  auto basis_element(const index_set<LO,HI>& ist) const -> const basis_matrix_t;
223 
224  public:
226 
228  auto operator= (const multivector_t& rhs) -> multivector_t&;
229 
231  static auto random(const index_set_t frm, Scalar_T fill = Scalar_T(1)) -> const matrix_multi_t;
232 
233  // Friend declarations
234 
235  friend auto
236  operator* <>(const matrix_multi_t& lhs, const matrix_multi_t& rhs) -> const matrix_multi_t;
237  friend auto
238  operator^ <>(const matrix_multi_t& lhs, const matrix_multi_t& rhs) -> const matrix_multi_t;
239  friend auto
240  operator& <>(const matrix_multi_t& lhs, const matrix_multi_t& rhs) -> const matrix_multi_t;
241  friend auto
242  operator% <>(const matrix_multi_t& lhs, const matrix_multi_t& rhs) -> const matrix_multi_t;
243  friend auto
244  star <>(const matrix_multi_t& lhs, const matrix_multi_t& rhs) -> Scalar_T;
245  friend auto
246  operator/ <>(const matrix_multi_t& lhs, const matrix_multi_t& rhs) -> const matrix_multi_t;
247  friend auto
248  operator| <>(const matrix_multi_t& lhs, const matrix_multi_t& rhs) -> const matrix_multi_t;
249 
250  friend auto
251  operator>> <>(std::istream& s, multivector_t& val) -> std::istream&;
252  friend auto
253  operator<< <>(std::ostream& os, const multivector_t& val) -> std::ostream&;
254  template< typename Other_Scalar_T, const index_t Other_LO, const index_t Other_HI, typename Other_Tune_P >
255  friend auto
256  reframe (const matrix_multi<Other_Scalar_T,Other_LO,Other_HI,Other_Tune_P>& lhs, const matrix_multi<Other_Scalar_T,Other_LO,Other_HI,Other_Tune_P>& rhs,
257  matrix_multi<Other_Scalar_T,Other_LO,Other_HI,Other_Tune_P>& lhs_reframed, matrix_multi<Other_Scalar_T,Other_LO,Other_HI,Other_Tune_P>& rhs_reframed) -> const index_set<Other_LO,Other_HI>;
258  template< typename Other_Scalar_T, const index_t Other_LO, const index_t Other_HI, typename Other_Tune_P >
259  friend auto
260  matrix_sqrt(const matrix_multi<Other_Scalar_T,Other_LO,Other_HI,Other_Tune_P>& val,
261  const matrix_multi<Other_Scalar_T,Other_LO,Other_HI,Other_Tune_P>& i,
262  const index_t level)
263  -> const matrix_multi<Other_Scalar_T,Other_LO,Other_HI,Other_Tune_P>;
264  template< typename Other_Scalar_T, const index_t Other_LO, const index_t Other_HI, typename Other_Tune_P >
265  friend auto
266  matrix_log(const matrix_multi<Other_Scalar_T,Other_LO,Other_HI,Other_Tune_P>& val,
267  const matrix_multi<Other_Scalar_T,Other_LO,Other_HI,Other_Tune_P>& i,
268  const index_t level)
269  -> const matrix_multi<Other_Scalar_T,Other_LO,Other_HI,Other_Tune_P>;
270 
272  auto operator+= (const term_t& rhs) -> multivector_t&;
273 
274  private:
275  // Data members
276 
281  };
282 
283  // Non-members
284 
286  template< typename Scalar_T, const index_t LO, const index_t HI, typename Tune_P >
287  auto
288  exp(const matrix_multi<Scalar_T,LO,HI,Tune_P>& val) -> const matrix_multi<Scalar_T,LO,HI,Tune_P>;
289 
290 }
291 
292 namespace std
293 {
295  template < typename Scalar_T, const glucat::index_t LO, const glucat::index_t HI, typename Tune_P >
296  struct numeric_limits< glucat::matrix_multi<Scalar_T,LO,HI,Tune_P> > :
297  public numeric_limits<Scalar_T>
298  { };
299 }
300 #endif // _GLUCAT_MATRIX_MULTI_H
friend auto star(const matrix_multi_t &lhs, const matrix_multi_t &rhs) -> Scalar_T
auto matrix_log(const matrix_multi< Scalar_T, LO, HI, Tune_P > &val, const matrix_multi< Scalar_T, LO, HI, Tune_P > &i, const index_t level) -> const matrix_multi< Scalar_T, LO, HI, Tune_P >
Natural logarithm of multivector with specified complexifier.
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.
friend auto matrix_log(const matrix_multi< Other_Scalar_T, Other_LO, Other_HI, Other_Tune_P > &val, const matrix_multi< Other_Scalar_T, Other_LO, Other_HI, Other_Tune_P > &i, const index_t level) -> const matrix_multi< Other_Scalar_T, Other_LO, Other_HI, Other_Tune_P >
auto exp(const framed_multi< Scalar_T, LO, HI, Tune_P > &val) -> const framed_multi< Scalar_T, LO, HI, Tune_P >
Exponential of multivector.
A framed_multi<Scalar_T,LO,HI,Tune_P> is a framed approximation to a multivector. ...
Definition: framed_multi.h:56
auto fast_framed_multi() const -> const framed_multi< Other_Scalar_T, LO, HI, Tune_P >
Use inverse generalized FFT to construct a framed_multi_t.
index_set_t m_frame
Index set representing the frame for the subalgebra which contains the multivector.
Definition: matrix_multi.h:278
auto matrix_sqrt(const matrix_multi< Scalar_T, LO, HI, Tune_P > &val, const matrix_multi< Scalar_T, LO, HI, Tune_P > &i, const index_t level) -> const matrix_multi< Scalar_T, LO, HI, Tune_P >
Square root 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.
std::pair< const index_set_t, Scalar_T > term_t
Definition: matrix_multi.h:146
index_set< LO, HI > index_set_t
Definition: matrix_multi.h:145
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.
multivector_t matrix_multi_t
Definition: matrix_multi.h:142
A matrix_multi<Scalar_T,LO,HI,Tune_P> is a matrix approximation to a multivector. ...
Definition: framed_multi.h:59
matrix_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: matrix_multi.h:199
ublas::matrix< Scalar_T, orientation_t > matrix_t
Definition: matrix_multi.h:158
auto operator>>(std::istream &s, framed_multi< Scalar_T, LO, HI, Tune_P > &val) -> std::istream &
Read multivector from input.
auto basis_element(const index_set< LO, HI > &ist) const -> const basis_matrix_t
Create a basis element matrix within the current frame.
auto reframe(const matrix_multi< Scalar_T, LO, HI, Tune_P > &lhs, const matrix_multi< Scalar_T, LO, HI, Tune_P > &rhs, matrix_multi< Scalar_T, LO, HI, Tune_P > &lhs_reframed, matrix_multi< Scalar_T, LO, HI, Tune_P > &rhs_reframed) -> const index_set< LO, HI >
Find a common frame for operands of a binary operator.
friend auto matrix_sqrt(const matrix_multi< Other_Scalar_T, Other_LO, Other_HI, Other_Tune_P > &val, const matrix_multi< Other_Scalar_T, Other_LO, Other_HI, Other_Tune_P > &i, const index_t level) -> const matrix_multi< Other_Scalar_T, Other_LO, Other_HI, Other_Tune_P >
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.
~matrix_multi() override=default
Destructor.
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 fast_matrix_multi(const index_set_t frm) const -> const matrix_multi_t
Use generalized FFT to construct a matrix_multi_t.
std::vector< Scalar_T > vector_t
Definition: matrix_multi.h:147
Specific exception class.
Definition: errors.h:56
typename matrix_t::size_type matrix_index_t
Definition: matrix_multi.h:159
friend auto reframe(const matrix_multi< Other_Scalar_T, Other_LO, Other_HI, Other_Tune_P > &lhs, const matrix_multi< Other_Scalar_T, Other_LO, Other_HI, Other_Tune_P > &rhs, matrix_multi< Other_Scalar_T, Other_LO, Other_HI, Other_Tune_P > &lhs_reframed, matrix_multi< Other_Scalar_T, Other_LO, Other_HI, Other_Tune_P > &rhs_reframed) -> const index_set< Other_LO, Other_HI >
static auto classname() -> const std::string
Class name used in messages.
int index_t
Size of index_t should be enough to represent LO, HI.
Definition: global.h:77
ublas::row_major orientation_t
Definition: matrix_multi.h:156
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
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 random(const index_set_t frm, Scalar_T fill=Scalar_T(1)) -> const matrix_multi_t
Random multivector within a frame.
ublas::compressed_matrix< int, orientation_t > basis_matrix_t
Definition: matrix_multi.h:157
matrix_multi()
Default constructor.
matrix_multi(const char *str)
Construct a multivector from a char*: eg: "3+2{1,2}-6.1e-2{2,3}".
Definition: matrix_multi.h:196
matrix_t m_matrix
Matrix value representing the multivector within the folded frame.
Definition: matrix_multi.h:280
#define _GLUCAT_CLIFFORD_ALGEBRA_OPERATIONS
matrix_multi multivector_t
Definition: matrix_multi.h:141
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.