Optimize math::length(vector) to prevent allocations for runtime-sized vectors

This commit is contained in:
Nikita Lisitsa 2025-12-04 18:11:11 +03:00
parent a5acb9534b
commit 8832700e25

View file

@ -1,6 +1,7 @@
#pragma once #pragma once
#include <psemek/math/detail/array.hpp> #include <psemek/math/detail/array.hpp>
#include <psemek/math/math.hpp>
#include <psemek/util/hash.hpp> #include <psemek/util/hash.hpp>
#include <psemek/util/span.hpp> #include <psemek/util/span.hpp>
@ -286,17 +287,22 @@ namespace psemek::math
using std::max; using std::max;
T r = abs(v[0]); T r = abs(v[0]);
for (std::size_t i = 1; i < v.dimension(); ++i) for (std::size_t i = 1; i < v.dimension(); ++i)
r = max(r, abs(v[i])); make_max(r, abs(v[i]));
return r; return r;
} }
template <typename T, std::size_t N> template <typename T, std::size_t N>
T length(vector<T, N> const & v) T length(vector<T, N> const & v)
{ {
T const m = linf_norm(v); T const max = linf_norm(v);
if (m == T(0)) return m; if (max == T(0)) return max;
T sum{};
for (auto const & value : v.values())
sum += sqr(value / max);
using std::sqrt; using std::sqrt;
return m * sqrt(length_sqr(v / m)); return max * sqrt(sum);
} }
template <typename T, std::size_t N> template <typename T, std::size_t N>