Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Functors.h
00001 // This file is part of Eigen, a lightweight C++ template library 00002 // for linear algebra. 00003 // 00004 // Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr> 00005 // 00006 // This Source Code Form is subject to the terms of the Mozilla 00007 // Public License v. 2.0. If a copy of the MPL was not distributed 00008 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 00009 00010 #ifndef EIGEN_FUNCTORS_H 00011 #define EIGEN_FUNCTORS_H 00012 00013 namespace Eigen { 00014 00015 namespace internal { 00016 00017 // associative functors: 00018 00019 /** \internal 00020 * \brief Template functor to compute the sum of two scalars 00021 * 00022 * \sa class CwiseBinaryOp, MatrixBase::operator+, class VectorwiseOp, MatrixBase::sum() 00023 */ 00024 template<typename Scalar> struct scalar_sum_op { 00025 EIGEN_EMPTY_STRUCT_CTOR(scalar_sum_op) 00026 EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return a + b; } 00027 template<typename Packet> 00028 EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const 00029 { return internal::padd(a,b); } 00030 template<typename Packet> 00031 EIGEN_STRONG_INLINE const Scalar predux(const Packet& a) const 00032 { return internal::predux(a); } 00033 }; 00034 template<typename Scalar> 00035 struct functor_traits<scalar_sum_op<Scalar> > { 00036 enum { 00037 Cost = NumTraits<Scalar>::AddCost, 00038 PacketAccess = packet_traits<Scalar>::HasAdd 00039 }; 00040 }; 00041 00042 /** \internal 00043 * \brief Template functor to compute the product of two scalars 00044 * 00045 * \sa class CwiseBinaryOp, Cwise::operator*(), class VectorwiseOp, MatrixBase::redux() 00046 */ 00047 template<typename LhsScalar,typename RhsScalar> struct scalar_product_op { 00048 enum { 00049 // TODO vectorize mixed product 00050 Vectorizable = is_same<LhsScalar,RhsScalar>::value && packet_traits<LhsScalar>::HasMul && packet_traits<RhsScalar>::HasMul 00051 }; 00052 typedef typename scalar_product_traits<LhsScalar,RhsScalar>::ReturnType result_type; 00053 EIGEN_EMPTY_STRUCT_CTOR(scalar_product_op) 00054 EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const { return a * b; } 00055 template<typename Packet> 00056 EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const 00057 { return internal::pmul(a,b); } 00058 template<typename Packet> 00059 EIGEN_STRONG_INLINE const result_type predux(const Packet& a) const 00060 { return internal::predux_mul(a); } 00061 }; 00062 template<typename LhsScalar,typename RhsScalar> 00063 struct functor_traits<scalar_product_op<LhsScalar,RhsScalar> > { 00064 enum { 00065 Cost = (NumTraits<LhsScalar>::MulCost + NumTraits<RhsScalar>::MulCost)/2, // rough estimate! 00066 PacketAccess = scalar_product_op<LhsScalar,RhsScalar>::Vectorizable 00067 }; 00068 }; 00069 00070 /** \internal 00071 * \brief Template functor to compute the conjugate product of two scalars 00072 * 00073 * This is a short cut for conj(x) * y which is needed for optimization purpose; in Eigen2 support mode, this becomes x * conj(y) 00074 */ 00075 template<typename LhsScalar,typename RhsScalar> struct scalar_conj_product_op { 00076 00077 enum { 00078 Conj = NumTraits<LhsScalar>::IsComplex 00079 }; 00080 00081 typedef typename scalar_product_traits<LhsScalar,RhsScalar>::ReturnType result_type; 00082 00083 EIGEN_EMPTY_STRUCT_CTOR(scalar_conj_product_op) 00084 EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const 00085 { return conj_helper<LhsScalar,RhsScalar,Conj,false>().pmul(a,b); } 00086 00087 template<typename Packet> 00088 EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const 00089 { return conj_helper<Packet,Packet,Conj,false>().pmul(a,b); } 00090 }; 00091 template<typename LhsScalar,typename RhsScalar> 00092 struct functor_traits<scalar_conj_product_op<LhsScalar,RhsScalar> > { 00093 enum { 00094 Cost = NumTraits<LhsScalar>::MulCost, 00095 PacketAccess = internal::is_same<LhsScalar, RhsScalar>::value && packet_traits<LhsScalar>::HasMul 00096 }; 00097 }; 00098 00099 /** \internal 00100 * \brief Template functor to compute the min of two scalars 00101 * 00102 * \sa class CwiseBinaryOp, MatrixBase::cwiseMin, class VectorwiseOp, MatrixBase::minCoeff() 00103 */ 00104 template<typename Scalar> struct scalar_min_op { 00105 EIGEN_EMPTY_STRUCT_CTOR(scalar_min_op) 00106 EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { using std::min; return (min)(a, b); } 00107 template<typename Packet> 00108 EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const 00109 { return internal::pmin(a,b); } 00110 template<typename Packet> 00111 EIGEN_STRONG_INLINE const Scalar predux(const Packet& a) const 00112 { return internal::predux_min(a); } 00113 }; 00114 template<typename Scalar> 00115 struct functor_traits<scalar_min_op<Scalar> > { 00116 enum { 00117 Cost = NumTraits<Scalar>::AddCost, 00118 PacketAccess = packet_traits<Scalar>::HasMin 00119 }; 00120 }; 00121 00122 /** \internal 00123 * \brief Template functor to compute the max of two scalars 00124 * 00125 * \sa class CwiseBinaryOp, MatrixBase::cwiseMax, class VectorwiseOp, MatrixBase::maxCoeff() 00126 */ 00127 template<typename Scalar> struct scalar_max_op { 00128 EIGEN_EMPTY_STRUCT_CTOR(scalar_max_op) 00129 EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { using std::max; return (max)(a, b); } 00130 template<typename Packet> 00131 EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const 00132 { return internal::pmax(a,b); } 00133 template<typename Packet> 00134 EIGEN_STRONG_INLINE const Scalar predux(const Packet& a) const 00135 { return internal::predux_max(a); } 00136 }; 00137 template<typename Scalar> 00138 struct functor_traits<scalar_max_op<Scalar> > { 00139 enum { 00140 Cost = NumTraits<Scalar>::AddCost, 00141 PacketAccess = packet_traits<Scalar>::HasMax 00142 }; 00143 }; 00144 00145 /** \internal 00146 * \brief Template functor to compute the hypot of two scalars 00147 * 00148 * \sa MatrixBase::stableNorm(), class Redux 00149 */ 00150 template<typename Scalar> struct scalar_hypot_op { 00151 EIGEN_EMPTY_STRUCT_CTOR(scalar_hypot_op) 00152 // typedef typename NumTraits<Scalar>::Real result_type; 00153 EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& _x, const Scalar& _y) const 00154 { 00155 using std::max; 00156 using std::min; 00157 using std::sqrt; 00158 Scalar p = (max)(_x, _y); 00159 Scalar q = (min)(_x, _y); 00160 Scalar qp = q/p; 00161 return p * sqrt(Scalar(1) + qp*qp); 00162 } 00163 }; 00164 template<typename Scalar> 00165 struct functor_traits<scalar_hypot_op<Scalar> > { 00166 enum { Cost = 5 * NumTraits<Scalar>::MulCost, PacketAccess=0 }; 00167 }; 00168 00169 /** \internal 00170 * \brief Template functor to compute the pow of two scalars 00171 */ 00172 template<typename Scalar, typename OtherScalar> struct scalar_binary_pow_op { 00173 EIGEN_EMPTY_STRUCT_CTOR(scalar_binary_pow_op) 00174 inline Scalar operator() (const Scalar& a, const OtherScalar& b) const { return numext::pow(a, b); } 00175 }; 00176 template<typename Scalar, typename OtherScalar> 00177 struct functor_traits<scalar_binary_pow_op<Scalar,OtherScalar> > { 00178 enum { Cost = 5 * NumTraits<Scalar>::MulCost, PacketAccess = false }; 00179 }; 00180 00181 // other binary functors: 00182 00183 /** \internal 00184 * \brief Template functor to compute the difference of two scalars 00185 * 00186 * \sa class CwiseBinaryOp, MatrixBase::operator- 00187 */ 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 00203 /** \internal 00204 * \brief Template functor to compute the quotient of two scalars 00205 * 00206 * \sa class CwiseBinaryOp, Cwise::operator/() 00207 */ 00208 template<typename LhsScalar,typename RhsScalar> struct scalar_quotient_op { 00209 enum { 00210 // TODO vectorize mixed product 00211 Vectorizable = is_same<LhsScalar,RhsScalar>::value && packet_traits<LhsScalar>::HasDiv && packet_traits<RhsScalar>::HasDiv 00212 }; 00213 typedef typename scalar_product_traits<LhsScalar,RhsScalar>::ReturnType result_type; 00214 EIGEN_EMPTY_STRUCT_CTOR(scalar_quotient_op) 00215 EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const { return a / b; } 00216 template<typename Packet> 00217 EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const 00218 { return internal::pdiv(a,b); } 00219 }; 00220 template<typename LhsScalar,typename RhsScalar> 00221 struct functor_traits<scalar_quotient_op<LhsScalar,RhsScalar> > { 00222 enum { 00223 Cost = (NumTraits<LhsScalar>::MulCost + NumTraits<RhsScalar>::MulCost), // rough estimate! 00224 PacketAccess = scalar_quotient_op<LhsScalar,RhsScalar>::Vectorizable 00225 }; 00226 }; 00227 00228 00229 00230 /** \internal 00231 * \brief Template functor to compute the and of two booleans 00232 * 00233 * \sa class CwiseBinaryOp, ArrayBase::operator&& 00234 */ 00235 struct scalar_boolean_and_op { 00236 EIGEN_EMPTY_STRUCT_CTOR(scalar_boolean_and_op) 00237 EIGEN_STRONG_INLINE bool operator() (const bool& a, const bool& b) const { return a && b; } 00238 }; 00239 template<> struct functor_traits<scalar_boolean_and_op> { 00240 enum { 00241 Cost = NumTraits<bool>::AddCost, 00242 PacketAccess = false 00243 }; 00244 }; 00245 00246 /** \internal 00247 * \brief Template functor to compute the or of two booleans 00248 * 00249 * \sa class CwiseBinaryOp, ArrayBase::operator|| 00250 */ 00251 struct scalar_boolean_or_op { 00252 EIGEN_EMPTY_STRUCT_CTOR(scalar_boolean_or_op) 00253 EIGEN_STRONG_INLINE bool operator() (const bool& a, const bool& b) const { return a || b; } 00254 }; 00255 template<> struct functor_traits<scalar_boolean_or_op> { 00256 enum { 00257 Cost = NumTraits<bool>::AddCost, 00258 PacketAccess = false 00259 }; 00260 }; 00261 00262 /** \internal 00263 * \brief Template functors for comparison of two scalars 00264 * \todo Implement packet-comparisons 00265 */ 00266 template<typename Scalar, ComparisonName cmp> struct scalar_cmp_op; 00267 00268 template<typename Scalar, ComparisonName cmp> 00269 struct functor_traits<scalar_cmp_op<Scalar, cmp> > { 00270 enum { 00271 Cost = NumTraits<Scalar>::AddCost, 00272 PacketAccess = false 00273 }; 00274 }; 00275 00276 template<ComparisonName Cmp, typename Scalar> 00277 struct result_of<scalar_cmp_op<Scalar, Cmp>(Scalar,Scalar)> { 00278 typedef bool type; 00279 }; 00280 00281 00282 template<typename Scalar> struct scalar_cmp_op<Scalar, cmp_EQ> { 00283 EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op) 00284 EIGEN_STRONG_INLINE bool operator()(const Scalar& a, const Scalar& b) const {return a==b;} 00285 }; 00286 template<typename Scalar> struct scalar_cmp_op<Scalar, cmp_LT> { 00287 EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op) 00288 EIGEN_STRONG_INLINE bool operator()(const Scalar& a, const Scalar& b) const {return a<b;} 00289 }; 00290 template<typename Scalar> struct scalar_cmp_op<Scalar, cmp_LE> { 00291 EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op) 00292 EIGEN_STRONG_INLINE bool operator()(const Scalar& a, const Scalar& b) const {return a<=b;} 00293 }; 00294 template<typename Scalar> struct scalar_cmp_op<Scalar, cmp_UNORD> { 00295 EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op) 00296 EIGEN_STRONG_INLINE bool operator()(const Scalar& a, const Scalar& b) const {return !(a<=b || b<=a);} 00297 }; 00298 template<typename Scalar> struct scalar_cmp_op<Scalar, cmp_NEQ> { 00299 EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op) 00300 EIGEN_STRONG_INLINE bool operator()(const Scalar& a, const Scalar& b) const {return a!=b;} 00301 }; 00302 00303 // unary functors: 00304 00305 /** \internal 00306 * \brief Template functor to compute the opposite of a scalar 00307 * 00308 * \sa class CwiseUnaryOp, MatrixBase::operator- 00309 */ 00310 template<typename Scalar> struct scalar_opposite_op { 00311 EIGEN_EMPTY_STRUCT_CTOR(scalar_opposite_op) 00312 EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a) const { return -a; } 00313 template<typename Packet> 00314 EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const 00315 { return internal::pnegate(a); } 00316 }; 00317 template<typename Scalar> 00318 struct functor_traits<scalar_opposite_op<Scalar> > 00319 { enum { 00320 Cost = NumTraits<Scalar>::AddCost, 00321 PacketAccess = packet_traits<Scalar>::HasNegate }; 00322 }; 00323 00324 /** \internal 00325 * \brief Template functor to compute the absolute value of a scalar 00326 * 00327 * \sa class CwiseUnaryOp, Cwise::abs 00328 */ 00329 template<typename Scalar> struct scalar_abs_op { 00330 EIGEN_EMPTY_STRUCT_CTOR(scalar_abs_op) 00331 typedef typename NumTraits<Scalar>::Real result_type; 00332 EIGEN_STRONG_INLINE const result_type operator() (const Scalar& a) const { using std::abs; return abs(a); } 00333 template<typename Packet> 00334 EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const 00335 { return internal::pabs(a); } 00336 }; 00337 template<typename Scalar> 00338 struct functor_traits<scalar_abs_op<Scalar> > 00339 { 00340 enum { 00341 Cost = NumTraits<Scalar>::AddCost, 00342 PacketAccess = packet_traits<Scalar>::HasAbs 00343 }; 00344 }; 00345 00346 /** \internal 00347 * \brief Template functor to compute the squared absolute value of a scalar 00348 * 00349 * \sa class CwiseUnaryOp, Cwise::abs2 00350 */ 00351 template<typename Scalar> struct scalar_abs2_op { 00352 EIGEN_EMPTY_STRUCT_CTOR(scalar_abs2_op) 00353 typedef typename NumTraits<Scalar>::Real result_type; 00354 EIGEN_STRONG_INLINE const result_type operator() (const Scalar& a) const { return numext::abs2(a); } 00355 template<typename Packet> 00356 EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const 00357 { return internal::pmul(a,a); } 00358 }; 00359 template<typename Scalar> 00360 struct functor_traits<scalar_abs2_op<Scalar> > 00361 { enum { Cost = NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasAbs2 }; }; 00362 00363 /** \internal 00364 * \brief Template functor to compute the conjugate of a complex value 00365 * 00366 * \sa class CwiseUnaryOp, MatrixBase::conjugate() 00367 */ 00368 template<typename Scalar> struct scalar_conjugate_op { 00369 EIGEN_EMPTY_STRUCT_CTOR(scalar_conjugate_op) 00370 EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a) const { using numext::conj; return conj(a); } 00371 template<typename Packet> 00372 EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const { return internal::pconj(a); } 00373 }; 00374 template<typename Scalar> 00375 struct functor_traits<scalar_conjugate_op<Scalar> > 00376 { 00377 enum { 00378 Cost = NumTraits<Scalar>::IsComplex ? NumTraits<Scalar>::AddCost : 0, 00379 PacketAccess = packet_traits<Scalar>::HasConj 00380 }; 00381 }; 00382 00383 /** \internal 00384 * \brief Template functor to cast a scalar to another type 00385 * 00386 * \sa class CwiseUnaryOp, MatrixBase::cast() 00387 */ 00388 template<typename Scalar, typename NewType> 00389 struct scalar_cast_op { 00390 EIGEN_EMPTY_STRUCT_CTOR(scalar_cast_op) 00391 typedef NewType result_type; 00392 EIGEN_STRONG_INLINE const NewType operator() (const Scalar& a) const { return cast<Scalar, NewType>(a); } 00393 }; 00394 template<typename Scalar, typename NewType> 00395 struct functor_traits<scalar_cast_op<Scalar,NewType> > 00396 { enum { Cost = is_same<Scalar, NewType>::value ? 0 : NumTraits<NewType>::AddCost, PacketAccess = false }; }; 00397 00398 /** \internal 00399 * \brief Template functor to extract the real part of a complex 00400 * 00401 * \sa class CwiseUnaryOp, MatrixBase::real() 00402 */ 00403 template<typename Scalar> 00404 struct scalar_real_op { 00405 EIGEN_EMPTY_STRUCT_CTOR(scalar_real_op) 00406 typedef typename NumTraits<Scalar>::Real result_type; 00407 EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return numext::real(a); } 00408 }; 00409 template<typename Scalar> 00410 struct functor_traits<scalar_real_op<Scalar> > 00411 { enum { Cost = 0, PacketAccess = false }; }; 00412 00413 /** \internal 00414 * \brief Template functor to extract the imaginary part of a complex 00415 * 00416 * \sa class CwiseUnaryOp, MatrixBase::imag() 00417 */ 00418 template<typename Scalar> 00419 struct scalar_imag_op { 00420 EIGEN_EMPTY_STRUCT_CTOR(scalar_imag_op) 00421 typedef typename NumTraits<Scalar>::Real result_type; 00422 EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return numext::imag(a); } 00423 }; 00424 template<typename Scalar> 00425 struct functor_traits<scalar_imag_op<Scalar> > 00426 { enum { Cost = 0, PacketAccess = false }; }; 00427 00428 /** \internal 00429 * \brief Template functor to extract the real part of a complex as a reference 00430 * 00431 * \sa class CwiseUnaryOp, MatrixBase::real() 00432 */ 00433 template<typename Scalar> 00434 struct scalar_real_ref_op { 00435 EIGEN_EMPTY_STRUCT_CTOR(scalar_real_ref_op) 00436 typedef typename NumTraits<Scalar>::Real result_type; 00437 EIGEN_STRONG_INLINE result_type& operator() (const Scalar& a) const { return numext::real_ref(*const_cast<Scalar*>(&a)); } 00438 }; 00439 template<typename Scalar> 00440 struct functor_traits<scalar_real_ref_op<Scalar> > 00441 { enum { Cost = 0, PacketAccess = false }; }; 00442 00443 /** \internal 00444 * \brief Template functor to extract the imaginary part of a complex as a reference 00445 * 00446 * \sa class CwiseUnaryOp, MatrixBase::imag() 00447 */ 00448 template<typename Scalar> 00449 struct scalar_imag_ref_op { 00450 EIGEN_EMPTY_STRUCT_CTOR(scalar_imag_ref_op) 00451 typedef typename NumTraits<Scalar>::Real result_type; 00452 EIGEN_STRONG_INLINE result_type& operator() (const Scalar& a) const { return numext::imag_ref(*const_cast<Scalar*>(&a)); } 00453 }; 00454 template<typename Scalar> 00455 struct functor_traits<scalar_imag_ref_op<Scalar> > 00456 { enum { Cost = 0, PacketAccess = false }; }; 00457 00458 /** \internal 00459 * 00460 * \brief Template functor to compute the exponential of a scalar 00461 * 00462 * \sa class CwiseUnaryOp, Cwise::exp() 00463 */ 00464 template<typename Scalar> struct scalar_exp_op { 00465 EIGEN_EMPTY_STRUCT_CTOR(scalar_exp_op) 00466 inline const Scalar operator() (const Scalar& a) const { using std::exp; return exp(a); } 00467 typedef typename packet_traits<Scalar>::type Packet; 00468 inline Packet packetOp(const Packet& a) const { return internal::pexp(a); } 00469 }; 00470 template<typename Scalar> 00471 struct functor_traits<scalar_exp_op<Scalar> > 00472 { enum { Cost = 5 * NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasExp }; }; 00473 00474 /** \internal 00475 * 00476 * \brief Template functor to compute the logarithm of a scalar 00477 * 00478 * \sa class CwiseUnaryOp, Cwise::log() 00479 */ 00480 template<typename Scalar> struct scalar_log_op { 00481 EIGEN_EMPTY_STRUCT_CTOR(scalar_log_op) 00482 inline const Scalar operator() (const Scalar& a) const { using std::log; return log(a); } 00483 typedef typename packet_traits<Scalar>::type Packet; 00484 inline Packet packetOp(const Packet& a) const { return internal::plog(a); } 00485 }; 00486 template<typename Scalar> 00487 struct functor_traits<scalar_log_op<Scalar> > 00488 { enum { Cost = 5 * NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasLog }; }; 00489 00490 /** \internal 00491 * \brief Template functor to multiply a scalar by a fixed other one 00492 * 00493 * \sa class CwiseUnaryOp, MatrixBase::operator*, MatrixBase::operator/ 00494 */ 00495 /* NOTE why doing the pset1() in packetOp *is* an optimization ? 00496 * indeed it seems better to declare m_other as a Packet and do the pset1() once 00497 * in the constructor. However, in practice: 00498 * - GCC does not like m_other as a Packet and generate a load every time it needs it 00499 * - on the other hand GCC is able to moves the pset1() outside the loop :) 00500 * - simpler code ;) 00501 * (ICC and gcc 4.4 seems to perform well in both cases, the issue is visible with y = a*x + b*y) 00502 */ 00503 template<typename Scalar> 00504 struct scalar_multiple_op { 00505 typedef typename packet_traits<Scalar>::type Packet; 00506 // FIXME default copy constructors seems bugged with std::complex<> 00507 EIGEN_STRONG_INLINE scalar_multiple_op(const scalar_multiple_op& other) : m_other(other.m_other) { } 00508 EIGEN_STRONG_INLINE scalar_multiple_op(const Scalar& other) : m_other(other) { } 00509 EIGEN_STRONG_INLINE Scalar operator() (const Scalar& a) const { return a * m_other; } 00510 EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const 00511 { return internal::pmul(a, pset1<Packet>(m_other)); } 00512 typename add_const_on_value_type<typename NumTraits<Scalar>::Nested>::type m_other; 00513 }; 00514 template<typename Scalar> 00515 struct functor_traits<scalar_multiple_op<Scalar> > 00516 { enum { Cost = NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasMul }; }; 00517 00518 template<typename Scalar1, typename Scalar2> 00519 struct scalar_multiple2_op { 00520 typedef typename scalar_product_traits<Scalar1,Scalar2>::ReturnType result_type; 00521 EIGEN_STRONG_INLINE scalar_multiple2_op(const scalar_multiple2_op& other) : m_other(other.m_other) { } 00522 EIGEN_STRONG_INLINE scalar_multiple2_op(const Scalar2& other) : m_other(other) { } 00523 EIGEN_STRONG_INLINE result_type operator() (const Scalar1& a) const { return a * m_other; } 00524 typename add_const_on_value_type<typename NumTraits<Scalar2>::Nested>::type m_other; 00525 }; 00526 template<typename Scalar1,typename Scalar2> 00527 struct functor_traits<scalar_multiple2_op<Scalar1,Scalar2> > 00528 { enum { Cost = NumTraits<Scalar1>::MulCost, PacketAccess = false }; }; 00529 00530 /** \internal 00531 * \brief Template functor to divide a scalar by a fixed other one 00532 * 00533 * This functor is used to implement the quotient of a matrix by 00534 * a scalar where the scalar type is not necessarily a floating point type. 00535 * 00536 * \sa class CwiseUnaryOp, MatrixBase::operator/ 00537 */ 00538 template<typename Scalar> 00539 struct scalar_quotient1_op { 00540 typedef typename packet_traits<Scalar>::type Packet; 00541 // FIXME default copy constructors seems bugged with std::complex<> 00542 EIGEN_STRONG_INLINE scalar_quotient1_op(const scalar_quotient1_op& other) : m_other(other.m_other) { } 00543 EIGEN_STRONG_INLINE scalar_quotient1_op(const Scalar& other) : m_other(other) {} 00544 EIGEN_STRONG_INLINE Scalar operator() (const Scalar& a) const { return a / m_other; } 00545 EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const 00546 { return internal::pdiv(a, pset1<Packet>(m_other)); } 00547 typename add_const_on_value_type<typename NumTraits<Scalar>::Nested>::type m_other; 00548 }; 00549 template<typename Scalar> 00550 struct functor_traits<scalar_quotient1_op<Scalar> > 00551 { enum { Cost = 2 * NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasDiv }; }; 00552 00553 // nullary functors 00554 00555 template<typename Scalar> 00556 struct scalar_constant_op { 00557 typedef typename packet_traits<Scalar>::type Packet; 00558 EIGEN_STRONG_INLINE scalar_constant_op(const scalar_constant_op& other) : m_other(other.m_other) { } 00559 EIGEN_STRONG_INLINE scalar_constant_op(const Scalar& other) : m_other(other) { } 00560 template<typename Index> 00561 EIGEN_STRONG_INLINE const Scalar operator() (Index, Index = 0) const { return m_other; } 00562 template<typename Index> 00563 EIGEN_STRONG_INLINE const Packet packetOp(Index, Index = 0) const { return internal::pset1<Packet>(m_other); } 00564 const Scalar m_other; 00565 }; 00566 template<typename Scalar> 00567 struct functor_traits<scalar_constant_op<Scalar> > 00568 // FIXME replace this packet test by a safe one 00569 { enum { Cost = 1, PacketAccess = packet_traits<Scalar>::Vectorizable, IsRepeatable = true }; }; 00570 00571 template<typename Scalar> struct scalar_identity_op { 00572 EIGEN_EMPTY_STRUCT_CTOR(scalar_identity_op) 00573 template<typename Index> 00574 EIGEN_STRONG_INLINE const Scalar operator() (Index row, Index col) const { return row==col ? Scalar(1) : Scalar(0); } 00575 }; 00576 template<typename Scalar> 00577 struct functor_traits<scalar_identity_op<Scalar> > 00578 { enum { Cost = NumTraits<Scalar>::AddCost, PacketAccess = false, IsRepeatable = true }; }; 00579 00580 template <typename Scalar, bool RandomAccess> struct linspaced_op_impl; 00581 00582 // linear access for packet ops: 00583 // 1) initialization 00584 // base = [low, ..., low] + ([step, ..., step] * [-size, ..., 0]) 00585 // 2) each step (where size is 1 for coeff access or PacketSize for packet access) 00586 // base += [size*step, ..., size*step] 00587 // 00588 // TODO: Perhaps it's better to initialize lazily (so not in the constructor but in packetOp) 00589 // in order to avoid the padd() in operator() ? 00590 template <typename Scalar> 00591 struct linspaced_op_impl<Scalar,false> 00592 { 00593 typedef typename packet_traits<Scalar>::type Packet; 00594 00595 linspaced_op_impl(const Scalar& low, const Scalar& step) : 00596 m_low(low), m_step(step), 00597 m_packetStep(pset1<Packet>(packet_traits<Scalar>::size*step)), 00598 m_base(padd(pset1<Packet>(low), pmul(pset1<Packet>(step),plset<Scalar>(-packet_traits<Scalar>::size)))) {} 00599 00600 template<typename Index> 00601 EIGEN_STRONG_INLINE const Scalar operator() (Index i) const 00602 { 00603 m_base = padd(m_base, pset1<Packet>(m_step)); 00604 return m_low+Scalar(i)*m_step; 00605 } 00606 00607 template<typename Index> 00608 EIGEN_STRONG_INLINE const Packet packetOp(Index) const { return m_base = padd(m_base,m_packetStep); } 00609 00610 const Scalar m_low; 00611 const Scalar m_step; 00612 const Packet m_packetStep; 00613 mutable Packet m_base; 00614 }; 00615 00616 // random access for packet ops: 00617 // 1) each step 00618 // [low, ..., low] + ( [step, ..., step] * ( [i, ..., i] + [0, ..., size] ) ) 00619 template <typename Scalar> 00620 struct linspaced_op_impl<Scalar,true> 00621 { 00622 typedef typename packet_traits<Scalar>::type Packet; 00623 00624 linspaced_op_impl(const Scalar& low, const Scalar& step) : 00625 m_low(low), m_step(step), 00626 m_lowPacket(pset1<Packet>(m_low)), m_stepPacket(pset1<Packet>(m_step)), m_interPacket(plset<Scalar>(0)) {} 00627 00628 template<typename Index> 00629 EIGEN_STRONG_INLINE const Scalar operator() (Index i) const { return m_low+i*m_step; } 00630 00631 template<typename Index> 00632 EIGEN_STRONG_INLINE const Packet packetOp(Index i) const 00633 { return internal::padd(m_lowPacket, pmul(m_stepPacket, padd(pset1<Packet>(Scalar(i)),m_interPacket))); } 00634 00635 const Scalar m_low; 00636 const Scalar m_step; 00637 const Packet m_lowPacket; 00638 const Packet m_stepPacket; 00639 const Packet m_interPacket; 00640 }; 00641 00642 // ----- Linspace functor ---------------------------------------------------------------- 00643 00644 // Forward declaration (we default to random access which does not really give 00645 // us a speed gain when using packet access but it allows to use the functor in 00646 // nested expressions). 00647 template <typename Scalar, bool RandomAccess = true> struct linspaced_op; 00648 template <typename Scalar, bool RandomAccess> struct functor_traits< linspaced_op<Scalar,RandomAccess> > 00649 { enum { Cost = 1, PacketAccess = packet_traits<Scalar>::HasSetLinear, IsRepeatable = true }; }; 00650 template <typename Scalar, bool RandomAccess> struct linspaced_op 00651 { 00652 typedef typename packet_traits<Scalar>::type Packet; 00653 linspaced_op(const Scalar& low, const Scalar& high, DenseIndex num_steps) : impl((num_steps==1 ? high : low), (num_steps==1 ? Scalar() : (high-low)/Scalar(num_steps-1))) {} 00654 00655 template<typename Index> 00656 EIGEN_STRONG_INLINE const Scalar operator() (Index i) const { return impl(i); } 00657 00658 // We need this function when assigning e.g. a RowVectorXd to a MatrixXd since 00659 // there row==0 and col is used for the actual iteration. 00660 template<typename Index> 00661 EIGEN_STRONG_INLINE const Scalar operator() (Index row, Index col) const 00662 { 00663 eigen_assert(col==0 || row==0); 00664 return impl(col + row); 00665 } 00666 00667 template<typename Index> 00668 EIGEN_STRONG_INLINE const Packet packetOp(Index i) const { return impl.packetOp(i); } 00669 00670 // We need this function when assigning e.g. a RowVectorXd to a MatrixXd since 00671 // there row==0 and col is used for the actual iteration. 00672 template<typename Index> 00673 EIGEN_STRONG_INLINE const Packet packetOp(Index row, Index col) const 00674 { 00675 eigen_assert(col==0 || row==0); 00676 return impl.packetOp(col + row); 00677 } 00678 00679 // This proxy object handles the actual required temporaries, the different 00680 // implementations (random vs. sequential access) as well as the 00681 // correct piping to size 2/4 packet operations. 00682 const linspaced_op_impl<Scalar,RandomAccess> impl; 00683 }; 00684 00685 // all functors allow linear access, except scalar_identity_op. So we fix here a quick meta 00686 // to indicate whether a functor allows linear access, just always answering 'yes' except for 00687 // scalar_identity_op. 00688 // FIXME move this to functor_traits adding a functor_default 00689 template<typename Functor> struct functor_has_linear_access { enum { ret = 1 }; }; 00690 template<typename Scalar> struct functor_has_linear_access<scalar_identity_op<Scalar> > { enum { ret = 0 }; }; 00691 00692 // In Eigen, any binary op (Product, CwiseBinaryOp) require the Lhs and Rhs to have the same scalar type, except for multiplication 00693 // where the mixing of different types is handled by scalar_product_traits 00694 // In particular, real * complex<real> is allowed. 00695 // FIXME move this to functor_traits adding a functor_default 00696 template<typename Functor> struct functor_is_product_like { enum { ret = 0 }; }; 00697 template<typename LhsScalar,typename RhsScalar> struct functor_is_product_like<scalar_product_op<LhsScalar,RhsScalar> > { enum { ret = 1 }; }; 00698 template<typename LhsScalar,typename RhsScalar> struct functor_is_product_like<scalar_conj_product_op<LhsScalar,RhsScalar> > { enum { ret = 1 }; }; 00699 template<typename LhsScalar,typename RhsScalar> struct functor_is_product_like<scalar_quotient_op<LhsScalar,RhsScalar> > { enum { ret = 1 }; }; 00700 00701 00702 /** \internal 00703 * \brief Template functor to add a scalar to a fixed other one 00704 * \sa class CwiseUnaryOp, Array::operator+ 00705 */ 00706 /* If you wonder why doing the pset1() in packetOp() is an optimization check scalar_multiple_op */ 00707 template<typename Scalar> 00708 struct scalar_add_op { 00709 typedef typename packet_traits<Scalar>::type Packet; 00710 // FIXME default copy constructors seems bugged with std::complex<> 00711 inline scalar_add_op(const scalar_add_op& other) : m_other(other.m_other) { } 00712 inline scalar_add_op(const Scalar& other) : m_other(other) { } 00713 inline Scalar operator() (const Scalar& a) const { return a + m_other; } 00714 inline const Packet packetOp(const Packet& a) const 00715 { return internal::padd(a, pset1<Packet>(m_other)); } 00716 const Scalar m_other; 00717 }; 00718 template<typename Scalar> 00719 struct functor_traits<scalar_add_op<Scalar> > 00720 { enum { Cost = NumTraits<Scalar>::AddCost, PacketAccess = packet_traits<Scalar>::HasAdd }; }; 00721 00722 /** \internal 00723 * \brief Template functor to compute the square root of a scalar 00724 * \sa class CwiseUnaryOp, Cwise::sqrt() 00725 */ 00726 template<typename Scalar> struct scalar_sqrt_op { 00727 EIGEN_EMPTY_STRUCT_CTOR(scalar_sqrt_op) 00728 inline const Scalar operator() (const Scalar& a) const { using std::sqrt; return sqrt(a); } 00729 typedef typename packet_traits<Scalar>::type Packet; 00730 inline Packet packetOp(const Packet& a) const { return internal::psqrt(a); } 00731 }; 00732 template<typename Scalar> 00733 struct functor_traits<scalar_sqrt_op<Scalar> > 00734 { enum { 00735 Cost = 5 * NumTraits<Scalar>::MulCost, 00736 PacketAccess = packet_traits<Scalar>::HasSqrt 00737 }; 00738 }; 00739 00740 /** \internal 00741 * \brief Template functor to compute the cosine of a scalar 00742 * \sa class CwiseUnaryOp, ArrayBase::cos() 00743 */ 00744 template<typename Scalar> struct scalar_cos_op { 00745 EIGEN_EMPTY_STRUCT_CTOR(scalar_cos_op) 00746 inline Scalar operator() (const Scalar& a) const { using std::cos; return cos(a); } 00747 typedef typename packet_traits<Scalar>::type Packet; 00748 inline Packet packetOp(const Packet& a) const { return internal::pcos(a); } 00749 }; 00750 template<typename Scalar> 00751 struct functor_traits<scalar_cos_op<Scalar> > 00752 { 00753 enum { 00754 Cost = 5 * NumTraits<Scalar>::MulCost, 00755 PacketAccess = packet_traits<Scalar>::HasCos 00756 }; 00757 }; 00758 00759 /** \internal 00760 * \brief Template functor to compute the sine of a scalar 00761 * \sa class CwiseUnaryOp, ArrayBase::sin() 00762 */ 00763 template<typename Scalar> struct scalar_sin_op { 00764 EIGEN_EMPTY_STRUCT_CTOR(scalar_sin_op) 00765 inline const Scalar operator() (const Scalar& a) const { using std::sin; return sin(a); } 00766 typedef typename packet_traits<Scalar>::type Packet; 00767 inline Packet packetOp(const Packet& a) const { return internal::psin(a); } 00768 }; 00769 template<typename Scalar> 00770 struct functor_traits<scalar_sin_op<Scalar> > 00771 { 00772 enum { 00773 Cost = 5 * NumTraits<Scalar>::MulCost, 00774 PacketAccess = packet_traits<Scalar>::HasSin 00775 }; 00776 }; 00777 00778 00779 /** \internal 00780 * \brief Template functor to compute the tan of a scalar 00781 * \sa class CwiseUnaryOp, ArrayBase::tan() 00782 */ 00783 template<typename Scalar> struct scalar_tan_op { 00784 EIGEN_EMPTY_STRUCT_CTOR(scalar_tan_op) 00785 inline const Scalar operator() (const Scalar& a) const { using std::tan; return tan(a); } 00786 typedef typename packet_traits<Scalar>::type Packet; 00787 inline Packet packetOp(const Packet& a) const { return internal::ptan(a); } 00788 }; 00789 template<typename Scalar> 00790 struct functor_traits<scalar_tan_op<Scalar> > 00791 { 00792 enum { 00793 Cost = 5 * NumTraits<Scalar>::MulCost, 00794 PacketAccess = packet_traits<Scalar>::HasTan 00795 }; 00796 }; 00797 00798 /** \internal 00799 * \brief Template functor to compute the arc cosine of a scalar 00800 * \sa class CwiseUnaryOp, ArrayBase::acos() 00801 */ 00802 template<typename Scalar> struct scalar_acos_op { 00803 EIGEN_EMPTY_STRUCT_CTOR(scalar_acos_op) 00804 inline const Scalar operator() (const Scalar& a) const { using std::acos; return acos(a); } 00805 typedef typename packet_traits<Scalar>::type Packet; 00806 inline Packet packetOp(const Packet& a) const { return internal::pacos(a); } 00807 }; 00808 template<typename Scalar> 00809 struct functor_traits<scalar_acos_op<Scalar> > 00810 { 00811 enum { 00812 Cost = 5 * NumTraits<Scalar>::MulCost, 00813 PacketAccess = packet_traits<Scalar>::HasACos 00814 }; 00815 }; 00816 00817 /** \internal 00818 * \brief Template functor to compute the arc sine of a scalar 00819 * \sa class CwiseUnaryOp, ArrayBase::asin() 00820 */ 00821 template<typename Scalar> struct scalar_asin_op { 00822 EIGEN_EMPTY_STRUCT_CTOR(scalar_asin_op) 00823 inline const Scalar operator() (const Scalar& a) const { using std::asin; return asin(a); } 00824 typedef typename packet_traits<Scalar>::type Packet; 00825 inline Packet packetOp(const Packet& a) const { return internal::pasin(a); } 00826 }; 00827 template<typename Scalar> 00828 struct functor_traits<scalar_asin_op<Scalar> > 00829 { 00830 enum { 00831 Cost = 5 * NumTraits<Scalar>::MulCost, 00832 PacketAccess = packet_traits<Scalar>::HasASin 00833 }; 00834 }; 00835 00836 /** \internal 00837 * \brief Template functor to raise a scalar to a power 00838 * \sa class CwiseUnaryOp, Cwise::pow 00839 */ 00840 template<typename Scalar> 00841 struct scalar_pow_op { 00842 // FIXME default copy constructors seems bugged with std::complex<> 00843 inline scalar_pow_op(const scalar_pow_op& other) : m_exponent(other.m_exponent) { } 00844 inline scalar_pow_op(const Scalar& exponent) : m_exponent(exponent) {} 00845 inline Scalar operator() (const Scalar& a) const { return numext::pow(a, m_exponent); } 00846 const Scalar m_exponent; 00847 }; 00848 template<typename Scalar> 00849 struct functor_traits<scalar_pow_op<Scalar> > 00850 { enum { Cost = 5 * NumTraits<Scalar>::MulCost, PacketAccess = false }; }; 00851 00852 /** \internal 00853 * \brief Template functor to compute the quotient between a scalar and array entries. 00854 * \sa class CwiseUnaryOp, Cwise::inverse() 00855 */ 00856 template<typename Scalar> 00857 struct scalar_inverse_mult_op { 00858 scalar_inverse_mult_op(const Scalar& other) : m_other(other) {} 00859 inline Scalar operator() (const Scalar& a) const { return m_other / a; } 00860 template<typename Packet> 00861 inline const Packet packetOp(const Packet& a) const 00862 { return internal::pdiv(pset1<Packet>(m_other),a); } 00863 Scalar m_other; 00864 }; 00865 00866 /** \internal 00867 * \brief Template functor to compute the inverse of a scalar 00868 * \sa class CwiseUnaryOp, Cwise::inverse() 00869 */ 00870 template<typename Scalar> 00871 struct scalar_inverse_op { 00872 EIGEN_EMPTY_STRUCT_CTOR(scalar_inverse_op) 00873 inline Scalar operator() (const Scalar& a) const { return Scalar(1)/a; } 00874 template<typename Packet> 00875 inline const Packet packetOp(const Packet& a) const 00876 { return internal::pdiv(pset1<Packet>(Scalar(1)),a); } 00877 }; 00878 template<typename Scalar> 00879 struct functor_traits<scalar_inverse_op<Scalar> > 00880 { enum { Cost = NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasDiv }; }; 00881 00882 /** \internal 00883 * \brief Template functor to compute the square of a scalar 00884 * \sa class CwiseUnaryOp, Cwise::square() 00885 */ 00886 template<typename Scalar> 00887 struct scalar_square_op { 00888 EIGEN_EMPTY_STRUCT_CTOR(scalar_square_op) 00889 inline Scalar operator() (const Scalar& a) const { return a*a; } 00890 template<typename Packet> 00891 inline const Packet packetOp(const Packet& a) const 00892 { return internal::pmul(a,a); } 00893 }; 00894 template<typename Scalar> 00895 struct functor_traits<scalar_square_op<Scalar> > 00896 { enum { Cost = NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasMul }; }; 00897 00898 /** \internal 00899 * \brief Template functor to compute the cube of a scalar 00900 * \sa class CwiseUnaryOp, Cwise::cube() 00901 */ 00902 template<typename Scalar> 00903 struct scalar_cube_op { 00904 EIGEN_EMPTY_STRUCT_CTOR(scalar_cube_op) 00905 inline Scalar operator() (const Scalar& a) const { return a*a*a; } 00906 template<typename Packet> 00907 inline const Packet packetOp(const Packet& a) const 00908 { return internal::pmul(a,pmul(a,a)); } 00909 }; 00910 template<typename Scalar> 00911 struct functor_traits<scalar_cube_op<Scalar> > 00912 { enum { Cost = 2*NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasMul }; }; 00913 00914 // default functor traits for STL functors: 00915 00916 template<typename T> 00917 struct functor_traits<std::multiplies<T> > 00918 { enum { Cost = NumTraits<T>::MulCost, PacketAccess = false }; }; 00919 00920 template<typename T> 00921 struct functor_traits<std::divides<T> > 00922 { enum { Cost = NumTraits<T>::MulCost, PacketAccess = false }; }; 00923 00924 template<typename T> 00925 struct functor_traits<std::plus<T> > 00926 { enum { Cost = NumTraits<T>::AddCost, PacketAccess = false }; }; 00927 00928 template<typename T> 00929 struct functor_traits<std::minus<T> > 00930 { enum { Cost = NumTraits<T>::AddCost, PacketAccess = false }; }; 00931 00932 template<typename T> 00933 struct functor_traits<std::negate<T> > 00934 { enum { Cost = NumTraits<T>::AddCost, PacketAccess = false }; }; 00935 00936 template<typename T> 00937 struct functor_traits<std::logical_or<T> > 00938 { enum { Cost = 1, PacketAccess = false }; }; 00939 00940 template<typename T> 00941 struct functor_traits<std::logical_and<T> > 00942 { enum { Cost = 1, PacketAccess = false }; }; 00943 00944 template<typename T> 00945 struct functor_traits<std::logical_not<T> > 00946 { enum { Cost = 1, PacketAccess = false }; }; 00947 00948 template<typename T> 00949 struct functor_traits<std::greater<T> > 00950 { enum { Cost = 1, PacketAccess = false }; }; 00951 00952 template<typename T> 00953 struct functor_traits<std::less<T> > 00954 { enum { Cost = 1, PacketAccess = false }; }; 00955 00956 template<typename T> 00957 struct functor_traits<std::greater_equal<T> > 00958 { enum { Cost = 1, PacketAccess = false }; }; 00959 00960 template<typename T> 00961 struct functor_traits<std::less_equal<T> > 00962 { enum { Cost = 1, PacketAccess = false }; }; 00963 00964 template<typename T> 00965 struct functor_traits<std::equal_to<T> > 00966 { enum { Cost = 1, PacketAccess = false }; }; 00967 00968 template<typename T> 00969 struct functor_traits<std::not_equal_to<T> > 00970 { enum { Cost = 1, PacketAccess = false }; }; 00971 00972 template<typename T> 00973 struct functor_traits<std::binder2nd<T> > 00974 { enum { Cost = functor_traits<T>::Cost, PacketAccess = false }; }; 00975 00976 template<typename T> 00977 struct functor_traits<std::binder1st<T> > 00978 { enum { Cost = functor_traits<T>::Cost, PacketAccess = false }; }; 00979 00980 template<typename T> 00981 struct functor_traits<std::unary_negate<T> > 00982 { enum { Cost = 1 + functor_traits<T>::Cost, PacketAccess = false }; }; 00983 00984 template<typename T> 00985 struct functor_traits<std::binary_negate<T> > 00986 { enum { Cost = 1 + functor_traits<T>::Cost, PacketAccess = false }; }; 00987 00988 #ifdef EIGEN_STDEXT_SUPPORT 00989 00990 template<typename T0,typename T1> 00991 struct functor_traits<std::project1st<T0,T1> > 00992 { enum { Cost = 0, PacketAccess = false }; }; 00993 00994 template<typename T0,typename T1> 00995 struct functor_traits<std::project2nd<T0,T1> > 00996 { enum { Cost = 0, PacketAccess = false }; }; 00997 00998 template<typename T0,typename T1> 00999 struct functor_traits<std::select2nd<std::pair<T0,T1> > > 01000 { enum { Cost = 0, PacketAccess = false }; }; 01001 01002 template<typename T0,typename T1> 01003 struct functor_traits<std::select1st<std::pair<T0,T1> > > 01004 { enum { Cost = 0, PacketAccess = false }; }; 01005 01006 template<typename T0,typename T1> 01007 struct functor_traits<std::unary_compose<T0,T1> > 01008 { enum { Cost = functor_traits<T0>::Cost + functor_traits<T1>::Cost, PacketAccess = false }; }; 01009 01010 template<typename T0,typename T1,typename T2> 01011 struct functor_traits<std::binary_compose<T0,T1,T2> > 01012 { enum { Cost = functor_traits<T0>::Cost + functor_traits<T1>::Cost + functor_traits<T2>::Cost, PacketAccess = false }; }; 01013 01014 #endif // EIGEN_STDEXT_SUPPORT 01015 01016 // allow to add new functors and specializations of functor_traits from outside Eigen. 01017 // this macro is really needed because functor_traits must be specialized after it is declared but before it is used... 01018 #ifdef EIGEN_FUNCTORS_PLUGIN 01019 #include EIGEN_FUNCTORS_PLUGIN 01020 #endif 01021 01022 } // end namespace internal 01023 01024 } // end namespace Eigen 01025 01026 #endif // EIGEN_FUNCTORS_H
Generated on Thu Nov 17 2022 22:01:28 by
1.7.2