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
38namespace 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
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
Table of generators for specific signatures.
Definition generation.h:54
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.
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.
static auto generator() -> generator_table< Matrix_T > &
Single instance of generator table.
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.
auto operator()(const index_t p, const index_t q) -> const Matrix_T *
Pointer to generators for a specific signature.
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.
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
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
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
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
auto unit(const typename Matrix_T::size_type n) -> const Matrix_T
Unit matrix - as per Matlab eye.
Definition matrix_imp.h:310
auto pos_mod(LHS_T lhs, RHS_T rhs) -> LHS_T
Modulo function which works reliably for lhs < 0.
Definition global.h:117
int index_t
Size of index_t should be enough to represent LO, HI.
Definition global.h:77