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));
250 template<
typename Func,
typename Derived>
251 struct redux_impl<Func, Derived, SliceVectorizedTraversal, NoUnrolling>
253 typedef typename Derived::Scalar Scalar;
254 typedef typename packet_traits<Scalar>::type PacketScalar;
255 typedef typename Derived::Index Index;
257 static Scalar run(
const Derived& mat,
const Func& func)
259 eigen_assert(mat.rows()>0 && mat.cols()>0 &&
"you are using an empty matrix");
260 const Index innerSize = mat.innerSize();
261 const Index outerSize = mat.outerSize();
263 packetSize = packet_traits<Scalar>::size
265 const Index packetedInnerSize = ((innerSize)/packetSize)*packetSize;
267 if(packetedInnerSize)
269 PacketScalar packet_res = mat.template packet<Unaligned>(0,0);
270 for(Index j=0; j<outerSize; ++j)
271 for(Index i=(j==0?packetSize:0); i<packetedInnerSize; i+=Index(packetSize))
272 packet_res = func.packetOp(packet_res, mat.template packetByOuterInner<Unaligned>(j,i));
274 res = func.predux(packet_res);
275 for(Index j=0; j<outerSize; ++j)
276 for(Index i=packetedInnerSize; i<innerSize; ++i)
277 res = func(res, mat.coeffByOuterInner(j,i));
282 res = redux_impl<Func, Derived, DefaultTraversal, NoUnrolling>::run(mat, func);
289 template<
typename Func,
typename Derived>
290 struct redux_impl<Func, Derived, LinearVectorizedTraversal, CompleteUnrolling>
292 typedef typename Derived::Scalar Scalar;
293 typedef typename packet_traits<Scalar>::type PacketScalar;
295 PacketSize = packet_traits<Scalar>::size,
296 Size = Derived::SizeAtCompileTime,
297 VectorizedSize = (Size / PacketSize) * PacketSize
299 static EIGEN_STRONG_INLINE Scalar run(
const Derived& mat,
const Func& func)
301 eigen_assert(mat.rows()>0 && mat.cols()>0 &&
"you are using an empty matrix");
302 Scalar res = func.predux(redux_vec_unroller<Func, Derived, 0, Size / PacketSize>::run(mat,func));
303 if (VectorizedSize != Size)
304 res = func(res,redux_novec_unroller<Func, Derived, VectorizedSize, Size-VectorizedSize>::run(mat,func));
323 template<
typename Derived>
324 template<
typename Func>
325 EIGEN_STRONG_INLINE
typename internal::result_of<Func(typename internal::traits<Derived>::Scalar)>::type
328 typedef typename internal::remove_all<typename Derived::Nested>::type ThisNested;
329 return internal::redux_impl<Func, ThisNested>
330 ::run(derived(), func);
336 template<
typename Derived>
337 EIGEN_STRONG_INLINE
typename internal::traits<Derived>::Scalar
340 return this->redux(Eigen::internal::scalar_min_op<Scalar>());
346 template<
typename Derived>
347 EIGEN_STRONG_INLINE
typename internal::traits<Derived>::Scalar
350 return this->redux(Eigen::internal::scalar_max_op<Scalar>());
357 template<
typename Derived>
358 EIGEN_STRONG_INLINE
typename internal::traits<Derived>::Scalar
361 if(SizeAtCompileTime==0 || (SizeAtCompileTime==Dynamic && size()==0))
363 return this->redux(Eigen::internal::scalar_sum_op<Scalar>());
370 template<
typename Derived>
371 EIGEN_STRONG_INLINE
typename internal::traits<Derived>::Scalar
374 return Scalar(this->redux(Eigen::internal::scalar_sum_op<Scalar>())) / Scalar(this->size());
384 template<
typename Derived>
385 EIGEN_STRONG_INLINE
typename internal::traits<Derived>::Scalar
388 if(SizeAtCompileTime==0 || (SizeAtCompileTime==Dynamic && size()==0))
390 return this->redux(Eigen::internal::scalar_product_op<Scalar>());
399 template<
typename Derived>
400 EIGEN_STRONG_INLINE
typename internal::traits<Derived>::Scalar
403 return derived().diagonal().sum();
408 #endif // EIGEN_REDUX_H
Scalar mean() const
Definition: Redux.h:372
internal::traits< Derived >::Scalar minCoeff() const
Definition: Redux.h:338
Scalar prod() const
Definition: Redux.h:386
internal::traits< Derived >::Scalar maxCoeff() const
Definition: Redux.h:348
Base class for all dense matrices, vectors, and arrays.
Definition: DenseBase.h:41
Definition: Constants.h:194
Scalar trace() const
Definition: Redux.h:401
const unsigned int ActualPacketAccessBit
Definition: Constants.h:92
Scalar sum() const
Definition: Redux.h:359
const unsigned int LinearAccessBit
Definition: Constants.h:117
Definition: Eigen_Colamd.h:54
Definition: Constants.h:192
const unsigned int DirectAccessBit
Definition: Constants.h:142
const unsigned int AlignedBit
Definition: Constants.h:147