glucat  0.8.2
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/generation.h"
35 
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  generator_table<Matrix_T>&
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  const Matrix_T*
59  operator() (const index_t p, const index_t q)
60  {
61  const index_t 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 index_t super_p = p + std::max(offset_to_super[bott],index_t(0));
71  const index_t 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  const std::vector<Matrix_T>&
80  gen_vector(const index_t p, const index_t q)
81  {
82  const index_t card = p + q;
83  const index_t bias = p - q;
84  const index_t bott = pos_mod(bias, 8);
85  const signature_t sig(p, q);
86  if (this->find(sig) == this->end())
87  switch(bott)
88  {
89  case 0:
90  if (bias < 0)
91  // Construct generators for p,q given generators for p+4,q-4
92  gen_from_pp4_qm4(gen_vector(p+4, q-4), sig);
93  else if (bias > 0)
94  // Construct generators for p,q given generators for p-4,q+4
95  gen_from_pm4_qp4(gen_vector(p-4, q+4), sig);
96  else if (card == 0)
97  { // Base case. Save a generator vector containing one matrix, size 1.
98  std::vector<Matrix_T> result(1, matrix::unit<Matrix_T>(1));
99  this->insert(make_pair(sig, result));
100  }
101  else
102  // Construct generators for p,q given generators for p-1,q-1
103  gen_from_pm1_qm1(gen_vector(p-1, q-1), sig);
104  break;
105  case 2:
106  if (bias < 2)
107  // Construct generators for p,q given generators for p+4,q-4
108  gen_from_pp4_qm4(gen_vector(p+4, q-4), sig);
109  else if (bias > 2)
110  // Construct generators for p,q given generators for p-4,q+4
111  gen_from_pm4_qp4(gen_vector(p-4, q+4), sig);
112  else
113  // Construct generators for p,q given generators for q+1,p-1
114  gen_from_qp1_pm1(gen_vector(q+1, p-1), sig);
115  break;
116  default:
117  break;
118  }
119  return (*this)[sig];
120  }
121 
123  // Reference: [P] Proposition 15.17, p 131
124  template< class Matrix_T >
125  void
127  gen_from_pm1_qm1(const std::vector<Matrix_T>& old, const signature_t sig)
128  {
129  typedef typename Matrix_T::size_type matrix_index_t;
130  Matrix_T neg(2,2,2);
131  neg(0,1) = -1;
132  neg(1,0) = 1;
133 
134  Matrix_T pos = neg;
135  pos(0,1) = 1;
136 
137  Matrix_T dup(2,2,2);
138  dup(0,0) = 1;
139  dup(1,1) = -1;
140 
141  const int new_size = old.size() + 2;
142  const matrix_index_t old_dim = old[0].size1();
143  const Matrix_T& eye = matrix::unit<Matrix_T>(old_dim);
144 
145  std::vector<Matrix_T> result(new_size);
146 
147  result[0] = matrix::mono_kron(neg, eye);
148  for (int
149  k = 1;
150  k != new_size-1;
151  ++k)
152  result[k] = matrix::mono_kron(dup, old[k-1]);
153  result[new_size-1] = matrix::mono_kron(pos, eye);
154 
155  // Save the resulting generator array.
156  this->insert(make_pair(sig, result));
157  }
158 
160  // Reference: [L] 16.4 Periodicity of 8, p216
161  template< class Matrix_T >
162  void
164  gen_from_pm4_qp4(const std::vector<Matrix_T>& old, const signature_t sig)
165  {
166  Matrix_T h = old[0];
167  for (int
168  k = 1;
169  k != 4;
170  ++k)
171  h = matrix::mono_prod(old[k], h);
172 
173  const int old_size = old.size();
174  std::vector<Matrix_T> result(old_size);
175  int m = old_size-4;
176  for (int
177  k = 0;
178  k != 4;
179  ++k, ++m)
180  result[m] = matrix::mono_prod(old[k], h);
181  for (int
182  k = 4;
183  k != old_size;
184  ++k)
185  result[k-4] = old[k];
186  // Save the resulting generator array.
187  this->insert(make_pair(sig, result));
188  }
189 
191  // Reference: [L] 16.4 Periodicity of 8, p216
192  template< class Matrix_T >
193  void
195  gen_from_pp4_qm4(const std::vector<Matrix_T>& old, const signature_t sig)
196  {
197  const int old_size = old.size();
198  Matrix_T h = old[old_size-1];
199  for (int
200  k = 1;
201  k != 4;
202  ++k)
203  h = matrix::mono_prod(old[old_size-1-k], h);
204 
205  std::vector<Matrix_T> result(old_size);
206  for (int
207  k = 0;
208  k != 4;
209  ++k)
210  result[k] = matrix::mono_prod(old[k+old_size-4], h);
211  for (int
212  k = 4;
213  k != old_size;
214  ++k)
215  result[k] = old[k-4];
216  // Save the resulting generator array.
217  this->insert(make_pair(sig, result));
218  }
219 
221  // Reference: [P] Proposition 15.20, p 131
222  template< class Matrix_T >
223  void
225  gen_from_qp1_pm1(const std::vector<Matrix_T>& old, const signature_t sig)
226  {
227  const int old_size = old.size();
228  const Matrix_T& a = old[old_size-1];
229  std::vector<Matrix_T> result(old_size);
230  int m = 0;
231  for (int
232  k = old_size-1;
233  k != 0;
234  --k, ++m)
235  result[m] = matrix::mono_prod(old[k-1], a);
236  result[old_size-1] = a;
237 
238  // Save the resulting generator array.
239  this->insert(make_pair(sig, result));
240  }
241 
242 } }
243 #endif // _GLUCAT_GENERATION_IMP_H
static generator_table< Matrix_T > & generator()
Single instance of generator table.
static const index_t offset_to_super[]
Offsets between the current signature and that of the real superalgebra.
Definition: generation.h:81
const RHS_T mono_kron(const LHS_T &lhs, const RHS_T &rhs)
Sparse Kronecker tensor product of monomial matrices.
Definition: matrix_imp.h:116
Table of generators for specific signatures.
Definition: generation.h:47
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.
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.
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:43
const RHS_T::expression_type mono_prod(const ublas::matrix_expression< LHS_T > &lhs, const ublas::matrix_expression< RHS_T > &rhs)
Product of monomial matrices.
Definition: matrix_imp.h:326
const std::vector< Matrix_T > & gen_vector(const index_t p, const index_t q)
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
LHS_T pos_mod(LHS_T lhs, RHS_T rhs)
Modulo function which works reliably for lhs < 0.
Definition: global.h:187
const Matrix_T * operator()(const index_t p, const index_t q)
Pointer to generators for a specific signature.