diff --git a/include/ircd/math/math.h b/include/ircd/math/math.h index b8c1cd276..88a423e5b 100644 --- a/include/ircd/math/math.h +++ b/include/ircd/math/math.h @@ -13,3 +13,4 @@ #include "log2.h" #include "inv.h" +#include "mean.h" diff --git a/include/ircd/math/mean.h b/include/ircd/math/mean.h new file mode 100644 index 000000000..c24da44d6 --- /dev/null +++ b/include/ircd/math/mean.h @@ -0,0 +1,65 @@ +// Matrix Construct +// +// Copyright (C) Matrix Construct Developers, Authors & Contributors +// Copyright (C) 2016-2021 Jason Volk +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice is present in all copies. The +// full license for this software is available in the LICENSE file. + +#pragma once +#define HAVE_IRCD_MATH_MEAN_H + +namespace ircd::math +{ + template + typename std::enable_if(), T>::type + mean(const vector_view &); + + template + typename std::enable_if(), simd::lane_type>::type + mean(const vector_view &); +} + +template +inline typename std::enable_if(), ircd::simd::lane_type>::type +ircd::math::mean(const vector_view &a) +{ + using value_type = simd::lane_type; + + const auto &sum + { + simd::accumulate(a.data(), u64x2{0, a.size()}, T{0}, [] + (auto &ret, const auto block, const auto mask) + { + ret += block; + }) + }; + + value_type num {0}; + for(size_t i{0}; i < simd::lanes(); ++i) + num += sum[i]; + + const auto &den + { + a.size() * simd::lanes() + }; + + num /= den; + return num; +} + +template +inline typename std::enable_if(), T>::type +ircd::math::mean(const vector_view &a) +{ + T ret{0}; + + size_t i{0}; + while(i < a.size()) + ret += a[i++]; + + ret /= i; + return ret; +}