glucat  0.12.0
generation_imp.h
Go to the documentation of this file.
1 #ifndef _GLUCAT_GENERATION_IMP_H
2 #define _GLUCAT_GENERATION_IMP_H
3 /***************************************************************************
4  GluCat : Generic library of universal Clifford algebra templates
5  generation_imp.h : Implement functions for generation of the matrix representation
6  -------------------
7  begin : Wed Jan 23 2002
8  copyright : (C) 2002-2012 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/generation.h"
36 #include "glucat/matrix.h"
37 
38 namespace glucat { namespace gen
39 {
40  // References for algorithms:
41  // [M]: Scott Meyers, "Effective C++" Second Edition, Addison-Wesley, 1998.
42  // [P]: Ian R. Porteous, "Clifford algebras and the classical groups", Cambridge UP, 1995.
43  // [L]: Pertti Lounesto, "Clifford algebras and spinors", Cambridge UP, 1997.
44 
46  // Reference: [M] Item 47
47  template< class Matrix_T >
48  auto
51  { static generator_table<Matrix_T> g; return g;}
52 
54  // Reference: [P] Table 15.27, p 133
55  template< class Matrix_T >
56  inline
57  auto
59  operator() (const index_t p, const index_t q) -> const Matrix_T*
60  {
61  const auto bott = pos_mod(p-q, 8);
62  switch(bott)
63  {
64  case 0:
65  case 2:
66  // Construct generators
67  return &(gen_vector(p, q)[q]);
68  default:
69  // Select generators from the vector for a larger frame
70  const auto super_p = p + std::max(offset_to_super[bott],index_t(0));
71  const auto super_q = q - std::min(offset_to_super[bott],index_t(0));
72  return &(gen_vector(super_p, super_q)[super_q]);
73  }
74  }
75 
77  template< class Matrix_T >
78  auto
80  gen_vector(const index_t p, const index_t q) -> const std::vector<Matrix_T>&
81  {
82  using result_t = std::vector<Matrix_T>;
83  const auto card = p + q;
84  const auto bias = p - q;
85  const auto bott = pos_mod(bias, 8);
86  const auto sig = signature_t(p, q);
87  if (this->find(sig) == this->end())
88  switch(bott)
89  {
90  case 0:
91  if (bias < 0)
92  // Construct generators for p,q given generators for p+4,q-4
93  gen_from_pp4_qm4(gen_vector(p+4, q-4), sig);
94  else if (bias > 0)
95  // Construct generators for p,q given generators for p-4,q+4
96  gen_from_pm4_qp4(gen_vector(p-4, q+4), sig);
97  else if (card == 0)
98  { // Base case. Save a generator vector containing one matrix, size 1.
99  auto result = result_t(1, matrix::unit<Matrix_T>(1));
100  this->insert(make_pair(sig, result));
101  }
102  else
103  // Construct generators for p,q given generators for p-1,q-1
104  gen_from_pm1_qm1(gen_vector(p-1, q-1), sig);
105  break;
106  case 2:
107  if (bias < 2)
108  // Construct generators for p,q given generators for p+4,q-4
109  gen_from_pp4_qm4(gen_vector(p+4, q-4), sig);
110  else if (bias > 2)
111  // Construct generators for p,q given generators for p-4,q+4
112  gen_from_pm4_qp4(gen_vector(p-4, q+4), sig);
113  else
114  // Construct generators for p,q given generators for q+1,p-1
115  gen_from_qp1_pm1(gen_vector(q+1, p-1), sig);
116  break;
117  default:
118  break;
119  }
120  return (*this)[sig];
121  }
122 
124  // Reference: [P] Proposition 15.17, p 131
125  template< class Matrix_T >
126  void
128  gen_from_pm1_qm1(const std::vector<Matrix_T>& old, const signature_t sig)
129  {
130  const auto new_size = old.size() + 2;
131  using size_t = decltype(new_size);
132  using result_t = std::vector<Matrix_T>;
133  auto result = result_t(new_size);
134 
135  const auto old_dim = old[0].size1();
136  const auto& eye = matrix::unit<Matrix_T>(old_dim);
137 
138  auto neg = Matrix_T(2,2,2);
139  neg(0,1) = -1;
140  neg(1,0) = 1;
141 
142  auto pos = neg;
143  pos(0,1) = 1;
144 
145  auto dup = Matrix_T(2,2,2);
146  dup(0,0) = 1;
147  dup(1,1) = -1;
148 
149  result[0] = matrix::mono_kron(neg, eye);
150  for (auto
151  k = size_t(1);
152  k != new_size-1;
153  ++k)
154  result[k] = matrix::mono_kron(dup, old[k-1]);
155  result[new_size-1] = matrix::mono_kron(pos, eye);
156 
157  // Save the resulting generator array.
158  this->insert(make_pair(sig, result));
159  }
160 
162  // Reference: [L] 16.4 Periodicity of 8, p216
163  template< class Matrix_T >
164  void
166  gen_from_pm4_qp4(const std::vector<Matrix_T>& old, const signature_t sig)
167  {
168  const auto old_size = old.size();
169  using size_t = decltype(old_size);
170  using result_t = std::vector<Matrix_T>;
171  auto result = result_t(old_size);
172 
173  auto h = old[0];
174  for (auto
175  k = size_t(1);
176  k != size_t(4);
177  ++k)
178  h = matrix::mono_prod(old[k], h);
179 
180  for (auto
181  k = size_t(0);
182  k != old_size-4;
183  ++k)
184  result[k] = old[k+4];
185  for (auto
186  k = old_size-4;
187  k != old_size;
188  ++k)
189  result[k] = matrix::mono_prod(old[k+4-old_size], h);
190  // Save the resulting generator array.
191  this->insert(make_pair(sig, result));
192  }
193 
195  // Reference: [L] 16.4 Periodicity of 8, p216
196  template< class Matrix_T >
197  void
199  gen_from_pp4_qm4(const std::vector<Matrix_T>& old, const signature_t sig)
200  {
201  const auto old_size = old.size();
202  using size_t = decltype(old_size);
203  using result_t = std::vector<Matrix_T>;
204  auto result = result_t(old_size);
205 
206  auto h = old[old_size-1];
207  for (auto
208  k = size_t(1);
209  k != size_t(4);
210  ++k)
211  h = matrix::mono_prod(old[old_size-1-k], h);
212 
213  for (auto
214  k = size_t(0);
215  k != size_t(4);
216  ++k)
217  result[k] = matrix::mono_prod(old[k+old_size-4], h);
218  for (auto
219  k = size_t(4);
220  k != old_size;
221  ++k)
222  result[k] = old[k-4];
223  // Save the resulting generator array.
224  this->insert(make_pair(sig, result));
225  }
226 
228  // Reference: [P] Proposition 15.20, p 131
229  template< class Matrix_T >
230  void
232  gen_from_qp1_pm1(const std::vector<Matrix_T>& old, const signature_t sig)
233  {
234  const auto old_size = old.size();
235  using size_t = decltype(old_size);
236  using result_t = std::vector<Matrix_T>;
237  auto result = result_t(old_size);
238 
239  const auto& h = old[old_size-1];
240  for (auto
241  k = size_t(0);
242  k != old_size-1;
243  ++k)
244  result[k] = matrix::mono_prod(old[old_size-2-k], h);
245  result[old_size-1] = h;
246 
247  // Save the resulting generator array.
248  this->insert(make_pair(sig, result));
249  }
250 
251 } }
252 #endif // _GLUCAT_GENERATION_IMP_H
auto operator()(const index_t p, const index_t q) -> const Matrix_T *
Pointer to generators for a specific signature.
auto mono_prod(const ublas::matrix_expression< LHS_T > &lhs, const ublas::matrix_expression< RHS_T > &rhs) -> const typename RHS_T::expression_type
Product of monomial matrices.
Definition: matrix_imp.h:320
Table of generators for specific signatures.
Definition: generation.h:52
auto pos_mod(LHS_T lhs, RHS_T rhs) -> LHS_T
Modulo function which works reliably for lhs < 0.
Definition: global.h:117
void gen_from_qp1_pm1(const std::vector< Matrix_T > &old, const signature_t sig)
Construct generators for p,q given generators for q+1,p-1.
std::pair< index_t, index_t > signature_t
A signature is a pair of indices, p, q, with p == frame.max(), q == -frame.min()
Definition: generation.h:48
static auto generator() -> generator_table< Matrix_T > &
Single instance of generator table.
void gen_from_pm4_qp4(const std::vector< Matrix_T > &old, const signature_t sig)
Construct generators for p,q given generators for p-4,q+4.
void gen_from_pp4_qm4(const std::vector< Matrix_T > &old, const signature_t sig)
Construct generators for p,q given generators for p+4,q-4.
void gen_from_pm1_qm1(const std::vector< Matrix_T > &old, const signature_t sig)
Construct generators for p,q given generators for p-1,q-1.
auto gen_vector(const index_t p, const index_t q) -> const std::vector< Matrix_T > &
Construct a vector of generators for a specific signature.
int index_t
Size of index_t should be enough to represent LO, HI.
Definition: global.h:77
static const std::array< index_t, 8 > offset_to_super
Offsets between the current signature and that of the real superalgebra.
Definition: generation.h:86
auto mono_kron(const LHS_T &lhs, const RHS_T &rhs) -> const RHS_T
Sparse Kronecker tensor product of monomial matrices.
Definition: matrix_imp.h:119