summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib/netlist/plib/vector_ops.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/netlist/plib/vector_ops.h')
-rw-r--r--src/lib/netlist/plib/vector_ops.h151
1 files changed, 151 insertions, 0 deletions
diff --git a/src/lib/netlist/plib/vector_ops.h b/src/lib/netlist/plib/vector_ops.h
new file mode 100644
index 00000000000..8043c48f61c
--- /dev/null
+++ b/src/lib/netlist/plib/vector_ops.h
@@ -0,0 +1,151 @@
+// license:GPL-2.0+
+// copyright-holders:Couriersud
+/*
+ * vector_ops.h
+ *
+ * Base vector operations
+ *
+ */
+
+#ifndef PLIB_VECTOR_OPS_H_
+#define PLIB_VECTOR_OPS_H_
+
+#include "pconfig.h"
+
+#include <algorithm>
+#include <cmath>
+#include <type_traits>
+
+#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<typename VT, typename T>
+ void vec_set_scalar(const std::size_t n, VT &v, T && scalar)
+ {
+ const typename std::remove_reference<decltype(v[0])>::type s(std::forward<T>(scalar));
+ for ( std::size_t i = 0; i < n; i++ )
+ v[i] = s;
+ }
+
+ template<typename VT, typename VS>
+ void vec_set(const std::size_t n, VT &v, const VS & source)
+ {
+ for ( std::size_t i = 0; i < n; i++ )
+ v[i] = source[i];
+ }
+
+ template<typename T, typename V1, typename V2>
+ T vec_mult(const std::size_t n, const V1 & v1, const V2 & v2 )
+ {
+ using b8 = T[8];
+ 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<typename T, typename VT>
+ T vec_mult2(const std::size_t n, const VT &v)
+ {
+ using b8 = T[8];
+ 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<typename T, typename VT>
+ T vec_sum(const std::size_t n, const VT &v)
+ {
+ if (n<8)
+ {
+ T value(0);
+ for (std::size_t i = 0; i < n ; i++ )
+ value += v[i];
+
+ return value;
+ }
+ else
+ {
+ using b8 = T[8];
+ 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<typename VV, typename T, typename VR>
+ void vec_mult_scalar(const std::size_t n, VR & result, const VV & v, T && scalar)
+ {
+ const typename std::remove_reference<decltype(v[0])>::type s(std::forward<T>(scalar));
+ for ( std::size_t i = 0; i < n; i++ )
+ result[i] = s * v[i];
+ }
+
+ template<typename VR, typename VV, typename T>
+ void vec_add_mult_scalar(const std::size_t n, VR & result, const VV & v, T && scalar)
+ {
+ const typename std::remove_reference<decltype(v[0])>::type s(std::forward<T>(scalar));
+ for ( std::size_t i = 0; i < n; i++ )
+ result[i] += s * v[i];
+ }
+
+ template<typename T>
+ void vec_add_mult_scalar_p(const std::size_t n, T * result, const T * v, T scalar)
+ {
+ for ( std::size_t i = 0; i < n; i++ )
+ result[i] += scalar * v[i];
+ }
+
+ template<typename R, typename V>
+ void vec_add_ip(const std::size_t n, R & result, const V & v)
+ {
+ for ( std::size_t i = 0; i < n; i++ )
+ result[i] += v[i];
+ }
+
+ template<typename VR, typename V1, typename V2>
+ void vec_sub(const std::size_t n, VR & result, const V1 &v1, const V2 & v2)
+ {
+ for ( std::size_t i = 0; i < n; i++ )
+ result[i] = v1[i] - v2[i];
+ }
+
+ template<typename V, typename T>
+ void vec_scale(const std::size_t n, V & v, T &&scalar)
+ {
+ const typename std::remove_reference<decltype(v[0])>::type s(std::forward<T>(scalar));
+ for ( std::size_t i = 0; i < n; i++ )
+ v[i] *= s;
+ }
+
+ template<typename T, typename V>
+ T vec_maxabs(const std::size_t n, const V & v)
+ {
+ T ret = 0.0;
+ for ( std::size_t i = 0; i < n; i++ )
+ ret = std::max(ret, std::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_ */