10 #ifndef EIGEN_CXX11_TENSOR_TENSOR_FUNCTORS_H 11 #define EIGEN_CXX11_TENSOR_TENSOR_FUNCTORS_H 20 template <
typename Scalar>
21 struct scalar_mod_op {
22 EIGEN_DEVICE_FUNC scalar_mod_op(
const Scalar& divisor) : m_divisor(divisor) {}
23 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar operator() (
const Scalar& a)
const {
return a % m_divisor; }
24 const Scalar m_divisor;
26 template <
typename Scalar>
27 struct functor_traits<scalar_mod_op<Scalar> >
28 {
enum { Cost = scalar_div_cost<Scalar,false>::value, PacketAccess =
false }; };
34 template <
typename Scalar>
35 struct scalar_mod2_op {
36 EIGEN_EMPTY_STRUCT_CTOR(scalar_mod2_op)
37 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar operator() (
const Scalar& a,
const Scalar& b)
const {
return a % b; }
39 template <
typename Scalar>
40 struct functor_traits<scalar_mod2_op<Scalar> >
41 {
enum { Cost = scalar_div_cost<Scalar,false>::value, PacketAccess =
false }; };
43 template <
typename Scalar>
44 struct scalar_fmod_op {
45 EIGEN_EMPTY_STRUCT_CTOR(scalar_fmod_op)
46 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar
47 operator()(
const Scalar& a,
const Scalar& b)
const {
48 return numext::fmod(a, b);
51 template <
typename Scalar>
52 struct functor_traits<scalar_fmod_op<Scalar> > {
54 PacketAccess =
false };
57 template<
typename Reducer,
typename Device>
58 struct reducer_traits {
63 IsExactlyAssociative =
true 68 template <
typename T>
struct SumReducer
70 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void reduce(
const T t, T* accum)
const {
71 internal::scalar_sum_op<T> sum_op;
72 *accum = sum_op(*accum, t);
74 template <
typename Packet>
75 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void reducePacket(
const Packet& p, Packet* accum)
const {
76 (*accum) = padd<Packet>(*accum, p);
79 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T initialize()
const {
80 internal::scalar_cast_op<int, T> conv;
83 template <
typename Packet>
84 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet initializePacket()
const {
85 return pset1<Packet>(initialize());
87 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T finalize(
const T accum)
const {
90 template <
typename Packet>
91 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet finalizePacket(
const Packet& vaccum)
const {
94 template <
typename Packet>
95 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T finalizeBoth(
const T saccum,
const Packet& vaccum)
const {
96 internal::scalar_sum_op<T> sum_op;
97 return sum_op(saccum, predux(vaccum));
101 template <
typename T,
typename Device>
102 struct reducer_traits<SumReducer<T>, Device> {
104 Cost = NumTraits<T>::AddCost,
105 PacketAccess = PacketType<T, Device>::HasAdd,
107 IsExactlyAssociative = NumTraits<T>::IsInteger
111 template <
typename T>
struct MeanReducer
113 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
114 MeanReducer() : scalarCount_(0), packetCount_(0) { }
116 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void reduce(
const T t, T* accum) {
117 internal::scalar_sum_op<T> sum_op;
118 *accum = sum_op(*accum, t);
121 template <
typename Packet>
122 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void reducePacket(
const Packet& p, Packet* accum) {
123 (*accum) = padd<Packet>(*accum, p);
127 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T initialize()
const {
128 internal::scalar_cast_op<int, T> conv;
131 template <
typename Packet>
132 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet initializePacket()
const {
133 return pset1<Packet>(initialize());
135 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T finalize(
const T accum)
const {
136 internal::scalar_quotient_op<T> quotient_op;
137 return quotient_op(accum, T(scalarCount_));
139 template <
typename Packet>
140 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet finalizePacket(
const Packet& vaccum)
const {
141 return pdiv(vaccum, pset1<Packet>(T(packetCount_)));
143 template <
typename Packet>
144 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T finalizeBoth(
const T saccum,
const Packet& vaccum)
const {
145 internal::scalar_sum_op<T> sum_op;
146 internal::scalar_quotient_op<T> quotient_op;
148 sum_op(saccum, predux(vaccum)),
149 T(scalarCount_ + packetCount_ * unpacket_traits<Packet>::size));
153 DenseIndex scalarCount_;
154 DenseIndex packetCount_;
157 template <
typename T,
typename Device>
158 struct reducer_traits<MeanReducer<T>, Device> {
160 Cost = NumTraits<T>::AddCost,
161 PacketAccess = PacketType<T, Device>::HasAdd &&
162 PacketType<T, Device>::HasDiv && !NumTraits<T>::IsInteger,
164 IsExactlyAssociative = NumTraits<T>::IsInteger
169 template <
typename T,
bool IsMax = true,
bool IsInteger = true>
170 struct MinMaxBottomValue {
171 EIGEN_DEVICE_FUNC
static EIGEN_STRONG_INLINE T bottom_value() {
175 template <
typename T>
176 struct MinMaxBottomValue<T, true, false> {
177 EIGEN_DEVICE_FUNC
static EIGEN_STRONG_INLINE T bottom_value() {
181 template <
typename T>
182 struct MinMaxBottomValue<T, false, true> {
183 EIGEN_DEVICE_FUNC
static EIGEN_STRONG_INLINE T bottom_value() {
187 template <
typename T>
188 struct MinMaxBottomValue<T, false, false> {
189 EIGEN_DEVICE_FUNC
static EIGEN_STRONG_INLINE T bottom_value() {
195 template <
typename T,
int NaNPropagation=PropagateFast>
struct MaxReducer
197 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void reduce(
const T t, T* accum)
const {
198 scalar_max_op<T, T, NaNPropagation> op;
199 *accum = op(t, *accum);
201 template <
typename Packet>
202 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void reducePacket(
const Packet& p, Packet* accum)
const {
203 scalar_max_op<T, T, NaNPropagation> op;
204 (*accum) = op.packetOp(*accum, p);
206 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T initialize()
const {
209 template <
typename Packet>
210 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet initializePacket()
const {
211 return pset1<Packet>(initialize());
213 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T finalize(
const T accum)
const {
216 template <
typename Packet>
217 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet finalizePacket(
const Packet& vaccum)
const {
220 template <
typename Packet>
221 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T finalizeBoth(
const T saccum,
const Packet& vaccum)
const {
222 scalar_max_op<T, T, NaNPropagation> op;
223 return op(saccum, op.predux(vaccum));
227 template <
typename T,
typename Device,
int NaNPropagation>
228 struct reducer_traits<MaxReducer<T, NaNPropagation>, Device> {
230 Cost = NumTraits<T>::AddCost,
231 PacketAccess = PacketType<T, Device>::HasMax,
237 template <
typename T,
int NaNPropagation=PropagateFast>
struct MinReducer
239 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void reduce(
const T t, T* accum)
const {
240 scalar_min_op<T, T, NaNPropagation> op;
241 *accum = op(t, *accum);
243 template <
typename Packet>
244 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void reducePacket(
const Packet& p, Packet* accum)
const {
245 scalar_min_op<T, T, NaNPropagation> op;
246 (*accum) = op.packetOp(*accum, p);
248 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T initialize()
const {
251 template <
typename Packet>
252 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet initializePacket()
const {
253 return pset1<Packet>(initialize());
255 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T finalize(
const T accum)
const {
258 template <
typename Packet>
259 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet finalizePacket(
const Packet& vaccum)
const {
262 template <
typename Packet>
263 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T finalizeBoth(
const T saccum,
const Packet& vaccum)
const {
264 scalar_min_op<T, T, NaNPropagation> op;
265 return op(saccum, op.predux(vaccum));
269 template <
typename T,
typename Device,
int NaNPropagation>
270 struct reducer_traits<MinReducer<T, NaNPropagation>, Device> {
272 Cost = NumTraits<T>::AddCost,
273 PacketAccess = PacketType<T, Device>::HasMin,
279 template <
typename T>
struct ProdReducer
281 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void reduce(
const T t, T* accum)
const {
282 internal::scalar_product_op<T> prod_op;
283 (*accum) = prod_op(*accum, t);
285 template <
typename Packet>
286 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void reducePacket(
const Packet& p, Packet* accum)
const {
287 (*accum) = pmul<Packet>(*accum, p);
289 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T initialize()
const {
290 internal::scalar_cast_op<int, T> conv;
293 template <
typename Packet>
294 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet initializePacket()
const {
295 return pset1<Packet>(initialize());
297 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T finalize(
const T accum)
const {
300 template <
typename Packet>
301 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet finalizePacket(
const Packet& vaccum)
const {
304 template <
typename Packet>
305 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T finalizeBoth(
const T saccum,
const Packet& vaccum)
const {
306 internal::scalar_product_op<T> prod_op;
307 return prod_op(saccum, predux_mul(vaccum));
311 template <
typename T,
typename Device>
312 struct reducer_traits<ProdReducer<T>, Device> {
314 Cost = NumTraits<T>::MulCost,
315 PacketAccess = PacketType<T, Device>::HasMul,
317 IsExactlyAssociative =
true 324 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void reduce(
bool t,
bool* accum)
const {
325 *accum = *accum && t;
327 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
bool initialize()
const {
330 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
bool finalize(
bool accum)
const {
335 template <
typename Device>
336 struct reducer_traits<AndReducer, Device> {
339 PacketAccess =
false,
341 IsExactlyAssociative =
true 347 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void reduce(
bool t,
bool* accum)
const {
348 *accum = *accum || t;
350 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
bool initialize()
const {
353 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
bool finalize(
bool accum)
const {
358 template <
typename Device>
359 struct reducer_traits<OrReducer, Device> {
362 PacketAccess =
false,
364 IsExactlyAssociative =
true 370 template <
typename T>
struct ArgMaxTupleReducer
372 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void reduce(
const T t, T* accum)
const {
373 if (t.second < accum->second) {
375 }
else if (t.second > accum->second || accum->first > t.first ) {
379 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T initialize()
const {
380 return T(0, NumTraits<typename T::second_type>::lowest());
382 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T finalize(
const T& accum)
const {
387 template <
typename T,
typename Device>
388 struct reducer_traits<ArgMaxTupleReducer<T>, Device> {
390 Cost = NumTraits<T>::AddCost,
391 PacketAccess =
false,
393 IsExactlyAssociative =
true 398 template <
typename T>
struct ArgMinTupleReducer
400 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void reduce(
const T& t, T* accum)
const {
401 if (t.second > accum->second) {
403 }
else if (t.second < accum->second || accum->first > t.first) {
407 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T initialize()
const {
408 return T(0, NumTraits<typename T::second_type>::highest());
410 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T finalize(
const T& accum)
const {
415 template <
typename T,
typename Device>
416 struct reducer_traits<ArgMinTupleReducer<T>, Device> {
418 Cost = NumTraits<T>::AddCost,
419 PacketAccess =
false,
421 IsExactlyAssociative =
true 426 template <
typename T,
typename Index,
size_t NumDims>
427 class GaussianGenerator {
429 static const bool PacketAccess =
false;
431 EIGEN_DEVICE_FUNC GaussianGenerator(
const array<T, NumDims>& means,
432 const array<T, NumDims>& std_devs)
436 for (
size_t i = 0; i < NumDims; ++i) {
437 m_two_sigmas[i] = std_devs[i] * std_devs[i] * 2;
441 EIGEN_DEVICE_FUNC T operator()(
const array<Index, NumDims>& coordinates)
const {
444 for (
size_t i = 0; i < NumDims; ++i) {
445 T offset = coordinates[i] - m_means[i];
446 tmp += offset * offset / m_two_sigmas[i];
448 return numext::exp(-tmp);
452 array<T, NumDims> m_means;
453 array<T, NumDims> m_two_sigmas;
456 template <
typename T,
typename Index,
size_t NumDims>
457 struct functor_traits<GaussianGenerator<T,
Index, NumDims> > {
459 Cost = NumDims * (2 * NumTraits<T>::AddCost + NumTraits<T>::MulCost +
460 functor_traits<scalar_quotient_op<T, T> >::Cost) +
461 functor_traits<scalar_exp_op<T> >::Cost,
462 PacketAccess = GaussianGenerator<T, Index, NumDims>::PacketAccess
466 template <
typename Scalar>
467 struct scalar_clamp_op {
468 EIGEN_DEVICE_FUNC
inline scalar_clamp_op(
const Scalar& _min,
const Scalar& _max) : m_min(_min), m_max(_max) {}
469 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const Scalar
470 operator()(
const Scalar& x)
const {
471 return numext::mini(numext::maxi(x, m_min), m_max);
473 template <
typename Packet>
474 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const Packet
475 packetOp(
const Packet& x)
const {
476 return internal::pmin(internal::pmax(x, pset1<Packet>(m_min)), pset1<Packet>(m_max));
481 template<
typename Scalar>
482 struct functor_traits<scalar_clamp_op<Scalar> >
483 {
enum { Cost = 2 * NumTraits<Scalar>::AddCost, PacketAccess = (packet_traits<Scalar>::HasMin && packet_traits<Scalar>::HasMax)}; };
488 #endif // EIGEN_CXX11_TENSOR_TENSOR_FUNCTORS_H
Namespace containing all symbols from the Eigen library.
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index