25 #ifndef EIGEN_FUNCTORS_H
26 #define EIGEN_FUNCTORS_H
39 template<
typename Scalar>
struct scalar_sum_op {
41 EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b)
const {
return a + b; }
42 template<
typename Packet>
45 template<
typename Packet>
49 template<
typename Scalar>
50 struct functor_traits<scalar_sum_op<Scalar> > {
53 PacketAccess = packet_traits<Scalar>::HasAdd
62 template<
typename LhsScalar,
typename RhsScalar>
struct scalar_product_op {
65 Vectorizable = is_same<LhsScalar,RhsScalar>::value && packet_traits<LhsScalar>::HasMul && packet_traits<RhsScalar>::HasMul
67 typedef typename scalar_product_traits<LhsScalar,RhsScalar>::ReturnType result_type;
69 EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b)
const {
return a * b; }
70 template<
typename Packet>
73 template<
typename Packet>
77 template<
typename LhsScalar,
typename RhsScalar>
78 struct functor_traits<scalar_product_op<LhsScalar,RhsScalar> > {
80 Cost = (NumTraits<LhsScalar>::MulCost + NumTraits<RhsScalar>::MulCost)/2,
81 PacketAccess = scalar_product_op<LhsScalar,RhsScalar>::Vectorizable
90 template<
typename LhsScalar,
typename RhsScalar>
struct scalar_conj_product_op {
96 typedef typename scalar_product_traits<LhsScalar,RhsScalar>::ReturnType result_type;
99 EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b)
const
100 {
return conj_helper<LhsScalar,RhsScalar,Conj,false>().
pmul(a,b); }
102 template<
typename Packet>
104 {
return conj_helper<Packet,Packet,Conj,false>().
pmul(a,b); }
106 template<
typename LhsScalar,
typename RhsScalar>
107 struct functor_traits<scalar_conj_product_op<LhsScalar,RhsScalar> > {
109 Cost = NumTraits<LhsScalar>::MulCost,
110 PacketAccess = internal::is_same<LhsScalar, RhsScalar>::value && packet_traits<LhsScalar>::HasMul
119 template<
typename Scalar>
struct scalar_min_op {
121 EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b)
const {
using std::min;
return (min)(a, b); }
122 template<
typename Packet>
125 template<
typename Packet>
129 template<
typename Scalar>
130 struct functor_traits<scalar_min_op<Scalar> > {
133 PacketAccess = packet_traits<Scalar>::HasMin
142 template<
typename Scalar>
struct scalar_max_op {
144 EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b)
const {
using std::max;
return (max)(a, b); }
145 template<
typename Packet>
148 template<
typename Packet>
152 template<
typename Scalar>
153 struct functor_traits<scalar_max_op<Scalar> > {
156 PacketAccess = packet_traits<Scalar>::HasMax
165 template<
typename Scalar>
struct scalar_hypot_op {
172 Scalar
p = (max)(_x, _y);
173 Scalar
q = (min)(_x, _y);
175 return p *
sqrt(Scalar(1) + qp*qp);
178 template<
typename Scalar>
179 struct functor_traits<scalar_hypot_op<Scalar> > {
186 template<
typename Scalar,
typename OtherScalar>
struct scalar_binary_pow_op {
188 inline Scalar operator() (const Scalar& a, const OtherScalar& b)
const {
return internal::pow(a, b); }
190 template<
typename Scalar,
typename OtherScalar>
191 struct functor_traits<scalar_binary_pow_op<Scalar,OtherScalar> > {
202 template<
typename Scalar>
struct scalar_difference_op {
204 EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b)
const {
return a - b; }
205 template<
typename Packet>
209 template<
typename Scalar>
210 struct functor_traits<scalar_difference_op<Scalar> > {
213 PacketAccess = packet_traits<Scalar>::HasSub
222 template<
typename Scalar>
struct scalar_quotient_op {
224 EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b)
const {
return a / b; }
225 template<
typename Packet>
229 template<
typename Scalar>
230 struct functor_traits<scalar_quotient_op<Scalar> > {
233 PacketAccess = packet_traits<Scalar>::HasDiv
242 struct scalar_boolean_and_op {
244 EIGEN_STRONG_INLINE bool operator() (const
bool& a, const
bool& b)
const {
return a && b; }
246 template<>
struct functor_traits<scalar_boolean_and_op> {
248 Cost = NumTraits<bool>::AddCost,
258 struct scalar_boolean_or_op {
260 EIGEN_STRONG_INLINE bool operator() (const
bool& a, const
bool& b)
const {
return a || b; }
262 template<>
struct functor_traits<scalar_boolean_or_op> {
264 Cost = NumTraits<bool>::AddCost,
276 template<
typename Scalar>
struct scalar_opposite_op {
279 template<
typename Packet>
283 template<
typename Scalar>
284 struct functor_traits<scalar_opposite_op<Scalar> >
287 PacketAccess = packet_traits<Scalar>::HasNegate };
295 template<
typename Scalar>
struct scalar_abs_op {
297 typedef typename NumTraits<Scalar>::Real result_type;
299 template<
typename Packet>
303 template<
typename Scalar>
304 struct functor_traits<scalar_abs_op<Scalar> >
308 PacketAccess = packet_traits<Scalar>::HasAbs
317 template<
typename Scalar>
struct scalar_abs2_op {
319 typedef typename NumTraits<Scalar>::Real result_type;
321 template<
typename Packet>
325 template<
typename Scalar>
326 struct functor_traits<scalar_abs2_op<Scalar> >
334 template<
typename Scalar>
struct scalar_conjugate_op {
337 template<
typename Packet>
340 template<
typename Scalar>
341 struct functor_traits<scalar_conjugate_op<Scalar> >
345 PacketAccess = packet_traits<Scalar>::HasConj
354 template<
typename Scalar,
typename NewType>
355 struct scalar_cast_op {
357 typedef NewType result_type;
358 EIGEN_STRONG_INLINE const NewType operator() (const Scalar& a)
const {
return cast<Scalar, NewType>(a); }
360 template<
typename Scalar,
typename NewType>
361 struct functor_traits<scalar_cast_op<Scalar,NewType> >
362 {
enum { Cost = is_same<Scalar, NewType>::value ? 0 : NumTraits<NewType>::AddCost, PacketAccess =
false }; };
369 template<
typename Scalar>
370 struct scalar_real_op {
372 typedef typename NumTraits<Scalar>::Real result_type;
375 template<
typename Scalar>
376 struct functor_traits<scalar_real_op<Scalar> >
377 {
enum { Cost = 0, PacketAccess =
false }; };
384 template<
typename Scalar>
385 struct scalar_imag_op {
387 typedef typename NumTraits<Scalar>::Real result_type;
390 template<
typename Scalar>
391 struct functor_traits<scalar_imag_op<Scalar> >
392 {
enum { Cost = 0, PacketAccess =
false }; };
399 template<
typename Scalar>
400 struct scalar_real_ref_op {
402 typedef typename NumTraits<Scalar>::Real result_type;
405 template<
typename Scalar>
406 struct functor_traits<scalar_real_ref_op<Scalar> >
407 {
enum { Cost = 0, PacketAccess =
false }; };
414 template<
typename Scalar>
415 struct scalar_imag_ref_op {
417 typedef typename NumTraits<Scalar>::Real result_type;
420 template<
typename Scalar>
421 struct functor_traits<scalar_imag_ref_op<Scalar> >
422 {
enum { Cost = 0, PacketAccess =
false }; };
430 template<
typename Scalar>
struct scalar_exp_op {
432 inline const Scalar operator() (const Scalar& a)
const {
return internal::exp(a); }
433 typedef typename packet_traits<Scalar>::type Packet;
434 inline Packet packetOp(
const Packet& a)
const {
return internal::pexp(a); }
436 template<
typename Scalar>
437 struct functor_traits<scalar_exp_op<Scalar> >
446 template<
typename Scalar>
struct scalar_log_op {
448 inline const Scalar operator() (const Scalar& a)
const {
return internal::log(a); }
449 typedef typename packet_traits<Scalar>::type Packet;
450 inline Packet packetOp(
const Packet& a)
const {
return internal::plog(a); }
452 template<
typename Scalar>
453 struct functor_traits<scalar_log_op<Scalar> >
469 template<
typename Scalar>
470 struct scalar_multiple_op {
471 typedef typename packet_traits<Scalar>::type Packet;
473 EIGEN_STRONG_INLINE scalar_multiple_op(
const scalar_multiple_op& other) : m_other(other.m_other) { }
478 typename add_const_on_value_type<typename NumTraits<Scalar>::Nested>::type m_other;
480 template<
typename Scalar>
481 struct functor_traits<scalar_multiple_op<Scalar> >
484 template<
typename Scalar1,
typename Scalar2>
485 struct scalar_multiple2_op {
486 typedef typename scalar_product_traits<Scalar1,Scalar2>::ReturnType result_type;
487 EIGEN_STRONG_INLINE scalar_multiple2_op(
const scalar_multiple2_op& other) : m_other(other.m_other) { }
489 EIGEN_STRONG_INLINE result_type operator() (
const Scalar1& a)
const {
return a * m_other; }
490 typename add_const_on_value_type<typename NumTraits<Scalar2>::Nested>::type m_other;
492 template<
typename Scalar1,
typename Scalar2>
493 struct functor_traits<scalar_multiple2_op<Scalar1,Scalar2> >
494 {
enum { Cost = NumTraits<Scalar1>::MulCost, PacketAccess =
false }; };
496 template<
typename Scalar,
bool IsInteger>
497 struct scalar_quotient1_impl {
498 typedef typename packet_traits<Scalar>::type Packet;
500 EIGEN_STRONG_INLINE scalar_quotient1_impl(
const scalar_quotient1_impl& other) : m_other(other.m_other) { }
501 EIGEN_STRONG_INLINE scalar_quotient1_impl(
const Scalar& other) : m_other(static_cast<Scalar>(1) / other) {}
505 const Scalar m_other;
507 template<
typename Scalar>
508 struct functor_traits<scalar_quotient1_impl<Scalar,false> >
511 template<
typename Scalar>
512 struct scalar_quotient1_impl<Scalar,true> {
514 EIGEN_STRONG_INLINE scalar_quotient1_impl(
const scalar_quotient1_impl& other) : m_other(other.m_other) { }
517 typename add_const_on_value_type<typename NumTraits<Scalar>::Nested>::type m_other;
519 template<
typename Scalar>
520 struct functor_traits<scalar_quotient1_impl<Scalar,true> >
531 template<
typename Scalar>
532 struct scalar_quotient1_op : scalar_quotient1_impl<Scalar, NumTraits<Scalar>::IsInteger > {
534 : scalar_quotient1_impl<Scalar, NumTraits<Scalar>::IsInteger >(other) {}
536 template<
typename Scalar>
537 struct functor_traits<scalar_quotient1_op<Scalar> >
538 : functor_traits<scalar_quotient1_impl<Scalar, NumTraits<Scalar>::IsInteger> >
543 template<
typename Scalar>
544 struct scalar_constant_op {
545 typedef typename packet_traits<Scalar>::type Packet;
546 EIGEN_STRONG_INLINE scalar_constant_op(
const scalar_constant_op& other) : m_other(other.m_other) { }
548 template<
typename Index>
550 template<
typename Index>
551 EIGEN_STRONG_INLINE const Packet packetOp(Index, Index = 0)
const {
return internal::pset1<Packet>(m_other); }
552 const Scalar m_other;
554 template<
typename Scalar>
555 struct functor_traits<scalar_constant_op<Scalar> >
557 {
enum { Cost = 1, PacketAccess = packet_traits<Scalar>::Vectorizable, IsRepeatable =
true }; };
559 template<
typename Scalar>
struct scalar_identity_op {
561 template<typename Index>
564 template<
typename Scalar>
565 struct functor_traits<scalar_identity_op<Scalar> >
568 template <
typename Scalar,
bool RandomAccess>
struct linspaced_op_impl;
575 template <
typename Scalar>
576 struct linspaced_op_impl<Scalar,false>
578 typedef typename packet_traits<Scalar>::type Packet;
580 linspaced_op_impl(Scalar low, Scalar step) :
581 m_low(low), m_step(step),
582 m_packetStep(
pset1<Packet>(packet_traits<Scalar>::size*step)),
585 template<
typename Index>
587 template<
typename Index>
592 const Packet m_packetStep;
593 mutable Packet m_base;
599 template <
typename Scalar>
600 struct linspaced_op_impl<Scalar,true>
602 typedef typename packet_traits<Scalar>::type Packet;
604 linspaced_op_impl(Scalar low, Scalar step) :
605 m_low(low), m_step(step),
606 m_lowPacket(
pset1<Packet>(m_low)), m_stepPacket(
pset1<Packet>(m_step)), m_interPacket(
plset<Scalar>(0)) {}
608 template<
typename Index>
611 template<
typename Index>
617 const Packet m_lowPacket;
618 const Packet m_stepPacket;
619 const Packet m_interPacket;
627 template <
typename Scalar,
bool RandomAccess = true>
struct linspaced_op;
628 template <
typename Scalar,
bool RandomAccess>
struct functor_traits< linspaced_op<Scalar,RandomAccess> >
629 {
enum { Cost = 1, PacketAccess = packet_traits<Scalar>::HasSetLinear, IsRepeatable =
true }; };
630 template <
typename Scalar,
bool RandomAccess>
struct linspaced_op
632 typedef typename packet_traits<Scalar>::type Packet;
633 linspaced_op(Scalar low, Scalar high,
int num_steps) : impl((num_steps==1 ? high : low), (num_steps==1 ? Scalar() : (high-low)/(num_steps-1))) {}
635 template<
typename Index>
640 template<
typename Index>
644 return impl(col + row);
647 template<
typename Index>
652 template<
typename Index>
656 return impl.packetOp(col + row);
662 const linspaced_op_impl<Scalar,RandomAccess> impl;
669 template<
typename Functor>
struct functor_has_linear_access {
enum { ret = 1 }; };
670 template<
typename Scalar>
struct functor_has_linear_access<scalar_identity_op<Scalar> > {
enum { ret = 0 }; };
675 template<
typename Functor>
struct functor_allows_mixing_real_and_complex {
enum { ret = 0 }; };
676 template<
typename LhsScalar,
typename RhsScalar>
struct functor_allows_mixing_real_and_complex<scalar_product_op<LhsScalar,RhsScalar> > {
enum { ret = 1 }; };
677 template<
typename LhsScalar,
typename RhsScalar>
struct functor_allows_mixing_real_and_complex<scalar_conj_product_op<LhsScalar,RhsScalar> > {
enum { ret = 1 }; };
685 template<
typename Scalar>
686 struct scalar_add_op {
687 typedef typename packet_traits<Scalar>::type Packet;
689 inline scalar_add_op(
const scalar_add_op& other) : m_other(other.m_other) { }
690 inline scalar_add_op(
const Scalar& other) : m_other(other) { }
691 inline Scalar operator() (
const Scalar& a)
const {
return a + m_other; }
692 inline const Packet packetOp(
const Packet& a)
const
694 const Scalar m_other;
696 template<
typename Scalar>
697 struct functor_traits<scalar_add_op<Scalar> >
704 template<
typename Scalar>
struct scalar_sqrt_op {
706 inline const Scalar operator() (const Scalar& a)
const {
return internal::sqrt(a); }
707 typedef typename packet_traits<Scalar>::type Packet;
708 inline Packet packetOp(
const Packet& a)
const {
return internal::psqrt(a); }
710 template<
typename Scalar>
711 struct functor_traits<scalar_sqrt_op<Scalar> >
714 PacketAccess = packet_traits<Scalar>::HasSqrt
722 template<
typename Scalar>
struct scalar_cos_op {
724 inline Scalar operator() (const Scalar& a)
const {
return internal::cos(a); }
725 typedef typename packet_traits<Scalar>::type Packet;
726 inline Packet packetOp(
const Packet& a)
const {
return internal::pcos(a); }
728 template<
typename Scalar>
729 struct functor_traits<scalar_cos_op<Scalar> >
733 PacketAccess = packet_traits<Scalar>::HasCos
741 template<
typename Scalar>
struct scalar_sin_op {
743 inline const Scalar operator() (const Scalar& a)
const {
return internal::sin(a); }
744 typedef typename packet_traits<Scalar>::type Packet;
745 inline Packet packetOp(
const Packet& a)
const {
return internal::psin(a); }
747 template<
typename Scalar>
748 struct functor_traits<scalar_sin_op<Scalar> >
752 PacketAccess = packet_traits<Scalar>::HasSin
761 template<
typename Scalar>
struct scalar_tan_op {
763 inline const Scalar operator() (const Scalar& a)
const {
return internal::tan(a); }
764 typedef typename packet_traits<Scalar>::type Packet;
765 inline Packet packetOp(
const Packet& a)
const {
return internal::ptan(a); }
767 template<
typename Scalar>
768 struct functor_traits<scalar_tan_op<Scalar> >
772 PacketAccess = packet_traits<Scalar>::HasTan
780 template<
typename Scalar>
struct scalar_acos_op {
782 inline const Scalar operator() (const Scalar& a)
const {
return internal::acos(a); }
783 typedef typename packet_traits<Scalar>::type Packet;
784 inline Packet packetOp(
const Packet& a)
const {
return internal::pacos(a); }
786 template<
typename Scalar>
787 struct functor_traits<scalar_acos_op<Scalar> >
791 PacketAccess = packet_traits<Scalar>::HasACos
799 template<
typename Scalar>
struct scalar_asin_op {
801 inline const Scalar operator() (const Scalar& a)
const {
return internal::asin(a); }
802 typedef typename packet_traits<Scalar>::type Packet;
803 inline Packet packetOp(
const Packet& a)
const {
return internal::pasin(a); }
805 template<
typename Scalar>
806 struct functor_traits<scalar_asin_op<Scalar> >
810 PacketAccess = packet_traits<Scalar>::HasASin
818 template<
typename Scalar>
819 struct scalar_pow_op {
821 inline scalar_pow_op(
const scalar_pow_op& other) : m_exponent(other.m_exponent) { }
822 inline scalar_pow_op(
const Scalar& exponent) : m_exponent(exponent) {}
823 inline Scalar operator() (
const Scalar& a)
const {
return internal::pow(a, m_exponent); }
824 const Scalar m_exponent;
826 template<
typename Scalar>
827 struct functor_traits<scalar_pow_op<Scalar> >
834 template<
typename Scalar>
835 struct scalar_inverse_mult_op {
836 scalar_inverse_mult_op(
const Scalar& other) : m_other(other) {}
837 inline Scalar operator() (
const Scalar& a)
const {
return m_other / a; }
838 template<
typename Packet>
839 inline const Packet packetOp(
const Packet& a)
const
848 template<
typename Scalar>
849 struct scalar_inverse_op {
851 inline Scalar operator() (const Scalar& a)
const {
return Scalar(1)/a; }
852 template<
typename Packet>
853 inline const Packet packetOp(
const Packet& a)
const
856 template<
typename Scalar>
857 struct functor_traits<scalar_inverse_op<Scalar> >
864 template<
typename Scalar>
865 struct scalar_square_op {
867 inline Scalar operator() (const Scalar& a)
const {
return a*a; }
868 template<
typename Packet>
869 inline const Packet packetOp(
const Packet& a)
const
872 template<
typename Scalar>
873 struct functor_traits<scalar_square_op<Scalar> >
880 template<
typename Scalar>
881 struct scalar_cube_op {
883 inline Scalar operator() (const Scalar& a)
const {
return a*a*a; }
884 template<
typename Packet>
885 inline const Packet packetOp(
const Packet& a)
const
888 template<
typename Scalar>
889 struct functor_traits<scalar_cube_op<Scalar> >
895 struct functor_traits<std::multiplies<T> >
896 {
enum { Cost = NumTraits<T>::MulCost, PacketAccess =
false }; };
899 struct functor_traits<std::divides<T> >
900 {
enum { Cost = NumTraits<T>::MulCost, PacketAccess =
false }; };
903 struct functor_traits<std::plus<T> >
904 {
enum { Cost = NumTraits<T>::AddCost, PacketAccess =
false }; };
907 struct functor_traits<std::minus<T> >
908 {
enum { Cost = NumTraits<T>::AddCost, PacketAccess =
false }; };
911 struct functor_traits<std::negate<T> >
912 {
enum { Cost = NumTraits<T>::AddCost, PacketAccess =
false }; };
915 struct functor_traits<std::logical_or<T> >
916 {
enum { Cost = 1, PacketAccess =
false }; };
919 struct functor_traits<std::logical_and<T> >
920 {
enum { Cost = 1, PacketAccess =
false }; };
923 struct functor_traits<std::logical_not<T> >
924 {
enum { Cost = 1, PacketAccess =
false }; };
927 struct functor_traits<std::greater<T> >
928 {
enum { Cost = 1, PacketAccess =
false }; };
931 struct functor_traits<std::less<T> >
932 {
enum { Cost = 1, PacketAccess =
false }; };
935 struct functor_traits<std::greater_equal<T> >
936 {
enum { Cost = 1, PacketAccess =
false }; };
939 struct functor_traits<std::less_equal<T> >
940 {
enum { Cost = 1, PacketAccess =
false }; };
943 struct functor_traits<std::equal_to<T> >
944 {
enum { Cost = 1, PacketAccess =
false }; };
947 struct functor_traits<std::not_equal_to<T> >
948 {
enum { Cost = 1, PacketAccess =
false }; };
951 struct functor_traits<std::binder2nd<T> >
952 {
enum { Cost = functor_traits<T>::Cost, PacketAccess =
false }; };
955 struct functor_traits<std::binder1st<T> >
956 {
enum { Cost = functor_traits<T>::Cost, PacketAccess =
false }; };
959 struct functor_traits<std::unary_negate<T> >
960 {
enum { Cost = 1 + functor_traits<T>::Cost, PacketAccess =
false }; };
963 struct functor_traits<std::binary_negate<T> >
964 {
enum { Cost = 1 + functor_traits<T>::Cost, PacketAccess =
false }; };
966 #ifdef EIGEN_STDEXT_SUPPORT
968 template<
typename T0,
typename T1>
969 struct functor_traits<std::project1st<T0,T1> >
970 {
enum { Cost = 0, PacketAccess =
false }; };
972 template<
typename T0,
typename T1>
973 struct functor_traits<std::project2nd<T0,T1> >
974 {
enum { Cost = 0, PacketAccess =
false }; };
976 template<
typename T0,
typename T1>
977 struct functor_traits<std::select2nd<std::pair<T0,T1> > >
978 {
enum { Cost = 0, PacketAccess =
false }; };
980 template<
typename T0,
typename T1>
981 struct functor_traits<std::select1st<std::pair<T0,T1> > >
982 {
enum { Cost = 0, PacketAccess =
false }; };
984 template<
typename T0,
typename T1>
985 struct functor_traits<std::unary_compose<T0,T1> >
986 {
enum { Cost = functor_traits<T0>::Cost + functor_traits<T1>::Cost, PacketAccess =
false }; };
988 template<
typename T0,
typename T1,
typename T2>
989 struct functor_traits<std::binary_compose<T0,T1,T2> >
990 {
enum { Cost = functor_traits<T0>::Cost + functor_traits<T1>::Cost + functor_traits<T2>::Cost, PacketAccess =
false }; };
992 #endif // EIGEN_STDEXT_SUPPORT
996 #ifdef EIGEN_FUNCTORS_PLUGIN
997 #include EIGEN_FUNCTORS_PLUGIN
1004 #endif // EIGEN_FUNCTORS_H