// license:GPL-2.0+ // copyright-holders:Couriersud #ifndef PLIB_VECTOR_OPS_H_ #define PLIB_VECTOR_OPS_H_ /// /// \file vector_ops.h /// /// Base vector operations /// /// #include "pconfig.h" #include "pmath.h" #include #include #include #if !defined(__clang__) && !defined(_MSC_VER) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 6)) #if !(__GNUC__ > 7 || (__GNUC__ == 7 && __GNUC_MINOR__ > 3)) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wmaybe-uninitialized" #endif #endif namespace plib { template void vec_set_scalar(const std::size_t n, VT &v, T && scalar) noexcept { const typename std::remove_reference::type s(std::forward(scalar)); for ( std::size_t i = 0; i < n; i++ ) v[i] = s; } template void vec_set(const std::size_t n, VT &v, const VS & source) noexcept { for ( std::size_t i = 0; i < n; i++ ) v[i] = source[i]; } template T vec_mult(const std::size_t n, const V1 & v1, const V2 & v2 ) noexcept { using b8 = std::array; PALIGNAS_VECTOROPT() b8 value = {0}; for (std::size_t i = 0; i < n ; i++ ) { value[i & 7] += v1[i] * v2[i]; } return value[0] + value[1] + value[2] + value[3] + value[4] + value[5] + value[6] + value[7]; } template T vec_mult2(const std::size_t n, const VT &v) noexcept { using b8 = std::array; PALIGNAS_VECTOROPT() b8 value = {0}; for (std::size_t i = 0; i < n ; i++ ) { value[i & 7] += v[i] * v[i]; } return value[0] + value[1] + value[2] + value[3] + value[4] + value[5] + value[6] + value[7]; } template T vec_sum(const std::size_t n, const VT &v) noexcept { if (n<8) { T value(0); for (std::size_t i = 0; i < n ; i++ ) value += v[i]; return value; } else { using b8 = std::array; PALIGNAS_VECTOROPT() b8 value = {0}; for (std::size_t i = 0; i < n ; i++ ) value[i & 7] += v[i]; return ((value[0] + value[1]) + (value[2] + value[3])) + ((value[4] + value[5]) + (value[6] + value[7])); } } template void vec_mult_scalar(const std::size_t n, VR & result, const VV & v, T && scalar) noexcept { const typename std::remove_reference::type s(std::forward(scalar)); for ( std::size_t i = 0; i < n; i++ ) result[i] = s * v[i]; } template void vec_add_mult_scalar(const std::size_t n, VR & result, const VV & v, T && scalar) noexcept { const typename std::remove_reference::type s(std::forward(scalar)); for ( std::size_t i = 0; i < n; i++ ) result[i] += s * v[i]; } template void vec_add_mult_scalar_p(const std::size_t n, T * result, const T * v, T scalar) noexcept { for ( std::size_t i = 0; i < n; i++ ) result[i] += scalar * v[i]; } template void vec_add_ip(const std::size_t n, R & result, const V & v) noexcept { for ( std::size_t i = 0; i < n; i++ ) result[i] += v[i]; } template void vec_sub(const std::size_t n, VR & result, const V1 &v1, const V2 & v2) noexcept { for ( std::size_t i = 0; i < n; i++ ) result[i] = v1[i] - v2[i]; } template void vec_scale(const std::size_t n, V & v, T &&scalar) noexcept { const typename std::remove_reference::type s(std::forward(scalar)); for ( std::size_t i = 0; i < n; i++ ) v[i] *= s; } template T vec_maxabs(const std::size_t n, const V & v) noexcept { T ret = 0.0; for ( std::size_t i = 0; i < n; i++ ) ret = std::max(ret, plib::abs(v[i])); return ret; } } // namespace plib #if !defined(__clang__) && !defined(_MSC_VER) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 6)) #if !(__GNUC__ > 7 || (__GNUC__ == 7 && __GNUC_MINOR__ > 3)) #pragma GCC diagnostic pop #endif #endif #endif // PLIB_VECTOR_OPS_H_