10#if !defined(MiniTensor_Quaternion_h)
11#define MiniTensor_Quaternion_h
34sin_x_over_x(T
const & x)
36 using S =
typename Sacado::ScalarType<T>::type;
42 y_val = Sacado::ScalarValue<T>::eval(y);
45 epsilon2 = std::sqrt(machine_epsilon<T>());
48 epsilon4 = std::sqrt(epsilon2);
50 if (y_val > epsilon4) {
51 return std::sin(y) / y;
52 }
else if (y_val > epsilon2) {
53 return 1.0 - y * y / 6.0;
166 return i == 0 ?
s_ :
v_(
i - 1);
178 return i == 0 ?
s_ :
v_(
i - 1);
305template<
typename T, Index N>
333template<
typename T, Index N>
357template<
typename T, Index N>
368template<
typename T, Index N>
382template<
typename T, Index N>
485 os << std::scientific << std::setprecision(17);
487 os << std::setw(24) << q.
scalar();
489 for (
Index i = 0; i < 3; ++i) {
490 os <<
"," << std::setw(24) << q.
vector()(i);
499template<
typename T, Index N>
507 assert(
norm(
dot_t(R, R) - eye<T, N>(3)) <
508 std::max(1.0e-12 *
norm(R), 1.0e-12));
509 assert(std::abs(
det(R) - 1.0) <
510 std::max(1.0e-12 *
norm(R), 1.0e-12));
512 using S =
typename Sacado::ScalarType<T>::type;
520 max_value = Sacado::ScalarValue<T>::eval(trace_R);
525 for (
Index i = 0; i < 3; ++i) {
528 diagonal_value = Sacado::ScalarValue<T>::eval(R(i, i));
530 if (diagonal_value > max_value) {
531 max_value = diagonal_value;
544 root = std::sqrt(trace_R + 1.0);
551 factor * (R(2, 1) - R(1, 2)),
552 factor * (R(0, 2) - R(2, 0)),
553 factor * (R(1, 0) - R(0, 1)));
560 root = std::sqrt(2.0 * R(2, 2) + 1.0 - trace_R);
566 factor * (R(1, 0) - R(0, 1)),
567 factor * (R(0, 2) + R(2, 0)),
568 factor * (R(1, 2) + R(2, 1)),
576 root = std::sqrt(2.0 * R(1, 1) + 1.0 - trace_R);
582 factor * (R(0, 2) - R(2, 0)),
583 factor * (R(0, 1) + R(1, 0)),
585 factor * (R(1, 2) + R(2, 1)));
592 root = std::sqrt(2.0 * R(0, 0) + 1.0 - trace_R);
598 factor * (R(2, 1) - R(1, 2)),
600 factor * (R(0, 1) + R(1, 0)),
601 factor * (R(0, 2) + R(2, 0)));
621 negative = Sacado::ScalarValue<T>::eval(q.
scalar()) < 0.0;
629 if (negative ==
true) {
630 for (
Index i = 0; i < 3; ++i) {
639 if (Sacado::ScalarValue<T>::eval(qv_norm) <
640 std::sqrt(machine_epsilon<T>())) {
648 if (Sacado::ScalarValue<T>::eval(qv_norm) < std::sqrt(0.5)) {
649 rv_norm = 2.0 * std::asin(qv_norm);
651 rv_norm = 2.0 * std::acos(qs);
654 return rv_norm / qv_norm * qv;
660template<
typename T, Index N>
668 half_norm = 0.5 *
norm(rv);
671 factor = 0.5 * impl::sin_x_over_x(half_norm);
695 R = 2.0 *
dyad(qv, qv) + 2.0 * qs *
skew(qv) +
696 (2.0 * qs * qs - 1.0) * identity<T, 3>(3);
704template<
typename T, Index N>
715template<
typename T, Index N>
726template<
typename T, Index N>
734 using S =
typename Sacado::ScalarType<T>::type;
737 norm_old =
norm(old);
745 if (Sacado::ScalarValue<T>::eval(norm_old) > 0.0) {
746 direction = old / norm_old;
747 projection =
dot(direction, prev);
749 projection =
norm(prev);
750 if (Sacado::ScalarValue<T>::eval(projection) == 0.0) {
753 direction = prev / projection;
756 if (Sacado::ScalarValue<T>::eval(projection) == 0.0) {
761 pi = std::acos(S(-1.0));
767 number_turns = std::round(
769 (Sacado::ScalarValue<T>::eval(projection) -
770 Sacado::ScalarValue<T>::eval(norm_old)) / pi);
772 if (number_turns == 0.0) {
776 return (2.0 * number_turns * pi + norm_old) * direction;
#define KOKKOS_INLINE_FUNCTION
KOKKOS_INLINE_FUNCTION T const & operator()(Index const i) const
KOKKOS_INLINE_FUNCTION T & scalar()
KOKKOS_INLINE_FUNCTION Quaternion(T const &s, T const &v0, T const &v1, T const &v2)
KOKKOS_INLINE_FUNCTION Vector< T, 3 > & vector()
KOKKOS_INLINE_FUNCTION T & operator()(Index const i)
KOKKOS_INLINE_FUNCTION Vector< T, 3 > const & vector() const
KOKKOS_INLINE_FUNCTION Vector< T, 4 > to_vector() const
KOKKOS_INLINE_FUNCTION Quaternion()
KOKKOS_INLINE_FUNCTION T const & scalar() const
KOKKOS_INLINE_FUNCTION Quaternion(Vector< T, 4 > const &q)
KOKKOS_INLINE_FUNCTION Quaternion(T const &s, Vector< T, 3 > const &v)
std::ostream & operator<<(std::ostream &os, Matrix< T, M, N > const &A)
KOKKOS_INLINE_FUNCTION Vector< typename Promote< S, T >::type, N > cross(Vector< S, N > const &u, Vector< T, N > const &v)
KOKKOS_INLINE_FUNCTION Tensor< typename Promote< S, T >::type, N > dyad(Vector< S, N > const &u, Vector< T, N > const &v)
KOKKOS_INLINE_FUNCTION Vector< typename Promote< S, T >::type, M > operator*(Matrix< T, M, N > const &A, Vector< S, N > const &u)
KOKKOS_INLINE_FUNCTION Index get_dimension() const
KOKKOS_INLINE_FUNCTION Index get_dimension() const
KOKKOS_INLINE_FUNCTION Matrix< typename Promote< S, T >::type, M, N > dot_t(Matrix< S, M, P > const &A, Matrix< T, N, P > const &B)
KOKKOS_INLINE_FUNCTION bool operator!=(Matrix< T, M, N > const &A, Matrix< T, M, N > const &B)
KOKKOS_INLINE_FUNCTION bool operator==(Matrix< T, M, N > const &A, Matrix< T, M, N > const &B)
KOKKOS_INLINE_FUNCTION Vector< typename Promote< S, T >::type, M > dot(Matrix< T, M, N > const &A, Vector< S, N > const &u)
KOKKOS_INLINE_FUNCTION T norm_square(Vector< T, N > const &u)
KOKKOS_INLINE_FUNCTION Tensor< T, N > skew(Tensor< T, N > const &A)
KOKKOS_INLINE_FUNCTION Tensor< T, N > inverse(Tensor< T, N > const &A)
KOKKOS_INLINE_FUNCTION T norm(Tensor< T, N > const &A)
KOKKOS_INLINE_FUNCTION T det(Tensor< T, N > const &A)
KOKKOS_INLINE_FUNCTION T trace(Tensor< T, N > const &A)
KOKKOS_INLINE_FUNCTION Vector< T, N > rv_continue(Vector< T, N > const &old, Vector< T, N > const &prev)
KOKKOS_INLINE_FUNCTION Vector< T, 3 > rv_of_rt(Tensor< T, N > const &R)
KOKKOS_INLINE_FUNCTION Quaternion< T > conjugate(Quaternion< T > const &q)
KOKKOS_INLINE_FUNCTION Vector< T, 3 > rv_of_q(Quaternion< T > const &q)
KOKKOS_INLINE_FUNCTION Tensor< T, 3 > rt_of_q(Quaternion< T > const &q)
KOKKOS_INLINE_FUNCTION Quaternion< T > q_of_rv(Vector< T, N > const &rv)
KOKKOS_INLINE_FUNCTION Tensor< T, 3 > rt_of_rv(Vector< T, N > const &rv)
KOKKOS_INLINE_FUNCTION Quaternion< T > q_of_rt(Tensor< T, N > const &R)
KOKKOS_INLINE_FUNCTION Quaternion< T > unit(Quaternion< T > const &q)
uint32_t Index
Indexing type.