10#ifndef EIGEN_NULLARY_FUNCTORS_H
11#define EIGEN_NULLARY_FUNCTORS_H
14#include "../InternalHeaderCheck.h"
20template <
typename Scalar>
21struct scalar_constant_op {
22 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE scalar_constant_op(
const Scalar& other) : m_other(other) {}
23 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const Scalar operator()()
const {
return m_other; }
24 template <
typename PacketType>
25 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const PacketType packetOp()
const {
26 return internal::pset1<PacketType>(m_other);
30template <
typename Scalar>
31struct functor_traits<scalar_constant_op<Scalar>> {
34 PacketAccess = packet_traits<Scalar>::Vectorizable,
39template <
typename Scalar>
40struct scalar_zero_op {
41 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE scalar_zero_op() =
default;
42 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const Scalar operator()()
const {
return Scalar(0); }
43 template <
typename PacketType>
44 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const PacketType packetOp()
const {
45 return internal::pzero<PacketType>(PacketType());
48template <
typename Scalar>
49struct functor_traits<scalar_zero_op<Scalar>> : functor_traits<scalar_constant_op<Scalar>> {};
51template <
typename Scalar>
52struct scalar_identity_op {
53 template <
typename IndexType>
54 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const Scalar operator()(IndexType row, IndexType col)
const {
55 return row == col ? Scalar(1) : Scalar(0);
58template <
typename Scalar>
59struct functor_traits<scalar_identity_op<Scalar>> {
60 enum { Cost = NumTraits<Scalar>::AddCost, PacketAccess =
false, IsRepeatable =
true };
63template <
typename Scalar,
bool IsInteger>
64struct linspaced_op_impl;
66template <
typename Scalar>
67struct linspaced_op_impl<Scalar, false> {
68 typedef typename NumTraits<Scalar>::Real RealScalar;
70 EIGEN_DEVICE_FUNC linspaced_op_impl(
const Scalar& low,
const Scalar& high,
Index num_steps)
73 m_size1(num_steps == 1 ? 1 : num_steps - 1),
74 m_step(num_steps == 1 ? Scalar() : Scalar((high - low) / RealScalar(num_steps - 1))),
75 m_flip(numext::
abs(high) < numext::
abs(low)) {}
77 template <
typename IndexType>
78 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const Scalar operator()(IndexType i)
const {
80 return (i == 0) ? m_low : Scalar(m_high - RealScalar(m_size1 - i) * m_step);
82 return (i == m_size1) ? m_high : Scalar(m_low + RealScalar(i) * m_step);
85 template <
typename Packet,
typename IndexType>
86 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const Packet packetOp(IndexType i)
const {
89 Packet low = pset1<Packet>(m_low);
90 Packet high = pset1<Packet>(m_high);
91 Packet step = pset1<Packet>(m_step);
93 Packet pi = plset<Packet>(Scalar(i - m_size1));
94 Packet res = pmadd(step, pi, high);
95 Packet mask = pcmp_lt(pzero(res), plset<Packet>(Scalar(i)));
96 return pselect<Packet>(mask, res, low);
98 Packet pi = plset<Packet>(Scalar(i));
99 Packet res = pmadd(step, pi, low);
100 Packet mask = pcmp_lt(pi, pset1<Packet>(Scalar(m_size1)));
101 return pselect<Packet>(mask, res, high);
112template <
typename Scalar>
113struct linspaced_op_impl<Scalar, true> {
114 EIGEN_DEVICE_FUNC linspaced_op_impl(
const Scalar& low,
const Scalar& high,
Index num_steps)
116 m_multiplier((high - low) / convert_index<Scalar>(num_steps <= 1 ? 1 : num_steps - 1)),
117 m_divisor(convert_index<Scalar>((high >= low ? num_steps : -num_steps) + (high - low)) /
118 ((numext::
abs(high - low) + 1) == 0 ? 1 : (numext::
abs(high - low) + 1))),
119 m_use_divisor(num_steps > 1 && (numext::
abs(high - low) + 1) < num_steps) {}
121 template <
typename IndexType>
122 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const Scalar operator()(IndexType i)
const {
124 return m_low + convert_index<Scalar>(i) / m_divisor;
126 return m_low + convert_index<Scalar>(i) * m_multiplier;
130 const Scalar m_multiplier;
131 const Scalar m_divisor;
132 const bool m_use_divisor;
140template <
typename Scalar>
142template <
typename Scalar>
143struct functor_traits<linspaced_op<Scalar>> {
146 PacketAccess = (!NumTraits<Scalar>::IsInteger) && packet_traits<Scalar>::HasSetLinear,
152template <
typename Scalar>
154 EIGEN_DEVICE_FUNC linspaced_op(
const Scalar& low,
const Scalar& high,
Index num_steps)
155 : impl((num_steps == 1 ? high : low), high, num_steps) {}
157 template <
typename IndexType>
158 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const Scalar operator()(IndexType i)
const {
162 template <
typename Packet,
typename IndexType>
163 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const Packet packetOp(IndexType i)
const {
164 return impl.template packetOp<Packet>(i);
169 const linspaced_op_impl<Scalar, NumTraits<Scalar>::IsInteger> impl;
172template <
typename Scalar>
173struct equalspaced_op {
174 typedef typename NumTraits<Scalar>::Real RealScalar;
176 EIGEN_DEVICE_FUNC equalspaced_op(
const Scalar& start,
const Scalar& step) : m_start(start), m_step(step) {}
177 template <
typename IndexType>
178 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const Scalar operator()(IndexType i)
const {
179 return m_start + m_step *
static_cast<Scalar
>(i);
181 template <
typename Packet,
typename IndexType>
182 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Packet packetOp(IndexType i)
const {
183 const Packet cst_start = pset1<Packet>(m_start);
184 const Packet cst_step = pset1<Packet>(m_step);
185 const Packet cst_lin0 = plset<Packet>(Scalar(0));
186 const Packet cst_offset = pmadd(cst_lin0, cst_step, cst_start);
188 Packet i_packet = pset1<Packet>(
static_cast<Scalar
>(i));
189 return pmadd(i_packet, cst_step, cst_offset);
191 const Scalar m_start;
195template <
typename Scalar>
196struct functor_traits<equalspaced_op<Scalar>> {
198 Cost = NumTraits<Scalar>::AddCost + NumTraits<Scalar>::MulCost,
200 packet_traits<Scalar>::HasSetLinear && packet_traits<Scalar>::HasMul && packet_traits<Scalar>::HasAdd,
209template <
typename Functor>
210struct functor_has_linear_access {
211 enum { ret = !has_binary_operator<Functor>::value };
216#if !(EIGEN_COMP_MSVC || EIGEN_COMP_GNUC || (EIGEN_COMP_ICC >= 1600))
217template <
typename Scalar,
typename IndexType>
218struct has_nullary_operator<scalar_constant_op<Scalar>, IndexType> {
221template <
typename Scalar,
typename IndexType>
222struct has_unary_operator<scalar_constant_op<Scalar>, IndexType> {
225template <
typename Scalar,
typename IndexType>
226struct has_binary_operator<scalar_constant_op<Scalar>, IndexType> {
230template <
typename Scalar,
typename IndexType>
231struct has_nullary_operator<scalar_identity_op<Scalar>, IndexType> {
234template <
typename Scalar,
typename IndexType>
235struct has_unary_operator<scalar_identity_op<Scalar>, IndexType> {
238template <
typename Scalar,
typename IndexType>
239struct has_binary_operator<scalar_identity_op<Scalar>, IndexType> {
243template <
typename Scalar,
typename IndexType>
244struct has_nullary_operator<linspaced_op<Scalar>, IndexType> {
247template <
typename Scalar,
typename IndexType>
248struct has_unary_operator<linspaced_op<Scalar>, IndexType> {
251template <
typename Scalar,
typename IndexType>
252struct has_binary_operator<linspaced_op<Scalar>, IndexType> {
256template <
typename Scalar,
typename IndexType>
257struct has_nullary_operator<scalar_random_op<Scalar>, IndexType> {
260template <
typename Scalar,
typename IndexType>
261struct has_unary_operator<scalar_random_op<Scalar>, IndexType> {
264template <
typename Scalar,
typename IndexType>
265struct has_binary_operator<scalar_random_op<Scalar>, IndexType> {
Namespace containing all symbols from the Eigen library.
Definition B01_Experimental.dox:1
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_abs_op< typename Derived::Scalar >, const Derived > abs(const Eigen::ArrayBase< Derived > &x)
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition Meta.h:82