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 scalar_cmp_op<LhsScalar, RhsScalar, cmp_EQ, UseTypedComparators> : binary_op_base<LhsScalar, RhsScalar> {
212 using result_type = std::conditional_t<UseTypedComparators, LhsScalar, bool>;
213 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator()(
const LhsScalar& a,
const RhsScalar& b)
const {
214 return a == b ? result_type(1) : result_type(0);
216 template <
typename Packet>
217 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(
const Packet& a,
const Packet& b)
const {
218 const Packet cst_one = pset1<Packet>(result_type(1));
219 return pand(pcmp_eq(a, b), cst_one);
223template <
typename LhsScalar,
typename RhsScalar,
bool UseTypedComparators>
224struct scalar_cmp_op<LhsScalar, RhsScalar, cmp_LT, UseTypedComparators> : binary_op_base<LhsScalar, RhsScalar> {
225 using result_type = std::conditional_t<UseTypedComparators, LhsScalar, bool>;
226 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator()(
const LhsScalar& a,
const RhsScalar& b)
const {
227 return a < b ? result_type(1) : result_type(0);
229 template <
typename Packet>
230 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(
const Packet& a,
const Packet& b)
const {
231 const Packet cst_one = pset1<Packet>(result_type(1));
232 return pand(pcmp_lt(a, b), cst_one);
236template <
typename LhsScalar,
typename RhsScalar,
bool UseTypedComparators>
237struct scalar_cmp_op<LhsScalar, RhsScalar, cmp_LE, UseTypedComparators> : binary_op_base<LhsScalar, RhsScalar> {
238 using result_type = std::conditional_t<UseTypedComparators, LhsScalar, bool>;
239 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator()(
const LhsScalar& a,
const RhsScalar& b)
const {
240 return a <= b ? result_type(1) : result_type(0);
242 template <
typename Packet>
243 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(
const Packet& a,
const Packet& b)
const {
244 const Packet cst_one = pset1<Packet>(result_type(1));
245 return pand(cst_one, pcmp_le(a, b));
249template <
typename LhsScalar,
typename RhsScalar,
bool UseTypedComparators>
250struct scalar_cmp_op<LhsScalar, RhsScalar, cmp_GT, UseTypedComparators> : binary_op_base<LhsScalar, RhsScalar> {
251 using result_type = std::conditional_t<UseTypedComparators, LhsScalar, bool>;
252 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator()(
const LhsScalar& a,
const RhsScalar& b)
const {
253 return a > b ? result_type(1) : result_type(0);
255 template <
typename Packet>
256 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(
const Packet& a,
const Packet& b)
const {
257 const Packet cst_one = pset1<Packet>(result_type(1));
258 return pand(cst_one, pcmp_lt(b, a));
262template <
typename LhsScalar,
typename RhsScalar,
bool UseTypedComparators>
263struct scalar_cmp_op<LhsScalar, RhsScalar, cmp_GE, UseTypedComparators> : binary_op_base<LhsScalar, RhsScalar> {
264 using result_type = std::conditional_t<UseTypedComparators, LhsScalar, bool>;
265 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator()(
const LhsScalar& a,
const RhsScalar& b)
const {
266 return a >= b ? result_type(1) : result_type(0);
268 template <
typename Packet>
269 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(
const Packet& a,
const Packet& b)
const {
270 const Packet cst_one = pset1<Packet>(result_type(1));
271 return pand(cst_one, pcmp_le(b, a));
275template <
typename LhsScalar,
typename RhsScalar,
bool UseTypedComparators>
276struct scalar_cmp_op<LhsScalar, RhsScalar, cmp_UNORD, UseTypedComparators> : binary_op_base<LhsScalar, RhsScalar> {
277 using result_type = std::conditional_t<UseTypedComparators, LhsScalar, bool>;
278 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator()(
const LhsScalar& a,
const RhsScalar& b)
const {
279 return !(a <= b || b <= a) ? result_type(1) : result_type(0);
281 template <
typename Packet>
282 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(
const Packet& a,
const Packet& b)
const {
283 const Packet cst_one = pset1<Packet>(result_type(1));
284 return pandnot(cst_one, por(pcmp_le(a, b), pcmp_le(b, a)));
288template <
typename LhsScalar,
typename RhsScalar,
bool UseTypedComparators>
289struct scalar_cmp_op<LhsScalar, RhsScalar, cmp_NEQ, UseTypedComparators> : binary_op_base<LhsScalar, RhsScalar> {
290 using result_type = std::conditional_t<UseTypedComparators, LhsScalar, bool>;
291 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator()(
const LhsScalar& a,
const RhsScalar& b)
const {
292 return a != b ? result_type(1) : result_type(0);
294 template <
typename Packet>
295 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(
const Packet& a,
const Packet& b)
const {
296 const Packet cst_one = pset1<Packet>(result_type(1));
297 return pandnot(cst_one, pcmp_eq(a, b));
306template <
typename Scalar>
307struct scalar_hypot_op<Scalar, Scalar> : binary_op_base<Scalar, Scalar> {
308 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const Scalar operator()(
const Scalar& x,
const Scalar& y)
const {
314 return internal::positive_real_hypot(x, y);
317template <
typename Scalar>
318struct functor_traits<scalar_hypot_op<Scalar, Scalar>> {
320 Cost = 3 * NumTraits<Scalar>::AddCost + 2 * NumTraits<Scalar>::MulCost + 2 * scalar_div_cost<Scalar, false>::value,
329template <
typename Scalar,
typename Exponent>
330struct scalar_pow_op : binary_op_base<Scalar, Exponent> {
331 typedef typename ScalarBinaryOpTraits<Scalar, Exponent, scalar_pow_op>::ReturnType result_type;
332#ifdef EIGEN_SCALAR_BINARY_OP_PLUGIN
334 typedef Scalar LhsScalar;
335 typedef Exponent RhsScalar;
336 EIGEN_SCALAR_BINARY_OP_PLUGIN
340 EIGEN_DEVICE_FUNC
inline result_type operator()(
const Scalar& a,
const Exponent& b)
const {
341 return numext::pow(a, b);
344 template <
typename Packet>
345 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const Packet packetOp(
const Packet& a,
const Packet& b)
const {
346 return generic_pow(a, b);
350template <
typename Scalar,
typename Exponent>
351struct functor_traits<scalar_pow_op<Scalar, Exponent>> {
353 Cost = 5 * NumTraits<Scalar>::MulCost,
354 PacketAccess = (!NumTraits<Scalar>::IsComplex && !NumTraits<Scalar>::IsInteger && packet_traits<Scalar>::HasPow)
365template <
typename LhsScalar,
typename RhsScalar>
366struct scalar_difference_op : binary_op_base<LhsScalar, RhsScalar> {
367 typedef typename ScalarBinaryOpTraits<LhsScalar, RhsScalar, scalar_difference_op>::ReturnType result_type;
368#ifdef EIGEN_SCALAR_BINARY_OP_PLUGIN
369 scalar_difference_op(){EIGEN_SCALAR_BINARY_OP_PLUGIN}
371 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const result_type
372 operator()(
const LhsScalar& a,
const RhsScalar& b)
const {
375 template <
typename Packet>
376 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const Packet packetOp(
const Packet& a,
const Packet& b)
const {
377 return internal::psub(a, b);
380template <
typename LhsScalar,
typename RhsScalar>
381struct functor_traits<scalar_difference_op<LhsScalar, RhsScalar>> {
383 Cost = (int(NumTraits<LhsScalar>::AddCost) + int(NumTraits<RhsScalar>::AddCost)) / 2,
385 is_same<LhsScalar, RhsScalar>::value && packet_traits<LhsScalar>::HasSub && packet_traits<RhsScalar>::HasSub
389template <typename Packet, bool IsInteger = NumTraits<typename unpacket_traits<Packet>::type>::IsInteger>
390struct maybe_raise_div_by_zero {
391 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void run(Packet x) { EIGEN_UNUSED_VARIABLE(x); }
394#ifndef EIGEN_GPU_COMPILE_PHASE
395template <
typename Packet>
396struct maybe_raise_div_by_zero<Packet, true> {
397 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void run(Packet x) {
398 if (EIGEN_PREDICT_FALSE(predux_any(pcmp_eq(x, pzero(x))))) {
401 volatile typename unpacket_traits<Packet>::type zero = 0;
402 volatile typename unpacket_traits<Packet>::type val = 1;
414template <
typename LhsScalar,
typename RhsScalar>
415struct scalar_quotient_op : binary_op_base<LhsScalar, RhsScalar> {
416 typedef typename ScalarBinaryOpTraits<LhsScalar, RhsScalar, scalar_quotient_op>::ReturnType result_type;
417#ifdef EIGEN_SCALAR_BINARY_OP_PLUGIN
418 scalar_quotient_op(){EIGEN_SCALAR_BINARY_OP_PLUGIN}
420 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const result_type
421 operator()(
const LhsScalar& a,
const RhsScalar& b)
const {
424 template <
typename Packet>
425 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const Packet packetOp(
const Packet& a,
const Packet& b)
const {
426 return internal::pdiv(a, b);
429template <
typename LhsScalar,
typename RhsScalar>
430struct functor_traits<scalar_quotient_op<LhsScalar, RhsScalar>> {
431 typedef typename scalar_quotient_op<LhsScalar, RhsScalar>::result_type result_type;
434 is_same<LhsScalar, RhsScalar>::value && packet_traits<LhsScalar>::HasDiv && packet_traits<RhsScalar>::HasDiv,
435 Cost = scalar_div_cost<result_type, PacketAccess>::value
444template <
typename Scalar>
445struct scalar_boolean_and_op {
446 using result_type = Scalar;
449 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar operator()(
const Scalar& a,
const Scalar& b)
const {
450 return (a != Scalar(0)) && (b != Scalar(0)) ? Scalar(1) : Scalar(0);
452 template <
typename Packet>
453 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(
const Packet& a,
const Packet& b)
const {
454 const Packet cst_one = pset1<Packet>(Scalar(1));
456 Packet not_a = pcmp_eq(a, pzero(a));
457 Packet not_b = pcmp_eq(b, pzero(b));
458 Packet a_nand_b = por(not_a, not_b);
459 return pandnot(cst_one, a_nand_b);
462template <
typename Scalar>
463struct functor_traits<scalar_boolean_and_op<Scalar>> {
464 enum { Cost = NumTraits<Scalar>::AddCost, PacketAccess = packet_traits<Scalar>::HasCmp };
472template <
typename Scalar>
473struct scalar_boolean_or_op {
474 using result_type = Scalar;
477 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar operator()(
const Scalar& a,
const Scalar& b)
const {
478 return (a != Scalar(0)) || (b != Scalar(0)) ? Scalar(1) : Scalar(0);
480 template <
typename Packet>
481 EIGEN_STRONG_INLINE Packet packetOp(
const Packet& a,
const Packet& b)
const {
482 const Packet cst_one = pset1<Packet>(Scalar(1));
485 Packet a_nor_b = pcmp_eq(por(a, b), pzero(a));
486 return pandnot(cst_one, a_nor_b);
489template <
typename Scalar>
490struct functor_traits<scalar_boolean_or_op<Scalar>> {
491 enum { Cost = NumTraits<Scalar>::AddCost, PacketAccess = packet_traits<Scalar>::HasCmp };
499template <
typename Scalar>
500struct scalar_boolean_xor_op {
501 using result_type = Scalar;
504 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar operator()(
const Scalar& a,
const Scalar& b)
const {
505 return (a != Scalar(0)) != (b != Scalar(0)) ? Scalar(1) : Scalar(0);
507 template <
typename Packet>
508 EIGEN_STRONG_INLINE Packet packetOp(
const Packet& a,
const Packet& b)
const {
509 const Packet cst_one = pset1<Packet>(Scalar(1));
511 Packet not_a = pcmp_eq(a, pzero(a));
512 Packet not_b = pcmp_eq(b, pzero(b));
513 Packet a_xor_b = pxor(not_a, not_b);
514 return pand(cst_one, a_xor_b);
517template <
typename Scalar>
518struct functor_traits<scalar_boolean_xor_op<Scalar>> {
519 enum { Cost = NumTraits<Scalar>::AddCost, PacketAccess = packet_traits<Scalar>::HasCmp };
522template <typename Scalar, bool IsComplex = NumTraits<Scalar>::IsComplex>
523struct bitwise_binary_impl {
524 static constexpr size_t Size =
sizeof(Scalar);
525 using uint_t =
typename numext::get_integer_by_size<Size>::unsigned_type;
526 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar run_and(
const Scalar& a,
const Scalar& b) {
527 uint_t a_as_uint = numext::bit_cast<uint_t, Scalar>(a);
528 uint_t b_as_uint = numext::bit_cast<uint_t, Scalar>(b);
529 uint_t result = a_as_uint & b_as_uint;
530 return numext::bit_cast<Scalar, uint_t>(result);
532 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar run_or(
const Scalar& a,
const Scalar& b) {
533 uint_t a_as_uint = numext::bit_cast<uint_t, Scalar>(a);
534 uint_t b_as_uint = numext::bit_cast<uint_t, Scalar>(b);
535 uint_t result = a_as_uint | b_as_uint;
536 return numext::bit_cast<Scalar, uint_t>(result);
538 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar run_xor(
const Scalar& a,
const Scalar& b) {
539 uint_t a_as_uint = numext::bit_cast<uint_t, Scalar>(a);
540 uint_t b_as_uint = numext::bit_cast<uint_t, Scalar>(b);
541 uint_t result = a_as_uint ^ b_as_uint;
542 return numext::bit_cast<Scalar, uint_t>(result);
546template <
typename Scalar>
547struct bitwise_binary_impl<Scalar, true> {
548 using Real =
typename NumTraits<Scalar>::Real;
549 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar run_and(
const Scalar& a,
const Scalar& b) {
550 Real real_result = bitwise_binary_impl<Real>::run_and(numext::real(a), numext::real(b));
551 Real imag_result = bitwise_binary_impl<Real>::run_and(numext::imag(a), numext::imag(b));
552 return Scalar(real_result, imag_result);
554 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar run_or(
const Scalar& a,
const Scalar& b) {
555 Real real_result = bitwise_binary_impl<Real>::run_or(numext::real(a), numext::real(b));
556 Real imag_result = bitwise_binary_impl<Real>::run_or(numext::imag(a), numext::imag(b));
557 return Scalar(real_result, imag_result);
559 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar run_xor(
const Scalar& a,
const Scalar& b) {
560 Real real_result = bitwise_binary_impl<Real>::run_xor(numext::real(a), numext::real(b));
561 Real imag_result = bitwise_binary_impl<Real>::run_xor(numext::imag(a), numext::imag(b));
562 return Scalar(real_result, imag_result);
571template <
typename Scalar>
572struct scalar_bitwise_and_op {
573 EIGEN_STATIC_ASSERT(!NumTraits<Scalar>::RequireInitialization,
574 BITWISE OPERATIONS MAY ONLY BE PERFORMED ON PLAIN DATA TYPES)
575 EIGEN_STATIC_ASSERT((!internal::is_same<Scalar, bool>::value), DONT USE BITWISE OPS ON BOOLEAN TYPES)
576 using result_type = Scalar;
577 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar operator()(
const Scalar& a,
const Scalar& b)
const {
578 return bitwise_binary_impl<Scalar>::run_and(a, b);
580 template <
typename Packet>
581 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(
const Packet& a,
const Packet& b)
const {
585template <
typename Scalar>
586struct functor_traits<scalar_bitwise_and_op<Scalar>> {
587 enum { Cost = NumTraits<Scalar>::AddCost, PacketAccess =
true };
595template <
typename Scalar>
596struct scalar_bitwise_or_op {
597 EIGEN_STATIC_ASSERT(!NumTraits<Scalar>::RequireInitialization,
598 BITWISE OPERATIONS MAY ONLY BE PERFORMED ON PLAIN DATA TYPES)
599 EIGEN_STATIC_ASSERT((!internal::is_same<Scalar, bool>::value), DONT USE BITWISE OPS ON BOOLEAN TYPES)
600 using result_type = Scalar;
601 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar operator()(
const Scalar& a,
const Scalar& b)
const {
602 return bitwise_binary_impl<Scalar>::run_or(a, b);
604 template <
typename Packet>
605 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(
const Packet& a,
const Packet& b)
const {
609template <
typename Scalar>
610struct functor_traits<scalar_bitwise_or_op<Scalar>> {
611 enum { Cost = NumTraits<Scalar>::AddCost, PacketAccess =
true };
619template <
typename Scalar>
620struct scalar_bitwise_xor_op {
621 EIGEN_STATIC_ASSERT(!NumTraits<Scalar>::RequireInitialization,
622 BITWISE OPERATIONS MAY ONLY BE PERFORMED ON PLAIN DATA TYPES)
623 EIGEN_STATIC_ASSERT((!internal::is_same<Scalar, bool>::value), DONT USE BITWISE OPS ON BOOLEAN TYPES)
624 using result_type = Scalar;
625 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar operator()(
const Scalar& a,
const Scalar& b)
const {
626 return bitwise_binary_impl<Scalar>::run_xor(a, b);
628 template <
typename Packet>
629 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(
const Packet& a,
const Packet& b)
const {
633template <
typename Scalar>
634struct functor_traits<scalar_bitwise_xor_op<Scalar>> {
635 enum { Cost = NumTraits<Scalar>::AddCost, PacketAccess =
true };
643template <
typename LhsScalar,
typename RhsScalar>
644struct scalar_absolute_difference_op : binary_op_base<LhsScalar, RhsScalar> {
645 typedef typename ScalarBinaryOpTraits<LhsScalar, RhsScalar, scalar_absolute_difference_op>::ReturnType result_type;
646#ifdef EIGEN_SCALAR_BINARY_OP_PLUGIN
647 scalar_absolute_difference_op(){EIGEN_SCALAR_BINARY_OP_PLUGIN}
649 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const result_type
650 operator()(
const LhsScalar& a,
const RhsScalar& b)
const {
651 return numext::absdiff(a, b);
653 template <
typename Packet>
654 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const Packet packetOp(
const Packet& a,
const Packet& b)
const {
655 return internal::pabsdiff(a, b);
658template <
typename LhsScalar,
typename RhsScalar>
659struct functor_traits<scalar_absolute_difference_op<LhsScalar, RhsScalar>> {
661 Cost = (NumTraits<LhsScalar>::AddCost + NumTraits<RhsScalar>::AddCost) / 2,
662 PacketAccess = is_same<LhsScalar, RhsScalar>::value && packet_traits<LhsScalar>::HasAbsDiff
666template <
typename LhsScalar,
typename RhsScalar>
667struct scalar_atan2_op {
668 using Scalar = LhsScalar;
670 static constexpr bool Enable =
671 is_same<LhsScalar, RhsScalar>::value && !NumTraits<Scalar>::IsInteger && !NumTraits<Scalar>::IsComplex;
672 EIGEN_STATIC_ASSERT(Enable,
"LhsScalar and RhsScalar must be the same non-integer, non-complex type")
674 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar operator()(const Scalar& y, const Scalar& x)
const {
675 return numext::atan2(y, x);
677 template <
typename Packet>
678 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(
const Packet& y,
const Packet& x)
const {
679 return internal::patan2(y, x);
683template <
typename LhsScalar,
typename RhsScalar>
684struct functor_traits<scalar_atan2_op<LhsScalar, RhsScalar>> {
685 using Scalar = LhsScalar;
687 PacketAccess = is_same<LhsScalar, RhsScalar>::value && packet_traits<Scalar>::HasATan &&
688 packet_traits<Scalar>::HasDiv && !NumTraits<Scalar>::IsInteger && !NumTraits<Scalar>::IsComplex,
689 Cost = int(scalar_div_cost<Scalar, PacketAccess>::value) + int(functor_traits<scalar_atan_op<Scalar>>::Cost)
699template <
typename BinaryOp>
700struct bind1st_op : BinaryOp {
701 typedef typename BinaryOp::first_argument_type first_argument_type;
702 typedef typename BinaryOp::second_argument_type second_argument_type;
703 typedef typename BinaryOp::result_type result_type;
705 EIGEN_DEVICE_FUNC
explicit bind1st_op(
const first_argument_type& val) : m_value(val) {}
707 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const result_type operator()(
const second_argument_type& b)
const {
708 return BinaryOp::operator()(m_value, b);
711 template <
typename Packet>
712 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const Packet packetOp(
const Packet& b)
const {
713 return BinaryOp::packetOp(internal::pset1<Packet>(m_value), b);
716 first_argument_type m_value;
718template <
typename BinaryOp>
719struct functor_traits<bind1st_op<BinaryOp>> : functor_traits<BinaryOp> {};
721template <
typename BinaryOp>
722struct bind2nd_op : BinaryOp {
723 typedef typename BinaryOp::first_argument_type first_argument_type;
724 typedef typename BinaryOp::second_argument_type second_argument_type;
725 typedef typename BinaryOp::result_type result_type;
727 EIGEN_DEVICE_FUNC
explicit bind2nd_op(
const second_argument_type& val) : m_value(val) {}
729 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const result_type operator()(
const first_argument_type& a)
const {
730 return BinaryOp::operator()(a, m_value);
733 template <
typename Packet>
734 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const Packet packetOp(
const Packet& a)
const {
735 return BinaryOp::packetOp(a, internal::pset1<Packet>(m_value));
738 second_argument_type m_value;
740template <
typename BinaryOp>
741struct functor_traits<bind2nd_op<BinaryOp>> : functor_traits<BinaryOp> {};
Namespace containing all symbols from the Eigen library.
Definition B01_Experimental.dox:1