00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef EIGEN_FUNCTORS_H
00026 #define EIGEN_FUNCTORS_H
00027
00028 namespace internal {
00029
00030
00031
00037 template<typename Scalar> struct scalar_sum_op {
00038 EIGEN_EMPTY_STRUCT_CTOR(scalar_sum_op)
00039 EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return a + b; }
00040 template<typename Packet>
00041 EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
00042 { return internal::padd(a,b); }
00043 template<typename Packet>
00044 EIGEN_STRONG_INLINE const Scalar predux(const Packet& a) const
00045 { return internal::predux(a); }
00046 };
00047 template<typename Scalar>
00048 struct functor_traits<scalar_sum_op<Scalar> > {
00049 enum {
00050 Cost = NumTraits<Scalar>::AddCost,
00051 PacketAccess = packet_traits<Scalar>::HasAdd
00052 };
00053 };
00054
00060 template<typename LhsScalar,typename RhsScalar> struct scalar_product_op {
00061 enum {
00062
00063 Vectorizable = is_same<LhsScalar,RhsScalar>::value && packet_traits<LhsScalar>::HasMul && packet_traits<RhsScalar>::HasMul
00064 };
00065 typedef typename scalar_product_traits<LhsScalar,RhsScalar>::ReturnType result_type;
00066 EIGEN_EMPTY_STRUCT_CTOR(scalar_product_op)
00067 EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const { return a * b; }
00068 template<typename Packet>
00069 EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
00070 { return internal::pmul(a,b); }
00071 template<typename Packet>
00072 EIGEN_STRONG_INLINE const result_type predux(const Packet& a) const
00073 { return internal::predux_mul(a); }
00074 };
00075 template<typename LhsScalar,typename RhsScalar>
00076 struct functor_traits<scalar_product_op<LhsScalar,RhsScalar> > {
00077 enum {
00078 Cost = (NumTraits<LhsScalar>::MulCost + NumTraits<RhsScalar>::MulCost)/2,
00079 PacketAccess = scalar_product_op<LhsScalar,RhsScalar>::Vectorizable
00080 };
00081 };
00082
00088 template<typename LhsScalar,typename RhsScalar> struct scalar_conj_product_op {
00089
00090 enum {
00091 Conj = NumTraits<LhsScalar>::IsComplex
00092 };
00093
00094 typedef typename scalar_product_traits<LhsScalar,RhsScalar>::ReturnType result_type;
00095
00096 EIGEN_EMPTY_STRUCT_CTOR(scalar_conj_product_op)
00097 EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const
00098 { return conj_helper<LhsScalar,RhsScalar,Conj,false>().pmul(a,b); }
00099
00100 template<typename Packet>
00101 EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
00102 { return conj_helper<Packet,Packet,Conj,false>().pmul(a,b); }
00103 };
00104 template<typename LhsScalar,typename RhsScalar>
00105 struct functor_traits<scalar_conj_product_op<LhsScalar,RhsScalar> > {
00106 enum {
00107 Cost = NumTraits<LhsScalar>::MulCost,
00108 PacketAccess = internal::is_same<LhsScalar, RhsScalar>::value && packet_traits<LhsScalar>::HasMul
00109 };
00110 };
00111
00117 template<typename Scalar> struct scalar_min_op {
00118 EIGEN_EMPTY_STRUCT_CTOR(scalar_min_op)
00119 EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { using std::min; return min(a, b); }
00120 template<typename Packet>
00121 EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
00122 { return internal::pmin(a,b); }
00123 template<typename Packet>
00124 EIGEN_STRONG_INLINE const Scalar predux(const Packet& a) const
00125 { return internal::predux_min(a); }
00126 };
00127 template<typename Scalar>
00128 struct functor_traits<scalar_min_op<Scalar> > {
00129 enum {
00130 Cost = NumTraits<Scalar>::AddCost,
00131 PacketAccess = packet_traits<Scalar>::HasMin
00132 };
00133 };
00134
00140 template<typename Scalar> struct scalar_max_op {
00141 EIGEN_EMPTY_STRUCT_CTOR(scalar_max_op)
00142 EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { using std::max; return max(a, b); }
00143 template<typename Packet>
00144 EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
00145 { return internal::pmax(a,b); }
00146 template<typename Packet>
00147 EIGEN_STRONG_INLINE const Scalar predux(const Packet& a) const
00148 { return internal::predux_max(a); }
00149 };
00150 template<typename Scalar>
00151 struct functor_traits<scalar_max_op<Scalar> > {
00152 enum {
00153 Cost = NumTraits<Scalar>::AddCost,
00154 PacketAccess = packet_traits<Scalar>::HasMax
00155 };
00156 };
00157
00163 template<typename Scalar> struct scalar_hypot_op {
00164 EIGEN_EMPTY_STRUCT_CTOR(scalar_hypot_op)
00165
00166 EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& _x, const Scalar& _y) const
00167 {
00168 using std::max;
00169 using std::min;
00170 Scalar p = max(_x, _y);
00171 Scalar q = min(_x, _y);
00172 Scalar qp = q/p;
00173 return p * sqrt(Scalar(1) + qp*qp);
00174 }
00175 };
00176 template<typename Scalar>
00177 struct functor_traits<scalar_hypot_op<Scalar> > {
00178 enum { Cost = 5 * NumTraits<Scalar>::MulCost, PacketAccess=0 };
00179 };
00180
00181
00182
00188 template<typename Scalar> struct scalar_difference_op {
00189 EIGEN_EMPTY_STRUCT_CTOR(scalar_difference_op)
00190 EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return a - b; }
00191 template<typename Packet>
00192 EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
00193 { return internal::psub(a,b); }
00194 };
00195 template<typename Scalar>
00196 struct functor_traits<scalar_difference_op<Scalar> > {
00197 enum {
00198 Cost = NumTraits<Scalar>::AddCost,
00199 PacketAccess = packet_traits<Scalar>::HasSub
00200 };
00201 };
00202
00208 template<typename Scalar> struct scalar_quotient_op {
00209 EIGEN_EMPTY_STRUCT_CTOR(scalar_quotient_op)
00210 EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return a / b; }
00211 template<typename Packet>
00212 EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
00213 { return internal::pdiv(a,b); }
00214 };
00215 template<typename Scalar>
00216 struct functor_traits<scalar_quotient_op<Scalar> > {
00217 enum {
00218 Cost = 2 * NumTraits<Scalar>::MulCost,
00219 PacketAccess = packet_traits<Scalar>::HasDiv
00220 };
00221 };
00222
00223
00224
00230 template<typename Scalar> struct scalar_opposite_op {
00231 EIGEN_EMPTY_STRUCT_CTOR(scalar_opposite_op)
00232 EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a) const { return -a; }
00233 template<typename Packet>
00234 EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const
00235 { return internal::pnegate(a); }
00236 };
00237 template<typename Scalar>
00238 struct functor_traits<scalar_opposite_op<Scalar> >
00239 { enum {
00240 Cost = NumTraits<Scalar>::AddCost,
00241 PacketAccess = packet_traits<Scalar>::HasNegate };
00242 };
00243
00249 template<typename Scalar> struct scalar_abs_op {
00250 EIGEN_EMPTY_STRUCT_CTOR(scalar_abs_op)
00251 typedef typename NumTraits<Scalar>::Real result_type;
00252 EIGEN_STRONG_INLINE const result_type operator() (const Scalar& a) const { return abs(a); }
00253 template<typename Packet>
00254 EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const
00255 { return internal::pabs(a); }
00256 };
00257 template<typename Scalar>
00258 struct functor_traits<scalar_abs_op<Scalar> >
00259 {
00260 enum {
00261 Cost = NumTraits<Scalar>::AddCost,
00262 PacketAccess = packet_traits<Scalar>::HasAbs
00263 };
00264 };
00265
00271 template<typename Scalar> struct scalar_abs2_op {
00272 EIGEN_EMPTY_STRUCT_CTOR(scalar_abs2_op)
00273 typedef typename NumTraits<Scalar>::Real result_type;
00274 EIGEN_STRONG_INLINE const result_type operator() (const Scalar& a) const { return abs2(a); }
00275 template<typename Packet>
00276 EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const
00277 { return internal::pmul(a,a); }
00278 };
00279 template<typename Scalar>
00280 struct functor_traits<scalar_abs2_op<Scalar> >
00281 { enum { Cost = NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasAbs2 }; };
00282
00288 template<typename Scalar> struct scalar_conjugate_op {
00289 EIGEN_EMPTY_STRUCT_CTOR(scalar_conjugate_op)
00290 EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a) const { return conj(a); }
00291 template<typename Packet>
00292 EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const { return internal::pconj(a); }
00293 };
00294 template<typename Scalar>
00295 struct functor_traits<scalar_conjugate_op<Scalar> >
00296 {
00297 enum {
00298 Cost = NumTraits<Scalar>::IsComplex ? NumTraits<Scalar>::AddCost : 0,
00299 PacketAccess = packet_traits<Scalar>::HasConj
00300 };
00301 };
00302
00308 template<typename Scalar, typename NewType>
00309 struct scalar_cast_op {
00310 EIGEN_EMPTY_STRUCT_CTOR(scalar_cast_op)
00311 typedef NewType result_type;
00312 EIGEN_STRONG_INLINE const NewType operator() (const Scalar& a) const { return cast<Scalar, NewType>(a); }
00313 };
00314 template<typename Scalar, typename NewType>
00315 struct functor_traits<scalar_cast_op<Scalar,NewType> >
00316 { enum { Cost = is_same<Scalar, NewType>::value ? 0 : NumTraits<NewType>::AddCost, PacketAccess = false }; };
00317
00323 template<typename Scalar>
00324 struct scalar_real_op {
00325 EIGEN_EMPTY_STRUCT_CTOR(scalar_real_op)
00326 typedef typename NumTraits<Scalar>::Real result_type;
00327 EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return real(a); }
00328 };
00329 template<typename Scalar>
00330 struct functor_traits<scalar_real_op<Scalar> >
00331 { enum { Cost = 0, PacketAccess = false }; };
00332
00338 template<typename Scalar>
00339 struct scalar_imag_op {
00340 EIGEN_EMPTY_STRUCT_CTOR(scalar_imag_op)
00341 typedef typename NumTraits<Scalar>::Real result_type;
00342 EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return imag(a); }
00343 };
00344 template<typename Scalar>
00345 struct functor_traits<scalar_imag_op<Scalar> >
00346 { enum { Cost = 0, PacketAccess = false }; };
00347
00353 template<typename Scalar>
00354 struct scalar_real_ref_op {
00355 EIGEN_EMPTY_STRUCT_CTOR(scalar_real_ref_op)
00356 typedef typename NumTraits<Scalar>::Real result_type;
00357 EIGEN_STRONG_INLINE result_type& operator() (const Scalar& a) const { return real_ref(*const_cast<Scalar*>(&a)); }
00358 };
00359 template<typename Scalar>
00360 struct functor_traits<scalar_real_ref_op<Scalar> >
00361 { enum { Cost = 0, PacketAccess = false }; };
00362
00368 template<typename Scalar>
00369 struct scalar_imag_ref_op {
00370 EIGEN_EMPTY_STRUCT_CTOR(scalar_imag_ref_op)
00371 typedef typename NumTraits<Scalar>::Real result_type;
00372 EIGEN_STRONG_INLINE result_type& operator() (const Scalar& a) const { return imag_ref(*const_cast<Scalar*>(&a)); }
00373 };
00374 template<typename Scalar>
00375 struct functor_traits<scalar_imag_ref_op<Scalar> >
00376 { enum { Cost = 0, PacketAccess = false }; };
00377
00384 template<typename Scalar> struct scalar_exp_op {
00385 EIGEN_EMPTY_STRUCT_CTOR(scalar_exp_op)
00386 inline const Scalar operator() (const Scalar& a) const { return exp(a); }
00387 typedef typename packet_traits<Scalar>::type Packet;
00388 inline Packet packetOp(const Packet& a) const { return internal::pexp(a); }
00389 };
00390 template<typename Scalar>
00391 struct functor_traits<scalar_exp_op<Scalar> >
00392 { enum { Cost = 5 * NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasExp }; };
00393
00400 template<typename Scalar> struct scalar_log_op {
00401 EIGEN_EMPTY_STRUCT_CTOR(scalar_log_op)
00402 inline const Scalar operator() (const Scalar& a) const { return log(a); }
00403 typedef typename packet_traits<Scalar>::type Packet;
00404 inline Packet packetOp(const Packet& a) const { return internal::plog(a); }
00405 };
00406 template<typename Scalar>
00407 struct functor_traits<scalar_log_op<Scalar> >
00408 { enum { Cost = 5 * NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasLog }; };
00409
00415
00416
00417
00418
00419
00420
00421
00422
00423 template<typename Scalar>
00424 struct scalar_multiple_op {
00425 typedef typename packet_traits<Scalar>::type Packet;
00426
00427 EIGEN_STRONG_INLINE scalar_multiple_op(const scalar_multiple_op& other) : m_other(other.m_other) { }
00428 EIGEN_STRONG_INLINE scalar_multiple_op(const Scalar& other) : m_other(other) { }
00429 EIGEN_STRONG_INLINE Scalar operator() (const Scalar& a) const { return a * m_other; }
00430 EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const
00431 { return internal::pmul(a, pset1<Packet>(m_other)); }
00432 typename add_const_on_value_type<typename NumTraits<Scalar>::Nested>::type m_other;
00433 };
00434 template<typename Scalar>
00435 struct functor_traits<scalar_multiple_op<Scalar> >
00436 { enum { Cost = NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasMul }; };
00437
00438 template<typename Scalar1, typename Scalar2>
00439 struct scalar_multiple2_op {
00440 typedef typename scalar_product_traits<Scalar1,Scalar2>::ReturnType result_type;
00441 EIGEN_STRONG_INLINE scalar_multiple2_op(const scalar_multiple2_op& other) : m_other(other.m_other) { }
00442 EIGEN_STRONG_INLINE scalar_multiple2_op(const Scalar2& other) : m_other(other) { }
00443 EIGEN_STRONG_INLINE result_type operator() (const Scalar1& a) const { return a * m_other; }
00444 typename add_const_on_value_type<typename NumTraits<Scalar2>::Nested>::type m_other;
00445 };
00446 template<typename Scalar1,typename Scalar2>
00447 struct functor_traits<scalar_multiple2_op<Scalar1,Scalar2> >
00448 { enum { Cost = NumTraits<Scalar1>::MulCost, PacketAccess = false }; };
00449
00450 template<typename Scalar, bool IsInteger>
00451 struct scalar_quotient1_impl {
00452 typedef typename packet_traits<Scalar>::type Packet;
00453
00454 EIGEN_STRONG_INLINE scalar_quotient1_impl(const scalar_quotient1_impl& other) : m_other(other.m_other) { }
00455 EIGEN_STRONG_INLINE scalar_quotient1_impl(const Scalar& other) : m_other(static_cast<Scalar>(1) / other) {}
00456 EIGEN_STRONG_INLINE Scalar operator() (const Scalar& a) const { return a * m_other; }
00457 EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const
00458 { return internal::pmul(a, pset1<Packet>(m_other)); }
00459 const Scalar m_other;
00460 };
00461 template<typename Scalar>
00462 struct functor_traits<scalar_quotient1_impl<Scalar,false> >
00463 { enum { Cost = NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasMul }; };
00464
00465 template<typename Scalar>
00466 struct scalar_quotient1_impl<Scalar,true> {
00467
00468 EIGEN_STRONG_INLINE scalar_quotient1_impl(const scalar_quotient1_impl& other) : m_other(other.m_other) { }
00469 EIGEN_STRONG_INLINE scalar_quotient1_impl(const Scalar& other) : m_other(other) {}
00470 EIGEN_STRONG_INLINE Scalar operator() (const Scalar& a) const { return a / m_other; }
00471 typename add_const_on_value_type<typename NumTraits<Scalar>::Nested>::type m_other;
00472 };
00473 template<typename Scalar>
00474 struct functor_traits<scalar_quotient1_impl<Scalar,true> >
00475 { enum { Cost = 2 * NumTraits<Scalar>::MulCost, PacketAccess = false }; };
00476
00485 template<typename Scalar>
00486 struct scalar_quotient1_op : scalar_quotient1_impl<Scalar, NumTraits<Scalar>::IsInteger > {
00487 EIGEN_STRONG_INLINE scalar_quotient1_op(const Scalar& other)
00488 : scalar_quotient1_impl<Scalar, NumTraits<Scalar>::IsInteger >(other) {}
00489 };
00490 template<typename Scalar>
00491 struct functor_traits<scalar_quotient1_op<Scalar> >
00492 : functor_traits<scalar_quotient1_impl<Scalar, NumTraits<Scalar>::IsInteger> >
00493 {};
00494
00495
00496
00497 template<typename Scalar>
00498 struct scalar_constant_op {
00499 typedef typename packet_traits<Scalar>::type Packet;
00500 EIGEN_STRONG_INLINE scalar_constant_op(const scalar_constant_op& other) : m_other(other.m_other) { }
00501 EIGEN_STRONG_INLINE scalar_constant_op(const Scalar& other) : m_other(other) { }
00502 template<typename Index>
00503 EIGEN_STRONG_INLINE const Scalar operator() (Index, Index = 0) const { return m_other; }
00504 template<typename Index>
00505 EIGEN_STRONG_INLINE const Packet packetOp(Index, Index = 0) const { return internal::pset1<Packet>(m_other); }
00506 const Scalar m_other;
00507 };
00508 template<typename Scalar>
00509 struct functor_traits<scalar_constant_op<Scalar> >
00510
00511 { enum { Cost = 1, PacketAccess = packet_traits<Scalar>::Vectorizable, IsRepeatable = true }; };
00512
00513 template<typename Scalar> struct scalar_identity_op {
00514 EIGEN_EMPTY_STRUCT_CTOR(scalar_identity_op)
00515 template<typename Index>
00516 EIGEN_STRONG_INLINE const Scalar operator() (Index row, Index col) const { return row==col ? Scalar(1) : Scalar(0); }
00517 };
00518 template<typename Scalar>
00519 struct functor_traits<scalar_identity_op<Scalar> >
00520 { enum { Cost = NumTraits<Scalar>::AddCost, PacketAccess = false, IsRepeatable = true }; };
00521
00522 template <typename Scalar, bool RandomAccess> struct linspaced_op_impl;
00523
00524
00525
00526
00527
00528
00529 template <typename Scalar>
00530 struct linspaced_op_impl<Scalar,false>
00531 {
00532 typedef typename packet_traits<Scalar>::type Packet;
00533
00534 linspaced_op_impl(Scalar low, Scalar step) :
00535 m_low(low), m_step(step),
00536 m_packetStep(pset1<Packet>(packet_traits<Scalar>::size*step)),
00537 m_base(padd(pset1<Packet>(low),pmul(pset1<Packet>(step),plset<Scalar>(-packet_traits<Scalar>::size)))) {}
00538
00539 template<typename Index>
00540 EIGEN_STRONG_INLINE const Scalar operator() (Index i) const { return m_low+i*m_step; }
00541 template<typename Index>
00542 EIGEN_STRONG_INLINE const Packet packetOp(Index) const { return m_base = padd(m_base,m_packetStep); }
00543
00544 const Scalar m_low;
00545 const Scalar m_step;
00546 const Packet m_packetStep;
00547 mutable Packet m_base;
00548 };
00549
00550
00551
00552
00553 template <typename Scalar>
00554 struct linspaced_op_impl<Scalar,true>
00555 {
00556 typedef typename packet_traits<Scalar>::type Packet;
00557
00558 linspaced_op_impl(Scalar low, Scalar step) :
00559 m_low(low), m_step(step),
00560 m_lowPacket(pset1<Packet>(m_low)), m_stepPacket(pset1<Packet>(m_step)), m_interPacket(plset<Scalar>(0)) {}
00561
00562 template<typename Index>
00563 EIGEN_STRONG_INLINE const Scalar operator() (Index i) const { return m_low+i*m_step; }
00564
00565 template<typename Index>
00566 EIGEN_STRONG_INLINE const Packet packetOp(Index i) const
00567 { return internal::padd(m_lowPacket, pmul(m_stepPacket, padd(pset1<Packet>(i),m_interPacket))); }
00568
00569 const Scalar m_low;
00570 const Scalar m_step;
00571 const Packet m_lowPacket;
00572 const Packet m_stepPacket;
00573 const Packet m_interPacket;
00574 };
00575
00576
00577
00578
00579
00580
00581 template <typename Scalar, bool RandomAccess = true> struct linspaced_op;
00582 template <typename Scalar, bool RandomAccess> struct functor_traits< linspaced_op<Scalar,RandomAccess> >
00583 { enum { Cost = 1, PacketAccess = packet_traits<Scalar>::HasSetLinear, IsRepeatable = true }; };
00584 template <typename Scalar, bool RandomAccess> struct linspaced_op
00585 {
00586 typedef typename packet_traits<Scalar>::type Packet;
00587 linspaced_op(Scalar low, Scalar high, int num_steps) : impl(low, (high-low)/(num_steps-1)) {}
00588
00589 template<typename Index>
00590 EIGEN_STRONG_INLINE const Scalar operator() (Index i) const { return impl(i); }
00591
00592
00593
00594 template<typename Index>
00595 EIGEN_STRONG_INLINE const Scalar operator() (Index row, Index col) const
00596 {
00597 eigen_assert(col==0 || row==0);
00598 return impl(col + row);
00599 }
00600
00601 template<typename Index>
00602 EIGEN_STRONG_INLINE const Packet packetOp(Index i) const { return impl.packetOp(i); }
00603
00604
00605
00606 template<typename Index>
00607 EIGEN_STRONG_INLINE const Packet packetOp(Index row, Index col) const
00608 {
00609 eigen_assert(col==0 || row==0);
00610 return impl.packetOp(col + row);
00611 }
00612
00613
00614
00615
00616 const linspaced_op_impl<Scalar,RandomAccess> impl;
00617 };
00618
00619
00620
00621
00622
00623 template<typename Functor> struct functor_has_linear_access { enum { ret = 1 }; };
00624 template<typename Scalar> struct functor_has_linear_access<scalar_identity_op<Scalar> > { enum { ret = 0 }; };
00625
00626
00627
00628
00629 template<typename Functor> struct functor_allows_mixing_real_and_complex { enum { ret = 0 }; };
00630 template<typename LhsScalar,typename RhsScalar> struct functor_allows_mixing_real_and_complex<scalar_product_op<LhsScalar,RhsScalar> > { enum { ret = 1 }; };
00631 template<typename LhsScalar,typename RhsScalar> struct functor_allows_mixing_real_and_complex<scalar_conj_product_op<LhsScalar,RhsScalar> > { enum { ret = 1 }; };
00632
00633
00638
00639 template<typename Scalar>
00640 struct scalar_add_op {
00641 typedef typename packet_traits<Scalar>::type Packet;
00642
00643 inline scalar_add_op(const scalar_add_op& other) : m_other(other.m_other) { }
00644 inline scalar_add_op(const Scalar& other) : m_other(other) { }
00645 inline Scalar operator() (const Scalar& a) const { return a + m_other; }
00646 inline const Packet packetOp(const Packet& a) const
00647 { return internal::padd(a, pset1<Packet>(m_other)); }
00648 const Scalar m_other;
00649 };
00650 template<typename Scalar>
00651 struct functor_traits<scalar_add_op<Scalar> >
00652 { enum { Cost = NumTraits<Scalar>::AddCost, PacketAccess = packet_traits<Scalar>::HasAdd }; };
00653
00658 template<typename Scalar> struct scalar_sqrt_op {
00659 EIGEN_EMPTY_STRUCT_CTOR(scalar_sqrt_op)
00660 inline const Scalar operator() (const Scalar& a) const { return sqrt(a); }
00661 typedef typename packet_traits<Scalar>::type Packet;
00662 inline Packet packetOp(const Packet& a) const { return internal::psqrt(a); }
00663 };
00664 template<typename Scalar>
00665 struct functor_traits<scalar_sqrt_op<Scalar> >
00666 { enum {
00667 Cost = 5 * NumTraits<Scalar>::MulCost,
00668 PacketAccess = packet_traits<Scalar>::HasSqrt
00669 };
00670 };
00671
00676 template<typename Scalar> struct scalar_cos_op {
00677 EIGEN_EMPTY_STRUCT_CTOR(scalar_cos_op)
00678 inline Scalar operator() (const Scalar& a) const { return cos(a); }
00679 typedef typename packet_traits<Scalar>::type Packet;
00680 inline Packet packetOp(const Packet& a) const { return internal::pcos(a); }
00681 };
00682 template<typename Scalar>
00683 struct functor_traits<scalar_cos_op<Scalar> >
00684 {
00685 enum {
00686 Cost = 5 * NumTraits<Scalar>::MulCost,
00687 PacketAccess = packet_traits<Scalar>::HasCos
00688 };
00689 };
00690
00695 template<typename Scalar> struct scalar_sin_op {
00696 EIGEN_EMPTY_STRUCT_CTOR(scalar_sin_op)
00697 inline const Scalar operator() (const Scalar& a) const { return sin(a); }
00698 typedef typename packet_traits<Scalar>::type Packet;
00699 inline Packet packetOp(const Packet& a) const { return internal::psin(a); }
00700 };
00701 template<typename Scalar>
00702 struct functor_traits<scalar_sin_op<Scalar> >
00703 {
00704 enum {
00705 Cost = 5 * NumTraits<Scalar>::MulCost,
00706 PacketAccess = packet_traits<Scalar>::HasSin
00707 };
00708 };
00709
00710
00715 template<typename Scalar> struct scalar_tan_op {
00716 EIGEN_EMPTY_STRUCT_CTOR(scalar_tan_op)
00717 inline const Scalar operator() (const Scalar& a) const { return tan(a); }
00718 typedef typename packet_traits<Scalar>::type Packet;
00719 inline Packet packetOp(const Packet& a) const { return internal::ptan(a); }
00720 };
00721 template<typename Scalar>
00722 struct functor_traits<scalar_tan_op<Scalar> >
00723 {
00724 enum {
00725 Cost = 5 * NumTraits<Scalar>::MulCost,
00726 PacketAccess = packet_traits<Scalar>::HasTan
00727 };
00728 };
00729
00734 template<typename Scalar> struct scalar_acos_op {
00735 EIGEN_EMPTY_STRUCT_CTOR(scalar_acos_op)
00736 inline const Scalar operator() (const Scalar& a) const { return acos(a); }
00737 typedef typename packet_traits<Scalar>::type Packet;
00738 inline Packet packetOp(const Packet& a) const { return internal::pacos(a); }
00739 };
00740 template<typename Scalar>
00741 struct functor_traits<scalar_acos_op<Scalar> >
00742 {
00743 enum {
00744 Cost = 5 * NumTraits<Scalar>::MulCost,
00745 PacketAccess = packet_traits<Scalar>::HasACos
00746 };
00747 };
00748
00753 template<typename Scalar> struct scalar_asin_op {
00754 EIGEN_EMPTY_STRUCT_CTOR(scalar_asin_op)
00755 inline const Scalar operator() (const Scalar& a) const { return asin(a); }
00756 typedef typename packet_traits<Scalar>::type Packet;
00757 inline Packet packetOp(const Packet& a) const { return internal::pasin(a); }
00758 };
00759 template<typename Scalar>
00760 struct functor_traits<scalar_asin_op<Scalar> >
00761 {
00762 enum {
00763 Cost = 5 * NumTraits<Scalar>::MulCost,
00764 PacketAccess = packet_traits<Scalar>::HasASin
00765 };
00766 };
00767
00772 template<typename Scalar>
00773 struct scalar_pow_op {
00774
00775 inline scalar_pow_op(const scalar_pow_op& other) : m_exponent(other.m_exponent) { }
00776 inline scalar_pow_op(const Scalar& exponent) : m_exponent(exponent) {}
00777 inline Scalar operator() (const Scalar& a) const { return internal::pow(a, m_exponent); }
00778 const Scalar m_exponent;
00779 };
00780 template<typename Scalar>
00781 struct functor_traits<scalar_pow_op<Scalar> >
00782 { enum { Cost = 5 * NumTraits<Scalar>::MulCost, PacketAccess = false }; };
00783
00788 template<typename Scalar>
00789 struct scalar_inverse_op {
00790 EIGEN_EMPTY_STRUCT_CTOR(scalar_inverse_op)
00791 inline Scalar operator() (const Scalar& a) const { return Scalar(1)/a; }
00792 template<typename Packet>
00793 inline const Packet packetOp(const Packet& a) const
00794 { return internal::pdiv(pset1<Packet>(Scalar(1)),a); }
00795 };
00796 template<typename Scalar>
00797 struct functor_traits<scalar_inverse_op<Scalar> >
00798 { enum { Cost = NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasDiv }; };
00799
00804 template<typename Scalar>
00805 struct scalar_square_op {
00806 EIGEN_EMPTY_STRUCT_CTOR(scalar_square_op)
00807 inline Scalar operator() (const Scalar& a) const { return a*a; }
00808 template<typename Packet>
00809 inline const Packet packetOp(const Packet& a) const
00810 { return internal::pmul(a,a); }
00811 };
00812 template<typename Scalar>
00813 struct functor_traits<scalar_square_op<Scalar> >
00814 { enum { Cost = NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasMul }; };
00815
00820 template<typename Scalar>
00821 struct scalar_cube_op {
00822 EIGEN_EMPTY_STRUCT_CTOR(scalar_cube_op)
00823 inline Scalar operator() (const Scalar& a) const { return a*a*a; }
00824 template<typename Packet>
00825 inline const Packet packetOp(const Packet& a) const
00826 { return internal::pmul(a,pmul(a,a)); }
00827 };
00828 template<typename Scalar>
00829 struct functor_traits<scalar_cube_op<Scalar> >
00830 { enum { Cost = 2*NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasMul }; };
00831
00832
00833
00834 template<typename T>
00835 struct functor_traits<std::multiplies<T> >
00836 { enum { Cost = NumTraits<T>::MulCost, PacketAccess = false }; };
00837
00838 template<typename T>
00839 struct functor_traits<std::divides<T> >
00840 { enum { Cost = NumTraits<T>::MulCost, PacketAccess = false }; };
00841
00842 template<typename T>
00843 struct functor_traits<std::plus<T> >
00844 { enum { Cost = NumTraits<T>::AddCost, PacketAccess = false }; };
00845
00846 template<typename T>
00847 struct functor_traits<std::minus<T> >
00848 { enum { Cost = NumTraits<T>::AddCost, PacketAccess = false }; };
00849
00850 template<typename T>
00851 struct functor_traits<std::negate<T> >
00852 { enum { Cost = NumTraits<T>::AddCost, PacketAccess = false }; };
00853
00854 template<typename T>
00855 struct functor_traits<std::logical_or<T> >
00856 { enum { Cost = 1, PacketAccess = false }; };
00857
00858 template<typename T>
00859 struct functor_traits<std::logical_and<T> >
00860 { enum { Cost = 1, PacketAccess = false }; };
00861
00862 template<typename T>
00863 struct functor_traits<std::logical_not<T> >
00864 { enum { Cost = 1, PacketAccess = false }; };
00865
00866 template<typename T>
00867 struct functor_traits<std::greater<T> >
00868 { enum { Cost = 1, PacketAccess = false }; };
00869
00870 template<typename T>
00871 struct functor_traits<std::less<T> >
00872 { enum { Cost = 1, PacketAccess = false }; };
00873
00874 template<typename T>
00875 struct functor_traits<std::greater_equal<T> >
00876 { enum { Cost = 1, PacketAccess = false }; };
00877
00878 template<typename T>
00879 struct functor_traits<std::less_equal<T> >
00880 { enum { Cost = 1, PacketAccess = false }; };
00881
00882 template<typename T>
00883 struct functor_traits<std::equal_to<T> >
00884 { enum { Cost = 1, PacketAccess = false }; };
00885
00886 template<typename T>
00887 struct functor_traits<std::not_equal_to<T> >
00888 { enum { Cost = 1, PacketAccess = false }; };
00889
00890 template<typename T>
00891 struct functor_traits<std::binder2nd<T> >
00892 { enum { Cost = functor_traits<T>::Cost, PacketAccess = false }; };
00893
00894 template<typename T>
00895 struct functor_traits<std::binder1st<T> >
00896 { enum { Cost = functor_traits<T>::Cost, PacketAccess = false }; };
00897
00898 template<typename T>
00899 struct functor_traits<std::unary_negate<T> >
00900 { enum { Cost = 1 + functor_traits<T>::Cost, PacketAccess = false }; };
00901
00902 template<typename T>
00903 struct functor_traits<std::binary_negate<T> >
00904 { enum { Cost = 1 + functor_traits<T>::Cost, PacketAccess = false }; };
00905
00906 #ifdef EIGEN_STDEXT_SUPPORT
00907
00908 template<typename T0,typename T1>
00909 struct functor_traits<std::project1st<T0,T1> >
00910 { enum { Cost = 0, PacketAccess = false }; };
00911
00912 template<typename T0,typename T1>
00913 struct functor_traits<std::project2nd<T0,T1> >
00914 { enum { Cost = 0, PacketAccess = false }; };
00915
00916 template<typename T0,typename T1>
00917 struct functor_traits<std::select2nd<std::pair<T0,T1> > >
00918 { enum { Cost = 0, PacketAccess = false }; };
00919
00920 template<typename T0,typename T1>
00921 struct functor_traits<std::select1st<std::pair<T0,T1> > >
00922 { enum { Cost = 0, PacketAccess = false }; };
00923
00924 template<typename T0,typename T1>
00925 struct functor_traits<std::unary_compose<T0,T1> >
00926 { enum { Cost = functor_traits<T0>::Cost + functor_traits<T1>::Cost, PacketAccess = false }; };
00927
00928 template<typename T0,typename T1,typename T2>
00929 struct functor_traits<std::binary_compose<T0,T1,T2> >
00930 { enum { Cost = functor_traits<T0>::Cost + functor_traits<T1>::Cost + functor_traits<T2>::Cost, PacketAccess = false }; };
00931
00932 #endif // EIGEN_STDEXT_SUPPORT
00933
00934
00935
00936 #ifdef EIGEN_FUNCTORS_PLUGIN
00937 #include EIGEN_FUNCTORS_PLUGIN
00938 #endif
00939
00940 }
00941
00942 #endif // EIGEN_FUNCTORS_H