25 #ifndef EIGEN_SKYLINEPRODUCT_H
26 #define EIGEN_SKYLINEPRODUCT_H
30 template<
typename Lhs,
typename Rhs,
int ProductMode>
31 struct SkylineProductReturnType {
32 typedef const typename internal::nested<Lhs, Rhs::RowsAtCompileTime>::type LhsNested;
33 typedef const typename internal::nested<Rhs, Lhs::RowsAtCompileTime>::type RhsNested;
35 typedef SkylineProduct<LhsNested, RhsNested, ProductMode>
Type;
38 template<
typename LhsNested,
typename RhsNested,
int ProductMode>
39 struct internal::traits<SkylineProduct<LhsNested, RhsNested, ProductMode> > {
41 typedef typename internal::remove_all<LhsNested>::type _LhsNested;
42 typedef typename internal::remove_all<RhsNested>::type _RhsNested;
43 typedef typename _LhsNested::Scalar Scalar;
46 LhsCoeffReadCost = _LhsNested::CoeffReadCost,
47 RhsCoeffReadCost = _RhsNested::CoeffReadCost,
48 LhsFlags = _LhsNested::Flags,
49 RhsFlags = _RhsNested::Flags,
51 RowsAtCompileTime = _LhsNested::RowsAtCompileTime,
52 ColsAtCompileTime = _RhsNested::ColsAtCompileTime,
53 InnerSize = EIGEN_SIZE_MIN_PREFER_FIXED(_LhsNested::ColsAtCompileTime, _RhsNested::RowsAtCompileTime),
55 MaxRowsAtCompileTime = _LhsNested::MaxRowsAtCompileTime,
56 MaxColsAtCompileTime = _RhsNested::MaxColsAtCompileTime,
58 EvalToRowMajor = (RhsFlags & LhsFlags &
RowMajorBit),
59 ResultIsSkyline = ProductMode == SkylineTimeSkylineProduct,
61 RemovedBits = ~((EvalToRowMajor ? 0 : RowMajorBit) | (ResultIsSkyline ? 0 : SkylineBit)),
64 | EvalBeforeAssigningBit
65 | EvalBeforeNestingBit,
67 CoeffReadCost = Dynamic
70 typedef typename internal::conditional<ResultIsSkyline,
71 SkylineMatrixBase<SkylineProduct<LhsNested, RhsNested, ProductMode> >,
72 MatrixBase<SkylineProduct<LhsNested, RhsNested, ProductMode> > >::type Base;
76 template<
typename LhsNested,
typename RhsNested,
int ProductMode>
77 class SkylineProduct : no_assignment_operator,
78 public traits<SkylineProduct<LhsNested, RhsNested, ProductMode> >::Base {
81 EIGEN_GENERIC_PUBLIC_INTERFACE(SkylineProduct)
85 typedef typename traits<SkylineProduct>::_LhsNested _LhsNested;
86 typedef typename traits<SkylineProduct>::_RhsNested _RhsNested;
90 template<typename Lhs, typename Rhs>
91 EIGEN_STRONG_INLINE SkylineProduct(const Lhs& lhs, const Rhs& rhs)
92 : m_lhs(lhs), m_rhs(rhs) {
93 eigen_assert(lhs.cols() == rhs.rows());
96 ProductIsValid = _LhsNested::ColsAtCompileTime ==
Dynamic
97 || _RhsNested::RowsAtCompileTime ==
Dynamic
98 || int(_LhsNested::ColsAtCompileTime) == int(_RhsNested::RowsAtCompileTime),
99 AreVectors = _LhsNested::IsVectorAtCompileTime && _RhsNested::IsVectorAtCompileTime,
100 SameSizes = EIGEN_PREDICATE_SAME_MATRIX_SIZE(_LhsNested, _RhsNested)
105 EIGEN_STATIC_ASSERT(ProductIsValid || !(AreVectors && SameSizes),
106 INVALID_VECTOR_VECTOR_PRODUCT__IF_YOU_WANTED_A_DOT_OR_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTIONS)
107 EIGEN_STATIC_ASSERT(ProductIsValid || !(SameSizes && !AreVectors),
108 INVALID_MATRIX_PRODUCT__IF_YOU_WANTED_A_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTION)
109 EIGEN_STATIC_ASSERT(ProductIsValid || SameSizes, INVALID_MATRIX_PRODUCT)
112 EIGEN_STRONG_INLINE Index rows()
const {
116 EIGEN_STRONG_INLINE Index cols()
const {
120 EIGEN_STRONG_INLINE
const _LhsNested& lhs()
const {
124 EIGEN_STRONG_INLINE
const _RhsNested& rhs()
const {
136 template<
typename Lhs,
typename Rhs,
typename Dest>
137 EIGEN_DONT_INLINE
void skyline_row_major_time_dense_product(
const Lhs& lhs,
const Rhs& rhs, Dest& dst) {
138 typedef typename remove_all<Lhs>::type _Lhs;
139 typedef typename remove_all<Rhs>::type _Rhs;
140 typedef typename traits<Lhs>::Scalar Scalar;
143 LhsIsRowMajor = (_Lhs::Flags &
RowMajorBit) == RowMajorBit,
144 LhsIsSelfAdjoint = (_Lhs::Flags & SelfAdjointBit) == SelfAdjointBit,
145 ProcessFirstHalf = LhsIsSelfAdjoint
146 && (((_Lhs::Flags & (UpperTriangularBit | LowerTriangularBit)) == 0)
147 || ((_Lhs::Flags & UpperTriangularBit) && !LhsIsRowMajor)
148 || ((_Lhs::Flags & LowerTriangularBit) && LhsIsRowMajor)),
149 ProcessSecondHalf = LhsIsSelfAdjoint && (!ProcessFirstHalf)
153 for (Index col = 0;
col < rhs.cols();
col++) {
154 for (Index row = 0;
row < lhs.rows();
row++) {
155 dst(row, col) = lhs.coeffDiag(row) * rhs(row, col);
159 for (Index row = 0;
row < lhs.rows();
row++) {
160 typename _Lhs::InnerLowerIterator lIt(lhs, row);
161 const Index stop = lIt.col() + lIt.size();
162 for (Index col = 0;
col < rhs.cols();
col++) {
172 dst(row, col) += tmp;
179 for (Index lhscol = 0; lhscol < lhs.cols(); lhscol++) {
180 typename _Lhs::InnerUpperIterator uIt(lhs, lhscol);
181 const Index stop = uIt.size() + uIt.row();
182 for (Index rhscol = 0; rhscol < rhs.cols(); rhscol++) {
185 const Scalar rhsCoeff = rhs.coeff(lhscol, rhscol);
199 template<
typename Lhs,
typename Rhs,
typename Dest>
200 EIGEN_DONT_INLINE
void skyline_col_major_time_dense_product(
const Lhs& lhs,
const Rhs& rhs, Dest& dst) {
201 typedef typename remove_all<Lhs>::type _Lhs;
202 typedef typename remove_all<Rhs>::type _Rhs;
203 typedef typename traits<Lhs>::Scalar Scalar;
206 LhsIsRowMajor = (_Lhs::Flags &
RowMajorBit) == RowMajorBit,
207 LhsIsSelfAdjoint = (_Lhs::Flags & SelfAdjointBit) == SelfAdjointBit,
208 ProcessFirstHalf = LhsIsSelfAdjoint
209 && (((_Lhs::Flags & (UpperTriangularBit | LowerTriangularBit)) == 0)
210 || ((_Lhs::Flags & UpperTriangularBit) && !LhsIsRowMajor)
211 || ((_Lhs::Flags & LowerTriangularBit) && LhsIsRowMajor)),
212 ProcessSecondHalf = LhsIsSelfAdjoint && (!ProcessFirstHalf)
216 for (Index col = 0;
col < rhs.cols();
col++) {
217 for (Index row = 0;
row < lhs.rows();
row++) {
218 dst(row, col) = lhs.coeffDiag(row) * rhs(row, col);
223 for (Index row = 0;
row < lhs.rows();
row++) {
224 typename _Lhs::InnerUpperIterator uIt(lhs, row);
225 const Index stop = uIt.col() + uIt.size();
226 for (Index col = 0;
col < rhs.cols();
col++) {
238 dst(row, col) += tmp;
244 for (Index lhscol = 0; lhscol < lhs.cols(); lhscol++) {
245 typename _Lhs::InnerLowerIterator lIt(lhs, lhscol);
246 const Index stop = lIt.size() + lIt.row();
247 for (Index rhscol = 0; rhscol < rhs.cols(); rhscol++) {
249 const Scalar rhsCoeff = rhs.coeff(lhscol, rhscol);
263 template<
typename Lhs,
typename Rhs,
typename ResultType,
264 int LhsStorageOrder = traits<Lhs>::Flags&
RowMajorBit>
265 struct skyline_product_selector;
267 template<
typename Lhs,
typename Rhs,
typename ResultType>
268 struct skyline_product_selector<Lhs, Rhs, ResultType,
RowMajor> {
269 typedef typename traits<typename remove_all<Lhs>::type>::Scalar Scalar;
271 static void run(
const Lhs& lhs,
const Rhs& rhs, ResultType & res) {
272 skyline_row_major_time_dense_product<Lhs, Rhs, ResultType > (lhs, rhs, res);
276 template<
typename Lhs,
typename Rhs,
typename ResultType>
277 struct skyline_product_selector<Lhs, Rhs, ResultType,
ColMajor> {
278 typedef typename traits<typename remove_all<Lhs>::type>::Scalar Scalar;
280 static void run(
const Lhs& lhs,
const Rhs& rhs, ResultType & res) {
281 skyline_col_major_time_dense_product<Lhs, Rhs, ResultType > (lhs, rhs, res);
300 template<
typename Derived>
301 template<
typename OtherDerived >
302 EIGEN_STRONG_INLINE
const typename SkylineProductReturnType<Derived, OtherDerived>::Type
303 SkylineMatrixBase<Derived>::operator*(
const MatrixBase<OtherDerived> &other)
const {
305 return typename SkylineProductReturnType<Derived, OtherDerived>::Type(derived(), other.derived());
310 #endif // EIGEN_SKYLINEPRODUCT_H