Committer:
ykuroda
Date:
Thu Oct 13 04:07:23 2016 +0000
Revision:
0:13a5d365ba16
First commint, Eigne Matrix Class Library

Who changed what in which revision?

UserRevisionLine numberNew contents of line
ykuroda 0:13a5d365ba16 1 // This file is part of Eigen, a lightweight C++ template library
ykuroda 0:13a5d365ba16 2 // for linear algebra.
ykuroda 0:13a5d365ba16 3 //
ykuroda 0:13a5d365ba16 4 // Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
ykuroda 0:13a5d365ba16 5 //
ykuroda 0:13a5d365ba16 6 // This Source Code Form is subject to the terms of the Mozilla
ykuroda 0:13a5d365ba16 7 // Public License v. 2.0. If a copy of the MPL was not distributed
ykuroda 0:13a5d365ba16 8 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
ykuroda 0:13a5d365ba16 9
ykuroda 0:13a5d365ba16 10 #ifndef EIGEN_FUNCTORS_H
ykuroda 0:13a5d365ba16 11 #define EIGEN_FUNCTORS_H
ykuroda 0:13a5d365ba16 12
ykuroda 0:13a5d365ba16 13 namespace Eigen {
ykuroda 0:13a5d365ba16 14
ykuroda 0:13a5d365ba16 15 namespace internal {
ykuroda 0:13a5d365ba16 16
ykuroda 0:13a5d365ba16 17 // associative functors:
ykuroda 0:13a5d365ba16 18
ykuroda 0:13a5d365ba16 19 /** \internal
ykuroda 0:13a5d365ba16 20 * \brief Template functor to compute the sum of two scalars
ykuroda 0:13a5d365ba16 21 *
ykuroda 0:13a5d365ba16 22 * \sa class CwiseBinaryOp, MatrixBase::operator+, class VectorwiseOp, MatrixBase::sum()
ykuroda 0:13a5d365ba16 23 */
ykuroda 0:13a5d365ba16 24 template<typename Scalar> struct scalar_sum_op {
ykuroda 0:13a5d365ba16 25 EIGEN_EMPTY_STRUCT_CTOR(scalar_sum_op)
ykuroda 0:13a5d365ba16 26 EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return a + b; }
ykuroda 0:13a5d365ba16 27 template<typename Packet>
ykuroda 0:13a5d365ba16 28 EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
ykuroda 0:13a5d365ba16 29 { return internal::padd(a,b); }
ykuroda 0:13a5d365ba16 30 template<typename Packet>
ykuroda 0:13a5d365ba16 31 EIGEN_STRONG_INLINE const Scalar predux(const Packet& a) const
ykuroda 0:13a5d365ba16 32 { return internal::predux(a); }
ykuroda 0:13a5d365ba16 33 };
ykuroda 0:13a5d365ba16 34 template<typename Scalar>
ykuroda 0:13a5d365ba16 35 struct functor_traits<scalar_sum_op<Scalar> > {
ykuroda 0:13a5d365ba16 36 enum {
ykuroda 0:13a5d365ba16 37 Cost = NumTraits<Scalar>::AddCost,
ykuroda 0:13a5d365ba16 38 PacketAccess = packet_traits<Scalar>::HasAdd
ykuroda 0:13a5d365ba16 39 };
ykuroda 0:13a5d365ba16 40 };
ykuroda 0:13a5d365ba16 41
ykuroda 0:13a5d365ba16 42 /** \internal
ykuroda 0:13a5d365ba16 43 * \brief Template functor to compute the product of two scalars
ykuroda 0:13a5d365ba16 44 *
ykuroda 0:13a5d365ba16 45 * \sa class CwiseBinaryOp, Cwise::operator*(), class VectorwiseOp, MatrixBase::redux()
ykuroda 0:13a5d365ba16 46 */
ykuroda 0:13a5d365ba16 47 template<typename LhsScalar,typename RhsScalar> struct scalar_product_op {
ykuroda 0:13a5d365ba16 48 enum {
ykuroda 0:13a5d365ba16 49 // TODO vectorize mixed product
ykuroda 0:13a5d365ba16 50 Vectorizable = is_same<LhsScalar,RhsScalar>::value && packet_traits<LhsScalar>::HasMul && packet_traits<RhsScalar>::HasMul
ykuroda 0:13a5d365ba16 51 };
ykuroda 0:13a5d365ba16 52 typedef typename scalar_product_traits<LhsScalar,RhsScalar>::ReturnType result_type;
ykuroda 0:13a5d365ba16 53 EIGEN_EMPTY_STRUCT_CTOR(scalar_product_op)
ykuroda 0:13a5d365ba16 54 EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const { return a * b; }
ykuroda 0:13a5d365ba16 55 template<typename Packet>
ykuroda 0:13a5d365ba16 56 EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
ykuroda 0:13a5d365ba16 57 { return internal::pmul(a,b); }
ykuroda 0:13a5d365ba16 58 template<typename Packet>
ykuroda 0:13a5d365ba16 59 EIGEN_STRONG_INLINE const result_type predux(const Packet& a) const
ykuroda 0:13a5d365ba16 60 { return internal::predux_mul(a); }
ykuroda 0:13a5d365ba16 61 };
ykuroda 0:13a5d365ba16 62 template<typename LhsScalar,typename RhsScalar>
ykuroda 0:13a5d365ba16 63 struct functor_traits<scalar_product_op<LhsScalar,RhsScalar> > {
ykuroda 0:13a5d365ba16 64 enum {
ykuroda 0:13a5d365ba16 65 Cost = (NumTraits<LhsScalar>::MulCost + NumTraits<RhsScalar>::MulCost)/2, // rough estimate!
ykuroda 0:13a5d365ba16 66 PacketAccess = scalar_product_op<LhsScalar,RhsScalar>::Vectorizable
ykuroda 0:13a5d365ba16 67 };
ykuroda 0:13a5d365ba16 68 };
ykuroda 0:13a5d365ba16 69
ykuroda 0:13a5d365ba16 70 /** \internal
ykuroda 0:13a5d365ba16 71 * \brief Template functor to compute the conjugate product of two scalars
ykuroda 0:13a5d365ba16 72 *
ykuroda 0:13a5d365ba16 73 * This is a short cut for conj(x) * y which is needed for optimization purpose; in Eigen2 support mode, this becomes x * conj(y)
ykuroda 0:13a5d365ba16 74 */
ykuroda 0:13a5d365ba16 75 template<typename LhsScalar,typename RhsScalar> struct scalar_conj_product_op {
ykuroda 0:13a5d365ba16 76
ykuroda 0:13a5d365ba16 77 enum {
ykuroda 0:13a5d365ba16 78 Conj = NumTraits<LhsScalar>::IsComplex
ykuroda 0:13a5d365ba16 79 };
ykuroda 0:13a5d365ba16 80
ykuroda 0:13a5d365ba16 81 typedef typename scalar_product_traits<LhsScalar,RhsScalar>::ReturnType result_type;
ykuroda 0:13a5d365ba16 82
ykuroda 0:13a5d365ba16 83 EIGEN_EMPTY_STRUCT_CTOR(scalar_conj_product_op)
ykuroda 0:13a5d365ba16 84 EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const
ykuroda 0:13a5d365ba16 85 { return conj_helper<LhsScalar,RhsScalar,Conj,false>().pmul(a,b); }
ykuroda 0:13a5d365ba16 86
ykuroda 0:13a5d365ba16 87 template<typename Packet>
ykuroda 0:13a5d365ba16 88 EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
ykuroda 0:13a5d365ba16 89 { return conj_helper<Packet,Packet,Conj,false>().pmul(a,b); }
ykuroda 0:13a5d365ba16 90 };
ykuroda 0:13a5d365ba16 91 template<typename LhsScalar,typename RhsScalar>
ykuroda 0:13a5d365ba16 92 struct functor_traits<scalar_conj_product_op<LhsScalar,RhsScalar> > {
ykuroda 0:13a5d365ba16 93 enum {
ykuroda 0:13a5d365ba16 94 Cost = NumTraits<LhsScalar>::MulCost,
ykuroda 0:13a5d365ba16 95 PacketAccess = internal::is_same<LhsScalar, RhsScalar>::value && packet_traits<LhsScalar>::HasMul
ykuroda 0:13a5d365ba16 96 };
ykuroda 0:13a5d365ba16 97 };
ykuroda 0:13a5d365ba16 98
ykuroda 0:13a5d365ba16 99 /** \internal
ykuroda 0:13a5d365ba16 100 * \brief Template functor to compute the min of two scalars
ykuroda 0:13a5d365ba16 101 *
ykuroda 0:13a5d365ba16 102 * \sa class CwiseBinaryOp, MatrixBase::cwiseMin, class VectorwiseOp, MatrixBase::minCoeff()
ykuroda 0:13a5d365ba16 103 */
ykuroda 0:13a5d365ba16 104 template<typename Scalar> struct scalar_min_op {
ykuroda 0:13a5d365ba16 105 EIGEN_EMPTY_STRUCT_CTOR(scalar_min_op)
ykuroda 0:13a5d365ba16 106 EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { using std::min; return (min)(a, b); }
ykuroda 0:13a5d365ba16 107 template<typename Packet>
ykuroda 0:13a5d365ba16 108 EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
ykuroda 0:13a5d365ba16 109 { return internal::pmin(a,b); }
ykuroda 0:13a5d365ba16 110 template<typename Packet>
ykuroda 0:13a5d365ba16 111 EIGEN_STRONG_INLINE const Scalar predux(const Packet& a) const
ykuroda 0:13a5d365ba16 112 { return internal::predux_min(a); }
ykuroda 0:13a5d365ba16 113 };
ykuroda 0:13a5d365ba16 114 template<typename Scalar>
ykuroda 0:13a5d365ba16 115 struct functor_traits<scalar_min_op<Scalar> > {
ykuroda 0:13a5d365ba16 116 enum {
ykuroda 0:13a5d365ba16 117 Cost = NumTraits<Scalar>::AddCost,
ykuroda 0:13a5d365ba16 118 PacketAccess = packet_traits<Scalar>::HasMin
ykuroda 0:13a5d365ba16 119 };
ykuroda 0:13a5d365ba16 120 };
ykuroda 0:13a5d365ba16 121
ykuroda 0:13a5d365ba16 122 /** \internal
ykuroda 0:13a5d365ba16 123 * \brief Template functor to compute the max of two scalars
ykuroda 0:13a5d365ba16 124 *
ykuroda 0:13a5d365ba16 125 * \sa class CwiseBinaryOp, MatrixBase::cwiseMax, class VectorwiseOp, MatrixBase::maxCoeff()
ykuroda 0:13a5d365ba16 126 */
ykuroda 0:13a5d365ba16 127 template<typename Scalar> struct scalar_max_op {
ykuroda 0:13a5d365ba16 128 EIGEN_EMPTY_STRUCT_CTOR(scalar_max_op)
ykuroda 0:13a5d365ba16 129 EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { using std::max; return (max)(a, b); }
ykuroda 0:13a5d365ba16 130 template<typename Packet>
ykuroda 0:13a5d365ba16 131 EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
ykuroda 0:13a5d365ba16 132 { return internal::pmax(a,b); }
ykuroda 0:13a5d365ba16 133 template<typename Packet>
ykuroda 0:13a5d365ba16 134 EIGEN_STRONG_INLINE const Scalar predux(const Packet& a) const
ykuroda 0:13a5d365ba16 135 { return internal::predux_max(a); }
ykuroda 0:13a5d365ba16 136 };
ykuroda 0:13a5d365ba16 137 template<typename Scalar>
ykuroda 0:13a5d365ba16 138 struct functor_traits<scalar_max_op<Scalar> > {
ykuroda 0:13a5d365ba16 139 enum {
ykuroda 0:13a5d365ba16 140 Cost = NumTraits<Scalar>::AddCost,
ykuroda 0:13a5d365ba16 141 PacketAccess = packet_traits<Scalar>::HasMax
ykuroda 0:13a5d365ba16 142 };
ykuroda 0:13a5d365ba16 143 };
ykuroda 0:13a5d365ba16 144
ykuroda 0:13a5d365ba16 145 /** \internal
ykuroda 0:13a5d365ba16 146 * \brief Template functor to compute the hypot of two scalars
ykuroda 0:13a5d365ba16 147 *
ykuroda 0:13a5d365ba16 148 * \sa MatrixBase::stableNorm(), class Redux
ykuroda 0:13a5d365ba16 149 */
ykuroda 0:13a5d365ba16 150 template<typename Scalar> struct scalar_hypot_op {
ykuroda 0:13a5d365ba16 151 EIGEN_EMPTY_STRUCT_CTOR(scalar_hypot_op)
ykuroda 0:13a5d365ba16 152 // typedef typename NumTraits<Scalar>::Real result_type;
ykuroda 0:13a5d365ba16 153 EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& _x, const Scalar& _y) const
ykuroda 0:13a5d365ba16 154 {
ykuroda 0:13a5d365ba16 155 using std::max;
ykuroda 0:13a5d365ba16 156 using std::min;
ykuroda 0:13a5d365ba16 157 using std::sqrt;
ykuroda 0:13a5d365ba16 158 Scalar p = (max)(_x, _y);
ykuroda 0:13a5d365ba16 159 Scalar q = (min)(_x, _y);
ykuroda 0:13a5d365ba16 160 Scalar qp = q/p;
ykuroda 0:13a5d365ba16 161 return p * sqrt(Scalar(1) + qp*qp);
ykuroda 0:13a5d365ba16 162 }
ykuroda 0:13a5d365ba16 163 };
ykuroda 0:13a5d365ba16 164 template<typename Scalar>
ykuroda 0:13a5d365ba16 165 struct functor_traits<scalar_hypot_op<Scalar> > {
ykuroda 0:13a5d365ba16 166 enum { Cost = 5 * NumTraits<Scalar>::MulCost, PacketAccess=0 };
ykuroda 0:13a5d365ba16 167 };
ykuroda 0:13a5d365ba16 168
ykuroda 0:13a5d365ba16 169 /** \internal
ykuroda 0:13a5d365ba16 170 * \brief Template functor to compute the pow of two scalars
ykuroda 0:13a5d365ba16 171 */
ykuroda 0:13a5d365ba16 172 template<typename Scalar, typename OtherScalar> struct scalar_binary_pow_op {
ykuroda 0:13a5d365ba16 173 EIGEN_EMPTY_STRUCT_CTOR(scalar_binary_pow_op)
ykuroda 0:13a5d365ba16 174 inline Scalar operator() (const Scalar& a, const OtherScalar& b) const { return numext::pow(a, b); }
ykuroda 0:13a5d365ba16 175 };
ykuroda 0:13a5d365ba16 176 template<typename Scalar, typename OtherScalar>
ykuroda 0:13a5d365ba16 177 struct functor_traits<scalar_binary_pow_op<Scalar,OtherScalar> > {
ykuroda 0:13a5d365ba16 178 enum { Cost = 5 * NumTraits<Scalar>::MulCost, PacketAccess = false };
ykuroda 0:13a5d365ba16 179 };
ykuroda 0:13a5d365ba16 180
ykuroda 0:13a5d365ba16 181 // other binary functors:
ykuroda 0:13a5d365ba16 182
ykuroda 0:13a5d365ba16 183 /** \internal
ykuroda 0:13a5d365ba16 184 * \brief Template functor to compute the difference of two scalars
ykuroda 0:13a5d365ba16 185 *
ykuroda 0:13a5d365ba16 186 * \sa class CwiseBinaryOp, MatrixBase::operator-
ykuroda 0:13a5d365ba16 187 */
ykuroda 0:13a5d365ba16 188 template<typename Scalar> struct scalar_difference_op {
ykuroda 0:13a5d365ba16 189 EIGEN_EMPTY_STRUCT_CTOR(scalar_difference_op)
ykuroda 0:13a5d365ba16 190 EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return a - b; }
ykuroda 0:13a5d365ba16 191 template<typename Packet>
ykuroda 0:13a5d365ba16 192 EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
ykuroda 0:13a5d365ba16 193 { return internal::psub(a,b); }
ykuroda 0:13a5d365ba16 194 };
ykuroda 0:13a5d365ba16 195 template<typename Scalar>
ykuroda 0:13a5d365ba16 196 struct functor_traits<scalar_difference_op<Scalar> > {
ykuroda 0:13a5d365ba16 197 enum {
ykuroda 0:13a5d365ba16 198 Cost = NumTraits<Scalar>::AddCost,
ykuroda 0:13a5d365ba16 199 PacketAccess = packet_traits<Scalar>::HasSub
ykuroda 0:13a5d365ba16 200 };
ykuroda 0:13a5d365ba16 201 };
ykuroda 0:13a5d365ba16 202
ykuroda 0:13a5d365ba16 203 /** \internal
ykuroda 0:13a5d365ba16 204 * \brief Template functor to compute the quotient of two scalars
ykuroda 0:13a5d365ba16 205 *
ykuroda 0:13a5d365ba16 206 * \sa class CwiseBinaryOp, Cwise::operator/()
ykuroda 0:13a5d365ba16 207 */
ykuroda 0:13a5d365ba16 208 template<typename LhsScalar,typename RhsScalar> struct scalar_quotient_op {
ykuroda 0:13a5d365ba16 209 enum {
ykuroda 0:13a5d365ba16 210 // TODO vectorize mixed product
ykuroda 0:13a5d365ba16 211 Vectorizable = is_same<LhsScalar,RhsScalar>::value && packet_traits<LhsScalar>::HasDiv && packet_traits<RhsScalar>::HasDiv
ykuroda 0:13a5d365ba16 212 };
ykuroda 0:13a5d365ba16 213 typedef typename scalar_product_traits<LhsScalar,RhsScalar>::ReturnType result_type;
ykuroda 0:13a5d365ba16 214 EIGEN_EMPTY_STRUCT_CTOR(scalar_quotient_op)
ykuroda 0:13a5d365ba16 215 EIGEN_STRONG_INLINE const result_type operator() (const LhsScalar& a, const RhsScalar& b) const { return a / b; }
ykuroda 0:13a5d365ba16 216 template<typename Packet>
ykuroda 0:13a5d365ba16 217 EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a, const Packet& b) const
ykuroda 0:13a5d365ba16 218 { return internal::pdiv(a,b); }
ykuroda 0:13a5d365ba16 219 };
ykuroda 0:13a5d365ba16 220 template<typename LhsScalar,typename RhsScalar>
ykuroda 0:13a5d365ba16 221 struct functor_traits<scalar_quotient_op<LhsScalar,RhsScalar> > {
ykuroda 0:13a5d365ba16 222 enum {
ykuroda 0:13a5d365ba16 223 Cost = (NumTraits<LhsScalar>::MulCost + NumTraits<RhsScalar>::MulCost), // rough estimate!
ykuroda 0:13a5d365ba16 224 PacketAccess = scalar_quotient_op<LhsScalar,RhsScalar>::Vectorizable
ykuroda 0:13a5d365ba16 225 };
ykuroda 0:13a5d365ba16 226 };
ykuroda 0:13a5d365ba16 227
ykuroda 0:13a5d365ba16 228
ykuroda 0:13a5d365ba16 229
ykuroda 0:13a5d365ba16 230 /** \internal
ykuroda 0:13a5d365ba16 231 * \brief Template functor to compute the and of two booleans
ykuroda 0:13a5d365ba16 232 *
ykuroda 0:13a5d365ba16 233 * \sa class CwiseBinaryOp, ArrayBase::operator&&
ykuroda 0:13a5d365ba16 234 */
ykuroda 0:13a5d365ba16 235 struct scalar_boolean_and_op {
ykuroda 0:13a5d365ba16 236 EIGEN_EMPTY_STRUCT_CTOR(scalar_boolean_and_op)
ykuroda 0:13a5d365ba16 237 EIGEN_STRONG_INLINE bool operator() (const bool& a, const bool& b) const { return a && b; }
ykuroda 0:13a5d365ba16 238 };
ykuroda 0:13a5d365ba16 239 template<> struct functor_traits<scalar_boolean_and_op> {
ykuroda 0:13a5d365ba16 240 enum {
ykuroda 0:13a5d365ba16 241 Cost = NumTraits<bool>::AddCost,
ykuroda 0:13a5d365ba16 242 PacketAccess = false
ykuroda 0:13a5d365ba16 243 };
ykuroda 0:13a5d365ba16 244 };
ykuroda 0:13a5d365ba16 245
ykuroda 0:13a5d365ba16 246 /** \internal
ykuroda 0:13a5d365ba16 247 * \brief Template functor to compute the or of two booleans
ykuroda 0:13a5d365ba16 248 *
ykuroda 0:13a5d365ba16 249 * \sa class CwiseBinaryOp, ArrayBase::operator||
ykuroda 0:13a5d365ba16 250 */
ykuroda 0:13a5d365ba16 251 struct scalar_boolean_or_op {
ykuroda 0:13a5d365ba16 252 EIGEN_EMPTY_STRUCT_CTOR(scalar_boolean_or_op)
ykuroda 0:13a5d365ba16 253 EIGEN_STRONG_INLINE bool operator() (const bool& a, const bool& b) const { return a || b; }
ykuroda 0:13a5d365ba16 254 };
ykuroda 0:13a5d365ba16 255 template<> struct functor_traits<scalar_boolean_or_op> {
ykuroda 0:13a5d365ba16 256 enum {
ykuroda 0:13a5d365ba16 257 Cost = NumTraits<bool>::AddCost,
ykuroda 0:13a5d365ba16 258 PacketAccess = false
ykuroda 0:13a5d365ba16 259 };
ykuroda 0:13a5d365ba16 260 };
ykuroda 0:13a5d365ba16 261
ykuroda 0:13a5d365ba16 262 /** \internal
ykuroda 0:13a5d365ba16 263 * \brief Template functors for comparison of two scalars
ykuroda 0:13a5d365ba16 264 * \todo Implement packet-comparisons
ykuroda 0:13a5d365ba16 265 */
ykuroda 0:13a5d365ba16 266 template<typename Scalar, ComparisonName cmp> struct scalar_cmp_op;
ykuroda 0:13a5d365ba16 267
ykuroda 0:13a5d365ba16 268 template<typename Scalar, ComparisonName cmp>
ykuroda 0:13a5d365ba16 269 struct functor_traits<scalar_cmp_op<Scalar, cmp> > {
ykuroda 0:13a5d365ba16 270 enum {
ykuroda 0:13a5d365ba16 271 Cost = NumTraits<Scalar>::AddCost,
ykuroda 0:13a5d365ba16 272 PacketAccess = false
ykuroda 0:13a5d365ba16 273 };
ykuroda 0:13a5d365ba16 274 };
ykuroda 0:13a5d365ba16 275
ykuroda 0:13a5d365ba16 276 template<ComparisonName Cmp, typename Scalar>
ykuroda 0:13a5d365ba16 277 struct result_of<scalar_cmp_op<Scalar, Cmp>(Scalar,Scalar)> {
ykuroda 0:13a5d365ba16 278 typedef bool type;
ykuroda 0:13a5d365ba16 279 };
ykuroda 0:13a5d365ba16 280
ykuroda 0:13a5d365ba16 281
ykuroda 0:13a5d365ba16 282 template<typename Scalar> struct scalar_cmp_op<Scalar, cmp_EQ> {
ykuroda 0:13a5d365ba16 283 EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op)
ykuroda 0:13a5d365ba16 284 EIGEN_STRONG_INLINE bool operator()(const Scalar& a, const Scalar& b) const {return a==b;}
ykuroda 0:13a5d365ba16 285 };
ykuroda 0:13a5d365ba16 286 template<typename Scalar> struct scalar_cmp_op<Scalar, cmp_LT> {
ykuroda 0:13a5d365ba16 287 EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op)
ykuroda 0:13a5d365ba16 288 EIGEN_STRONG_INLINE bool operator()(const Scalar& a, const Scalar& b) const {return a<b;}
ykuroda 0:13a5d365ba16 289 };
ykuroda 0:13a5d365ba16 290 template<typename Scalar> struct scalar_cmp_op<Scalar, cmp_LE> {
ykuroda 0:13a5d365ba16 291 EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op)
ykuroda 0:13a5d365ba16 292 EIGEN_STRONG_INLINE bool operator()(const Scalar& a, const Scalar& b) const {return a<=b;}
ykuroda 0:13a5d365ba16 293 };
ykuroda 0:13a5d365ba16 294 template<typename Scalar> struct scalar_cmp_op<Scalar, cmp_UNORD> {
ykuroda 0:13a5d365ba16 295 EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op)
ykuroda 0:13a5d365ba16 296 EIGEN_STRONG_INLINE bool operator()(const Scalar& a, const Scalar& b) const {return !(a<=b || b<=a);}
ykuroda 0:13a5d365ba16 297 };
ykuroda 0:13a5d365ba16 298 template<typename Scalar> struct scalar_cmp_op<Scalar, cmp_NEQ> {
ykuroda 0:13a5d365ba16 299 EIGEN_EMPTY_STRUCT_CTOR(scalar_cmp_op)
ykuroda 0:13a5d365ba16 300 EIGEN_STRONG_INLINE bool operator()(const Scalar& a, const Scalar& b) const {return a!=b;}
ykuroda 0:13a5d365ba16 301 };
ykuroda 0:13a5d365ba16 302
ykuroda 0:13a5d365ba16 303 // unary functors:
ykuroda 0:13a5d365ba16 304
ykuroda 0:13a5d365ba16 305 /** \internal
ykuroda 0:13a5d365ba16 306 * \brief Template functor to compute the opposite of a scalar
ykuroda 0:13a5d365ba16 307 *
ykuroda 0:13a5d365ba16 308 * \sa class CwiseUnaryOp, MatrixBase::operator-
ykuroda 0:13a5d365ba16 309 */
ykuroda 0:13a5d365ba16 310 template<typename Scalar> struct scalar_opposite_op {
ykuroda 0:13a5d365ba16 311 EIGEN_EMPTY_STRUCT_CTOR(scalar_opposite_op)
ykuroda 0:13a5d365ba16 312 EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a) const { return -a; }
ykuroda 0:13a5d365ba16 313 template<typename Packet>
ykuroda 0:13a5d365ba16 314 EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const
ykuroda 0:13a5d365ba16 315 { return internal::pnegate(a); }
ykuroda 0:13a5d365ba16 316 };
ykuroda 0:13a5d365ba16 317 template<typename Scalar>
ykuroda 0:13a5d365ba16 318 struct functor_traits<scalar_opposite_op<Scalar> >
ykuroda 0:13a5d365ba16 319 { enum {
ykuroda 0:13a5d365ba16 320 Cost = NumTraits<Scalar>::AddCost,
ykuroda 0:13a5d365ba16 321 PacketAccess = packet_traits<Scalar>::HasNegate };
ykuroda 0:13a5d365ba16 322 };
ykuroda 0:13a5d365ba16 323
ykuroda 0:13a5d365ba16 324 /** \internal
ykuroda 0:13a5d365ba16 325 * \brief Template functor to compute the absolute value of a scalar
ykuroda 0:13a5d365ba16 326 *
ykuroda 0:13a5d365ba16 327 * \sa class CwiseUnaryOp, Cwise::abs
ykuroda 0:13a5d365ba16 328 */
ykuroda 0:13a5d365ba16 329 template<typename Scalar> struct scalar_abs_op {
ykuroda 0:13a5d365ba16 330 EIGEN_EMPTY_STRUCT_CTOR(scalar_abs_op)
ykuroda 0:13a5d365ba16 331 typedef typename NumTraits<Scalar>::Real result_type;
ykuroda 0:13a5d365ba16 332 EIGEN_STRONG_INLINE const result_type operator() (const Scalar& a) const { using std::abs; return abs(a); }
ykuroda 0:13a5d365ba16 333 template<typename Packet>
ykuroda 0:13a5d365ba16 334 EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const
ykuroda 0:13a5d365ba16 335 { return internal::pabs(a); }
ykuroda 0:13a5d365ba16 336 };
ykuroda 0:13a5d365ba16 337 template<typename Scalar>
ykuroda 0:13a5d365ba16 338 struct functor_traits<scalar_abs_op<Scalar> >
ykuroda 0:13a5d365ba16 339 {
ykuroda 0:13a5d365ba16 340 enum {
ykuroda 0:13a5d365ba16 341 Cost = NumTraits<Scalar>::AddCost,
ykuroda 0:13a5d365ba16 342 PacketAccess = packet_traits<Scalar>::HasAbs
ykuroda 0:13a5d365ba16 343 };
ykuroda 0:13a5d365ba16 344 };
ykuroda 0:13a5d365ba16 345
ykuroda 0:13a5d365ba16 346 /** \internal
ykuroda 0:13a5d365ba16 347 * \brief Template functor to compute the squared absolute value of a scalar
ykuroda 0:13a5d365ba16 348 *
ykuroda 0:13a5d365ba16 349 * \sa class CwiseUnaryOp, Cwise::abs2
ykuroda 0:13a5d365ba16 350 */
ykuroda 0:13a5d365ba16 351 template<typename Scalar> struct scalar_abs2_op {
ykuroda 0:13a5d365ba16 352 EIGEN_EMPTY_STRUCT_CTOR(scalar_abs2_op)
ykuroda 0:13a5d365ba16 353 typedef typename NumTraits<Scalar>::Real result_type;
ykuroda 0:13a5d365ba16 354 EIGEN_STRONG_INLINE const result_type operator() (const Scalar& a) const { return numext::abs2(a); }
ykuroda 0:13a5d365ba16 355 template<typename Packet>
ykuroda 0:13a5d365ba16 356 EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const
ykuroda 0:13a5d365ba16 357 { return internal::pmul(a,a); }
ykuroda 0:13a5d365ba16 358 };
ykuroda 0:13a5d365ba16 359 template<typename Scalar>
ykuroda 0:13a5d365ba16 360 struct functor_traits<scalar_abs2_op<Scalar> >
ykuroda 0:13a5d365ba16 361 { enum { Cost = NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasAbs2 }; };
ykuroda 0:13a5d365ba16 362
ykuroda 0:13a5d365ba16 363 /** \internal
ykuroda 0:13a5d365ba16 364 * \brief Template functor to compute the conjugate of a complex value
ykuroda 0:13a5d365ba16 365 *
ykuroda 0:13a5d365ba16 366 * \sa class CwiseUnaryOp, MatrixBase::conjugate()
ykuroda 0:13a5d365ba16 367 */
ykuroda 0:13a5d365ba16 368 template<typename Scalar> struct scalar_conjugate_op {
ykuroda 0:13a5d365ba16 369 EIGEN_EMPTY_STRUCT_CTOR(scalar_conjugate_op)
ykuroda 0:13a5d365ba16 370 EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a) const { using numext::conj; return conj(a); }
ykuroda 0:13a5d365ba16 371 template<typename Packet>
ykuroda 0:13a5d365ba16 372 EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const { return internal::pconj(a); }
ykuroda 0:13a5d365ba16 373 };
ykuroda 0:13a5d365ba16 374 template<typename Scalar>
ykuroda 0:13a5d365ba16 375 struct functor_traits<scalar_conjugate_op<Scalar> >
ykuroda 0:13a5d365ba16 376 {
ykuroda 0:13a5d365ba16 377 enum {
ykuroda 0:13a5d365ba16 378 Cost = NumTraits<Scalar>::IsComplex ? NumTraits<Scalar>::AddCost : 0,
ykuroda 0:13a5d365ba16 379 PacketAccess = packet_traits<Scalar>::HasConj
ykuroda 0:13a5d365ba16 380 };
ykuroda 0:13a5d365ba16 381 };
ykuroda 0:13a5d365ba16 382
ykuroda 0:13a5d365ba16 383 /** \internal
ykuroda 0:13a5d365ba16 384 * \brief Template functor to cast a scalar to another type
ykuroda 0:13a5d365ba16 385 *
ykuroda 0:13a5d365ba16 386 * \sa class CwiseUnaryOp, MatrixBase::cast()
ykuroda 0:13a5d365ba16 387 */
ykuroda 0:13a5d365ba16 388 template<typename Scalar, typename NewType>
ykuroda 0:13a5d365ba16 389 struct scalar_cast_op {
ykuroda 0:13a5d365ba16 390 EIGEN_EMPTY_STRUCT_CTOR(scalar_cast_op)
ykuroda 0:13a5d365ba16 391 typedef NewType result_type;
ykuroda 0:13a5d365ba16 392 EIGEN_STRONG_INLINE const NewType operator() (const Scalar& a) const { return cast<Scalar, NewType>(a); }
ykuroda 0:13a5d365ba16 393 };
ykuroda 0:13a5d365ba16 394 template<typename Scalar, typename NewType>
ykuroda 0:13a5d365ba16 395 struct functor_traits<scalar_cast_op<Scalar,NewType> >
ykuroda 0:13a5d365ba16 396 { enum { Cost = is_same<Scalar, NewType>::value ? 0 : NumTraits<NewType>::AddCost, PacketAccess = false }; };
ykuroda 0:13a5d365ba16 397
ykuroda 0:13a5d365ba16 398 /** \internal
ykuroda 0:13a5d365ba16 399 * \brief Template functor to extract the real part of a complex
ykuroda 0:13a5d365ba16 400 *
ykuroda 0:13a5d365ba16 401 * \sa class CwiseUnaryOp, MatrixBase::real()
ykuroda 0:13a5d365ba16 402 */
ykuroda 0:13a5d365ba16 403 template<typename Scalar>
ykuroda 0:13a5d365ba16 404 struct scalar_real_op {
ykuroda 0:13a5d365ba16 405 EIGEN_EMPTY_STRUCT_CTOR(scalar_real_op)
ykuroda 0:13a5d365ba16 406 typedef typename NumTraits<Scalar>::Real result_type;
ykuroda 0:13a5d365ba16 407 EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return numext::real(a); }
ykuroda 0:13a5d365ba16 408 };
ykuroda 0:13a5d365ba16 409 template<typename Scalar>
ykuroda 0:13a5d365ba16 410 struct functor_traits<scalar_real_op<Scalar> >
ykuroda 0:13a5d365ba16 411 { enum { Cost = 0, PacketAccess = false }; };
ykuroda 0:13a5d365ba16 412
ykuroda 0:13a5d365ba16 413 /** \internal
ykuroda 0:13a5d365ba16 414 * \brief Template functor to extract the imaginary part of a complex
ykuroda 0:13a5d365ba16 415 *
ykuroda 0:13a5d365ba16 416 * \sa class CwiseUnaryOp, MatrixBase::imag()
ykuroda 0:13a5d365ba16 417 */
ykuroda 0:13a5d365ba16 418 template<typename Scalar>
ykuroda 0:13a5d365ba16 419 struct scalar_imag_op {
ykuroda 0:13a5d365ba16 420 EIGEN_EMPTY_STRUCT_CTOR(scalar_imag_op)
ykuroda 0:13a5d365ba16 421 typedef typename NumTraits<Scalar>::Real result_type;
ykuroda 0:13a5d365ba16 422 EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return numext::imag(a); }
ykuroda 0:13a5d365ba16 423 };
ykuroda 0:13a5d365ba16 424 template<typename Scalar>
ykuroda 0:13a5d365ba16 425 struct functor_traits<scalar_imag_op<Scalar> >
ykuroda 0:13a5d365ba16 426 { enum { Cost = 0, PacketAccess = false }; };
ykuroda 0:13a5d365ba16 427
ykuroda 0:13a5d365ba16 428 /** \internal
ykuroda 0:13a5d365ba16 429 * \brief Template functor to extract the real part of a complex as a reference
ykuroda 0:13a5d365ba16 430 *
ykuroda 0:13a5d365ba16 431 * \sa class CwiseUnaryOp, MatrixBase::real()
ykuroda 0:13a5d365ba16 432 */
ykuroda 0:13a5d365ba16 433 template<typename Scalar>
ykuroda 0:13a5d365ba16 434 struct scalar_real_ref_op {
ykuroda 0:13a5d365ba16 435 EIGEN_EMPTY_STRUCT_CTOR(scalar_real_ref_op)
ykuroda 0:13a5d365ba16 436 typedef typename NumTraits<Scalar>::Real result_type;
ykuroda 0:13a5d365ba16 437 EIGEN_STRONG_INLINE result_type& operator() (const Scalar& a) const { return numext::real_ref(*const_cast<Scalar*>(&a)); }
ykuroda 0:13a5d365ba16 438 };
ykuroda 0:13a5d365ba16 439 template<typename Scalar>
ykuroda 0:13a5d365ba16 440 struct functor_traits<scalar_real_ref_op<Scalar> >
ykuroda 0:13a5d365ba16 441 { enum { Cost = 0, PacketAccess = false }; };
ykuroda 0:13a5d365ba16 442
ykuroda 0:13a5d365ba16 443 /** \internal
ykuroda 0:13a5d365ba16 444 * \brief Template functor to extract the imaginary part of a complex as a reference
ykuroda 0:13a5d365ba16 445 *
ykuroda 0:13a5d365ba16 446 * \sa class CwiseUnaryOp, MatrixBase::imag()
ykuroda 0:13a5d365ba16 447 */
ykuroda 0:13a5d365ba16 448 template<typename Scalar>
ykuroda 0:13a5d365ba16 449 struct scalar_imag_ref_op {
ykuroda 0:13a5d365ba16 450 EIGEN_EMPTY_STRUCT_CTOR(scalar_imag_ref_op)
ykuroda 0:13a5d365ba16 451 typedef typename NumTraits<Scalar>::Real result_type;
ykuroda 0:13a5d365ba16 452 EIGEN_STRONG_INLINE result_type& operator() (const Scalar& a) const { return numext::imag_ref(*const_cast<Scalar*>(&a)); }
ykuroda 0:13a5d365ba16 453 };
ykuroda 0:13a5d365ba16 454 template<typename Scalar>
ykuroda 0:13a5d365ba16 455 struct functor_traits<scalar_imag_ref_op<Scalar> >
ykuroda 0:13a5d365ba16 456 { enum { Cost = 0, PacketAccess = false }; };
ykuroda 0:13a5d365ba16 457
ykuroda 0:13a5d365ba16 458 /** \internal
ykuroda 0:13a5d365ba16 459 *
ykuroda 0:13a5d365ba16 460 * \brief Template functor to compute the exponential of a scalar
ykuroda 0:13a5d365ba16 461 *
ykuroda 0:13a5d365ba16 462 * \sa class CwiseUnaryOp, Cwise::exp()
ykuroda 0:13a5d365ba16 463 */
ykuroda 0:13a5d365ba16 464 template<typename Scalar> struct scalar_exp_op {
ykuroda 0:13a5d365ba16 465 EIGEN_EMPTY_STRUCT_CTOR(scalar_exp_op)
ykuroda 0:13a5d365ba16 466 inline const Scalar operator() (const Scalar& a) const { using std::exp; return exp(a); }
ykuroda 0:13a5d365ba16 467 typedef typename packet_traits<Scalar>::type Packet;
ykuroda 0:13a5d365ba16 468 inline Packet packetOp(const Packet& a) const { return internal::pexp(a); }
ykuroda 0:13a5d365ba16 469 };
ykuroda 0:13a5d365ba16 470 template<typename Scalar>
ykuroda 0:13a5d365ba16 471 struct functor_traits<scalar_exp_op<Scalar> >
ykuroda 0:13a5d365ba16 472 { enum { Cost = 5 * NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasExp }; };
ykuroda 0:13a5d365ba16 473
ykuroda 0:13a5d365ba16 474 /** \internal
ykuroda 0:13a5d365ba16 475 *
ykuroda 0:13a5d365ba16 476 * \brief Template functor to compute the logarithm of a scalar
ykuroda 0:13a5d365ba16 477 *
ykuroda 0:13a5d365ba16 478 * \sa class CwiseUnaryOp, Cwise::log()
ykuroda 0:13a5d365ba16 479 */
ykuroda 0:13a5d365ba16 480 template<typename Scalar> struct scalar_log_op {
ykuroda 0:13a5d365ba16 481 EIGEN_EMPTY_STRUCT_CTOR(scalar_log_op)
ykuroda 0:13a5d365ba16 482 inline const Scalar operator() (const Scalar& a) const { using std::log; return log(a); }
ykuroda 0:13a5d365ba16 483 typedef typename packet_traits<Scalar>::type Packet;
ykuroda 0:13a5d365ba16 484 inline Packet packetOp(const Packet& a) const { return internal::plog(a); }
ykuroda 0:13a5d365ba16 485 };
ykuroda 0:13a5d365ba16 486 template<typename Scalar>
ykuroda 0:13a5d365ba16 487 struct functor_traits<scalar_log_op<Scalar> >
ykuroda 0:13a5d365ba16 488 { enum { Cost = 5 * NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasLog }; };
ykuroda 0:13a5d365ba16 489
ykuroda 0:13a5d365ba16 490 /** \internal
ykuroda 0:13a5d365ba16 491 * \brief Template functor to multiply a scalar by a fixed other one
ykuroda 0:13a5d365ba16 492 *
ykuroda 0:13a5d365ba16 493 * \sa class CwiseUnaryOp, MatrixBase::operator*, MatrixBase::operator/
ykuroda 0:13a5d365ba16 494 */
ykuroda 0:13a5d365ba16 495 /* NOTE why doing the pset1() in packetOp *is* an optimization ?
ykuroda 0:13a5d365ba16 496 * indeed it seems better to declare m_other as a Packet and do the pset1() once
ykuroda 0:13a5d365ba16 497 * in the constructor. However, in practice:
ykuroda 0:13a5d365ba16 498 * - GCC does not like m_other as a Packet and generate a load every time it needs it
ykuroda 0:13a5d365ba16 499 * - on the other hand GCC is able to moves the pset1() outside the loop :)
ykuroda 0:13a5d365ba16 500 * - simpler code ;)
ykuroda 0:13a5d365ba16 501 * (ICC and gcc 4.4 seems to perform well in both cases, the issue is visible with y = a*x + b*y)
ykuroda 0:13a5d365ba16 502 */
ykuroda 0:13a5d365ba16 503 template<typename Scalar>
ykuroda 0:13a5d365ba16 504 struct scalar_multiple_op {
ykuroda 0:13a5d365ba16 505 typedef typename packet_traits<Scalar>::type Packet;
ykuroda 0:13a5d365ba16 506 // FIXME default copy constructors seems bugged with std::complex<>
ykuroda 0:13a5d365ba16 507 EIGEN_STRONG_INLINE scalar_multiple_op(const scalar_multiple_op& other) : m_other(other.m_other) { }
ykuroda 0:13a5d365ba16 508 EIGEN_STRONG_INLINE scalar_multiple_op(const Scalar& other) : m_other(other) { }
ykuroda 0:13a5d365ba16 509 EIGEN_STRONG_INLINE Scalar operator() (const Scalar& a) const { return a * m_other; }
ykuroda 0:13a5d365ba16 510 EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const
ykuroda 0:13a5d365ba16 511 { return internal::pmul(a, pset1<Packet>(m_other)); }
ykuroda 0:13a5d365ba16 512 typename add_const_on_value_type<typename NumTraits<Scalar>::Nested>::type m_other;
ykuroda 0:13a5d365ba16 513 };
ykuroda 0:13a5d365ba16 514 template<typename Scalar>
ykuroda 0:13a5d365ba16 515 struct functor_traits<scalar_multiple_op<Scalar> >
ykuroda 0:13a5d365ba16 516 { enum { Cost = NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasMul }; };
ykuroda 0:13a5d365ba16 517
ykuroda 0:13a5d365ba16 518 template<typename Scalar1, typename Scalar2>
ykuroda 0:13a5d365ba16 519 struct scalar_multiple2_op {
ykuroda 0:13a5d365ba16 520 typedef typename scalar_product_traits<Scalar1,Scalar2>::ReturnType result_type;
ykuroda 0:13a5d365ba16 521 EIGEN_STRONG_INLINE scalar_multiple2_op(const scalar_multiple2_op& other) : m_other(other.m_other) { }
ykuroda 0:13a5d365ba16 522 EIGEN_STRONG_INLINE scalar_multiple2_op(const Scalar2& other) : m_other(other) { }
ykuroda 0:13a5d365ba16 523 EIGEN_STRONG_INLINE result_type operator() (const Scalar1& a) const { return a * m_other; }
ykuroda 0:13a5d365ba16 524 typename add_const_on_value_type<typename NumTraits<Scalar2>::Nested>::type m_other;
ykuroda 0:13a5d365ba16 525 };
ykuroda 0:13a5d365ba16 526 template<typename Scalar1,typename Scalar2>
ykuroda 0:13a5d365ba16 527 struct functor_traits<scalar_multiple2_op<Scalar1,Scalar2> >
ykuroda 0:13a5d365ba16 528 { enum { Cost = NumTraits<Scalar1>::MulCost, PacketAccess = false }; };
ykuroda 0:13a5d365ba16 529
ykuroda 0:13a5d365ba16 530 /** \internal
ykuroda 0:13a5d365ba16 531 * \brief Template functor to divide a scalar by a fixed other one
ykuroda 0:13a5d365ba16 532 *
ykuroda 0:13a5d365ba16 533 * This functor is used to implement the quotient of a matrix by
ykuroda 0:13a5d365ba16 534 * a scalar where the scalar type is not necessarily a floating point type.
ykuroda 0:13a5d365ba16 535 *
ykuroda 0:13a5d365ba16 536 * \sa class CwiseUnaryOp, MatrixBase::operator/
ykuroda 0:13a5d365ba16 537 */
ykuroda 0:13a5d365ba16 538 template<typename Scalar>
ykuroda 0:13a5d365ba16 539 struct scalar_quotient1_op {
ykuroda 0:13a5d365ba16 540 typedef typename packet_traits<Scalar>::type Packet;
ykuroda 0:13a5d365ba16 541 // FIXME default copy constructors seems bugged with std::complex<>
ykuroda 0:13a5d365ba16 542 EIGEN_STRONG_INLINE scalar_quotient1_op(const scalar_quotient1_op& other) : m_other(other.m_other) { }
ykuroda 0:13a5d365ba16 543 EIGEN_STRONG_INLINE scalar_quotient1_op(const Scalar& other) : m_other(other) {}
ykuroda 0:13a5d365ba16 544 EIGEN_STRONG_INLINE Scalar operator() (const Scalar& a) const { return a / m_other; }
ykuroda 0:13a5d365ba16 545 EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const
ykuroda 0:13a5d365ba16 546 { return internal::pdiv(a, pset1<Packet>(m_other)); }
ykuroda 0:13a5d365ba16 547 typename add_const_on_value_type<typename NumTraits<Scalar>::Nested>::type m_other;
ykuroda 0:13a5d365ba16 548 };
ykuroda 0:13a5d365ba16 549 template<typename Scalar>
ykuroda 0:13a5d365ba16 550 struct functor_traits<scalar_quotient1_op<Scalar> >
ykuroda 0:13a5d365ba16 551 { enum { Cost = 2 * NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasDiv }; };
ykuroda 0:13a5d365ba16 552
ykuroda 0:13a5d365ba16 553 // nullary functors
ykuroda 0:13a5d365ba16 554
ykuroda 0:13a5d365ba16 555 template<typename Scalar>
ykuroda 0:13a5d365ba16 556 struct scalar_constant_op {
ykuroda 0:13a5d365ba16 557 typedef typename packet_traits<Scalar>::type Packet;
ykuroda 0:13a5d365ba16 558 EIGEN_STRONG_INLINE scalar_constant_op(const scalar_constant_op& other) : m_other(other.m_other) { }
ykuroda 0:13a5d365ba16 559 EIGEN_STRONG_INLINE scalar_constant_op(const Scalar& other) : m_other(other) { }
ykuroda 0:13a5d365ba16 560 template<typename Index>
ykuroda 0:13a5d365ba16 561 EIGEN_STRONG_INLINE const Scalar operator() (Index, Index = 0) const { return m_other; }
ykuroda 0:13a5d365ba16 562 template<typename Index>
ykuroda 0:13a5d365ba16 563 EIGEN_STRONG_INLINE const Packet packetOp(Index, Index = 0) const { return internal::pset1<Packet>(m_other); }
ykuroda 0:13a5d365ba16 564 const Scalar m_other;
ykuroda 0:13a5d365ba16 565 };
ykuroda 0:13a5d365ba16 566 template<typename Scalar>
ykuroda 0:13a5d365ba16 567 struct functor_traits<scalar_constant_op<Scalar> >
ykuroda 0:13a5d365ba16 568 // FIXME replace this packet test by a safe one
ykuroda 0:13a5d365ba16 569 { enum { Cost = 1, PacketAccess = packet_traits<Scalar>::Vectorizable, IsRepeatable = true }; };
ykuroda 0:13a5d365ba16 570
ykuroda 0:13a5d365ba16 571 template<typename Scalar> struct scalar_identity_op {
ykuroda 0:13a5d365ba16 572 EIGEN_EMPTY_STRUCT_CTOR(scalar_identity_op)
ykuroda 0:13a5d365ba16 573 template<typename Index>
ykuroda 0:13a5d365ba16 574 EIGEN_STRONG_INLINE const Scalar operator() (Index row, Index col) const { return row==col ? Scalar(1) : Scalar(0); }
ykuroda 0:13a5d365ba16 575 };
ykuroda 0:13a5d365ba16 576 template<typename Scalar>
ykuroda 0:13a5d365ba16 577 struct functor_traits<scalar_identity_op<Scalar> >
ykuroda 0:13a5d365ba16 578 { enum { Cost = NumTraits<Scalar>::AddCost, PacketAccess = false, IsRepeatable = true }; };
ykuroda 0:13a5d365ba16 579
ykuroda 0:13a5d365ba16 580 template <typename Scalar, bool RandomAccess> struct linspaced_op_impl;
ykuroda 0:13a5d365ba16 581
ykuroda 0:13a5d365ba16 582 // linear access for packet ops:
ykuroda 0:13a5d365ba16 583 // 1) initialization
ykuroda 0:13a5d365ba16 584 // base = [low, ..., low] + ([step, ..., step] * [-size, ..., 0])
ykuroda 0:13a5d365ba16 585 // 2) each step (where size is 1 for coeff access or PacketSize for packet access)
ykuroda 0:13a5d365ba16 586 // base += [size*step, ..., size*step]
ykuroda 0:13a5d365ba16 587 //
ykuroda 0:13a5d365ba16 588 // TODO: Perhaps it's better to initialize lazily (so not in the constructor but in packetOp)
ykuroda 0:13a5d365ba16 589 // in order to avoid the padd() in operator() ?
ykuroda 0:13a5d365ba16 590 template <typename Scalar>
ykuroda 0:13a5d365ba16 591 struct linspaced_op_impl<Scalar,false>
ykuroda 0:13a5d365ba16 592 {
ykuroda 0:13a5d365ba16 593 typedef typename packet_traits<Scalar>::type Packet;
ykuroda 0:13a5d365ba16 594
ykuroda 0:13a5d365ba16 595 linspaced_op_impl(const Scalar& low, const Scalar& step) :
ykuroda 0:13a5d365ba16 596 m_low(low), m_step(step),
ykuroda 0:13a5d365ba16 597 m_packetStep(pset1<Packet>(packet_traits<Scalar>::size*step)),
ykuroda 0:13a5d365ba16 598 m_base(padd(pset1<Packet>(low), pmul(pset1<Packet>(step),plset<Scalar>(-packet_traits<Scalar>::size)))) {}
ykuroda 0:13a5d365ba16 599
ykuroda 0:13a5d365ba16 600 template<typename Index>
ykuroda 0:13a5d365ba16 601 EIGEN_STRONG_INLINE const Scalar operator() (Index i) const
ykuroda 0:13a5d365ba16 602 {
ykuroda 0:13a5d365ba16 603 m_base = padd(m_base, pset1<Packet>(m_step));
ykuroda 0:13a5d365ba16 604 return m_low+Scalar(i)*m_step;
ykuroda 0:13a5d365ba16 605 }
ykuroda 0:13a5d365ba16 606
ykuroda 0:13a5d365ba16 607 template<typename Index>
ykuroda 0:13a5d365ba16 608 EIGEN_STRONG_INLINE const Packet packetOp(Index) const { return m_base = padd(m_base,m_packetStep); }
ykuroda 0:13a5d365ba16 609
ykuroda 0:13a5d365ba16 610 const Scalar m_low;
ykuroda 0:13a5d365ba16 611 const Scalar m_step;
ykuroda 0:13a5d365ba16 612 const Packet m_packetStep;
ykuroda 0:13a5d365ba16 613 mutable Packet m_base;
ykuroda 0:13a5d365ba16 614 };
ykuroda 0:13a5d365ba16 615
ykuroda 0:13a5d365ba16 616 // random access for packet ops:
ykuroda 0:13a5d365ba16 617 // 1) each step
ykuroda 0:13a5d365ba16 618 // [low, ..., low] + ( [step, ..., step] * ( [i, ..., i] + [0, ..., size] ) )
ykuroda 0:13a5d365ba16 619 template <typename Scalar>
ykuroda 0:13a5d365ba16 620 struct linspaced_op_impl<Scalar,true>
ykuroda 0:13a5d365ba16 621 {
ykuroda 0:13a5d365ba16 622 typedef typename packet_traits<Scalar>::type Packet;
ykuroda 0:13a5d365ba16 623
ykuroda 0:13a5d365ba16 624 linspaced_op_impl(const Scalar& low, const Scalar& step) :
ykuroda 0:13a5d365ba16 625 m_low(low), m_step(step),
ykuroda 0:13a5d365ba16 626 m_lowPacket(pset1<Packet>(m_low)), m_stepPacket(pset1<Packet>(m_step)), m_interPacket(plset<Scalar>(0)) {}
ykuroda 0:13a5d365ba16 627
ykuroda 0:13a5d365ba16 628 template<typename Index>
ykuroda 0:13a5d365ba16 629 EIGEN_STRONG_INLINE const Scalar operator() (Index i) const { return m_low+i*m_step; }
ykuroda 0:13a5d365ba16 630
ykuroda 0:13a5d365ba16 631 template<typename Index>
ykuroda 0:13a5d365ba16 632 EIGEN_STRONG_INLINE const Packet packetOp(Index i) const
ykuroda 0:13a5d365ba16 633 { return internal::padd(m_lowPacket, pmul(m_stepPacket, padd(pset1<Packet>(Scalar(i)),m_interPacket))); }
ykuroda 0:13a5d365ba16 634
ykuroda 0:13a5d365ba16 635 const Scalar m_low;
ykuroda 0:13a5d365ba16 636 const Scalar m_step;
ykuroda 0:13a5d365ba16 637 const Packet m_lowPacket;
ykuroda 0:13a5d365ba16 638 const Packet m_stepPacket;
ykuroda 0:13a5d365ba16 639 const Packet m_interPacket;
ykuroda 0:13a5d365ba16 640 };
ykuroda 0:13a5d365ba16 641
ykuroda 0:13a5d365ba16 642 // ----- Linspace functor ----------------------------------------------------------------
ykuroda 0:13a5d365ba16 643
ykuroda 0:13a5d365ba16 644 // Forward declaration (we default to random access which does not really give
ykuroda 0:13a5d365ba16 645 // us a speed gain when using packet access but it allows to use the functor in
ykuroda 0:13a5d365ba16 646 // nested expressions).
ykuroda 0:13a5d365ba16 647 template <typename Scalar, bool RandomAccess = true> struct linspaced_op;
ykuroda 0:13a5d365ba16 648 template <typename Scalar, bool RandomAccess> struct functor_traits< linspaced_op<Scalar,RandomAccess> >
ykuroda 0:13a5d365ba16 649 { enum { Cost = 1, PacketAccess = packet_traits<Scalar>::HasSetLinear, IsRepeatable = true }; };
ykuroda 0:13a5d365ba16 650 template <typename Scalar, bool RandomAccess> struct linspaced_op
ykuroda 0:13a5d365ba16 651 {
ykuroda 0:13a5d365ba16 652 typedef typename packet_traits<Scalar>::type Packet;
ykuroda 0:13a5d365ba16 653 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))) {}
ykuroda 0:13a5d365ba16 654
ykuroda 0:13a5d365ba16 655 template<typename Index>
ykuroda 0:13a5d365ba16 656 EIGEN_STRONG_INLINE const Scalar operator() (Index i) const { return impl(i); }
ykuroda 0:13a5d365ba16 657
ykuroda 0:13a5d365ba16 658 // We need this function when assigning e.g. a RowVectorXd to a MatrixXd since
ykuroda 0:13a5d365ba16 659 // there row==0 and col is used for the actual iteration.
ykuroda 0:13a5d365ba16 660 template<typename Index>
ykuroda 0:13a5d365ba16 661 EIGEN_STRONG_INLINE const Scalar operator() (Index row, Index col) const
ykuroda 0:13a5d365ba16 662 {
ykuroda 0:13a5d365ba16 663 eigen_assert(col==0 || row==0);
ykuroda 0:13a5d365ba16 664 return impl(col + row);
ykuroda 0:13a5d365ba16 665 }
ykuroda 0:13a5d365ba16 666
ykuroda 0:13a5d365ba16 667 template<typename Index>
ykuroda 0:13a5d365ba16 668 EIGEN_STRONG_INLINE const Packet packetOp(Index i) const { return impl.packetOp(i); }
ykuroda 0:13a5d365ba16 669
ykuroda 0:13a5d365ba16 670 // We need this function when assigning e.g. a RowVectorXd to a MatrixXd since
ykuroda 0:13a5d365ba16 671 // there row==0 and col is used for the actual iteration.
ykuroda 0:13a5d365ba16 672 template<typename Index>
ykuroda 0:13a5d365ba16 673 EIGEN_STRONG_INLINE const Packet packetOp(Index row, Index col) const
ykuroda 0:13a5d365ba16 674 {
ykuroda 0:13a5d365ba16 675 eigen_assert(col==0 || row==0);
ykuroda 0:13a5d365ba16 676 return impl.packetOp(col + row);
ykuroda 0:13a5d365ba16 677 }
ykuroda 0:13a5d365ba16 678
ykuroda 0:13a5d365ba16 679 // This proxy object handles the actual required temporaries, the different
ykuroda 0:13a5d365ba16 680 // implementations (random vs. sequential access) as well as the
ykuroda 0:13a5d365ba16 681 // correct piping to size 2/4 packet operations.
ykuroda 0:13a5d365ba16 682 const linspaced_op_impl<Scalar,RandomAccess> impl;
ykuroda 0:13a5d365ba16 683 };
ykuroda 0:13a5d365ba16 684
ykuroda 0:13a5d365ba16 685 // all functors allow linear access, except scalar_identity_op. So we fix here a quick meta
ykuroda 0:13a5d365ba16 686 // to indicate whether a functor allows linear access, just always answering 'yes' except for
ykuroda 0:13a5d365ba16 687 // scalar_identity_op.
ykuroda 0:13a5d365ba16 688 // FIXME move this to functor_traits adding a functor_default
ykuroda 0:13a5d365ba16 689 template<typename Functor> struct functor_has_linear_access { enum { ret = 1 }; };
ykuroda 0:13a5d365ba16 690 template<typename Scalar> struct functor_has_linear_access<scalar_identity_op<Scalar> > { enum { ret = 0 }; };
ykuroda 0:13a5d365ba16 691
ykuroda 0:13a5d365ba16 692 // In Eigen, any binary op (Product, CwiseBinaryOp) require the Lhs and Rhs to have the same scalar type, except for multiplication
ykuroda 0:13a5d365ba16 693 // where the mixing of different types is handled by scalar_product_traits
ykuroda 0:13a5d365ba16 694 // In particular, real * complex<real> is allowed.
ykuroda 0:13a5d365ba16 695 // FIXME move this to functor_traits adding a functor_default
ykuroda 0:13a5d365ba16 696 template<typename Functor> struct functor_is_product_like { enum { ret = 0 }; };
ykuroda 0:13a5d365ba16 697 template<typename LhsScalar,typename RhsScalar> struct functor_is_product_like<scalar_product_op<LhsScalar,RhsScalar> > { enum { ret = 1 }; };
ykuroda 0:13a5d365ba16 698 template<typename LhsScalar,typename RhsScalar> struct functor_is_product_like<scalar_conj_product_op<LhsScalar,RhsScalar> > { enum { ret = 1 }; };
ykuroda 0:13a5d365ba16 699 template<typename LhsScalar,typename RhsScalar> struct functor_is_product_like<scalar_quotient_op<LhsScalar,RhsScalar> > { enum { ret = 1 }; };
ykuroda 0:13a5d365ba16 700
ykuroda 0:13a5d365ba16 701
ykuroda 0:13a5d365ba16 702 /** \internal
ykuroda 0:13a5d365ba16 703 * \brief Template functor to add a scalar to a fixed other one
ykuroda 0:13a5d365ba16 704 * \sa class CwiseUnaryOp, Array::operator+
ykuroda 0:13a5d365ba16 705 */
ykuroda 0:13a5d365ba16 706 /* If you wonder why doing the pset1() in packetOp() is an optimization check scalar_multiple_op */
ykuroda 0:13a5d365ba16 707 template<typename Scalar>
ykuroda 0:13a5d365ba16 708 struct scalar_add_op {
ykuroda 0:13a5d365ba16 709 typedef typename packet_traits<Scalar>::type Packet;
ykuroda 0:13a5d365ba16 710 // FIXME default copy constructors seems bugged with std::complex<>
ykuroda 0:13a5d365ba16 711 inline scalar_add_op(const scalar_add_op& other) : m_other(other.m_other) { }
ykuroda 0:13a5d365ba16 712 inline scalar_add_op(const Scalar& other) : m_other(other) { }
ykuroda 0:13a5d365ba16 713 inline Scalar operator() (const Scalar& a) const { return a + m_other; }
ykuroda 0:13a5d365ba16 714 inline const Packet packetOp(const Packet& a) const
ykuroda 0:13a5d365ba16 715 { return internal::padd(a, pset1<Packet>(m_other)); }
ykuroda 0:13a5d365ba16 716 const Scalar m_other;
ykuroda 0:13a5d365ba16 717 };
ykuroda 0:13a5d365ba16 718 template<typename Scalar>
ykuroda 0:13a5d365ba16 719 struct functor_traits<scalar_add_op<Scalar> >
ykuroda 0:13a5d365ba16 720 { enum { Cost = NumTraits<Scalar>::AddCost, PacketAccess = packet_traits<Scalar>::HasAdd }; };
ykuroda 0:13a5d365ba16 721
ykuroda 0:13a5d365ba16 722 /** \internal
ykuroda 0:13a5d365ba16 723 * \brief Template functor to compute the square root of a scalar
ykuroda 0:13a5d365ba16 724 * \sa class CwiseUnaryOp, Cwise::sqrt()
ykuroda 0:13a5d365ba16 725 */
ykuroda 0:13a5d365ba16 726 template<typename Scalar> struct scalar_sqrt_op {
ykuroda 0:13a5d365ba16 727 EIGEN_EMPTY_STRUCT_CTOR(scalar_sqrt_op)
ykuroda 0:13a5d365ba16 728 inline const Scalar operator() (const Scalar& a) const { using std::sqrt; return sqrt(a); }
ykuroda 0:13a5d365ba16 729 typedef typename packet_traits<Scalar>::type Packet;
ykuroda 0:13a5d365ba16 730 inline Packet packetOp(const Packet& a) const { return internal::psqrt(a); }
ykuroda 0:13a5d365ba16 731 };
ykuroda 0:13a5d365ba16 732 template<typename Scalar>
ykuroda 0:13a5d365ba16 733 struct functor_traits<scalar_sqrt_op<Scalar> >
ykuroda 0:13a5d365ba16 734 { enum {
ykuroda 0:13a5d365ba16 735 Cost = 5 * NumTraits<Scalar>::MulCost,
ykuroda 0:13a5d365ba16 736 PacketAccess = packet_traits<Scalar>::HasSqrt
ykuroda 0:13a5d365ba16 737 };
ykuroda 0:13a5d365ba16 738 };
ykuroda 0:13a5d365ba16 739
ykuroda 0:13a5d365ba16 740 /** \internal
ykuroda 0:13a5d365ba16 741 * \brief Template functor to compute the cosine of a scalar
ykuroda 0:13a5d365ba16 742 * \sa class CwiseUnaryOp, ArrayBase::cos()
ykuroda 0:13a5d365ba16 743 */
ykuroda 0:13a5d365ba16 744 template<typename Scalar> struct scalar_cos_op {
ykuroda 0:13a5d365ba16 745 EIGEN_EMPTY_STRUCT_CTOR(scalar_cos_op)
ykuroda 0:13a5d365ba16 746 inline Scalar operator() (const Scalar& a) const { using std::cos; return cos(a); }
ykuroda 0:13a5d365ba16 747 typedef typename packet_traits<Scalar>::type Packet;
ykuroda 0:13a5d365ba16 748 inline Packet packetOp(const Packet& a) const { return internal::pcos(a); }
ykuroda 0:13a5d365ba16 749 };
ykuroda 0:13a5d365ba16 750 template<typename Scalar>
ykuroda 0:13a5d365ba16 751 struct functor_traits<scalar_cos_op<Scalar> >
ykuroda 0:13a5d365ba16 752 {
ykuroda 0:13a5d365ba16 753 enum {
ykuroda 0:13a5d365ba16 754 Cost = 5 * NumTraits<Scalar>::MulCost,
ykuroda 0:13a5d365ba16 755 PacketAccess = packet_traits<Scalar>::HasCos
ykuroda 0:13a5d365ba16 756 };
ykuroda 0:13a5d365ba16 757 };
ykuroda 0:13a5d365ba16 758
ykuroda 0:13a5d365ba16 759 /** \internal
ykuroda 0:13a5d365ba16 760 * \brief Template functor to compute the sine of a scalar
ykuroda 0:13a5d365ba16 761 * \sa class CwiseUnaryOp, ArrayBase::sin()
ykuroda 0:13a5d365ba16 762 */
ykuroda 0:13a5d365ba16 763 template<typename Scalar> struct scalar_sin_op {
ykuroda 0:13a5d365ba16 764 EIGEN_EMPTY_STRUCT_CTOR(scalar_sin_op)
ykuroda 0:13a5d365ba16 765 inline const Scalar operator() (const Scalar& a) const { using std::sin; return sin(a); }
ykuroda 0:13a5d365ba16 766 typedef typename packet_traits<Scalar>::type Packet;
ykuroda 0:13a5d365ba16 767 inline Packet packetOp(const Packet& a) const { return internal::psin(a); }
ykuroda 0:13a5d365ba16 768 };
ykuroda 0:13a5d365ba16 769 template<typename Scalar>
ykuroda 0:13a5d365ba16 770 struct functor_traits<scalar_sin_op<Scalar> >
ykuroda 0:13a5d365ba16 771 {
ykuroda 0:13a5d365ba16 772 enum {
ykuroda 0:13a5d365ba16 773 Cost = 5 * NumTraits<Scalar>::MulCost,
ykuroda 0:13a5d365ba16 774 PacketAccess = packet_traits<Scalar>::HasSin
ykuroda 0:13a5d365ba16 775 };
ykuroda 0:13a5d365ba16 776 };
ykuroda 0:13a5d365ba16 777
ykuroda 0:13a5d365ba16 778
ykuroda 0:13a5d365ba16 779 /** \internal
ykuroda 0:13a5d365ba16 780 * \brief Template functor to compute the tan of a scalar
ykuroda 0:13a5d365ba16 781 * \sa class CwiseUnaryOp, ArrayBase::tan()
ykuroda 0:13a5d365ba16 782 */
ykuroda 0:13a5d365ba16 783 template<typename Scalar> struct scalar_tan_op {
ykuroda 0:13a5d365ba16 784 EIGEN_EMPTY_STRUCT_CTOR(scalar_tan_op)
ykuroda 0:13a5d365ba16 785 inline const Scalar operator() (const Scalar& a) const { using std::tan; return tan(a); }
ykuroda 0:13a5d365ba16 786 typedef typename packet_traits<Scalar>::type Packet;
ykuroda 0:13a5d365ba16 787 inline Packet packetOp(const Packet& a) const { return internal::ptan(a); }
ykuroda 0:13a5d365ba16 788 };
ykuroda 0:13a5d365ba16 789 template<typename Scalar>
ykuroda 0:13a5d365ba16 790 struct functor_traits<scalar_tan_op<Scalar> >
ykuroda 0:13a5d365ba16 791 {
ykuroda 0:13a5d365ba16 792 enum {
ykuroda 0:13a5d365ba16 793 Cost = 5 * NumTraits<Scalar>::MulCost,
ykuroda 0:13a5d365ba16 794 PacketAccess = packet_traits<Scalar>::HasTan
ykuroda 0:13a5d365ba16 795 };
ykuroda 0:13a5d365ba16 796 };
ykuroda 0:13a5d365ba16 797
ykuroda 0:13a5d365ba16 798 /** \internal
ykuroda 0:13a5d365ba16 799 * \brief Template functor to compute the arc cosine of a scalar
ykuroda 0:13a5d365ba16 800 * \sa class CwiseUnaryOp, ArrayBase::acos()
ykuroda 0:13a5d365ba16 801 */
ykuroda 0:13a5d365ba16 802 template<typename Scalar> struct scalar_acos_op {
ykuroda 0:13a5d365ba16 803 EIGEN_EMPTY_STRUCT_CTOR(scalar_acos_op)
ykuroda 0:13a5d365ba16 804 inline const Scalar operator() (const Scalar& a) const { using std::acos; return acos(a); }
ykuroda 0:13a5d365ba16 805 typedef typename packet_traits<Scalar>::type Packet;
ykuroda 0:13a5d365ba16 806 inline Packet packetOp(const Packet& a) const { return internal::pacos(a); }
ykuroda 0:13a5d365ba16 807 };
ykuroda 0:13a5d365ba16 808 template<typename Scalar>
ykuroda 0:13a5d365ba16 809 struct functor_traits<scalar_acos_op<Scalar> >
ykuroda 0:13a5d365ba16 810 {
ykuroda 0:13a5d365ba16 811 enum {
ykuroda 0:13a5d365ba16 812 Cost = 5 * NumTraits<Scalar>::MulCost,
ykuroda 0:13a5d365ba16 813 PacketAccess = packet_traits<Scalar>::HasACos
ykuroda 0:13a5d365ba16 814 };
ykuroda 0:13a5d365ba16 815 };
ykuroda 0:13a5d365ba16 816
ykuroda 0:13a5d365ba16 817 /** \internal
ykuroda 0:13a5d365ba16 818 * \brief Template functor to compute the arc sine of a scalar
ykuroda 0:13a5d365ba16 819 * \sa class CwiseUnaryOp, ArrayBase::asin()
ykuroda 0:13a5d365ba16 820 */
ykuroda 0:13a5d365ba16 821 template<typename Scalar> struct scalar_asin_op {
ykuroda 0:13a5d365ba16 822 EIGEN_EMPTY_STRUCT_CTOR(scalar_asin_op)
ykuroda 0:13a5d365ba16 823 inline const Scalar operator() (const Scalar& a) const { using std::asin; return asin(a); }
ykuroda 0:13a5d365ba16 824 typedef typename packet_traits<Scalar>::type Packet;
ykuroda 0:13a5d365ba16 825 inline Packet packetOp(const Packet& a) const { return internal::pasin(a); }
ykuroda 0:13a5d365ba16 826 };
ykuroda 0:13a5d365ba16 827 template<typename Scalar>
ykuroda 0:13a5d365ba16 828 struct functor_traits<scalar_asin_op<Scalar> >
ykuroda 0:13a5d365ba16 829 {
ykuroda 0:13a5d365ba16 830 enum {
ykuroda 0:13a5d365ba16 831 Cost = 5 * NumTraits<Scalar>::MulCost,
ykuroda 0:13a5d365ba16 832 PacketAccess = packet_traits<Scalar>::HasASin
ykuroda 0:13a5d365ba16 833 };
ykuroda 0:13a5d365ba16 834 };
ykuroda 0:13a5d365ba16 835
ykuroda 0:13a5d365ba16 836 /** \internal
ykuroda 0:13a5d365ba16 837 * \brief Template functor to raise a scalar to a power
ykuroda 0:13a5d365ba16 838 * \sa class CwiseUnaryOp, Cwise::pow
ykuroda 0:13a5d365ba16 839 */
ykuroda 0:13a5d365ba16 840 template<typename Scalar>
ykuroda 0:13a5d365ba16 841 struct scalar_pow_op {
ykuroda 0:13a5d365ba16 842 // FIXME default copy constructors seems bugged with std::complex<>
ykuroda 0:13a5d365ba16 843 inline scalar_pow_op(const scalar_pow_op& other) : m_exponent(other.m_exponent) { }
ykuroda 0:13a5d365ba16 844 inline scalar_pow_op(const Scalar& exponent) : m_exponent(exponent) {}
ykuroda 0:13a5d365ba16 845 inline Scalar operator() (const Scalar& a) const { return numext::pow(a, m_exponent); }
ykuroda 0:13a5d365ba16 846 const Scalar m_exponent;
ykuroda 0:13a5d365ba16 847 };
ykuroda 0:13a5d365ba16 848 template<typename Scalar>
ykuroda 0:13a5d365ba16 849 struct functor_traits<scalar_pow_op<Scalar> >
ykuroda 0:13a5d365ba16 850 { enum { Cost = 5 * NumTraits<Scalar>::MulCost, PacketAccess = false }; };
ykuroda 0:13a5d365ba16 851
ykuroda 0:13a5d365ba16 852 /** \internal
ykuroda 0:13a5d365ba16 853 * \brief Template functor to compute the quotient between a scalar and array entries.
ykuroda 0:13a5d365ba16 854 * \sa class CwiseUnaryOp, Cwise::inverse()
ykuroda 0:13a5d365ba16 855 */
ykuroda 0:13a5d365ba16 856 template<typename Scalar>
ykuroda 0:13a5d365ba16 857 struct scalar_inverse_mult_op {
ykuroda 0:13a5d365ba16 858 scalar_inverse_mult_op(const Scalar& other) : m_other(other) {}
ykuroda 0:13a5d365ba16 859 inline Scalar operator() (const Scalar& a) const { return m_other / a; }
ykuroda 0:13a5d365ba16 860 template<typename Packet>
ykuroda 0:13a5d365ba16 861 inline const Packet packetOp(const Packet& a) const
ykuroda 0:13a5d365ba16 862 { return internal::pdiv(pset1<Packet>(m_other),a); }
ykuroda 0:13a5d365ba16 863 Scalar m_other;
ykuroda 0:13a5d365ba16 864 };
ykuroda 0:13a5d365ba16 865
ykuroda 0:13a5d365ba16 866 /** \internal
ykuroda 0:13a5d365ba16 867 * \brief Template functor to compute the inverse of a scalar
ykuroda 0:13a5d365ba16 868 * \sa class CwiseUnaryOp, Cwise::inverse()
ykuroda 0:13a5d365ba16 869 */
ykuroda 0:13a5d365ba16 870 template<typename Scalar>
ykuroda 0:13a5d365ba16 871 struct scalar_inverse_op {
ykuroda 0:13a5d365ba16 872 EIGEN_EMPTY_STRUCT_CTOR(scalar_inverse_op)
ykuroda 0:13a5d365ba16 873 inline Scalar operator() (const Scalar& a) const { return Scalar(1)/a; }
ykuroda 0:13a5d365ba16 874 template<typename Packet>
ykuroda 0:13a5d365ba16 875 inline const Packet packetOp(const Packet& a) const
ykuroda 0:13a5d365ba16 876 { return internal::pdiv(pset1<Packet>(Scalar(1)),a); }
ykuroda 0:13a5d365ba16 877 };
ykuroda 0:13a5d365ba16 878 template<typename Scalar>
ykuroda 0:13a5d365ba16 879 struct functor_traits<scalar_inverse_op<Scalar> >
ykuroda 0:13a5d365ba16 880 { enum { Cost = NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasDiv }; };
ykuroda 0:13a5d365ba16 881
ykuroda 0:13a5d365ba16 882 /** \internal
ykuroda 0:13a5d365ba16 883 * \brief Template functor to compute the square of a scalar
ykuroda 0:13a5d365ba16 884 * \sa class CwiseUnaryOp, Cwise::square()
ykuroda 0:13a5d365ba16 885 */
ykuroda 0:13a5d365ba16 886 template<typename Scalar>
ykuroda 0:13a5d365ba16 887 struct scalar_square_op {
ykuroda 0:13a5d365ba16 888 EIGEN_EMPTY_STRUCT_CTOR(scalar_square_op)
ykuroda 0:13a5d365ba16 889 inline Scalar operator() (const Scalar& a) const { return a*a; }
ykuroda 0:13a5d365ba16 890 template<typename Packet>
ykuroda 0:13a5d365ba16 891 inline const Packet packetOp(const Packet& a) const
ykuroda 0:13a5d365ba16 892 { return internal::pmul(a,a); }
ykuroda 0:13a5d365ba16 893 };
ykuroda 0:13a5d365ba16 894 template<typename Scalar>
ykuroda 0:13a5d365ba16 895 struct functor_traits<scalar_square_op<Scalar> >
ykuroda 0:13a5d365ba16 896 { enum { Cost = NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasMul }; };
ykuroda 0:13a5d365ba16 897
ykuroda 0:13a5d365ba16 898 /** \internal
ykuroda 0:13a5d365ba16 899 * \brief Template functor to compute the cube of a scalar
ykuroda 0:13a5d365ba16 900 * \sa class CwiseUnaryOp, Cwise::cube()
ykuroda 0:13a5d365ba16 901 */
ykuroda 0:13a5d365ba16 902 template<typename Scalar>
ykuroda 0:13a5d365ba16 903 struct scalar_cube_op {
ykuroda 0:13a5d365ba16 904 EIGEN_EMPTY_STRUCT_CTOR(scalar_cube_op)
ykuroda 0:13a5d365ba16 905 inline Scalar operator() (const Scalar& a) const { return a*a*a; }
ykuroda 0:13a5d365ba16 906 template<typename Packet>
ykuroda 0:13a5d365ba16 907 inline const Packet packetOp(const Packet& a) const
ykuroda 0:13a5d365ba16 908 { return internal::pmul(a,pmul(a,a)); }
ykuroda 0:13a5d365ba16 909 };
ykuroda 0:13a5d365ba16 910 template<typename Scalar>
ykuroda 0:13a5d365ba16 911 struct functor_traits<scalar_cube_op<Scalar> >
ykuroda 0:13a5d365ba16 912 { enum { Cost = 2*NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasMul }; };
ykuroda 0:13a5d365ba16 913
ykuroda 0:13a5d365ba16 914 // default functor traits for STL functors:
ykuroda 0:13a5d365ba16 915
ykuroda 0:13a5d365ba16 916 template<typename T>
ykuroda 0:13a5d365ba16 917 struct functor_traits<std::multiplies<T> >
ykuroda 0:13a5d365ba16 918 { enum { Cost = NumTraits<T>::MulCost, PacketAccess = false }; };
ykuroda 0:13a5d365ba16 919
ykuroda 0:13a5d365ba16 920 template<typename T>
ykuroda 0:13a5d365ba16 921 struct functor_traits<std::divides<T> >
ykuroda 0:13a5d365ba16 922 { enum { Cost = NumTraits<T>::MulCost, PacketAccess = false }; };
ykuroda 0:13a5d365ba16 923
ykuroda 0:13a5d365ba16 924 template<typename T>
ykuroda 0:13a5d365ba16 925 struct functor_traits<std::plus<T> >
ykuroda 0:13a5d365ba16 926 { enum { Cost = NumTraits<T>::AddCost, PacketAccess = false }; };
ykuroda 0:13a5d365ba16 927
ykuroda 0:13a5d365ba16 928 template<typename T>
ykuroda 0:13a5d365ba16 929 struct functor_traits<std::minus<T> >
ykuroda 0:13a5d365ba16 930 { enum { Cost = NumTraits<T>::AddCost, PacketAccess = false }; };
ykuroda 0:13a5d365ba16 931
ykuroda 0:13a5d365ba16 932 template<typename T>
ykuroda 0:13a5d365ba16 933 struct functor_traits<std::negate<T> >
ykuroda 0:13a5d365ba16 934 { enum { Cost = NumTraits<T>::AddCost, PacketAccess = false }; };
ykuroda 0:13a5d365ba16 935
ykuroda 0:13a5d365ba16 936 template<typename T>
ykuroda 0:13a5d365ba16 937 struct functor_traits<std::logical_or<T> >
ykuroda 0:13a5d365ba16 938 { enum { Cost = 1, PacketAccess = false }; };
ykuroda 0:13a5d365ba16 939
ykuroda 0:13a5d365ba16 940 template<typename T>
ykuroda 0:13a5d365ba16 941 struct functor_traits<std::logical_and<T> >
ykuroda 0:13a5d365ba16 942 { enum { Cost = 1, PacketAccess = false }; };
ykuroda 0:13a5d365ba16 943
ykuroda 0:13a5d365ba16 944 template<typename T>
ykuroda 0:13a5d365ba16 945 struct functor_traits<std::logical_not<T> >
ykuroda 0:13a5d365ba16 946 { enum { Cost = 1, PacketAccess = false }; };
ykuroda 0:13a5d365ba16 947
ykuroda 0:13a5d365ba16 948 template<typename T>
ykuroda 0:13a5d365ba16 949 struct functor_traits<std::greater<T> >
ykuroda 0:13a5d365ba16 950 { enum { Cost = 1, PacketAccess = false }; };
ykuroda 0:13a5d365ba16 951
ykuroda 0:13a5d365ba16 952 template<typename T>
ykuroda 0:13a5d365ba16 953 struct functor_traits<std::less<T> >
ykuroda 0:13a5d365ba16 954 { enum { Cost = 1, PacketAccess = false }; };
ykuroda 0:13a5d365ba16 955
ykuroda 0:13a5d365ba16 956 template<typename T>
ykuroda 0:13a5d365ba16 957 struct functor_traits<std::greater_equal<T> >
ykuroda 0:13a5d365ba16 958 { enum { Cost = 1, PacketAccess = false }; };
ykuroda 0:13a5d365ba16 959
ykuroda 0:13a5d365ba16 960 template<typename T>
ykuroda 0:13a5d365ba16 961 struct functor_traits<std::less_equal<T> >
ykuroda 0:13a5d365ba16 962 { enum { Cost = 1, PacketAccess = false }; };
ykuroda 0:13a5d365ba16 963
ykuroda 0:13a5d365ba16 964 template<typename T>
ykuroda 0:13a5d365ba16 965 struct functor_traits<std::equal_to<T> >
ykuroda 0:13a5d365ba16 966 { enum { Cost = 1, PacketAccess = false }; };
ykuroda 0:13a5d365ba16 967
ykuroda 0:13a5d365ba16 968 template<typename T>
ykuroda 0:13a5d365ba16 969 struct functor_traits<std::not_equal_to<T> >
ykuroda 0:13a5d365ba16 970 { enum { Cost = 1, PacketAccess = false }; };
ykuroda 0:13a5d365ba16 971
ykuroda 0:13a5d365ba16 972 template<typename T>
ykuroda 0:13a5d365ba16 973 struct functor_traits<std::binder2nd<T> >
ykuroda 0:13a5d365ba16 974 { enum { Cost = functor_traits<T>::Cost, PacketAccess = false }; };
ykuroda 0:13a5d365ba16 975
ykuroda 0:13a5d365ba16 976 template<typename T>
ykuroda 0:13a5d365ba16 977 struct functor_traits<std::binder1st<T> >
ykuroda 0:13a5d365ba16 978 { enum { Cost = functor_traits<T>::Cost, PacketAccess = false }; };
ykuroda 0:13a5d365ba16 979
ykuroda 0:13a5d365ba16 980 template<typename T>
ykuroda 0:13a5d365ba16 981 struct functor_traits<std::unary_negate<T> >
ykuroda 0:13a5d365ba16 982 { enum { Cost = 1 + functor_traits<T>::Cost, PacketAccess = false }; };
ykuroda 0:13a5d365ba16 983
ykuroda 0:13a5d365ba16 984 template<typename T>
ykuroda 0:13a5d365ba16 985 struct functor_traits<std::binary_negate<T> >
ykuroda 0:13a5d365ba16 986 { enum { Cost = 1 + functor_traits<T>::Cost, PacketAccess = false }; };
ykuroda 0:13a5d365ba16 987
ykuroda 0:13a5d365ba16 988 #ifdef EIGEN_STDEXT_SUPPORT
ykuroda 0:13a5d365ba16 989
ykuroda 0:13a5d365ba16 990 template<typename T0,typename T1>
ykuroda 0:13a5d365ba16 991 struct functor_traits<std::project1st<T0,T1> >
ykuroda 0:13a5d365ba16 992 { enum { Cost = 0, PacketAccess = false }; };
ykuroda 0:13a5d365ba16 993
ykuroda 0:13a5d365ba16 994 template<typename T0,typename T1>
ykuroda 0:13a5d365ba16 995 struct functor_traits<std::project2nd<T0,T1> >
ykuroda 0:13a5d365ba16 996 { enum { Cost = 0, PacketAccess = false }; };
ykuroda 0:13a5d365ba16 997
ykuroda 0:13a5d365ba16 998 template<typename T0,typename T1>
ykuroda 0:13a5d365ba16 999 struct functor_traits<std::select2nd<std::pair<T0,T1> > >
ykuroda 0:13a5d365ba16 1000 { enum { Cost = 0, PacketAccess = false }; };
ykuroda 0:13a5d365ba16 1001
ykuroda 0:13a5d365ba16 1002 template<typename T0,typename T1>
ykuroda 0:13a5d365ba16 1003 struct functor_traits<std::select1st<std::pair<T0,T1> > >
ykuroda 0:13a5d365ba16 1004 { enum { Cost = 0, PacketAccess = false }; };
ykuroda 0:13a5d365ba16 1005
ykuroda 0:13a5d365ba16 1006 template<typename T0,typename T1>
ykuroda 0:13a5d365ba16 1007 struct functor_traits<std::unary_compose<T0,T1> >
ykuroda 0:13a5d365ba16 1008 { enum { Cost = functor_traits<T0>::Cost + functor_traits<T1>::Cost, PacketAccess = false }; };
ykuroda 0:13a5d365ba16 1009
ykuroda 0:13a5d365ba16 1010 template<typename T0,typename T1,typename T2>
ykuroda 0:13a5d365ba16 1011 struct functor_traits<std::binary_compose<T0,T1,T2> >
ykuroda 0:13a5d365ba16 1012 { enum { Cost = functor_traits<T0>::Cost + functor_traits<T1>::Cost + functor_traits<T2>::Cost, PacketAccess = false }; };
ykuroda 0:13a5d365ba16 1013
ykuroda 0:13a5d365ba16 1014 #endif // EIGEN_STDEXT_SUPPORT
ykuroda 0:13a5d365ba16 1015
ykuroda 0:13a5d365ba16 1016 // allow to add new functors and specializations of functor_traits from outside Eigen.
ykuroda 0:13a5d365ba16 1017 // this macro is really needed because functor_traits must be specialized after it is declared but before it is used...
ykuroda 0:13a5d365ba16 1018 #ifdef EIGEN_FUNCTORS_PLUGIN
ykuroda 0:13a5d365ba16 1019 #include EIGEN_FUNCTORS_PLUGIN
ykuroda 0:13a5d365ba16 1020 #endif
ykuroda 0:13a5d365ba16 1021
ykuroda 0:13a5d365ba16 1022 } // end namespace internal
ykuroda 0:13a5d365ba16 1023
ykuroda 0:13a5d365ba16 1024 } // end namespace Eigen
ykuroda 0:13a5d365ba16 1025
ykuroda 0:13a5d365ba16 1026 #endif // EIGEN_FUNCTORS_H