BinaryFunctors.h
Go to the documentation of this file.
1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra.
3 //
4 // Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
5 //
6 // This Source Code Form is subject to the terms of the Mozilla
7 // Public License v. 2.0. If a copy of the MPL was not distributed
8 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 
10 #ifndef EIGEN_BINARY_FUNCTORS_H
11 #define EIGEN_BINARY_FUNCTORS_H
12 
13 namespace Eigen {
14 
15 namespace internal {
16 
17 //---------- associative binary functors ----------
18 
19 template<typename Arg1, typename Arg2>
21 {
22  typedef Arg1 first_argument_type;
23  typedef Arg2 second_argument_type;
24 };
25 
31 template<typename LhsScalar,typename RhsScalar>
32 struct scalar_sum_op : binary_op_base<LhsScalar,RhsScalar>
33 {
35 #ifndef EIGEN_SCALAR_BINARY_OP_PLUGIN
37 #else
38  scalar_sum_op() {
39  EIGEN_SCALAR_BINARY_OP_PLUGIN
40  }
41 #endif
42  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const { return a + b; }
43  template<typename Packet>
44  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
45  { return internal::padd(a,b); }
46  template<typename Packet>
47  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type predux(const Packet& a) const
48  { return internal::predux(a); }
49 };
50 template<typename LhsScalar,typename RhsScalar>
51 struct functor_traits<scalar_sum_op<LhsScalar,RhsScalar> > {
52  enum {
55  // TODO vectorize mixed sum
56  };
57 };
58 
64 template<> struct scalar_sum_op<bool,bool> : scalar_sum_op<int,int> {
67 };
68 
69 
75 template<typename LhsScalar,typename RhsScalar>
76 struct scalar_product_op : binary_op_base<LhsScalar,RhsScalar>
77 {
79 #ifndef EIGEN_SCALAR_BINARY_OP_PLUGIN
81 #else
83  EIGEN_SCALAR_BINARY_OP_PLUGIN
84  }
85 #endif
86  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const { return a * b; }
87  template<typename Packet>
88  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
89  { return internal::pmul(a,b); }
90  template<typename Packet>
91  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type predux(const Packet& a) const
92  { return internal::predux_mul(a); }
93 };
94 template<typename LhsScalar,typename RhsScalar>
95 struct functor_traits<scalar_product_op<LhsScalar,RhsScalar> > {
96  enum {
99  // TODO vectorize mixed product
100  };
101 };
102 
108 template<typename LhsScalar,typename RhsScalar>
109 struct scalar_conj_product_op : binary_op_base<LhsScalar,RhsScalar>
110 {
111 
112  enum {
114  };
115 
117 
119  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const
121 
122  template<typename Packet>
123  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
125 };
126 template<typename LhsScalar,typename RhsScalar>
127 struct functor_traits<scalar_conj_product_op<LhsScalar,RhsScalar> > {
128  enum {
131  };
132 };
133 
139 template<typename LhsScalar,typename RhsScalar>
140 struct scalar_min_op : binary_op_base<LhsScalar,RhsScalar>
141 {
144  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const { return numext::mini(a, b); }
145  template<typename Packet>
146  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
147  { return internal::pmin(a,b); }
148  template<typename Packet>
149  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type predux(const Packet& a) const
150  { return internal::predux_min(a); }
151 };
152 template<typename LhsScalar,typename RhsScalar>
153 struct functor_traits<scalar_min_op<LhsScalar,RhsScalar> > {
154  enum {
157  };
158 };
159 
165 template<typename LhsScalar,typename RhsScalar>
166 struct scalar_max_op : binary_op_base<LhsScalar,RhsScalar>
167 {
170  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const { return numext::maxi(a, b); }
171  template<typename Packet>
172  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
173  { return internal::pmax(a,b); }
174  template<typename Packet>
175  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type predux(const Packet& a) const
176  { return internal::predux_max(a); }
177 };
178 template<typename LhsScalar,typename RhsScalar>
179 struct functor_traits<scalar_max_op<LhsScalar,RhsScalar> > {
180  enum {
183  };
184 };
185 
190 template<typename LhsScalar, typename RhsScalar, ComparisonName cmp> struct scalar_cmp_op;
191 
192 template<typename LhsScalar, typename RhsScalar, ComparisonName cmp>
193 struct functor_traits<scalar_cmp_op<LhsScalar,RhsScalar, cmp> > {
194  enum {
196  PacketAccess = false
197  };
198 };
199 
200 template<ComparisonName Cmp, typename LhsScalar, typename RhsScalar>
201 struct result_of<scalar_cmp_op<LhsScalar, RhsScalar, Cmp>(LhsScalar,RhsScalar)> {
202  typedef bool type;
203 };
204 
205 
206 template<typename LhsScalar, typename RhsScalar>
207 struct scalar_cmp_op<LhsScalar,RhsScalar, cmp_EQ> : binary_op_base<LhsScalar,RhsScalar>
208 {
209  typedef bool result_type;
211  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool operator()(const LhsScalar& a, const RhsScalar& b) const {return a==b;}
212 };
213 template<typename LhsScalar, typename RhsScalar>
214 struct scalar_cmp_op<LhsScalar,RhsScalar, cmp_LT> : binary_op_base<LhsScalar,RhsScalar>
215 {
216  typedef bool result_type;
218  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool operator()(const LhsScalar& a, const RhsScalar& b) const {return a<b;}
219 };
220 template<typename LhsScalar, typename RhsScalar>
221 struct scalar_cmp_op<LhsScalar,RhsScalar, cmp_LE> : binary_op_base<LhsScalar,RhsScalar>
222 {
223  typedef bool result_type;
225  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool operator()(const LhsScalar& a, const RhsScalar& b) const {return a<=b;}
226 };
227 template<typename LhsScalar, typename RhsScalar>
228 struct scalar_cmp_op<LhsScalar,RhsScalar, cmp_GT> : binary_op_base<LhsScalar,RhsScalar>
229 {
230  typedef bool result_type;
232  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool operator()(const LhsScalar& a, const RhsScalar& b) const {return a>b;}
233 };
234 template<typename LhsScalar, typename RhsScalar>
235 struct scalar_cmp_op<LhsScalar,RhsScalar, cmp_GE> : binary_op_base<LhsScalar,RhsScalar>
236 {
237  typedef bool result_type;
239  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool operator()(const LhsScalar& a, const RhsScalar& b) const {return a>=b;}
240 };
241 template<typename LhsScalar, typename RhsScalar>
242 struct scalar_cmp_op<LhsScalar,RhsScalar, cmp_UNORD> : binary_op_base<LhsScalar,RhsScalar>
243 {
244  typedef bool result_type;
246  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool operator()(const LhsScalar& a, const RhsScalar& b) const {return !(a<=b || b<=a);}
247 };
248 template<typename LhsScalar, typename RhsScalar>
249 struct scalar_cmp_op<LhsScalar,RhsScalar, cmp_NEQ> : binary_op_base<LhsScalar,RhsScalar>
250 {
251  typedef bool result_type;
253  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool operator()(const LhsScalar& a, const RhsScalar& b) const {return a!=b;}
254 };
255 
256 
262 template<typename Scalar>
263 struct scalar_hypot_op<Scalar,Scalar> : binary_op_base<Scalar,Scalar>
264 {
266 // typedef typename NumTraits<Scalar>::Real result_type;
267  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& _x, const Scalar& _y) const
268  {
269  EIGEN_USING_STD_MATH(sqrt)
270  Scalar p, qp;
271  if(_x>_y)
272  {
273  p = _x;
274  qp = _y / p;
275  }
276  else
277  {
278  p = _y;
279  qp = _x / p;
280  }
281  return p * sqrt(Scalar(1) + qp*qp);
282  }
283 };
284 template<typename Scalar>
285 struct functor_traits<scalar_hypot_op<Scalar,Scalar> > {
286  enum
287  {
291  PacketAccess = false
292  };
293 };
294 
298 template<typename Scalar, typename Exponent>
299 struct scalar_pow_op : binary_op_base<Scalar,Exponent>
300 {
302 #ifndef EIGEN_SCALAR_BINARY_OP_PLUGIN
304 #else
305  scalar_pow_op() {
306  typedef Scalar LhsScalar;
307  typedef Exponent RhsScalar;
308  EIGEN_SCALAR_BINARY_OP_PLUGIN
309  }
310 #endif
311  EIGEN_DEVICE_FUNC
312  inline result_type operator() (const Scalar& a, const Exponent& b) const { return numext::pow(a, b); }
313 };
314 template<typename Scalar, typename Exponent>
315 struct functor_traits<scalar_pow_op<Scalar,Exponent> > {
316  enum { Cost = 5 * NumTraits<Scalar>::MulCost, PacketAccess = false };
317 };
318 
319 
320 
321 //---------- non associative binary functors ----------
322 
328 template<typename LhsScalar,typename RhsScalar>
329 struct scalar_difference_op : binary_op_base<LhsScalar,RhsScalar>
330 {
332 #ifndef EIGEN_SCALAR_BINARY_OP_PLUGIN
334 #else
336  EIGEN_SCALAR_BINARY_OP_PLUGIN
337  }
338 #endif
339  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const { return a - b; }
340  template<typename Packet>
341  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
342  { return internal::psub(a,b); }
343 };
344 template<typename LhsScalar,typename RhsScalar>
345 struct functor_traits<scalar_difference_op<LhsScalar,RhsScalar> > {
346  enum {
349  };
350 };
351 
357 template<typename LhsScalar,typename RhsScalar>
358 struct scalar_quotient_op : binary_op_base<LhsScalar,RhsScalar>
359 {
361 #ifndef EIGEN_SCALAR_BINARY_OP_PLUGIN
363 #else
365  EIGEN_SCALAR_BINARY_OP_PLUGIN
366  }
367 #endif
368  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const { return a / b; }
369  template<typename Packet>
370  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
371  { return internal::pdiv(a,b); }
372 };
373 template<typename LhsScalar,typename RhsScalar>
374 struct functor_traits<scalar_quotient_op<LhsScalar,RhsScalar> > {
376  enum {
379  };
380 };
381 
382 
383 
391  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool operator() (const bool& a, const bool& b) const { return a && b; }
392 };
394  enum {
396  PacketAccess = false
397  };
398 };
399 
407  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool operator() (const bool& a, const bool& b) const { return a || b; }
408 };
410  enum {
412  PacketAccess = false
413  };
414 };
415 
423  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool operator() (const bool& a, const bool& b) const { return a ^ b; }
424 };
426  enum {
428  PacketAccess = false
429  };
430 };
431 
432 
433 
434 //---------- binary functors bound to a constant, thus appearing as a unary functor ----------
435 
436 // The following two classes permits to turn any binary functor into a unary one with one argument bound to a constant value.
437 // They are analogues to std::binder1st/binder2nd but with the following differences:
438 // - they are compatible with packetOp
439 // - they are portable across C++ versions (the std::binder* are deprecated in C++11)
440 template<typename BinaryOp> struct bind1st_op : BinaryOp {
441 
442  typedef typename BinaryOp::first_argument_type first_argument_type;
443  typedef typename BinaryOp::second_argument_type second_argument_type;
444  typedef typename BinaryOp::result_type result_type;
445 
446  bind1st_op(const first_argument_type &val) : m_value(val) {}
447 
448  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const second_argument_type& b) const { return BinaryOp::operator()(m_value,b); }
449 
450  template<typename Packet>
451  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& b) const
452  { return BinaryOp::packetOp(internal::pset1<Packet>(m_value), b); }
453 
454  first_argument_type m_value;
455 };
456 template<typename BinaryOp> struct functor_traits<bind1st_op<BinaryOp> > : functor_traits<BinaryOp> {};
457 
458 
459 template<typename BinaryOp> struct bind2nd_op : BinaryOp {
460 
461  typedef typename BinaryOp::first_argument_type first_argument_type;
462  typedef typename BinaryOp::second_argument_type second_argument_type;
463  typedef typename BinaryOp::result_type result_type;
464 
465  bind2nd_op(const second_argument_type &val) : m_value(val) {}
466 
467  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const first_argument_type& a) const { return BinaryOp::operator()(a,m_value); }
468 
469  template<typename Packet>
470  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const
471  { return BinaryOp::packetOp(a,internal::pset1<Packet>(m_value)); }
472 
473  second_argument_type m_value;
474 };
475 template<typename BinaryOp> struct functor_traits<bind2nd_op<BinaryOp> > : functor_traits<BinaryOp> {};
476 
477 
478 } // end namespace internal
479 
480 } // end namespace Eigen
481 
482 #endif // EIGEN_BINARY_FUNCTORS_H
ScalarBinaryOpTraits< LhsScalar, RhsScalar, scalar_sum_op >::ReturnType result_type
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type predux(const Packet &a) const
BinaryOp::result_type result_type
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC half pow(const half &a, const half &b)
Definition: Half.h:407
#define EIGEN_STRONG_INLINE
Definition: Macros.h:493
#define EIGEN_EMPTY_STRUCT_CTOR(X)
Definition: XprHelper.h:22
ScalarBinaryOpTraits< LhsScalar, RhsScalar, scalar_min_op >::ReturnType result_type
BinaryOp::first_argument_type first_argument_type
BinaryOp::first_argument_type first_argument_type
scalar_quotient_op< LhsScalar, RhsScalar >::result_type result_type
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet &a, const Packet &b) const
ScalarBinaryOpTraits< LhsScalar, RhsScalar, scalar_max_op >::ReturnType result_type
EIGEN_DEVICE_FUNC unpacket_traits< Packet >::type predux_min(const Packet &a)
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet &a, const Packet &b) const
BinaryOp::second_argument_type second_argument_type
EIGEN_DEVICE_FUNC unpacket_traits< Packet >::type predux_max(const Packet &a)
EIGEN_DEVICE_FUNC const SqrtReturnType sqrt() const
Definition: LDLT.h:16
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet &a, const Packet &b) const
Holds information about the various numeric (i.e. scalar) types allowed by Eigen. ...
Definition: NumTraits.h:150
EIGEN_DEVICE_FUNC unpacket_traits< Packet >::type predux(const Packet &a)
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet &b) const
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet &a, const Packet &b) const
ScalarBinaryOpTraits< Scalar, Exponent, scalar_pow_op >::ReturnType result_type
BinaryOp::result_type result_type
BinaryOp::second_argument_type second_argument_type
EIGEN_DEVICE_FUNC Packet padd(const Packet &a, const Packet &b)
EIGEN_DEVICE_FUNC Packet pmin(const Packet &a, const Packet &b)
ScalarBinaryOpTraits< LhsScalar, RhsScalar, scalar_product_op >::ReturnType result_type
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type predux(const Packet &a) const
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet &a, const Packet &b) const
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet &a, const Packet &b) const
first_argument_type m_value
ScalarBinaryOpTraits< LhsScalar, RhsScalar, scalar_quotient_op >::ReturnType result_type
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type predux(const Packet &a) const
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type predux(const Packet &a) const
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet &a, const Packet &b) const
EIGEN_DEVICE_FUNC Packet pdiv(const Packet &a, const Packet &b)
bind1st_op(const first_argument_type &val)
second_argument_type m_value
ScalarBinaryOpTraits< LhsScalar, RhsScalar, scalar_conj_product_op >::ReturnType result_type
EIGEN_DEVICE_FUNC unpacket_traits< Packet >::type predux_mul(const Packet &a)
#define EIGEN_DEPRECATED
Definition: Macros.h:598
EIGEN_DEVICE_FUNC Packet psub(const Packet &a, const Packet &b)
Determines whether the given binary operation of two numeric types is allowed and what the scalar ret...
Definition: XprHelper.h:766
bind2nd_op(const second_argument_type &val)
ScalarBinaryOpTraits< LhsScalar, RhsScalar, scalar_difference_op >::ReturnType result_type
EIGEN_DEVICE_FUNC const Scalar & b
EIGEN_DEVICE_FUNC Packet pmul(const Packet &a, const Packet &b)
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet &a) const
EIGEN_DEVICE_FUNC Packet pmax(const Packet &a, const Packet &b)


hebiros
Author(s): Xavier Artache , Matthew Tesch
autogenerated on Thu Sep 3 2020 04:08:02