versor  3.0
C++11 library for Geometric algebra
vsr_algebra.h
Go to the documentation of this file.
1 
23 #ifndef vsr_algebra_INC
24 #define vsr_algebra_INC
25 
26 #include "vsr_xlists.h"
27 #include "vsr_products.h"
28 
29 namespace vsr {
30 
31 
32  // using metric = Metric;
33  /*-----------------------------------------------------------------------------
34  * generates basis blade in dimension dim of grade
35 
36  note: to do: guard again negative dimensions and negative grades
37  *-----------------------------------------------------------------------------*/
38 
40  template<bits::type dim, bits::type grade>
41  struct blade {
42  using vec = typename vsr::Blade1<dim>::VEC;
43  using sub = typename blade<dim, grade-1>::type;
44  using type = typename EOProd<vec,sub>::basis;
45 
46  };
47 
49  template<bits::type dim>
50  struct blade<dim, 0>{
51  using type = Basis<0>;
52  };
53 
55  template<bits::type dim, bits::type grade=dim>
56  struct all_blades{
57  using sub = typename all_blades<dim, grade-1>::type;
58  using one = typename blade<dim, grade>::type;
59  using type = typename ICat< one, sub >::Type;
60  };
61 
63  template<bits::type dim>
64  struct all_blades<dim,0>{
65  using type = Basis<0>;
66  };
67 
68  //forward declaration of multivector
69  template<class algebra, class basis> struct Multivector;
70  //forward declaration of algebraImpl
71  template<class algebra, bool, bool> struct algebra_impl;
72  //forward declaration of named_types
73  template<class algebraimpl> struct named_types;
74 
95  template< class metric_type, class value_type >
96  struct algebra {
97 
98  using metric = metric_type;
99 
100  using value_t = value_type;
101 
102  static const int dim = metric::type::Num;
103 
105  template <class B> using mv_t = Multivector<algebra<metric, value_t>, B>;
106 
108  using impl = algebra_impl< algebra<metric, value_t>, metric::is_euclidean, metric::is_conformal >;
109 
110  template <class A, class B> using sum_basis_t = typename ICat< typename NotType< A, B >::Type, A >::Type;
111  template <class A, class B> using gp_basis_t = typename impl::template gp_arrow_t<A,B>::basis;
112  template <class A, class B> using op_basis_t = typename impl::template op_arrow_t<A,B>::basis;
113  template <class A, class B> using ip_basis_t = typename impl::template ip_arrow_t<A,B>::basis;
114 
115  // lift functions of A and B into the multivector form
116  template <class A, class B> using sum_lift_t = mv_t< sum_basis_t< A, B>>;
117  template <class A, class B> using gp_lift_t = mv_t< gp_basis_t<A,B> >;
118  template <class A, class B> using op_lift_t = mv_t< op_basis_t< A, B> >;
119  template <class A, class B> using ip_lift_t = mv_t< ip_basis_t< A, B> >;
120 
121  // bind the contents of multivectors A and B into the functions
122  template <class A, class B> using sum_t = sum_lift_t<typename A::basis,typename B::basis>;
123  template <class A, class B> using gp_t = gp_lift_t<typename A::basis,typename B::basis>;
124  template <class A, class B> using op_t = op_lift_t<typename A::basis,typename B::basis>;
125  template <class A, class B> using ip_t = ip_lift_t<typename A::basis,typename B::basis>;
126 
127  /*-----------------------------------------------------------------------------
128  * Sum Functions
129  *-----------------------------------------------------------------------------*/
131  template<class B>
132  static mv_t<B>
133  sum( const mv_t<B> & a, const mv_t<B>& b) {
134  mv_t<B> c;
135  for (int i = 0; i < B::Num; ++i) c[i] = a[i] + b[i];
136  return c;
137  }
139  template<class B>
140  static mv_t<B>
141  diff( const mv_t<B> & a, const mv_t<B>& b) {
142  mv_t<B> c;
143  for (int i = 0; i < B::Num; ++i) c[i] = a[i] - b[i];
144  return c;
145  }
146 
148  template<class B1, class B2>
149  static mv_t<typename ICat< typename NotType< B1, B2 >::Type, B1 >::Type>
150  sum( const mv_t<B1> & a, const mv_t<B2>& b) {
152  return sum( a.template cast<Ret>() , b.template cast<Ret>() );
153  }
155  template<class B1, class B2>
156  static mv_t<typename ICat< typename NotType< B1, B2 >::Type, B1 >::Type>
157  diff( const mv_t<B1> & a, const mv_t<B2>& b) {
159  return diff( a.template cast<Ret>() , b.template cast<Ret>() );
160  }
161 
163  template<class B>
164  static mv_t<typename ICat< typename NotType< Basis<0>, B >::Type, Basis<0> >::Type>
165  sumv( VSR_PRECISION a, const mv_t<B>& b) {
166  typedef mv_t<typename ICat< typename NotType< Basis<0>, B >::Type, Basis<0> >::Type> Ret;
167  return sum( Ret(a) , b.template cast<Ret>() );
168  }
169 
170  /*-----------------------------------------------------------------------------
171  * Product Functions (unknown return type)
172  *-----------------------------------------------------------------------------*/
173  template<class A, class B>
174  static constexpr auto gp(const A& a, const B& b) -> gp_t<A,B> {
175  typedef typename impl::template gp_arrow_t<typename A::basis, typename B::basis> x;
176  typedef mv_t<typename x::basis> type;
177  return x::Arrow::template Make<type>(a,b);
178  }
179  template<class A, class B>
180  static constexpr auto op(const A& a, const B& b) -> op_t<A,B> {
181  typedef typename impl::template op_arrow_t<typename A::basis, typename B::basis> x;
182  typedef mv_t<typename x::basis> type;
183  return x::Arrow::template Make<type>(a,b);
184  }
185  template<class A, class B>
186  static constexpr auto ip(const A& a, const B& b) -> ip_t<A,B> {
187  typedef typename impl::template ip_arrow_t<typename A::basis, typename B::basis> x;
188  typedef mv_t<typename x::basis> type;
189  return x::Arrow::template Make<type>(a,b);
190  }
191 
193  template<class A, class B>
194  static constexpr A spin(const A& a, const B& b) {
195  typedef gp_basis_t<typename B::basis, typename A::basis > tmp_basis;
196  //............................................lh...........rh.................return type
197  using x = typename impl::template rot_arrow_t<tmp_basis, typename B::basis, typename A::basis>;
198  return x::Arrow::template Make<A>( gp(b, a), Reverse<typename B::basis>::Type::template Make(b) );
199  }
200 
202  template<class A, class B>
203  static constexpr A reflect(const A& a, const B& b) {
204  typedef gp_basis_t<typename B::basis, typename A::basis > tmp_basis;
205  using x = typename impl::template rot_arrow_t<tmp_basis, typename B::basis, typename A::basis>;
206  return x::Arrow::template Make<A>( gp(b, a.involution() ), Reverse<typename B::basis>::Type::template Make(b) );
207  }
208 
210  template<typename B1, typename B2>
212 
214  template<typename B1, typename B2>
216 
218  template<typename B1, typename B2>
220 
222  template<typename B1, typename B2>
224 
226  template<bits::type grade>
228 
231 
234 
235 
236  using vector_basis = typename blade<dim,1>::type;
238 
239 
240  };
241 
242 
243 
244 
245  /*-----------------------------------------------------------------------------
246  * ALGEBRA SPECIFIC PRODUCTS
247  *-----------------------------------------------------------------------------*/
248  template<typename Algebra, bool Euclidean, bool Conformal>
249  struct algebra_impl {
250  // using algebra = Algebra;
251  };
252 
253  /*-----------------------------------------------------------------------------
254  * EUCLIDEAN (NO NEGATIVE METRIC)
255  *-----------------------------------------------------------------------------*/
256  template<typename Algebra>
257  struct algebra_impl<Algebra,true, false> {
258 
259  // static const bits::type dim = Algebra::dim;
260 
261  template <class A, class B> using gp_arrow_t = EGProd<A,B>;
262  template <class A, class B> using op_arrow_t = EOProd<A,B>;
263  template <class A, class B> using ip_arrow_t = EIProd<A,B>;
264 
265  template< class R, class A, class B> using rot_arrow_t = REGProd< R, A, B>;
266 
267  };
268 
269 
270 
271  /*-----------------------------------------------------------------------------
272  * Metric Product Functions (e.g for spacetime algebra)
273  *-----------------------------------------------------------------------------*/
274  template<typename Algebra>
275  struct algebra_impl<Algebra,false, false> {
276  using algebra = Algebra;
277  using metric_type = typename Algebra::metric::type;
278  // static const bits::type dim = Algebra::dim;
279 
280  template <class A, class B> using gp_arrow_t = MGProd<A, B, metric_type>;
281  template <class A, class B> using op_arrow_t = MOProd<A, B, metric_type>;
282  template <class A, class B> using ip_arrow_t = MIProd<A, B, metric_type>;
283 
284  template< class R, class A, class B> using rot_arrow_t = RMGProd< R, A, B, metric_type>;
285 
286  };
287 
288  /*-----------------------------------------------------------------------------
289  * CONFORMAL
290  *-----------------------------------------------------------------------------*/
291  template<typename Algebra>
292  struct algebra_impl<Algebra,false, true> {
293 
294  using metric_type = typename Algebra::metric::type;
295  // static const bits::type dim = Algebra::dim;
296 
297  template <class A, class B> using gp_arrow_t = CGProd<A, B, metric_type>;
298  template <class A, class B> using op_arrow_t = COProd<A, B, metric_type>;
299  template <class A, class B> using ip_arrow_t = CIProd<A, B, metric_type>;
300 
301  template< class R, class A, class B> using rot_arrow_t = RCGProd< R, A, B, metric_type>;
302  };
303 
304 
305 
306 
307  /*-----------------------------------------------------------------------------
308  * Default Metric Types don't exist . . . use ::vector
309  *-----------------------------------------------------------------------------*/
310  template<typename A>
311  struct named_types{
312 
313  using alg = typename A::algebra;
314  //use as e<1,2,3> will return e123 blade
315  template<bits::type ... N> using e_basis = Basis< bits::blade((1<<(N-1))...)>;
316  template<bits::type ... N> using e = Multivector<alg, e_basis<N...>>;
317 
318  using sca = Basis<0>;
319  using pss = Basis<bits::pss(alg::dim)>;
320  using vec = typename Blade1<alg::dim>::VEC;
321  using biv = typename alg::template op_basis_t<vec,vec>;
322  using tri = typename alg::template op_basis_t<vec,biv>;
323  using rot = typename alg::template sum_basis_t<biv,sca>;
324 
325 
326  };
327 
328  /*-----------------------------------------------------------------------------
329  * Default Euclidean Basis Types (specialize named_types to your own needs)
330  *-----------------------------------------------------------------------------*/
331  template<typename alg>
332  struct named_types<algebra_impl<alg,true,false>>{
333 
334  using algebra = alg;//AlgebraImpl<alg,true,false>;
335 
336  //use as e<1,2,3> will return e123 blade
337  template<bits::type ... N> using e_basis = Basis< bits::blade((1<<(N-1))...)>;
338  template<bits::type ... N> using e = Multivector<alg, e_basis<N...>>;
339 
340  using sca = Basis<0>;
341  using pss = Basis<bits::pss(alg::dim)>;
342  using vec = typename Blade1<alg::dim>::VEC;
343  using biv = typename algebra::template op_basis_t<vec,vec>;
344  using tri = typename algebra::template op_basis_t<vec,biv>;
345  using rot = typename algebra::template sum_basis_t<biv,sca>;
346  using euc = pss; //necessary redundancy to avoid errors when compiling euclidean duale() method
347 
348  using Sca = Multivector<alg,sca >;
349  using Pss = Multivector<alg,pss >;
350  using Vec = Multivector<alg,vec >;
351  using Biv = Multivector<alg,biv >;
352  using Tri = Multivector<alg,tri >;
353  using Rot = Multivector<alg,rot >;
354  using Euc = Multivector<alg,euc >;
355 
356  using scalar_basis = Basis<0>;
357  using pseudoscalar_basis = Basis<bits::pss(alg::dim)>;
358  using vector_basis = typename blade<alg::dim,1>::type;
359  using bivector_basis = typename blade<alg::dim,2>::type;
360  using trivector_basis = typename blade<alg::dim,3>::type;
361  using rotor_basis = typename algebra::template sum_basis_t<bivector_basis, scalar_basis>;
362  using euclidean_pseudoscalar_basis = pseudoscalar_basis;
363 
370 
371  };
372 
373 
374 
375  /*-----------------------------------------------------------------------------
376  * Default Conformal Basis Types
377  *-----------------------------------------------------------------------------*/
378  template<typename alg>
379  struct named_types<algebra_impl<alg,false,true>>{
380 
381  using algebra = alg;//AlgebraImpl<alg,false,true>;
382  //use as e<1,2,3> will return e123 blade
383  template<bits::type ... N> using e = Basis< bits::blade((1<<(N-1))...)>;
384 
385  //BASIS
386  using sca = Basis<0>;
387  using pss = Basis<bits::pss(algebra::dim)>;
388  using euc = Basis<bits::pss(algebra::dim-2)>;
389  using vec = typename Blade1<algebra::dim-2>::VEC;
390  using pnt = typename Blade1<algebra::dim>::VEC ;
391  using ori = typename basis_t::origin<algebra::dim> ;
392  using inf = typename basis_t::infinity<algebra::dim> ;
393  using mnk = typename basis_t::eplane<algebra::dim> ;
394 
395  using biv = typename algebra::template op_basis_t<vec,vec>;
396  using tri = typename algebra::template op_basis_t<vec,biv>;
397  using rot = typename algebra::template sum_basis_t<biv,sca>;
398  using tnv = typename algebra::template op_basis_t<vec,ori>;
399  using drv = typename algebra::template op_basis_t<vec,inf>;
400  using tnb = typename algebra::template op_basis_t<biv,ori>;
401  using drb = typename algebra::template op_basis_t<biv,inf>;
402  using tnt = typename algebra::template op_basis_t<tri,ori>;
403  using drt = typename algebra::template op_basis_t<tri,inf>;
404  using par = typename algebra::template op_basis_t<pnt,pnt>;
405  using cir = typename algebra::template op_basis_t<par,pnt>;
406  using sph = typename algebra::template op_basis_t<cir,pnt>;
407  using flp = typename algebra::template op_basis_t<pnt,inf>;
408  // using dll = typename algebra::template sum_basis_t<biv,drv>;
409  using lin = typename algebra::template op_basis_t<pnt,flp>;
410  using dll = typename algebra::template gp_basis_t<lin,pss>;
411  using dlp = typename algebra::template sum_basis_t<vec,inf>;
412  using pln = typename algebra::template op_basis_t<cir,inf>;
413  using trs = typename algebra::template sum_basis_t<drv, sca>;// 1 );
414  using trv = typename algebra::template sum_basis_t<tnv, sca>;// 1 );
415  using dil = typename algebra::template sum_basis_t<mnk, sca>;// 1 );
416  using tsd = typename algebra::template sum_basis_t<flp, sca>;// 1 );
417  using mot = typename algebra::template gp_basis_t<rot, trs>;
418  using bst = typename algebra::template sum_basis_t<par,sca>;
419  using con = typename algebra::template gp_basis_t<par, par>;
420  using dls = pnt;
421 
422  //MULTIVECTORS
423  using Sca = Multivector<alg,sca>;
424  using Pss = Multivector<alg,pss>;
425  using Euc = Multivector<alg,euc>;
426  using Vec = Multivector<alg,vec>;
427  using Pnt = Multivector<alg,pnt>;
428  using Ori = Multivector<alg,ori>;
429  using Inf = Multivector<alg,inf>;
430  using Mnk = Multivector<alg,mnk>;
431  using Biv = Multivector<alg,biv>;
432  using Tri = Multivector<alg,tri>;
433  using Rot = Multivector<alg,rot>;
434  using Tnv = Multivector<alg,tnv>;
435  using Drv = Multivector<alg,drv>;
436  using Tnb = Multivector<alg,tnb>;
437  using Drb = Multivector<alg,drb>;
438  using Tnt = Multivector<alg,tnt>;
439  using Drt = Multivector<alg,drt>;
440  using Par = Multivector<alg,par>;
441  using Cir = Multivector<alg,cir>;
442  using Sph = Multivector<alg,sph>;
443  using Flp = Multivector<alg,flp>;
444  using Dll = Multivector<alg,dll>;
445  using Lin = Multivector<alg,lin>;
446  using Dlp = Multivector<alg,dlp>;
447  using Pln = Multivector<alg,pln>;
448  using Trs = Multivector<alg,trs>;
449  using Trv = Multivector<alg,trv>;
450  using Dil = Multivector<alg,dil>;
451  using Tsd = Multivector<alg,tsd>;
452  using Mot = Multivector<alg,mot>;
453  using Bst = Multivector<alg,bst>;
454  using Con = Multivector<alg,con>;
455  using Dls = Multivector<alg,dls>;
456 
457 
458  using scalar = Multivector<alg,sca>;
461  using vector = Multivector<alg,vec>;
462  using point = Multivector<alg,pnt>;
468  using rotor = Multivector<alg,rot>;
475  using pair = Multivector<alg,par>;
480  using line = Multivector<alg,lin>;
482  using plane = Multivector<alg,pln>;
487  using motor = Multivector<alg,mot>;
488  using boost = Multivector<alg,bst>;
491 
492 
493  using Scalar = Multivector<alg,sca>;
496  using Vector = Multivector<alg,vec>;
497  using Point = Multivector<alg,pnt>;
503  using Rotor = Multivector<alg,rot>;
510  using Pair = Multivector<alg,par>;
515  using Line = Multivector<alg,lin>;
517  using Plane = Multivector<alg,pln>;
522  using Motor = Multivector<alg,mot>;
523  using Boost = Multivector<alg,bst>;
526 
527 
528 
529  };
530 
531 
532 
533 
534 
535 } //vsr::
536 
537 #endif /* ----- #ifndef vsr_algebra_INC ----- */
static mv_t< typename ICat< typename NotType< B1, B2 >::Type, B1 >::Type > sum(const mv_t< B1 > &a, const mv_t< B2 > &b)
Sum of Different types.
Definition: vsr_algebra.h:150
static const int dim
– Dimension of Algebra (2,3,4,5,etc)
Definition: vsr_algebra.h:102
static mv_t< B > diff(const mv_t< B > &a, const mv_t< B > &b)
Difference of Similar types.
Definition: vsr_algebra.h:141
An algebra instance is templated on:
Definition: vsr_algebra.h:96
Generic Geometric Number Types (templated on an algebra and a basis )
Definition: vsr_algebra.h:69
Definition: vsr_algebra.h:73
static mv_t< typename ICat< typename NotType< Basis< 0 >, B >::Type, Basis< 0 > >::Type > sumv(VSR_PRECISION a, const mv_t< B > &b)
Sum some scalar value.
Definition: vsr_algebra.h:165
all blades within a spatial dim upto and including maxgrade
Definition: vsr_algebra.h:56
typename blade< dim, 1 >::type vector_basis
– 1-blade vector basis (no data)
Definition: vsr_algebra.h:236
Definition: vsr_algebra.h:71
static mv_t< typename ICat< typename NotType< B1, B2 >::Type, B1 >::Type > diff(const mv_t< B1 > &a, const mv_t< B2 > &b)
Difference of Different types.
Definition: vsr_algebra.h:157
static constexpr A reflect(const A &a, const B &b)
Reflect a by b, return type a.
Definition: vsr_algebra.h:203
the versor library namespace
Definition: vsr_algebra.h:29
static constexpr A spin(const A &a, const B &b)
Spin a by b, return type a.
Definition: vsr_algebra.h:194
metafunction to construct a basis blade type from spatial dimension and subspace grade ...
Definition: vsr_algebra.h:41
metric_type metric
– Metric, with signature, whether Euclidean, Projective, Conformal, etc
Definition: vsr_algebra.h:98
static mv_t< B > sum(const mv_t< B > &a, const mv_t< B > &b)
Sum of Similar types.
Definition: vsr_algebra.h:133
value_type value_t
– Field over which Algebra is Defined (e.g. float, double, complex)
Definition: vsr_algebra.h:100