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
00032
00033
00034
00035
00036
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
00055
00056
00057
00058
00059
00060 template<typename LhsScalar,typename RhsScalar> struct scalar_product_op {
00061 enum {
00062 Vectorizable = is_same<LhsScalar,RhsScalar>::value && packet_traits<LhsScalar>::HasMul && packet_traits<RhsScalar>::HasMul
00063 };
00064 typedef typename scalar_product_traits<LhsScalar,RhsScalar>::ReturnType result_type;
00065 EIGEN_EMPTY_STRUCT_CTOR(scalar_product_op)
00066 EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const { return a * b; }
00067 template<typename Packet>
00068 EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
00069 { return internal::pmul(a,b); }
00070 template<typename Packet>
00071 EIGEN_STRONG_INLINE const result_type predux(const Packet& a) const
00072 { return internal::predux_mul(a); }
00073 };
00074 template<typename LhsScalar,typename RhsScalar>
00075 struct functor_traits<scalar_product_op<LhsScalar,RhsScalar> > {
00076 enum {
00077 Cost = (NumTraits<LhsScalar>::MulCost + NumTraits<RhsScalar>::MulCost)/2,
00078 PacketAccess = scalar_product_op<LhsScalar,RhsScalar>::Vectorizable
00079 };
00080 };
00081
00082
00083
00084
00085
00086
00087 template<typename Scalar> struct scalar_conj_product_op {
00088 enum { Conj = NumTraits<Scalar>::IsComplex };
00089 EIGEN_EMPTY_STRUCT_CTOR(scalar_conj_product_op)
00090 EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const
00091 { return conj_helper<Scalar,Scalar,Conj,false>().pmul(a,b); }
00092 template<typename Packet>
00093 EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
00094 { return conj_helper<Packet,Packet,Conj,false>().pmul(a,b); }
00095 };
00096 template<typename Scalar>
00097 struct functor_traits<scalar_conj_product_op<Scalar> > {
00098 enum {
00099 Cost = NumTraits<Scalar>::MulCost,
00100 PacketAccess = packet_traits<Scalar>::HasMul
00101 };
00102 };
00103
00104
00105
00106
00107
00108
00109 template<typename Scalar> struct scalar_min_op {
00110 EIGEN_EMPTY_STRUCT_CTOR(scalar_min_op)
00111 EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return std::min(a, b); }
00112 template<typename Packet>
00113 EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
00114 { return internal::pmin(a,b); }
00115 template<typename Packet>
00116 EIGEN_STRONG_INLINE const Scalar predux(const Packet& a) const
00117 { return internal::predux_min(a); }
00118 };
00119 template<typename Scalar>
00120 struct functor_traits<scalar_min_op<Scalar> > {
00121 enum {
00122 Cost = NumTraits<Scalar>::AddCost,
00123 PacketAccess = packet_traits<Scalar>::HasMin
00124 };
00125 };
00126
00127
00128
00129
00130
00131
00132 template<typename Scalar> struct scalar_max_op {
00133 EIGEN_EMPTY_STRUCT_CTOR(scalar_max_op)
00134 EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return std::max(a, b); }
00135 template<typename Packet>
00136 EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
00137 { return internal::pmax(a,b); }
00138 template<typename Packet>
00139 EIGEN_STRONG_INLINE const Scalar predux(const Packet& a) const
00140 { return internal::predux_max(a); }
00141 };
00142 template<typename Scalar>
00143 struct functor_traits<scalar_max_op<Scalar> > {
00144 enum {
00145 Cost = NumTraits<Scalar>::AddCost,
00146 PacketAccess = packet_traits<Scalar>::HasMax
00147 };
00148 };
00149
00150
00151
00152
00153
00154
00155 template<typename Scalar> struct scalar_hypot_op {
00156 EIGEN_EMPTY_STRUCT_CTOR(scalar_hypot_op)
00157
00158 EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& _x, const Scalar& _y) const
00159 {
00160 Scalar p = std::max(_x, _y);
00161 Scalar q = std::min(_x, _y);
00162 Scalar qp = q/p;
00163 return p * sqrt(Scalar(1) + qp*qp);
00164 }
00165 };
00166 template<typename Scalar>
00167 struct functor_traits<scalar_hypot_op<Scalar> > {
00168 enum { Cost = 5 * NumTraits<Scalar>::MulCost, PacketAccess=0 };
00169 };
00170
00171
00172
00173
00174
00175
00176
00177
00178 template<typename Scalar> struct scalar_difference_op {
00179 EIGEN_EMPTY_STRUCT_CTOR(scalar_difference_op)
00180 EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return a - b; }
00181 template<typename Packet>
00182 EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
00183 { return internal::psub(a,b); }
00184 };
00185 template<typename Scalar>
00186 struct functor_traits<scalar_difference_op<Scalar> > {
00187 enum {
00188 Cost = NumTraits<Scalar>::AddCost,
00189 PacketAccess = packet_traits<Scalar>::HasSub
00190 };
00191 };
00192
00193
00194
00195
00196
00197
00198 template<typename Scalar> struct scalar_quotient_op {
00199 EIGEN_EMPTY_STRUCT_CTOR(scalar_quotient_op)
00200 EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return a / b; }
00201 template<typename Packet>
00202 EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
00203 { return internal::pdiv(a,b); }
00204 };
00205 template<typename Scalar>
00206 struct functor_traits<scalar_quotient_op<Scalar> > {
00207 enum {
00208 Cost = 2 * NumTraits<Scalar>::MulCost,
00209 PacketAccess = packet_traits<Scalar>::HasDiv
00210 };
00211 };
00212
00213
00214
00215
00216
00217
00218
00219
00220 template<typename Scalar> struct scalar_opposite_op {
00221 EIGEN_EMPTY_STRUCT_CTOR(scalar_opposite_op)
00222 EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a) const { return -a; }
00223 template<typename Packet>
00224 EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const
00225 { return internal::pnegate(a); }
00226 };
00227 template<typename Scalar>
00228 struct functor_traits<scalar_opposite_op<Scalar> >
00229 { enum {
00230 Cost = NumTraits<Scalar>::AddCost,
00231 PacketAccess = packet_traits<Scalar>::HasNegate };
00232 };
00233
00234
00235
00236
00237
00238
00239 template<typename Scalar> struct scalar_abs_op {
00240 EIGEN_EMPTY_STRUCT_CTOR(scalar_abs_op)
00241 typedef typename NumTraits<Scalar>::Real result_type;
00242 EIGEN_STRONG_INLINE const result_type operator() (const Scalar& a) const { return abs(a); }
00243 template<typename Packet>
00244 EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const
00245 { return internal::pabs(a); }
00246 };
00247 template<typename Scalar>
00248 struct functor_traits<scalar_abs_op<Scalar> >
00249 {
00250 enum {
00251 Cost = NumTraits<Scalar>::AddCost,
00252 PacketAccess = packet_traits<Scalar>::HasAbs
00253 };
00254 };
00255
00256
00257
00258
00259
00260
00261 template<typename Scalar> struct scalar_abs2_op {
00262 EIGEN_EMPTY_STRUCT_CTOR(scalar_abs2_op)
00263 typedef typename NumTraits<Scalar>::Real result_type;
00264 EIGEN_STRONG_INLINE const result_type operator() (const Scalar& a) const { return abs2(a); }
00265 template<typename Packet>
00266 EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const
00267 { return internal::pmul(a,a); }
00268 };
00269 template<typename Scalar>
00270 struct functor_traits<scalar_abs2_op<Scalar> >
00271 { enum { Cost = NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasAbs2 }; };
00272
00273
00274
00275
00276
00277
00278 template<typename Scalar> struct scalar_conjugate_op {
00279 EIGEN_EMPTY_STRUCT_CTOR(scalar_conjugate_op)
00280 EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a) const { return conj(a); }
00281 template<typename Packet>
00282 EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const { return internal::pconj(a); }
00283 };
00284 template<typename Scalar>
00285 struct functor_traits<scalar_conjugate_op<Scalar> >
00286 {
00287 enum {
00288 Cost = NumTraits<Scalar>::IsComplex ? NumTraits<Scalar>::AddCost : 0,
00289 PacketAccess = packet_traits<Scalar>::HasConj
00290 };
00291 };
00292
00293
00294
00295
00296
00297
00298 template<typename Scalar, typename NewType>
00299 struct scalar_cast_op {
00300 EIGEN_EMPTY_STRUCT_CTOR(scalar_cast_op)
00301 typedef NewType result_type;
00302 EIGEN_STRONG_INLINE const NewType operator() (const Scalar& a) const { return cast<Scalar, NewType>(a); }
00303 };
00304 template<typename Scalar, typename NewType>
00305 struct functor_traits<scalar_cast_op<Scalar,NewType> >
00306 { enum { Cost = is_same<Scalar, NewType>::value ? 0 : NumTraits<NewType>::AddCost, PacketAccess = false }; };
00307
00308
00309
00310
00311
00312
00313 template<typename Scalar>
00314 struct scalar_real_op {
00315 EIGEN_EMPTY_STRUCT_CTOR(scalar_real_op)
00316 typedef typename NumTraits<Scalar>::Real result_type;
00317 EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return real(a); }
00318 };
00319 template<typename Scalar>
00320 struct functor_traits<scalar_real_op<Scalar> >
00321 { enum { Cost = 0, PacketAccess = false }; };
00322
00323
00324
00325
00326
00327
00328 template<typename Scalar>
00329 struct scalar_imag_op {
00330 EIGEN_EMPTY_STRUCT_CTOR(scalar_imag_op)
00331 typedef typename NumTraits<Scalar>::Real result_type;
00332 EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return imag(a); }
00333 };
00334 template<typename Scalar>
00335 struct functor_traits<scalar_imag_op<Scalar> >
00336 { enum { Cost = 0, PacketAccess = false }; };
00337
00338
00339
00340
00341
00342
00343 template<typename Scalar>
00344 struct scalar_real_ref_op {
00345 EIGEN_EMPTY_STRUCT_CTOR(scalar_real_ref_op)
00346 typedef typename NumTraits<Scalar>::Real result_type;
00347 EIGEN_STRONG_INLINE result_type& operator() (const Scalar& a) const { return real_ref(*const_cast<Scalar*>(&a)); }
00348 };
00349 template<typename Scalar>
00350 struct functor_traits<scalar_real_ref_op<Scalar> >
00351 { enum { Cost = 0, PacketAccess = false }; };
00352
00353
00354
00355
00356
00357
00358 template<typename Scalar>
00359 struct scalar_imag_ref_op {
00360 EIGEN_EMPTY_STRUCT_CTOR(scalar_imag_ref_op)
00361 typedef typename NumTraits<Scalar>::Real result_type;
00362 EIGEN_STRONG_INLINE result_type& operator() (const Scalar& a) const { return imag_ref(*const_cast<Scalar*>(&a)); }
00363 };
00364 template<typename Scalar>
00365 struct functor_traits<scalar_imag_ref_op<Scalar> >
00366 { enum { Cost = 0, PacketAccess = false }; };
00367
00368
00369
00370
00371
00372
00373
00374 template<typename Scalar> struct scalar_exp_op {
00375 EIGEN_EMPTY_STRUCT_CTOR(scalar_exp_op)
00376 inline const Scalar operator() (const Scalar& a) const { return exp(a); }
00377 typedef typename packet_traits<Scalar>::type Packet;
00378 inline Packet packetOp(const Packet& a) const { return internal::pexp(a); }
00379 };
00380 template<typename Scalar>
00381 struct functor_traits<scalar_exp_op<Scalar> >
00382 { enum { Cost = 5 * NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasExp }; };
00383
00384
00385
00386
00387
00388
00389
00390 template<typename Scalar> struct scalar_log_op {
00391 EIGEN_EMPTY_STRUCT_CTOR(scalar_log_op)
00392 inline const Scalar operator() (const Scalar& a) const { return log(a); }
00393 typedef typename packet_traits<Scalar>::type Packet;
00394 inline Packet packetOp(const Packet& a) const { return internal::plog(a); }
00395 };
00396 template<typename Scalar>
00397 struct functor_traits<scalar_log_op<Scalar> >
00398 { enum { Cost = 5 * NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasLog }; };
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413 template<typename Scalar>
00414 struct scalar_multiple_op {
00415 typedef typename packet_traits<Scalar>::type Packet;
00416
00417 EIGEN_STRONG_INLINE scalar_multiple_op(const scalar_multiple_op& other) : m_other(other.m_other) { }
00418 EIGEN_STRONG_INLINE scalar_multiple_op(const Scalar& other) : m_other(other) { }
00419 EIGEN_STRONG_INLINE Scalar operator() (const Scalar& a) const { return a * m_other; }
00420 EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const
00421 { return internal::pmul(a, pset1<Packet>(m_other)); }
00422 typename add_const_on_value_type<typename NumTraits<Scalar>::Nested>::type m_other;
00423 };
00424 template<typename Scalar>
00425 struct functor_traits<scalar_multiple_op<Scalar> >
00426 { enum { Cost = NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasMul }; };
00427
00428 template<typename Scalar1, typename Scalar2>
00429 struct scalar_multiple2_op {
00430 typedef typename scalar_product_traits<Scalar1,Scalar2>::ReturnType result_type;
00431 EIGEN_STRONG_INLINE scalar_multiple2_op(const scalar_multiple2_op& other) : m_other(other.m_other) { }
00432 EIGEN_STRONG_INLINE scalar_multiple2_op(const Scalar2& other) : m_other(other) { }
00433 EIGEN_STRONG_INLINE result_type operator() (const Scalar1& a) const { return a * m_other; }
00434 typename add_const_on_value_type<typename NumTraits<Scalar2>::Nested>::type m_other;
00435 };
00436 template<typename Scalar1,typename Scalar2>
00437 struct functor_traits<scalar_multiple2_op<Scalar1,Scalar2> >
00438 { enum { Cost = NumTraits<Scalar1>::MulCost, PacketAccess = false }; };
00439
00440 template<typename Scalar, bool IsInteger>
00441 struct scalar_quotient1_impl {
00442 typedef typename packet_traits<Scalar>::type Packet;
00443
00444 EIGEN_STRONG_INLINE scalar_quotient1_impl(const scalar_quotient1_impl& other) : m_other(other.m_other) { }
00445 EIGEN_STRONG_INLINE scalar_quotient1_impl(const Scalar& other) : m_other(static_cast<Scalar>(1) / other) {}
00446 EIGEN_STRONG_INLINE Scalar operator() (const Scalar& a) const { return a * m_other; }
00447 EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const
00448 { return internal::pmul(a, pset1<Packet>(m_other)); }
00449 const Scalar m_other;
00450 };
00451 template<typename Scalar>
00452 struct functor_traits<scalar_quotient1_impl<Scalar,false> >
00453 { enum { Cost = NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasMul }; };
00454
00455 template<typename Scalar>
00456 struct scalar_quotient1_impl<Scalar,true> {
00457
00458 EIGEN_STRONG_INLINE scalar_quotient1_impl(const scalar_quotient1_impl& other) : m_other(other.m_other) { }
00459 EIGEN_STRONG_INLINE scalar_quotient1_impl(const Scalar& other) : m_other(other) {}
00460 EIGEN_STRONG_INLINE Scalar operator() (const Scalar& a) const { return a / m_other; }
00461 typename add_const_on_value_type<typename NumTraits<Scalar>::Nested>::type m_other;
00462 };
00463 template<typename Scalar>
00464 struct functor_traits<scalar_quotient1_impl<Scalar,true> >
00465 { enum { Cost = 2 * NumTraits<Scalar>::MulCost, PacketAccess = false }; };
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475 template<typename Scalar>
00476 struct scalar_quotient1_op : scalar_quotient1_impl<Scalar, NumTraits<Scalar>::IsInteger > {
00477 EIGEN_STRONG_INLINE scalar_quotient1_op(const Scalar& other)
00478 : scalar_quotient1_impl<Scalar, NumTraits<Scalar>::IsInteger >(other) {}
00479 };
00480 template<typename Scalar>
00481 struct functor_traits<scalar_quotient1_op<Scalar> >
00482 : functor_traits<scalar_quotient1_impl<Scalar, NumTraits<Scalar>::IsInteger> >
00483 {};
00484
00485
00486
00487 template<typename Scalar>
00488 struct scalar_constant_op {
00489 typedef typename packet_traits<Scalar>::type Packet;
00490 EIGEN_STRONG_INLINE scalar_constant_op(const scalar_constant_op& other) : m_other(other.m_other) { }
00491 EIGEN_STRONG_INLINE scalar_constant_op(const Scalar& other) : m_other(other) { }
00492 template<typename Index>
00493 EIGEN_STRONG_INLINE const Scalar operator() (Index, Index = 0) const { return m_other; }
00494 template<typename Index>
00495 EIGEN_STRONG_INLINE const Packet packetOp(Index, Index = 0) const { return internal::pset1<Packet>(m_other); }
00496 const Scalar m_other;
00497 };
00498 template<typename Scalar>
00499 struct functor_traits<scalar_constant_op<Scalar> >
00500
00501 { enum { Cost = 1, PacketAccess = packet_traits<Scalar>::Vectorizable, IsRepeatable = true }; };
00502
00503 template<typename Scalar> struct scalar_identity_op {
00504 EIGEN_EMPTY_STRUCT_CTOR(scalar_identity_op)
00505 template<typename Index>
00506 EIGEN_STRONG_INLINE const Scalar operator() (Index row, Index col) const { return row==col ? Scalar(1) : Scalar(0); }
00507 };
00508 template<typename Scalar>
00509 struct functor_traits<scalar_identity_op<Scalar> >
00510 { enum { Cost = NumTraits<Scalar>::AddCost, PacketAccess = false, IsRepeatable = true }; };
00511
00512 template <typename Scalar, bool RandomAccess> struct linspaced_op_impl;
00513
00514
00515
00516
00517
00518
00519 template <typename Scalar>
00520 struct linspaced_op_impl<Scalar,false>
00521 {
00522 typedef typename packet_traits<Scalar>::type Packet;
00523
00524 linspaced_op_impl(Scalar low, Scalar step) :
00525 m_low(low), m_step(step),
00526 m_packetStep(pset1<Packet>(packet_traits<Scalar>::size*step)),
00527 m_base(padd(pset1<Packet>(low),pmul(pset1<Packet>(step),plset<Scalar>(-packet_traits<Scalar>::size)))) {}
00528
00529 template<typename Index>
00530 EIGEN_STRONG_INLINE const Scalar operator() (Index i) const { return m_low+i*m_step; }
00531 template<typename Index>
00532 EIGEN_STRONG_INLINE const Packet packetOp(Index) const { return m_base = padd(m_base,m_packetStep); }
00533
00534 const Scalar m_low;
00535 const Scalar m_step;
00536 const Packet m_packetStep;
00537 mutable Packet m_base;
00538 };
00539
00540
00541
00542
00543 template <typename Scalar>
00544 struct linspaced_op_impl<Scalar,true>
00545 {
00546 typedef typename packet_traits<Scalar>::type Packet;
00547
00548 linspaced_op_impl(Scalar low, Scalar step) :
00549 m_low(low), m_step(step),
00550 m_lowPacket(pset1<Packet>(m_low)), m_stepPacket(pset1<Packet>(m_step)), m_interPacket(plset<Scalar>(0)) {}
00551
00552 template<typename Index>
00553 EIGEN_STRONG_INLINE const Scalar operator() (Index i) const { return m_low+i*m_step; }
00554
00555 template<typename Index>
00556 EIGEN_STRONG_INLINE const Packet packetOp(Index i) const
00557 { return internal::padd(m_lowPacket, pmul(m_stepPacket, padd(pset1<Packet>(i),m_interPacket))); }
00558
00559 const Scalar m_low;
00560 const Scalar m_step;
00561 const Packet m_lowPacket;
00562 const Packet m_stepPacket;
00563 const Packet m_interPacket;
00564 };
00565
00566
00567
00568
00569
00570
00571 template <typename Scalar, bool RandomAccess = true> struct linspaced_op;
00572 template <typename Scalar, bool RandomAccess> struct functor_traits< linspaced_op<Scalar,RandomAccess> >
00573 { enum { Cost = 1, PacketAccess = packet_traits<Scalar>::HasSetLinear, IsRepeatable = true }; };
00574 template <typename Scalar, bool RandomAccess> struct linspaced_op
00575 {
00576 typedef typename packet_traits<Scalar>::type Packet;
00577 linspaced_op(Scalar low, Scalar high, int num_steps) : impl(low, (high-low)/(num_steps-1)) {}
00578
00579 template<typename Index>
00580 EIGEN_STRONG_INLINE const Scalar operator() (Index i) const { return impl(i); }
00581
00582
00583
00584 template<typename Index>
00585 EIGEN_STRONG_INLINE const Scalar operator() (Index row, Index col) const
00586 {
00587 eigen_assert(col==0 || row==0);
00588 return impl(col + row);
00589 }
00590
00591 template<typename Index>
00592 EIGEN_STRONG_INLINE const Packet packetOp(Index i) const { return impl.packetOp(i); }
00593
00594
00595
00596 template<typename Index>
00597 EIGEN_STRONG_INLINE const Packet packetOp(Index row, Index col) const
00598 {
00599 eigen_assert(col==0 || row==0);
00600 return impl(col + row);
00601 }
00602
00603
00604
00605
00606 const linspaced_op_impl<Scalar,RandomAccess> impl;
00607 };
00608
00609
00610
00611
00612
00613 template<typename Functor> struct functor_has_linear_access { enum { ret = 1 }; };
00614 template<typename Scalar> struct functor_has_linear_access<scalar_identity_op<Scalar> > { enum { ret = 0 }; };
00615
00616
00617
00618
00619 template<typename Functor> struct functor_allows_mixing_real_and_complex { enum { ret = 0 }; };
00620 template<typename LhsScalar,typename RhsScalar> struct functor_allows_mixing_real_and_complex<scalar_product_op<LhsScalar,RhsScalar> > { enum { ret = 1 }; };
00621
00622
00623
00624
00625
00626
00627
00628 template<typename Scalar>
00629 struct scalar_add_op {
00630 typedef typename packet_traits<Scalar>::type Packet;
00631
00632 inline scalar_add_op(const scalar_add_op& other) : m_other(other.m_other) { }
00633 inline scalar_add_op(const Scalar& other) : m_other(other) { }
00634 inline Scalar operator() (const Scalar& a) const { return a + m_other; }
00635 inline const Packet packetOp(const Packet& a) const
00636 { return internal::padd(a, pset1<Packet>(m_other)); }
00637 const Scalar m_other;
00638 };
00639 template<typename Scalar>
00640 struct functor_traits<scalar_add_op<Scalar> >
00641 { enum { Cost = NumTraits<Scalar>::AddCost, PacketAccess = packet_traits<Scalar>::HasAdd }; };
00642
00643
00644
00645
00646
00647 template<typename Scalar> struct scalar_sqrt_op {
00648 EIGEN_EMPTY_STRUCT_CTOR(scalar_sqrt_op)
00649 inline const Scalar operator() (const Scalar& a) const { return sqrt(a); }
00650 typedef typename packet_traits<Scalar>::type Packet;
00651 inline Packet packetOp(const Packet& a) const { return internal::psqrt(a); }
00652 };
00653 template<typename Scalar>
00654 struct functor_traits<scalar_sqrt_op<Scalar> >
00655 { enum {
00656 Cost = 5 * NumTraits<Scalar>::MulCost,
00657 PacketAccess = packet_traits<Scalar>::HasSqrt
00658 };
00659 };
00660
00661
00662
00663
00664
00665 template<typename Scalar> struct scalar_cos_op {
00666 EIGEN_EMPTY_STRUCT_CTOR(scalar_cos_op)
00667 inline Scalar operator() (const Scalar& a) const { return cos(a); }
00668 typedef typename packet_traits<Scalar>::type Packet;
00669 inline Packet packetOp(const Packet& a) const { return internal::pcos(a); }
00670 };
00671 template<typename Scalar>
00672 struct functor_traits<scalar_cos_op<Scalar> >
00673 {
00674 enum {
00675 Cost = 5 * NumTraits<Scalar>::MulCost,
00676 PacketAccess = packet_traits<Scalar>::HasCos
00677 };
00678 };
00679
00680
00681
00682
00683
00684 template<typename Scalar> struct scalar_sin_op {
00685 EIGEN_EMPTY_STRUCT_CTOR(scalar_sin_op)
00686 inline const Scalar operator() (const Scalar& a) const { return sin(a); }
00687 typedef typename packet_traits<Scalar>::type Packet;
00688 inline Packet packetOp(const Packet& a) const { return internal::psin(a); }
00689 };
00690 template<typename Scalar>
00691 struct functor_traits<scalar_sin_op<Scalar> >
00692 {
00693 enum {
00694 Cost = 5 * NumTraits<Scalar>::MulCost,
00695 PacketAccess = packet_traits<Scalar>::HasSin
00696 };
00697 };
00698
00699
00700
00701
00702
00703 template<typename Scalar>
00704 struct scalar_pow_op {
00705
00706 inline scalar_pow_op(const scalar_pow_op& other) : m_exponent(other.m_exponent) { }
00707 inline scalar_pow_op(const Scalar& exponent) : m_exponent(exponent) {}
00708 inline Scalar operator() (const Scalar& a) const { return internal::pow(a, m_exponent); }
00709 const Scalar m_exponent;
00710 };
00711 template<typename Scalar>
00712 struct functor_traits<scalar_pow_op<Scalar> >
00713 { enum { Cost = 5 * NumTraits<Scalar>::MulCost, PacketAccess = false }; };
00714
00715
00716
00717
00718
00719 template<typename Scalar>
00720 struct scalar_inverse_op {
00721 EIGEN_EMPTY_STRUCT_CTOR(scalar_inverse_op)
00722 inline Scalar operator() (const Scalar& a) const { return Scalar(1)/a; }
00723 template<typename Packet>
00724 inline const Packet packetOp(const Packet& a) const
00725 { return internal::pdiv(pset1<Packet>(Scalar(1)),a); }
00726 };
00727 template<typename Scalar>
00728 struct functor_traits<scalar_inverse_op<Scalar> >
00729 { enum { Cost = NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasDiv }; };
00730
00731
00732
00733
00734
00735 template<typename Scalar>
00736 struct scalar_square_op {
00737 EIGEN_EMPTY_STRUCT_CTOR(scalar_square_op)
00738 inline Scalar operator() (const Scalar& a) const { return a*a; }
00739 template<typename Packet>
00740 inline const Packet packetOp(const Packet& a) const
00741 { return internal::pmul(a,a); }
00742 };
00743 template<typename Scalar>
00744 struct functor_traits<scalar_square_op<Scalar> >
00745 { enum { Cost = NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasMul }; };
00746
00747
00748
00749
00750
00751 template<typename Scalar>
00752 struct scalar_cube_op {
00753 EIGEN_EMPTY_STRUCT_CTOR(scalar_cube_op)
00754 inline Scalar operator() (const Scalar& a) const { return a*a*a; }
00755 template<typename Packet>
00756 inline const Packet packetOp(const Packet& a) const
00757 { return internal::pmul(a,pmul(a,a)); }
00758 };
00759 template<typename Scalar>
00760 struct functor_traits<scalar_cube_op<Scalar> >
00761 { enum { Cost = 2*NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasMul }; };
00762
00763
00764
00765 template<typename T>
00766 struct functor_traits<std::multiplies<T> >
00767 { enum { Cost = NumTraits<T>::MulCost, PacketAccess = false }; };
00768
00769 template<typename T>
00770 struct functor_traits<std::divides<T> >
00771 { enum { Cost = NumTraits<T>::MulCost, PacketAccess = false }; };
00772
00773 template<typename T>
00774 struct functor_traits<std::plus<T> >
00775 { enum { Cost = NumTraits<T>::AddCost, PacketAccess = false }; };
00776
00777 template<typename T>
00778 struct functor_traits<std::minus<T> >
00779 { enum { Cost = NumTraits<T>::AddCost, PacketAccess = false }; };
00780
00781 template<typename T>
00782 struct functor_traits<std::negate<T> >
00783 { enum { Cost = NumTraits<T>::AddCost, PacketAccess = false }; };
00784
00785 template<typename T>
00786 struct functor_traits<std::logical_or<T> >
00787 { enum { Cost = 1, PacketAccess = false }; };
00788
00789 template<typename T>
00790 struct functor_traits<std::logical_and<T> >
00791 { enum { Cost = 1, PacketAccess = false }; };
00792
00793 template<typename T>
00794 struct functor_traits<std::logical_not<T> >
00795 { enum { Cost = 1, PacketAccess = false }; };
00796
00797 template<typename T>
00798 struct functor_traits<std::greater<T> >
00799 { enum { Cost = 1, PacketAccess = false }; };
00800
00801 template<typename T>
00802 struct functor_traits<std::less<T> >
00803 { enum { Cost = 1, PacketAccess = false }; };
00804
00805 template<typename T>
00806 struct functor_traits<std::greater_equal<T> >
00807 { enum { Cost = 1, PacketAccess = false }; };
00808
00809 template<typename T>
00810 struct functor_traits<std::less_equal<T> >
00811 { enum { Cost = 1, PacketAccess = false }; };
00812
00813 template<typename T>
00814 struct functor_traits<std::equal_to<T> >
00815 { enum { Cost = 1, PacketAccess = false }; };
00816
00817 template<typename T>
00818 struct functor_traits<std::not_equal_to<T> >
00819 { enum { Cost = 1, PacketAccess = false }; };
00820
00821 template<typename T>
00822 struct functor_traits<std::binder2nd<T> >
00823 { enum { Cost = functor_traits<T>::Cost, PacketAccess = false }; };
00824
00825 template<typename T>
00826 struct functor_traits<std::binder1st<T> >
00827 { enum { Cost = functor_traits<T>::Cost, PacketAccess = false }; };
00828
00829 template<typename T>
00830 struct functor_traits<std::unary_negate<T> >
00831 { enum { Cost = 1 + functor_traits<T>::Cost, PacketAccess = false }; };
00832
00833 template<typename T>
00834 struct functor_traits<std::binary_negate<T> >
00835 { enum { Cost = 1 + functor_traits<T>::Cost, PacketAccess = false }; };
00836
00837 #ifdef EIGEN_STDEXT_SUPPORT
00838
00839 template<typename T0,typename T1>
00840 struct functor_traits<std::project1st<T0,T1> >
00841 { enum { Cost = 0, PacketAccess = false }; };
00842
00843 template<typename T0,typename T1>
00844 struct functor_traits<std::project2nd<T0,T1> >
00845 { enum { Cost = 0, PacketAccess = false }; };
00846
00847 template<typename T0,typename T1>
00848 struct functor_traits<std::select2nd<std::pair<T0,T1> > >
00849 { enum { Cost = 0, PacketAccess = false }; };
00850
00851 template<typename T0,typename T1>
00852 struct functor_traits<std::select1st<std::pair<T0,T1> > >
00853 { enum { Cost = 0, PacketAccess = false }; };
00854
00855 template<typename T0,typename T1>
00856 struct functor_traits<std::unary_compose<T0,T1> >
00857 { enum { Cost = functor_traits<T0>::Cost + functor_traits<T1>::Cost, PacketAccess = false }; };
00858
00859 template<typename T0,typename T1,typename T2>
00860 struct functor_traits<std::binary_compose<T0,T1,T2> >
00861 { enum { Cost = functor_traits<T0>::Cost + functor_traits<T1>::Cost + functor_traits<T2>::Cost, PacketAccess = false }; };
00862
00863 #endif // EIGEN_STDEXT_SUPPORT
00864
00865
00866
00867 #ifdef EIGEN_FUNCTORS_PLUGIN
00868 #include EIGEN_FUNCTORS_PLUGIN
00869 #endif
00870
00871 }
00872
00873 #endif // EIGEN_FUNCTORS_H