35template <
class ForwardIt>
36inline constexpr ForwardIt
MinElement(ForwardIt first, ForwardIt last) {
41 ForwardIt smallest = first;
43 for (; first != last; ++first) {
44 if (*first < *smallest) {
53template <
class ForwardIt>
54inline constexpr ForwardIt
MaxElement(ForwardIt first, ForwardIt last) {
59 ForwardIt largest = first;
61 for (; first != last; ++first) {
62 if (*largest < *first) {
69template <
typename T,
size_t N>
74template <
typename T,
size_t N>
83template <
typename T,
typename Eps,
size_t D0,
size_t... DIMS>
86 static_assert(D0 > 0,
"NearEqual requires non-empty arrays");
87 bool isNear =
NearEqual(a[0], b[0], epsilon);
88 for (
size_t i = 1; i < D0; ++i) {
89 isNear = isNear &&
NearEqual(a[i], b[i], epsilon);
94template <
typename T,
size_t D0,
int D1>
99 static_assert(D0 > 0,
"VNearEqual requires non-empty arrays");
100 auto isNear =
VNearEqual(a[0], b[0], epsilon);
101 for (
size_t i = 1; i < D0; ++i) {
107template <
typename T,
size_t D0,
int D1>
117template <
typename T,
size_t N>
122template <
typename T,
size_t N>
131template <
typename T,
int N>
135 for (
int i = 0; i < axis; ++i) {
141 for (
int i = axis + 1; i < N; ++i) {
152template <
typename T,
size_t N>
156 constexpr auto kSmallestFloat = std::numeric_limits<ScalarType<T>>::min();
157 static_assert(kSmallestFloat > 0);
158 return a * (T(1) / (
Norm(a) + T(kSmallestFloat)));
161template <
typename T,
size_t N>
163 constexpr auto kSmallestFloat = std::numeric_limits<ScalarType<T>>::min();
164 static_assert(kSmallestFloat > 0);
165 return a * (T(1) / (
Sqrt(sqrNorm) + T(kSmallestFloat)));
172template <
typename T,
size_t N>
174 static_assert(std::is_arithmetic_v<T>,
"Arithmetic type required");
175 static_assert(N > 0,
"Sum requires a non-empty array");
177 for (
size_t i = 1; i < N; ++i) {
183template <
typename T,
size_t N>
185 static_assert(std::is_arithmetic_v<T>,
"Arithmetic type required");
186 static_assert(N > 0,
"Prod requires a non-empty array");
188 for (
size_t i = 1; i < N; ++i) {
194template <
typename T,
size_t N>
196 static_assert(std::is_arithmetic_v<T>,
"Arithmetic type required");
197 static_assert(N > 0,
"Mean requires a non-empty array");
198 return Sum(a) /
static_cast<T
>(N);
201template <
typename T,
size_t N>
203 static_assert(N > 0,
"Max requires a non-empty array");
204 static_assert(std::is_arithmetic_v<T>,
"Arithmetic type required");
206 for (
int i = 1; i < N; ++i) {
214template <
typename T,
size_t N>
216 static_assert(N > 0,
"Min requires a non-empty array");
217 static_assert(std::is_arithmetic_v<T>,
"Arithmetic type required");
219 for (
int i = 1; i < N; ++i) {
231template <
typename T,
size_t N>
234 for (
int i = 0; i < N; ++i) {
235 output[i] = T(
Floor(a[i]));
240template <
typename T,
size_t N>
243 for (
int i = 0; i < N; ++i) {
244 output[i] = T(
Ceil(a[i]));
249template <
typename T,
size_t N>
252 for (
int i = 0; i < N; ++i) {
253 output[i] = T(
Round(a[i]));
258template <
typename T,
size_t N>
261 for (
int i = 0; i < N; ++i) {
262 output[i] =
Clamp(a[i], min, max);
267template <
typename T,
size_t N>
270 for (
int i = 0; i < N; ++i) {
271 output[i] =
Max(a[i], max);
276template <
typename T,
size_t N>
279 for (
int i = 0; i < N; ++i) {
280 output[i] =
Min(a[i], min);
285template <
typename T,
size_t N>
289 for (
int i = 0; i < N; ++i) {
290 output[i] =
Clamp(a[i], min[i], max[i]);
295template <
typename T,
size_t N,
bool MinInclusiveT,
bool MaxInclusiveT>
300 std::integral_constant<bool, MinInclusiveT> minInclusive,
301 std::integral_constant<bool, MaxInclusiveT> maxInclusive) {
303 for (
int i = 0; i < N; ++i) {
304 output[i] =
Rect(a[i], min[i], max[i], minInclusive, maxInclusive);
309template <
typename T,
size_t N>
312 for (
int i = 0; i < N; ++i) {
313 output[i] =
Max(a[i], max[i]);
318template <
typename T,
size_t N>
321 for (
int i = 0; i < N; ++i) {
322 output[i] =
Min(a[i], min[i]);
331template <
typename T,
size_t N>
333 static_assert(N > 0,
"Dot requires non-empty arrays");
334 T result = a[0] * b[0];
335 for (
size_t i = 1; i < N; ++i) {
336 result += a[i] * b[i];
341template <
typename T,
size_t N>
343 static_assert(N > 0,
"Dot requires non-empty arrays");
345 T result = a[0] * b[0];
346 for (
size_t i = 1; i < N; ++i) {
347 result += a[i] * b[i];
356 for (
size_t i = 0; i < a.
size(); ++i) {
357 result += a[i] * b[i];
369 (a[1] * b[2] - a[2] * b[1]), (a[2] * b[0] - a[0] * b[2]), (a[0] * b[1] - a[1] * b[0])};
379 static_assert(std::is_arithmetic_v<T>,
"Arithmetic type required");
398 T
const absX =
Abs(vec[0]);
399 T
const absY =
Abs(vec[1]);
400 T
const absZ =
Abs(vec[2]);
402 auto const xSmallest = (absX <= absY) && (absX <= absZ);
403 auto const ySmallest = (absY <= absX) && (absY <= absZ);
406 Select(xSmallest, zero,
Select(ySmallest, -vec[2], vec[1])),
407 Select(xSmallest, vec[2],
Select(ySmallest, zero, -vec[0])),
408 Select(xSmallest, -vec[1],
Select(ySmallest, vec[0], zero))};
415template <
class T,
int DN,
size_t D0,
size_t... DIMS>
417 static_assert(std::is_floating_point_v<T>,
"VIsFinite only supports float or double");
418 static_assert(D0 > 0,
"VIsFinite requires non-empty arrays");
420 for (
size_t i = 1; i < D0; ++i) {
426template <
class T,
int DN,
size_t D0,
size_t... DIMS>
428 if constexpr (std::is_integral_v<T>) {
435template <
class T,
size_t D0,
size_t... DIMS>
437 static_assert(D0 > 0,
"IsFinite requires non-empty arrays");
439 for (
size_t i = 1; i < D0; ++i) {
constexpr SizeT size() const
#define MOCHI_ASSERT_VERBOSE(condition_without_side_effects,...)
T Dot(Simd< T, N > a, Simd< T, N > b)
Simd< T, N > VIsFinite(Simd< T, N > a)
constexpr T const & Min(T const &a, T const &b)
T NormSqr(Simd< T, N > a)
constexpr T TripleProduct(NdArray< T, 3 > const &a, NdArray< T, 3 > const &b, NdArray< T, 3 > const &c)
constexpr ValT Rect(ValT value, MinT min, MaxT max, std::integral_constant< bool, kMinInclusive >=std::true_type{}, std::integral_constant< bool, kMaxInclusive >=std::false_type{})
V VNearEqual(V a, V b, V epsilon)
constexpr NdArray< T, 2 > OrthogonalVector(NdArray< T, 2 > const &vec)
Simd< T, N > Normalize(Simd< T, N > a)
constexpr T Select(bool condition, T a, T b)
constexpr size_t ArgMin(NdArray< T, N > const &a)
constexpr NdArray< T, N > BasisVector(int axis)
constexpr T Mean(NdArray< T, N > const &a)
constexpr T Sum(NdArray< T, N > const &a)
constexpr size_t ArgMax(NdArray< T, N > const &a)
constexpr ValT Clamp(ValT value, MinT min, MaxT max)
constexpr ForwardIt MinElement(ForwardIt first, ForwardIt last)
constexpr T const & Max(T const &a, T const &b)
constexpr T Prod(NdArray< T, N > const &a)
bool NearEqual(TransformRT const &a, TransformRT const &b, real epsilon=kDefaultNearEqualEpsilon< real >)
bool IsFinite(TransformRT const &a)
constexpr NdArray< T, 3 > Cross(NdArray< T, 3 > const &a, NdArray< T, 3 > const &b)
constexpr ForwardIt MaxElement(ForwardIt first, ForwardIt last)