10#ifndef EIGEN_BINARY_FUNCTORS_H
11#define EIGEN_BINARY_FUNCTORS_H
14#include "../InternalHeaderCheck.h"
22template <
typename Arg1,
typename Arg2>
23struct binary_op_base {
24 typedef Arg1 first_argument_type;
25 typedef Arg2 second_argument_type;
33template <
typename LhsScalar,
typename RhsScalar>
34struct scalar_sum_op : binary_op_base<LhsScalar, RhsScalar> {
35 typedef typename ScalarBinaryOpTraits<LhsScalar, RhsScalar, scalar_sum_op>::ReturnType result_type;
36#ifdef EIGEN_SCALAR_BINARY_OP_PLUGIN
37 scalar_sum_op(){EIGEN_SCALAR_BINARY_OP_PLUGIN}
39 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type
40 operator()(
const LhsScalar& a,
const RhsScalar& b)
const {
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);
47 template <
typename Packet>
48 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type predux(
const Packet& a)
const {
49 return internal::predux(a);
52template <
typename LhsScalar,
typename RhsScalar>
53struct functor_traits<scalar_sum_op<LhsScalar, RhsScalar>> {
55 Cost = (int(NumTraits<LhsScalar>::AddCost) + int(NumTraits<RhsScalar>::AddCost)) / 2,
57 is_same<LhsScalar, RhsScalar>::value && packet_traits<LhsScalar>::HasAdd && packet_traits<RhsScalar>::HasAdd
63EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
bool scalar_sum_op<bool, bool>::operator()(
const bool& a,
const bool& b)
const {
72template <
typename LhsScalar,
typename RhsScalar>
73struct scalar_product_op : binary_op_base<LhsScalar, RhsScalar> {
74 typedef typename ScalarBinaryOpTraits<LhsScalar, RhsScalar, scalar_product_op>::ReturnType result_type;
75#ifdef EIGEN_SCALAR_BINARY_OP_PLUGIN
76 scalar_product_op(){EIGEN_SCALAR_BINARY_OP_PLUGIN}
78 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type
79 operator()(
const LhsScalar& a,
const RhsScalar& b)
const {
82 template <
typename Packet>
83 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(
const Packet& a,
const Packet& b)
const {
84 return internal::pmul(a, b);
86 template <
typename Packet>
87 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type predux(
const Packet& a)
const {
88 return internal::predux_mul(a);
91template <
typename LhsScalar,
typename RhsScalar>
92struct functor_traits<scalar_product_op<LhsScalar, RhsScalar>> {
94 Cost = (int(NumTraits<LhsScalar>::MulCost) + int(NumTraits<RhsScalar>::MulCost)) / 2,
96 is_same<LhsScalar, RhsScalar>::value && packet_traits<LhsScalar>::HasMul && packet_traits<RhsScalar>::HasMul
102EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
bool scalar_product_op<bool, bool>::operator()(
const bool& a,
103 const bool& b)
const {
113template <
typename LhsScalar,
typename RhsScalar>
114struct scalar_conj_product_op : binary_op_base<LhsScalar, RhsScalar> {
115 enum { Conj = NumTraits<LhsScalar>::IsComplex };
117 typedef typename ScalarBinaryOpTraits<LhsScalar, RhsScalar, scalar_conj_product_op>::ReturnType result_type;
119 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator()(
const LhsScalar& a,
const RhsScalar& b)
const {
120 return conj_helper<LhsScalar, RhsScalar, Conj, false>().pmul(a, b);
123 template <
typename Packet>
124 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(
const Packet& a,
const Packet& b)
const {
125 return conj_helper<Packet, Packet, Conj, false>().pmul(a, b);
128template <
typename LhsScalar,
typename RhsScalar>
129struct functor_traits<scalar_conj_product_op<LhsScalar, RhsScalar>> {
131 Cost = NumTraits<LhsScalar>::MulCost,
132 PacketAccess = internal::is_same<LhsScalar, RhsScalar>::value && packet_traits<LhsScalar>::HasMul
141template <
typename LhsScalar,
typename RhsScalar,
int NaNPropagation>
142struct scalar_min_op : binary_op_base<LhsScalar, RhsScalar> {
143 typedef typename ScalarBinaryOpTraits<LhsScalar, RhsScalar, scalar_min_op>::ReturnType result_type;
144 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator()(
const LhsScalar& a,
const RhsScalar& b)
const {
145 return internal::pmin<NaNPropagation>(a, b);
147 template <
typename Packet>
148 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(
const Packet& a,
const Packet& b)
const {
149 return internal::pmin<NaNPropagation>(a, b);
151 template <
typename Packet>
152 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> {
172 typedef typename ScalarBinaryOpTraits<LhsScalar, RhsScalar, scalar_max_op>::ReturnType result_type;
173 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator()(
const LhsScalar& a,
const RhsScalar& b)
const {
174 return internal::pmax<NaNPropagation>(a, b);
176 template <
typename Packet>
177 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(
const Packet& a,
const Packet& b)
const {
178 return internal::pmax<NaNPropagation>(a, b);
180 template <
typename Packet>
181 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type predux(
const Packet& a)
const {
182 return internal::predux_max<NaNPropagation>(a);
186template <
typename LhsScalar,
typename RhsScalar,
int NaNPropagation>
187struct functor_traits<scalar_max_op<LhsScalar, RhsScalar, NaNPropagation>> {
189 Cost = (NumTraits<LhsScalar>::AddCost + NumTraits<RhsScalar>::AddCost) / 2,
190 PacketAccess = internal::is_same<LhsScalar, RhsScalar>::value && packet_traits<LhsScalar>::HasMax
198template <
typename LhsScalar,
typename RhsScalar, ComparisonName cmp,
bool UseTypedComparators = false>
201template <
typename LhsScalar,
typename RhsScalar, ComparisonName cmp,
bool UseTypedComparators>
202struct functor_traits<scalar_cmp_op<LhsScalar, RhsScalar, cmp, UseTypedComparators>> {
204 Cost = (NumTraits<LhsScalar>::AddCost + NumTraits<RhsScalar>::AddCost) / 2,
205 PacketAccess = (UseTypedComparators || is_same<LhsScalar, bool>::value) && is_same<LhsScalar, RhsScalar>::value &&
206 packet_traits<LhsScalar>::HasCmp
210template <
typename LhsScalar,
typename RhsScalar,
bool UseTypedComparators>
211struct typed_cmp_helper {
212 static constexpr bool SameType = is_same<LhsScalar, RhsScalar>::value;
213 static constexpr bool IsNumeric = is_arithmetic<typename NumTraits<LhsScalar>::Real>::value;
214 static constexpr bool UseTyped = UseTypedComparators && SameType && IsNumeric;
215 using type =
typename conditional<UseTyped, LhsScalar, bool>::type;
218template <
typename LhsScalar,
typename RhsScalar,
bool UseTypedComparators>
219using cmp_return_t =
typename typed_cmp_helper<LhsScalar, RhsScalar, UseTypedComparators>::type;
221template <
typename LhsScalar,
typename RhsScalar,
bool UseTypedComparators>
222struct scalar_cmp_op<LhsScalar, RhsScalar, cmp_EQ, UseTypedComparators> : binary_op_base<LhsScalar, RhsScalar> {
223 using result_type = cmp_return_t<LhsScalar, RhsScalar, UseTypedComparators>;
224 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator()(
const LhsScalar& a,
const RhsScalar& b)
const {
225 return a == b ? result_type(1) : result_type(0);
227 template <
typename Packet>
228 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(
const Packet& a,
const Packet& b)
const {
229 const Packet cst_one = pset1<Packet>(result_type(1));
230 return pand(pcmp_eq(a, b), cst_one);
234template <
typename LhsScalar,
typename RhsScalar,
bool UseTypedComparators>
235struct scalar_cmp_op<LhsScalar, RhsScalar, cmp_LT, UseTypedComparators> : binary_op_base<LhsScalar, RhsScalar> {
236 using result_type = cmp_return_t<LhsScalar, RhsScalar, UseTypedComparators>;
237 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator()(
const LhsScalar& a,
const RhsScalar& b)
const {
238 return a < b ? result_type(1) : result_type(0);
240 template <
typename Packet>
241 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(
const Packet& a,
const Packet& b)
const {
242 const Packet cst_one = pset1<Packet>(result_type(1));
243 return pand(pcmp_lt(a, b), cst_one);
247template <
typename LhsScalar,
typename RhsScalar,
bool UseTypedComparators>
248struct scalar_cmp_op<LhsScalar, RhsScalar, cmp_LE, UseTypedComparators> : binary_op_base<LhsScalar, RhsScalar> {
249 using result_type = cmp_return_t<LhsScalar, RhsScalar, UseTypedComparators>;
250 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator()(
const LhsScalar& a,
const RhsScalar& b)
const {
251 return a <= b ? result_type(1) : result_type(0);
253 template <
typename Packet>
254 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(
const Packet& a,
const Packet& b)
const {
255 const Packet cst_one = pset1<Packet>(result_type(1));
256 return pand(cst_one, pcmp_le(a, b));
260template <
typename LhsScalar,
typename RhsScalar,
bool UseTypedComparators>
261struct scalar_cmp_op<LhsScalar, RhsScalar, cmp_GT, UseTypedComparators> : binary_op_base<LhsScalar, RhsScalar> {
262 using result_type = cmp_return_t<LhsScalar, RhsScalar, UseTypedComparators>;
263 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator()(
const LhsScalar& a,
const RhsScalar& b)
const {
264 return a > b ? result_type(1) : result_type(0);
266 template <
typename Packet>
267 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(
const Packet& a,
const Packet& b)
const {
268 const Packet cst_one = pset1<Packet>(result_type(1));
269 return pand(cst_one, pcmp_lt(b, a));
273template <
typename LhsScalar,
typename RhsScalar,
bool UseTypedComparators>
274struct scalar_cmp_op<LhsScalar, RhsScalar, cmp_GE, UseTypedComparators> : binary_op_base<LhsScalar, RhsScalar> {
275 using result_type = cmp_return_t<LhsScalar, RhsScalar, UseTypedComparators>;
276 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator()(
const LhsScalar& a,
const RhsScalar& b)
const {
277 return a >= b ? result_type(1) : result_type(0);
279 template <
typename Packet>
280 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(
const Packet& a,
const Packet& b)
const {
281 const Packet cst_one = pset1<Packet>(result_type(1));
282 return pand(cst_one, pcmp_le(b, a));
286template <
typename LhsScalar,
typename RhsScalar,
bool UseTypedComparators>
287struct scalar_cmp_op<LhsScalar, RhsScalar, cmp_UNORD, UseTypedComparators> : binary_op_base<LhsScalar, RhsScalar> {
288 using result_type = cmp_return_t<LhsScalar, RhsScalar, UseTypedComparators>;
289 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator()(
const LhsScalar& a,
const RhsScalar& b)
const {
290 return !(a <= b || b <= a) ? result_type(1) : result_type(0);
292 template <
typename Packet>
293 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(
const Packet& a,
const Packet& b)
const {
294 const Packet cst_one = pset1<Packet>(result_type(1));
295 return pandnot(cst_one, por(pcmp_le(a, b), pcmp_le(b, a)));
299template <
typename LhsScalar,
typename RhsScalar,
bool UseTypedComparators>
300struct scalar_cmp_op<LhsScalar, RhsScalar, cmp_NEQ, UseTypedComparators> : binary_op_base<LhsScalar, RhsScalar> {
301 using result_type = cmp_return_t<LhsScalar, RhsScalar, UseTypedComparators>;
302 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator()(
const LhsScalar& a,
const RhsScalar& b)
const {
303 return a != b ? result_type(1) : result_type(0);
305 template <
typename Packet>
306 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(
const Packet& a,
const Packet& b)
const {
307 const Packet cst_one = pset1<Packet>(result_type(1));
308 return pandnot(cst_one, pcmp_eq(a, b));
317template <
typename Scalar>
318struct scalar_hypot_op<Scalar, Scalar> : binary_op_base<Scalar, Scalar> {
319 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const Scalar operator()(
const Scalar& x,
const Scalar& y)
const {
325 return internal::positive_real_hypot(x, y);
328template <
typename Scalar>
329struct functor_traits<scalar_hypot_op<Scalar, Scalar>> {
331 Cost = 3 * NumTraits<Scalar>::AddCost + 2 * NumTraits<Scalar>::MulCost + 2 * scalar_div_cost<Scalar, false>::value,
340template <
typename Scalar,
typename Exponent>
341struct scalar_pow_op : binary_op_base<Scalar, Exponent> {
342 typedef typename ScalarBinaryOpTraits<Scalar, Exponent, scalar_pow_op>::ReturnType result_type;
343#ifdef EIGEN_SCALAR_BINARY_OP_PLUGIN
345 typedef Scalar LhsScalar;
346 typedef Exponent RhsScalar;
347 EIGEN_SCALAR_BINARY_OP_PLUGIN
351 EIGEN_DEVICE_FUNC
inline result_type operator()(
const Scalar& a,
const Exponent& b)
const {
352 return numext::pow(a, b);
355 template <
typename Packet>
356 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const Packet packetOp(
const Packet& a,
const Packet& b)
const {
357 return generic_pow(a, b);
361template <
typename Scalar,
typename Exponent>
362struct functor_traits<scalar_pow_op<Scalar, Exponent>> {
364 Cost = 5 * NumTraits<Scalar>::MulCost,
365 PacketAccess = (!NumTraits<Scalar>::IsComplex && !NumTraits<Scalar>::IsInteger && packet_traits<Scalar>::HasExp &&
366 packet_traits<Scalar>::HasLog && packet_traits<Scalar>::HasRound && packet_traits<Scalar>::HasCmp &&
369 !is_same<Scalar, half>::value && !is_same<Scalar, bfloat16>::value)
380template <
typename LhsScalar,
typename RhsScalar>
381struct scalar_difference_op : binary_op_base<LhsScalar, RhsScalar> {
382 typedef typename ScalarBinaryOpTraits<LhsScalar, RhsScalar, scalar_difference_op>::ReturnType result_type;
383#ifdef EIGEN_SCALAR_BINARY_OP_PLUGIN
384 scalar_difference_op(){EIGEN_SCALAR_BINARY_OP_PLUGIN}
386 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const result_type
387 operator()(
const LhsScalar& a,
const RhsScalar& b)
const {
390 template <
typename Packet>
391 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const Packet packetOp(
const Packet& a,
const Packet& b)
const {
392 return internal::psub(a, b);
395template <
typename LhsScalar,
typename RhsScalar>
396struct functor_traits<scalar_difference_op<LhsScalar, RhsScalar>> {
398 Cost = (int(NumTraits<LhsScalar>::AddCost) + int(NumTraits<RhsScalar>::AddCost)) / 2,
400 is_same<LhsScalar, RhsScalar>::value && packet_traits<LhsScalar>::HasSub && packet_traits<RhsScalar>::HasSub
404template <typename Packet, bool IsInteger = NumTraits<typename unpacket_traits<Packet>::type>::IsInteger>
405struct maybe_raise_div_by_zero {
406 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void run(Packet x) { EIGEN_UNUSED_VARIABLE(x); }
409#ifndef EIGEN_GPU_COMPILE_PHASE
410template <
typename Packet>
411struct maybe_raise_div_by_zero<Packet, true> {
412 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void run(Packet x) {
413 if (EIGEN_PREDICT_FALSE(predux_any(pcmp_eq(x, pzero(x))))) {
416 volatile typename unpacket_traits<Packet>::type zero = 0;
417 volatile typename unpacket_traits<Packet>::type val = 1;
429template <
typename LhsScalar,
typename RhsScalar>
430struct scalar_quotient_op : binary_op_base<LhsScalar, RhsScalar> {
431 typedef typename ScalarBinaryOpTraits<LhsScalar, RhsScalar, scalar_quotient_op>::ReturnType result_type;
432#ifdef EIGEN_SCALAR_BINARY_OP_PLUGIN
433 scalar_quotient_op(){EIGEN_SCALAR_BINARY_OP_PLUGIN}
435 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const result_type
436 operator()(
const LhsScalar& a,
const RhsScalar& b)
const {
439 template <
typename Packet>
440 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const Packet packetOp(
const Packet& a,
const Packet& b)
const {
441 maybe_raise_div_by_zero<Packet>::run(b);
442 return internal::pdiv(a, b);
445template <
typename LhsScalar,
typename RhsScalar>
446struct functor_traits<scalar_quotient_op<LhsScalar, RhsScalar>> {
447 typedef typename scalar_quotient_op<LhsScalar, RhsScalar>::result_type result_type;
450 is_same<LhsScalar, RhsScalar>::value && packet_traits<LhsScalar>::HasDiv && packet_traits<RhsScalar>::HasDiv,
451 Cost = scalar_div_cost<result_type, PacketAccess>::value
460template <
typename Scalar>
461struct scalar_boolean_and_op {
462 using result_type = Scalar;
465 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar operator()(
const Scalar& a,
const Scalar& b)
const {
466 return (a != Scalar(0)) && (b != Scalar(0)) ? Scalar(1) : Scalar(0);
468 template <
typename Packet>
469 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(
const Packet& a,
const Packet& b)
const {
470 const Packet cst_one = pset1<Packet>(Scalar(1));
472 Packet not_a = pcmp_eq(a, pzero(a));
473 Packet not_b = pcmp_eq(b, pzero(b));
474 Packet a_nand_b = por(not_a, not_b);
475 return pandnot(cst_one, a_nand_b);
478template <
typename Scalar>
479struct functor_traits<scalar_boolean_and_op<Scalar>> {
480 enum { Cost = NumTraits<Scalar>::AddCost, PacketAccess = packet_traits<Scalar>::HasCmp };
488template <
typename Scalar>
489struct scalar_boolean_or_op {
490 using result_type = Scalar;
493 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar operator()(
const Scalar& a,
const Scalar& b)
const {
494 return (a != Scalar(0)) || (b != Scalar(0)) ? Scalar(1) : Scalar(0);
496 template <
typename Packet>
497 EIGEN_STRONG_INLINE Packet packetOp(
const Packet& a,
const Packet& b)
const {
498 const Packet cst_one = pset1<Packet>(Scalar(1));
501 Packet a_nor_b = pcmp_eq(por(a, b), pzero(a));
502 return pandnot(cst_one, a_nor_b);
505template <
typename Scalar>
506struct functor_traits<scalar_boolean_or_op<Scalar>> {
507 enum { Cost = NumTraits<Scalar>::AddCost, PacketAccess = packet_traits<Scalar>::HasCmp };
515template <
typename Scalar>
516struct scalar_boolean_xor_op {
517 using result_type = Scalar;
520 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar operator()(
const Scalar& a,
const Scalar& b)
const {
521 return (a != Scalar(0)) != (b != Scalar(0)) ? Scalar(1) : Scalar(0);
523 template <
typename Packet>
524 EIGEN_STRONG_INLINE Packet packetOp(
const Packet& a,
const Packet& b)
const {
525 const Packet cst_one = pset1<Packet>(Scalar(1));
527 Packet not_a = pcmp_eq(a, pzero(a));
528 Packet not_b = pcmp_eq(b, pzero(b));
529 Packet a_xor_b = pxor(not_a, not_b);
530 return pand(cst_one, a_xor_b);
533template <
typename Scalar>
534struct functor_traits<scalar_boolean_xor_op<Scalar>> {
535 enum { Cost = NumTraits<Scalar>::AddCost, PacketAccess = packet_traits<Scalar>::HasCmp };
538template <typename Scalar, bool IsComplex = NumTraits<Scalar>::IsComplex>
539struct bitwise_binary_impl {
540 static constexpr size_t Size =
sizeof(Scalar);
541 using uint_t =
typename numext::get_integer_by_size<Size>::unsigned_type;
542 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar run_and(
const Scalar& a,
const Scalar& b) {
543 uint_t a_as_uint = numext::bit_cast<uint_t, Scalar>(a);
544 uint_t b_as_uint = numext::bit_cast<uint_t, Scalar>(b);
545 uint_t result = a_as_uint & b_as_uint;
546 return numext::bit_cast<Scalar, uint_t>(result);
548 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar run_or(
const Scalar& a,
const Scalar& b) {
549 uint_t a_as_uint = numext::bit_cast<uint_t, Scalar>(a);
550 uint_t b_as_uint = numext::bit_cast<uint_t, Scalar>(b);
551 uint_t result = a_as_uint | b_as_uint;
552 return numext::bit_cast<Scalar, uint_t>(result);
554 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar run_xor(
const Scalar& a,
const Scalar& b) {
555 uint_t a_as_uint = numext::bit_cast<uint_t, Scalar>(a);
556 uint_t b_as_uint = numext::bit_cast<uint_t, Scalar>(b);
557 uint_t result = a_as_uint ^ b_as_uint;
558 return numext::bit_cast<Scalar, uint_t>(result);
562template <
typename Scalar>
563struct bitwise_binary_impl<Scalar, true> {
564 using Real =
typename NumTraits<Scalar>::Real;
565 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar run_and(
const Scalar& a,
const Scalar& b) {
566 Real real_result = bitwise_binary_impl<Real>::run_and(numext::real(a), numext::real(b));
567 Real imag_result = bitwise_binary_impl<Real>::run_and(numext::imag(a), numext::imag(b));
568 return Scalar(real_result, imag_result);
570 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar run_or(
const Scalar& a,
const Scalar& b) {
571 Real real_result = bitwise_binary_impl<Real>::run_or(numext::real(a), numext::real(b));
572 Real imag_result = bitwise_binary_impl<Real>::run_or(numext::imag(a), numext::imag(b));
573 return Scalar(real_result, imag_result);
575 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar run_xor(
const Scalar& a,
const Scalar& b) {
576 Real real_result = bitwise_binary_impl<Real>::run_xor(numext::real(a), numext::real(b));
577 Real imag_result = bitwise_binary_impl<Real>::run_xor(numext::imag(a), numext::imag(b));
578 return Scalar(real_result, imag_result);
587template <
typename Scalar>
588struct scalar_bitwise_and_op {
589 EIGEN_STATIC_ASSERT(!NumTraits<Scalar>::RequireInitialization,
590 BITWISE OPERATIONS MAY ONLY BE PERFORMED ON PLAIN DATA TYPES)
591 EIGEN_STATIC_ASSERT((!internal::is_same<Scalar, bool>::value), DONT USE BITWISE OPS ON BOOLEAN TYPES)
592 using result_type = Scalar;
593 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar operator()(
const Scalar& a,
const Scalar& b)
const {
594 return bitwise_binary_impl<Scalar>::run_and(a, b);
596 template <
typename Packet>
597 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(
const Packet& a,
const Packet& b)
const {
601template <
typename Scalar>
602struct functor_traits<scalar_bitwise_and_op<Scalar>> {
603 enum { Cost = NumTraits<Scalar>::AddCost, PacketAccess =
true };
611template <
typename Scalar>
612struct scalar_bitwise_or_op {
613 EIGEN_STATIC_ASSERT(!NumTraits<Scalar>::RequireInitialization,
614 BITWISE OPERATIONS MAY ONLY BE PERFORMED ON PLAIN DATA TYPES)
615 EIGEN_STATIC_ASSERT((!internal::is_same<Scalar, bool>::value), DONT USE BITWISE OPS ON BOOLEAN TYPES)
616 using result_type = Scalar;
617 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar operator()(
const Scalar& a,
const Scalar& b)
const {
618 return bitwise_binary_impl<Scalar>::run_or(a, b);
620 template <
typename Packet>
621 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(
const Packet& a,
const Packet& b)
const {
625template <
typename Scalar>
626struct functor_traits<scalar_bitwise_or_op<Scalar>> {
627 enum { Cost = NumTraits<Scalar>::AddCost, PacketAccess =
true };
635template <
typename Scalar>
636struct scalar_bitwise_xor_op {
637 EIGEN_STATIC_ASSERT(!NumTraits<Scalar>::RequireInitialization,
638 BITWISE OPERATIONS MAY ONLY BE PERFORMED ON PLAIN DATA TYPES)
639 EIGEN_STATIC_ASSERT((!internal::is_same<Scalar, bool>::value), DONT USE BITWISE OPS ON BOOLEAN TYPES)
640 using result_type = Scalar;
641 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar operator()(
const Scalar& a,
const Scalar& b)
const {
642 return bitwise_binary_impl<Scalar>::run_xor(a, b);
644 template <
typename Packet>
645 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(
const Packet& a,
const Packet& b)
const {
649template <
typename Scalar>
650struct functor_traits<scalar_bitwise_xor_op<Scalar>> {
651 enum { Cost = NumTraits<Scalar>::AddCost, PacketAccess =
true };
659template <
typename LhsScalar,
typename RhsScalar>
660struct scalar_absolute_difference_op : binary_op_base<LhsScalar, RhsScalar> {
661 typedef typename ScalarBinaryOpTraits<LhsScalar, RhsScalar, scalar_absolute_difference_op>::ReturnType result_type;
662#ifdef EIGEN_SCALAR_BINARY_OP_PLUGIN
663 scalar_absolute_difference_op(){EIGEN_SCALAR_BINARY_OP_PLUGIN}
665 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const result_type
666 operator()(
const LhsScalar& a,
const RhsScalar& b)
const {
667 return numext::absdiff(a, b);
669 template <
typename Packet>
670 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const Packet packetOp(
const Packet& a,
const Packet& b)
const {
671 return internal::pabsdiff(a, b);
674template <
typename LhsScalar,
typename RhsScalar>
675struct functor_traits<scalar_absolute_difference_op<LhsScalar, RhsScalar>> {
677 Cost = (NumTraits<LhsScalar>::AddCost + NumTraits<RhsScalar>::AddCost) / 2,
678 PacketAccess = is_same<LhsScalar, RhsScalar>::value && packet_traits<LhsScalar>::HasAbsDiff
682template <
typename LhsScalar,
typename RhsScalar>
683struct scalar_atan2_op {
684 using Scalar = LhsScalar;
686 static constexpr bool Enable =
687 is_same<LhsScalar, RhsScalar>::value && !NumTraits<Scalar>::IsInteger && !NumTraits<Scalar>::IsComplex;
688 EIGEN_STATIC_ASSERT(Enable,
"LhsScalar and RhsScalar must be the same non-integer, non-complex type")
690 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar operator()(const Scalar& y, const Scalar& x)
const {
691 return numext::atan2(y, x);
693 template <
typename Packet>
694 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(
const Packet& y,
const Packet& x)
const {
695 return internal::patan2(y, x);
699template <
typename LhsScalar,
typename RhsScalar>
700struct functor_traits<scalar_atan2_op<LhsScalar, RhsScalar>> {
701 using Scalar = LhsScalar;
703 PacketAccess = is_same<LhsScalar, RhsScalar>::value && packet_traits<Scalar>::HasATan &&
704 packet_traits<Scalar>::HasDiv && !NumTraits<Scalar>::IsInteger && !NumTraits<Scalar>::IsComplex,
705 Cost = int(scalar_div_cost<Scalar, PacketAccess>::value) + int(functor_traits<scalar_atan_op<Scalar>>::Cost)
715template <
typename BinaryOp>
716struct bind1st_op : BinaryOp {
717 typedef typename BinaryOp::first_argument_type first_argument_type;
718 typedef typename BinaryOp::second_argument_type second_argument_type;
719 typedef typename BinaryOp::result_type result_type;
721 EIGEN_DEVICE_FUNC
explicit bind1st_op(
const first_argument_type& val) : m_value(val) {}
723 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const result_type operator()(
const second_argument_type& b)
const {
724 return BinaryOp::operator()(m_value, b);
727 template <
typename Packet>
728 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const Packet packetOp(
const Packet& b)
const {
729 return BinaryOp::packetOp(internal::pset1<Packet>(m_value), b);
732 first_argument_type m_value;
734template <
typename BinaryOp>
735struct functor_traits<bind1st_op<BinaryOp>> : functor_traits<BinaryOp> {};
737template <
typename BinaryOp>
738struct bind2nd_op : BinaryOp {
739 typedef typename BinaryOp::first_argument_type first_argument_type;
740 typedef typename BinaryOp::second_argument_type second_argument_type;
741 typedef typename BinaryOp::result_type result_type;
743 EIGEN_DEVICE_FUNC
explicit bind2nd_op(
const second_argument_type& val) : m_value(val) {}
745 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const result_type operator()(
const first_argument_type& a)
const {
746 return BinaryOp::operator()(a, m_value);
749 template <
typename Packet>
750 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const Packet packetOp(
const Packet& a)
const {
751 return BinaryOp::packetOp(a, internal::pset1<Packet>(m_value));
754 second_argument_type m_value;
756template <
typename BinaryOp>
757struct functor_traits<bind2nd_op<BinaryOp>> : functor_traits<BinaryOp> {};
Namespace containing all symbols from the Eigen library.
Definition Core:137