versor  3.0
C++11 library for Geometric algebra
vsr_root.h
1 // Versor
2 // Author: pablo colapinto
3 //
4 // this file was written with the help of Pierre Dechant
5 //
6 // given a simple root, find all the others through reflections
7 //
8 // used e.g. in vsr_groups.h to create reflection groups
9 //
10 //
11 
12 
13 #ifndef ROOT_SYSTEM_INCLUDED
14 #define ROOT_SYSTEM_INCLUDED
15 
16 #include <vector>
17 #include "detail/vsr_generic_op.h"
18 
19 using namespace std;
20 
21 namespace vsr{
22 
23 //template<class V>
24 //struct SymmetryGroup {
25 //
26 // using Pin1 = V;
27 // using Pin2 = decltype(V()*V());
28 // using Pin3 = decltype(V()*V()*V());
29 //
30 // vector<Pin1> p1;
31 // vector<Pin2> p2;
32 // vector<Pin3> p3;
33 //
34 // ///Utility function to compare two vectors (looks at dot product, or norm of diff...)
35 // /// if ref=false then 180 degree reflections are considered equal
36 // static bool Compare(const V& a, const V& b, bool ref = true){
37 // return ( ref ? (a<=b)[0] > .99999 : fabs ((a<=b)[0]) > .99999 );// amt;
38 // }
39 //
40 // //seed generators with this until nothing new comes out
41 // //probes will store transformation operator and result
42 // struct VecProbe {
43 //
44 // V vec = V(1.2234578,2.838967,.123689).unit();
45 //
46 // Pin1 pin1; Pin2 pin2; Pin3 pin3;
47 //
48 // enum { PIN1, PIN2, PIN3 };
49 // int xf; ///< type of transformaiton used to make this
50 //
51 // VecProbe(){}
52 //
53 // VecProbe( const V& input, const Pin1& versor) : xf(PIN1), pin1(versor), vec( input.reflect(versor)) {}
54 // VecProbe( const V& input, const Pin2& rotor) : xf(PIN2), pin2(rotor), vec( input.spin(rotor)) {}
55 // VecProbe( const V& input, const Pin3& rotvec) : xf(PIN3), pin3(rotvec), vec( input.reflect(rotvec)) {}
56 //
57 // };
58 //
59 // SymmetryGroup& add(const Pin1& _p1) { p1.push_back(_p1); }
60 // SymmetryGroup& add(const Pin2& _p2) { p2.push_back(_p2); }
61 // SymmetryGroup& add(const Pin3& _p3) { p3.push_back(_p3); }
62 
66 // void System() {
67 //
68 // vector<VecProbe> results;
69 // for (auto& j : p1 ){
70 // results.push_back( VecProbe(j,j) );
71 // }
72 // //pins of pins...
73 // bool keepGoing = true;
74 // while (keepGoing){
75 // bool done = true;
76 // int cs = results.size(); // for all probes, add new probes until none are new
77 // // recording transformation sequences along the way
78 // for (int i=0; i<cs; ++i){
79 // int ns = results.size();
80 //
81 // for (int j=0;j<ns; ++j){
82 //
83 // auto nr = VecProbe(results[i].vec, results[j].versor );
84 //
85 // bool exists = 0;
86 // for ( int k=0; k<cs; ++k){
87 // exists = ( Compare(nr.vec.unit(),results[k].vec.unit(), false) );
88 // if (exists) {
89 // break;
90 // }
91 // }
92 //
93 // if (!exists) {
94 // results.push_back( nr );
95 // done = false; //if even one is new, try them all again
96 // }
97 // }
98 // }
99 // // if none are new or results is too big, end loop
100 // if (done || (results.size() > 500) ) { keepGoing = false; } // if not, then stop
101 //
102 // }
103 //
104 // }
105 
106 
107 //};
108 
109 
115 struct Root{
116 
117 
118  //indices into a reflection operation group and its results
119  struct ReflectIdx{
120  int opIdx, resIdx;
121  };
122 
124  template<class V>
125  static bool Compare(const V& a, const V& b, bool ref = true){
126 // return ( ( a-b ).wt() ) < .000001;
127  return ( ref ? (a<=b)[0] > .99999 : fabs ((a<=b)[0]) > .99999 );// amt;
128  }
129 
130  //Build a Root System from Simple Root Generators (ANY Dimension!)
131  template<class V, class ... R>
132  static vector<V> System( const V& x, const R&... v ){
133 
134  vector< V > initial; //<-- Initial Simple Roots
135 
136  int n = sizeof...(R) + 1;
137 
138  V root[] = {x, v... };
139 
140  for ( int i = 0; i < n; ++i ){
141  initial.push_back( root[i].unit() );
142  }
143 
144  return System( initial, false ); //flag for repeating opposite sides
145  }
146 
147  // Build a Root System from A vector of Simple Roots
148  template<class V>
149  static vector<V> System( const vector<V>& root, bool ref=true, int nMaxIter = 500){
150 
151  //Copy simple roots into results first
152  vector< V > results = root;
153 
154  int n = root.size(); //<-- Number of Simple Roots
155 
156  bool keepGoing = true;
157  int iter = 0;
158  while (keepGoing){
159  iter++;
160  bool done = true;
161  int cs = results.size();
162 
163  for (int i=0; i<cs; ++i){
164  int ns = results.size();
165 
166  for (int j=0; j<ns; ++j ){
167 
168  V nr = results[j].reflect( results[i] );
169 
170  bool exists = 0;
171  for ( int k=0; k<ns; ++k){
172  exists = ( Compare(nr.unit(),results[k].unit(),ref) );
173  if (exists) {
174  break;
175  }
176  }
177 
178  if (!exists) {
179  results.push_back( nr );
180  done = false; //if even one is new, try them all again
181  }
182  }
183  }
184 
185  if (done || (results.size() > nMaxIter) ) { keepGoing = false; } // if not, then stop
186 
187  }
188  return results;
189  }
190 
191 
192  /*-----------------------------------------------------------------------------
193  * Calculate number of extra reflections to calculate for a given (unit) seed vector (beyond System results)
194 
195  @param vec a random seed vec (must be unit)
196  @param op a vector of vec versors
197  *-----------------------------------------------------------------------------*/
198 // template<class V>
199 // static vector<ReflectIdx> Reflections(const V& vec, const vector<V>& op){ //<-- vec can be random or specifc axis MUST BE UNIT
200 //
201 // vector<ReflectIdx> rIdx;
202 //
203 // //FIRST PASS
204 // vector<Vec> vvec;
205 //
206 // for(auto& i : op){
207 // auto tvec = vec.reflect(i);
208 // vvec.push_back(tvec);
209 // }
210 //
211 // //Keep doing it until none new, record results in rIdx
212 // bool keepgoing=true;
213 // while(keepgoing){
214 //
215 // keepgoing=false;
216 // int tn = vvec.size();
217 // for(int i =0; i<op.size(); ++i){
218 // for (int j=0;j<tn;++j){
219 //
220 // auto tvec = vvec[j].reflect( op[i] );
221 //
222 // bool exists = false;
223 // for (auto& k : vvec){
224 // exists = Root::Compare(tvec,k);
225 // if (exists) {
226 // break;
227 // }
228 // }
229 //
230 // if (!exists){
231 // vvec.push_back(tvec);
232 // // cout << i << " " << j << endl;
233 // rIdx.push_back( {i,j} );
234 // keepgoing=true;
235 // }
236 // }
237 // }
238 // }
239 //
240 // return rIdx;
241 // }
242 
243 };
244 
245 
246 } //vsr::
247 #endif
248 
249 
250 
251 
252 
253  //FIRST PASS: reflect all roots around each other, and save if new
254  /* for (int i = 0; i < n; ++i){ */
255  /* for (int j = 0; j < n; ++j){ */
256 
257  /* V nr = root[i].re(root[j]); //<-- Reflection */
258 
259  /* bool exists = 0; */
260  /* for ( int k = 0; k < results.size(); ++k){ */
261  /* exists = ( Compare(nr,results[k]) ); //<-- Use the Compare function */
262  /* if (exists) break; */
263  /* } */
264 
265  /* if (!exists) results.push_back( nr ); */
266 
267  /* } */
268  /* } */
269 
270  //Okay, now repeat reflections until no new ones are created
271  /* bool keepGoing = true; */
272 
273  /* while (keepGoing){ */
274  /* //For EACH simple root */
275  /* for (int i = 0; i < n; ++i){ */
276 
277  /* //How big is results so far? (this will change every loop) */
278  /* int cs = results.size(); */
279 
280  /* for (int j = 0; j < cs; ++j ){ */
281 
282  /* bool done = true; //expect to be finished unless . . . */
283  /* V nr = results[j].re( root[i] ); */
284 
285  /* bool exists = 0; */
286  /* for ( int k = 0; k < cs; ++k){ */
287  /* exists = ( Compare(nr,results[k]) ); */
288  /* if (exists) { */
289  /* break; //<-- break out of this mini search loop */
290  /* } */
291  /* } */
292 
293  /* if (!exists) { */
294  /* results.push_back( nr ); */
295  /* done = false; //... we reset here and do it again */
296  /* } */
297 
298  /* if (done) { keepGoing = false; } */
299 
300  /* } */
301  /* } */
302  /* } */
static bool Compare(const V &a, const V &b, bool ref=true)
Utility function to compare two unit vectors (looks at dot product, or norm of diff...)
Definition: vsr_root.h:125
core namespaced operations that are metric-agnostic
goal is to use generators to collect all the unique transformations of the group, so we can apply the...
Definition: vsr_root.h:115
Definition: vsr_root.h:119
the versor library namespace
Definition: vsr_algebra.h:29