versor  3.0
C++11 library for Geometric algebra
vsr_group.h
1 /*
2 
3 Generic Group
4 
5 see also vsr_root.h for generating reflection groups
6 
7 replaces vsr_pointGroup.h
8 
9 */
10 
11 #ifndef vsr_group_INC
12 #define vsr_group_INC
13 
14 
15 #include "vsr_set.h"
16 #include "vsr_root.h"
17 #include "detail/vsr_generic_op.h"
18 #include <vector>
19 
20 using std::vector;
21 
22 namespace vsr{
23 
25 template<class V>
26 struct SimpleGroup{
27  vector<V> ops;
28 
29  SimpleGroup() {}
30  SimpleGroup( vector<V> v ) : ops(v) {}
31 
33  template<class T>
34  vector<T> operator()(const T& p){
35  vector<T> res;
36  for (auto& i : ops ){
37  T tp = p.reflect( i ); //assuming all i's are unit
38  res.push_back( tp );
39  //reflect back over first mirror plane to get original ...
40  res.push_back( tp.reflect( ops[0] ) );
41  }
42  return res;
43  }
44 };
45 
49 template< class V >
50 struct Group {
51 
52  int numSimple;
53 
55  //typedef typename V::template BType< typename V::Mode::Trs > Trs;
56  using Trs = typename V::space::translator;
57 
58  vector<V> ops;
59  vector<decltype(V()*V())> sops;
60  vector<decltype(V()*V()*V())> tops;
61  vector<decltype(V()*Trs())> gops;
62  vector<decltype(V()*V()*Trs())> scrops;
63 
64  Group() {}
65  Group( vector<V> v ) : ops(v) {}
66 
68  // Note this is overloaded in PointGroups, which use a "seed-based recording" approach
69  template<class T>
70  vector<T> operator()(const T& p){
71  vector<T> res;
72 
73  for (auto& i : ops ){
74  T tp = p.reflect( i.unit() );
75  res.push_back( tp );
76  //reflect EACH back over first mirror plane to get original ...
77  res.push_back( tp.reflect( ops[0].unit() ) );
78  }
79 
80  for (auto& i : sops){
81  T tp = p.spin(i);
82  res.push_back(tp);
83  }
84 
85  //unsure about this (abc)..
86  for (auto& i : tops){
87  T tp = p.reflect(i);
88  res.push_back(tp);
89  }
90 
91 
92  //apply glides and reapply pins
93  for (auto& i : gops){
94  T tg = p.reflect(i);
95  if (ops.empty()) {
96  res.push_back(tg);
97  res.push_back( tg.reflect( gops[0] ) );
98  }
99  for (auto& j : ops){
100  T tp = tg.reflect( j.unit() );
101  res.push_back(tp);
102  res.push_back( tp.reflect( ops[0].unit() ) );
103  }
104  }
105 
106  return res;
107  }
108 
110  template<class T>
111  vector<T> operator()(const vector<T>& p){
112  vector<T> res;
113  for (auto& i : p) {
114  auto tRes = (*this)(i);
115  for (auto& j : tRes){
116  res.push_back(j);
117  }
118  }
119  return res;
120  }
121 
122 
123 
124 };
125 
126 //A 2d point group at the origin . . .
128 template< class V >
129 struct PointGroup2D : Group<V> {
130 
131  typedef decltype( V() ^ V() ) Biv;
132 
133  V a, b;
134 
135  int mP;
136  bool bPin;
137 
138  PointGroup2D(int p, bool pin = true) : mP(p), bPin(pin) {
139  a = V::x;
140  b = V::x.rot( Biv::xy * PIOVERTWO/p );
141  calcOps(a.unit(), b.unit());
142  }
143 
144  void calcOps(const V& ta, const V& tb){
145  this->ops.clear();
146  this->sops.clear();
147  this->gops.clear();
148  if (bPin) this->ops = Root::System(ta,tb);
149  else {
150  auto rot = a*b;
151  auto trot = rot;
152  for (int i=0;i<mP;++i){
153  this->sops.push_back(trot);
154  trot = trot * rot;
155  }
156  }
157  }
158 
159 };
160 
161 //a pointgroup + a lattice formed by translating along the generators a and b
162 //we generate the point group calcOps() and then replace by glide reflections if called for
163 //To use Translators multiplicatively, here we assume the conformal model is in play (2D or above)
164 template<class V >
166 
167  using Trs = typename V::space::translator;
168  using Vec = typename V::space::vector;
169 
170  typedef decltype( V() ^ V() ) Biv;
171 
172  int mDiv; //(p)rimitive lattice = 1.0 (default); (c)entered lattice = 2; (h)exagonal lattice = 3
173  float mRatioY=1;
174  float mRatioX=1;
175 
177  // @param mP: symmetry group (1,2,3,4,6)
178  // @param mRatio: for translations on the lattice
179  // @param bPin: pin or spin generators
180  // @param mDiv: number of divisions into lattice cell
181  // @param ga: whether a glide reflection replaces first mirror generator
182  // @param gb: whether a glide reflection replaces second mirror generator
183  SpaceGroup2D(int p, float ratio = 1.0, bool pin=true, int div = 1, bool ga=false, bool gb=false)
184  : PointGroup2D<V>(p,pin), mRatioY(ratio), mDiv(div) {
185 
186 
187  if (p==1){
188  //Glide Reflections
189  if (ga) { //replace first mirror
190  this->ops.clear();
191  // this->ops.push_back(this->b);
192  this->gops.push_back( this->a * Gen::trs( Vec::y * .5) );
193  }
194  } else if (p<4){
195  //Glide Reflections
196  if (ga) { //replace first mirror
197  this->ops.clear();
198  this->ops.push_back(this->b);
199  this->gops.push_back( this->a * Gen::trs(this->b * .5) );
200  }
201  if (gb) { //replace second mirror
202  this->ops.pop_back();
203  this->gops.push_back( this->b * Gen::trs(this->a * .5) );
204  }
205  } else {
206  if (p==4){
207  this->b = this->a + (this->a).rot( Biv::xy * PIOVERTWO/2);
208  if(ga){
209  this->ops.clear();
210  this->ops.push_back(this->b.unit());
211  this->ops.push_back(this->b.reflect(this->a).unit());
212  this->gops.push_back( this->a * Gen::trs((this->b - this->a) * .5) );
213  }
214  }
215  if (p==6){
216  this->b = this->a + this->a.rot( Biv::xy * PIOVERTWO/3);
217  }
218  }
219 
220  }
221 
222 
223  Vec vec(float x, float y){
224  if (this->mP!=1) return this->a*x*mRatioX + this->b*y*mRatioY;
225  else return this->a*x + Vec::y*y;
226  }
227 
228 
229  /*-----------------------------------------------------------------------------
230  * Apply translations to a single element
231  *-----------------------------------------------------------------------------*/
232  template<class T>
233  vector<T> apply(const T& motif, int x, int y){
234 
235  auto tmp = (*this)(motif);
236  vector<T> res;
237 
238  for (auto& i : tmp ){
239  for (int j=-x/2.0;j<x/2.0;++j){
240  for (int k=-y/2.0;k<y/2.0;++k){
241  for (int m =0;m<mDiv;++m){
242  float t = (float)m/mDiv;
243  //Vec v = vec(j
244  res.push_back( i.trs( vec(j,k) + vec(t,t) ) );
245  }
246  }
247  }
248  }
249  return res;
250  }
251 
253  template<class T>
254  vector<T> apply(const vector<T>& motif, int x, int y){
255  vector<T> res;
256  for (auto& i : motif){
257  vector<T> tRes = apply(i,x,y);
258  for (auto& j : tRes) res.push_back(j);
259  }
260  return res;
261  }
262 
264  template<class T>
265  vector<T> hang(const T& motif, int x, int y){
266  vector<T> res;
267  for (int j=-x/2.0;j<x/2.0;++j){
268  for (int k=-y/2.0;k<y/2.0;++k){
269  for (int m =0;m<mDiv;++m){
270  float t = (float)m/mDiv;
271  res.push_back( motif.trs( vec(j,k) + vec(t,t) ) );
272  }
273  }
274  }
275  return res;
276  }
278  template<class T>
279  vector<T> hang(const vector<T>& motif, int x, int y){
280  vector<T> res;
281  for (auto& i : motif){
282  for (int j=-x/2.0;j<x/2.0;++j){
283  for (int k=-y/2.0;k<y/2.0;++k){
284  for (int m =0;m<mDiv;++m){
285  float t = (float)m/mDiv;
286  res.push_back( i.trs( vec(j,k) + vec(t,t) ) );
287  }
288  }
289  }
290  }
291  return res;
292  }
293 };
294 
295 
297 template< int DIM, class V >
298 struct Lattice {
299 
300  static const int Dim = DIM;
301 
302  //GET VEC "B" TYPE OF TYPE V's AMBIENT METRIC ("MODE")
303  typedef typename V::template BType< typename V::Mode::Vec > Vec;
304  typedef typename V::template BType< typename V::Mode::Biv > Biv;
305 
306  Vec vec[ DIM ];
307 
308  Vec& operator[](int idx) { return vec[idx]; }
309  Vec operator[](int idx) const { return vec[idx]; }
310 
311  Vec at() { return Vec(); }
312 
313  template<class ... T>
314  Vec at( int x, T...v ){
315  int idx = DIM - ( sizeof...(v) + 1 );
316  return vec[idx] * x + at(v...);
317  }
318 
320  void set(){}
322  template<class ... T>
323  void set(int x, T ... xs){
324  using TE = typename V::template BType< typename V::Mode::template e< ( DIM - ( sizeof...(T) )) > >;
325  int idx = DIM - ( sizeof...(T) + 1);
326  Biv biv = V::x ^ TE(1);
327  vec[idx] = V::x.rot( biv * PIOVERTWO/x );
328 
329  set(xs...);
330  }
331 
333  template<class ... T>
334  Lattice(int x, T ... xs) {
335  vec[0] = V::x;
336  set(x,xs...);
337  }
338 
339 };
340 
341 
342 
343 
344 template<class V>
345 struct PointGroup3D : Group<V> {
346 
347  struct OpIdx{
348  int type, opIdx, resIdx;
349  };
350 
351  using Biv = typename V::space::Biv;
352  using Vec = typename V::space::Vec;
353 
354  V a, b, c; //<-- basis generators
355 
356  vector<OpIdx> opIdx; //<-- given a seed vector, store all reflection operations here.
357  // vector<OpIdx> spinIdx; //<-- "" spin operations
358 
359  //must satisfy dicycle ab^p = bc^q = ac^2
360  PointGroup3D(int p, int q, bool abar=false, bool bbar=false, bool abbar=false) {
361 
362  //0. a and c are at 90 degrees, must find b...
363  a = V::x;
364  c = V::y;
365 
366  //1. employ the good old spherical trig cosine rule ...
367  double tb = PIOVERTWO;
368  double ta = PI/(int)p;
369  double tc = PI/(int)q;
370 
371  double ca = cos(ta);
372  double sa = sin(ta);
373  double cb = cos(tb);
374  double sb = sin(tb);
375  double cc = cos(tc);
376  double sc = sin(tc);
377 
378  double tA = acos( (ca-(cb*cc))/(sb*sc) );
379  double tC = acos( (cc-(ca*cb))/(sa*sb) );
380 
381  //2. ... to rotate the yx plane ...
382  auto bivA = (a ^ c).rot( a.duale() * tC / 2.0 );
383  auto bivC = (a ^ c).rot( c.duale() * tA / 2.0 );
384 
385  //3. ... and find b via coincidence of planes ...
386  b = (bivA.duale() ^ bivC.duale()).duale().unit();
387 
388 
389  if (!abar && !bbar && !abbar ){ //Case of only reflections. easy!
390  this->ops = {a,b,c};
391  } else if (abbar){
392  this->tops.push_back(a*b*c); //<--implications?
393  } else if ( abar && bbar ) {
394  this->sops.push_back(a*b);
395  this->sops.push_back(b*c);
396  } else if (abar){ //Case of only one or other are cyclic
397  this->sops.push_back(a*b);
398  this->ops.push_back(c);
399  } else if (bbar){
400  this->sops.push_back(b*c);
401  this->ops.push_back(a);
402  }
403 
404  // seed a random vector to "record" all unique reflection and spin operations
405  seed();
406 
407  }
408 
409 
410  template<class T>
411  vector<T> operator() (const T& p){
412  return apply(p);
413  }
414 
415  template<class T>
416  vector<T> operator() (const vector<T>& p){
417  vector<T> res;
418  for (auto& i : p){
419  auto tmp = apply(i);
420  for (auto& j : tmp){
421  res.push_back(j);
422  }
423  }
424  return res;
425  }
426 
427  void seed(const Vec& vec=Vec(.213,.659,1.6967).unit() ){
428 
429  opIdx.clear();
430  vector<Vec> tv;
431 
432  //FIRST PASS (ops and sops)
433  for(auto& i : this->ops){
434  auto tvec = vec.reflect(i);
435  tv.push_back(tvec);
436  }
437 
438  for(auto& i : this->sops){
439  auto tvec = vec.spin(i);
440  tv.push_back(tvec);
441  }
442 
443  //tops? gops?
444 
445  //REFLECTIONS RECORD
446  //Keep doing it until none new, record results in reflectIdx
447  bool keepgoing=true; int iter=0; int maxiter = 100;
448  while(keepgoing && iter<maxiter){
449  iter++;
450  keepgoing=false;
451  int tn = tv.size();
452 
453  //Any New Reflections?
454  for(int i =0; i<this->ops.size(); ++i){
455  for (int j=0;j<tn;++j){
456 
457  auto tvec = tv[j].reflect( this->ops[i] );
458 
459  bool exists = false;
460  for (auto& k : tv){
461  exists = Root::Compare(tvec,k);
462  if (exists) {
463  break;
464  }
465  }
466 
467  if (!exists){
468  tv.push_back(tvec);
469  opIdx.push_back( {1,i,j} );
470  keepgoing=true;
471  }
472  }
473  }
474 
475  //Any New Spins?
476  for(int i =0; i<this->sops.size(); ++i){
477  for (int j=0;j<tn;++j){
478 
479  auto tvec = tv[j].spin( this->sops[i] );
480 
481  bool exists = false;
482  for (auto& k : tv){
483  exists = Root::Compare(tvec,k);
484  if (exists) {
485  break;
486  }
487  }
488 
489  if (!exists){
490  tv.push_back(tvec);
491  opIdx.push_back( {0,i,j} );
492  keepgoing=true;
493  }
494  }
495  }
496  }
497 
498 
499  }
500 
501  template<class T>
502  vector<T> apply(const T& p){
503 
504  vector<T> res;
505  //pin first
506  for(auto& i : this->ops){
507  res.push_back(p.reflect(i));
508  }
509 
510  //spin second
511  for(auto& i : this->sops){
512  res.push_back(p.spin(i));
513  }
514 
515  for (auto& i : opIdx){
516  auto tmp = i.type ? res[ i.resIdx ].reflect( this->ops[ i.opIdx] )
517  : res[ i.resIdx ].spin( this->sops[ i.opIdx] );
518  res.push_back(tmp);
519  }
520 
521  return res;
522  }
523 
524 
525 
526  auto ab() RETURNS ( a * b )
527  auto ac() RETURNS ( a * c )
528  auto bc() RETURNS ( b * c )
529 
530 };
531 
532  //Biv biv = Biv::xy * PIOVERTWO / p;
533  //Biv biv2 = Biv::yz * PIOVERTWO / q;
534  //b = V::x.rot(biv).rot(biv2);
535  //c = V::y;
536 
537 
538 template<class V>
540 
541  // typedef typename V::template BType< typename V::Mode::Trs >
542  using Trs = typename V::space::translator;
543  using Vec = typename V::space::Vec;
544 
545 // Trs ta, tb, tc;
546  //.5
547  //Primitive, Body, A-Face, C-Face, Hexagonal, Face2, Face3, Rhombo
548  enum LatticeType{
549  Primitive, Body, AFace, CFace, HFace, Face2, Face3, Rhombo
550  };
551 
552  //A axial (a), B axial (b), C axial (c), Diagonal (n), Diamond (d)
553  enum GlideType{
554  None, AxialA, AxialB, AxialC, Diagonal, Diamond
555  };
557  GlideType type; //
558  bool bInvert; //boolean switch for b or a-b, b+c or a-b+c
559  };
560 
561  struct Glide{
562  Glide( GlideParameter _a = {None,false}, GlideParameter _b = {None,false}, GlideParameter _c = {None,false}) : a(_a), b(_b), c(_c) {}
563  GlideParameter a, b, c;
564  };
565 
566  LatticeType mLatticeType;
567  Glide mGlide;
568 
569  Vec mRatio; //<-- ratio of width to height
570  int mScrew;
571 
572  SpaceGroup3D(
573  int p, int q,
574  bool abar=false, bool bbar=false, bool abbar=false,
575  LatticeType lattice = Primitive,
576  Vec ratio= Vec(1,1,1),
577  Glide glide = Glide(),
578  int screw=0
579  )
580  :
581  PointGroup3D<V>(p,q,abar,bbar,abbar),
582  mLatticeType(lattice),
583  mRatio(ratio),
584  mGlide(glide),
585  mScrew(screw)
586  {
587  init();
588  }
589 
590 
591  //Q: how to seed non-symmorphic space groups
592  void init(){
593 
594  //GLIDE replacements for non-symmorphic groups
595  vector<int> replace; //keep track of indices into this->ops to replace
596  vector<V> nops; //new operations list
597  switch(mGlide.a.type){
598  case AxialB: //< replace a reflection with a glide
599  {
600  replace.push_back(0);
601  auto trs = Gen::trs( ( (mGlide.a.bInvert) ? (this->a - this->b) : (this->b) ) * .5 );
602  this->gops.push_back( this->a * trs );
603  break;
604  }
605  case AxialC:
606  {
607  replace.push_back(0);
608  auto trs = Gen::trs( ( (mGlide.a.bInvert) ? (this->a - this->c) : (this->c) ) * .5 );
609  this->gops.push_back( this->a * trs );
610  break;
611  }
612  case Diagonal:
613  {
614  replace.push_back(0); //we will replace 0 idx
615  auto trs = Gen::trs( ( (mGlide.a.bInvert) ? (this->a - (this->b+this->c)) : (this->b+this->c) ) * .5 );
616  this->gops.push_back( this->a * trs );
617  break;
618  }
619 
620  }
621 
622  switch(mGlide.b.type){
623 
624  }
625 
626  switch(mGlide.c.type){
627 
628  }
629 
630  for (int i = 0; i < this->ops.size(); ++i){
631  //bool add=true;
632  //for (auto& j : replace) if (i==j) add = false;
633  //if (bool) nops.push_back(i);
634  }
635 
636  //SCREW replacements
637 
638  //Reseed opIdx
639  this->seed();
640 
641  }
642 
643  template<class T>
644  vector<T> operator() (const T& p){
645  return apply(p);
646  }
647 
648  template<class T>
649  vector<T> apply( const T& p ){
650  auto pg = PointGroup3D<V>::apply(p);
651 
652  for (int i=0;i<pg.size();++i){
653  for (auto& j : this->gops ){
654  pg.push_back( pg[i].reflect(j) );
655  }
656  for (auto& j : this->scrops ){
657  pg.push_back( pg[i].spin(j) );
658  }
659  }
660 
661  return pg;
662  }
663 
664  template<class T>
665  vector<T> apply(const vector<T>& p){
666  vector<T> res;
667  for(auto& i : p){
668  auto tmp = apply(i);
669  for (auto& j : tmp){
670  res.push_back(j);
671  }
672  }
673  return res;
674  }
675 
676 
680  Vec vec(float x, float y, float z){
681  return this->a*x * mRatio[0] + this->b*y * mRatio[1] + this->c*z * mRatio[2];
682  }
683 
684 
688  template<class T>
689  vector<T> hang(const T& motif, int x, int y, int z){
690  vector<T> res;
691 
692  switch( mLatticeType ){
693  case Primitive: //Primitive
694  {
695  for (int j=-x/2.0;j<x/2.0;++j){
696  for (int k=-y/2.0;k<y/2.0;++k){
697  for (int l=-z/2.0;l<z/2.0;++l){
698  res.push_back( motif.trs( vec(j,k,l) ) );
699  }
700  }
701  }
702  break;
703  }
704  case Body://Body
705  {
706  for (int j=-x/2.0;j<x/2.0;++j){
707  for (int k=-y/2.0;k<y/2.0;++k){
708  for (int l=-z/2.0;l<z/2.0;++l){
709  res.push_back( motif.trs( vec(j,k,l) ) );
710  res.push_back( motif.trs( vec(j,k,l) + vec(.5,.5,.5) ) );
711  }
712  }
713  }
714  break;
715  }
716  case AFace:
717  {
718  for (int j=-x/2.0;j<x/2.0;++j){
719  for (int k=-y/2.0;k<y/2.0;++k){
720  for (int l=-z/2.0;l<z/2.0;++l){
721  res.push_back( motif.trs( vec(j,k,l) ) );
722  res.push_back( motif.trs( vec(j,k,l) + vec(0,.5,.5) ) );
723  }
724  }
725  }
726  break;
727  }
728  case CFace:
729  {
730  for (int j=-x/2.0;j<x/2.0;++j){
731  for (int k=-y/2.0;k<y/2.0;++k){
732  for (int l=-z/2.0;l<z/2.0;++l){
733  res.push_back( motif.trs( vec(j,k,l) ) );
734  res.push_back( motif.trs( vec(j,k,l) + vec(.5,.5,0) ) );
735  }
736  }
737  }
738  break;
739  }
740  case HFace:
741  {
742  for (int j=-x/2.0;j<x/2.0;++j){
743  for (int k=-y/2.0;k<y/2.0;++k){
744  for (int l=-z/2.0;l<z/2.0;++l){
745  res.push_back( motif.trs( vec(j,k,l) ) );
746  res.push_back( motif.trs( vec(j,k,l) + vec(.3333333,.3333333,0) ) );
747  res.push_back( motif.trs( vec(j,k,l) + vec(.6666666,.6666666,0) ) );
748  }
749  }
750  }
751  break;
752  }
753  case Rhombo:
754  {
755  for (int j=-x/2.0;j<x/2.0;++j){
756  for (int k=-y/2.0;k<y/2.0;++k){
757  for (int l=-z/2.0;l<z/2.0;++l){
758  res.push_back( motif.trs( vec(j,k,l) ) );
759  res.push_back( motif.trs( vec(j,k,l) + vec(.3333333,.3333333,.3333333) ) );
760  res.push_back( motif.trs( vec(j,k,l) + vec(.6666666,.6666666,.6666666) ) );
761  }
762  }
763  }
764  break;
765  }
766  case Face2:
767  {
768  for (int j=-x/2.0;j<x/2.0;++j){
769  for (int k=-y/2.0;k<y/2.0;++k){
770  for (int l=-z/2.0;l<z/2.0;++l){
771  res.push_back( motif.trs( vec(j,k,l) ) );
772  for (int m =1;m<2;++m){
773  float t = (float)m/2;
774  res.push_back( motif.trs( vec(j,k,l) + vec(t,t,0) ) );
775  res.push_back( motif.trs( vec(j,k,l) + vec(0,t,t) ) );
776  res.push_back( motif.trs( vec(j,k,l) + vec(-t,0,t) ) );
777  }
778  }
779  }
780  }
781  break;
782  }
783  case Face3:
784  {
785  for (int j=-x/2.0;j<x/2.0;++j){
786  for (int k=-y/2.0;k<y/2.0;++k){
787  for (int l=-z/2.0;l<z/2.0;++l){
788  res.push_back( motif.trs( vec(j,k,l) ) );
789  for (int m =1;m<3;++m){
790  float t = (float)m/3;
791  res.push_back( motif.trs( vec(j,k,l) + vec(t,t,0) ) );
792  res.push_back( motif.trs( vec(j,k,l) + vec(0,t,t) ) );
793  res.push_back( motif.trs( vec(j,k,l) + vec(-t,0,t) ) );
794  }
795  }
796  }
797  }
798  break;
799  }
800 
801  }
802  return res;
803  }
804 
805  template<class T>
806  vector<T> hang(const vector<T>& motif, int x, int y, int z ){
807  vector<T> res;
808  for (auto& i : motif){
809  auto tmp = hang(i,x,y,z);
810  for (auto& j : tmp) res.push_back(j);
811  }
812  return res;
813  }
814 
815 };
816 
817 
818 } //vsr::
819 #endif /* ----- #ifndef vsr_group_INC ----- */
SimpleGroup(vector< V > v)
Instantiate with unit length pin group.
Definition: vsr_group.h:30
vector< T > hang(const T &motif, int x, int y, int z)
Hang a motif on a Lattice of dimensions x,y,z
Definition: vsr_group.h:689
V b
Generators.
Definition: vsr_group.h:133
NVec< 5 > Vec
Vector
Definition: vsr_cga3D_types.h:62
void set()
END case.
Definition: vsr_group.h:320
ND lattice, on a metric specified by V's type. Not a group, but a group can be made from it...
Definition: vsr_group.h:298
bool bPin
Pin or Spin.
Definition: vsr_group.h:136
Definition: vsr_group.h:129
Definition: vsr_group.h:345
Generic Geometric Number Types (templated on an algebra and a basis )
Definition: vsr_algebra.h:69
vector< T > operator()(const T &p)
Applies all operators on p motif and returns results.
Definition: vsr_group.h:34
vector< T > operator()(const T &p)
Applies all operators on p motif and returns results.
Definition: vsr_group.h:70
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
vector< decltype(V()*V()*V())> tops
Triple Reflection (abbar 3d group)
Definition: vsr_group.h:60
vector< V > ops
Pin Operators (Vec, etc)
Definition: vsr_group.h:58
Definition: vsr_group.h:561
Vec vec(float x, float y, float z)
Calculate a vector transformation basice on generators and ratio
Definition: vsr_group.h:680
SpaceGroup2D(int p, float ratio=1.0, bool pin=true, int div=1, bool ga=false, bool gb=false)
Constructor.
Definition: vsr_group.h:183
core namespaced operations that are metric-agnostic
vector< T > operator()(const vector< T > &p)
Applies all operations on a vector of type T.
Definition: vsr_group.h:111
vector< T > apply(const vector< T > &motif, int x, int y)
Apply to a vector of elements.
Definition: vsr_group.h:254
vector< decltype(V()*V())> sops
Spin Operators (Rot, etc)
Definition: vsr_group.h:59
vector< T > hang(const T &motif, int x, int y)
Don't apply operations, just hang on lattice points.
Definition: vsr_group.h:265
void set(int x, T...xs)
Recursively set each idx.
Definition: vsr_group.h:323
Lattice(int x, T...xs)
Feed in a list of ratios.
Definition: vsr_group.h:334
vector< T > hang(const vector< T > &motif, int x, int y)
Don't apply operations, just hang on lattice points.
Definition: vsr_group.h:279
typename V::space::translator Trs
Trs is the translator type of whatever conformal metric we are in.
Definition: vsr_group.h:56
int numSimple
number of simple roots used to generate group
Definition: vsr_group.h:52
vector< V > ops
Pin Operators (Vec, etc)
Definition: vsr_group.h:27
the versor library namespace
Definition: vsr_algebra.h:29
Definition: vsr_group.h:347
NBiv< 5 > Biv
Bivector
Definition: vsr_cga3D_types.h:63
int mP
Symmetry Group.
Definition: vsr_group.h:135
Definition: vsr_group.h:556
Definition: vsr_group.h:165
Definition: vsr_group.h:539
static Trs trs(const A &a)
vsr::cga::Translator from any type
Definition: vsr_cga3D_op.h:136
vector< decltype(V()*V()*Trs())> scrops
Screw Operators (Motor)
Definition: vsr_group.h:62
A Group of Operations called with group( sometype t ) or group( vector t) V are versors any...
Definition: vsr_group.h:50
vector< decltype(V()*Trs())> gops
Glide Operators.
Definition: vsr_group.h:61
Simple Reflection Group (no translating or gliding spinors)
Definition: vsr_group.h:26