LCOV - code coverage report
Current view: top level - Core/functors - UnaryFunctors.h (source / functions) Hit Total Coverage
Test: coverage.info.cleaned Lines: 8 8 100.0 %
Date: 1980-01-01 00:00:00 Functions: 8 8 100.0 %
Branches: 0 0 -

           Branch data     Line data    Source code
       1                 :            : // This file is part of Eigen, a lightweight C++ template library
       2                 :            : // for linear algebra.
       3                 :            : //
       4                 :            : // Copyright (C) 2008-2016 Gael Guennebaud <gael.guennebaud@inria.fr>
       5                 :            : //
       6                 :            : // This Source Code Form is subject to the terms of the Mozilla
       7                 :            : // Public License v. 2.0. If a copy of the MPL was not distributed
       8                 :            : // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
       9                 :            : 
      10                 :            : #ifndef EIGEN_UNARY_FUNCTORS_H
      11                 :            : #define EIGEN_UNARY_FUNCTORS_H
      12                 :            : 
      13                 :            : namespace Eigen {
      14                 :            : 
      15                 :            : namespace internal {
      16                 :            : 
      17                 :            : /** \internal
      18                 :            :   * \brief Template functor to compute the opposite of a scalar
      19                 :            :   *
      20                 :            :   * \sa class CwiseUnaryOp, MatrixBase::operator-
      21                 :            :   */
      22                 :            : template<typename Scalar> struct scalar_opposite_op {
      23                 :      12300 :   EIGEN_EMPTY_STRUCT_CTOR(scalar_opposite_op)
      24                 :       2050 :   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a) const { return -a; }
      25                 :            :   template<typename Packet>
      26                 :       4100 :   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const
      27                 :       4100 :   { return internal::pnegate(a); }
      28                 :            : };
      29                 :            : template<typename Scalar>
      30                 :            : struct functor_traits<scalar_opposite_op<Scalar> >
      31                 :            : { enum {
      32                 :            :     Cost = NumTraits<Scalar>::AddCost,
      33                 :            :     PacketAccess = packet_traits<Scalar>::HasNegate };
      34                 :            : };
      35                 :            : 
      36                 :            : /** \internal
      37                 :            :   * \brief Template functor to compute the absolute value of a scalar
      38                 :            :   *
      39                 :            :   * \sa class CwiseUnaryOp, Cwise::abs
      40                 :            :   */
      41                 :            : template<typename Scalar> struct scalar_abs_op {
      42                 :            :   EIGEN_EMPTY_STRUCT_CTOR(scalar_abs_op)
      43                 :            :   typedef typename NumTraits<Scalar>::Real result_type;
      44                 :            :   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const Scalar& a) const { return numext::abs(a); }
      45                 :            :   template<typename Packet>
      46                 :            :   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const
      47                 :            :   { return internal::pabs(a); }
      48                 :            : };
      49                 :            : template<typename Scalar>
      50                 :            : struct functor_traits<scalar_abs_op<Scalar> >
      51                 :            : {
      52                 :            :   enum {
      53                 :            :     Cost = NumTraits<Scalar>::AddCost,
      54                 :            :     PacketAccess = packet_traits<Scalar>::HasAbs
      55                 :            :   };
      56                 :            : };
      57                 :            : 
      58                 :            : /** \internal
      59                 :            :   * \brief Template functor to compute the score of a scalar, to chose a pivot
      60                 :            :   *
      61                 :            :   * \sa class CwiseUnaryOp
      62                 :            :   */
      63                 :            : template<typename Scalar> struct scalar_score_coeff_op : scalar_abs_op<Scalar>
      64                 :            : {
      65                 :            :   typedef void Score_is_abs;
      66                 :            : };
      67                 :            : template<typename Scalar>
      68                 :            : struct functor_traits<scalar_score_coeff_op<Scalar> > : functor_traits<scalar_abs_op<Scalar> > {};
      69                 :            : 
      70                 :            : /* Avoid recomputing abs when we know the score and they are the same. Not a true Eigen functor.  */
      71                 :            : template<typename Scalar, typename=void> struct abs_knowing_score
      72                 :            : {
      73                 :            :   EIGEN_EMPTY_STRUCT_CTOR(abs_knowing_score)
      74                 :            :   typedef typename NumTraits<Scalar>::Real result_type;
      75                 :            :   template<typename Score>
      76                 :            :   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const Scalar& a, const Score&) const { return numext::abs(a); }
      77                 :            : };
      78                 :            : template<typename Scalar> struct abs_knowing_score<Scalar, typename scalar_score_coeff_op<Scalar>::Score_is_abs>
      79                 :            : {
      80                 :            :   EIGEN_EMPTY_STRUCT_CTOR(abs_knowing_score)
      81                 :            :   typedef typename NumTraits<Scalar>::Real result_type;
      82                 :            :   template<typename Scal>
      83                 :            :   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const Scal&, const result_type& a) const { return a; }
      84                 :            : };
      85                 :            : 
      86                 :            : /** \internal
      87                 :            :   * \brief Template functor to compute the squared absolute value of a scalar
      88                 :            :   *
      89                 :            :   * \sa class CwiseUnaryOp, Cwise::abs2
      90                 :            :   */
      91                 :            : template<typename Scalar> struct scalar_abs2_op {
      92                 :      64008 :   EIGEN_EMPTY_STRUCT_CTOR(scalar_abs2_op)
      93                 :            :   typedef typename NumTraits<Scalar>::Real result_type;
      94                 :            :   EIGEN_DEVICE_FUNC
      95                 :       4526 :   EIGEN_STRONG_INLINE const result_type operator() (const Scalar& a) const { return numext::abs2(a); }
      96                 :            :   template<typename Packet>
      97                 :      31636 :   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const
      98                 :      31636 :   { return internal::pmul(a,a); }
      99                 :            : };
     100                 :            : template<typename Scalar>
     101                 :            : struct functor_traits<scalar_abs2_op<Scalar> >
     102                 :            : { enum { Cost = NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasAbs2 }; };
     103                 :            : 
     104                 :            : /** \internal
     105                 :            :   * \brief Template functor to compute the conjugate of a complex value
     106                 :            :   *
     107                 :            :   * \sa class CwiseUnaryOp, MatrixBase::conjugate()
     108                 :            :   */
     109                 :            : template<typename Scalar> struct scalar_conjugate_op {
     110                 :            :   EIGEN_EMPTY_STRUCT_CTOR(scalar_conjugate_op)
     111                 :            :   EIGEN_DEVICE_FUNC
     112                 :            :   EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a) const { return numext::conj(a); }
     113                 :            :   template<typename Packet>
     114                 :            :   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const { return internal::pconj(a); }
     115                 :            : };
     116                 :            : template<typename Scalar>
     117                 :            : struct functor_traits<scalar_conjugate_op<Scalar> >
     118                 :            : {
     119                 :            :   enum {
     120                 :            :     Cost = 0,
     121                 :            :     // Yes the cost is zero even for complexes because in most cases for which
     122                 :            :     // the cost is used, conjugation turns to be a no-op. Some examples:
     123                 :            :     //   cost(a*conj(b)) == cost(a*b)
     124                 :            :     //   cost(a+conj(b)) == cost(a+b)
     125                 :            :     //   <etc.
     126                 :            :     // If we don't set it to zero, then:
     127                 :            :     //   A.conjugate().lazyProduct(B.conjugate())
     128                 :            :     // will bake its operands. We definitely don't want that!
     129                 :            :     PacketAccess = packet_traits<Scalar>::HasConj
     130                 :            :   };
     131                 :            : };
     132                 :            : 
     133                 :            : /** \internal
     134                 :            :   * \brief Template functor to compute the phase angle of a complex
     135                 :            :   *
     136                 :            :   * \sa class CwiseUnaryOp, Cwise::arg
     137                 :            :   */
     138                 :            : template<typename Scalar> struct scalar_arg_op {
     139                 :            :   EIGEN_EMPTY_STRUCT_CTOR(scalar_arg_op)
     140                 :            :   typedef typename NumTraits<Scalar>::Real result_type;
     141                 :            :   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const result_type operator() (const Scalar& a) const { return numext::arg(a); }
     142                 :            :   template<typename Packet>
     143                 :            :   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const
     144                 :            :   { return internal::parg(a); }
     145                 :            : };
     146                 :            : template<typename Scalar>
     147                 :            : struct functor_traits<scalar_arg_op<Scalar> >
     148                 :            : {
     149                 :            :   enum {
     150                 :            :     Cost = NumTraits<Scalar>::IsComplex ? 5 * NumTraits<Scalar>::MulCost : NumTraits<Scalar>::AddCost,
     151                 :            :     PacketAccess = packet_traits<Scalar>::HasArg
     152                 :            :   };
     153                 :            : };
     154                 :            : /** \internal
     155                 :            :   * \brief Template functor to cast a scalar to another type
     156                 :            :   *
     157                 :            :   * \sa class CwiseUnaryOp, MatrixBase::cast()
     158                 :            :   */
     159                 :            : template<typename Scalar, typename NewType>
     160                 :            : struct scalar_cast_op {
     161                 :            :   EIGEN_EMPTY_STRUCT_CTOR(scalar_cast_op)
     162                 :            :   typedef NewType result_type;
     163                 :            :   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const NewType operator() (const Scalar& a) const { return cast<Scalar, NewType>(a); }
     164                 :            : };
     165                 :            : template<typename Scalar, typename NewType>
     166                 :            : struct functor_traits<scalar_cast_op<Scalar,NewType> >
     167                 :            : { enum { Cost = is_same<Scalar, NewType>::value ? 0 : NumTraits<NewType>::AddCost, PacketAccess = false }; };
     168                 :            : 
     169                 :            : /** \internal
     170                 :            :   * \brief Template functor to arithmetically shift a scalar right by a number of bits
     171                 :            :   *
     172                 :            :   * \sa class CwiseUnaryOp, MatrixBase::shift_right()
     173                 :            :   */
     174                 :            : template<typename Scalar, int N>
     175                 :            : struct scalar_shift_right_op {
     176                 :            :   EIGEN_EMPTY_STRUCT_CTOR(scalar_shift_right_op)
     177                 :            : 
     178                 :            :   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a) const
     179                 :            :   { return a >> N; }
     180                 :            :   template<typename Packet>
     181                 :            :   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const
     182                 :            :   { return internal::parithmetic_shift_right<N>(a); }
     183                 :            : };
     184                 :            : template<typename Scalar, int N>
     185                 :            : struct functor_traits<scalar_shift_right_op<Scalar,N> >
     186                 :            : { enum { Cost = NumTraits<Scalar>::AddCost, PacketAccess = packet_traits<Scalar>::HasShift }; };
     187                 :            : 
     188                 :            : /** \internal
     189                 :            :   * \brief Template functor to logically shift a scalar left by a number of bits
     190                 :            :   *
     191                 :            :   * \sa class CwiseUnaryOp, MatrixBase::shift_left()
     192                 :            :   */
     193                 :            : template<typename Scalar, int N>
     194                 :            : struct scalar_shift_left_op {
     195                 :            :   EIGEN_EMPTY_STRUCT_CTOR(scalar_shift_left_op)
     196                 :            : 
     197                 :            :   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a) const
     198                 :            :   { return a << N; }
     199                 :            :   template<typename Packet>
     200                 :            :   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(const Packet& a) const
     201                 :            :   { return internal::plogical_shift_left<N>(a); }
     202                 :            : };
     203                 :            : template<typename Scalar, int N>
     204                 :            : struct functor_traits<scalar_shift_left_op<Scalar,N> >
     205                 :            : { enum { Cost = NumTraits<Scalar>::AddCost, PacketAccess = packet_traits<Scalar>::HasShift }; };
     206                 :            : 
     207                 :            : /** \internal
     208                 :            :   * \brief Template functor to extract the real part of a complex
     209                 :            :   *
     210                 :            :   * \sa class CwiseUnaryOp, MatrixBase::real()
     211                 :            :   */
     212                 :            : template<typename Scalar>
     213                 :            : struct scalar_real_op {
     214                 :            :   EIGEN_EMPTY_STRUCT_CTOR(scalar_real_op)
     215                 :            :   typedef typename NumTraits<Scalar>::Real result_type;
     216                 :            :   EIGEN_DEVICE_FUNC
     217                 :            :   EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return numext::real(a); }
     218                 :            : };
     219                 :            : template<typename Scalar>
     220                 :            : struct functor_traits<scalar_real_op<Scalar> >
     221                 :            : { enum { Cost = 0, PacketAccess = false }; };
     222                 :            : 
     223                 :            : /** \internal
     224                 :            :   * \brief Template functor to extract the imaginary part of a complex
     225                 :            :   *
     226                 :            :   * \sa class CwiseUnaryOp, MatrixBase::imag()
     227                 :            :   */
     228                 :            : template<typename Scalar>
     229                 :            : struct scalar_imag_op {
     230                 :            :   EIGEN_EMPTY_STRUCT_CTOR(scalar_imag_op)
     231                 :            :   typedef typename NumTraits<Scalar>::Real result_type;
     232                 :            :   EIGEN_DEVICE_FUNC
     233                 :            :   EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return numext::imag(a); }
     234                 :            : };
     235                 :            : template<typename Scalar>
     236                 :            : struct functor_traits<scalar_imag_op<Scalar> >
     237                 :            : { enum { Cost = 0, PacketAccess = false }; };
     238                 :            : 
     239                 :            : /** \internal
     240                 :            :   * \brief Template functor to extract the real part of a complex as a reference
     241                 :            :   *
     242                 :            :   * \sa class CwiseUnaryOp, MatrixBase::real()
     243                 :            :   */
     244                 :            : template<typename Scalar>
     245                 :            : struct scalar_real_ref_op {
     246                 :            :   EIGEN_EMPTY_STRUCT_CTOR(scalar_real_ref_op)
     247                 :            :   typedef typename NumTraits<Scalar>::Real result_type;
     248                 :            :   EIGEN_DEVICE_FUNC
     249                 :            :   EIGEN_STRONG_INLINE result_type& operator() (const Scalar& a) const { return numext::real_ref(*const_cast<Scalar*>(&a)); }
     250                 :            : };
     251                 :            : template<typename Scalar>
     252                 :            : struct functor_traits<scalar_real_ref_op<Scalar> >
     253                 :            : { enum { Cost = 0, PacketAccess = false }; };
     254                 :            : 
     255                 :            : /** \internal
     256                 :            :   * \brief Template functor to extract the imaginary part of a complex as a reference
     257                 :            :   *
     258                 :            :   * \sa class CwiseUnaryOp, MatrixBase::imag()
     259                 :            :   */
     260                 :            : template<typename Scalar>
     261                 :            : struct scalar_imag_ref_op {
     262                 :            :   EIGEN_EMPTY_STRUCT_CTOR(scalar_imag_ref_op)
     263                 :            :   typedef typename NumTraits<Scalar>::Real result_type;
     264                 :            :   EIGEN_DEVICE_FUNC
     265                 :            :   EIGEN_STRONG_INLINE result_type& operator() (const Scalar& a) const { return numext::imag_ref(*const_cast<Scalar*>(&a)); }
     266                 :            : };
     267                 :            : template<typename Scalar>
     268                 :            : struct functor_traits<scalar_imag_ref_op<Scalar> >
     269                 :            : { enum { Cost = 0, PacketAccess = false }; };
     270                 :            : 
     271                 :            : /** \internal
     272                 :            :   *
     273                 :            :   * \brief Template functor to compute the exponential of a scalar
     274                 :            :   *
     275                 :            :   * \sa class CwiseUnaryOp, Cwise::exp()
     276                 :            :   */
     277                 :            : template<typename Scalar> struct scalar_exp_op {
     278                 :            :   EIGEN_EMPTY_STRUCT_CTOR(scalar_exp_op)
     279                 :            :   EIGEN_DEVICE_FUNC inline const Scalar operator() (const Scalar& a) const { return numext::exp(a); }
     280                 :            :   template <typename Packet>
     281                 :            :   EIGEN_DEVICE_FUNC inline Packet packetOp(const Packet& a) const { return internal::pexp(a); }
     282                 :            : };
     283                 :            : template <typename Scalar>
     284                 :            : struct functor_traits<scalar_exp_op<Scalar> > {
     285                 :            :   enum {
     286                 :            :     PacketAccess = packet_traits<Scalar>::HasExp,
     287                 :            :     // The following numbers are based on the AVX implementation.
     288                 :            : #ifdef EIGEN_VECTORIZE_FMA
     289                 :            :     // Haswell can issue 2 add/mul/madd per cycle.
     290                 :            :     Cost =
     291                 :            :     (sizeof(Scalar) == 4
     292                 :            :      // float: 8 pmadd, 4 pmul, 2 padd/psub, 6 other
     293                 :            :      ? (8 * NumTraits<Scalar>::AddCost + 6 * NumTraits<Scalar>::MulCost)
     294                 :            :      // double: 7 pmadd, 5 pmul, 3 padd/psub, 1 div,  13 other
     295                 :            :      : (14 * NumTraits<Scalar>::AddCost +
     296                 :            :         6 * NumTraits<Scalar>::MulCost +
     297                 :            :         scalar_div_cost<Scalar,packet_traits<Scalar>::HasDiv>::value))
     298                 :            : #else
     299                 :            :     Cost =
     300                 :            :     (sizeof(Scalar) == 4
     301                 :            :      // float: 7 pmadd, 6 pmul, 4 padd/psub, 10 other
     302                 :            :      ? (21 * NumTraits<Scalar>::AddCost + 13 * NumTraits<Scalar>::MulCost)
     303                 :            :      // double: 7 pmadd, 5 pmul, 3 padd/psub, 1 div,  13 other
     304                 :            :      : (23 * NumTraits<Scalar>::AddCost +
     305                 :            :         12 * NumTraits<Scalar>::MulCost +
     306                 :            :         scalar_div_cost<Scalar,packet_traits<Scalar>::HasDiv>::value))
     307                 :            : #endif
     308                 :            :   };
     309                 :            : };
     310                 :            : 
     311                 :            : /** \internal
     312                 :            :   *
     313                 :            :   * \brief Template functor to compute the exponential of a scalar - 1.
     314                 :            :   *
     315                 :            :   * \sa class CwiseUnaryOp, ArrayBase::expm1()
     316                 :            :   */
     317                 :            : template<typename Scalar> struct scalar_expm1_op {
     318                 :            :   EIGEN_EMPTY_STRUCT_CTOR(scalar_expm1_op)
     319                 :            :   EIGEN_DEVICE_FUNC inline const Scalar operator() (const Scalar& a) const { return numext::expm1(a); }
     320                 :            :   template <typename Packet>
     321                 :            :   EIGEN_DEVICE_FUNC inline Packet packetOp(const Packet& a) const { return internal::pexpm1(a); }
     322                 :            : };
     323                 :            : template <typename Scalar>
     324                 :            : struct functor_traits<scalar_expm1_op<Scalar> > {
     325                 :            :   enum {
     326                 :            :     PacketAccess = packet_traits<Scalar>::HasExpm1,
     327                 :            :     Cost = functor_traits<scalar_exp_op<Scalar> >::Cost // TODO measure cost of expm1
     328                 :            :   };
     329                 :            : };
     330                 :            : 
     331                 :            : /** \internal
     332                 :            :   *
     333                 :            :   * \brief Template functor to compute the logarithm of a scalar
     334                 :            :   *
     335                 :            :   * \sa class CwiseUnaryOp, ArrayBase::log()
     336                 :            :   */
     337                 :            : template<typename Scalar> struct scalar_log_op {
     338                 :            :   EIGEN_EMPTY_STRUCT_CTOR(scalar_log_op)
     339                 :            :   EIGEN_DEVICE_FUNC inline const Scalar operator() (const Scalar& a) const { return numext::log(a); }
     340                 :            :   template <typename Packet>
     341                 :            :   EIGEN_DEVICE_FUNC inline Packet packetOp(const Packet& a) const { return internal::plog(a); }
     342                 :            : };
     343                 :            : template <typename Scalar>
     344                 :            : struct functor_traits<scalar_log_op<Scalar> > {
     345                 :            :   enum {
     346                 :            :     PacketAccess = packet_traits<Scalar>::HasLog,
     347                 :            :     Cost =
     348                 :            :     (PacketAccess
     349                 :            :      // The following numbers are based on the AVX implementation.
     350                 :            : #ifdef EIGEN_VECTORIZE_FMA
     351                 :            :      // 8 pmadd, 6 pmul, 8 padd/psub, 16 other, can issue 2 add/mul/madd per cycle.
     352                 :            :      ? (20 * NumTraits<Scalar>::AddCost + 7 * NumTraits<Scalar>::MulCost)
     353                 :            : #else
     354                 :            :      // 8 pmadd, 6 pmul, 8 padd/psub, 20 other
     355                 :            :      ? (36 * NumTraits<Scalar>::AddCost + 14 * NumTraits<Scalar>::MulCost)
     356                 :            : #endif
     357                 :            :      // Measured cost of std::log.
     358                 :            :      : sizeof(Scalar)==4 ? 40 : 85)
     359                 :            :   };
     360                 :            : };
     361                 :            : 
     362                 :            : /** \internal
     363                 :            :   *
     364                 :            :   * \brief Template functor to compute the logarithm of 1 plus a scalar value
     365                 :            :   *
     366                 :            :   * \sa class CwiseUnaryOp, ArrayBase::log1p()
     367                 :            :   */
     368                 :            : template<typename Scalar> struct scalar_log1p_op {
     369                 :            :   EIGEN_EMPTY_STRUCT_CTOR(scalar_log1p_op)
     370                 :            :   EIGEN_DEVICE_FUNC inline const Scalar operator() (const Scalar& a) const { return numext::log1p(a); }
     371                 :            :   template <typename Packet>
     372                 :            :   EIGEN_DEVICE_FUNC inline Packet packetOp(const Packet& a) const { return internal::plog1p(a); }
     373                 :            : };
     374                 :            : template <typename Scalar>
     375                 :            : struct functor_traits<scalar_log1p_op<Scalar> > {
     376                 :            :   enum {
     377                 :            :     PacketAccess = packet_traits<Scalar>::HasLog1p,
     378                 :            :     Cost = functor_traits<scalar_log_op<Scalar> >::Cost // TODO measure cost of log1p
     379                 :            :   };
     380                 :            : };
     381                 :            : 
     382                 :            : /** \internal
     383                 :            :   *
     384                 :            :   * \brief Template functor to compute the base-10 logarithm of a scalar
     385                 :            :   *
     386                 :            :   * \sa class CwiseUnaryOp, Cwise::log10()
     387                 :            :   */
     388                 :            : template<typename Scalar> struct scalar_log10_op {
     389                 :            :   EIGEN_EMPTY_STRUCT_CTOR(scalar_log10_op)
     390                 :            :   EIGEN_DEVICE_FUNC inline const Scalar operator() (const Scalar& a) const { EIGEN_USING_STD(log10) return log10(a); }
     391                 :            :   template <typename Packet>
     392                 :            :   EIGEN_DEVICE_FUNC inline Packet packetOp(const Packet& a) const { return internal::plog10(a); }
     393                 :            : };
     394                 :            : template<typename Scalar>
     395                 :            : struct functor_traits<scalar_log10_op<Scalar> >
     396                 :            : { enum { Cost = 5 * NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasLog10 }; };
     397                 :            : 
     398                 :            : /** \internal
     399                 :            :   *
     400                 :            :   * \brief Template functor to compute the base-2 logarithm of a scalar
     401                 :            :   *
     402                 :            :   * \sa class CwiseUnaryOp, Cwise::log2()
     403                 :            :   */
     404                 :            : template<typename Scalar> struct scalar_log2_op {
     405                 :            :   EIGEN_EMPTY_STRUCT_CTOR(scalar_log2_op)
     406                 :            :   EIGEN_DEVICE_FUNC inline const Scalar operator() (const Scalar& a) const { return Scalar(EIGEN_LOG2E) * numext::log(a); }
     407                 :            :   template <typename Packet>
     408                 :            :   EIGEN_DEVICE_FUNC inline Packet packetOp(const Packet& a) const { return internal::plog2(a); }
     409                 :            : };
     410                 :            : template<typename Scalar>
     411                 :            : struct functor_traits<scalar_log2_op<Scalar> >
     412                 :            : { enum { Cost = 5 * NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasLog }; };
     413                 :            : 
     414                 :            : /** \internal
     415                 :            :   * \brief Template functor to compute the square root of a scalar
     416                 :            :   * \sa class CwiseUnaryOp, Cwise::sqrt()
     417                 :            :   */
     418                 :            : template<typename Scalar> struct scalar_sqrt_op {
     419                 :            :   EIGEN_EMPTY_STRUCT_CTOR(scalar_sqrt_op)
     420                 :            :   EIGEN_DEVICE_FUNC inline const Scalar operator() (const Scalar& a) const { return numext::sqrt(a); }
     421                 :            :   template <typename Packet>
     422                 :            :   EIGEN_DEVICE_FUNC inline Packet packetOp(const Packet& a) const { return internal::psqrt(a); }
     423                 :            : };
     424                 :            : template <typename Scalar>
     425                 :            : struct functor_traits<scalar_sqrt_op<Scalar> > {
     426                 :            :   enum {
     427                 :            : #if EIGEN_FAST_MATH
     428                 :            :     // The following numbers are based on the AVX implementation.
     429                 :            :     Cost = (sizeof(Scalar) == 8 ? 28
     430                 :            :                                 // 4 pmul, 1 pmadd, 3 other
     431                 :            :                                 : (3 * NumTraits<Scalar>::AddCost +
     432                 :            :                                    5 * NumTraits<Scalar>::MulCost)),
     433                 :            : #else
     434                 :            :     // The following numbers are based on min VSQRT throughput on Haswell.
     435                 :            :     Cost = (sizeof(Scalar) == 8 ? 28 : 14),
     436                 :            : #endif
     437                 :            :     PacketAccess = packet_traits<Scalar>::HasSqrt
     438                 :            :   };
     439                 :            : };
     440                 :            : 
     441                 :            : // Boolean specialization to eliminate -Wimplicit-conversion-floating-point-to-bool warnings.
     442                 :            : template<> struct scalar_sqrt_op<bool> {
     443                 :            :   EIGEN_EMPTY_STRUCT_CTOR(scalar_sqrt_op)
     444                 :            :   EIGEN_DEPRECATED EIGEN_DEVICE_FUNC inline bool operator() (const bool& a) const { return a; }
     445                 :            :   template <typename Packet>
     446                 :            :   EIGEN_DEPRECATED EIGEN_DEVICE_FUNC inline Packet packetOp(const Packet& a) const { return a; }
     447                 :            : };
     448                 :            : template <>
     449                 :            : struct functor_traits<scalar_sqrt_op<bool> > {
     450                 :            :   enum { Cost = 1, PacketAccess = packet_traits<bool>::Vectorizable };
     451                 :            : };
     452                 :            : 
     453                 :            : /** \internal
     454                 :            :   * \brief Template functor to compute the reciprocal square root of a scalar
     455                 :            :   * \sa class CwiseUnaryOp, Cwise::rsqrt()
     456                 :            :   */
     457                 :            : template<typename Scalar> struct scalar_rsqrt_op {
     458                 :            :   EIGEN_EMPTY_STRUCT_CTOR(scalar_rsqrt_op)
     459                 :            :   EIGEN_DEVICE_FUNC inline const Scalar operator() (const Scalar& a) const { return numext::rsqrt(a); }
     460                 :            :   template <typename Packet>
     461                 :            :   EIGEN_DEVICE_FUNC inline Packet packetOp(const Packet& a) const { return internal::prsqrt(a); }
     462                 :            : };
     463                 :            : 
     464                 :            : template<typename Scalar>
     465                 :            : struct functor_traits<scalar_rsqrt_op<Scalar> >
     466                 :            : { enum {
     467                 :            :     Cost = 5 * NumTraits<Scalar>::MulCost,
     468                 :            :     PacketAccess = packet_traits<Scalar>::HasRsqrt
     469                 :            :   };
     470                 :            : };
     471                 :            : 
     472                 :            : /** \internal
     473                 :            :   * \brief Template functor to compute the cosine of a scalar
     474                 :            :   * \sa class CwiseUnaryOp, ArrayBase::cos()
     475                 :            :   */
     476                 :            : template<typename Scalar> struct scalar_cos_op {
     477                 :            :   EIGEN_EMPTY_STRUCT_CTOR(scalar_cos_op)
     478                 :            :   EIGEN_DEVICE_FUNC inline Scalar operator() (const Scalar& a) const { return numext::cos(a); }
     479                 :            :   template <typename Packet>
     480                 :            :   EIGEN_DEVICE_FUNC inline Packet packetOp(const Packet& a) const { return internal::pcos(a); }
     481                 :            : };
     482                 :            : template<typename Scalar>
     483                 :            : struct functor_traits<scalar_cos_op<Scalar> >
     484                 :            : {
     485                 :            :   enum {
     486                 :            :     Cost = 5 * NumTraits<Scalar>::MulCost,
     487                 :            :     PacketAccess = packet_traits<Scalar>::HasCos
     488                 :            :   };
     489                 :            : };
     490                 :            : 
     491                 :            : /** \internal
     492                 :            :   * \brief Template functor to compute the sine of a scalar
     493                 :            :   * \sa class CwiseUnaryOp, ArrayBase::sin()
     494                 :            :   */
     495                 :            : template<typename Scalar> struct scalar_sin_op {
     496                 :            :   EIGEN_EMPTY_STRUCT_CTOR(scalar_sin_op)
     497                 :            :   EIGEN_DEVICE_FUNC inline const Scalar operator() (const Scalar& a) const { return numext::sin(a); }
     498                 :            :   template <typename Packet>
     499                 :            :   EIGEN_DEVICE_FUNC inline Packet packetOp(const Packet& a) const { return internal::psin(a); }
     500                 :            : };
     501                 :            : template<typename Scalar>
     502                 :            : struct functor_traits<scalar_sin_op<Scalar> >
     503                 :            : {
     504                 :            :   enum {
     505                 :            :     Cost = 5 * NumTraits<Scalar>::MulCost,
     506                 :            :     PacketAccess = packet_traits<Scalar>::HasSin
     507                 :            :   };
     508                 :            : };
     509                 :            : 
     510                 :            : 
     511                 :            : /** \internal
     512                 :            :   * \brief Template functor to compute the tan of a scalar
     513                 :            :   * \sa class CwiseUnaryOp, ArrayBase::tan()
     514                 :            :   */
     515                 :            : template<typename Scalar> struct scalar_tan_op {
     516                 :            :   EIGEN_EMPTY_STRUCT_CTOR(scalar_tan_op)
     517                 :            :   EIGEN_DEVICE_FUNC inline const Scalar operator() (const Scalar& a) const { return numext::tan(a); }
     518                 :            :   template <typename Packet>
     519                 :            :   EIGEN_DEVICE_FUNC inline Packet packetOp(const Packet& a) const { return internal::ptan(a); }
     520                 :            : };
     521                 :            : template<typename Scalar>
     522                 :            : struct functor_traits<scalar_tan_op<Scalar> >
     523                 :            : {
     524                 :            :   enum {
     525                 :            :     Cost = 5 * NumTraits<Scalar>::MulCost,
     526                 :            :     PacketAccess = packet_traits<Scalar>::HasTan
     527                 :            :   };
     528                 :            : };
     529                 :            : 
     530                 :            : /** \internal
     531                 :            :   * \brief Template functor to compute the arc cosine of a scalar
     532                 :            :   * \sa class CwiseUnaryOp, ArrayBase::acos()
     533                 :            :   */
     534                 :            : template<typename Scalar> struct scalar_acos_op {
     535                 :            :   EIGEN_EMPTY_STRUCT_CTOR(scalar_acos_op)
     536                 :            :   EIGEN_DEVICE_FUNC inline const Scalar operator() (const Scalar& a) const { return numext::acos(a); }
     537                 :            :   template <typename Packet>
     538                 :            :   EIGEN_DEVICE_FUNC inline Packet packetOp(const Packet& a) const { return internal::pacos(a); }
     539                 :            : };
     540                 :            : template<typename Scalar>
     541                 :            : struct functor_traits<scalar_acos_op<Scalar> >
     542                 :            : {
     543                 :            :   enum {
     544                 :            :     Cost = 5 * NumTraits<Scalar>::MulCost,
     545                 :            :     PacketAccess = packet_traits<Scalar>::HasACos
     546                 :            :   };
     547                 :            : };
     548                 :            : 
     549                 :            : /** \internal
     550                 :            :   * \brief Template functor to compute the arc sine of a scalar
     551                 :            :   * \sa class CwiseUnaryOp, ArrayBase::asin()
     552                 :            :   */
     553                 :            : template<typename Scalar> struct scalar_asin_op {
     554                 :            :   EIGEN_EMPTY_STRUCT_CTOR(scalar_asin_op)
     555                 :            :   EIGEN_DEVICE_FUNC inline const Scalar operator() (const Scalar& a) const { return numext::asin(a); }
     556                 :            :   template <typename Packet>
     557                 :            :   EIGEN_DEVICE_FUNC inline Packet packetOp(const Packet& a) const { return internal::pasin(a); }
     558                 :            : };
     559                 :            : template<typename Scalar>
     560                 :            : struct functor_traits<scalar_asin_op<Scalar> >
     561                 :            : {
     562                 :            :   enum {
     563                 :            :     Cost = 5 * NumTraits<Scalar>::MulCost,
     564                 :            :     PacketAccess = packet_traits<Scalar>::HasASin
     565                 :            :   };
     566                 :            : };
     567                 :            : 
     568                 :            : 
     569                 :            : /** \internal
     570                 :            :   * \brief Template functor to compute the atan of a scalar
     571                 :            :   * \sa class CwiseUnaryOp, ArrayBase::atan()
     572                 :            :   */
     573                 :            : template<typename Scalar> struct scalar_atan_op {
     574                 :            :   EIGEN_EMPTY_STRUCT_CTOR(scalar_atan_op)
     575                 :            :   EIGEN_DEVICE_FUNC inline const Scalar operator() (const Scalar& a) const { return numext::atan(a); }
     576                 :            :   template <typename Packet>
     577                 :            :   EIGEN_DEVICE_FUNC inline Packet packetOp(const Packet& a) const { return internal::patan(a); }
     578                 :            : };
     579                 :            : template<typename Scalar>
     580                 :            : struct functor_traits<scalar_atan_op<Scalar> >
     581                 :            : {
     582                 :            :   enum {
     583                 :            :     Cost = 5 * NumTraits<Scalar>::MulCost,
     584                 :            :     PacketAccess = packet_traits<Scalar>::HasATan
     585                 :            :   };
     586                 :            : };
     587                 :            : 
     588                 :            : /** \internal
     589                 :            :   * \brief Template functor to compute the tanh of a scalar
     590                 :            :   * \sa class CwiseUnaryOp, ArrayBase::tanh()
     591                 :            :   */
     592                 :            : template <typename Scalar>
     593                 :            : struct scalar_tanh_op {
     594                 :            :   EIGEN_EMPTY_STRUCT_CTOR(scalar_tanh_op)
     595                 :            :   EIGEN_DEVICE_FUNC inline const Scalar operator()(const Scalar& a) const { return numext::tanh(a); }
     596                 :            :   template <typename Packet>
     597                 :            :   EIGEN_DEVICE_FUNC inline Packet packetOp(const Packet& x) const { return ptanh(x); }
     598                 :            : };
     599                 :            : 
     600                 :            : template <typename Scalar>
     601                 :            : struct functor_traits<scalar_tanh_op<Scalar> > {
     602                 :            :   enum {
     603                 :            :     PacketAccess = packet_traits<Scalar>::HasTanh,
     604                 :            :     Cost = ( (EIGEN_FAST_MATH && is_same<Scalar,float>::value)
     605                 :            : // The following numbers are based on the AVX implementation,
     606                 :            : #ifdef EIGEN_VECTORIZE_FMA
     607                 :            :                 // Haswell can issue 2 add/mul/madd per cycle.
     608                 :            :                 // 9 pmadd, 2 pmul, 1 div, 2 other
     609                 :            :                 ? (2 * NumTraits<Scalar>::AddCost +
     610                 :            :                    6 * NumTraits<Scalar>::MulCost +
     611                 :            :                    scalar_div_cost<Scalar,packet_traits<Scalar>::HasDiv>::value)
     612                 :            : #else
     613                 :            :                 ? (11 * NumTraits<Scalar>::AddCost +
     614                 :            :                    11 * NumTraits<Scalar>::MulCost +
     615                 :            :                    scalar_div_cost<Scalar,packet_traits<Scalar>::HasDiv>::value)
     616                 :            : #endif
     617                 :            :                 // This number assumes a naive implementation of tanh
     618                 :            :                 : (6 * NumTraits<Scalar>::AddCost +
     619                 :            :                    3 * NumTraits<Scalar>::MulCost +
     620                 :            :                    2 * scalar_div_cost<Scalar,packet_traits<Scalar>::HasDiv>::value +
     621                 :            :                    functor_traits<scalar_exp_op<Scalar> >::Cost))
     622                 :            :   };
     623                 :            : };
     624                 :            : 
     625                 :            : #if EIGEN_HAS_CXX11_MATH
     626                 :            : /** \internal
     627                 :            :   * \brief Template functor to compute the atanh of a scalar
     628                 :            :   * \sa class CwiseUnaryOp, ArrayBase::atanh()
     629                 :            :   */
     630                 :            : template <typename Scalar>
     631                 :            : struct scalar_atanh_op {
     632                 :            :   EIGEN_EMPTY_STRUCT_CTOR(scalar_atanh_op)
     633                 :            :   EIGEN_DEVICE_FUNC inline const Scalar operator()(const Scalar& a) const { return numext::atanh(a); }
     634                 :            : };
     635                 :            : 
     636                 :            : template <typename Scalar>
     637                 :            : struct functor_traits<scalar_atanh_op<Scalar> > {
     638                 :            :   enum { Cost = 5 * NumTraits<Scalar>::MulCost, PacketAccess = false };
     639                 :            : };
     640                 :            : #endif
     641                 :            : 
     642                 :            : /** \internal
     643                 :            :   * \brief Template functor to compute the sinh of a scalar
     644                 :            :   * \sa class CwiseUnaryOp, ArrayBase::sinh()
     645                 :            :   */
     646                 :            : template<typename Scalar> struct scalar_sinh_op {
     647                 :            :   EIGEN_EMPTY_STRUCT_CTOR(scalar_sinh_op)
     648                 :            :   EIGEN_DEVICE_FUNC inline const Scalar operator() (const Scalar& a) const { return numext::sinh(a); }
     649                 :            :   template <typename Packet>
     650                 :            :   EIGEN_DEVICE_FUNC inline Packet packetOp(const Packet& a) const { return internal::psinh(a); }
     651                 :            : };
     652                 :            : template<typename Scalar>
     653                 :            : struct functor_traits<scalar_sinh_op<Scalar> >
     654                 :            : {
     655                 :            :   enum {
     656                 :            :     Cost = 5 * NumTraits<Scalar>::MulCost,
     657                 :            :     PacketAccess = packet_traits<Scalar>::HasSinh
     658                 :            :   };
     659                 :            : };
     660                 :            : 
     661                 :            : #if EIGEN_HAS_CXX11_MATH
     662                 :            : /** \internal
     663                 :            :   * \brief Template functor to compute the asinh of a scalar
     664                 :            :   * \sa class CwiseUnaryOp, ArrayBase::asinh()
     665                 :            :   */
     666                 :            : template <typename Scalar>
     667                 :            : struct scalar_asinh_op {
     668                 :            :   EIGEN_EMPTY_STRUCT_CTOR(scalar_asinh_op)
     669                 :            :   EIGEN_DEVICE_FUNC inline const Scalar operator()(const Scalar& a) const { return numext::asinh(a); }
     670                 :            : };
     671                 :            : 
     672                 :            : template <typename Scalar>
     673                 :            : struct functor_traits<scalar_asinh_op<Scalar> > {
     674                 :            :   enum { Cost = 5 * NumTraits<Scalar>::MulCost, PacketAccess = false };
     675                 :            : };
     676                 :            : #endif
     677                 :            : 
     678                 :            : /** \internal
     679                 :            :   * \brief Template functor to compute the cosh of a scalar
     680                 :            :   * \sa class CwiseUnaryOp, ArrayBase::cosh()
     681                 :            :   */
     682                 :            : template<typename Scalar> struct scalar_cosh_op {
     683                 :            :   EIGEN_EMPTY_STRUCT_CTOR(scalar_cosh_op)
     684                 :            :   EIGEN_DEVICE_FUNC inline const Scalar operator() (const Scalar& a) const { return numext::cosh(a); }
     685                 :            :   template <typename Packet>
     686                 :            :   EIGEN_DEVICE_FUNC inline Packet packetOp(const Packet& a) const { return internal::pcosh(a); }
     687                 :            : };
     688                 :            : template<typename Scalar>
     689                 :            : struct functor_traits<scalar_cosh_op<Scalar> >
     690                 :            : {
     691                 :            :   enum {
     692                 :            :     Cost = 5 * NumTraits<Scalar>::MulCost,
     693                 :            :     PacketAccess = packet_traits<Scalar>::HasCosh
     694                 :            :   };
     695                 :            : };
     696                 :            : 
     697                 :            : #if EIGEN_HAS_CXX11_MATH
     698                 :            : /** \internal
     699                 :            :   * \brief Template functor to compute the acosh of a scalar
     700                 :            :   * \sa class CwiseUnaryOp, ArrayBase::acosh()
     701                 :            :   */
     702                 :            : template <typename Scalar>
     703                 :            : struct scalar_acosh_op {
     704                 :            :   EIGEN_EMPTY_STRUCT_CTOR(scalar_acosh_op)
     705                 :            :   EIGEN_DEVICE_FUNC inline const Scalar operator()(const Scalar& a) const { return numext::acosh(a); }
     706                 :            : };
     707                 :            : 
     708                 :            : template <typename Scalar>
     709                 :            : struct functor_traits<scalar_acosh_op<Scalar> > {
     710                 :            :   enum { Cost = 5 * NumTraits<Scalar>::MulCost, PacketAccess = false };
     711                 :            : };
     712                 :            : #endif
     713                 :            : 
     714                 :            : /** \internal
     715                 :            :   * \brief Template functor to compute the inverse of a scalar
     716                 :            :   * \sa class CwiseUnaryOp, Cwise::inverse()
     717                 :            :   */
     718                 :            : template<typename Scalar>
     719                 :            : struct scalar_inverse_op {
     720                 :            :   EIGEN_EMPTY_STRUCT_CTOR(scalar_inverse_op)
     721                 :            :   EIGEN_DEVICE_FUNC inline Scalar operator() (const Scalar& a) const { return Scalar(1)/a; }
     722                 :            :   template<typename Packet>
     723                 :            :   EIGEN_DEVICE_FUNC inline const Packet packetOp(const Packet& a) const
     724                 :            :   { return internal::pdiv(pset1<Packet>(Scalar(1)),a); }
     725                 :            : };
     726                 :            : template <typename Scalar>
     727                 :            : struct functor_traits<scalar_inverse_op<Scalar> > {
     728                 :            :   enum {
     729                 :            :     PacketAccess = packet_traits<Scalar>::HasDiv,
     730                 :            :     Cost = scalar_div_cost<Scalar, PacketAccess>::value
     731                 :            :   };
     732                 :            : };
     733                 :            : 
     734                 :            : /** \internal
     735                 :            :   * \brief Template functor to compute the square of a scalar
     736                 :            :   * \sa class CwiseUnaryOp, Cwise::square()
     737                 :            :   */
     738                 :            : template<typename Scalar>
     739                 :            : struct scalar_square_op {
     740                 :            :   EIGEN_EMPTY_STRUCT_CTOR(scalar_square_op)
     741                 :            :   EIGEN_DEVICE_FUNC inline Scalar operator() (const Scalar& a) const { return a*a; }
     742                 :            :   template<typename Packet>
     743                 :            :   EIGEN_DEVICE_FUNC inline const Packet packetOp(const Packet& a) const
     744                 :            :   { return internal::pmul(a,a); }
     745                 :            : };
     746                 :            : template<typename Scalar>
     747                 :            : struct functor_traits<scalar_square_op<Scalar> >
     748                 :            : { enum { Cost = NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasMul }; };
     749                 :            : 
     750                 :            : // Boolean specialization to avoid -Wint-in-bool-context warnings on GCC.
     751                 :            : template<>
     752                 :            : struct scalar_square_op<bool> {
     753                 :            :   EIGEN_EMPTY_STRUCT_CTOR(scalar_square_op)
     754                 :            :   EIGEN_DEPRECATED EIGEN_DEVICE_FUNC inline bool operator() (const bool& a) const { return a; }
     755                 :            :   template<typename Packet>
     756                 :            :   EIGEN_DEPRECATED EIGEN_DEVICE_FUNC inline const Packet packetOp(const Packet& a) const
     757                 :            :   { return a; }
     758                 :            : };
     759                 :            : template<>
     760                 :            : struct functor_traits<scalar_square_op<bool> >
     761                 :            : { enum { Cost = 0, PacketAccess = packet_traits<bool>::Vectorizable }; };
     762                 :            : 
     763                 :            : /** \internal
     764                 :            :   * \brief Template functor to compute the cube of a scalar
     765                 :            :   * \sa class CwiseUnaryOp, Cwise::cube()
     766                 :            :   */
     767                 :            : template<typename Scalar>
     768                 :            : struct scalar_cube_op {
     769                 :            :   EIGEN_EMPTY_STRUCT_CTOR(scalar_cube_op)
     770                 :            :   EIGEN_DEVICE_FUNC inline Scalar operator() (const Scalar& a) const { return a*a*a; }
     771                 :            :   template<typename Packet>
     772                 :            :   EIGEN_DEVICE_FUNC inline const Packet packetOp(const Packet& a) const
     773                 :            :   { return internal::pmul(a,pmul(a,a)); }
     774                 :            : };
     775                 :            : template<typename Scalar>
     776                 :            : struct functor_traits<scalar_cube_op<Scalar> >
     777                 :            : { enum { Cost = 2*NumTraits<Scalar>::MulCost, PacketAccess = packet_traits<Scalar>::HasMul }; };
     778                 :            : 
     779                 :            : // Boolean specialization to avoid -Wint-in-bool-context warnings on GCC.
     780                 :            : template<>
     781                 :            : struct scalar_cube_op<bool> {
     782                 :            :   EIGEN_EMPTY_STRUCT_CTOR(scalar_cube_op)
     783                 :            :   EIGEN_DEPRECATED EIGEN_DEVICE_FUNC inline bool operator() (const bool& a) const { return a; }
     784                 :            :   template<typename Packet>
     785                 :            :   EIGEN_DEPRECATED EIGEN_DEVICE_FUNC inline const Packet packetOp(const Packet& a) const
     786                 :            :   { return a; }
     787                 :            : };
     788                 :            : template<>
     789                 :            : struct functor_traits<scalar_cube_op<bool> >
     790                 :            : { enum { Cost = 0, PacketAccess = packet_traits<bool>::Vectorizable }; };
     791                 :            : 
     792                 :            : /** \internal
     793                 :            :   * \brief Template functor to compute the rounded value of a scalar
     794                 :            :   * \sa class CwiseUnaryOp, ArrayBase::round()
     795                 :            :   */
     796                 :            : template<typename Scalar> struct scalar_round_op {
     797                 :            :   EIGEN_EMPTY_STRUCT_CTOR(scalar_round_op)
     798                 :            :   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a) const { return numext::round(a); }
     799                 :            :   template <typename Packet>
     800                 :            :   EIGEN_DEVICE_FUNC inline Packet packetOp(const Packet& a) const { return internal::pround(a); }
     801                 :            : };
     802                 :            : template<typename Scalar>
     803                 :            : struct functor_traits<scalar_round_op<Scalar> >
     804                 :            : {
     805                 :            :   enum {
     806                 :            :     Cost = NumTraits<Scalar>::MulCost,
     807                 :            :     PacketAccess = packet_traits<Scalar>::HasRound
     808                 :            :   };
     809                 :            : };
     810                 :            : 
     811                 :            : /** \internal
     812                 :            :   * \brief Template functor to compute the floor of a scalar
     813                 :            :   * \sa class CwiseUnaryOp, ArrayBase::floor()
     814                 :            :   */
     815                 :            : template<typename Scalar> struct scalar_floor_op {
     816                 :            :   EIGEN_EMPTY_STRUCT_CTOR(scalar_floor_op)
     817                 :            :   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a) const { return numext::floor(a); }
     818                 :            :   template <typename Packet>
     819                 :            :   EIGEN_DEVICE_FUNC inline Packet packetOp(const Packet& a) const { return internal::pfloor(a); }
     820                 :            : };
     821                 :            : template<typename Scalar>
     822                 :            : struct functor_traits<scalar_floor_op<Scalar> >
     823                 :            : {
     824                 :            :   enum {
     825                 :            :     Cost = NumTraits<Scalar>::MulCost,
     826                 :            :     PacketAccess = packet_traits<Scalar>::HasFloor
     827                 :            :   };
     828                 :            : };
     829                 :            : 
     830                 :            : /** \internal
     831                 :            :   * \brief Template functor to compute the rounded (with current rounding mode)  value of a scalar
     832                 :            :   * \sa class CwiseUnaryOp, ArrayBase::rint()
     833                 :            :   */
     834                 :            : template<typename Scalar> struct scalar_rint_op {
     835                 :            :   EIGEN_EMPTY_STRUCT_CTOR(scalar_rint_op)
     836                 :            :   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a) const { return numext::rint(a); }
     837                 :            :   template <typename Packet>
     838                 :            :   EIGEN_DEVICE_FUNC inline Packet packetOp(const Packet& a) const { return internal::print(a); }
     839                 :            : };
     840                 :            : template<typename Scalar>
     841                 :            : struct functor_traits<scalar_rint_op<Scalar> >
     842                 :            : {
     843                 :            :   enum {
     844                 :            :     Cost = NumTraits<Scalar>::MulCost,
     845                 :            :     PacketAccess = packet_traits<Scalar>::HasRint
     846                 :            :   };
     847                 :            : };
     848                 :            : 
     849                 :            : /** \internal
     850                 :            :   * \brief Template functor to compute the ceil of a scalar
     851                 :            :   * \sa class CwiseUnaryOp, ArrayBase::ceil()
     852                 :            :   */
     853                 :            : template<typename Scalar> struct scalar_ceil_op {
     854                 :            :   EIGEN_EMPTY_STRUCT_CTOR(scalar_ceil_op)
     855                 :            :   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a) const { return numext::ceil(a); }
     856                 :            :   template <typename Packet>
     857                 :            :   EIGEN_DEVICE_FUNC inline Packet packetOp(const Packet& a) const { return internal::pceil(a); }
     858                 :            : };
     859                 :            : template<typename Scalar>
     860                 :            : struct functor_traits<scalar_ceil_op<Scalar> >
     861                 :            : {
     862                 :            :   enum {
     863                 :            :     Cost = NumTraits<Scalar>::MulCost,
     864                 :            :     PacketAccess = packet_traits<Scalar>::HasCeil
     865                 :            :   };
     866                 :            : };
     867                 :            : 
     868                 :            : /** \internal
     869                 :            :   * \brief Template functor to compute whether a scalar is NaN
     870                 :            :   * \sa class CwiseUnaryOp, ArrayBase::isnan()
     871                 :            :   */
     872                 :            : template<typename Scalar> struct scalar_isnan_op {
     873                 :            :   EIGEN_EMPTY_STRUCT_CTOR(scalar_isnan_op)
     874                 :            :   typedef bool result_type;
     875                 :            :   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const {
     876                 :            : #if defined(SYCL_DEVICE_ONLY)
     877                 :            :     return numext::isnan(a);
     878                 :            : #else
     879                 :            :     return (numext::isnan)(a);
     880                 :            : #endif
     881                 :            :   }
     882                 :            : };
     883                 :            : template<typename Scalar>
     884                 :            : struct functor_traits<scalar_isnan_op<Scalar> >
     885                 :            : {
     886                 :            :   enum {
     887                 :            :     Cost = NumTraits<Scalar>::MulCost,
     888                 :            :     PacketAccess = false
     889                 :            :   };
     890                 :            : };
     891                 :            : 
     892                 :            : /** \internal
     893                 :            :   * \brief Template functor to check whether a scalar is +/-inf
     894                 :            :   * \sa class CwiseUnaryOp, ArrayBase::isinf()
     895                 :            :   */
     896                 :            : template<typename Scalar> struct scalar_isinf_op {
     897                 :            :   EIGEN_EMPTY_STRUCT_CTOR(scalar_isinf_op)
     898                 :            :   typedef bool result_type;
     899                 :            :   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const {
     900                 :            : #if defined(SYCL_DEVICE_ONLY)
     901                 :            :     return numext::isinf(a);
     902                 :            : #else
     903                 :            :     return (numext::isinf)(a);
     904                 :            : #endif
     905                 :            :   }
     906                 :            : };
     907                 :            : template<typename Scalar>
     908                 :            : struct functor_traits<scalar_isinf_op<Scalar> >
     909                 :            : {
     910                 :            :   enum {
     911                 :            :     Cost = NumTraits<Scalar>::MulCost,
     912                 :            :     PacketAccess = false
     913                 :            :   };
     914                 :            : };
     915                 :            : 
     916                 :            : /** \internal
     917                 :            :   * \brief Template functor to check whether a scalar has a finite value
     918                 :            :   * \sa class CwiseUnaryOp, ArrayBase::isfinite()
     919                 :            :   */
     920                 :            : template<typename Scalar> struct scalar_isfinite_op {
     921                 :            :   EIGEN_EMPTY_STRUCT_CTOR(scalar_isfinite_op)
     922                 :            :   typedef bool result_type;
     923                 :            :   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const {
     924                 :            : #if defined(SYCL_DEVICE_ONLY)
     925                 :            :     return numext::isfinite(a);
     926                 :            : #else
     927                 :            :     return (numext::isfinite)(a);
     928                 :            : #endif
     929                 :            :   }
     930                 :            : };
     931                 :            : template<typename Scalar>
     932                 :            : struct functor_traits<scalar_isfinite_op<Scalar> >
     933                 :            : {
     934                 :            :   enum {
     935                 :            :     Cost = NumTraits<Scalar>::MulCost,
     936                 :            :     PacketAccess = false
     937                 :            :   };
     938                 :            : };
     939                 :            : 
     940                 :            : /** \internal
     941                 :            :   * \brief Template functor to compute the logical not of a boolean
     942                 :            :   *
     943                 :            :   * \sa class CwiseUnaryOp, ArrayBase::operator!
     944                 :            :   */
     945                 :            : template<typename Scalar> struct scalar_boolean_not_op {
     946                 :            :   EIGEN_EMPTY_STRUCT_CTOR(scalar_boolean_not_op)
     947                 :            :   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE bool operator() (const bool& a) const { return !a; }
     948                 :            : };
     949                 :            : template<typename Scalar>
     950                 :            : struct functor_traits<scalar_boolean_not_op<Scalar> > {
     951                 :            :   enum {
     952                 :            :     Cost = NumTraits<bool>::AddCost,
     953                 :            :     PacketAccess = false
     954                 :            :   };
     955                 :            : };
     956                 :            : 
     957                 :            : /** \internal
     958                 :            :   * \brief Template functor to compute the signum of a scalar
     959                 :            :   * \sa class CwiseUnaryOp, Cwise::sign()
     960                 :            :   */
     961                 :            : template<typename Scalar,bool is_complex=(NumTraits<Scalar>::IsComplex!=0), bool is_integer=(NumTraits<Scalar>::IsInteger!=0) > struct scalar_sign_op;
     962                 :            : template<typename Scalar>
     963                 :            : struct scalar_sign_op<Scalar, false, true> {
     964                 :            :   EIGEN_EMPTY_STRUCT_CTOR(scalar_sign_op)
     965                 :            :   EIGEN_DEVICE_FUNC inline const Scalar operator() (const Scalar& a) const
     966                 :            :   {
     967                 :            :       return Scalar( (a>Scalar(0)) - (a<Scalar(0)) );
     968                 :            :   }
     969                 :            :   //TODO
     970                 :            :   //template <typename Packet>
     971                 :            :   //EIGEN_DEVICE_FUNC inline Packet packetOp(const Packet& a) const { return internal::psign(a); }
     972                 :            : };
     973                 :            : 
     974                 :            : template<typename Scalar>
     975                 :            : struct scalar_sign_op<Scalar, false, false> {
     976                 :            :   EIGEN_EMPTY_STRUCT_CTOR(scalar_sign_op)
     977                 :            :   EIGEN_DEVICE_FUNC inline const Scalar operator() (const Scalar& a) const
     978                 :            :   {
     979                 :            :     return (numext::isnan)(a) ? a : Scalar( (a>Scalar(0)) - (a<Scalar(0)) );
     980                 :            :   }
     981                 :            :   //TODO
     982                 :            :   //template <typename Packet>
     983                 :            :   //EIGEN_DEVICE_FUNC inline Packet packetOp(const Packet& a) const { return internal::psign(a); }
     984                 :            : };
     985                 :            : 
     986                 :            : template<typename Scalar, bool is_integer>
     987                 :            : struct scalar_sign_op<Scalar,true, is_integer> {
     988                 :            :   EIGEN_EMPTY_STRUCT_CTOR(scalar_sign_op)
     989                 :            :   EIGEN_DEVICE_FUNC inline const Scalar operator() (const Scalar& a) const
     990                 :            :   {
     991                 :            :     typedef typename NumTraits<Scalar>::Real real_type;
     992                 :            :     real_type aa = numext::abs(a);
     993                 :            :     if (aa==real_type(0))
     994                 :            :       return Scalar(0);
     995                 :            :     aa = real_type(1)/aa;
     996                 :            :     return Scalar(a.real()*aa, a.imag()*aa );
     997                 :            :   }
     998                 :            :   //TODO
     999                 :            :   //template <typename Packet>
    1000                 :            :   //EIGEN_DEVICE_FUNC inline Packet packetOp(const Packet& a) const { return internal::psign(a); }
    1001                 :            : };
    1002                 :            : template<typename Scalar>
    1003                 :            : struct functor_traits<scalar_sign_op<Scalar> >
    1004                 :            : { enum {
    1005                 :            :     Cost =
    1006                 :            :         NumTraits<Scalar>::IsComplex
    1007                 :            :         ? ( 8*NumTraits<Scalar>::MulCost  ) // roughly
    1008                 :            :         : ( 3*NumTraits<Scalar>::AddCost),
    1009                 :            :     PacketAccess = packet_traits<Scalar>::HasSign
    1010                 :            :   };
    1011                 :            : };
    1012                 :            : 
    1013                 :            : /** \internal
    1014                 :            :   * \brief Template functor to compute the logistic function of a scalar
    1015                 :            :   * \sa class CwiseUnaryOp, ArrayBase::logistic()
    1016                 :            :   */
    1017                 :            : template <typename T>
    1018                 :            : struct scalar_logistic_op {
    1019                 :            :   EIGEN_EMPTY_STRUCT_CTOR(scalar_logistic_op)
    1020                 :            :   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T operator()(const T& x) const {
    1021                 :            :     return packetOp(x);
    1022                 :            :   }
    1023                 :            : 
    1024                 :            :   template <typename Packet> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    1025                 :            :   Packet packetOp(const Packet& x) const {
    1026                 :            :     const Packet one = pset1<Packet>(T(1));
    1027                 :            :     return pdiv(one, padd(one, pexp(pnegate(x))));
    1028                 :            :   }
    1029                 :            : };
    1030                 :            : 
    1031                 :            : #ifndef EIGEN_GPU_COMPILE_PHASE
    1032                 :            : /** \internal
    1033                 :            :   * \brief Template specialization of the logistic function for float.
    1034                 :            :   *
    1035                 :            :   *  Uses just a 9/10-degree rational interpolant which
    1036                 :            :   *  interpolates 1/(1+exp(-x)) - 0.5 up to a couple of ulps in the range
    1037                 :            :   *  [-9, 18]. Below -9 we use the more accurate approximation
    1038                 :            :   *  1/(1+exp(-x)) ~= exp(x), and above 18 the logistic function is 1 withing
    1039                 :            :   *  one ulp. The shifted logistic is interpolated because it was easier to
    1040                 :            :   *  make the fit converge.
    1041                 :            :   *
    1042                 :            :   */
    1043                 :            : template <>
    1044                 :            : struct scalar_logistic_op<float> {
    1045                 :            :   EIGEN_EMPTY_STRUCT_CTOR(scalar_logistic_op)
    1046                 :            :   EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE float operator()(const float& x) const {
    1047                 :            :     return packetOp(x);
    1048                 :            :   }
    1049                 :            : 
    1050                 :            :   template <typename Packet> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    1051                 :            :   Packet packetOp(const Packet& _x) const {
    1052                 :            :     const Packet cutoff_lower = pset1<Packet>(-9.f);
    1053                 :            :     const Packet lt_mask = pcmp_lt<Packet>(_x, cutoff_lower);
    1054                 :            :     const bool any_small = predux_any(lt_mask);
    1055                 :            : 
    1056                 :            :     // The upper cut-off is the smallest x for which the rational approximation evaluates to 1.
    1057                 :            :     // Choosing this value saves us a few instructions clamping the results at the end.
    1058                 :            : #ifdef EIGEN_VECTORIZE_FMA
    1059                 :            :     const Packet cutoff_upper = pset1<Packet>(15.7243833541870117f);
    1060                 :            : #else
    1061                 :            :     const Packet cutoff_upper = pset1<Packet>(15.6437711715698242f);
    1062                 :            : #endif
    1063                 :            :     const Packet x = pmin(_x, cutoff_upper);
    1064                 :            : 
    1065                 :            :     // The monomial coefficients of the numerator polynomial (odd).
    1066                 :            :     const Packet alpha_1 = pset1<Packet>(2.48287947061529e-01f);
    1067                 :            :     const Packet alpha_3 = pset1<Packet>(8.51377133304701e-03f);
    1068                 :            :     const Packet alpha_5 = pset1<Packet>(6.08574864600143e-05f);
    1069                 :            :     const Packet alpha_7 = pset1<Packet>(1.15627324459942e-07f);
    1070                 :            :     const Packet alpha_9 = pset1<Packet>(4.37031012579801e-11f);
    1071                 :            : 
    1072                 :            :     // The monomial coefficients of the denominator polynomial (even).
    1073                 :            :     const Packet beta_0 = pset1<Packet>(9.93151921023180e-01f);
    1074                 :            :     const Packet beta_2 = pset1<Packet>(1.16817656904453e-01f);
    1075                 :            :     const Packet beta_4 = pset1<Packet>(1.70198817374094e-03f);
    1076                 :            :     const Packet beta_6 = pset1<Packet>(6.29106785017040e-06f);
    1077                 :            :     const Packet beta_8 = pset1<Packet>(5.76102136993427e-09f);
    1078                 :            :     const Packet beta_10 = pset1<Packet>(6.10247389755681e-13f);
    1079                 :            : 
    1080                 :            :     // Since the polynomials are odd/even, we need x^2.
    1081                 :            :     const Packet x2 = pmul(x, x);
    1082                 :            : 
    1083                 :            :     // Evaluate the numerator polynomial p.
    1084                 :            :     Packet p = pmadd(x2, alpha_9, alpha_7);
    1085                 :            :     p = pmadd(x2, p, alpha_5);
    1086                 :            :     p = pmadd(x2, p, alpha_3);
    1087                 :            :     p = pmadd(x2, p, alpha_1);
    1088                 :            :     p = pmul(x, p);
    1089                 :            : 
    1090                 :            :     // Evaluate the denominator polynomial q.
    1091                 :            :     Packet q = pmadd(x2, beta_10, beta_8);
    1092                 :            :     q = pmadd(x2, q, beta_6);
    1093                 :            :     q = pmadd(x2, q, beta_4);
    1094                 :            :     q = pmadd(x2, q, beta_2);
    1095                 :            :     q = pmadd(x2, q, beta_0);
    1096                 :            :     // Divide the numerator by the denominator and shift it up.
    1097                 :            :     const Packet logistic = padd(pdiv(p, q), pset1<Packet>(0.5f));
    1098                 :            :     if (EIGEN_PREDICT_FALSE(any_small)) {
    1099                 :            :       const Packet exponential = pexp(_x);
    1100                 :            :       return pselect(lt_mask, exponential, logistic);
    1101                 :            :     } else {
    1102                 :            :       return logistic;
    1103                 :            :     }
    1104                 :            :   }
    1105                 :            : };
    1106                 :            : #endif  // #ifndef EIGEN_GPU_COMPILE_PHASE
    1107                 :            : 
    1108                 :            : template <typename T>
    1109                 :            : struct functor_traits<scalar_logistic_op<T> > {
    1110                 :            :   enum {
    1111                 :            :     // The cost estimate for float here here is for the common(?) case where
    1112                 :            :     // all arguments are greater than -9.
    1113                 :            :     Cost = scalar_div_cost<T, packet_traits<T>::HasDiv>::value +
    1114                 :            :            (internal::is_same<T, float>::value
    1115                 :            :                 ? NumTraits<T>::AddCost * 15 + NumTraits<T>::MulCost * 11
    1116                 :            :                 : NumTraits<T>::AddCost * 2 +
    1117                 :            :                       functor_traits<scalar_exp_op<T> >::Cost),
    1118                 :            :     PacketAccess =
    1119                 :            :         packet_traits<T>::HasAdd && packet_traits<T>::HasDiv &&
    1120                 :            :         (internal::is_same<T, float>::value
    1121                 :            :              ? packet_traits<T>::HasMul && packet_traits<T>::HasMax &&
    1122                 :            :                    packet_traits<T>::HasMin
    1123                 :            :              : packet_traits<T>::HasNegate && packet_traits<T>::HasExp)
    1124                 :            :   };
    1125                 :            : };
    1126                 :            : 
    1127                 :            : } // end namespace internal
    1128                 :            : 
    1129                 :            : } // end namespace Eigen
    1130                 :            : 
    1131                 :            : #endif // EIGEN_FUNCTORS_H

Generated by: LCOV version 1.0