26 template<
typename Func,
typename Derived>
31 PacketSize = packet_traits<typename Derived::Scalar>::size,
32 InnerMaxSize = int(Derived::IsRowMajor)
33 ? Derived::MaxColsAtCompileTime
34 : Derived::MaxRowsAtCompileTime
39 && (functor_traits<Func>::PacketAccess),
40 MayLinearVectorize = MightVectorize && (int(Derived::Flags)&
LinearAccessBit),
41 MaySliceVectorize = MightVectorize &&
int(InnerMaxSize)>=3*PacketSize
46 Traversal = int(MayLinearVectorize) ? int(LinearVectorizedTraversal)
47 : int(MaySliceVectorize) ? int(SliceVectorizedTraversal)
48 : int(DefaultTraversal)
53 Cost = ( Derived::SizeAtCompileTime ==
Dynamic
54 || Derived::CoeffReadCost ==
Dynamic
55 || (Derived::SizeAtCompileTime!=1 && functor_traits<Func>::Cost ==
Dynamic)
57 : Derived::SizeAtCompileTime * Derived::CoeffReadCost
58 + (Derived::SizeAtCompileTime-1) * functor_traits<Func>::Cost,
59 UnrollingLimit = EIGEN_UNROLLING_LIMIT * (
int(Traversal) == int(DefaultTraversal) ? 1 : int(PacketSize))
64 Unrolling = Cost !=
Dynamic && Cost <= UnrollingLimit
76 template<
typename Func,
typename Derived,
int Start,
int Length>
77 struct redux_novec_unroller
83 typedef typename Derived::Scalar Scalar;
85 static EIGEN_STRONG_INLINE Scalar run(
const Derived &mat,
const Func& func)
87 return func(redux_novec_unroller<Func, Derived, Start, HalfLength>::run(mat,func),
88 redux_novec_unroller<Func, Derived, Start+HalfLength, Length-HalfLength>::run(mat,func));
92 template<
typename Func,
typename Derived,
int Start>
93 struct redux_novec_unroller<Func, Derived, Start, 1>
96 outer = Start / Derived::InnerSizeAtCompileTime,
97 inner = Start % Derived::InnerSizeAtCompileTime
100 typedef typename Derived::Scalar Scalar;
102 static EIGEN_STRONG_INLINE Scalar run(
const Derived &mat,
const Func&)
104 return mat.coeffByOuterInner(outer, inner);
111 template<
typename Func,
typename Derived,
int Start>
112 struct redux_novec_unroller<Func, Derived, Start, 0>
114 typedef typename Derived::Scalar Scalar;
115 static EIGEN_STRONG_INLINE Scalar run(
const Derived&,
const Func&) {
return Scalar(); }
120 template<
typename Func,
typename Derived,
int Start,
int Length>
121 struct redux_vec_unroller
124 PacketSize = packet_traits<typename Derived::Scalar>::size,
125 HalfLength = Length/2
128 typedef typename Derived::Scalar Scalar;
129 typedef typename packet_traits<Scalar>::type PacketScalar;
131 static EIGEN_STRONG_INLINE PacketScalar run(
const Derived &mat,
const Func& func)
133 return func.packetOp(
134 redux_vec_unroller<Func, Derived, Start, HalfLength>::run(mat,func),
135 redux_vec_unroller<Func, Derived, Start+HalfLength, Length-HalfLength>::run(mat,func) );
139 template<
typename Func,
typename Derived,
int Start>
140 struct redux_vec_unroller<Func, Derived, Start, 1>
143 index = Start * packet_traits<typename Derived::Scalar>::size,
144 outer = index / int(Derived::InnerSizeAtCompileTime),
145 inner = index % int(Derived::InnerSizeAtCompileTime),
149 typedef typename Derived::Scalar Scalar;
150 typedef typename packet_traits<Scalar>::type PacketScalar;
152 static EIGEN_STRONG_INLINE PacketScalar run(
const Derived &mat,
const Func&)
154 return mat.template packetByOuterInner<alignment>(outer, inner);
162 template<
typename Func,
typename Derived,
163 int Traversal = redux_traits<Func, Derived>::Traversal,
164 int Unrolling = redux_traits<Func, Derived>::Unrolling
168 template<
typename Func,
typename Derived>
169 struct redux_impl<Func, Derived, DefaultTraversal, NoUnrolling>
171 typedef typename Derived::Scalar Scalar;
172 typedef typename Derived::Index Index;
173 static EIGEN_STRONG_INLINE Scalar run(
const Derived& mat,
const Func& func)
175 eigen_assert(mat.rows()>0 && mat.cols()>0 &&
"you are using an empty matrix");
177 res = mat.coeffByOuterInner(0, 0);
178 for(Index i = 1; i < mat.innerSize(); ++i)
179 res = func(res, mat.coeffByOuterInner(0, i));
180 for(Index i = 1; i < mat.outerSize(); ++i)
181 for(Index j = 0; j < mat.innerSize(); ++j)
182 res = func(res, mat.coeffByOuterInner(i, j));
187 template<
typename Func,
typename Derived>
188 struct redux_impl<Func,Derived, DefaultTraversal, CompleteUnrolling>
189 :
public redux_novec_unroller<Func,Derived, 0, Derived::SizeAtCompileTime>
192 template<
typename Func,
typename Derived>
193 struct redux_impl<Func, Derived, LinearVectorizedTraversal, NoUnrolling>
195 typedef typename Derived::Scalar Scalar;
196 typedef typename packet_traits<Scalar>::type PacketScalar;
197 typedef typename Derived::Index Index;
199 static Scalar run(
const Derived& mat,
const Func& func)
201 const Index size = mat.size();
202 eigen_assert(size &&
"you are using an empty matrix");
203 const Index packetSize = packet_traits<Scalar>::size;
204 const Index alignedStart = internal::first_aligned(mat);
209 const Index alignedSize2 = ((size-alignedStart)/(2*packetSize))*(2*packetSize);
210 const Index alignedSize = ((size-alignedStart)/(packetSize))*(packetSize);
211 const Index alignedEnd2 = alignedStart + alignedSize2;
212 const Index alignedEnd = alignedStart + alignedSize;
216 PacketScalar packet_res0 = mat.template packet<alignment>(alignedStart);
217 if(alignedSize>packetSize)
219 PacketScalar packet_res1 = mat.template packet<alignment>(alignedStart+packetSize);
220 for(Index index = alignedStart + 2*packetSize; index < alignedEnd2; index += 2*packetSize)
222 packet_res0 = func.packetOp(packet_res0, mat.template packet<alignment>(index));
223 packet_res1 = func.packetOp(packet_res1, mat.template packet<alignment>(index+packetSize));
226 packet_res0 = func.packetOp(packet_res0,packet_res1);
227 if(alignedEnd>alignedEnd2)
228 packet_res0 = func.packetOp(packet_res0, mat.template packet<alignment>(alignedEnd2));
230 res = func.predux(packet_res0);
232 for(Index index = 0; index < alignedStart; ++index)
233 res = func(res,mat.coeff(index));
235 for(Index index = alignedEnd; index < size; ++index)
236 res = func(res,mat.coeff(index));
242 for(Index index = 1; index < size; ++index)
243 res = func(res,mat.coeff(index));
251 template<
typename Func,
typename Derived,
int Unrolling>
252 struct redux_impl<Func, Derived, SliceVectorizedTraversal, Unrolling>
254 typedef typename Derived::Scalar Scalar;
255 typedef typename packet_traits<Scalar>::type PacketScalar;
256 typedef typename Derived::Index Index;
258 static Scalar run(
const Derived& mat,
const Func& func)
260 eigen_assert(mat.rows()>0 && mat.cols()>0 &&
"you are using an empty matrix");
261 const Index innerSize = mat.innerSize();
262 const Index outerSize = mat.outerSize();
264 packetSize = packet_traits<Scalar>::size
266 const Index packetedInnerSize = ((innerSize)/packetSize)*packetSize;
268 if(packetedInnerSize)
270 PacketScalar packet_res = mat.template packet<Unaligned>(0,0);
271 for(Index j=0; j<outerSize; ++j)
272 for(Index i=(j==0?packetSize:0); i<packetedInnerSize; i+=Index(packetSize))
273 packet_res = func.packetOp(packet_res, mat.template packetByOuterInner<Unaligned>(j,i));
275 res = func.predux(packet_res);
276 for(Index j=0; j<outerSize; ++j)
277 for(Index i=packetedInnerSize; i<innerSize; ++i)
278 res = func(res, mat.coeffByOuterInner(j,i));
283 res = redux_impl<Func, Derived, DefaultTraversal, NoUnrolling>::run(mat, func);
290 template<
typename Func,
typename Derived>
291 struct redux_impl<Func, Derived, LinearVectorizedTraversal, CompleteUnrolling>
293 typedef typename Derived::Scalar Scalar;
294 typedef typename packet_traits<Scalar>::type PacketScalar;
296 PacketSize = packet_traits<Scalar>::size,
297 Size = Derived::SizeAtCompileTime,
298 VectorizedSize = (Size / PacketSize) * PacketSize
300 static EIGEN_STRONG_INLINE Scalar run(
const Derived& mat,
const Func& func)
302 eigen_assert(mat.rows()>0 && mat.cols()>0 &&
"you are using an empty matrix");
303 Scalar res = func.predux(redux_vec_unroller<Func, Derived, 0, Size / PacketSize>::run(mat,func));
304 if (VectorizedSize != Size)
305 res = func(res,redux_novec_unroller<Func, Derived, VectorizedSize, Size-VectorizedSize>::run(mat,func));
324 template<
typename Derived>
325 template<
typename Func>
326 EIGEN_STRONG_INLINE
typename internal::result_of<Func(typename internal::traits<Derived>::Scalar)>::type
329 typedef typename internal::remove_all<typename Derived::Nested>::type ThisNested;
330 return internal::redux_impl<Func, ThisNested>
331 ::run(derived(), func);
337 template<
typename Derived>
338 EIGEN_STRONG_INLINE
typename internal::traits<Derived>::Scalar
341 return this->redux(Eigen::internal::scalar_min_op<Scalar>());
347 template<
typename Derived>
348 EIGEN_STRONG_INLINE
typename internal::traits<Derived>::Scalar
351 return this->redux(Eigen::internal::scalar_max_op<Scalar>());
358 template<
typename Derived>
359 EIGEN_STRONG_INLINE
typename internal::traits<Derived>::Scalar
362 if(SizeAtCompileTime==0 || (SizeAtCompileTime==
Dynamic && size()==0))
364 return this->redux(Eigen::internal::scalar_sum_op<Scalar>());
371 template<
typename Derived>
372 EIGEN_STRONG_INLINE
typename internal::traits<Derived>::Scalar
375 return Scalar(this->redux(Eigen::internal::scalar_sum_op<Scalar>())) / Scalar(this->size());
385 template<
typename Derived>
386 EIGEN_STRONG_INLINE
typename internal::traits<Derived>::Scalar
389 if(SizeAtCompileTime==0 || (SizeAtCompileTime==
Dynamic && size()==0))
391 return this->redux(Eigen::internal::scalar_product_op<Scalar>());
400 template<
typename Derived>
401 EIGEN_STRONG_INLINE
typename internal::traits<Derived>::Scalar
404 return derived().diagonal().sum();
409 #endif // EIGEN_REDUX_H
Scalar mean() const
Definition: Redux.h:373
internal::traits< Derived >::Scalar minCoeff() const
Definition: Redux.h:339
Scalar prod() const
Definition: Redux.h:387
const int Dynamic
Definition: Constants.h:21
internal::traits< Derived >::Scalar maxCoeff() const
Definition: Redux.h:349
Base class for all dense matrices, vectors, and arrays.
Definition: DenseBase.h:41
Definition: Constants.h:194
Scalar trace() const
Definition: Redux.h:402
const unsigned int ActualPacketAccessBit
Definition: Constants.h:92
Scalar sum() const
Definition: Redux.h:360
const unsigned int LinearAccessBit
Definition: Constants.h:117
Definition: Constants.h:192
const unsigned int DirectAccessBit
Definition: Constants.h:142
const unsigned int AlignedBit
Definition: Constants.h:147