10#ifndef EIGEN_BINARY_FUNCTORS_H
11#define EIGEN_BINARY_FUNCTORS_H
19template<
typename Arg1,
typename Arg2>
22 typedef Arg1 first_argument_type;
23 typedef Arg2 second_argument_type;
31template<
typename LhsScalar,
typename RhsScalar>
32struct scalar_sum_op : binary_op_base<LhsScalar,RhsScalar>
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)
39 EIGEN_SCALAR_BINARY_OP_PLUGIN
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); }
50template<
typename LhsScalar,
typename RhsScalar>
51struct functor_traits<scalar_sum_op<LhsScalar,RhsScalar> > {
53 Cost = (int(NumTraits<LhsScalar>::AddCost) + int(NumTraits<RhsScalar>::AddCost)) / 2,
54 PacketAccess = is_same<LhsScalar,RhsScalar>::value && packet_traits<LhsScalar>::HasAdd && packet_traits<RhsScalar>::HasAdd
61EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
bool scalar_sum_op<bool,bool>::operator() (
const bool& a,
const bool& b)
const {
return a || b; }
69template<
typename LhsScalar,
typename RhsScalar>
70struct scalar_product_op : binary_op_base<LhsScalar,RhsScalar>
72 typedef typename ScalarBinaryOpTraits<LhsScalar,RhsScalar,scalar_product_op>::ReturnType result_type;
73#ifndef EIGEN_SCALAR_BINARY_OP_PLUGIN
74 EIGEN_EMPTY_STRUCT_CTOR(scalar_product_op)
77 EIGEN_SCALAR_BINARY_OP_PLUGIN
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); }
88template<
typename LhsScalar,
typename RhsScalar>
89struct functor_traits<scalar_product_op<LhsScalar,RhsScalar> > {
91 Cost = (int(NumTraits<LhsScalar>::MulCost) + int(NumTraits<RhsScalar>::MulCost))/2,
92 PacketAccess = is_same<LhsScalar,RhsScalar>::value && packet_traits<LhsScalar>::HasMul && packet_traits<RhsScalar>::HasMul
98EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
bool scalar_product_op<bool,bool>::operator() (
const bool& a,
const bool& b)
const {
return a && b; }
106template<
typename LhsScalar,
typename RhsScalar>
107struct scalar_conj_product_op : binary_op_base<LhsScalar,RhsScalar>
111 Conj = NumTraits<LhsScalar>::IsComplex
114 typedef typename ScalarBinaryOpTraits<LhsScalar,RhsScalar,scalar_conj_product_op>::ReturnType result_type;
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); }
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); }
124template<
typename LhsScalar,
typename RhsScalar>
125struct functor_traits<scalar_conj_product_op<LhsScalar,RhsScalar> > {
127 Cost = NumTraits<LhsScalar>::MulCost,
128 PacketAccess = internal::is_same<LhsScalar, RhsScalar>::value && packet_traits<LhsScalar>::HasMul
137template<
typename LhsScalar,
typename RhsScalar,
int NaNPropagation>
138struct scalar_min_op : binary_op_base<LhsScalar,RhsScalar>
140 typedef typename ScalarBinaryOpTraits<LhsScalar,RhsScalar,scalar_min_op>::ReturnType result_type;
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);
145 template<
typename Packet>
146 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(
const Packet& a,
const Packet& b)
const
148 return internal::pmin<NaNPropagation>(a,b);
150 template<
typename Packet>
151 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type predux(
const Packet& a)
const
153 return internal::predux_min<NaNPropagation>(a);
157template<
typename LhsScalar,
typename RhsScalar,
int NaNPropagation>
158struct functor_traits<scalar_min_op<LhsScalar,RhsScalar, NaNPropagation> > {
160 Cost = (NumTraits<LhsScalar>::AddCost+NumTraits<RhsScalar>::AddCost)/2,
161 PacketAccess = internal::is_same<LhsScalar, RhsScalar>::value && packet_traits<LhsScalar>::HasMin
170template<
typename LhsScalar,
typename RhsScalar,
int NaNPropagation>
171struct scalar_max_op : binary_op_base<LhsScalar,RhsScalar>
173 typedef typename ScalarBinaryOpTraits<LhsScalar,RhsScalar,scalar_max_op>::ReturnType result_type;
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);
178 template<
typename Packet>
179 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(
const Packet& a,
const Packet& b)
const
181 return internal::pmax<NaNPropagation>(a,b);
183 template<
typename Packet>
184 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type predux(
const Packet& a)
const
186 return internal::predux_max<NaNPropagation>(a);
190template<
typename LhsScalar,
typename RhsScalar,
int NaNPropagation>
191struct functor_traits<scalar_max_op<LhsScalar,RhsScalar, NaNPropagation> > {
193 Cost = (NumTraits<LhsScalar>::AddCost+NumTraits<RhsScalar>::AddCost)/2,
194 PacketAccess = internal::is_same<LhsScalar, RhsScalar>::value && packet_traits<LhsScalar>::HasMax
202template<
typename LhsScalar,
typename RhsScalar, ComparisonName cmp>
struct scalar_cmp_op;
204template<
typename LhsScalar,
typename RhsScalar, ComparisonName cmp>
205struct functor_traits<scalar_cmp_op<LhsScalar,RhsScalar, cmp> > {
207 Cost = (NumTraits<LhsScalar>::AddCost+NumTraits<RhsScalar>::AddCost)/2,
212template<ComparisonName Cmp,
typename LhsScalar,
typename RhsScalar>
213struct result_of<scalar_cmp_op<LhsScalar, RhsScalar, Cmp>(LhsScalar,RhsScalar)> {
218template<
typename LhsScalar,
typename RhsScalar>
219struct scalar_cmp_op<LhsScalar,RhsScalar, cmp_EQ> : binary_op_base<LhsScalar,RhsScalar>
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;}
225template<
typename LhsScalar,
typename RhsScalar>
226struct scalar_cmp_op<LhsScalar,RhsScalar, cmp_LT> : binary_op_base<LhsScalar,RhsScalar>
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;}
232template<
typename LhsScalar,
typename RhsScalar>
233struct scalar_cmp_op<LhsScalar,RhsScalar, cmp_LE> : binary_op_base<LhsScalar,RhsScalar>
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;}
239template<
typename LhsScalar,
typename RhsScalar>
240struct scalar_cmp_op<LhsScalar,RhsScalar, cmp_GT> : binary_op_base<LhsScalar,RhsScalar>
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;}
246template<
typename LhsScalar,
typename RhsScalar>
247struct scalar_cmp_op<LhsScalar,RhsScalar, cmp_GE> : binary_op_base<LhsScalar,RhsScalar>
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;}
253template<
typename LhsScalar,
typename RhsScalar>
254struct scalar_cmp_op<LhsScalar,RhsScalar, cmp_UNORD> : binary_op_base<LhsScalar,RhsScalar>
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);}
260template<
typename LhsScalar,
typename RhsScalar>
261struct scalar_cmp_op<LhsScalar,RhsScalar, cmp_NEQ> : binary_op_base<LhsScalar,RhsScalar>
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;}
273template<
typename Scalar>
274struct scalar_hypot_op<Scalar,Scalar> : binary_op_base<Scalar,Scalar>
276 EIGEN_EMPTY_STRUCT_CTOR(scalar_hypot_op)
278 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const Scalar operator() (
const Scalar &x,
const Scalar &y)
const
285 return internal::positive_real_hypot(x,y);
288template<
typename Scalar>
289struct functor_traits<scalar_hypot_op<Scalar,Scalar> > {
292 Cost = 3 * NumTraits<Scalar>::AddCost +
293 2 * NumTraits<Scalar>::MulCost +
294 2 * scalar_div_cost<Scalar,false>::value,
303template<
typename Scalar,
typename Exponent>
304struct scalar_pow_op : binary_op_base<Scalar,Exponent>
306 typedef typename ScalarBinaryOpTraits<Scalar,Exponent,scalar_pow_op>::ReturnType result_type;
307#ifndef EIGEN_SCALAR_BINARY_OP_PLUGIN
308 EIGEN_EMPTY_STRUCT_CTOR(scalar_pow_op)
311 typedef Scalar LhsScalar;
312 typedef Exponent RhsScalar;
313 EIGEN_SCALAR_BINARY_OP_PLUGIN
318 inline result_type operator() (
const Scalar& a,
const Exponent& b)
const {
return numext::pow(a, b); }
320 template<
typename Packet>
321 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const Packet packetOp(
const Packet& a,
const Packet& b)
const
323 return generic_pow(a,b);
327template<
typename Scalar,
typename Exponent>
328struct functor_traits<scalar_pow_op<Scalar,Exponent> > {
330 Cost = 5 * NumTraits<Scalar>::MulCost,
331 PacketAccess = (!NumTraits<Scalar>::IsComplex && !NumTraits<Scalar>::IsInteger &&
332 packet_traits<Scalar>::HasExp && packet_traits<Scalar>::HasLog &&
333 packet_traits<Scalar>::HasRound && packet_traits<Scalar>::HasCmp &&
336 !is_same<Scalar, half>::value && !is_same<Scalar, bfloat16>::value
348template<
typename LhsScalar,
typename RhsScalar>
349struct scalar_difference_op : binary_op_base<LhsScalar,RhsScalar>
351 typedef typename ScalarBinaryOpTraits<LhsScalar,RhsScalar,scalar_difference_op>::ReturnType result_type;
352#ifndef EIGEN_SCALAR_BINARY_OP_PLUGIN
353 EIGEN_EMPTY_STRUCT_CTOR(scalar_difference_op)
355 scalar_difference_op() {
356 EIGEN_SCALAR_BINARY_OP_PLUGIN
359 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const result_type operator() (
const LhsScalar& a,
const RhsScalar& b)
const {
return a - b; }
360 template<
typename Packet>
361 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const Packet packetOp(
const Packet& a,
const Packet& b)
const
362 {
return internal::psub(a,b); }
364template<
typename LhsScalar,
typename RhsScalar>
365struct functor_traits<scalar_difference_op<LhsScalar,RhsScalar> > {
367 Cost = (int(NumTraits<LhsScalar>::AddCost) + int(NumTraits<RhsScalar>::AddCost)) / 2,
368 PacketAccess = is_same<LhsScalar,RhsScalar>::value && packet_traits<LhsScalar>::HasSub && packet_traits<RhsScalar>::HasSub
377template<
typename LhsScalar,
typename RhsScalar>
378struct scalar_quotient_op : binary_op_base<LhsScalar,RhsScalar>
380 typedef typename ScalarBinaryOpTraits<LhsScalar,RhsScalar,scalar_quotient_op>::ReturnType result_type;
381#ifndef EIGEN_SCALAR_BINARY_OP_PLUGIN
382 EIGEN_EMPTY_STRUCT_CTOR(scalar_quotient_op)
384 scalar_quotient_op() {
385 EIGEN_SCALAR_BINARY_OP_PLUGIN
388 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const result_type operator() (
const LhsScalar& a,
const RhsScalar& b)
const {
return a / b; }
389 template<
typename Packet>
390 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const Packet packetOp(
const Packet& a,
const Packet& b)
const
391 {
return internal::pdiv(a,b); }
393template<
typename LhsScalar,
typename RhsScalar>
394struct functor_traits<scalar_quotient_op<LhsScalar,RhsScalar> > {
395 typedef typename scalar_quotient_op<LhsScalar,RhsScalar>::result_type result_type;
397 PacketAccess = is_same<LhsScalar,RhsScalar>::value && packet_traits<LhsScalar>::HasDiv && packet_traits<RhsScalar>::HasDiv,
398 Cost = scalar_div_cost<result_type,PacketAccess>::value
409struct scalar_boolean_and_op {
410 EIGEN_EMPTY_STRUCT_CTOR(scalar_boolean_and_op)
411 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
bool operator() (
const bool& a,
const bool& b)
const {
return a && b; }
412 template<
typename Packet>
413 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const Packet packetOp(
const Packet& a,
const Packet& b)
const
414 {
return internal::pand(a,b); }
416template<>
struct functor_traits<scalar_boolean_and_op> {
418 Cost = NumTraits<bool>::AddCost,
428struct scalar_boolean_or_op {
429 EIGEN_EMPTY_STRUCT_CTOR(scalar_boolean_or_op)
430 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
bool operator() (
const bool& a,
const bool& b)
const {
return a || b; }
431 template<
typename Packet>
432 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const Packet packetOp(
const Packet& a,
const Packet& b)
const
433 {
return internal::por(a,b); }
435template<>
struct functor_traits<scalar_boolean_or_op> {
437 Cost = NumTraits<bool>::AddCost,
447struct scalar_boolean_xor_op {
448 EIGEN_EMPTY_STRUCT_CTOR(scalar_boolean_xor_op)
449 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
bool operator() (
const bool& a,
const bool& b)
const {
return a ^ b; }
450 template<
typename Packet>
451 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const Packet packetOp(
const Packet& a,
const Packet& b)
const
452 {
return internal::pxor(a,b); }
454template<>
struct functor_traits<scalar_boolean_xor_op> {
456 Cost = NumTraits<bool>::AddCost,
466template<
typename LhsScalar,
typename RhsScalar>
467struct scalar_absolute_difference_op : binary_op_base<LhsScalar,RhsScalar>
469 typedef typename ScalarBinaryOpTraits<LhsScalar,RhsScalar,scalar_absolute_difference_op>::ReturnType result_type;
470#ifndef EIGEN_SCALAR_BINARY_OP_PLUGIN
471 EIGEN_EMPTY_STRUCT_CTOR(scalar_absolute_difference_op)
473 scalar_absolute_difference_op() {
474 EIGEN_SCALAR_BINARY_OP_PLUGIN
477 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const result_type operator() (
const LhsScalar& a,
const RhsScalar& b)
const
478 {
return numext::absdiff(a,b); }
479 template<
typename Packet>
480 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const Packet packetOp(
const Packet& a,
const Packet& b)
const
481 {
return internal::pabsdiff(a,b); }
483template<
typename LhsScalar,
typename RhsScalar>
484struct functor_traits<scalar_absolute_difference_op<LhsScalar,RhsScalar> > {
486 Cost = (NumTraits<LhsScalar>::AddCost+NumTraits<RhsScalar>::AddCost)/2,
487 PacketAccess = is_same<LhsScalar,RhsScalar>::value && packet_traits<LhsScalar>::HasAbsDiff
499template<
typename BinaryOp>
struct bind1st_op : BinaryOp {
501 typedef typename BinaryOp::first_argument_type first_argument_type;
502 typedef typename BinaryOp::second_argument_type second_argument_type;
503 typedef typename BinaryOp::result_type result_type;
505 EIGEN_DEVICE_FUNC
explicit bind1st_op(
const first_argument_type &val) : m_value(val) {}
507 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const result_type operator() (
const second_argument_type& b)
const {
return BinaryOp::operator()(m_value,b); }
509 template<
typename Packet>
510 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const Packet packetOp(
const Packet& b)
const
511 {
return BinaryOp::packetOp(internal::pset1<Packet>(m_value), b); }
513 first_argument_type m_value;
515template<
typename BinaryOp>
struct functor_traits<bind1st_op<BinaryOp> > : functor_traits<BinaryOp> {};
518template<
typename BinaryOp>
struct bind2nd_op : BinaryOp {
520 typedef typename BinaryOp::first_argument_type first_argument_type;
521 typedef typename BinaryOp::second_argument_type second_argument_type;
522 typedef typename BinaryOp::result_type result_type;
524 EIGEN_DEVICE_FUNC
explicit bind2nd_op(
const second_argument_type &val) : m_value(val) {}
526 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const result_type operator() (
const first_argument_type& a)
const {
return BinaryOp::operator()(a,m_value); }
528 template<
typename Packet>
529 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const Packet packetOp(
const Packet& a)
const
530 {
return BinaryOp::packetOp(a,internal::pset1<Packet>(m_value)); }
532 second_argument_type m_value;
534template<
typename BinaryOp>
struct functor_traits<bind2nd_op<BinaryOp> > : functor_traits<BinaryOp> {};
Namespace containing all symbols from the Eigen library.
Definition: Core:141