Lines 119-168
struct product_evaluator<Product<Lhs, Rh
Link Here
|
119 |
} |
119 |
} |
120 |
|
120 |
|
121 |
protected: |
121 |
protected: |
122 |
PlainObject m_result; |
122 |
PlainObject m_result; |
123 |
}; |
123 |
}; |
124 |
|
124 |
|
125 |
// Dense = Product |
125 |
// Dense = Product |
126 |
template< typename DstXprType, typename Lhs, typename Rhs, int Options, typename Scalar> |
126 |
template< typename DstXprType, typename Lhs, typename Rhs, int Options, typename Scalar> |
127 |
struct Assignment<DstXprType, Product<Lhs,Rhs,Options>, internal::assign_op<Scalar>, Dense2Dense, |
127 |
struct Assignment<DstXprType, Product<Lhs,Rhs,Options>, internal::assign_op<Scalar,typename Product<Lhs,Rhs,Options>::Scalar>, Dense2Dense, |
128 |
typename enable_if<(Options==DefaultProduct || Options==AliasFreeProduct),Scalar>::type> |
128 |
typename enable_if<(Options==DefaultProduct || Options==AliasFreeProduct),Scalar>::type> |
129 |
{ |
129 |
{ |
130 |
typedef Product<Lhs,Rhs,Options> SrcXprType; |
130 |
typedef Product<Lhs,Rhs,Options> SrcXprType; |
131 |
static EIGEN_STRONG_INLINE |
131 |
static EIGEN_STRONG_INLINE |
132 |
void run(DstXprType &dst, const SrcXprType &src, const internal::assign_op<Scalar> &) |
132 |
void run(DstXprType &dst, const SrcXprType &src, const internal::assign_op<Scalar,typename SrcXprType::Scalar> &) |
133 |
{ |
133 |
{ |
134 |
// FIXME shall we handle nested_eval here? |
134 |
// FIXME shall we handle nested_eval here? |
135 |
generic_product_impl<Lhs, Rhs>::evalTo(dst, src.lhs(), src.rhs()); |
135 |
generic_product_impl<Lhs, Rhs>::evalTo(dst, src.lhs(), src.rhs()); |
136 |
} |
136 |
} |
137 |
}; |
137 |
}; |
138 |
|
138 |
|
139 |
// Dense += Product |
139 |
// Dense += Product |
140 |
template< typename DstXprType, typename Lhs, typename Rhs, int Options, typename Scalar> |
140 |
template< typename DstXprType, typename Lhs, typename Rhs, int Options, typename Scalar> |
141 |
struct Assignment<DstXprType, Product<Lhs,Rhs,Options>, internal::add_assign_op<Scalar>, Dense2Dense, |
141 |
struct Assignment<DstXprType, Product<Lhs,Rhs,Options>, internal::add_assign_op<Scalar,typename Product<Lhs,Rhs,Options>::Scalar>, Dense2Dense, |
142 |
typename enable_if<(Options==DefaultProduct || Options==AliasFreeProduct),Scalar>::type> |
142 |
typename enable_if<(Options==DefaultProduct || Options==AliasFreeProduct),Scalar>::type> |
143 |
{ |
143 |
{ |
144 |
typedef Product<Lhs,Rhs,Options> SrcXprType; |
144 |
typedef Product<Lhs,Rhs,Options> SrcXprType; |
145 |
static EIGEN_STRONG_INLINE |
145 |
static EIGEN_STRONG_INLINE |
146 |
void run(DstXprType &dst, const SrcXprType &src, const internal::add_assign_op<Scalar> &) |
146 |
void run(DstXprType &dst, const SrcXprType &src, const internal::add_assign_op<Scalar,typename SrcXprType::Scalar> &) |
147 |
{ |
147 |
{ |
148 |
// FIXME shall we handle nested_eval here? |
148 |
// FIXME shall we handle nested_eval here? |
149 |
generic_product_impl<Lhs, Rhs>::addTo(dst, src.lhs(), src.rhs()); |
149 |
generic_product_impl<Lhs, Rhs>::addTo(dst, src.lhs(), src.rhs()); |
150 |
} |
150 |
} |
151 |
}; |
151 |
}; |
152 |
|
152 |
|
153 |
// Dense -= Product |
153 |
// Dense -= Product |
154 |
template< typename DstXprType, typename Lhs, typename Rhs, int Options, typename Scalar> |
154 |
template< typename DstXprType, typename Lhs, typename Rhs, int Options, typename Scalar> |
155 |
struct Assignment<DstXprType, Product<Lhs,Rhs,Options>, internal::sub_assign_op<Scalar>, Dense2Dense, |
155 |
struct Assignment<DstXprType, Product<Lhs,Rhs,Options>, internal::sub_assign_op<Scalar,typename Product<Lhs,Rhs,Options>::Scalar>, Dense2Dense, |
156 |
typename enable_if<(Options==DefaultProduct || Options==AliasFreeProduct),Scalar>::type> |
156 |
typename enable_if<(Options==DefaultProduct || Options==AliasFreeProduct),Scalar>::type> |
157 |
{ |
157 |
{ |
158 |
typedef Product<Lhs,Rhs,Options> SrcXprType; |
158 |
typedef Product<Lhs,Rhs,Options> SrcXprType; |
159 |
static EIGEN_STRONG_INLINE |
159 |
static EIGEN_STRONG_INLINE |
160 |
void run(DstXprType &dst, const SrcXprType &src, const internal::sub_assign_op<Scalar> &) |
160 |
void run(DstXprType &dst, const SrcXprType &src, const internal::sub_assign_op<Scalar,typename SrcXprType::Scalar> &) |
161 |
{ |
161 |
{ |
162 |
// FIXME shall we handle nested_eval here? |
162 |
// FIXME shall we handle nested_eval here? |
163 |
generic_product_impl<Lhs, Rhs>::subTo(dst, src.lhs(), src.rhs()); |
163 |
generic_product_impl<Lhs, Rhs>::subTo(dst, src.lhs(), src.rhs()); |
164 |
} |
164 |
} |
165 |
}; |
165 |
}; |
166 |
|
166 |
|
167 |
|
167 |
|
168 |
// Dense ?= scalar * Product |
168 |
// Dense ?= scalar * Product |
Lines 182-228
struct Assignment<DstXprType, CwiseUnary
Link Here
|
182 |
}; |
182 |
}; |
183 |
|
183 |
|
184 |
//---------------------------------------- |
184 |
//---------------------------------------- |
185 |
// Catch "Dense ?= xpr + Product<>" expression to save one temporary |
185 |
// Catch "Dense ?= xpr + Product<>" expression to save one temporary |
186 |
// FIXME we could probably enable these rules for any product, i.e., not only Dense and DefaultProduct |
186 |
// FIXME we could probably enable these rules for any product, i.e., not only Dense and DefaultProduct |
187 |
// TODO enable it for "Dense ?= xpr - Product<>" as well. |
187 |
// TODO enable it for "Dense ?= xpr - Product<>" as well. |
188 |
|
188 |
|
189 |
template<typename OtherXpr, typename Lhs, typename Rhs> |
189 |
template<typename OtherXpr, typename Lhs, typename Rhs> |
190 |
struct evaluator_assume_aliasing<CwiseBinaryOp<internal::scalar_sum_op<typename OtherXpr::Scalar>, const OtherXpr, |
190 |
struct evaluator_assume_aliasing<CwiseBinaryOp<internal::scalar_sum_op<typename OtherXpr::Scalar,typename Product<Lhs,Rhs,DefaultProduct>::Scalar>, const OtherXpr, |
191 |
const Product<Lhs,Rhs,DefaultProduct> >, DenseShape > { |
191 |
const Product<Lhs,Rhs,DefaultProduct> >, DenseShape > { |
192 |
static const bool value = true; |
192 |
static const bool value = true; |
193 |
}; |
193 |
}; |
194 |
|
194 |
|
195 |
template<typename DstXprType, typename OtherXpr, typename ProductType, typename Scalar, typename Func1, typename Func2> |
195 |
template<typename DstXprType, typename OtherXpr, typename ProductType, typename Func1, typename Func2> |
196 |
struct assignment_from_xpr_plus_product |
196 |
struct assignment_from_xpr_plus_product |
197 |
{ |
197 |
{ |
198 |
typedef CwiseBinaryOp<internal::scalar_sum_op<Scalar>, const OtherXpr, const ProductType> SrcXprType; |
198 |
typedef CwiseBinaryOp<internal::scalar_sum_op<typename OtherXpr::Scalar,typename ProductType::Scalar>, const OtherXpr, const ProductType> SrcXprType; |
|
|
199 |
template<typename InitialFunc> |
199 |
static EIGEN_STRONG_INLINE |
200 |
static EIGEN_STRONG_INLINE |
200 |
void run(DstXprType &dst, const SrcXprType &src, const Func1& func) |
201 |
void run(DstXprType &dst, const SrcXprType &src, const InitialFunc& /*func*/) |
201 |
{ |
202 |
{ |
202 |
call_assignment_no_alias(dst, src.lhs(), func); |
203 |
call_assignment_no_alias(dst, src.lhs(), Func1()); |
203 |
call_assignment_no_alias(dst, src.rhs(), Func2()); |
204 |
call_assignment_no_alias(dst, src.rhs(), Func2()); |
204 |
} |
205 |
} |
205 |
}; |
206 |
}; |
206 |
|
207 |
|
207 |
template< typename DstXprType, typename OtherXpr, typename Lhs, typename Rhs, typename Scalar> |
208 |
template< typename DstXprType, typename OtherXpr, typename Lhs, typename Rhs, typename DstScalar, typename SrcScalar, typename OtherScalar,typename ProdScalar> |
208 |
struct Assignment<DstXprType, CwiseBinaryOp<internal::scalar_sum_op<Scalar>, const OtherXpr, |
209 |
struct Assignment<DstXprType, CwiseBinaryOp<internal::scalar_sum_op<OtherScalar,ProdScalar>, const OtherXpr, |
209 |
const Product<Lhs,Rhs,DefaultProduct> >, internal::assign_op<Scalar>, Dense2Dense> |
210 |
const Product<Lhs,Rhs,DefaultProduct> >, internal::assign_op<DstScalar,SrcScalar>, Dense2Dense> |
210 |
: assignment_from_xpr_plus_product<DstXprType, OtherXpr, Product<Lhs,Rhs,DefaultProduct>, Scalar, internal::assign_op<Scalar>, internal::add_assign_op<Scalar> > |
211 |
: assignment_from_xpr_plus_product<DstXprType, OtherXpr, Product<Lhs,Rhs,DefaultProduct>, internal::assign_op<DstScalar,OtherScalar>, internal::add_assign_op<DstScalar,ProdScalar> > |
211 |
{}; |
212 |
{}; |
212 |
template< typename DstXprType, typename OtherXpr, typename Lhs, typename Rhs, typename Scalar> |
213 |
template< typename DstXprType, typename OtherXpr, typename Lhs, typename Rhs, typename DstScalar, typename SrcScalar, typename OtherScalar,typename ProdScalar> |
213 |
struct Assignment<DstXprType, CwiseBinaryOp<internal::scalar_sum_op<Scalar>, const OtherXpr, |
214 |
struct Assignment<DstXprType, CwiseBinaryOp<internal::scalar_sum_op<OtherScalar,ProdScalar>, const OtherXpr, |
214 |
const Product<Lhs,Rhs,DefaultProduct> >, internal::add_assign_op<Scalar>, Dense2Dense> |
215 |
const Product<Lhs,Rhs,DefaultProduct> >, internal::add_assign_op<DstScalar,SrcScalar>, Dense2Dense> |
215 |
: assignment_from_xpr_plus_product<DstXprType, OtherXpr, Product<Lhs,Rhs,DefaultProduct>, Scalar, internal::add_assign_op<Scalar>, internal::add_assign_op<Scalar> > |
216 |
: assignment_from_xpr_plus_product<DstXprType, OtherXpr, Product<Lhs,Rhs,DefaultProduct>, internal::add_assign_op<DstScalar,OtherScalar>, internal::add_assign_op<DstScalar,ProdScalar> > |
216 |
{}; |
217 |
{}; |
217 |
template< typename DstXprType, typename OtherXpr, typename Lhs, typename Rhs, typename Scalar> |
218 |
template< typename DstXprType, typename OtherXpr, typename Lhs, typename Rhs, typename DstScalar, typename SrcScalar, typename OtherScalar,typename ProdScalar> |
218 |
struct Assignment<DstXprType, CwiseBinaryOp<internal::scalar_sum_op<Scalar>, const OtherXpr, |
219 |
struct Assignment<DstXprType, CwiseBinaryOp<internal::scalar_sum_op<OtherScalar,ProdScalar>, const OtherXpr, |
219 |
const Product<Lhs,Rhs,DefaultProduct> >, internal::sub_assign_op<Scalar>, Dense2Dense> |
220 |
const Product<Lhs,Rhs,DefaultProduct> >, internal::sub_assign_op<DstScalar,SrcScalar>, Dense2Dense> |
220 |
: assignment_from_xpr_plus_product<DstXprType, OtherXpr, Product<Lhs,Rhs,DefaultProduct>, Scalar, internal::sub_assign_op<Scalar>, internal::sub_assign_op<Scalar> > |
221 |
: assignment_from_xpr_plus_product<DstXprType, OtherXpr, Product<Lhs,Rhs,DefaultProduct>, internal::sub_assign_op<DstScalar,OtherScalar>, internal::sub_assign_op<DstScalar,ProdScalar> > |
221 |
{}; |
222 |
{}; |
222 |
//---------------------------------------- |
223 |
//---------------------------------------- |
223 |
|
224 |
|
224 |
template<typename Lhs, typename Rhs> |
225 |
template<typename Lhs, typename Rhs> |
225 |
struct generic_product_impl<Lhs,Rhs,DenseShape,DenseShape,InnerProduct> |
226 |
struct generic_product_impl<Lhs,Rhs,DenseShape,DenseShape,InnerProduct> |
226 |
{ |
227 |
{ |
227 |
template<typename Dst> |
228 |
template<typename Dst> |
228 |
static inline void evalTo(Dst& dst, const Lhs& lhs, const Rhs& rhs) |
229 |
static inline void evalTo(Dst& dst, const Lhs& lhs, const Rhs& rhs) |
Lines 364-394
struct generic_product_impl<Lhs,Rhs,Dens
Link Here
|
364 |
{ |
365 |
{ |
365 |
typedef typename Product<Lhs,Rhs>::Scalar Scalar; |
366 |
typedef typename Product<Lhs,Rhs>::Scalar Scalar; |
366 |
|
367 |
|
367 |
template<typename Dst> |
368 |
template<typename Dst> |
368 |
static EIGEN_STRONG_INLINE void evalTo(Dst& dst, const Lhs& lhs, const Rhs& rhs) |
369 |
static EIGEN_STRONG_INLINE void evalTo(Dst& dst, const Lhs& lhs, const Rhs& rhs) |
369 |
{ |
370 |
{ |
370 |
// Same as: dst.noalias() = lhs.lazyProduct(rhs); |
371 |
// Same as: dst.noalias() = lhs.lazyProduct(rhs); |
371 |
// but easier on the compiler side |
372 |
// but easier on the compiler side |
372 |
call_assignment_no_alias(dst, lhs.lazyProduct(rhs), internal::assign_op<Scalar>()); |
373 |
call_assignment_no_alias(dst, lhs.lazyProduct(rhs), internal::assign_op<typename Dst::Scalar,Scalar>()); |
373 |
} |
374 |
} |
374 |
|
375 |
|
375 |
template<typename Dst> |
376 |
template<typename Dst> |
376 |
static EIGEN_STRONG_INLINE void addTo(Dst& dst, const Lhs& lhs, const Rhs& rhs) |
377 |
static EIGEN_STRONG_INLINE void addTo(Dst& dst, const Lhs& lhs, const Rhs& rhs) |
377 |
{ |
378 |
{ |
378 |
// dst.noalias() += lhs.lazyProduct(rhs); |
379 |
// dst.noalias() += lhs.lazyProduct(rhs); |
379 |
call_assignment_no_alias(dst, lhs.lazyProduct(rhs), internal::add_assign_op<Scalar>()); |
380 |
call_assignment_no_alias(dst, lhs.lazyProduct(rhs), internal::add_assign_op<typename Dst::Scalar,Scalar>()); |
380 |
} |
381 |
} |
381 |
|
382 |
|
382 |
template<typename Dst> |
383 |
template<typename Dst> |
383 |
static EIGEN_STRONG_INLINE void subTo(Dst& dst, const Lhs& lhs, const Rhs& rhs) |
384 |
static EIGEN_STRONG_INLINE void subTo(Dst& dst, const Lhs& lhs, const Rhs& rhs) |
384 |
{ |
385 |
{ |
385 |
// dst.noalias() -= lhs.lazyProduct(rhs); |
386 |
// dst.noalias() -= lhs.lazyProduct(rhs); |
386 |
call_assignment_no_alias(dst, lhs.lazyProduct(rhs), internal::sub_assign_op<Scalar>()); |
387 |
call_assignment_no_alias(dst, lhs.lazyProduct(rhs), internal::sub_assign_op<typename Dst::Scalar,Scalar>()); |
387 |
} |
388 |
} |
388 |
|
389 |
|
389 |
// template<typename Dst> |
390 |
// template<typename Dst> |
390 |
// static inline void scaleAndAddTo(Dst& dst, const Lhs& lhs, const Rhs& rhs, const Scalar& alpha) |
391 |
// static inline void scaleAndAddTo(Dst& dst, const Lhs& lhs, const Rhs& rhs, const Scalar& alpha) |
391 |
// { dst.noalias() += alpha * lhs.lazyProduct(rhs); } |
392 |
// { dst.noalias() += alpha * lhs.lazyProduct(rhs); } |
392 |
}; |
393 |
}; |
393 |
|
394 |
|
394 |
// This specialization enforces the use of a coefficient-based evaluation strategy |
395 |
// This specialization enforces the use of a coefficient-based evaluation strategy |
Lines 730-746
struct generic_product_impl<Lhs,Rhs,Dens
Link Here
|
730 |
/*************************************************************************** |
731 |
/*************************************************************************** |
731 |
* Diagonal products |
732 |
* Diagonal products |
732 |
***************************************************************************/ |
733 |
***************************************************************************/ |
733 |
|
734 |
|
734 |
template<typename MatrixType, typename DiagonalType, typename Derived, int ProductOrder> |
735 |
template<typename MatrixType, typename DiagonalType, typename Derived, int ProductOrder> |
735 |
struct diagonal_product_evaluator_base |
736 |
struct diagonal_product_evaluator_base |
736 |
: evaluator_base<Derived> |
737 |
: evaluator_base<Derived> |
737 |
{ |
738 |
{ |
738 |
typedef typename scalar_product_traits<typename MatrixType::Scalar, typename DiagonalType::Scalar>::ReturnType Scalar; |
739 |
typedef typename ScalarBinaryOpTraits<typename MatrixType::Scalar, typename DiagonalType::Scalar>::ReturnType Scalar; |
739 |
public: |
740 |
public: |
740 |
enum { |
741 |
enum { |
741 |
CoeffReadCost = NumTraits<Scalar>::MulCost + evaluator<MatrixType>::CoeffReadCost + evaluator<DiagonalType>::CoeffReadCost, |
742 |
CoeffReadCost = NumTraits<Scalar>::MulCost + evaluator<MatrixType>::CoeffReadCost + evaluator<DiagonalType>::CoeffReadCost, |
742 |
|
743 |
|
743 |
MatrixFlags = evaluator<MatrixType>::Flags, |
744 |
MatrixFlags = evaluator<MatrixType>::Flags, |
744 |
DiagFlags = evaluator<DiagonalType>::Flags, |
745 |
DiagFlags = evaluator<DiagonalType>::Flags, |
745 |
_StorageOrder = MatrixFlags & RowMajorBit ? RowMajor : ColMajor, |
746 |
_StorageOrder = MatrixFlags & RowMajorBit ? RowMajor : ColMajor, |
746 |
_ScalarAccessOnDiag = !((int(_StorageOrder) == ColMajor && int(ProductOrder) == OnTheLeft) |
747 |
_ScalarAccessOnDiag = !((int(_StorageOrder) == ColMajor && int(ProductOrder) == OnTheLeft) |