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 Eigen {
00029
00030 namespace internal {
00031
00032
00033
00039 template<typename Scalar> struct scalar_sum_op {
00040 EIGEN_EMPTY_STRUCT_CTOR(scalar_sum_op)
00041 EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return a + b; }
00042 template<typename Packet>
00043 EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
00044 { return internal::padd(a,b); }
00045 template<typename Packet>
00046 EIGEN_STRONG_INLINE const Scalar predux(const Packet& a) const
00047 { return internal::predux(a); }
00048 };
00049 template<typename Scalar>
00050 struct functor_traits<scalar_sum_op<Scalar> > {
00051 enum {
00052 Cost = NumTraits<Scalar>::AddCost,
00053 PacketAccess = packet_traits<Scalar>::HasAdd
00054 };
00055 };
00056
00062 template<typename LhsScalar,typename RhsScalar> struct scalar_product_op {
00063 enum {
00064
00065 Vectorizable = is_same<LhsScalar,RhsScalar>::value && packet_traits<LhsScalar>::HasMul && packet_traits<RhsScalar>::HasMul
00066 };
00067 typedef typename scalar_product_traits<LhsScalar,RhsScalar>::ReturnType result_type;
00068 EIGEN_EMPTY_STRUCT_CTOR(scalar_product_op)
00069 EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const { return a * b; }
00070 template<typename Packet>
00071 EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
00072 { return internal::pmul(a,b); }
00073 template<typename Packet>
00074 EIGEN_STRONG_INLINE const result_type predux(const Packet& a) const
00075 { return internal::predux_mul(a); }
00076 };
00077 template<typename LhsScalar,typename RhsScalar>
00078 struct functor_traits<scalar_product_op<LhsScalar,RhsScalar> > {
00079 enum {
00080 Cost = (NumTraits<LhsScalar>::MulCost + NumTraits<RhsScalar>::MulCost)/2,
00081 PacketAccess = scalar_product_op<LhsScalar,RhsScalar>::Vectorizable
00082 };
00083 };
00084
00090 template<typename LhsScalar,typename RhsScalar> struct scalar_conj_product_op {
00091
00092 enum {
00093 Conj = NumTraits<LhsScalar>::IsComplex
00094 };
00095
00096 typedef typename scalar_product_traits<LhsScalar,RhsScalar>::ReturnType result_type;
00097
00098 EIGEN_EMPTY_STRUCT_CTOR(scalar_conj_product_op)
00099 EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const
00100 { return conj_helper<LhsScalar,RhsScalar,Conj,false>().pmul(a,b); }
00101
00102 template<typename Packet>
00103 EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
00104 { return conj_helper<Packet,Packet,Conj,false>().pmul(a,b); }
00105 };
00106 template<typename LhsScalar,typename RhsScalar>
00107 struct functor_traits<scalar_conj_product_op<LhsScalar,RhsScalar> > {
00108 enum {
00109 Cost = NumTraits<LhsScalar>::MulCost,
00110 PacketAccess = internal::is_same<LhsScalar, RhsScalar>::value && packet_traits<LhsScalar>::HasMul
00111 };
00112 };
00113
00119 template<typename Scalar> struct scalar_min_op {
00120 EIGEN_EMPTY_STRUCT_CTOR(scalar_min_op)
00121 EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { using std::min; return (min)(a, b); }
00122 template<typename Packet>
00123 EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
00124 { return internal::pmin(a,b); }
00125 template<typename Packet>
00126 EIGEN_STRONG_INLINE const Scalar predux(const Packet& a) const
00127 { return internal::predux_min(a); }
00128 };
00129 template<typename Scalar>
00130 struct functor_traits<scalar_min_op<Scalar> > {
00131 enum {
00132 Cost = NumTraits<Scalar>::AddCost,
00133 PacketAccess = packet_traits<Scalar>::HasMin
00134 };
00135 };
00136
00142 template<typename Scalar> struct scalar_max_op {
00143 EIGEN_EMPTY_STRUCT_CTOR(scalar_max_op)
00144 EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { using std::max; return (max)(a, b); }
00145 template<typename Packet>
00146 EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
00147 { return internal::pmax(a,b); }
00148 template<typename Packet>
00149 EIGEN_STRONG_INLINE const Scalar predux(const Packet& a) const
00150 { return internal::predux_max(a); }
00151 };
00152 template<typename Scalar>
00153 struct functor_traits<scalar_max_op<Scalar> > {
00154 enum {
00155 Cost = NumTraits<Scalar>::AddCost,
00156 PacketAccess = packet_traits<Scalar>::HasMax
00157 };
00158 };
00159
00165 template<typename Scalar> struct scalar_hypot_op {
00166 EIGEN_EMPTY_STRUCT_CTOR(scalar_hypot_op)
00167
00168 EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& _x, const Scalar& _y) const
00169 {
00170 using std::max;
00171 using std::min;
00172 Scalar p = (max)(_x, _y);
00173 Scalar q = (min)(_x, _y);
00174 Scalar qp = q/p;
00175 return p * sqrt(Scalar(1) + qp*qp);
00176 }
00177 };
00178 template<typename Scalar>
00179 struct functor_traits<scalar_hypot_op<Scalar> > {
00180 enum { Cost = 5 * NumTraits<Scalar>::MulCost, PacketAccess=0 };
00181 };
00182
00186 template<typename Scalar, typename OtherScalar> struct scalar_binary_pow_op {
00187 EIGEN_EMPTY_STRUCT_CTOR(scalar_binary_pow_op)
00188 inline Scalar operator() (const Scalar& a, const OtherScalar& b) const { return internal::pow(a, b); }
00189 };
00190 template<typename Scalar, typename OtherScalar>
00191 struct functor_traits<scalar_binary_pow_op<Scalar,OtherScalar> > {
00192 enum { Cost = 5 * NumTraits<Scalar>::MulCost, PacketAccess = false };
00193 };
00194
00195
00196
00202 template<typename Scalar> struct scalar_difference_op {
00203 EIGEN_EMPTY_STRUCT_CTOR(scalar_difference_op)
00204 EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return a - b; }
00205 template<typename Packet>
00206 EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
00207 { return internal::psub(a,b); }
00208 };
00209 template<typename Scalar>
00210 struct functor_traits<scalar_difference_op<Scalar> > {
00211 enum {
00212 Cost = NumTraits<Scalar>::AddCost,
00213 PacketAccess = packet_traits<Scalar>::HasSub
00214 };
00215 };
00216
00222 template<typename Scalar> struct scalar_quotient_op {
00223 EIGEN_EMPTY_STRUCT_CTOR(scalar_quotient_op)
00224 EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return a / b; }
00225 template<typename Packet>
00226 EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
00227 { return internal::pdiv(a,b); }
00228 };
00229 template<typename Scalar>
00230 struct functor_traits<scalar_quotient_op<Scalar> > {
00231 enum {
00232 Cost = 2 * NumTraits<Scalar>::MulCost,
00233 PacketAccess = packet_traits<Scalar>::HasDiv
00234 };
00235 };
00236
00242 struct scalar_boolean_and_op {
00243 EIGEN_EMPTY_STRUCT_CTOR(scalar_boolean_and_op)
00244 EIGEN_STRONG_INLINE bool operator() (const bool& a, const bool& b) const { return a && b; }
00245 };
00246 template<> struct functor_traits<scalar_boolean_and_op> {
00247 enum {
00248 Cost = NumTraits<bool>::AddCost,
00249 PacketAccess = false
00250 };
00251 };
00252
00258 struct scalar_boolean_or_op {
00259 EIGEN_EMPTY_STRUCT_CTOR(scalar_boolean_or_op)
00260 EIGEN_STRONG_INLINE bool operator() (const bool& a, const bool& b) const { return a || b; }
00261 };
00262 template<> struct functor_traits<scalar_boolean_or_op> {
00263 enum {
00264 Cost = NumTraits<bool>::AddCost,
00265 PacketAccess = false
00266 };
00267 };
00268
00269
00270
00276 template<typename Scalar> struct scalar_opposite_op {
00277 EIGEN_EMPTY_STRUCT_CTOR(scalar_opposite_op)
00278 EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a) const { return -a; }
00279 template<typename Packet>
00280 EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const
00281 { return internal::pnegate(a); }
00282 };
00283 template<typename Scalar>
00284 struct functor_traits<scalar_opposite_op<Scalar> >
00285 { enum {
00286 Cost = NumTraits<Scalar>::AddCost,
00287 PacketAccess = packet_traits<Scalar>::HasNegate };
00288 };
00289
00295 template<typename Scalar> struct scalar_abs_op {
00296 EIGEN_EMPTY_STRUCT_CTOR(scalar_abs_op)
00297 typedef typename NumTraits<Scalar>::Real result_type;
00298 EIGEN_STRONG_INLINE const result_type operator() (const Scalar& a) const { return abs(a); }
00299 template<typename Packet>
00300 EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const
00301 { return internal::pabs(a); }
00302 };
00303 template<typename Scalar>
00304 struct functor_traits<scalar_abs_op<Scalar> >
00305 {
00306 enum {
00307 Cost = NumTraits<Scalar>::AddCost,
00308 PacketAccess = packet_traits<Scalar>::HasAbs
00309 };
00310 };
00311
00317 template<typename Scalar> struct scalar_abs2_op {
00318 EIGEN_EMPTY_STRUCT_CTOR(scalar_abs2_op)
00319 typedef typename NumTraits<Scalar>::Real result_type;
00320 EIGEN_STRONG_INLINE const result_type operator() (const Scalar& a) const { return abs2(a); }
00321 template<typename Packet>
00322 EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const
00323 { return internal::pmul(a,a); }
00324 };
00325 template<typename Scalar>
00326 struct functor_traits<scalar_abs2_op<Scalar> >
00327 { enum { Cost = NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasAbs2 }; };
00328
00334 template<typename Scalar> struct scalar_conjugate_op {
00335 EIGEN_EMPTY_STRUCT_CTOR(scalar_conjugate_op)
00336 EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a) const { return conj(a); }
00337 template<typename Packet>
00338 EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const { return internal::pconj(a); }
00339 };
00340 template<typename Scalar>
00341 struct functor_traits<scalar_conjugate_op<Scalar> >
00342 {
00343 enum {
00344 Cost = NumTraits<Scalar>::IsComplex ? NumTraits<Scalar>::AddCost : 0,
00345 PacketAccess = packet_traits<Scalar>::HasConj
00346 };
00347 };
00348
00354 template<typename Scalar, typename NewType>
00355 struct scalar_cast_op {
00356 EIGEN_EMPTY_STRUCT_CTOR(scalar_cast_op)
00357 typedef NewType result_type;
00358 EIGEN_STRONG_INLINE const NewType operator() (const Scalar& a) const { return cast<Scalar, NewType>(a); }
00359 };
00360 template<typename Scalar, typename NewType>
00361 struct functor_traits<scalar_cast_op<Scalar,NewType> >
00362 { enum { Cost = is_same<Scalar, NewType>::value ? 0 : NumTraits<NewType>::AddCost, PacketAccess = false }; };
00363
00369 template<typename Scalar>
00370 struct scalar_real_op {
00371 EIGEN_EMPTY_STRUCT_CTOR(scalar_real_op)
00372 typedef typename NumTraits<Scalar>::Real result_type;
00373 EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return real(a); }
00374 };
00375 template<typename Scalar>
00376 struct functor_traits<scalar_real_op<Scalar> >
00377 { enum { Cost = 0, PacketAccess = false }; };
00378
00384 template<typename Scalar>
00385 struct scalar_imag_op {
00386 EIGEN_EMPTY_STRUCT_CTOR(scalar_imag_op)
00387 typedef typename NumTraits<Scalar>::Real result_type;
00388 EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return imag(a); }
00389 };
00390 template<typename Scalar>
00391 struct functor_traits<scalar_imag_op<Scalar> >
00392 { enum { Cost = 0, PacketAccess = false }; };
00393
00399 template<typename Scalar>
00400 struct scalar_real_ref_op {
00401 EIGEN_EMPTY_STRUCT_CTOR(scalar_real_ref_op)
00402 typedef typename NumTraits<Scalar>::Real result_type;
00403 EIGEN_STRONG_INLINE result_type& operator() (const Scalar& a) const { return real_ref(*const_cast<Scalar*>(&a)); }
00404 };
00405 template<typename Scalar>
00406 struct functor_traits<scalar_real_ref_op<Scalar> >
00407 { enum { Cost = 0, PacketAccess = false }; };
00408
00414 template<typename Scalar>
00415 struct scalar_imag_ref_op {
00416 EIGEN_EMPTY_STRUCT_CTOR(scalar_imag_ref_op)
00417 typedef typename NumTraits<Scalar>::Real result_type;
00418 EIGEN_STRONG_INLINE result_type& operator() (const Scalar& a) const { return imag_ref(*const_cast<Scalar*>(&a)); }
00419 };
00420 template<typename Scalar>
00421 struct functor_traits<scalar_imag_ref_op<Scalar> >
00422 { enum { Cost = 0, PacketAccess = false }; };
00423
00430 template<typename Scalar> struct scalar_exp_op {
00431 EIGEN_EMPTY_STRUCT_CTOR(scalar_exp_op)
00432 inline const Scalar operator() (const Scalar& a) const { return exp(a); }
00433 typedef typename packet_traits<Scalar>::type Packet;
00434 inline Packet packetOp(const Packet& a) const { return internal::pexp(a); }
00435 };
00436 template<typename Scalar>
00437 struct functor_traits<scalar_exp_op<Scalar> >
00438 { enum { Cost = 5 * NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasExp }; };
00439
00446 template<typename Scalar> struct scalar_log_op {
00447 EIGEN_EMPTY_STRUCT_CTOR(scalar_log_op)
00448 inline const Scalar operator() (const Scalar& a) const { return log(a); }
00449 typedef typename packet_traits<Scalar>::type Packet;
00450 inline Packet packetOp(const Packet& a) const { return internal::plog(a); }
00451 };
00452 template<typename Scalar>
00453 struct functor_traits<scalar_log_op<Scalar> >
00454 { enum { Cost = 5 * NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasLog }; };
00455
00461
00462
00463
00464
00465
00466
00467
00468
00469 template<typename Scalar>
00470 struct scalar_multiple_op {
00471 typedef typename packet_traits<Scalar>::type Packet;
00472
00473 EIGEN_STRONG_INLINE scalar_multiple_op(const scalar_multiple_op& other) : m_other(other.m_other) { }
00474 EIGEN_STRONG_INLINE scalar_multiple_op(const Scalar& other) : m_other(other) { }
00475 EIGEN_STRONG_INLINE Scalar operator() (const Scalar& a) const { return a * m_other; }
00476 EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const
00477 { return internal::pmul(a, pset1<Packet>(m_other)); }
00478 typename add_const_on_value_type<typename NumTraits<Scalar>::Nested>::type m_other;
00479 };
00480 template<typename Scalar>
00481 struct functor_traits<scalar_multiple_op<Scalar> >
00482 { enum { Cost = NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasMul }; };
00483
00484 template<typename Scalar1, typename Scalar2>
00485 struct scalar_multiple2_op {
00486 typedef typename scalar_product_traits<Scalar1,Scalar2>::ReturnType result_type;
00487 EIGEN_STRONG_INLINE scalar_multiple2_op(const scalar_multiple2_op& other) : m_other(other.m_other) { }
00488 EIGEN_STRONG_INLINE scalar_multiple2_op(const Scalar2& other) : m_other(other) { }
00489 EIGEN_STRONG_INLINE result_type operator() (const Scalar1& a) const { return a * m_other; }
00490 typename add_const_on_value_type<typename NumTraits<Scalar2>::Nested>::type m_other;
00491 };
00492 template<typename Scalar1,typename Scalar2>
00493 struct functor_traits<scalar_multiple2_op<Scalar1,Scalar2> >
00494 { enum { Cost = NumTraits<Scalar1>::MulCost, PacketAccess = false }; };
00495
00496 template<typename Scalar, bool IsInteger>
00497 struct scalar_quotient1_impl {
00498 typedef typename packet_traits<Scalar>::type Packet;
00499
00500 EIGEN_STRONG_INLINE scalar_quotient1_impl(const scalar_quotient1_impl& other) : m_other(other.m_other) { }
00501 EIGEN_STRONG_INLINE scalar_quotient1_impl(const Scalar& other) : m_other(static_cast<Scalar>(1) / other) {}
00502 EIGEN_STRONG_INLINE Scalar operator() (const Scalar& a) const { return a * m_other; }
00503 EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const
00504 { return internal::pmul(a, pset1<Packet>(m_other)); }
00505 const Scalar m_other;
00506 };
00507 template<typename Scalar>
00508 struct functor_traits<scalar_quotient1_impl<Scalar,false> >
00509 { enum { Cost = NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasMul }; };
00510
00511 template<typename Scalar>
00512 struct scalar_quotient1_impl<Scalar,true> {
00513
00514 EIGEN_STRONG_INLINE scalar_quotient1_impl(const scalar_quotient1_impl& other) : m_other(other.m_other) { }
00515 EIGEN_STRONG_INLINE scalar_quotient1_impl(const Scalar& other) : m_other(other) {}
00516 EIGEN_STRONG_INLINE Scalar operator() (const Scalar& a) const { return a / m_other; }
00517 typename add_const_on_value_type<typename NumTraits<Scalar>::Nested>::type m_other;
00518 };
00519 template<typename Scalar>
00520 struct functor_traits<scalar_quotient1_impl<Scalar,true> >
00521 { enum { Cost = 2 * NumTraits<Scalar>::MulCost, PacketAccess = false }; };
00522
00531 template<typename Scalar>
00532 struct scalar_quotient1_op : scalar_quotient1_impl<Scalar, NumTraits<Scalar>::IsInteger > {
00533 EIGEN_STRONG_INLINE scalar_quotient1_op(const Scalar& other)
00534 : scalar_quotient1_impl<Scalar, NumTraits<Scalar>::IsInteger >(other) {}
00535 };
00536 template<typename Scalar>
00537 struct functor_traits<scalar_quotient1_op<Scalar> >
00538 : functor_traits<scalar_quotient1_impl<Scalar, NumTraits<Scalar>::IsInteger> >
00539 {};
00540
00541
00542
00543 template<typename Scalar>
00544 struct scalar_constant_op {
00545 typedef typename packet_traits<Scalar>::type Packet;
00546 EIGEN_STRONG_INLINE scalar_constant_op(const scalar_constant_op& other) : m_other(other.m_other) { }
00547 EIGEN_STRONG_INLINE scalar_constant_op(const Scalar& other) : m_other(other) { }
00548 template<typename Index>
00549 EIGEN_STRONG_INLINE const Scalar operator() (Index, Index = 0) const { return m_other; }
00550 template<typename Index>
00551 EIGEN_STRONG_INLINE const Packet packetOp(Index, Index = 0) const { return internal::pset1<Packet>(m_other); }
00552 const Scalar m_other;
00553 };
00554 template<typename Scalar>
00555 struct functor_traits<scalar_constant_op<Scalar> >
00556
00557 { enum { Cost = 1, PacketAccess = packet_traits<Scalar>::Vectorizable, IsRepeatable = true }; };
00558
00559 template<typename Scalar> struct scalar_identity_op {
00560 EIGEN_EMPTY_STRUCT_CTOR(scalar_identity_op)
00561 template<typename Index>
00562 EIGEN_STRONG_INLINE const Scalar operator() (Index row, Index col) const { return row==col ? Scalar(1) : Scalar(0); }
00563 };
00564 template<typename Scalar>
00565 struct functor_traits<scalar_identity_op<Scalar> >
00566 { enum { Cost = NumTraits<Scalar>::AddCost, PacketAccess = false, IsRepeatable = true }; };
00567
00568 template <typename Scalar, bool RandomAccess> struct linspaced_op_impl;
00569
00570
00571
00572
00573
00574
00575 template <typename Scalar>
00576 struct linspaced_op_impl<Scalar,false>
00577 {
00578 typedef typename packet_traits<Scalar>::type Packet;
00579
00580 linspaced_op_impl(Scalar low, Scalar step) :
00581 m_low(low), m_step(step),
00582 m_packetStep(pset1<Packet>(packet_traits<Scalar>::size*step)),
00583 m_base(padd(pset1<Packet>(low),pmul(pset1<Packet>(step),plset<Scalar>(-packet_traits<Scalar>::size)))) {}
00584
00585 template<typename Index>
00586 EIGEN_STRONG_INLINE const Scalar operator() (Index i) const { return m_low+i*m_step; }
00587 template<typename Index>
00588 EIGEN_STRONG_INLINE const Packet packetOp(Index) const { return m_base = padd(m_base,m_packetStep); }
00589
00590 const Scalar m_low;
00591 const Scalar m_step;
00592 const Packet m_packetStep;
00593 mutable Packet m_base;
00594 };
00595
00596
00597
00598
00599 template <typename Scalar>
00600 struct linspaced_op_impl<Scalar,true>
00601 {
00602 typedef typename packet_traits<Scalar>::type Packet;
00603
00604 linspaced_op_impl(Scalar low, Scalar step) :
00605 m_low(low), m_step(step),
00606 m_lowPacket(pset1<Packet>(m_low)), m_stepPacket(pset1<Packet>(m_step)), m_interPacket(plset<Scalar>(0)) {}
00607
00608 template<typename Index>
00609 EIGEN_STRONG_INLINE const Scalar operator() (Index i) const { return m_low+i*m_step; }
00610
00611 template<typename Index>
00612 EIGEN_STRONG_INLINE const Packet packetOp(Index i) const
00613 { return internal::padd(m_lowPacket, pmul(m_stepPacket, padd(pset1<Packet>(i),m_interPacket))); }
00614
00615 const Scalar m_low;
00616 const Scalar m_step;
00617 const Packet m_lowPacket;
00618 const Packet m_stepPacket;
00619 const Packet m_interPacket;
00620 };
00621
00622
00623
00624
00625
00626
00627 template <typename Scalar, bool RandomAccess = true> struct linspaced_op;
00628 template <typename Scalar, bool RandomAccess> struct functor_traits< linspaced_op<Scalar,RandomAccess> >
00629 { enum { Cost = 1, PacketAccess = packet_traits<Scalar>::HasSetLinear, IsRepeatable = true }; };
00630 template <typename Scalar, bool RandomAccess> struct linspaced_op
00631 {
00632 typedef typename packet_traits<Scalar>::type Packet;
00633 linspaced_op(Scalar low, Scalar high, int num_steps) : impl((num_steps==1 ? high : low), (num_steps==1 ? Scalar() : (high-low)/(num_steps-1))) {}
00634
00635 template<typename Index>
00636 EIGEN_STRONG_INLINE const Scalar operator() (Index i) const { return impl(i); }
00637
00638
00639
00640 template<typename Index>
00641 EIGEN_STRONG_INLINE const Scalar operator() (Index row, Index col) const
00642 {
00643 eigen_assert(col==0 || row==0);
00644 return impl(col + row);
00645 }
00646
00647 template<typename Index>
00648 EIGEN_STRONG_INLINE const Packet packetOp(Index i) const { return impl.packetOp(i); }
00649
00650
00651
00652 template<typename Index>
00653 EIGEN_STRONG_INLINE const Packet packetOp(Index row, Index col) const
00654 {
00655 eigen_assert(col==0 || row==0);
00656 return impl.packetOp(col + row);
00657 }
00658
00659
00660
00661
00662 const linspaced_op_impl<Scalar,RandomAccess> impl;
00663 };
00664
00665
00666
00667
00668
00669 template<typename Functor> struct functor_has_linear_access { enum { ret = 1 }; };
00670 template<typename Scalar> struct functor_has_linear_access<scalar_identity_op<Scalar> > { enum { ret = 0 }; };
00671
00672
00673
00674
00675 template<typename Functor> struct functor_allows_mixing_real_and_complex { enum { ret = 0 }; };
00676 template<typename LhsScalar,typename RhsScalar> struct functor_allows_mixing_real_and_complex<scalar_product_op<LhsScalar,RhsScalar> > { enum { ret = 1 }; };
00677 template<typename LhsScalar,typename RhsScalar> struct functor_allows_mixing_real_and_complex<scalar_conj_product_op<LhsScalar,RhsScalar> > { enum { ret = 1 }; };
00678
00679
00684
00685 template<typename Scalar>
00686 struct scalar_add_op {
00687 typedef typename packet_traits<Scalar>::type Packet;
00688
00689 inline scalar_add_op(const scalar_add_op& other) : m_other(other.m_other) { }
00690 inline scalar_add_op(const Scalar& other) : m_other(other) { }
00691 inline Scalar operator() (const Scalar& a) const { return a + m_other; }
00692 inline const Packet packetOp(const Packet& a) const
00693 { return internal::padd(a, pset1<Packet>(m_other)); }
00694 const Scalar m_other;
00695 };
00696 template<typename Scalar>
00697 struct functor_traits<scalar_add_op<Scalar> >
00698 { enum { Cost = NumTraits<Scalar>::AddCost, PacketAccess = packet_traits<Scalar>::HasAdd }; };
00699
00704 template<typename Scalar> struct scalar_sqrt_op {
00705 EIGEN_EMPTY_STRUCT_CTOR(scalar_sqrt_op)
00706 inline const Scalar operator() (const Scalar& a) const { return sqrt(a); }
00707 typedef typename packet_traits<Scalar>::type Packet;
00708 inline Packet packetOp(const Packet& a) const { return internal::psqrt(a); }
00709 };
00710 template<typename Scalar>
00711 struct functor_traits<scalar_sqrt_op<Scalar> >
00712 { enum {
00713 Cost = 5 * NumTraits<Scalar>::MulCost,
00714 PacketAccess = packet_traits<Scalar>::HasSqrt
00715 };
00716 };
00717
00722 template<typename Scalar> struct scalar_cos_op {
00723 EIGEN_EMPTY_STRUCT_CTOR(scalar_cos_op)
00724 inline Scalar operator() (const Scalar& a) const { return cos(a); }
00725 typedef typename packet_traits<Scalar>::type Packet;
00726 inline Packet packetOp(const Packet& a) const { return internal::pcos(a); }
00727 };
00728 template<typename Scalar>
00729 struct functor_traits<scalar_cos_op<Scalar> >
00730 {
00731 enum {
00732 Cost = 5 * NumTraits<Scalar>::MulCost,
00733 PacketAccess = packet_traits<Scalar>::HasCos
00734 };
00735 };
00736
00741 template<typename Scalar> struct scalar_sin_op {
00742 EIGEN_EMPTY_STRUCT_CTOR(scalar_sin_op)
00743 inline const Scalar operator() (const Scalar& a) const { return sin(a); }
00744 typedef typename packet_traits<Scalar>::type Packet;
00745 inline Packet packetOp(const Packet& a) const { return internal::psin(a); }
00746 };
00747 template<typename Scalar>
00748 struct functor_traits<scalar_sin_op<Scalar> >
00749 {
00750 enum {
00751 Cost = 5 * NumTraits<Scalar>::MulCost,
00752 PacketAccess = packet_traits<Scalar>::HasSin
00753 };
00754 };
00755
00756
00761 template<typename Scalar> struct scalar_tan_op {
00762 EIGEN_EMPTY_STRUCT_CTOR(scalar_tan_op)
00763 inline const Scalar operator() (const Scalar& a) const { return tan(a); }
00764 typedef typename packet_traits<Scalar>::type Packet;
00765 inline Packet packetOp(const Packet& a) const { return internal::ptan(a); }
00766 };
00767 template<typename Scalar>
00768 struct functor_traits<scalar_tan_op<Scalar> >
00769 {
00770 enum {
00771 Cost = 5 * NumTraits<Scalar>::MulCost,
00772 PacketAccess = packet_traits<Scalar>::HasTan
00773 };
00774 };
00775
00780 template<typename Scalar> struct scalar_acos_op {
00781 EIGEN_EMPTY_STRUCT_CTOR(scalar_acos_op)
00782 inline const Scalar operator() (const Scalar& a) const { return acos(a); }
00783 typedef typename packet_traits<Scalar>::type Packet;
00784 inline Packet packetOp(const Packet& a) const { return internal::pacos(a); }
00785 };
00786 template<typename Scalar>
00787 struct functor_traits<scalar_acos_op<Scalar> >
00788 {
00789 enum {
00790 Cost = 5 * NumTraits<Scalar>::MulCost,
00791 PacketAccess = packet_traits<Scalar>::HasACos
00792 };
00793 };
00794
00799 template<typename Scalar> struct scalar_asin_op {
00800 EIGEN_EMPTY_STRUCT_CTOR(scalar_asin_op)
00801 inline const Scalar operator() (const Scalar& a) const { return asin(a); }
00802 typedef typename packet_traits<Scalar>::type Packet;
00803 inline Packet packetOp(const Packet& a) const { return internal::pasin(a); }
00804 };
00805 template<typename Scalar>
00806 struct functor_traits<scalar_asin_op<Scalar> >
00807 {
00808 enum {
00809 Cost = 5 * NumTraits<Scalar>::MulCost,
00810 PacketAccess = packet_traits<Scalar>::HasASin
00811 };
00812 };
00813
00818 template<typename Scalar>
00819 struct scalar_pow_op {
00820
00821 inline scalar_pow_op(const scalar_pow_op& other) : m_exponent(other.m_exponent) { }
00822 inline scalar_pow_op(const Scalar& exponent) : m_exponent(exponent) {}
00823 inline Scalar operator() (const Scalar& a) const { return internal::pow(a, m_exponent); }
00824 const Scalar m_exponent;
00825 };
00826 template<typename Scalar>
00827 struct functor_traits<scalar_pow_op<Scalar> >
00828 { enum { Cost = 5 * NumTraits<Scalar>::MulCost, PacketAccess = false }; };
00829
00834 template<typename Scalar>
00835 struct scalar_inverse_mult_op {
00836 scalar_inverse_mult_op(const Scalar& other) : m_other(other) {}
00837 inline Scalar operator() (const Scalar& a) const { return m_other / a; }
00838 template<typename Packet>
00839 inline const Packet packetOp(const Packet& a) const
00840 { return internal::pdiv(pset1<Packet>(m_other),a); }
00841 Scalar m_other;
00842 };
00843
00848 template<typename Scalar>
00849 struct scalar_inverse_op {
00850 EIGEN_EMPTY_STRUCT_CTOR(scalar_inverse_op)
00851 inline Scalar operator() (const Scalar& a) const { return Scalar(1)/a; }
00852 template<typename Packet>
00853 inline const Packet packetOp(const Packet& a) const
00854 { return internal::pdiv(pset1<Packet>(Scalar(1)),a); }
00855 };
00856 template<typename Scalar>
00857 struct functor_traits<scalar_inverse_op<Scalar> >
00858 { enum { Cost = NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasDiv }; };
00859
00864 template<typename Scalar>
00865 struct scalar_square_op {
00866 EIGEN_EMPTY_STRUCT_CTOR(scalar_square_op)
00867 inline Scalar operator() (const Scalar& a) const { return a*a; }
00868 template<typename Packet>
00869 inline const Packet packetOp(const Packet& a) const
00870 { return internal::pmul(a,a); }
00871 };
00872 template<typename Scalar>
00873 struct functor_traits<scalar_square_op<Scalar> >
00874 { enum { Cost = NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasMul }; };
00875
00880 template<typename Scalar>
00881 struct scalar_cube_op {
00882 EIGEN_EMPTY_STRUCT_CTOR(scalar_cube_op)
00883 inline Scalar operator() (const Scalar& a) const { return a*a*a; }
00884 template<typename Packet>
00885 inline const Packet packetOp(const Packet& a) const
00886 { return internal::pmul(a,pmul(a,a)); }
00887 };
00888 template<typename Scalar>
00889 struct functor_traits<scalar_cube_op<Scalar> >
00890 { enum { Cost = 2*NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasMul }; };
00891
00892
00893
00894 template<typename T>
00895 struct functor_traits<std::multiplies<T> >
00896 { enum { Cost = NumTraits<T>::MulCost, PacketAccess = false }; };
00897
00898 template<typename T>
00899 struct functor_traits<std::divides<T> >
00900 { enum { Cost = NumTraits<T>::MulCost, PacketAccess = false }; };
00901
00902 template<typename T>
00903 struct functor_traits<std::plus<T> >
00904 { enum { Cost = NumTraits<T>::AddCost, PacketAccess = false }; };
00905
00906 template<typename T>
00907 struct functor_traits<std::minus<T> >
00908 { enum { Cost = NumTraits<T>::AddCost, PacketAccess = false }; };
00909
00910 template<typename T>
00911 struct functor_traits<std::negate<T> >
00912 { enum { Cost = NumTraits<T>::AddCost, PacketAccess = false }; };
00913
00914 template<typename T>
00915 struct functor_traits<std::logical_or<T> >
00916 { enum { Cost = 1, PacketAccess = false }; };
00917
00918 template<typename T>
00919 struct functor_traits<std::logical_and<T> >
00920 { enum { Cost = 1, PacketAccess = false }; };
00921
00922 template<typename T>
00923 struct functor_traits<std::logical_not<T> >
00924 { enum { Cost = 1, PacketAccess = false }; };
00925
00926 template<typename T>
00927 struct functor_traits<std::greater<T> >
00928 { enum { Cost = 1, PacketAccess = false }; };
00929
00930 template<typename T>
00931 struct functor_traits<std::less<T> >
00932 { enum { Cost = 1, PacketAccess = false }; };
00933
00934 template<typename T>
00935 struct functor_traits<std::greater_equal<T> >
00936 { enum { Cost = 1, PacketAccess = false }; };
00937
00938 template<typename T>
00939 struct functor_traits<std::less_equal<T> >
00940 { enum { Cost = 1, PacketAccess = false }; };
00941
00942 template<typename T>
00943 struct functor_traits<std::equal_to<T> >
00944 { enum { Cost = 1, PacketAccess = false }; };
00945
00946 template<typename T>
00947 struct functor_traits<std::not_equal_to<T> >
00948 { enum { Cost = 1, PacketAccess = false }; };
00949
00950 template<typename T>
00951 struct functor_traits<std::binder2nd<T> >
00952 { enum { Cost = functor_traits<T>::Cost, PacketAccess = false }; };
00953
00954 template<typename T>
00955 struct functor_traits<std::binder1st<T> >
00956 { enum { Cost = functor_traits<T>::Cost, PacketAccess = false }; };
00957
00958 template<typename T>
00959 struct functor_traits<std::unary_negate<T> >
00960 { enum { Cost = 1 + functor_traits<T>::Cost, PacketAccess = false }; };
00961
00962 template<typename T>
00963 struct functor_traits<std::binary_negate<T> >
00964 { enum { Cost = 1 + functor_traits<T>::Cost, PacketAccess = false }; };
00965
00966 #ifdef EIGEN_STDEXT_SUPPORT
00967
00968 template<typename T0,typename T1>
00969 struct functor_traits<std::project1st<T0,T1> >
00970 { enum { Cost = 0, PacketAccess = false }; };
00971
00972 template<typename T0,typename T1>
00973 struct functor_traits<std::project2nd<T0,T1> >
00974 { enum { Cost = 0, PacketAccess = false }; };
00975
00976 template<typename T0,typename T1>
00977 struct functor_traits<std::select2nd<std::pair<T0,T1> > >
00978 { enum { Cost = 0, PacketAccess = false }; };
00979
00980 template<typename T0,typename T1>
00981 struct functor_traits<std::select1st<std::pair<T0,T1> > >
00982 { enum { Cost = 0, PacketAccess = false }; };
00983
00984 template<typename T0,typename T1>
00985 struct functor_traits<std::unary_compose<T0,T1> >
00986 { enum { Cost = functor_traits<T0>::Cost + functor_traits<T1>::Cost, PacketAccess = false }; };
00987
00988 template<typename T0,typename T1,typename T2>
00989 struct functor_traits<std::binary_compose<T0,T1,T2> >
00990 { enum { Cost = functor_traits<T0>::Cost + functor_traits<T1>::Cost + functor_traits<T2>::Cost, PacketAccess = false }; };
00991
00992 #endif // EIGEN_STDEXT_SUPPORT
00993
00994
00995
00996 #ifdef EIGEN_FUNCTORS_PLUGIN
00997 #include EIGEN_FUNCTORS_PLUGIN
00998 #endif
00999
01000 }
01001
01002 }
01003
01004 #endif // EIGEN_FUNCTORS_H