Path Tracer
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>
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
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 result_type operator() (const LhsScalar& a, const RhsScalar& b) const { return a + b; }
43  template<typename Packet>
44  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE 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 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 
59 
60 template<>
61 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool scalar_sum_op<bool,bool>::operator() (const bool& a, const bool& b) const { return a || b; }
62 
63 
69 template<typename LhsScalar,typename RhsScalar>
70 struct scalar_product_op : binary_op_base<LhsScalar,RhsScalar>
71 {
73 #ifndef EIGEN_SCALAR_BINARY_OP_PLUGIN
74  EIGEN_EMPTY_STRUCT_CTOR(scalar_product_op)
75 #else
77  EIGEN_SCALAR_BINARY_OP_PLUGIN
78  }
79 #endif
80  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator() (const LhsScalar& a, const RhsScalar& b) const { return a * b; }
81  template<typename Packet>
82  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(const Packet& a, const Packet& b) const
83  { return internal::pmul(a,b); }
84  template<typename Packet>
85  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type predux(const Packet& a) const
86  { return internal::predux_mul(a); }
87 };
88 template<typename LhsScalar,typename RhsScalar>
89 struct functor_traits<scalar_product_op<LhsScalar,RhsScalar> > {
90  enum {
91  Cost = (NumTraits<LhsScalar>::MulCost + NumTraits<RhsScalar>::MulCost)/2, // rough estimate!
93  // TODO vectorize mixed product
94  };
95 };
96 
97 template<>
98 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool scalar_product_op<bool,bool>::operator() (const bool& a, const bool& b) const { return a && b; }
99 
100 
106 template<typename LhsScalar,typename RhsScalar>
107 struct scalar_conj_product_op : binary_op_base<LhsScalar,RhsScalar>
108 {
109 
110  enum {
112  };
113 
115 
116  EIGEN_EMPTY_STRUCT_CTOR(scalar_conj_product_op)
117  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator() (const LhsScalar& a, const RhsScalar& b) const
118  { return conj_helper<LhsScalar,RhsScalar,Conj,false>().pmul(a,b); }
119 
120  template<typename Packet>
121  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(const Packet& a, const Packet& b) const
122  { return conj_helper<Packet,Packet,Conj,false>().pmul(a,b); }
123 };
124 template<typename LhsScalar,typename RhsScalar>
125 struct functor_traits<scalar_conj_product_op<LhsScalar,RhsScalar> > {
126  enum {
129  };
130 };
131 
137 template<typename LhsScalar,typename RhsScalar, int NaNPropagation>
138 struct scalar_min_op : binary_op_base<LhsScalar,RhsScalar>
139 {
141  EIGEN_EMPTY_STRUCT_CTOR(scalar_min_op)
142  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator() (const LhsScalar& a, const RhsScalar& b) const {
143  return internal::pmin<NaNPropagation>(a, b);
144  }
145  template<typename Packet>
146  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(const Packet& a, const Packet& b) const
147  {
148  return internal::pmin<NaNPropagation>(a,b);
149  }
150  template<typename Packet>
151  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type predux(const Packet& a) const
152  {
153  return internal::predux_min<NaNPropagation>(a);
154  }
155 };
156 
157 template<typename LhsScalar,typename RhsScalar, int NaNPropagation>
158 struct functor_traits<scalar_min_op<LhsScalar,RhsScalar, NaNPropagation> > {
159  enum {
162  };
163 };
164 
170 template<typename LhsScalar,typename RhsScalar, int NaNPropagation>
171 struct scalar_max_op : binary_op_base<LhsScalar,RhsScalar>
172 {
174  EIGEN_EMPTY_STRUCT_CTOR(scalar_max_op)
175  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator() (const LhsScalar& a, const RhsScalar& b) const {
176  return internal::pmax<NaNPropagation>(a,b);
177  }
178  template<typename Packet>
179  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(const Packet& a, const Packet& b) const
180  {
181  return internal::pmax<NaNPropagation>(a,b);
182  }
183  template<typename Packet>
184  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type predux(const Packet& a) const
185  {
186  return internal::predux_max<NaNPropagation>(a);
187  }
188 };
189 
190 template<typename LhsScalar,typename RhsScalar, int NaNPropagation>
191 struct functor_traits<scalar_max_op<LhsScalar,RhsScalar, NaNPropagation> > {
192  enum {
195  };
196 };
197 
202 template<typename LhsScalar, typename RhsScalar, ComparisonName cmp> struct scalar_cmp_op;
203 
204 template<typename LhsScalar, typename RhsScalar, ComparisonName cmp>
205 struct functor_traits<scalar_cmp_op<LhsScalar,RhsScalar, cmp> > {
206  enum {
208  PacketAccess = false
209  };
210 };
211 
212 template<ComparisonName Cmp, typename LhsScalar, typename RhsScalar>
213 struct result_of<scalar_cmp_op<LhsScalar, RhsScalar, Cmp>(LhsScalar,RhsScalar)> {
214  typedef bool type;
215 };
216 
217 
218 template<typename LhsScalar, typename RhsScalar>
219 struct scalar_cmp_op<LhsScalar,RhsScalar, cmp_EQ> : binary_op_base<LhsScalar,RhsScalar>
220 {
221  typedef bool result_type;
222  EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op)
223  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool operator()(const LhsScalar& a, const RhsScalar& b) const {return a==b;}
224 };
225 template<typename LhsScalar, typename RhsScalar>
226 struct scalar_cmp_op<LhsScalar,RhsScalar, cmp_LT> : binary_op_base<LhsScalar,RhsScalar>
227 {
228  typedef bool result_type;
229  EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op)
230  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool operator()(const LhsScalar& a, const RhsScalar& b) const {return a<b;}
231 };
232 template<typename LhsScalar, typename RhsScalar>
233 struct scalar_cmp_op<LhsScalar,RhsScalar, cmp_LE> : binary_op_base<LhsScalar,RhsScalar>
234 {
235  typedef bool result_type;
236  EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op)
237  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool operator()(const LhsScalar& a, const RhsScalar& b) const {return a<=b;}
238 };
239 template<typename LhsScalar, typename RhsScalar>
240 struct scalar_cmp_op<LhsScalar,RhsScalar, cmp_GT> : binary_op_base<LhsScalar,RhsScalar>
241 {
242  typedef bool result_type;
243  EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op)
244  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool operator()(const LhsScalar& a, const RhsScalar& b) const {return a>b;}
245 };
246 template<typename LhsScalar, typename RhsScalar>
247 struct scalar_cmp_op<LhsScalar,RhsScalar, cmp_GE> : binary_op_base<LhsScalar,RhsScalar>
248 {
249  typedef bool result_type;
250  EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op)
251  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool operator()(const LhsScalar& a, const RhsScalar& b) const {return a>=b;}
252 };
253 template<typename LhsScalar, typename RhsScalar>
254 struct scalar_cmp_op<LhsScalar,RhsScalar, cmp_UNORD> : binary_op_base<LhsScalar,RhsScalar>
255 {
256  typedef bool result_type;
257  EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op)
258  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool operator()(const LhsScalar& a, const RhsScalar& b) const {return !(a<=b || b<=a);}
259 };
260 template<typename LhsScalar, typename RhsScalar>
261 struct scalar_cmp_op<LhsScalar,RhsScalar, cmp_NEQ> : binary_op_base<LhsScalar,RhsScalar>
262 {
263  typedef bool result_type;
264  EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op)
265  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool operator()(const LhsScalar& a, const RhsScalar& b) const {return a!=b;}
266 };
267 
271 template<typename LhsScalar, typename RhsScalar, ComparisonName cmp> struct scalar_cmp_with_cast_op;
272 
273 template<typename LhsScalar, typename RhsScalar, ComparisonName cmp>
274 struct functor_traits<scalar_cmp_with_cast_op<LhsScalar,RhsScalar, cmp> > {
275  enum {
278  };
279 };
280 
281 template<typename LhsScalar, typename RhsScalar>
282 struct scalar_cmp_with_cast_op<LhsScalar, RhsScalar, cmp_EQ> : binary_op_base<LhsScalar,RhsScalar>
283 {
285  EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_with_cast_op)
286  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const {
287  if(a==b) return static_cast<result_type>(1);
288  else return static_cast<result_type>(0);
289  }
290  template<typename Packet>
291  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
292  { return internal::pselect(internal::pcmp_eq(a,b), internal::pset1<Packet>(static_cast<result_type>(1)), internal::pzero(a)); }
293 };
294 template<typename LhsScalar, typename RhsScalar>
295 struct scalar_cmp_with_cast_op<LhsScalar, RhsScalar, cmp_LT> : binary_op_base<LhsScalar,RhsScalar>
296 {
298  EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_with_cast_op)
299  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const {
300  if(a<b) return static_cast<result_type>(1);
301  else return static_cast<result_type>(0);
302  }
303  template<typename Packet>
304  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
305  { return internal::pselect(internal::pcmp_lt(a,b), internal::pset1<Packet>(static_cast<result_type>(1)), internal::pzero(a)); }
306 };
307 template<typename LhsScalar, typename RhsScalar>
308 struct scalar_cmp_with_cast_op<LhsScalar, RhsScalar, cmp_LE> : binary_op_base<LhsScalar,RhsScalar>
309 {
311  EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_with_cast_op)
312  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const {
313  if(a<=b) return static_cast<result_type>(1);
314  else return static_cast<result_type>(0);
315  }
316  template<typename Packet>
317  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
318  { return internal::pselect(internal::pcmp_le(a,b), internal::pset1<Packet>(static_cast<result_type>(1)), internal::pzero(a)); }
319 };
320 template<typename LhsScalar, typename RhsScalar>
321 struct scalar_cmp_with_cast_op<LhsScalar, RhsScalar, cmp_GT> : binary_op_base<LhsScalar,RhsScalar>
322 {
324  EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_with_cast_op)
325  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const {
326  if(a>b) return static_cast<result_type>(1);
327  else return static_cast<result_type>(0);
328  }
329  template<typename Packet>
330  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
331  { return internal::pselect(internal::pcmp_le(a,b), internal::pzero(a), internal::pset1<Packet>(static_cast<result_type>(1))); }
332 };
333 template<typename LhsScalar, typename RhsScalar>
334 struct scalar_cmp_with_cast_op<LhsScalar, RhsScalar, cmp_GE> : binary_op_base<LhsScalar,RhsScalar>
335 {
337  EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_with_cast_op)
338  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const {
339  if(a>=b) return static_cast<result_type>(1);
340  else return static_cast<result_type>(0);
341  }
342  template<typename Packet>
343  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
344  { return internal::pselect(internal::pcmp_lt(a,b), internal::pzero(a), internal::pset1<Packet>(static_cast<result_type>(1))); }
345 };
346 template<typename LhsScalar, typename RhsScalar>
347 struct scalar_cmp_with_cast_op<LhsScalar, RhsScalar, cmp_UNORD> : binary_op_base<LhsScalar,RhsScalar>
348 {
350  EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_with_cast_op)
351  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const {
352  if(a<=b || b<=a) return static_cast<result_type>(0);
353  else return static_cast<result_type>(1);
354  }
355  template<typename Packet>
356  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
357  { return internal::pselect(por(internal::pcmp_le(a,b), internal::pcmp_le(b,a)), internal::pzero(a), internal::pset1<Packet>(static_cast<result_type>(1))); }
358 };
359 template<typename LhsScalar, typename RhsScalar>
360 struct scalar_cmp_with_cast_op<LhsScalar, RhsScalar, cmp_NEQ> : binary_op_base<LhsScalar,RhsScalar>
361 {
363  EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_with_cast_op)
364  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const {
365  if(a!=b) return static_cast<result_type>(1);
366  else return static_cast<result_type>(0);
367  }
368  template<typename Packet>
369  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
370  { return internal::pselect(internal::pcmp_eq(a,b), internal::pzero(a), internal::pset1<Packet>(static_cast<result_type>(1))); }
371 };
372 
378 template<typename Scalar>
379 struct scalar_hypot_op<Scalar,Scalar> : binary_op_base<Scalar,Scalar>
380 {
381  EIGEN_EMPTY_STRUCT_CTOR(scalar_hypot_op)
382 
383  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (const Scalar &x, const Scalar &y) const
384  {
385  // This functor is used by hypotNorm only for which it is faster to first apply abs
386  // on all coefficients prior to reduction through hypot.
387  // This way we avoid calling abs on positive and real entries, and this also permits
388  // to seamlessly handle complexes. Otherwise we would have to handle both real and complexes
389  // through the same functor...
390  return internal::positive_real_hypot(x,y);
391  }
392 };
393 template<typename Scalar>
394 struct functor_traits<scalar_hypot_op<Scalar,Scalar> > {
395  enum
396  {
397  Cost = 3 * NumTraits<Scalar>::AddCost +
400  PacketAccess = false
401  };
402 };
403 
407 template<typename Scalar, typename Exponent>
408 struct scalar_pow_op : binary_op_base<Scalar,Exponent>
409 {
411 #ifndef EIGEN_SCALAR_BINARY_OP_PLUGIN
412  EIGEN_EMPTY_STRUCT_CTOR(scalar_pow_op)
413 #else
414  scalar_pow_op() {
415  typedef Scalar LhsScalar;
416  typedef Exponent RhsScalar;
417  EIGEN_SCALAR_BINARY_OP_PLUGIN
418  }
419 #endif
420  EIGEN_DEVICE_FUNC
421  inline result_type operator() (const Scalar& a, const Exponent& b) const { return numext::pow(a, b); }
422 };
423 template<typename Scalar, typename Exponent>
424 struct functor_traits<scalar_pow_op<Scalar,Exponent> > {
425  enum { Cost = 5 * NumTraits<Scalar>::MulCost, PacketAccess = false };
426 };
427 
428 
429 
430 //---------- non associative binary functors ----------
431 
437 template<typename LhsScalar,typename RhsScalar>
438 struct scalar_difference_op : binary_op_base<LhsScalar,RhsScalar>
439 {
441 #ifndef EIGEN_SCALAR_BINARY_OP_PLUGIN
442  EIGEN_EMPTY_STRUCT_CTOR(scalar_difference_op)
443 #else
445  EIGEN_SCALAR_BINARY_OP_PLUGIN
446  }
447 #endif
448  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const { return a - b; }
449  template<typename Packet>
450  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
451  { return internal::psub(a,b); }
452 };
453 template<typename LhsScalar,typename RhsScalar>
454 struct functor_traits<scalar_difference_op<LhsScalar,RhsScalar> > {
455  enum {
458  };
459 };
460 
466 template<typename LhsScalar,typename RhsScalar>
467 struct scalar_quotient_op : binary_op_base<LhsScalar,RhsScalar>
468 {
470 #ifndef EIGEN_SCALAR_BINARY_OP_PLUGIN
471  EIGEN_EMPTY_STRUCT_CTOR(scalar_quotient_op)
472 #else
474  EIGEN_SCALAR_BINARY_OP_PLUGIN
475  }
476 #endif
477  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const { return a / b; }
478  template<typename Packet>
479  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
480  { return internal::pdiv(a,b); }
481 };
482 template<typename LhsScalar,typename RhsScalar>
483 struct functor_traits<scalar_quotient_op<LhsScalar,RhsScalar> > {
484  typedef typename scalar_quotient_op<LhsScalar,RhsScalar>::result_type result_type;
485  enum {
488  };
489 };
490 
491 
492 
499  EIGEN_EMPTY_STRUCT_CTOR(scalar_boolean_and_op)
500  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool operator() (const bool& a, const bool& b) const { return a && b; }
501  template<typename Packet>
502  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
503  { return internal::pand(a,b); }
504 };
506  enum {
508  PacketAccess = true
509  };
510 };
511 
518  EIGEN_EMPTY_STRUCT_CTOR(scalar_boolean_or_op)
519  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool operator() (const bool& a, const bool& b) const { return a || b; }
520  template<typename Packet>
521  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
522  { return internal::por(a,b); }
523 };
525  enum {
527  PacketAccess = true
528  };
529 };
530 
537  EIGEN_EMPTY_STRUCT_CTOR(scalar_boolean_xor_op)
538  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool operator() (const bool& a, const bool& b) const { return a ^ b; }
539  template<typename Packet>
540  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
541  { return internal::pxor(a,b); }
542 };
544  enum {
546  PacketAccess = true
547  };
548 };
549 
555 template<typename LhsScalar,typename RhsScalar>
556 struct scalar_absolute_difference_op : binary_op_base<LhsScalar,RhsScalar>
557 {
559 #ifndef EIGEN_SCALAR_BINARY_OP_PLUGIN
560  EIGEN_EMPTY_STRUCT_CTOR(scalar_absolute_difference_op)
561 #else
563  EIGEN_SCALAR_BINARY_OP_PLUGIN
564  }
565 #endif
566  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const
567  { return numext::absdiff(a,b); }
568  template<typename Packet>
569  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
570  { return internal::pabsdiff(a,b); }
571 };
572 template<typename LhsScalar,typename RhsScalar>
573 struct functor_traits<scalar_absolute_difference_op<LhsScalar,RhsScalar> > {
574  enum {
577  };
578 };
579 
580 
581 
582 //---------- binary functors bound to a constant, thus appearing as a unary functor ----------
583 
584 // The following two classes permits to turn any binary functor into a unary one with one argument bound to a constant value.
585 // They are analogues to std::binder1st/binder2nd but with the following differences:
586 // - they are compatible with packetOp
587 // - they are portable across C++ versions (the std::binder* are deprecated in C++11)
588 template<typename BinaryOp> struct bind1st_op : BinaryOp {
589 
590  typedef typename BinaryOp::first_argument_type first_argument_type;
591  typedef typename BinaryOp::second_argument_type second_argument_type;
592  typedef typename BinaryOp::result_type result_type;
593 
594  EIGEN_DEVICE_FUNC explicit bind1st_op(const first_argument_type &val) : m_value(val) {}
595 
596  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const second_argument_type& b) const { return BinaryOp::operator()(m_value,b); }
597 
598  template<typename Packet>
599  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& b) const
600  { return BinaryOp::packetOp(internal::pset1<Packet>(m_value), b); }
601 
602  first_argument_type m_value;
603 };
604 template<typename BinaryOp> struct functor_traits<bind1st_op<BinaryOp> > : functor_traits<BinaryOp> {};
605 
606 
607 template<typename BinaryOp> struct bind2nd_op : BinaryOp {
608 
609  typedef typename BinaryOp::first_argument_type first_argument_type;
610  typedef typename BinaryOp::second_argument_type second_argument_type;
611  typedef typename BinaryOp::result_type result_type;
612 
613  EIGEN_DEVICE_FUNC explicit bind2nd_op(const second_argument_type &val) : m_value(val) {}
614 
615  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const first_argument_type& a) const { return BinaryOp::operator()(a,m_value); }
616 
617  template<typename Packet>
618  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const
619  { return BinaryOp::packetOp(a,internal::pset1<Packet>(m_value)); }
620 
621  second_argument_type m_value;
622 };
623 template<typename BinaryOp> struct functor_traits<bind2nd_op<BinaryOp> > : functor_traits<BinaryOp> {};
624 
625 
626 } // end namespace internal
627 
628 } // end namespace Eigen
629 
630 #endif // EIGEN_BINARY_FUNCTORS_H
Eigen
Namespace containing all symbols from the Eigen library.
Definition: LDLT.h:16
Eigen::internal::scalar_pow_op
Definition: BinaryFunctors.h:409
Eigen::internal::scalar_cmp_op
Definition: BinaryFunctors.h:202
Eigen::internal::scalar_quotient_op
Definition: BinaryFunctors.h:468
Eigen::internal::scalar_absolute_difference_op
Definition: BinaryFunctors.h:557
Eigen::internal::scalar_cmp_with_cast_op
Definition: BinaryFunctors.h:271
Eigen::internal::packet_traits
Definition: GenericPacketMath.h:107
Eigen::internal::bind1st_op
Definition: BinaryFunctors.h:588
Eigen::ScalarBinaryOpTraits
Determines whether the given binary operation of two numeric types is allowed and what the scalar ret...
Definition: XprHelper.h:814
Eigen::internal::scalar_product_op
Definition: BinaryFunctors.h:71
Eigen::internal::scalar_hypot_op
Definition: ForwardDeclarations.h:210
Eigen::internal::scalar_boolean_xor_op
Definition: BinaryFunctors.h:536
Eigen::internal::scalar_difference_op
Definition: BinaryFunctors.h:439
Eigen::internal::scalar_min_op
Definition: BinaryFunctors.h:139
Eigen::internal::Packet
Definition: ZVector/PacketMath.h:53
Eigen::internal::scalar_boolean_or_op
Definition: BinaryFunctors.h:517
Eigen::internal::binary_op_base
Definition: BinaryFunctors.h:21
Eigen::internal::scalar_div_cost
Definition: XprHelper.h:718
Eigen::internal::conj_helper
Definition: BlasUtil.h:62
Eigen::internal::scalar_boolean_and_op
Definition: BinaryFunctors.h:498
Eigen::internal::result_of
Definition: Meta.h:458
Eigen::internal::is_same
Definition: Meta.h:115
Eigen::internal::scalar_max_op
Definition: BinaryFunctors.h:172
Eigen::internal::functor_traits
Definition: XprHelper.h:172
Eigen::internal::scalar_sum_op
Definition: BinaryFunctors.h:33
Eigen::internal::bind2nd_op
Definition: BinaryFunctors.h:607
Eigen::NumTraits
Holds information about the various numeric (i.e. scalar) types allowed by Eigen.
Definition: NumTraits.h:213
Eigen::internal::scalar_conj_product_op
Definition: BinaryFunctors.h:108