46#if defined(_MSC_VER) && (_MSC_VER <= 1900) 
   47#define LINALG_CONSTEXPR14 
   49#define LINALG_CONSTEXPR14 constexpr 
   55template <
class T, 
int M>
 
   60template <
class T, 
int M, 
int N>
 
   65template <
class T, 
class U>
 
   68template <
class T, 
class U>
 
   69using conv_t = 
typename std::enable_if<!std::is_same<T, U>::value,
 
   71                                           std::declval<U>()))>::type;
 
   76template <
class T, 
int M>
 
   80template <
class T, 
int M, 
int N>
 
   92constexpr bool operator==(
const ord<T>& o, std::nullptr_t) {
 
   96constexpr bool operator!=(
const ord<T>& o, std::nullptr_t) {
 
  100constexpr bool operator<(
const ord<T>& o, std::nullptr_t) {
 
  104constexpr bool operator>(
const ord<T>& o, std::nullptr_t) {
 
  108constexpr bool operator<=(
const ord<T>& o, std::nullptr_t) {
 
  112constexpr bool operator>=(
const ord<T>& o, std::nullptr_t) {
 
  117template <
class A, 
class B>
 
  130    return !(a.x == b.x) ? 
ord<T>{a.x, b.x} : 
ord<T>{a.y, b.y};
 
 
  137    return !(a.x == b.x)   ? 
ord<T>{a.x, b.x}
 
  138           : !(a.y == b.y) ? 
ord<T>{a.y, b.y}
 
 
  146    return !(a.x == b.x)   ? 
ord<T>{a.x, b.x}
 
  147           : !(a.y == b.y) ? 
ord<T>{a.y, b.y}
 
  148           : !(a.z == b.z) ? 
ord<T>{a.z, b.z}
 
 
  152template <
class T, 
int M>
 
  157    return compare(a.x, b.x);
 
 
  160template <
class T, 
int M>
 
  165    return a.x != b.x ? compare(a.x, b.x) : compare(a.y, b.y);
 
 
  168template <
class T, 
int M>
 
  173    return a.x != b.x   ? compare(a.x, b.x)
 
  174           : a.y != b.y ? compare(a.y, b.y)
 
 
  178template <
class T, 
int M>
 
  183    return a.x != b.x   ? compare(a.x, b.x)
 
  184           : a.y != b.y ? compare(a.y, b.y)
 
  185           : a.z != b.z ? compare(a.z, b.z)
 
 
  197  constexpr auto operator()(A& a) 
const -> 
decltype(a.x) {
 
 
  204  constexpr auto operator()(A& a) 
const -> 
decltype(a.y) {
 
 
  211  constexpr auto operator()(A& a) 
const -> 
decltype(a.z) {
 
 
  218  constexpr auto operator()(A& a) 
const -> 
decltype(a.w) {
 
 
  226template <
int A, 
int N>
 
  248template <
int A, 
int B>
 
  250template <
class T, 
int M, 
int... I>
 
  254template <
class T, 
int M, 
int N, 
int... I, 
int... J>
 
  255mat<T, 
sizeof...(I), 
sizeof...(J)> 
constexpr swizzle(
const mat<T, M, N>& m,
 
  261template <
class F, 
class... T>
 
  262using ret_t = 
decltype(std::declval<F>()(std::declval<T>()...));
 
  272template <
class T, 
class... U>
 
  273struct scalars<T, U...> : std::conditional<std::is_arithmetic<T>::value,
 
  274                                           scalars<U...>, empty>::type {};
 
 
  276using scalars_t = 
typename scalars<T...>::type;
 
  280template <
class F, 
class Void, 
class... T>
 
  282template <
class F, 
int M, 
class A>
 
  285  enum { size = M, mm = 0 };
 
 
  291template <
class F, 
int M, 
class A, 
class B>
 
  294  enum { size = M, mm = 0 };
 
 
  301template <
class F, 
int M, 
class A, 
class B>
 
  304  enum { size = M, mm = 0 };
 
 
  310template <
class F, 
int M, 
class A, 
class B>
 
  313  enum { size = M, mm = 0 };
 
 
  319template <
class F, 
int M, 
class A, 
class B, 
class C>
 
  322  enum { size = M, mm = 0 };
 
 
  329template <
class F, 
int M, 
class A, 
class B, 
class C>
 
  332  enum { size = M, mm = 0 };
 
 
  339template <
class F, 
int M, 
class A, 
class B, 
class C>
 
  342  enum { size = M, mm = 0 };
 
 
  349template <
class F, 
int M, 
class A, 
class B, 
class C>
 
  352  enum { size = M, mm = 0 };
 
 
  358template <
class F, 
int M, 
class A, 
class B, 
class C>
 
  361  enum { size = M, mm = 0 };
 
 
  368template <
class F, 
int M, 
class A, 
class B, 
class C>
 
  371  enum { size = M, mm = 0 };
 
 
  377template <
class F, 
int M, 
class A, 
class B, 
class C>
 
  380  enum { size = M, mm = 0 };
 
 
  386template <
class F, 
int M, 
int N, 
class A>
 
  389  enum { size = N, mm = 0 };
 
 
  396template <
class F, 
int M, 
int N, 
class A, 
class B>
 
  399  enum { size = N, mm = 1 };
 
 
  407template <
class F, 
int M, 
int N, 
class A, 
class B>
 
  410  enum { size = N, mm = 0 };
 
 
  417template <
class F, 
int M, 
int N, 
class A, 
class B>
 
  420  enum { size = N, mm = 0 };
 
 
  427template <
class F, 
class... A>
 
  428struct apply<F, scalars_t<A...>, A...> {
 
  429  using type = ret_t<F, A...>;
 
  430  enum { size = 0, mm = 0 };
 
  431  static constexpr type impl(
seq<>, F f, A... a) { 
return f(a...); }
 
 
  436  template <
class A, 
class B>
 
  437  constexpr auto operator()(A a, B b) 
const ->
 
  438      typename std::remove_reference<
decltype(a < b ? a : b)>::type {
 
  439    return a < b ? a : b;
 
 
  443  template <
class A, 
class B>
 
  444  constexpr auto operator()(A a, B b) 
const ->
 
  445      typename std::remove_reference<
decltype(a < b ? b : a)>::type {
 
  446    return a < b ? b : a;
 
 
  450  template <
class A, 
class B, 
class C>
 
  451  constexpr auto operator()(A a, B b, C c) 
const ->
 
  452      typename std::remove_reference<
decltype(a < b   ? b
 
  455    return a < b ? b : a < c ? a : c;
 
 
  459  template <
class A, 
class B, 
class C>
 
  460  constexpr auto operator()(A a, B b, C c) 
const ->
 
  461      typename std::remove_reference<
decltype(a ? b : c)>::type {
 
 
  466  template <
class A, 
class B, 
class C>
 
  467  constexpr auto operator()(A a, B b, C c) 
const 
  468      -> 
decltype(a * (1 - c) + b * c) {
 
  469    return a * (1 - c) + b * c;
 
 
  476  constexpr auto operator()(A a) 
const -> 
decltype(+a) {
 
 
  482  constexpr auto operator()(A a) 
const -> 
decltype(-a) {
 
 
  488  constexpr auto operator()(A a) 
const -> 
decltype(!a) {
 
 
  494  constexpr auto operator()(A a) 
const -> 
decltype(~(a)) {
 
 
  499  template <
class A, 
class B>
 
  500  constexpr auto operator()(A a, B b) 
const -> 
decltype(a * b) {
 
 
  505  template <
class A, 
class B>
 
  506  constexpr auto operator()(A a, B b) 
const -> 
decltype(a / b) {
 
 
  511  template <
class A, 
class B>
 
  512  constexpr auto operator()(A a, B b) 
const -> 
decltype(a % b) {
 
 
  517  template <
class A, 
class B>
 
  518  constexpr auto operator()(A a, B b) 
const -> 
decltype(a + b) {
 
 
  523  template <
class A, 
class B>
 
  524  constexpr auto operator()(A a, B b) 
const -> 
decltype(a - b) {
 
 
  529  template <
class A, 
class B>
 
  530  constexpr auto operator()(A a, B b) 
const -> 
decltype(a << b) {
 
 
  535  template <
class A, 
class B>
 
  536  constexpr auto operator()(A a, B b) 
const -> 
decltype(a >> b) {
 
 
  541  template <
class A, 
class B>
 
  542  constexpr auto operator()(A a, B b) 
const -> 
decltype(a < b) {
 
 
  547  template <
class A, 
class B>
 
  548  constexpr auto operator()(A a, B b) 
const -> 
decltype(a > b) {
 
 
  553  template <
class A, 
class B>
 
  554  constexpr auto operator()(A a, B b) 
const -> 
decltype(a <= b) {
 
 
  559  template <
class A, 
class B>
 
  560  constexpr auto operator()(A a, B b) 
const -> 
decltype(a >= b) {
 
 
  565  template <
class A, 
class B>
 
  566  constexpr auto operator()(A a, B b) 
const -> 
decltype(a == b) {
 
 
  571  template <
class A, 
class B>
 
  572  constexpr auto operator()(A a, B b) 
const -> 
decltype(a != b) {
 
 
  577  template <
class A, 
class B>
 
  578  constexpr auto operator()(A a, B b) 
const -> 
decltype(a & b) {
 
 
  583  template <
class A, 
class B>
 
  584  constexpr auto operator()(A a, B b) 
const -> 
decltype(a ^ b) {
 
 
  589  template <
class A, 
class B>
 
  590  constexpr auto operator()(A a, B b) 
const -> 
decltype(a | b) {
 
 
  595  template <
class A, 
class B>
 
  596  constexpr auto operator()(A a, B b) 
const -> 
decltype(a && b) {
 
 
  601  template <
class A, 
class B>
 
  602  constexpr auto operator()(A a, B b) 
const -> 
decltype(a || b) {
 
 
  610  constexpr auto operator()(A a) 
const -> 
decltype(std::isfinite(a)) {
 
  611    return std::isfinite(a);
 
 
  616  constexpr auto operator()(A a) 
const -> 
decltype(std::abs(a)) {
 
 
  622  constexpr auto operator()(A a) 
const -> 
decltype(std::floor(a)) {
 
  623    return std::floor(a);
 
 
  628  constexpr auto operator()(A a) 
const -> 
decltype(std::ceil(a)) {
 
 
  634  constexpr auto operator()(A a) 
const -> 
decltype(std::exp(a)) {
 
 
  640  constexpr auto operator()(A a) 
const -> 
decltype(std::log(a)) {
 
 
  646  constexpr auto operator()(A a) 
const -> 
decltype(std::log2(a)) {
 
 
  652  constexpr auto operator()(A a) 
const -> 
decltype(std::log10(a)) {
 
  653    return std::log10(a);
 
 
  658  constexpr auto operator()(A a) 
const -> 
decltype(std::sqrt(a)) {
 
 
  664  constexpr auto operator()(A a) 
const -> 
decltype(std::sin(a)) {
 
 
  670  constexpr auto operator()(A a) 
const -> 
decltype(std::cos(a)) {
 
 
  676  constexpr auto operator()(A a) 
const -> 
decltype(std::tan(a)) {
 
 
  682  constexpr auto operator()(A a) 
const -> 
decltype(std::asin(a)) {
 
 
  688  constexpr auto operator()(A a) 
const -> 
decltype(std::acos(a)) {
 
 
  694  constexpr auto operator()(A a) 
const -> 
decltype(std::atan(a)) {
 
 
  700  constexpr auto operator()(A a) 
const -> 
decltype(std::sinh(a)) {
 
 
  706  constexpr auto operator()(A a) 
const -> 
decltype(std::cosh(a)) {
 
 
  712  constexpr auto operator()(A a) 
const -> 
decltype(std::tanh(a)) {
 
 
  718  constexpr auto operator()(A a) 
const -> 
decltype(std::round(a)) {
 
  719    return std::round(a);
 
 
  723  template <
class A, 
class B>
 
  724  constexpr auto operator()(A a, B b) 
const -> 
decltype(std::fmod(a, b)) {
 
  725    return std::fmod(a, b);
 
 
  729  template <
class A, 
class B>
 
  730  constexpr auto operator()(A a, B b) 
const -> 
decltype(std::pow(a, b)) {
 
  731    return std::pow(a, b);
 
 
  735  template <
class A, 
class B>
 
  736  constexpr auto operator()(A a, B b) 
const -> 
decltype(std::atan2(a, b)) {
 
  737    return std::atan2(a, b);
 
 
  741  template <
class A, 
class B>
 
  742  constexpr auto operator()(A a, B b) 
const -> 
decltype(std::copysign(a, b)) {
 
  743    return std::copysign(a, b);
 
 
  850  constexpr vec() : x() {}
 
  851  constexpr vec(
const T& x_) : x(x_) {}
 
  855  constexpr explicit vec(
const vec<U, 1>& v) : vec(
static_cast<T
>(v.x)) {}
 
  856  constexpr const T& operator[](
int)
 const { 
return x; }
 
  857  LINALG_CONSTEXPR14 T& operator[](
int) { 
return x; }
 
  859  template <
class U, 
class = detail::conv_t<vec, U>>
 
  861  template <
class U, 
class = detail::conv_t<U, vec>>
 
  862  constexpr operator U()
 const {
 
 
  869  constexpr vec() : x(), y() {}
 
  870  constexpr vec(
const T& x_, 
const T& y_) : x(x_), y(y_) {}
 
  871  constexpr explicit vec(
const T& s) : vec(s, s) {}
 
  872  constexpr explicit vec(
const T* p) : vec(p[0], p[1]) {}
 
  873  template <
class U, 
int N>
 
  874  constexpr explicit vec(
const vec<U, N>& v)
 
  875      : vec(
static_cast<T
>(v.x), 
static_cast<T
>(v.y)) {
 
  878        "You must give extra arguments if your input vector is shorter.");
 
  880  constexpr const T& operator[](
int i)
 const { 
return i == 0 ? x : y; }
 
  881  LINALG_CONSTEXPR14 T& operator[](
int i) { 
return i == 0 ? x : y; }
 
  883  template <
class U, 
class = detail::conv_t<vec, U>>
 
  885  template <
class U, 
class = detail::conv_t<U, vec>>
 
  886  constexpr operator U()
 const {
 
 
  893  constexpr vec() : x(), y(), z() {}
 
  894  constexpr vec(
const T& x_, 
const T& y_, 
const T& z_) : x(x_), y(y_), z(z_) {}
 
  895  constexpr vec(
const vec<T, 2>& xy, 
const T& z_) : vec(xy.x, xy.y, z_) {}
 
  896  constexpr explicit vec(
const T& s) : vec(s, s, s) {}
 
  897  constexpr explicit vec(
const T* p) : vec(p[0], p[1], p[2]) {}
 
  898  template <
class U, 
int N>
 
  899  constexpr explicit vec(
const vec<U, N>& v)
 
  900      : vec(
static_cast<T
>(v.x), 
static_cast<T
>(v.y), 
static_cast<T
>(v.z)) {
 
  903        "You must give extra arguments if your input vector is shorter.");
 
  905  constexpr const T& operator[](
int i)
 const {
 
  906    return i == 0 ? x : i == 1 ? y : z;
 
  908  LINALG_CONSTEXPR14 T& operator[](
int i) {
 
  909    return i == 0 ? x : i == 1 ? y : z;
 
  911  constexpr const vec<T, 2>& xy()
 const {
 
  912    return *
reinterpret_cast<const vec<T, 2>*
>(
this);
 
  914  vec<T, 2>& xy() { 
return *
reinterpret_cast<vec<T, 2>*
>(
this); }
 
  916  template <
class U, 
class = detail::conv_t<vec, U>>
 
  918  template <
class U, 
class = detail::conv_t<U, vec>>
 
  919  constexpr operator U()
 const {
 
 
  926  constexpr vec() : x(), y(), z(), w() {}
 
  927  constexpr vec(
const T& x_, 
const T& y_, 
const T& z_, 
const T& w_)
 
  928      : x(x_), y(y_), z(z_), w(w_) {}
 
  929  constexpr vec(
const vec<T, 2>& xy, 
const T& z_, 
const T& w_)
 
  930      : vec(xy.x, xy.y, z_, w_) {}
 
  931  constexpr vec(
const vec<T, 3>& xyz, 
const T& w_)
 
  932      : vec(xyz.x, xyz.y, xyz.z, w_) {}
 
  933  constexpr explicit vec(
const T& s) : vec(s, s, s, s) {}
 
  934  constexpr explicit vec(
const T* p) : vec(p[0], p[1], p[2], p[3]) {}
 
  935  template <
class U, 
int N>
 
  936  constexpr explicit vec(
const vec<U, N>& v)
 
  937      : vec(
static_cast<T
>(v.x), 
static_cast<T
>(v.y), 
static_cast<T
>(v.z),
 
  938            static_cast<T
>(v.w)) {
 
  941        "You must give extra arguments if your input vector is shorter.");
 
  943  constexpr const T& operator[](
int i)
 const {
 
  944    return i == 0 ? x : i == 1 ? y : i == 2 ? z : w;
 
  946  LINALG_CONSTEXPR14 T& operator[](
int i) {
 
  947    return i == 0 ? x : i == 1 ? y : i == 2 ? z : w;
 
  949  constexpr const vec<T, 2>& xy()
 const {
 
  950    return *
reinterpret_cast<const vec<T, 2>*
>(
this);
 
  952  constexpr const vec<T, 3>& xyz()
 const {
 
  953    return *
reinterpret_cast<const vec<T, 3>*
>(
this);
 
  955  vec<T, 2>& xy() { 
return *
reinterpret_cast<vec<T, 2>*
>(
this); }
 
  956  vec<T, 3>& xyz() { 
return *
reinterpret_cast<vec<T, 3>*
>(
this); }
 
  958  template <
class U, 
class = detail::conv_t<vec, U>>
 
  960  template <
class U, 
class = detail::conv_t<U, vec>>
 
  961  constexpr operator U()
 const {
 
 
 1061template <
class T, 
int M>
 
 1062struct mat<T, M, 1> {
 
 1065  constexpr mat() : x() {}
 
 1066  constexpr mat(
const V& x_) : x(x_) {}
 
 1067  constexpr explicit mat(
const T& s) : x(s) {}
 
 1068  constexpr explicit mat(
const T* p) : x(p + M * 0) {}
 
 1070  constexpr explicit mat(
const mat<U, M, 1>& m) : mat(V(m.x)) {}
 
 1071  constexpr vec<T, 1> row(
int i)
 const { 
return {x[i]}; }
 
 1072  constexpr const V& operator[](
int)
 const { 
return x; }
 
 1073  LINALG_CONSTEXPR14 V& operator[](
int) { 
return x; }
 
 1075  template <
class U, 
class = detail::conv_t<mat, U>>
 
 1077  template <
class U, 
class = detail::conv_t<U, mat>>
 
 1078  constexpr operator U()
 const {
 
 
 1082template <
class T, 
int M>
 
 1083struct mat<T, M, 2> {
 
 1086  constexpr mat() : x(), y() {}
 
 1087  constexpr mat(
const V& x_, 
const V& y_) : x(x_), y(y_) {}
 
 1088  constexpr explicit mat(
const T& s) : x(s), y(s) {}
 
 1089  constexpr explicit mat(
const T* p) : x(p + M * 0), y(p + M * 1) {}
 
 1090  template <
class U, 
int N, 
int P>
 
 1091  constexpr explicit mat(
const mat<U, N, P>& m) : mat(V(m.x), V(m.y)) {
 
 1092    static_assert(P >= 2, 
"Input matrix dimensions must be at least as big.");
 
 1094  constexpr vec<T, 2> row(
int i)
 const { 
return {x[i], y[i]}; }
 
 1095  constexpr const V& operator[](
int j)
 const { 
return j == 0 ? x : y; }
 
 1096  LINALG_CONSTEXPR14 V& operator[](
int j) { 
return j == 0 ? x : y; }
 
 1098  template <
class U, 
class = detail::conv_t<mat, U>>
 
 1100  template <
class U, 
class = detail::conv_t<U, mat>>
 
 1101  constexpr operator U()
 const {
 
 
 1105template <
class T, 
int M>
 
 1106struct mat<T, M, 3> {
 
 1109  constexpr mat() : x(), y(), z() {}
 
 1110  constexpr mat(
const V& x_, 
const V& y_, 
const V& z_) : x(x_), y(y_), z(z_) {}
 
 1111  constexpr mat(
const mat<T, M, 2>& m_, 
const V& z_)
 
 1112      : x(m_.x), y(m_.y), z(z_) {}
 
 1113  constexpr explicit mat(
const T& s) : x(s), y(s), z(s) {}
 
 1114  constexpr explicit mat(
const T* p)
 
 1115      : x(p + M * 0), y(p + M * 1), z(p + M * 2) {}
 
 1116  template <
class U, 
int N, 
int P>
 
 1117  constexpr explicit mat(
const mat<U, N, P>& m) : mat(V(m.x), V(m.y), V(m.z)) {
 
 1118    static_assert(P >= 3, 
"Input matrix dimensions must be at least as big.");
 
 1120  constexpr vec<T, 3> row(
int i)
 const { 
return {x[i], y[i], z[i]}; }
 
 1121  constexpr const V& operator[](
int j)
 const {
 
 1122    return j == 0 ? x : j == 1 ? y : z;
 
 1124  LINALG_CONSTEXPR14 V& operator[](
int j) {
 
 1125    return j == 0 ? x : j == 1 ? y : z;
 
 1128  template <
class U, 
class = detail::conv_t<mat, U>>
 
 1130  template <
class U, 
class = detail::conv_t<U, mat>>
 
 1131  constexpr operator U()
 const {
 
 
 1135template <
class T, 
int M>
 
 1136struct mat<T, M, 4> {
 
 1139  constexpr mat() : x(), y(), z(), w() {}
 
 1140  constexpr mat(
const V& x_, 
const V& y_, 
const V& z_, 
const V& w_)
 
 1141      : x(x_), y(y_), z(z_), w(w_) {}
 
 1142  constexpr mat(
const mat<T, M, 3>& m_, 
const V& w_)
 
 1143      : x(m_.x), y(m_.y), z(m_.z), w(w_) {}
 
 1144  constexpr explicit mat(
const T& s) : x(s), y(s), z(s), w(s) {}
 
 1145  constexpr explicit mat(
const T* p)
 
 1146      : x(p + M * 0), y(p + M * 1), z(p + M * 2), w(p + M * 3) {}
 
 1147  template <
class U, 
int N, 
int P>
 
 1148  constexpr explicit mat(
const mat<U, N, P>& m)
 
 1149      : mat(V(m.x), V(m.y), V(m.z), V(m.w)) {
 
 1150    static_assert(P >= 4, 
"Input matrix dimensions must be at least as big.");
 
 1153  constexpr vec<T, 4> row(
int i)
 const { 
return {x[i], y[i], z[i], w[i]}; }
 
 1154  constexpr const V& operator[](
int j)
 const {
 
 1155    return j == 0 ? x : j == 1 ? y : j == 2 ? z : w;
 
 1157  LINALG_CONSTEXPR14 V& operator[](
int j) {
 
 1158    return j == 0 ? x : j == 1 ? y : j == 2 ? z : w;
 
 1161  template <
class U, 
class = detail::conv_t<mat, U>>
 
 1163  template <
class U, 
class = detail::conv_t<U, mat>>
 
 1164  constexpr operator U()
 const {
 
 
 1177  constexpr explicit identity_t(
int) {}
 
 
 1186    return {{1, 0}, {0, 1}};
 
 
 1192    return {{1, 0}, {0, 1}, {0, 0}};
 
 
 1198    return {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}};
 
 
 1204    return {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}, {0, 0, 0}};
 
 
 1210    return {{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}};
 
 
 1223template <
class F, 
class A, 
class B>
 
 1224constexpr A fold(F f, A a, 
const vec<B, 1>& b) {
 
 1227template <
class F, 
class A, 
class B>
 
 1228constexpr A fold(F f, A a, 
const vec<B, 2>& b) {
 
 1229  return f(f(a, b.x), b.y);
 
 1231template <
class F, 
class A, 
class B>
 
 1232constexpr A fold(F f, A a, 
const vec<B, 3>& b) {
 
 1233  return f(f(f(a, b.x), b.y), b.z);
 
 1235template <
class F, 
class A, 
class B>
 
 1236constexpr A fold(F f, A a, 
const vec<B, 4>& b) {
 
 1237  return f(f(f(f(a, b.x), b.y), b.z), b.w);
 
 1239template <
class F, 
class A, 
class B, 
int M>
 
 1241  return fold(f, a, b.x);
 
 1243template <
class F, 
class A, 
class B, 
int M>
 
 1245  return fold(f, fold(f, a, b.x), b.y);
 
 1247template <
class F, 
class A, 
class B, 
int M>
 
 1249  return fold(f, fold(f, fold(f, a, b.x), b.y), b.z);
 
 1251template <
class F, 
class A, 
class B, 
int M>
 
 1253  return fold(f, fold(f, fold(f, fold(f, a, b.x), b.y), b.z), b.w);
 
 1266template <
class F, 
class... A>
 
 1268template <
class F, 
class... A>
 
 1269using mm_apply_t = 
typename std::enable_if<
detail::apply<F, void, A...>::mm,
 
 1270                                           apply_t<F, A...>>::type;
 
 1271template <
class F, 
class... A>
 
 1272using no_mm_apply_t = 
typename std::enable_if<!
detail::apply<F, void, A...>::mm,
 
 1273                                              apply_t<F, A...>>::type;
 
 1281template <
class F, 
class... A>
 
 1282constexpr apply_t<F, A...> apply(F func, 
const A&... args) {
 
 1288template <
class A, 
class F>
 
 1289constexpr apply_t<F, A> map(
const A& a, F func) {
 
 1290  return apply(func, a);
 
 1294template <
class A, 
class B, 
class F>
 
 1295constexpr apply_t<F, A, B> zip(
const A& a, 
const B& b, F func) {
 
 1296  return apply(func, a, b);
 
 1306template <
class A, 
class B>
 
 1311template <
class A, 
class B>
 
 1312constexpr auto operator==(
const A& a, 
const B& b)
 
 1313    -> 
decltype(compare(a, b) == 0) {
 
 1314  return compare(a, b) == 0;
 
 1316template <
class A, 
class B>
 
 1317constexpr auto operator!=(
const A& a, 
const B& b)
 
 1318    -> 
decltype(compare(a, b) != 0) {
 
 1319  return compare(a, b) != 0;
 
 1321template <
class A, 
class B>
 
 1322constexpr auto operator<(
const A& a, 
const B& b)
 
 1323    -> 
decltype(compare(a, b) < 0) {
 
 1324  return compare(a, b) < 0;
 
 1326template <
class A, 
class B>
 
 1327constexpr auto operator>(
const A& a, 
const B& b)
 
 1328    -> 
decltype(compare(a, b) > 0) {
 
 1329  return compare(a, b) > 0;
 
 1331template <
class A, 
class B>
 
 1332constexpr auto operator<=(
const A& a, 
const B& b)
 
 1333    -> 
decltype(compare(a, b) <= 0) {
 
 1334  return compare(a, b) <= 0;
 
 1336template <
class A, 
class B>
 
 1337constexpr auto operator>=(
const A& a, 
const B& b)
 
 1338    -> 
decltype(compare(a, b) >= 0) {
 
 1339  return compare(a, b) >= 0;
 
 1349constexpr bool any(
const A& a) {
 
 1353constexpr bool all(
const A& a) {
 
 1357constexpr scalar_t<A> sum(
const A& a) {
 
 1361constexpr scalar_t<A> product(
const A& a) {
 
 1365constexpr scalar_t<A> minelem(
const A& a) {
 
 1369constexpr scalar_t<A> maxelem(
const A& a) {
 
 1372template <
class T, 
int M>
 
 1375  for (
int i = 1; i < M; ++i)
 
 1376    if (a[i] < a[j]) j = i;
 
 1379template <
class T, 
int M>
 
 1382  for (
int i = 1; i < M; ++i)
 
 1383    if (a[i] > a[j]) j = i;
 
 1394constexpr apply_t<detail::op_pos, A> operator+(
const A& a) {
 
 1398constexpr apply_t<detail::op_neg, A> operator-(
const A& a) {
 
 1402constexpr apply_t<detail::op_cmp, A> operator~(
const A& a) {
 
 1406constexpr apply_t<detail::op_not, A> operator!(
const A& a) {
 
 1419template <
class A, 
class B>
 
 1420constexpr apply_t<detail::op_add, A, B> operator+(
const A& a, 
const B& b) {
 
 1423template <
class A, 
class B>
 
 1424constexpr apply_t<detail::op_sub, A, B> operator-(
const A& a, 
const B& b) {
 
 1427template <
class A, 
class B>
 
 1428constexpr apply_t<detail::op_mul, A, B> cmul(
const A& a, 
const B& b) {
 
 1431template <
class A, 
class B>
 
 1432constexpr apply_t<detail::op_div, A, B> operator/(
const A& a, 
const B& b) {
 
 1435template <
class A, 
class B>
 
 1436constexpr apply_t<detail::op_mod, A, B> operator%(
const A& a, 
const B& b) {
 
 1439template <
class A, 
class B>
 
 1440constexpr apply_t<detail::op_un, A, B> operator|(
const A& a, 
const B& b) {
 
 1443template <
class A, 
class B>
 
 1444constexpr apply_t<detail::op_xor, A, B> operator^(
const A& a, 
const B& b) {
 
 1447template <
class A, 
class B>
 
 1448constexpr apply_t<detail::op_int, A, B> operator&(
const A& a, 
const B& b) {
 
 1451template <
class A, 
class B>
 
 1452constexpr apply_t<detail::op_lsh, A, B> operator<<(
const A& a, 
const B& b) {
 
 1455template <
class A, 
class B>
 
 1456constexpr apply_t<detail::op_rsh, A, B> operator>>(
const A& a, 
const B& b) {
 
 1462template <
class A, 
class B>
 
 1463constexpr auto operator*(
const A& a, 
const B& b) {
 
 1469template <
class A, 
class B>
 
 1470constexpr auto operator+=(A& a, 
const B& b) -> 
decltype(a = a + b) {
 
 1473template <
class A, 
class B>
 
 1474constexpr auto operator-=(A& a, 
const B& b) -> 
decltype(a = a - b) {
 
 1477template <
class A, 
class B>
 
 1478constexpr auto operator*=(A& a, 
const B& b) -> 
decltype(a = a * b) {
 
 1481template <
class A, 
class B>
 
 1482constexpr auto operator/=(A& a, 
const B& b) -> 
decltype(a = a / b) {
 
 1485template <
class A, 
class B>
 
 1486constexpr auto operator%=(A& a, 
const B& b) -> 
decltype(a = a % b) {
 
 1489template <
class A, 
class B>
 
 1490constexpr auto operator|=(A& a, 
const B& b) -> 
decltype(a = a | b) {
 
 1493template <
class A, 
class B>
 
 1494constexpr auto operator^=(A& a, 
const B& b) -> 
decltype(a = a ^ b) {
 
 1497template <
class A, 
class B>
 
 1498constexpr auto operator&=(A& a, 
const B& b) -> 
decltype(a = a & b) {
 
 1501template <
class A, 
class B>
 
 1502constexpr auto operator<<=(A& a, 
const B& b) -> 
decltype(a = a << b) {
 
 1505template <
class A, 
class B>
 
 1506constexpr auto operator>>=(A& a, 
const B& b) -> 
decltype(a = a >> b) {
 
 1520template <
int... I, 
class T, 
int M>
 
 1528template <
int I0, 
int I1, 
class T, 
int M>
 
 1530  return detail::swizzle(a, detail::make_seq<I0, I1>{});
 
 
 1536template <
int I0, 
int J0, 
int I1, 
int J1, 
class T, 
int M, 
int N>
 
 1538  return detail::swizzle(a, detail::make_seq<I0, I1>{},
 
 1539                         detail::make_seq<J0, J1>{});
 
 
 1549constexpr apply_t<detail::std_isfinite, A> isfinite(
const A& a) {
 
 1550  return apply(detail::std_isfinite{}, a);
 
 1553constexpr apply_t<detail::std_abs, A> abs(
const A& a) {
 
 1557constexpr apply_t<detail::std_floor, A> floor(
const A& a) {
 
 1561constexpr apply_t<detail::std_ceil, A> ceil(
const A& a) {
 
 1565constexpr apply_t<detail::std_exp, A> exp(
const A& a) {
 
 1569constexpr apply_t<detail::std_log, A> log(
const A& a) {
 
 1573constexpr apply_t<detail::std_log2, A> log2(
const A& a) {
 
 1577constexpr apply_t<detail::std_log10, A> log10(
const A& a) {
 
 1581constexpr apply_t<detail::std_sqrt, A> sqrt(
const A& a) {
 
 1585constexpr apply_t<detail::std_sin, A> sin(
const A& a) {
 
 1589constexpr apply_t<detail::std_cos, A> cos(
const A& a) {
 
 1593constexpr apply_t<detail::std_tan, A> tan(
const A& a) {
 
 1597constexpr apply_t<detail::std_asin, A> asin(
const A& a) {
 
 1601constexpr apply_t<detail::std_acos, A> acos(
const A& a) {
 
 1605constexpr apply_t<detail::std_atan, A> atan(
const A& a) {
 
 1609constexpr apply_t<detail::std_sinh, A> sinh(
const A& a) {
 
 1613constexpr apply_t<detail::std_cosh, A> cosh(
const A& a) {
 
 1617constexpr apply_t<detail::std_tanh, A> tanh(
const A& a) {
 
 1621constexpr apply_t<detail::std_round, A> round(
const A& a) {
 
 1632template <
class A, 
class B>
 
 1633constexpr apply_t<detail::std_fmod, A, B> fmod(
const A& a, 
const B& b) {
 
 1636template <
class A, 
class B>
 
 1637constexpr apply_t<detail::std_pow, A, B> pow(
const A& a, 
const B& b) {
 
 1640template <
class A, 
class B>
 
 1641constexpr apply_t<detail::std_atan2, A, B> atan2(
const A& a, 
const B& b) {
 
 1644template <
class A, 
class B>
 
 1645constexpr apply_t<detail::std_copysign, A, B> copysign(
const A& a, 
const B& b) {
 
 1656template <
class A, 
class B>
 
 1657constexpr apply_t<detail::op_eq, A, B> equal(
const A& a, 
const B& b) {
 
 1660template <
class A, 
class B>
 
 1661constexpr apply_t<detail::op_ne, A, B> nequal(
const A& a, 
const B& b) {
 
 1664template <
class A, 
class B>
 
 1665constexpr apply_t<detail::op_lt, A, B> less(
const A& a, 
const B& b) {
 
 1668template <
class A, 
class B>
 
 1669constexpr apply_t<detail::op_gt, A, B> greater(
const A& a, 
const B& b) {
 
 1672template <
class A, 
class B>
 
 1673constexpr apply_t<detail::op_le, A, B> lequal(
const A& a, 
const B& b) {
 
 1676template <
class A, 
class B>
 
 1677constexpr apply_t<detail::op_ge, A, B> gequal(
const A& a, 
const B& b) {
 
 1688template <
class A, 
class B>
 
 1689constexpr apply_t<detail::min, A, B> min(
const A& a, 
const B& b) {
 
 1692template <
class A, 
class B>
 
 1693constexpr apply_t<detail::max, A, B> max(
const A& a, 
const B& b) {
 
 1699template <
class X, 
class L, 
class H>
 
 1700constexpr apply_t<detail::clamp, X, L, H> 
clamp(
const X& x, 
const L& l,
 
 
 1708template <
class P, 
class A, 
class B>
 
 1709constexpr apply_t<detail::select, P, A, B> 
select(
const P& p, 
const A& a,
 
 
 1717template <
class A, 
class B, 
class T>
 
 1718constexpr apply_t<detail::lerp, A, B, T> 
lerp(
const A& a, 
const B& b,
 
 
 1734  return a.x * b.y - a.y * b.x;
 
 
 1741  return {-a * b.y, a * b.x};
 
 
 1748  return {a.y * b, -a.x * b};
 
 
 1756  return {a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x};
 
 
 1762template <
class T, 
int M>
 
 1769template <
class T, 
int M>
 
 1776template <
class T, 
int M>
 
 1785template <
class T, 
int M>
 
 1794template <
class T, 
int M>
 
 1802template <
class T, 
int M>
 
 1809template <
class T, 
int M>
 
 1812  return d > 1 ? 0 : std::acos(d < -1 ? -1 : d);
 
 
 1817template <
class T, 
int M>
 
 1827  const T s = std::sin(a), c = std::cos(a);
 
 1828  return {v.x * c - v.y * s, v.x * s + v.y * c};
 
 
 1836  const T s = std::sin(a), c = std::cos(a);
 
 1837  return {v.x, v.y * c - v.z * s, v.y * s + v.z * c};
 
 
 1845  const T s = std::sin(a), c = std::cos(a);
 
 1846  return {v.x * c + v.z * s, v.y, -v.x * s + v.z * c};
 
 
 1854  const T s = std::sin(a), c = std::cos(a);
 
 1855  return {v.x * c - v.y * s, v.x * s + v.y * c, v.z};
 
 
 1860template <
class T, 
int M>
 
 1869template <
class T, 
int M>
 
 1873                 : a * (std::sin(th * (1 - t)) / std::sin(th)) +
 
 1874                       b * (std::sin(th * t) / std::sin(th));
 
 
 1891  return {-q.x, -q.y, -q.z, q.w};
 
 
 1909  const auto v = q.xyz();
 
 1910  const auto vv = 
length(v);
 
 1911  return std::exp(q.w) *
 
 1912         vec<T, 4>{v * (vv > 0 ? std::sin(vv) / vv : 0), std::cos(vv)};
 
 
 1921  const auto v = q.xyz();
 
 1923  return {v * (vv > 0 ? std::acos(q.w / qq) / vv : 0), std::log(qq)};
 
 
 1930  const auto v = q.xyz();
 
 1931  const auto vv = 
length(v), qq = 
length(q), th = std::acos(q.w / qq);
 
 1932  return std::pow(qq, p) *
 
 1933         vec<T, 4>{v * (vv > 0 ? std::sin(p * th) / vv : 0), std::cos(p * th)};
 
 
 1942  return {a.x * b.w + a.w * b.x + a.y * b.z - a.z * b.y,
 
 1943          a.y * b.w + a.w * b.y + a.z * b.x - a.x * b.z,
 
 1944          a.z * b.w + a.w * b.z + a.x * b.y - a.y * b.x,
 
 1945          a.w * b.w - a.x * b.x - a.y * b.y - a.z * b.z};
 
 
 1950template <
class T, 
class... R>
 
 1966  return {q.w * q.w + q.x * q.x - q.y * q.y - q.z * q.z,
 
 1967          (q.x * q.y + q.z * q.w) * 2, (q.z * q.x - q.y * q.w) * 2};
 
 
 1974  return {(q.x * q.y - q.z * q.w) * 2,
 
 1975          q.w * q.w - q.x * q.x + q.y * q.y - q.z * q.z,
 
 1976          (q.y * q.z + q.x * q.w) * 2};
 
 
 1983  return {(q.z * q.x + q.y * q.w) * 2, (q.y * q.z - q.x * q.w) * 2,
 
 1984          q.w * q.w - q.x * q.x - q.y * q.y + q.z * q.z};
 
 
 2006  return std::atan2(
length(q.xyz()), q.w) * 2;
 
 
 2022  return nlerp(a, 
dot(a, b) < 0 ? -b : b, t);
 
 
 2029  return slerp(a, 
dot(a, b) < 0 ? -b : b, t);
 
 
 2037  return {axis * std::sin(
angle / 2), std::cos(
angle / 2)};
 
 
 2058template <
class T, 
int M>
 
 2062template <
class T, 
int M>
 
 2063constexpr vec<T, M> mul(
const T& b, 
const vec<T, M>& a) {
 
 2066template <
class T, 
int M, 
int N>
 
 2070template <
class T, 
int M, 
int N>
 
 2074template <
class T, 
int M>
 
 2078template <
class T, 
int M>
 
 2082template <
class T, 
int M>
 
 2084  return a.x * b.x + a.y * b.y;
 
 2086template <
class T, 
int M>
 
 2088  return a.x * b.x + a.y * b.y + a.z * b.z;
 
 2090template <
class T, 
int M>
 
 2092  return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w;
 
 2094template <
class T, 
int M, 
int N>
 
 2096  return {mul(a, b.x)};
 
 2098template <
class T, 
int M, 
int N>
 
 2100  return {mul(a, b.x), mul(a, b.y)};
 
 2102template <
class T, 
int M, 
int N>
 
 2104  return {mul(a, b.x), mul(a, b.y), mul(a, b.z)};
 
 2106template <
class T, 
int M, 
int N>
 
 2108  return {mul(a, b.x), mul(a, b.y), mul(a, b.z), mul(a, b.w)};
 
 2110template <
class T, 
int M, 
int N, 
int P>
 
 2113  return mul(mul(a, b), c);
 
 2115template <
class T, 
int M, 
int N, 
int P, 
int Q>
 
 2118  return mul(mul(a, b), c);
 
 2120template <
class T, 
int M, 
int N, 
int P, 
int Q>
 
 2123  return mul(mul(a, b, c), d);
 
 2125template <
class T, 
int M, 
int N, 
int P, 
int Q, 
int R>
 
 2128  return mul(mul(a, b, c), d);
 
 2130template <
class T, 
int M>
 
 2134template <
class T, 
int M>
 
 2136  return {a * b.x, a * b.y};
 
 2138template <
class T, 
int M>
 
 2140  return {a * b.x, a * b.y, a * b.z};
 
 2142template <
class T, 
int M>
 
 2144  return {a * b.x, a * b.y, a * b.z, a * b.w};
 
 2152  return {a.x.x, a.y.y};
 
 2156  return {a.x.x, a.y.y, a.z.z};
 
 2160  return {a.x.x, a.y.y, a.z.z, a.w.w};
 
 2162template <
class T, 
int N>
 
 2164  return sum(diagonal(a));
 
 2166template <
class T, 
int M>
 
 2170template <
class T, 
int M>
 
 2172  return {m.row(0), m.row(1)};
 
 2174template <
class T, 
int M>
 
 2176  return {m.row(0), m.row(1), m.row(2)};
 
 2178template <
class T, 
int M>
 
 2180  return {m.row(0), m.row(1), m.row(2), m.row(3)};
 
 2182template <
class T, 
int M>
 
 2192  return {{a.y.y, -a.x.y}, {-a.y.x, a.x.x}};
 
 2198template <
class T, 
int N>
 
 2200  return transpose(adjugate(a));
 
 2208  return a.x.x * a.y.y - a.x.y * a.y.x;
 
 2212  return a.x.x * (a.y.y * a.z.z - a.z.y * a.y.z) +
 
 2213         a.x.y * (a.y.z * a.z.x - a.z.z * a.y.x) +
 
 2214         a.x.z * (a.y.x * a.z.y - a.z.x * a.y.y);
 
 2218template <
class T, 
int N>
 
 2220  return adjugate(a) / determinant(a);
 
 2229template <
class T, 
int M>
 
 2233template <
class T, 
int M>
 
 2237template <
class T, 
int M>
 
 2239  return begin(a) + M;
 
 2241template <
class T, 
int M>
 
 2243  return begin(a) + M;
 
 2245template <
class T, 
int M, 
int N>
 
 2249template <
class T, 
int M, 
int N>
 
 2253template <
class T, 
int M, 
int N>
 
 2255  return begin(a) + N;
 
 2257template <
class T, 
int M, 
int N>
 
 2259  return begin(a) + N;
 
 2279  return {{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {translation, 1}};
 
 2283  return {{
qxdir(rotation), 0},
 
 2284          {
qydir(rotation), 0},
 
 2285          {
qzdir(rotation), 0},
 
 2290  return {{scaling.x, 0, 0, 0},
 
 2291          {0, scaling.y, 0, 0},
 
 2292          {0, 0, scaling.z, 0},
 
 2301                           const vec<T, 3>& view_y_dir, fwd_axis fwd = neg_z);
 
 2303mat<T, 4, 4> frustum_matrix(T x0, T x1, T y0, T y1, T n, T f,
 
 2304                            fwd_axis a = neg_z, z_range z = neg_one_to_one);
 
 2306mat<T, 4, 4> perspective_matrix(T fovy, T aspect, T n, T f, fwd_axis a = neg_z,
 
 2307                                z_range z = neg_one_to_one) {
 
 2308  T y = n * std::tan(fovy / 2), x = y * aspect;
 
 2309  return frustum_matrix(-x, x, -y, y, n, f, a, z);
 
 2321  vec<T, 1> operator()(
const std::array<T, 1>& a)
 const { 
return {a[0]}; }
 
 
 2325  vec<T, 2> operator()(
const std::array<T, 2>& a)
 const { 
return {a[0], a[1]}; }
 
 
 2329  vec<T, 3> operator()(
const std::array<T, 3>& a)
 const {
 
 2330    return {a[0], a[1], a[2]};
 
 
 2335  vec<T, 4> operator()(
const std::array<T, 4>& a)
 const {
 
 2336    return {a[0], a[1], a[2], a[3]};
 
 
 2342  std::array<T, 1> operator()(
const vec<T, 1>& a)
 const { 
return {a[0]}; }
 
 
 2346  std::array<T, 2> operator()(
const vec<T, 2>& a)
 const { 
return {a[0], a[1]}; }
 
 
 2350  std::array<T, 3> operator()(
const vec<T, 3>& a)
 const {
 
 2351    return {a[0], a[1], a[2]};
 
 
 2356  std::array<T, 4> operator()(
const vec<T, 4>& a)
 const {
 
 2357    return {a[0], a[1], a[2], a[3]};
 
 
 2363#ifdef MANIFOLD_DEBUG 
 2368std::ostream& operator<<(std::ostream& out, 
const vec<T, 1>& v) {
 
 2369  return out << 
'{' << v[0] << 
'}';
 
 2372std::ostream& operator<<(std::ostream& out, 
const vec<T, 2>& v) {
 
 2373  return out << 
'{' << v[0] << 
',' << v[1] << 
'}';
 
 2376std::ostream& operator<<(std::ostream& out, 
const vec<T, 3>& v) {
 
 2377  return out << 
'{' << v[0] << 
',' << v[1] << 
',' << v[2] << 
'}';
 
 2380std::ostream& operator<<(std::ostream& out, 
const vec<T, 4>& v) {
 
 2381  return out << 
'{' << v[0] << 
',' << v[1] << 
',' << v[2] << 
',' << v[3] << 
'}';
 
 2384template <
class T, 
int M>
 
 2385std::ostream& operator<<(std::ostream& out, 
const mat<T, M, 1>& m) {
 
 2386  return out << 
'{' << m[0] << 
'}';
 
 2388template <
class T, 
int M>
 
 2389std::ostream& operator<<(std::ostream& out, 
const mat<T, M, 2>& m) {
 
 2390  return out << 
'{' << m[0] << 
',' << m[1] << 
'}';
 
 2392template <
class T, 
int M>
 
 2393std::ostream& operator<<(std::ostream& out, 
const mat<T, M, 3>& m) {
 
 2394  return out << 
'{' << m[0] << 
',' << m[1] << 
',' << m[2] << 
'}';
 
 2396template <
class T, 
int M>
 
 2397std::ostream& operator<<(std::ostream& out, 
const mat<T, M, 4>& m) {
 
 2398  return out << 
'{' << m[0] << 
',' << m[1] << 
',' << m[2] << 
',' << m[3] << 
'}';
 
 2410struct hash<linalg::vec<T, 1>> {
 
 
 2417struct hash<linalg::vec<T, 2>> {
 
 2420    return h(v.x) ^ (h(v.y) << 1);
 
 
 2424struct hash<linalg::vec<T, 3>> {
 
 2427    return h(v.x) ^ (h(v.y) << 1) ^ (h(v.z) << 2);
 
 
 2431struct hash<linalg::vec<T, 4>> {
 
 2434    return h(v.x) ^ (h(v.y) << 1) ^ (h(v.z) << 2) ^ (h(v.w) << 3);
 
 
 2438template <
class T, 
int M>
 
 2439struct hash<linalg::mat<T, M, 1>> {
 
 2441    std::hash<linalg::vec<T, M>> h;
 
 
 2445template <
class T, 
int M>
 
 2446struct hash<linalg::mat<T, M, 2>> {
 
 2448    std::hash<linalg::vec<T, M>> h;
 
 2449    return h(v.x) ^ (h(v.y) << M);
 
 
 2452template <
class T, 
int M>
 
 2453struct hash<linalg::mat<T, M, 3>> {
 
 2455    std::hash<linalg::vec<T, M>> h;
 
 2456    return h(v.x) ^ (h(v.y) << M) ^ (h(v.z) << (M * 2));
 
 
 2459template <
class T, 
int M>
 
 2460struct hash<linalg::mat<T, M, 4>> {
 
 2462    std::hash<linalg::vec<T, M>> h;
 
 2463    return h(v.x) ^ (h(v.y) << M) ^ (h(v.z) << (M * 2)) ^ (h(v.w) << (M * 3));
 
 
 2472  return {{a.y.y * a.z.z - a.z.y * a.y.z, a.z.y * a.x.z - a.x.y * a.z.z,
 
 2473           a.x.y * a.y.z - a.y.y * a.x.z},
 
 2474          {a.y.z * a.z.x - a.z.z * a.y.x, a.z.z * a.x.x - a.x.z * a.z.x,
 
 2475           a.x.z * a.y.x - a.y.z * a.x.x},
 
 2476          {a.y.x * a.z.y - a.z.x * a.y.y, a.z.x * a.x.y - a.x.x * a.z.y,
 
 2477           a.x.x * a.y.y - a.y.x * a.x.y}};
 
 2482  return {{a.y.y * a.z.z * a.w.w + a.w.y * a.y.z * a.z.w +
 
 2483               a.z.y * a.w.z * a.y.w - a.y.y * a.w.z * a.z.w -
 
 2484               a.z.y * a.y.z * a.w.w - a.w.y * a.z.z * a.y.w,
 
 2485           a.x.y * a.w.z * a.z.w + a.z.y * a.x.z * a.w.w +
 
 2486               a.w.y * a.z.z * a.x.w - a.w.y * a.x.z * a.z.w -
 
 2487               a.z.y * a.w.z * a.x.w - a.x.y * a.z.z * a.w.w,
 
 2488           a.x.y * a.y.z * a.w.w + a.w.y * a.x.z * a.y.w +
 
 2489               a.y.y * a.w.z * a.x.w - a.x.y * a.w.z * a.y.w -
 
 2490               a.y.y * a.x.z * a.w.w - a.w.y * a.y.z * a.x.w,
 
 2491           a.x.y * a.z.z * a.y.w + a.y.y * a.x.z * a.z.w +
 
 2492               a.z.y * a.y.z * a.x.w - a.x.y * a.y.z * a.z.w -
 
 2493               a.z.y * a.x.z * a.y.w - a.y.y * a.z.z * a.x.w},
 
 2494          {a.y.z * a.w.w * a.z.x + a.z.z * a.y.w * a.w.x +
 
 2495               a.w.z * a.z.w * a.y.x - a.y.z * a.z.w * a.w.x -
 
 2496               a.w.z * a.y.w * a.z.x - a.z.z * a.w.w * a.y.x,
 
 2497           a.x.z * a.z.w * a.w.x + a.w.z * a.x.w * a.z.x +
 
 2498               a.z.z * a.w.w * a.x.x - a.x.z * a.w.w * a.z.x -
 
 2499               a.z.z * a.x.w * a.w.x - a.w.z * a.z.w * a.x.x,
 
 2500           a.x.z * a.w.w * a.y.x + a.y.z * a.x.w * a.w.x +
 
 2501               a.w.z * a.y.w * a.x.x - a.x.z * a.y.w * a.w.x -
 
 2502               a.w.z * a.x.w * a.y.x - a.y.z * a.w.w * a.x.x,
 
 2503           a.x.z * a.y.w * a.z.x + a.z.z * a.x.w * a.y.x +
 
 2504               a.y.z * a.z.w * a.x.x - a.x.z * a.z.w * a.y.x -
 
 2505               a.y.z * a.x.w * a.z.x - a.z.z * a.y.w * a.x.x},
 
 2506          {a.y.w * a.z.x * a.w.y + a.w.w * a.y.x * a.z.y +
 
 2507               a.z.w * a.w.x * a.y.y - a.y.w * a.w.x * a.z.y -
 
 2508               a.z.w * a.y.x * a.w.y - a.w.w * a.z.x * a.y.y,
 
 2509           a.x.w * a.w.x * a.z.y + a.z.w * a.x.x * a.w.y +
 
 2510               a.w.w * a.z.x * a.x.y - a.x.w * a.z.x * a.w.y -
 
 2511               a.w.w * a.x.x * a.z.y - a.z.w * a.w.x * a.x.y,
 
 2512           a.x.w * a.y.x * a.w.y + a.w.w * a.x.x * a.y.y +
 
 2513               a.y.w * a.w.x * a.x.y - a.x.w * a.w.x * a.y.y -
 
 2514               a.y.w * a.x.x * a.w.y - a.w.w * a.y.x * a.x.y,
 
 2515           a.x.w * a.z.x * a.y.y + a.y.w * a.x.x * a.z.y +
 
 2516               a.z.w * a.y.x * a.x.y - a.x.w * a.y.x * a.z.y -
 
 2517               a.z.w * a.x.x * a.y.y - a.y.w * a.z.x * a.x.y},
 
 2518          {a.y.x * a.w.y * a.z.z + a.z.x * a.y.y * a.w.z +
 
 2519               a.w.x * a.z.y * a.y.z - a.y.x * a.z.y * a.w.z -
 
 2520               a.w.x * a.y.y * a.z.z - a.z.x * a.w.y * a.y.z,
 
 2521           a.x.x * a.z.y * a.w.z + a.w.x * a.x.y * a.z.z +
 
 2522               a.z.x * a.w.y * a.x.z - a.x.x * a.w.y * a.z.z -
 
 2523               a.z.x * a.x.y * a.w.z - a.w.x * a.z.y * a.x.z,
 
 2524           a.x.x * a.w.y * a.y.z + a.y.x * a.x.y * a.w.z +
 
 2525               a.w.x * a.y.y * a.x.z - a.x.x * a.y.y * a.w.z -
 
 2526               a.w.x * a.x.y * a.y.z - a.y.x * a.w.y * a.x.z,
 
 2527           a.x.x * a.y.y * a.z.z + a.z.x * a.x.y * a.y.z +
 
 2528               a.y.x * a.z.y * a.x.z - a.x.x * a.z.y * a.y.z -
 
 2529               a.y.x * a.x.y * a.z.z - a.z.x * a.y.y * a.x.z}};
 
 2533constexpr T linalg::determinant(
const mat<T, 4, 4>& a) {
 
 2534  return a.x.x * (a.y.y * a.z.z * a.w.w + a.w.y * a.y.z * a.z.w +
 
 2535                  a.z.y * a.w.z * a.y.w - a.y.y * a.w.z * a.z.w -
 
 2536                  a.z.y * a.y.z * a.w.w - a.w.y * a.z.z * a.y.w) +
 
 2537         a.x.y * (a.y.z * a.w.w * a.z.x + a.z.z * a.y.w * a.w.x +
 
 2538                  a.w.z * a.z.w * a.y.x - a.y.z * a.z.w * a.w.x -
 
 2539                  a.w.z * a.y.w * a.z.x - a.z.z * a.w.w * a.y.x) +
 
 2540         a.x.z * (a.y.w * a.z.x * a.w.y + a.w.w * a.y.x * a.z.y +
 
 2541                  a.z.w * a.w.x * a.y.y - a.y.w * a.w.x * a.z.y -
 
 2542                  a.z.w * a.y.x * a.w.y - a.w.w * a.z.x * a.y.y) +
 
 2543         a.x.w * (a.y.x * a.w.y * a.z.z + a.z.x * a.y.y * a.w.z +
 
 2544                  a.w.x * a.z.y * a.y.z - a.y.x * a.z.y * a.w.z -
 
 2545                  a.w.x * a.y.y * a.z.z - a.z.x * a.w.y * a.y.z);
 
 2550                                        const vec<T, 3>& dest) {
 
 2551  T cosTheta = 
dot(orig, dest);
 
 2552  if (cosTheta >= 1 - std::numeric_limits<T>::epsilon()) {
 
 2553    return {0, 0, 0, 1};
 
 2555  if (cosTheta < -1 + std::numeric_limits<T>::epsilon()) {
 
 2556    vec<T, 3> axis = 
cross(vec<T, 3>(0, 0, 1), orig);
 
 2557    if (
length2(axis) < std::numeric_limits<T>::epsilon())
 
 2558      axis = 
cross(vec<T, 3>(1, 0, 0), orig);
 
 2560                         3.14159265358979323846264338327950288);
 
 2562  vec<T, 3> axis = 
cross(orig, dest);
 
 2563  T s = std::sqrt((1 + cosTheta) * 2);
 
 2564  return {axis * (1 / s), s * 0.5};
 
 2569  const vec<T, 4> q{m.x.x - m.y.y - m.z.z, m.y.y - m.x.x - m.z.z,
 
 2570                    m.z.z - m.x.x - m.y.y, m.x.x + m.y.y + m.z.z},
 
 2571      s[]{{1, m.x.y + m.y.x, m.z.x + m.x.z, m.y.z - m.z.y},
 
 2572          {m.x.y + m.y.x, 1, m.y.z + m.z.y, m.z.x - m.x.z},
 
 2573          {m.x.z + m.z.x, m.y.z + m.z.y, 1, m.x.y - m.y.x},
 
 2574          {m.y.z - m.z.y, m.z.x - m.x.z, m.x.y - m.y.x, 1}};
 
 2575  return copysign(
normalize(sqrt(max(T(0), T(1) + q))), s[argmax(q)]);
 
 2580                                           const vec<T, 3>& center,
 
 2581                                           const vec<T, 3>& view_y_dir,
 
 2583  const vec<T, 3> f = 
normalize(center - eye), z = a == pos_z ? f : -f,
 
 2585  return inverse(mat<T, 4, 4>{{x, 0}, {y, 0}, {z, 0}, {eye, 1}});
 
 2590                                            fwd_axis a, z_range z) {
 
 2591  const T s = a == pos_z ? T(1) : T(-1), o = z == neg_one_to_one ? n : 0;
 
 2592  return {{2 * n / (x1 - x0), 0, 0, 0},
 
 2593          {0, 2 * n / (y1 - y0), 0, 0},
 
 2594          {-s * (x0 + x1) / (x1 - x0), -s * (y0 + y1) / (y1 - y0),
 
 2595           s * (f + o) / (f - n), s},
 
 2596          {0, 0, -(n + o) * f / (f - n), 0}};
 
constexpr mat< T, 3, 3 > qmat(const vec< T, 4 > &q)
Create an equivalent mat3 rotation matrix from the input quaternion.
Definition linalg.h:1990
 
vec< T, 4 > qslerp(const vec< T, 4 > &a, const vec< T, 4 > &b, T t)
Spherical linear interpolation that takes the shortest path.
Definition linalg.h:2028
 
T qangle(const vec< T, 4 > &q)
Return the angle in radians of the axis-angle representation of the input normalized quaternion.
Definition linalg.h:2005
 
constexpr vec< T, 3 > qzdir(const vec< T, 4 > &q)
efficient shorthand for qrot(q, {0,0,1})
Definition linalg.h:1982
 
vec< T, 4 > qnlerp(const vec< T, 4 > &a, const vec< T, 4 > &b, T t)
Linear interpolation that takes the shortest path - this is not geometrically sensible,...
Definition linalg.h:2021
 
vec< T, 3 > qaxis(const vec< T, 4 > &q)
Return the normalized axis of the axis-angle representation of the input normalized quaternion.
Definition linalg.h:2013
 
vec< T, 4 > constexpr rotation_quat(const vec< T, 3 > &axis, T angle)
Returns a normalized quaternion representing a rotation by angle in radians about the provided axis.
Definition linalg.h:2036
 
constexpr vec< T, 3 > qxdir(const vec< T, 4 > &q)
efficient shorthand for qrot(q, {1,0,0})
Definition linalg.h:1965
 
constexpr vec< T, 3 > qrot(const vec< T, 4 > &q, const vec< T, 3 > &v)
Rotate a vector by a quaternion.
Definition linalg.h:1997
 
constexpr vec< T, 3 > qydir(const vec< T, 4 > &q)
efficient shorthand for qrot(q, {0,1,0})
Definition linalg.h:1973
 
vec< T, 4 > qinv(const vec< T, 4 > &q)
inverse or reciprocal of quaternion q (undefined for zero-length quaternions)
Definition linalg.h:1899
 
vec< T, 4 > qexp(const vec< T, 4 > &q)
exponential of quaternion q
Definition linalg.h:1908
 
vec< T, 4 > qpow(const vec< T, 4 > &q, const T &p)
quaternion q raised to the exponent p
Definition linalg.h:1929
 
vec< T, 4 > qlog(const vec< T, 4 > &q)
logarithm of quaternion q
Definition linalg.h:1920
 
constexpr vec< T, 4 > qmul(const vec< T, 4 > &a, const vec< T, 4 > &b)
Hamilton product of quaternions a and b
Definition linalg.h:1941
 
constexpr vec< T, 4 > qconj(const vec< T, 4 > &q)
conjugate of quaternion q
Definition linalg.h:1890
 
constexpr apply_t< detail::clamp, X, L, H > clamp(const X &x, const L &l, const H &h)
Clamps the components of x between l and h, provided l[i] < h[i].
Definition linalg.h:1700
 
constexpr apply_t< detail::select, P, A, B > select(const P &p, const A &a, const B &b)
Returns the component from a if the corresponding component of p is true and from b otherwise.
Definition linalg.h:1709
 
constexpr apply_t< detail::lerp, A, B, T > lerp(const A &a, const B &b, const T &t)
Linear interpolation from a to b as t goes from 0 -> 1. Values beyond [a, b] will result if t is outs...
Definition linalg.h:1718
 
constexpr vec< T, sizeof...(I)> swizzle(const vec< T, M > &a)
Returns a vector containing the specified ordered indices, e.g. linalg::swizzle<1,...
Definition linalg.h:1521
 
constexpr mat< T, I1 - I0, J1 - J0 > submat(const mat< T, M, N > &a)
Returns a matrix containing the specified row and column range: linalg::submat<rowStart,...
Definition linalg.h:1537
 
constexpr vec< T, I1 - I0 > subvec(const vec< T, M > &a)
Returns a vector containing the specified index range, e.g. linalg::subvec<1, 4>(vec4(4,...
Definition linalg.h:1529
 
vec< T, 3 > roty(T a, const vec< T, 3 > &v)
vector v rotated counter-clockwise by the angle a in radians around the Y axis
Definition linalg.h:1844
 
vec< T, 2 > rot(T a, const vec< T, 2 > &v)
vector v rotated counter-clockwise by the angle a in radians
Definition linalg.h:1826
 
constexpr T distance2(const vec< T, M > &a, const vec< T, M > &b)
square of the Euclidean distance between points a and b
Definition linalg.h:1795
 
vec< T, 3 > rotx(T a, const vec< T, 3 > &v)
vector v rotated counter-clockwise by the angle a in radians around the X axis
Definition linalg.h:1835
 
constexpr T length2(const vec< T, M > &a)
square of the length or magnitude of vector a
Definition linalg.h:1770
 
constexpr T dot(const vec< T, M > &a, const vec< T, M > &b)
dot or inner product of vectors a and b
Definition linalg.h:1763
 
vec< T, M > nlerp(const vec< T, M > &a, const vec< T, M > &b, T t)
shorthand for normalize(lerp(a,b,t))
Definition linalg.h:1861
 
vec< T, M > normalize(const vec< T, M > &a)
unit length vector in the same direction as a (undefined for zero-length vectors)
Definition linalg.h:1786
 
vec< T, M > slerp(const vec< T, M > &a, const vec< T, M > &b, T t)
spherical linear interpolation between unit vectors a and b (undefined for non-unit vectors) by param...
Definition linalg.h:1870
 
T angle(const vec< T, M > &a, const vec< T, M > &b)
Return the angle in radians between two non-unit vectors.
Definition linalg.h:1818
 
T uangle(const vec< T, M > &a, const vec< T, M > &b)
Return the angle in radians between two unit vectors.
Definition linalg.h:1810
 
constexpr T cross(const vec< T, 2 > &a, const vec< T, 2 > &b)
shorthand for cross({a.x,a.y,0}, {b.x,b.y,0}).z
Definition linalg.h:1733
 
vec< T, 3 > rotz(T a, const vec< T, 3 > &v)
vector v rotated counter-clockwise by the angle a in radians around the Z axis
Definition linalg.h:1853
 
T length(const vec< T, M > &a)
length or magnitude of a vector a
Definition linalg.h:1777
 
T distance(const vec< T, M > &a, const vec< T, M > &b)
Euclidean distance between points a and b
Definition linalg.h:1803