Please, help us to better know about our user community by answering the following short survey: https://forms.gle/wpyrxWi18ox9Z5ae9
Eigen  3.3.9
BinaryFunctors.h
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>
20 struct binary_op_base
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 {
34  typedef typename ScalarBinaryOpTraits<LhsScalar,RhsScalar,scalar_sum_op>::ReturnType result_type;
35 #ifndef EIGEN_SCALAR_BINARY_OP_PLUGIN
36  EIGEN_EMPTY_STRUCT_CTOR(scalar_sum_op)
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 {
53  Cost = (NumTraits<LhsScalar>::AddCost+NumTraits<RhsScalar>::AddCost)/2, // rough estimate!
54  PacketAccess = is_same<LhsScalar,RhsScalar>::value && packet_traits<LhsScalar>::HasAdd && packet_traits<RhsScalar>::HasAdd
55  // TODO vectorize mixed sum
56  };
57 };
58 
64 template<> struct scalar_sum_op<bool,bool> : scalar_sum_op<int,int> {
65  EIGEN_DEPRECATED
66  scalar_sum_op() {}
67 };
68 
69 
75 template<typename LhsScalar,typename RhsScalar>
76 struct scalar_product_op : binary_op_base<LhsScalar,RhsScalar>
77 {
78  typedef typename ScalarBinaryOpTraits<LhsScalar,RhsScalar,scalar_product_op>::ReturnType result_type;
79 #ifndef EIGEN_SCALAR_BINARY_OP_PLUGIN
80  EIGEN_EMPTY_STRUCT_CTOR(scalar_product_op)
81 #else
82  scalar_product_op() {
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 {
97  Cost = (NumTraits<LhsScalar>::MulCost + NumTraits<RhsScalar>::MulCost)/2, // rough estimate!
98  PacketAccess = is_same<LhsScalar,RhsScalar>::value && packet_traits<LhsScalar>::HasMul && packet_traits<RhsScalar>::HasMul
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 {
113  Conj = NumTraits<LhsScalar>::IsComplex
114  };
115 
116  typedef typename ScalarBinaryOpTraits<LhsScalar,RhsScalar,scalar_conj_product_op>::ReturnType result_type;
117 
118  EIGEN_EMPTY_STRUCT_CTOR(scalar_conj_product_op)
119  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const
120  { return conj_helper<LhsScalar,RhsScalar,Conj,false>().pmul(a,b); }
121 
122  template<typename Packet>
123  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
124  { return conj_helper<Packet,Packet,Conj,false>().pmul(a,b); }
125 };
126 template<typename LhsScalar,typename RhsScalar>
127 struct functor_traits<scalar_conj_product_op<LhsScalar,RhsScalar> > {
128  enum {
129  Cost = NumTraits<LhsScalar>::MulCost,
130  PacketAccess = internal::is_same<LhsScalar, RhsScalar>::value && packet_traits<LhsScalar>::HasMul
131  };
132 };
133 
139 template<typename LhsScalar,typename RhsScalar>
140 struct scalar_min_op : binary_op_base<LhsScalar,RhsScalar>
141 {
142  typedef typename ScalarBinaryOpTraits<LhsScalar,RhsScalar,scalar_min_op>::ReturnType result_type;
143  EIGEN_EMPTY_STRUCT_CTOR(scalar_min_op)
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 {
155  Cost = (NumTraits<LhsScalar>::AddCost+NumTraits<RhsScalar>::AddCost)/2,
156  PacketAccess = internal::is_same<LhsScalar, RhsScalar>::value && packet_traits<LhsScalar>::HasMin
157  };
158 };
159 
165 template<typename LhsScalar,typename RhsScalar>
166 struct scalar_max_op : binary_op_base<LhsScalar,RhsScalar>
167 {
168  typedef typename ScalarBinaryOpTraits<LhsScalar,RhsScalar,scalar_max_op>::ReturnType result_type;
169  EIGEN_EMPTY_STRUCT_CTOR(scalar_max_op)
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 {
181  Cost = (NumTraits<LhsScalar>::AddCost+NumTraits<RhsScalar>::AddCost)/2,
182  PacketAccess = internal::is_same<LhsScalar, RhsScalar>::value && packet_traits<LhsScalar>::HasMax
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 {
195  Cost = (NumTraits<LhsScalar>::AddCost+NumTraits<RhsScalar>::AddCost)/2,
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;
210  EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op)
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;
217  EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op)
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;
224  EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op)
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;
231  EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op)
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;
238  EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op)
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;
245  EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op)
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;
252  EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op)
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 {
265  EIGEN_EMPTY_STRUCT_CTOR(scalar_hypot_op)
266 
267  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (const Scalar &x, const Scalar &y) const
268  {
269  // This functor is used by hypotNorm only for which it is faster to first apply abs
270  // on all coefficients prior to reduction through hypot.
271  // This way we avoid calling abs on positive and real entries, and this also permits
272  // to seamlessly handle complexes. Otherwise we would have to handle both real and complexes
273  // through the same functor...
274  return internal::positive_real_hypot(x,y);
275  }
276 };
277 template<typename Scalar>
278 struct functor_traits<scalar_hypot_op<Scalar,Scalar> > {
279  enum
280  {
281  Cost = 3 * NumTraits<Scalar>::AddCost +
282  2 * NumTraits<Scalar>::MulCost +
283  2 * scalar_div_cost<Scalar,false>::value,
284  PacketAccess = false
285  };
286 };
287 
291 template<typename Scalar, typename Exponent>
292 struct scalar_pow_op : binary_op_base<Scalar,Exponent>
293 {
294  typedef typename ScalarBinaryOpTraits<Scalar,Exponent,scalar_pow_op>::ReturnType result_type;
295 #ifndef EIGEN_SCALAR_BINARY_OP_PLUGIN
296  EIGEN_EMPTY_STRUCT_CTOR(scalar_pow_op)
297 #else
298  scalar_pow_op() {
299  typedef Scalar LhsScalar;
300  typedef Exponent RhsScalar;
301  EIGEN_SCALAR_BINARY_OP_PLUGIN
302  }
303 #endif
304  EIGEN_DEVICE_FUNC
305  inline result_type operator() (const Scalar& a, const Exponent& b) const { return numext::pow(a, b); }
306 };
307 template<typename Scalar, typename Exponent>
308 struct functor_traits<scalar_pow_op<Scalar,Exponent> > {
309  enum { Cost = 5 * NumTraits<Scalar>::MulCost, PacketAccess = false };
310 };
311 
312 
313 
314 //---------- non associative binary functors ----------
315 
321 template<typename LhsScalar,typename RhsScalar>
322 struct scalar_difference_op : binary_op_base<LhsScalar,RhsScalar>
323 {
324  typedef typename ScalarBinaryOpTraits<LhsScalar,RhsScalar,scalar_difference_op>::ReturnType result_type;
325 #ifndef EIGEN_SCALAR_BINARY_OP_PLUGIN
326  EIGEN_EMPTY_STRUCT_CTOR(scalar_difference_op)
327 #else
328  scalar_difference_op() {
329  EIGEN_SCALAR_BINARY_OP_PLUGIN
330  }
331 #endif
332  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const { return a - b; }
333  template<typename Packet>
334  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
335  { return internal::psub(a,b); }
336 };
337 template<typename LhsScalar,typename RhsScalar>
338 struct functor_traits<scalar_difference_op<LhsScalar,RhsScalar> > {
339  enum {
340  Cost = (NumTraits<LhsScalar>::AddCost+NumTraits<RhsScalar>::AddCost)/2,
341  PacketAccess = is_same<LhsScalar,RhsScalar>::value && packet_traits<LhsScalar>::HasSub && packet_traits<RhsScalar>::HasSub
342  };
343 };
344 
350 template<typename LhsScalar,typename RhsScalar>
351 struct scalar_quotient_op : binary_op_base<LhsScalar,RhsScalar>
352 {
353  typedef typename ScalarBinaryOpTraits<LhsScalar,RhsScalar,scalar_quotient_op>::ReturnType result_type;
354 #ifndef EIGEN_SCALAR_BINARY_OP_PLUGIN
355  EIGEN_EMPTY_STRUCT_CTOR(scalar_quotient_op)
356 #else
357  scalar_quotient_op() {
358  EIGEN_SCALAR_BINARY_OP_PLUGIN
359  }
360 #endif
361  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const { return a / b; }
362  template<typename Packet>
363  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
364  { return internal::pdiv(a,b); }
365 };
366 template<typename LhsScalar,typename RhsScalar>
367 struct functor_traits<scalar_quotient_op<LhsScalar,RhsScalar> > {
368  typedef typename scalar_quotient_op<LhsScalar,RhsScalar>::result_type result_type;
369  enum {
370  PacketAccess = is_same<LhsScalar,RhsScalar>::value && packet_traits<LhsScalar>::HasDiv && packet_traits<RhsScalar>::HasDiv,
371  Cost = scalar_div_cost<result_type,PacketAccess>::value
372  };
373 };
374 
375 
376 
382 struct scalar_boolean_and_op {
383  EIGEN_EMPTY_STRUCT_CTOR(scalar_boolean_and_op)
384  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool operator() (const bool& a, const bool& b) const { return a && b; }
385 };
386 template<> struct functor_traits<scalar_boolean_and_op> {
387  enum {
388  Cost = NumTraits<bool>::AddCost,
389  PacketAccess = false
390  };
391 };
392 
398 struct scalar_boolean_or_op {
399  EIGEN_EMPTY_STRUCT_CTOR(scalar_boolean_or_op)
400  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool operator() (const bool& a, const bool& b) const { return a || b; }
401 };
402 template<> struct functor_traits<scalar_boolean_or_op> {
403  enum {
404  Cost = NumTraits<bool>::AddCost,
405  PacketAccess = false
406  };
407 };
408 
414 struct scalar_boolean_xor_op {
415  EIGEN_EMPTY_STRUCT_CTOR(scalar_boolean_xor_op)
416  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool operator() (const bool& a, const bool& b) const { return a ^ b; }
417 };
418 template<> struct functor_traits<scalar_boolean_xor_op> {
419  enum {
420  Cost = NumTraits<bool>::AddCost,
421  PacketAccess = false
422  };
423 };
424 
425 
426 
427 //---------- binary functors bound to a constant, thus appearing as a unary functor ----------
428 
429 // The following two classes permits to turn any binary functor into a unary one with one argument bound to a constant value.
430 // They are analogues to std::binder1st/binder2nd but with the following differences:
431 // - they are compatible with packetOp
432 // - they are portable across C++ versions (the std::binder* are deprecated in C++11)
433 template<typename BinaryOp> struct bind1st_op : BinaryOp {
434 
435  typedef typename BinaryOp::first_argument_type first_argument_type;
436  typedef typename BinaryOp::second_argument_type second_argument_type;
437  typedef typename BinaryOp::result_type result_type;
438 
439  bind1st_op(const first_argument_type &val) : m_value(val) {}
440 
441  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const second_argument_type& b) const { return BinaryOp::operator()(m_value,b); }
442 
443  template<typename Packet>
444  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& b) const
445  { return BinaryOp::packetOp(internal::pset1<Packet>(m_value), b); }
446 
447  first_argument_type m_value;
448 };
449 template<typename BinaryOp> struct functor_traits<bind1st_op<BinaryOp> > : functor_traits<BinaryOp> {};
450 
451 
452 template<typename BinaryOp> struct bind2nd_op : BinaryOp {
453 
454  typedef typename BinaryOp::first_argument_type first_argument_type;
455  typedef typename BinaryOp::second_argument_type second_argument_type;
456  typedef typename BinaryOp::result_type result_type;
457 
458  bind2nd_op(const second_argument_type &val) : m_value(val) {}
459 
460  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const first_argument_type& a) const { return BinaryOp::operator()(a,m_value); }
461 
462  template<typename Packet>
463  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const
464  { return BinaryOp::packetOp(a,internal::pset1<Packet>(m_value)); }
465 
466  second_argument_type m_value;
467 };
468 template<typename BinaryOp> struct functor_traits<bind2nd_op<BinaryOp> > : functor_traits<BinaryOp> {};
469 
470 
471 } // end namespace internal
472 
473 } // end namespace Eigen
474 
475 #endif // EIGEN_BINARY_FUNCTORS_H
Namespace containing all symbols from the Eigen library.
Definition: Core:309
Definition: Eigen_Colamd.h:50