Message ID | 20241118221618.13953-7-laurent.pinchart@ideasonboard.com |
---|---|
State | New |
Headers | show |
Series |
|
Related | show |
Hi 2024. november 18., hétfő 23:16 keltezéssel, Laurent Pinchart <laurent.pinchart@ideasonboard.com> írta: > Instead of hand-coding all arithmetic operators, implement them based on > a generic apply() function that takes an operator-specific > std::function. This will simplify adding missing arithmetic operators. > > Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> > Reviewed-by: Milan Zamazal <mzamazal@redhat.com> > --- > Changes since v2: > > - Include <algorithm> > - Use std::plus, std::minus, std::multiplies and std::divides > --- > src/ipa/libipa/vector.h | 50 ++++++++++++++++++++++++----------------- > 1 file changed, 30 insertions(+), 20 deletions(-) > > diff --git a/src/ipa/libipa/vector.h b/src/ipa/libipa/vector.h > index 2abb5536361c..76fd2934b870 100644 > --- a/src/ipa/libipa/vector.h > +++ b/src/ipa/libipa/vector.h > @@ -6,8 +6,10 @@ > */ > #pragma once > > +#include <algorithm> > #include <array> > #include <cmath> > +#include <functional> > #include <optional> > #include <ostream> > > @@ -78,36 +80,24 @@ public: > return ret; > } > > - constexpr Vector<T, Rows> operator-(const Vector<T, Rows> &other) const > + constexpr Vector operator-(const Vector &other) const > { > - Vector<T, Rows> ret; > - for (unsigned int i = 0; i < Rows; i++) > - ret[i] = data_[i] - other[i]; > - return ret; > + return apply(*this, other, std::minus<>{}); > } > > - constexpr Vector<T, Rows> operator+(const Vector<T, Rows> &other) const > + constexpr Vector operator+(const Vector &other) const > { > - Vector<T, Rows> ret; > - for (unsigned int i = 0; i < Rows; i++) > - ret[i] = data_[i] + other[i]; > - return ret; > + return apply(*this, other, std::plus<>{}); > } > > - constexpr Vector<T, Rows> operator*(T factor) const > + constexpr Vector operator*(T factor) const > { > - Vector<T, Rows> ret; > - for (unsigned int i = 0; i < Rows; i++) > - ret[i] = data_[i] * factor; > - return ret; > + return apply(*this, factor, std::multiplies<>{}); > } > > - constexpr Vector<T, Rows> operator/(T factor) const > + constexpr Vector operator/(T factor) const > { > - Vector<T, Rows> ret; > - for (unsigned int i = 0; i < Rows; i++) > - ret[i] = data_[i] / factor; > - return ret; > + return apply(*this, factor, std::divides<>{}); > } > > constexpr T dot(const Vector<T, Rows> &other) const > @@ -182,6 +172,26 @@ public: > } > > private: > + static constexpr Vector apply(const Vector &lhs, const Vector &rhs, std::function<T(T, T)> func) > + { > + Vector result; > + std::transform(lhs.data_.begin(), lhs.data_.end(), > + rhs.data_.begin(), result.data_.begin(), > + func); > + > + return result; > + } > + > + static constexpr Vector apply(const Vector &lhs, T rhs, std::function<T(T, T)> func) > + { > + Vector result; > + std::transform(lhs.data_.begin(), lhs.data_.end(), > + result.data_.begin(), > + [&func, rhs](T v) { return func(v, rhs); }); > + > + return result; > + } `std::function` is quite heavy. I think making `apply()` a template would be beneficial wrt. performance. Regards, Barnabás Pőcze > + > std::array<T, Rows> data_; > }; > > -- > Regards, > > Laurent Pinchart
Hi Barnabás, On Mon, Nov 18, 2024 at 11:40:16PM +0000, Barnabás Pőcze wrote: > 2024. november 18., hétfő 23:16 keltezéssel, Laurent Pinchart írta: > > > Instead of hand-coding all arithmetic operators, implement them based on > > a generic apply() function that takes an operator-specific > > std::function. This will simplify adding missing arithmetic operators. > > > > Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> > > Reviewed-by: Milan Zamazal <mzamazal@redhat.com> > > --- > > Changes since v2: > > > > - Include <algorithm> > > - Use std::plus, std::minus, std::multiplies and std::divides > > --- > > src/ipa/libipa/vector.h | 50 ++++++++++++++++++++++++----------------- > > 1 file changed, 30 insertions(+), 20 deletions(-) > > > > diff --git a/src/ipa/libipa/vector.h b/src/ipa/libipa/vector.h > > index 2abb5536361c..76fd2934b870 100644 > > --- a/src/ipa/libipa/vector.h > > +++ b/src/ipa/libipa/vector.h > > @@ -6,8 +6,10 @@ > > */ > > #pragma once > > > > +#include <algorithm> > > #include <array> > > #include <cmath> > > +#include <functional> > > #include <optional> > > #include <ostream> > > > > @@ -78,36 +80,24 @@ public: > > return ret; > > } > > > > - constexpr Vector<T, Rows> operator-(const Vector<T, Rows> &other) const > > + constexpr Vector operator-(const Vector &other) const > > { > > - Vector<T, Rows> ret; > > - for (unsigned int i = 0; i < Rows; i++) > > - ret[i] = data_[i] - other[i]; > > - return ret; > > + return apply(*this, other, std::minus<>{}); > > } > > > > - constexpr Vector<T, Rows> operator+(const Vector<T, Rows> &other) const > > + constexpr Vector operator+(const Vector &other) const > > { > > - Vector<T, Rows> ret; > > - for (unsigned int i = 0; i < Rows; i++) > > - ret[i] = data_[i] + other[i]; > > - return ret; > > + return apply(*this, other, std::plus<>{}); > > } > > > > - constexpr Vector<T, Rows> operator*(T factor) const > > + constexpr Vector operator*(T factor) const > > { > > - Vector<T, Rows> ret; > > - for (unsigned int i = 0; i < Rows; i++) > > - ret[i] = data_[i] * factor; > > - return ret; > > + return apply(*this, factor, std::multiplies<>{}); > > } > > > > - constexpr Vector<T, Rows> operator/(T factor) const > > + constexpr Vector operator/(T factor) const > > { > > - Vector<T, Rows> ret; > > - for (unsigned int i = 0; i < Rows; i++) > > - ret[i] = data_[i] / factor; > > - return ret; > > + return apply(*this, factor, std::divides<>{}); > > } > > > > constexpr T dot(const Vector<T, Rows> &other) const > > @@ -182,6 +172,26 @@ public: > > } > > > > private: > > + static constexpr Vector apply(const Vector &lhs, const Vector &rhs, std::function<T(T, T)> func) > > + { > > + Vector result; > > + std::transform(lhs.data_.begin(), lhs.data_.end(), > > + rhs.data_.begin(), result.data_.begin(), > > + func); > > + > > + return result; > > + } > > + > > + static constexpr Vector apply(const Vector &lhs, T rhs, std::function<T(T, T)> func) > > + { > > + Vector result; > > + std::transform(lhs.data_.begin(), lhs.data_.end(), > > + result.data_.begin(), > > + [&func, rhs](T v) { return func(v, rhs); }); > > + > > + return result; > > + } > > `std::function` is quite heavy. I think making `apply()` a template would be > beneficial wrt. performance. I'll try it out in v4. > > + > > std::array<T, Rows> data_; > > }; > >
diff --git a/src/ipa/libipa/vector.h b/src/ipa/libipa/vector.h index 2abb5536361c..76fd2934b870 100644 --- a/src/ipa/libipa/vector.h +++ b/src/ipa/libipa/vector.h @@ -6,8 +6,10 @@ */ #pragma once +#include <algorithm> #include <array> #include <cmath> +#include <functional> #include <optional> #include <ostream> @@ -78,36 +80,24 @@ public: return ret; } - constexpr Vector<T, Rows> operator-(const Vector<T, Rows> &other) const + constexpr Vector operator-(const Vector &other) const { - Vector<T, Rows> ret; - for (unsigned int i = 0; i < Rows; i++) - ret[i] = data_[i] - other[i]; - return ret; + return apply(*this, other, std::minus<>{}); } - constexpr Vector<T, Rows> operator+(const Vector<T, Rows> &other) const + constexpr Vector operator+(const Vector &other) const { - Vector<T, Rows> ret; - for (unsigned int i = 0; i < Rows; i++) - ret[i] = data_[i] + other[i]; - return ret; + return apply(*this, other, std::plus<>{}); } - constexpr Vector<T, Rows> operator*(T factor) const + constexpr Vector operator*(T factor) const { - Vector<T, Rows> ret; - for (unsigned int i = 0; i < Rows; i++) - ret[i] = data_[i] * factor; - return ret; + return apply(*this, factor, std::multiplies<>{}); } - constexpr Vector<T, Rows> operator/(T factor) const + constexpr Vector operator/(T factor) const { - Vector<T, Rows> ret; - for (unsigned int i = 0; i < Rows; i++) - ret[i] = data_[i] / factor; - return ret; + return apply(*this, factor, std::divides<>{}); } constexpr T dot(const Vector<T, Rows> &other) const @@ -182,6 +172,26 @@ public: } private: + static constexpr Vector apply(const Vector &lhs, const Vector &rhs, std::function<T(T, T)> func) + { + Vector result; + std::transform(lhs.data_.begin(), lhs.data_.end(), + rhs.data_.begin(), result.data_.begin(), + func); + + return result; + } + + static constexpr Vector apply(const Vector &lhs, T rhs, std::function<T(T, T)> func) + { + Vector result; + std::transform(lhs.data_.begin(), lhs.data_.end(), + result.data_.begin(), + [&func, rhs](T v) { return func(v, rhs); }); + + return result; + } + std::array<T, Rows> data_; };