1 #ifndef _GLUCAT_CLIFFORD_ALGEBRA_IMP_H 2 #define _GLUCAT_CLIFFORD_ALGEBRA_IMP_H 63 template<
typename Scalar_T,
typename Index_Set_T,
typename Multivector_T>
67 {
return "clifford_algebra"; }
72 template<
typename, const index_t, const index_t>
class Multivector,
73 template<
typename, const index_t, const index_t>
class RHS,
78 operator!= (
const Multivector<Scalar_T,LO,HI>& lhs,
const RHS<Scalar_T,LO,HI>& rhs)
79 {
return !(lhs == rhs); }
82 template<
template<
typename, const index_t, const index_t>
class Multivector,
86 operator!= (
const Multivector<Scalar_T,LO,HI>& lhs,
const Scalar_T& scr)
87 {
return !(lhs == scr); }
90 template<
template<
typename, const index_t, const index_t>
class Multivector,
94 operator!= (
const Scalar_T& scr,
const Multivector<Scalar_T,LO,HI>& rhs)
95 {
return !(rhs == scr); }
98 template<
template<
typename, const index_t, const index_t>
class Multivector,
101 const Multivector<Scalar_T,LO,HI>
102 operator+ (
const Multivector<Scalar_T,LO,HI>& lhs,
const Scalar_T& scr)
104 Multivector<Scalar_T,LO,HI> result = lhs;
105 return result += scr;
109 template<
template<
typename, const index_t, const index_t>
class Multivector,
112 const Multivector<Scalar_T,LO,HI>
113 operator+ (
const Scalar_T& scr,
const Multivector<Scalar_T,LO,HI>& rhs)
121 template<
typename, const index_t, const index_t>
class Multivector,
122 template<
typename, const index_t, const index_t>
class RHS,
126 const Multivector<Scalar_T,LO,HI>
127 operator+ (
const Multivector<Scalar_T,LO,HI>& lhs,
const RHS<Scalar_T,LO,HI>& rhs)
129 Multivector<Scalar_T,LO,HI> result = lhs;
130 return result += rhs;
134 template<
template<
typename, const index_t, const index_t>
class Multivector,
137 const Multivector<Scalar_T,LO,HI>
138 operator- (
const Multivector<Scalar_T,LO,HI>& lhs,
const Scalar_T& scr)
140 Multivector<Scalar_T,LO,HI> result = lhs;
141 return result += -scr;
145 template<
template<
typename, const index_t, const index_t>
class Multivector,
148 const Multivector<Scalar_T,LO,HI>
149 operator- (
const Scalar_T& scr,
const Multivector<Scalar_T,LO,HI>& rhs)
150 {
return -rhs + scr; }
155 template<
typename, const index_t, const index_t>
class Multivector,
156 template<
typename, const index_t, const index_t>
class RHS,
160 const Multivector<Scalar_T,LO,HI>
161 operator- (
const Multivector<Scalar_T,LO,HI>& lhs,
const RHS<Scalar_T,LO,HI>& rhs)
163 Multivector<Scalar_T,LO,HI> result = lhs;
164 return result -= rhs;
168 template<
template<
typename, const index_t, const index_t>
class Multivector,
171 const Multivector<Scalar_T,LO,HI>
172 operator* (
const Multivector<Scalar_T,LO,HI>& lhs,
const Scalar_T& scr)
174 Multivector<Scalar_T,LO,HI> result = lhs;
175 return result *= scr;
179 template<
template<
typename, const index_t, const index_t>
class Multivector,
182 const Multivector<Scalar_T,LO,HI>
183 operator* (
const Scalar_T& scr,
const Multivector<Scalar_T,LO,HI>& rhs)
192 template<
typename, const index_t, const index_t>
class Multivector,
193 template<
typename, const index_t, const index_t>
class RHS,
197 const Multivector<Scalar_T,LO,HI>
198 operator* (
const Multivector<Scalar_T,LO,HI>& lhs,
const RHS<Scalar_T,LO,HI>& rhs)
200 typedef Multivector<Scalar_T,LO,HI> multivector_t;
201 return lhs * multivector_t(rhs);
207 template<
typename, const index_t, const index_t>
class Multivector,
208 template<
typename, const index_t, const index_t>
class RHS,
212 const Multivector<Scalar_T,LO,HI>
213 operator^ (
const Multivector<Scalar_T,LO,HI>& lhs,
const RHS<Scalar_T,LO,HI>& rhs)
215 typedef Multivector<Scalar_T,LO,HI> multivector_t;
216 return lhs ^ multivector_t(rhs);
222 template<
typename, const index_t, const index_t>
class Multivector,
223 template<
typename, const index_t, const index_t>
class RHS,
227 const Multivector<Scalar_T,LO,HI>
228 operator& (
const Multivector<Scalar_T,LO,HI>& lhs,
const RHS<Scalar_T,LO,HI>& rhs)
230 typedef Multivector<Scalar_T,LO,HI> multivector_t;
231 return lhs & multivector_t(rhs);
237 template<
typename, const index_t, const index_t>
class Multivector,
238 template<
typename, const index_t, const index_t>
class RHS,
242 const Multivector<Scalar_T,LO,HI>
243 operator% (
const Multivector<Scalar_T,LO,HI>& lhs,
const RHS<Scalar_T,LO,HI>& rhs)
245 typedef Multivector<Scalar_T,LO,HI> multivector_t;
246 return lhs % multivector_t(rhs);
252 template<
typename, const index_t, const index_t>
class Multivector,
253 template<
typename, const index_t, const index_t>
class RHS,
258 star (
const Multivector<Scalar_T,LO,HI>& lhs,
const RHS<Scalar_T,LO,HI>& rhs)
260 typedef Multivector<Scalar_T,LO,HI> multivector_t;
261 return star(lhs, multivector_t(rhs));
265 template<
template<
typename, const index_t, const index_t>
class Multivector,
268 const Multivector<Scalar_T,LO,HI>
269 operator/ (
const Multivector<Scalar_T,LO,HI>& lhs,
const Scalar_T& scr)
271 Multivector<Scalar_T,LO,HI> result = lhs;
272 return result /= scr;
276 template<
template<
typename, const index_t, const index_t>
class Multivector,
279 const Multivector<Scalar_T,LO,HI>
280 operator/ (
const Scalar_T& scr,
const Multivector<Scalar_T,LO,HI>& rhs)
282 Multivector<Scalar_T,LO,HI> result = scr;
283 return result /= rhs;
289 template<
typename, const index_t, const index_t>
class Multivector,
290 template<
typename, const index_t, const index_t>
class RHS,
294 const Multivector<Scalar_T,LO,HI>
295 operator/ (
const Multivector<Scalar_T,LO,HI>& lhs,
const RHS<Scalar_T,LO,HI>& rhs)
297 typedef Multivector<Scalar_T,LO,HI> multivector_t;
298 return lhs / multivector_t(rhs);
304 template<
typename, const index_t, const index_t>
class Multivector,
305 template<
typename, const index_t, const index_t>
class RHS,
309 const Multivector<Scalar_T,LO,HI>
310 operator| (
const Multivector<Scalar_T,LO,HI>& lhs,
const RHS<Scalar_T,LO,HI>& rhs)
312 typedef Multivector<Scalar_T,LO,HI> multivector_t;
313 return lhs | multivector_t(rhs);
317 template<
template<
typename, const index_t, const index_t>
class Multivector,
320 const Multivector<Scalar_T,LO,HI>
321 inv(
const Multivector<Scalar_T,LO,HI>& val)
322 {
return val.inv(); }
325 template<
template<
typename, const index_t, const index_t>
class Multivector,
327 const Multivector<Scalar_T,LO,HI>
328 pow(
const Multivector<Scalar_T,LO,HI>& lhs,
int rhs)
330 typedef Multivector<Scalar_T,LO,HI> multivector_t;
336 if (lhs == Scalar_T(0))
337 return traits_t::NaN();
343 multivector_t result = Scalar_T(1);
355 template<
typename, const index_t, const index_t>
class Multivector,
356 template<
typename, const index_t, const index_t>
class RHS,
360 const Multivector<Scalar_T,LO,HI>
361 pow(
const Multivector<Scalar_T,LO,HI>& lhs,
const RHS<Scalar_T,LO,HI>& rhs)
365 if (lhs == Scalar_T(0))
367 const Scalar_T m = rhs.scalar();
377 return exp(
log(lhs) * rhs);
381 template<
template<
typename, const index_t, const index_t>
class Multivector,
383 const Multivector<Scalar_T,LO,HI>
384 outer_pow(
const Multivector<Scalar_T,LO,HI>& lhs,
int rhs)
385 {
return lhs.outer_pow(rhs); }
388 template<
template<
typename, const index_t, const index_t>
class Multivector,
392 scalar(
const Multivector<Scalar_T,LO,HI>& val)
393 {
return val.scalar(); }
396 template<
template<
typename, const index_t, const index_t>
class Multivector,
400 real(
const Multivector<Scalar_T,LO,HI>& val)
401 {
return val.scalar(); }
406 template<
typename, const index_t, const index_t>
class Multivector,
411 imag(
const Multivector<Scalar_T,LO,HI>& val)
412 {
return Scalar_T(0); }
415 template<
template<
typename, const index_t, const index_t>
class Multivector,
418 const Multivector<Scalar_T,LO,HI>
419 pure(
const Multivector<Scalar_T,LO,HI>& val)
420 {
return val - val.scalar(); }
423 template<
template<
typename, const index_t, const index_t>
class Multivector,
426 const Multivector<Scalar_T,LO,HI>
427 even(
const Multivector<Scalar_T,LO,HI>& val)
428 {
return val.even(); }
431 template<
template<
typename, const index_t, const index_t>
class Multivector,
434 const Multivector<Scalar_T,LO,HI>
435 odd(
const Multivector<Scalar_T,LO,HI>& val)
436 {
return val.odd(); }
439 template<
template<
typename, const index_t, const index_t>
class Multivector,
442 const std::vector<Scalar_T>
444 {
return val.vector_part(); }
447 template<
template<
typename, const index_t, const index_t>
class Multivector,
450 const Multivector<Scalar_T,LO,HI>
452 {
return val.involute(); }
455 template<
template<
typename, const index_t, const index_t>
class Multivector,
458 const Multivector<Scalar_T,LO,HI>
459 reverse(
const Multivector<Scalar_T,LO,HI>& val)
460 {
return val.reverse(); }
463 template<
template<
typename, const index_t, const index_t>
class Multivector,
466 const Multivector<Scalar_T,LO,HI>
467 conj(
const Multivector<Scalar_T,LO,HI>& val)
468 {
return val.conj(); }
471 template<
template<
typename, const index_t, const index_t>
class Multivector,
475 quad(
const Multivector<Scalar_T,LO,HI>& val)
476 {
return val.quad(); }
479 template<
template<
typename, const index_t, const index_t>
class Multivector,
483 norm(
const Multivector<Scalar_T,LO,HI>& val)
484 {
return val.norm(); }
487 template<
template<
typename, const index_t, const index_t>
class Multivector,
491 abs(
const Multivector<Scalar_T,LO,HI>& val)
495 template<
template<
typename, const index_t, const index_t>
class Multivector,
499 max_abs(
const Multivector<Scalar_T,LO,HI>& val)
500 {
return val.max_abs(); }
503 template<
template<
typename, const index_t, const index_t>
class Multivector,
505 const Multivector<Scalar_T,LO,HI>
508 typedef Multivector<Scalar_T,LO,HI> multivector_t;
510 typedef typename multivector_t::index_set_t index_set_t;
512 index_set_t frm = val.frame();
544 if ((incp[new_bott] == 0) && (incq[new_bott] == 0))
545 return multivector_t(frm, Scalar_T(1));
548 return traits_t::NaN();
553 template<
template<
typename, const index_t, const index_t>
class Multivector,
556 const Multivector<Scalar_T,LO,HI>
561 template<
template<
typename, const index_t, const index_t>
class Multivector,
567 const Multivector<Scalar_T,LO,HI>&
i,
const bool prechecked =
false)
571 typedef Multivector<Scalar_T,LO,HI> multivector_t;
572 typedef typename multivector_t::index_set_t index_set_t;
573 typedef typename multivector_t::error_t error_t;
575 const index_set_t i_frame =
i.frame();
578 (val.frame() | i_frame) != i_frame ||
580 throw error_t(
"check_complex(val, i): i is not a valid complexifier for val");
585 template<
template<
typename, const index_t, const index_t>
class Multivector,
588 const Multivector<Scalar_T,LO,HI>
589 sqrt(
const Multivector<Scalar_T,LO,HI>& val,
const Multivector<Scalar_T,LO,HI>&
i,
bool prechecked)
590 {
return sqrt(val,
i, prechecked); }
593 template<
template<
typename, const index_t, const index_t>
class Multivector,
596 const Multivector<Scalar_T,LO,HI>
597 sqrt(
const Multivector<Scalar_T,LO,HI>& val)
601 template<
template<
typename, const index_t, const index_t>
class Multivector,
603 const Multivector<Scalar_T,LO,HI>
612 const Scalar_T scalar_val =
scalar(val);
614 if (traits_t::isNaN_or_isInf(scalar_exp))
615 return traits_t::NaN();
616 if (val == scalar_val)
619 typedef Multivector<Scalar_T,LO,HI> multivector_t;
620 multivector_t A = val - scalar_val;
621 const Scalar_T pure_scale2 = A.norm();
623 if (traits_t::isNaN_or_isInf(pure_scale2))
624 return traits_t::NaN();
625 if (pure_scale2 == Scalar_T(0))
628 const int ilog2_scale =
629 std::max(0, traits_t::to_int(ceil((
log2(pure_scale2) + Scalar_T(A.frame().count()))/Scalar_T(2))) - 3);
630 const Scalar_T i_scale =
traits_t::pow(Scalar_T(2), ilog2_scale);
631 if (traits_t::isNaN_or_isInf(i_scale))
632 return traits_t::NaN();
635 multivector_t pure_exp;
637 typedef std::numeric_limits<Scalar_T> limits_t;
638 const int nbr_even_powers = 2*(limits_t::digits / 32) + 4;
641 const int max_power = 2*nbr_even_powers + 1;
642 static Scalar_T c[max_power+1];
643 if (c[0] != Scalar_T(1))
650 c[k+1] = c[k]*(max_power-k) / ((2*max_power-k)*(k+1));
654 multivector_t AA[nbr_even_powers];
656 AA[1] = AA[0] * AA[0];
659 k != nbr_even_powers;
661 AA[k] = AA[k-2] * AA[1];
664 multivector_t residual = 0;
665 multivector_t U = c[0];
668 k != nbr_even_powers;
671 const multivector_t& term = AA[k]*c[2*k + 2] - residual;
672 const multivector_t& sum = U + term;
673 residual = (sum - U) - term;
677 multivector_t AV = c[1];
680 k != nbr_even_powers;
683 const multivector_t& term = AA[k]*c[2*k + 3] - residual;
684 const multivector_t& sum = AV + term;
685 residual = (sum - AV) - term;
689 pure_exp = (U+AV) / (U-AV);
695 pure_exp *= pure_exp;
696 return pure_exp * scalar_exp;
700 template<
template<
typename, const index_t, const index_t>
class Multivector,
703 const Multivector<Scalar_T,LO,HI>
704 log(
const Multivector<Scalar_T,LO,HI>& val,
const Multivector<Scalar_T,LO,HI>&
i,
bool prechecked)
705 {
return log(val,
i, prechecked); }
708 template<
template<
typename, const index_t, const index_t>
class Multivector,
711 const Multivector<Scalar_T,LO,HI>
712 log(
const Multivector<Scalar_T,LO,HI>& val)
716 template<
template<
typename, const index_t, const index_t>
class Multivector,
719 const Multivector<Scalar_T,LO,HI>
720 cosh(
const Multivector<Scalar_T,LO,HI>& val)
724 return traits_t::NaN();
726 const Scalar_T& s =
scalar(val);
729 return (
exp(val)+
exp(-val)) / Scalar_T(2);
734 template<
template<
typename, const index_t, const index_t>
class Multivector,
737 const Multivector<Scalar_T,LO,HI>
738 acosh(
const Multivector<Scalar_T,LO,HI>& val,
const Multivector<Scalar_T,LO,HI>&
i,
bool prechecked)
743 return traits_t::NaN();
745 typedef Multivector<Scalar_T,LO,HI> multivector_t;
746 const multivector_t radical =
sqrt(val*val - Scalar_T(1),
i,
true);
747 return (
norm(val + radical) >=
norm(val))
748 ?
log(val + radical,
i,
true)
749 : -
log(val - radical,
i,
true);
754 template<
template<
typename, const index_t, const index_t>
class Multivector,
757 const Multivector<Scalar_T,LO,HI>
758 acosh(
const Multivector<Scalar_T,LO,HI>& val)
762 template<
template<
typename, const index_t, const index_t>
class Multivector,
764 const Multivector<Scalar_T,LO,HI>
765 cos(
const Multivector<Scalar_T,LO,HI>& val,
const Multivector<Scalar_T,LO,HI>&
i,
bool prechecked)
769 return traits_t::NaN();
771 const Scalar_T& s =
scalar(val);
777 typedef Multivector<Scalar_T,LO,HI> multivector_t;
778 static const Scalar_T& twopi = Scalar_T(2) *
traits_t::pi();
779 const multivector_t& z =
i *
780 (val - s + traits_t::fmod(s, twopi));
781 return (
exp(z)+
exp(-z)) / Scalar_T(2);
785 template<
template<
typename, const index_t, const index_t>
class Multivector,
788 const Multivector<Scalar_T,LO,HI>
789 cos(
const Multivector<Scalar_T,LO,HI>& val)
794 template<
template<
typename, const index_t, const index_t>
class Multivector,
797 const Multivector<Scalar_T,LO,HI>
798 acos(
const Multivector<Scalar_T,LO,HI>& val,
const Multivector<Scalar_T,LO,HI>&
i,
bool prechecked)
802 return traits_t::NaN();
804 const Scalar_T& realval = val.scalar();
809 return i *
acosh(val,
i,
true);
814 template<
template<
typename, const index_t, const index_t>
class Multivector,
817 const Multivector<Scalar_T,LO,HI>
818 acos(
const Multivector<Scalar_T,LO,HI>& val)
822 template<
template<
typename, const index_t, const index_t>
class Multivector,
825 const Multivector<Scalar_T,LO,HI>
826 sinh(
const Multivector<Scalar_T,LO,HI>& val)
830 return traits_t::NaN();
832 const Scalar_T& s =
scalar(val);
836 return (
exp(val)-
exp(-val)) / Scalar_T(2);
841 template<
template<
typename, const index_t, const index_t>
class Multivector,
844 const Multivector<Scalar_T,LO,HI>
845 asinh(
const Multivector<Scalar_T,LO,HI>& val,
const Multivector<Scalar_T,LO,HI>&
i,
bool prechecked)
850 return traits_t::NaN();
852 typedef Multivector<Scalar_T,LO,HI> multivector_t;
853 const multivector_t radical =
sqrt(val*val + Scalar_T(1),
i,
true);
854 return (
norm(val + radical) >=
norm(val))
855 ?
log( val + radical,
i,
true)
856 : -
log(-val + radical,
i,
true);
861 template<
template<
typename, const index_t, const index_t>
class Multivector,
864 const Multivector<Scalar_T,LO,HI>
865 asinh(
const Multivector<Scalar_T,LO,HI>& val)
869 template<
template<
typename, const index_t, const index_t>
class Multivector,
871 const Multivector<Scalar_T,LO,HI>
872 sin(
const Multivector<Scalar_T,LO,HI>& val,
const Multivector<Scalar_T,LO,HI>&
i,
bool prechecked)
876 return traits_t::NaN();
878 const Scalar_T& s =
scalar(val);
884 typedef Multivector<Scalar_T,LO,HI> multivector_t;
885 static const Scalar_T& twopi = Scalar_T(2) *
traits_t::pi();
886 const multivector_t& z =
i *
887 (val - s + traits_t::fmod(s, twopi));
888 return i * (
exp(-z)-
exp(z)) / Scalar_T(2);
892 template<
template<
typename, const index_t, const index_t>
class Multivector,
895 const Multivector<Scalar_T,LO,HI>
896 sin(
const Multivector<Scalar_T,LO,HI>& val)
901 template<
template<
typename, const index_t, const index_t>
class Multivector,
904 const Multivector<Scalar_T,LO,HI>
905 asin(
const Multivector<Scalar_T,LO,HI>& val,
const Multivector<Scalar_T,LO,HI>&
i,
bool prechecked)
909 return traits_t::NaN();
911 const Scalar_T& realval = val.scalar();
916 return -
i *
asinh(
i * val,
i,
true);
921 template<
template<
typename, const index_t, const index_t>
class Multivector,
924 const Multivector<Scalar_T,LO,HI>
925 asin(
const Multivector<Scalar_T,LO,HI>& val)
929 template<
template<
typename, const index_t, const index_t>
class Multivector,
932 const Multivector<Scalar_T,LO,HI>
933 tanh(
const Multivector<Scalar_T,LO,HI>& val)
937 return traits_t::NaN();
939 const Scalar_T& s =
scalar(val);
948 template<
template<
typename, const index_t, const index_t>
class Multivector,
951 const Multivector<Scalar_T,LO,HI>
952 atanh(
const Multivector<Scalar_T,LO,HI>& val,
const Multivector<Scalar_T,LO,HI>&
i,
bool prechecked)
958 : (
norm(val + Scalar_T(1)) >
norm(val - Scalar_T(1)))
959 ? (
log(val + Scalar_T(1),
i,
true) -
log(-val + Scalar_T(1),
i,
true)) / Scalar_T(2)
960 :
log((val + Scalar_T(1)) / (-val + Scalar_T(1)),
i,
true) / Scalar_T(2);
965 template<
template<
typename, const index_t, const index_t>
class Multivector,
968 const Multivector<Scalar_T,LO,HI>
969 atanh(
const Multivector<Scalar_T,LO,HI>& val)
973 template<
template<
typename, const index_t, const index_t>
class Multivector,
976 const Multivector<Scalar_T,LO,HI>
977 tan(
const Multivector<Scalar_T,LO,HI>& val,
const Multivector<Scalar_T,LO,HI>&
i,
bool prechecked)
981 return traits_t::NaN();
983 const Scalar_T& s =
scalar(val);
988 return sin(val,
i,
true) /
cos(val,
i,
true);
992 template<
template<
typename, const index_t, const index_t>
class Multivector,
995 const Multivector<Scalar_T,LO,HI>
996 tan(
const Multivector<Scalar_T,LO,HI>& val)
1001 template<
template<
typename, const index_t, const index_t>
class Multivector,
1004 const Multivector<Scalar_T,LO,HI>
1005 atan(
const Multivector<Scalar_T,LO,HI>& val,
const Multivector<Scalar_T,LO,HI>&
i,
bool prechecked)
1009 return traits_t::NaN();
1011 const Scalar_T& s =
scalar(val);
1016 return -
i *
atanh(
i * val,
i,
true);
1021 template<
template<
typename, const index_t, const index_t>
class Multivector,
1024 const Multivector<Scalar_T,LO,HI>
1025 atan(
const Multivector<Scalar_T,LO,HI>& val)
1029 #endif // _GLUCAT_CLIFFORD_ALGEBRA_IMP_H const Multivector< Scalar_T, LO, HI > pure(const Multivector< Scalar_T, LO, HI > &val)
Pure part.
Scalar_T star(const Multivector< Scalar_T, LO, HI > &lhs, const RHS< Scalar_T, LO, HI > &rhs)
Hestenes scalar product.
const Multivector< Scalar_T, LO, HI > sqrt(const Multivector< Scalar_T, LO, HI > &val, const Multivector< Scalar_T, LO, HI > &i, const bool prechecked=false)
Square root of multivector with specified complexifier.
const Multivector< Scalar_T, LO, HI > acosh(const Multivector< Scalar_T, LO, HI > &val, const Multivector< Scalar_T, LO, HI > &i, const bool prechecked=false)
Inverse hyperbolic cosine of multivector with specified complexifier.
const Multivector< Scalar_T, LO, HI > operator/(const Multivector< Scalar_T, LO, HI > &lhs, const Scalar_T &scr)
Quotient of multivector and scalar.
const Multivector< Scalar_T, LO, HI > sinh(const Multivector< Scalar_T, LO, HI > &val)
Hyperbolic sine of multivector.
Scalar_T abs(const Multivector< Scalar_T, LO, HI > &val)
Absolute value == sqrt(norm)
const Multivector< Scalar_T, LO, HI > operator*(const Multivector< Scalar_T, LO, HI > &lhs, const Scalar_T &scr)
Product of multivector and scalar.
const Multivector< Scalar_T, LO, HI > log(const Multivector< Scalar_T, LO, HI > &val, const Multivector< Scalar_T, LO, HI > &i, const bool prechecked=false)
Natural logarithm of multivector with specified complexifier.
const Multivector< Scalar_T, LO, HI > conj(const Multivector< Scalar_T, LO, HI > &val)
Conjugation, rev o invo == invo o rev.
Scalar_T quad(const Multivector< Scalar_T, LO, HI > &val)
Scalar_T quadratic form == (rev(x)*x)(0)
Scalar_T norm(const Multivector< Scalar_T, LO, HI > &val)
Scalar_T norm == sum of norm of coordinates.
const Multivector< Scalar_T, LO, HI > odd(const Multivector< Scalar_T, LO, HI > &val)
Odd part.
Extra traits which extend numeric limits.
const Multivector< Scalar_T, LO, HI > clifford_exp(const Multivector< Scalar_T, LO, HI > &val)
Exponential of multivector.
const Multivector< Scalar_T, LO, HI > pow(const Multivector< Scalar_T, LO, HI > &lhs, int rhs)
Integer power of multivector.
static void check_complex(const Multivector< Scalar_T, LO, HI > &val, const Multivector< Scalar_T, LO, HI > &i, const bool prechecked=false)
Check that i is a valid complexifier for val.
Scalar_T log2(const Scalar_T &x)
Log base 2 of scalar.
Scalar_T imag(const Multivector< Scalar_T, LO, HI > &val)
Imaginary part: deprecated (always 0)
static const std::string classname()
const Multivector< Scalar_T, LO, HI > outer_pow(const Multivector< Scalar_T, LO, HI > &lhs, int rhs)
Outer product power of multivector.
const Multivector< Scalar_T, LO, HI > operator^(const Multivector< Scalar_T, LO, HI > &lhs, const RHS< Scalar_T, LO, HI > &rhs)
Outer product.
const Multivector< Scalar_T, LO, HI > sin(const Multivector< Scalar_T, LO, HI > &val, const Multivector< Scalar_T, LO, HI > &i, const bool prechecked=false)
Sine of multivector with specified complexifier.
const Multivector< Scalar_T, LO, HI > elliptic(const Multivector< Scalar_T, LO, HI > &val)
const std::vector< Scalar_T > vector_part(const Multivector< Scalar_T, LO, HI > &val)
Vector part of multivector, as a vector_t with respect to frame()
const Multivector< Scalar_T, LO, HI > atanh(const Multivector< Scalar_T, LO, HI > &val, const Multivector< Scalar_T, LO, HI > &i, const bool prechecked=false)
Inverse hyperbolic tangent of multivector with specified complexifier.
const Multivector< Scalar_T, LO, HI > reverse(const Multivector< Scalar_T, LO, HI > &val)
Reversion, eg. {1}*{2} -> {2}*{1}.
const framed_multi< Scalar_T, LO, HI > exp(const framed_multi< Scalar_T, LO, HI > &val)
Exponential of multivector.
static Scalar_T sqrt(const Scalar_T &val)
Square root of scalar.
const Multivector< Scalar_T, LO, HI > cos(const Multivector< Scalar_T, LO, HI > &val, const Multivector< Scalar_T, LO, HI > &i, const bool prechecked=false)
Cosine of multivector with specified complexifier.
const Multivector< Scalar_T, LO, HI > tanh(const Multivector< Scalar_T, LO, HI > &val)
Hyperbolic tangent of multivector.
const Multivector< Scalar_T, LO, HI > operator+(const Multivector< Scalar_T, LO, HI > &lhs, const Scalar_T &scr)
Geometric sum of multivector and scalar.
const Multivector< Scalar_T, LO, HI > inv(const Multivector< Scalar_T, LO, HI > &val)
Geometric multiplicative inverse.
const Multivector< Scalar_T, LO, HI > operator%(const Multivector< Scalar_T, LO, HI > &lhs, const RHS< Scalar_T, LO, HI > &rhs)
Left contraction.
const Multivector< Scalar_T, LO, HI > asin(const Multivector< Scalar_T, LO, HI > &val, const Multivector< Scalar_T, LO, HI > &i, const bool prechecked=false)
Inverse sine of multivector with specified complexifier.
Scalar_T scalar(const Multivector< Scalar_T, LO, HI > &val)
Scalar part.
const Multivector< Scalar_T, LO, HI > complexifier(const Multivector< Scalar_T, LO, HI > &val)
Square root of -1 which commutes with all members of the frame of the given multivector.
const Multivector< Scalar_T, LO, HI > involute(const Multivector< Scalar_T, LO, HI > &val)
Main involution, each {i} is replaced by -{i} in each term, eg. {1}*{2} -> (-{2})*(-{1}) ...
const Multivector< Scalar_T, LO, HI > atan(const Multivector< Scalar_T, LO, HI > &val, const Multivector< Scalar_T, LO, HI > &i, const bool prechecked=false)
Inverse tangent of multivector with specified complexifier.
const Multivector< Scalar_T, LO, HI > tan(const Multivector< Scalar_T, LO, HI > &val, const Multivector< Scalar_T, LO, HI > &i, const bool prechecked=false)
Tangent of multivector with specified complexifier.
Scalar_T real(const Multivector< Scalar_T, LO, HI > &val)
Real part: synonym for scalar part.
const Multivector< Scalar_T, LO, HI > operator|(const Multivector< Scalar_T, LO, HI > &lhs, const RHS< Scalar_T, LO, HI > &rhs)
Transformation via twisted adjoint action.
const Multivector< Scalar_T, LO, HI > acos(const Multivector< Scalar_T, LO, HI > &val, const Multivector< Scalar_T, LO, HI > &i, const bool prechecked=false)
Inverse cosine of multivector with specified complexifier.
const Multivector< Scalar_T, LO, HI > asinh(const Multivector< Scalar_T, LO, HI > &val, const Multivector< Scalar_T, LO, HI > &i, const bool prechecked=false)
Inverse hyperbolic sine of multivector with specified complexifier.
int index_t
Size of index_t should be enough to represent LO, HI.
const Multivector< Scalar_T, LO, HI > operator &(const Multivector< Scalar_T, LO, HI > &lhs, const RHS< Scalar_T, LO, HI > &rhs)
Inner product.
Scalar_T max_abs(const Multivector< Scalar_T, LO, HI > &val)
Maximum of absolute values of components of multivector: multivector infinity norm.
const Multivector< Scalar_T, LO, HI > cosh(const Multivector< Scalar_T, LO, HI > &val)
Hyperbolic cosine of multivector.
LHS_T pos_mod(LHS_T lhs, RHS_T rhs)
Modulo function which works reliably for lhs < 0.
bool operator!=(const Multivector< Scalar_T, LO, HI > &lhs, const RHS< Scalar_T, LO, HI > &rhs)
Test for inequality of multivectors.
const Multivector< Scalar_T, LO, HI > even(const Multivector< Scalar_T, LO, HI > &val)
Even part.
const Multivector< Scalar_T, LO, HI > operator-(const Multivector< Scalar_T, LO, HI > &lhs, const Scalar_T &scr)
Geometric difference of multivector and scalar.