Warning, file /include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorFunctors.h was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef EIGEN_CXX11_TENSOR_TENSOR_FUNCTORS_H
0011 #define EIGEN_CXX11_TENSOR_TENSOR_FUNCTORS_H
0012
0013 namespace Eigen {
0014 namespace internal {
0015
0016
0017
0018
0019
0020 template <typename Scalar>
0021 struct scalar_mod_op {
0022 EIGEN_DEVICE_FUNC scalar_mod_op(const Scalar& divisor) : m_divisor(divisor) {}
0023 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar operator() (const Scalar& a) const { return a % m_divisor; }
0024 const Scalar m_divisor;
0025 };
0026 template <typename Scalar>
0027 struct functor_traits<scalar_mod_op<Scalar> >
0028 { enum { Cost = scalar_div_cost<Scalar,false>::value, PacketAccess = false }; };
0029
0030
0031
0032
0033
0034 template <typename Scalar>
0035 struct scalar_mod2_op {
0036 EIGEN_EMPTY_STRUCT_CTOR(scalar_mod2_op)
0037 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar operator() (const Scalar& a, const Scalar& b) const { return a % b; }
0038 };
0039 template <typename Scalar>
0040 struct functor_traits<scalar_mod2_op<Scalar> >
0041 { enum { Cost = scalar_div_cost<Scalar,false>::value, PacketAccess = false }; };
0042
0043 template <typename Scalar>
0044 struct scalar_fmod_op {
0045 EIGEN_EMPTY_STRUCT_CTOR(scalar_fmod_op)
0046 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar
0047 operator()(const Scalar& a, const Scalar& b) const {
0048 return numext::fmod(a, b);
0049 }
0050 };
0051 template <typename Scalar>
0052 struct functor_traits<scalar_fmod_op<Scalar> > {
0053 enum { Cost = 13,
0054 PacketAccess = false };
0055 };
0056
0057 template<typename Reducer, typename Device>
0058 struct reducer_traits {
0059 enum {
0060 Cost = 1,
0061 PacketAccess = false,
0062 IsStateful = false,
0063 IsExactlyAssociative = true
0064 };
0065 };
0066
0067
0068 template <typename T> struct SumReducer
0069 {
0070 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void reduce(const T t, T* accum) const {
0071 internal::scalar_sum_op<T> sum_op;
0072 *accum = sum_op(*accum, t);
0073 }
0074 template <typename Packet>
0075 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void reducePacket(const Packet& p, Packet* accum) const {
0076 (*accum) = padd<Packet>(*accum, p);
0077 }
0078
0079 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T initialize() const {
0080 internal::scalar_cast_op<int, T> conv;
0081 return conv(0);
0082 }
0083 template <typename Packet>
0084 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet initializePacket() const {
0085 return pset1<Packet>(initialize());
0086 }
0087 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T finalize(const T accum) const {
0088 return accum;
0089 }
0090 template <typename Packet>
0091 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet finalizePacket(const Packet& vaccum) const {
0092 return vaccum;
0093 }
0094 template <typename Packet>
0095 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T finalizeBoth(const T saccum, const Packet& vaccum) const {
0096 internal::scalar_sum_op<T> sum_op;
0097 return sum_op(saccum, predux(vaccum));
0098 }
0099 };
0100
0101 template <typename T, typename Device>
0102 struct reducer_traits<SumReducer<T>, Device> {
0103 enum {
0104 Cost = NumTraits<T>::AddCost,
0105 PacketAccess = PacketType<T, Device>::HasAdd,
0106 IsStateful = false,
0107 IsExactlyAssociative = NumTraits<T>::IsInteger
0108 };
0109 };
0110
0111 template <typename T> struct MeanReducer
0112 {
0113 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
0114 MeanReducer() : scalarCount_(0), packetCount_(0) { }
0115
0116 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void reduce(const T t, T* accum) {
0117 internal::scalar_sum_op<T> sum_op;
0118 *accum = sum_op(*accum, t);
0119 scalarCount_++;
0120 }
0121 template <typename Packet>
0122 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void reducePacket(const Packet& p, Packet* accum) {
0123 (*accum) = padd<Packet>(*accum, p);
0124 packetCount_++;
0125 }
0126
0127 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T initialize() const {
0128 internal::scalar_cast_op<int, T> conv;
0129 return conv(0);
0130 }
0131 template <typename Packet>
0132 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet initializePacket() const {
0133 return pset1<Packet>(initialize());
0134 }
0135 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T finalize(const T accum) const {
0136 internal::scalar_quotient_op<T> quotient_op;
0137 return quotient_op(accum, T(scalarCount_));
0138 }
0139 template <typename Packet>
0140 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet finalizePacket(const Packet& vaccum) const {
0141 return pdiv(vaccum, pset1<Packet>(T(packetCount_)));
0142 }
0143 template <typename Packet>
0144 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T finalizeBoth(const T saccum, const Packet& vaccum) const {
0145 internal::scalar_sum_op<T> sum_op;
0146 internal::scalar_quotient_op<T> quotient_op;
0147 return quotient_op(
0148 sum_op(saccum, predux(vaccum)),
0149 T(scalarCount_ + packetCount_ * unpacket_traits<Packet>::size));
0150 }
0151
0152 protected:
0153 DenseIndex scalarCount_;
0154 DenseIndex packetCount_;
0155 };
0156
0157 template <typename T, typename Device>
0158 struct reducer_traits<MeanReducer<T>, Device> {
0159 enum {
0160 Cost = NumTraits<T>::AddCost,
0161 PacketAccess = PacketType<T, Device>::HasAdd &&
0162 PacketType<T, Device>::HasDiv && !NumTraits<T>::IsInteger,
0163 IsStateful = true,
0164 IsExactlyAssociative = NumTraits<T>::IsInteger
0165 };
0166 };
0167
0168
0169 template <typename T, bool IsMax = true, bool IsInteger = true>
0170 struct MinMaxBottomValue {
0171 EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE T bottom_value() {
0172 return Eigen::NumTraits<T>::lowest();
0173 }
0174 };
0175 template <typename T>
0176 struct MinMaxBottomValue<T, true, false> {
0177 EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE T bottom_value() {
0178 return -Eigen::NumTraits<T>::infinity();
0179 }
0180 };
0181 template <typename T>
0182 struct MinMaxBottomValue<T, false, true> {
0183 EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE T bottom_value() {
0184 return Eigen::NumTraits<T>::highest();
0185 }
0186 };
0187 template <typename T>
0188 struct MinMaxBottomValue<T, false, false> {
0189 EIGEN_DEVICE_FUNC static EIGEN_STRONG_INLINE T bottom_value() {
0190 return Eigen::NumTraits<T>::infinity();
0191 }
0192 };
0193
0194
0195 template <typename T, int NaNPropagation=PropagateFast> struct MaxReducer
0196 {
0197 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void reduce(const T t, T* accum) const {
0198 scalar_max_op<T, T, NaNPropagation> op;
0199 *accum = op(t, *accum);
0200 }
0201 template <typename Packet>
0202 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void reducePacket(const Packet& p, Packet* accum) const {
0203 scalar_max_op<T, T, NaNPropagation> op;
0204 (*accum) = op.packetOp(*accum, p);
0205 }
0206 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T initialize() const {
0207 return MinMaxBottomValue<T, true, Eigen::NumTraits<T>::IsInteger>::bottom_value();
0208 }
0209 template <typename Packet>
0210 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet initializePacket() const {
0211 return pset1<Packet>(initialize());
0212 }
0213 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T finalize(const T accum) const {
0214 return accum;
0215 }
0216 template <typename Packet>
0217 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet finalizePacket(const Packet& vaccum) const {
0218 return vaccum;
0219 }
0220 template <typename Packet>
0221 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T finalizeBoth(const T saccum, const Packet& vaccum) const {
0222 scalar_max_op<T, T, NaNPropagation> op;
0223 return op(saccum, op.predux(vaccum));
0224 }
0225 };
0226
0227 template <typename T, typename Device, int NaNPropagation>
0228 struct reducer_traits<MaxReducer<T, NaNPropagation>, Device> {
0229 enum {
0230 Cost = NumTraits<T>::AddCost,
0231 PacketAccess = PacketType<T, Device>::HasMax,
0232 IsStateful = false,
0233 IsExactlyAssociative = (NaNPropagation!=PropagateFast)
0234 };
0235 };
0236
0237 template <typename T, int NaNPropagation=PropagateFast> struct MinReducer
0238 {
0239 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void reduce(const T t, T* accum) const {
0240 scalar_min_op<T, T, NaNPropagation> op;
0241 *accum = op(t, *accum);
0242 }
0243 template <typename Packet>
0244 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void reducePacket(const Packet& p, Packet* accum) const {
0245 scalar_min_op<T, T, NaNPropagation> op;
0246 (*accum) = op.packetOp(*accum, p);
0247 }
0248 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T initialize() const {
0249 return MinMaxBottomValue<T, false, Eigen::NumTraits<T>::IsInteger>::bottom_value();
0250 }
0251 template <typename Packet>
0252 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet initializePacket() const {
0253 return pset1<Packet>(initialize());
0254 }
0255 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T finalize(const T accum) const {
0256 return accum;
0257 }
0258 template <typename Packet>
0259 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet finalizePacket(const Packet& vaccum) const {
0260 return vaccum;
0261 }
0262 template <typename Packet>
0263 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T finalizeBoth(const T saccum, const Packet& vaccum) const {
0264 scalar_min_op<T, T, NaNPropagation> op;
0265 return op(saccum, op.predux(vaccum));
0266 }
0267 };
0268
0269 template <typename T, typename Device, int NaNPropagation>
0270 struct reducer_traits<MinReducer<T, NaNPropagation>, Device> {
0271 enum {
0272 Cost = NumTraits<T>::AddCost,
0273 PacketAccess = PacketType<T, Device>::HasMin,
0274 IsStateful = false,
0275 IsExactlyAssociative = (NaNPropagation!=PropagateFast)
0276 };
0277 };
0278
0279 template <typename T> struct ProdReducer
0280 {
0281 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void reduce(const T t, T* accum) const {
0282 internal::scalar_product_op<T> prod_op;
0283 (*accum) = prod_op(*accum, t);
0284 }
0285 template <typename Packet>
0286 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void reducePacket(const Packet& p, Packet* accum) const {
0287 (*accum) = pmul<Packet>(*accum, p);
0288 }
0289 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T initialize() const {
0290 internal::scalar_cast_op<int, T> conv;
0291 return conv(1);
0292 }
0293 template <typename Packet>
0294 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet initializePacket() const {
0295 return pset1<Packet>(initialize());
0296 }
0297 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T finalize(const T accum) const {
0298 return accum;
0299 }
0300 template <typename Packet>
0301 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet finalizePacket(const Packet& vaccum) const {
0302 return vaccum;
0303 }
0304 template <typename Packet>
0305 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T finalizeBoth(const T saccum, const Packet& vaccum) const {
0306 internal::scalar_product_op<T> prod_op;
0307 return prod_op(saccum, predux_mul(vaccum));
0308 }
0309 };
0310
0311 template <typename T, typename Device>
0312 struct reducer_traits<ProdReducer<T>, Device> {
0313 enum {
0314 Cost = NumTraits<T>::MulCost,
0315 PacketAccess = PacketType<T, Device>::HasMul,
0316 IsStateful = false,
0317 IsExactlyAssociative = true
0318 };
0319 };
0320
0321
0322 struct AndReducer
0323 {
0324 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void reduce(bool t, bool* accum) const {
0325 *accum = *accum && t;
0326 }
0327 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool initialize() const {
0328 return true;
0329 }
0330 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool finalize(bool accum) const {
0331 return accum;
0332 }
0333 };
0334
0335 template <typename Device>
0336 struct reducer_traits<AndReducer, Device> {
0337 enum {
0338 Cost = 1,
0339 PacketAccess = false,
0340 IsStateful = false,
0341 IsExactlyAssociative = true
0342 };
0343 };
0344
0345
0346 struct OrReducer {
0347 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void reduce(bool t, bool* accum) const {
0348 *accum = *accum || t;
0349 }
0350 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool initialize() const {
0351 return false;
0352 }
0353 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool finalize(bool accum) const {
0354 return accum;
0355 }
0356 };
0357
0358 template <typename Device>
0359 struct reducer_traits<OrReducer, Device> {
0360 enum {
0361 Cost = 1,
0362 PacketAccess = false,
0363 IsStateful = false,
0364 IsExactlyAssociative = true
0365 };
0366 };
0367
0368
0369
0370 template <typename T> struct ArgMaxTupleReducer
0371 {
0372 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void reduce(const T t, T* accum) const {
0373 if (t.second < accum->second) {
0374 return;
0375 } else if (t.second > accum->second || accum->first > t.first ) {
0376 *accum = t;
0377 }
0378 }
0379 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T initialize() const {
0380 return T(0, NumTraits<typename T::second_type>::lowest());
0381 }
0382 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T finalize(const T& accum) const {
0383 return accum;
0384 }
0385 };
0386
0387 template <typename T, typename Device>
0388 struct reducer_traits<ArgMaxTupleReducer<T>, Device> {
0389 enum {
0390 Cost = NumTraits<T>::AddCost,
0391 PacketAccess = false,
0392 IsStateful = false,
0393 IsExactlyAssociative = true
0394 };
0395 };
0396
0397
0398 template <typename T> struct ArgMinTupleReducer
0399 {
0400 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void reduce(const T& t, T* accum) const {
0401 if (t.second > accum->second) {
0402 return;
0403 } else if (t.second < accum->second || accum->first > t.first) {
0404 *accum = t;
0405 }
0406 }
0407 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T initialize() const {
0408 return T(0, NumTraits<typename T::second_type>::highest());
0409 }
0410 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T finalize(const T& accum) const {
0411 return accum;
0412 }
0413 };
0414
0415 template <typename T, typename Device>
0416 struct reducer_traits<ArgMinTupleReducer<T>, Device> {
0417 enum {
0418 Cost = NumTraits<T>::AddCost,
0419 PacketAccess = false,
0420 IsStateful = false,
0421 IsExactlyAssociative = true
0422 };
0423 };
0424
0425
0426 template <typename T, typename Index, size_t NumDims>
0427 class GaussianGenerator {
0428 public:
0429 static const bool PacketAccess = false;
0430
0431 EIGEN_DEVICE_FUNC GaussianGenerator(const array<T, NumDims>& means,
0432 const array<T, NumDims>& std_devs)
0433 : m_means(means)
0434 {
0435 EIGEN_UNROLL_LOOP
0436 for (size_t i = 0; i < NumDims; ++i) {
0437 m_two_sigmas[i] = std_devs[i] * std_devs[i] * 2;
0438 }
0439 }
0440
0441 EIGEN_DEVICE_FUNC T operator()(const array<Index, NumDims>& coordinates) const {
0442 T tmp = T(0);
0443 EIGEN_UNROLL_LOOP
0444 for (size_t i = 0; i < NumDims; ++i) {
0445 T offset = coordinates[i] - m_means[i];
0446 tmp += offset * offset / m_two_sigmas[i];
0447 }
0448 return numext::exp(-tmp);
0449 }
0450
0451 private:
0452 array<T, NumDims> m_means;
0453 array<T, NumDims> m_two_sigmas;
0454 };
0455
0456 template <typename T, typename Index, size_t NumDims>
0457 struct functor_traits<GaussianGenerator<T, Index, NumDims> > {
0458 enum {
0459 Cost = NumDims * (2 * NumTraits<T>::AddCost + NumTraits<T>::MulCost +
0460 functor_traits<scalar_quotient_op<T, T> >::Cost) +
0461 functor_traits<scalar_exp_op<T> >::Cost,
0462 PacketAccess = GaussianGenerator<T, Index, NumDims>::PacketAccess
0463 };
0464 };
0465
0466 template <typename Scalar>
0467 struct scalar_clamp_op {
0468 EIGEN_DEVICE_FUNC inline scalar_clamp_op(const Scalar& _min, const Scalar& _max) : m_min(_min), m_max(_max) {}
0469 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar
0470 operator()(const Scalar& x) const {
0471 return numext::mini(numext::maxi(x, m_min), m_max);
0472 }
0473 template <typename Packet>
0474 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet
0475 packetOp(const Packet& x) const {
0476 return internal::pmin(internal::pmax(x, pset1<Packet>(m_min)), pset1<Packet>(m_max));
0477 }
0478 const Scalar m_min;
0479 const Scalar m_max;
0480 };
0481 template<typename Scalar>
0482 struct functor_traits<scalar_clamp_op<Scalar> >
0483 { enum { Cost = 2 * NumTraits<Scalar>::AddCost, PacketAccess = (packet_traits<Scalar>::HasMin && packet_traits<Scalar>::HasMax)}; };
0484
0485 }
0486 }
0487
0488 #endif