1c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// This file is part of Eigen, a lightweight C++ template library 2c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// for linear algebra. 3c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// 4c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// Copyright (C) 2008-2009 Guillaume Saupin <guillaume.saupin@cea.fr> 5c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// 6c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// This Source Code Form is subject to the terms of the Mozilla 7c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// Public License v. 2.0. If a copy of the MPL was not distributed 8c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 9c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 10c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#ifndef EIGEN_SKYLINEPRODUCT_H 11c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#define EIGEN_SKYLINEPRODUCT_H 12c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 13c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathnamespace Eigen { 14c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 15c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Lhs, typename Rhs, int ProductMode> 16c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct SkylineProductReturnType { 172b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef const typename internal::nested_eval<Lhs, Rhs::RowsAtCompileTime>::type LhsNested; 182b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef const typename internal::nested_eval<Rhs, Lhs::RowsAtCompileTime>::type RhsNested; 19c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 20c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef SkylineProduct<LhsNested, RhsNested, ProductMode> Type; 21c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 22c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 23c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename LhsNested, typename RhsNested, int ProductMode> 24c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct internal::traits<SkylineProduct<LhsNested, RhsNested, ProductMode> > { 25c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // clean the nested types: 26c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef typename internal::remove_all<LhsNested>::type _LhsNested; 27c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef typename internal::remove_all<RhsNested>::type _RhsNested; 28c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef typename _LhsNested::Scalar Scalar; 29c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 30c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath enum { 31c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath LhsCoeffReadCost = _LhsNested::CoeffReadCost, 32c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath RhsCoeffReadCost = _RhsNested::CoeffReadCost, 33c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath LhsFlags = _LhsNested::Flags, 34c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath RhsFlags = _RhsNested::Flags, 35c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 36c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath RowsAtCompileTime = _LhsNested::RowsAtCompileTime, 37c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ColsAtCompileTime = _RhsNested::ColsAtCompileTime, 38c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath InnerSize = EIGEN_SIZE_MIN_PREFER_FIXED(_LhsNested::ColsAtCompileTime, _RhsNested::RowsAtCompileTime), 39c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 40c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath MaxRowsAtCompileTime = _LhsNested::MaxRowsAtCompileTime, 41c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath MaxColsAtCompileTime = _RhsNested::MaxColsAtCompileTime, 42c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 43c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath EvalToRowMajor = (RhsFlags & LhsFlags & RowMajorBit), 44c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ResultIsSkyline = ProductMode == SkylineTimeSkylineProduct, 45c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 46c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath RemovedBits = ~((EvalToRowMajor ? 0 : RowMajorBit) | (ResultIsSkyline ? 0 : SkylineBit)), 47c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 48c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Flags = (int(LhsFlags | RhsFlags) & HereditaryBits & RemovedBits) 49c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath | EvalBeforeAssigningBit 50c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath | EvalBeforeNestingBit, 51c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 522b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang CoeffReadCost = HugeCost 53c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath }; 54c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 55c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef typename internal::conditional<ResultIsSkyline, 56c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath SkylineMatrixBase<SkylineProduct<LhsNested, RhsNested, ProductMode> >, 57c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath MatrixBase<SkylineProduct<LhsNested, RhsNested, ProductMode> > >::type Base; 58c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 59c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 60c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathnamespace internal { 61c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename LhsNested, typename RhsNested, int ProductMode> 62c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathclass SkylineProduct : no_assignment_operator, 63c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathpublic traits<SkylineProduct<LhsNested, RhsNested, ProductMode> >::Base { 64c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathpublic: 65c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 66c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath EIGEN_GENERIC_PUBLIC_INTERFACE(SkylineProduct) 67c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 68c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathprivate: 69c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 70c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef typename traits<SkylineProduct>::_LhsNested _LhsNested; 71c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef typename traits<SkylineProduct>::_RhsNested _RhsNested; 72c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 73c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathpublic: 74c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 75c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath template<typename Lhs, typename Rhs> 76c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath EIGEN_STRONG_INLINE SkylineProduct(const Lhs& lhs, const Rhs& rhs) 77c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath : m_lhs(lhs), m_rhs(rhs) { 78c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath eigen_assert(lhs.cols() == rhs.rows()); 79c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 80c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath enum { 81c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ProductIsValid = _LhsNested::ColsAtCompileTime == Dynamic 82c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath || _RhsNested::RowsAtCompileTime == Dynamic 83c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath || int(_LhsNested::ColsAtCompileTime) == int(_RhsNested::RowsAtCompileTime), 84c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath AreVectors = _LhsNested::IsVectorAtCompileTime && _RhsNested::IsVectorAtCompileTime, 85c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath SameSizes = EIGEN_PREDICATE_SAME_MATRIX_SIZE(_LhsNested, _RhsNested) 86c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath }; 87c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // note to the lost user: 88c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // * for a dot product use: v1.dot(v2) 89c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // * for a coeff-wise product use: v1.cwise()*v2 90c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath EIGEN_STATIC_ASSERT(ProductIsValid || !(AreVectors && SameSizes), 91c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath INVALID_VECTOR_VECTOR_PRODUCT__IF_YOU_WANTED_A_DOT_OR_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTIONS) 92c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath EIGEN_STATIC_ASSERT(ProductIsValid || !(SameSizes && !AreVectors), 93c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath INVALID_MATRIX_PRODUCT__IF_YOU_WANTED_A_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTION) 94c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath EIGEN_STATIC_ASSERT(ProductIsValid || SameSizes, INVALID_MATRIX_PRODUCT) 95c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 96c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 97c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath EIGEN_STRONG_INLINE Index rows() const { 98c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return m_lhs.rows(); 99c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 100c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 101c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath EIGEN_STRONG_INLINE Index cols() const { 102c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return m_rhs.cols(); 103c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 104c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 105c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath EIGEN_STRONG_INLINE const _LhsNested& lhs() const { 106c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return m_lhs; 107c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 108c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 109c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath EIGEN_STRONG_INLINE const _RhsNested& rhs() const { 110c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return m_rhs; 111c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 112c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 113c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathprotected: 114c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath LhsNested m_lhs; 115c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath RhsNested m_rhs; 116c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 117c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 118c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// dense = skyline * dense 119c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// Note that here we force no inlining and separate the setZero() because GCC messes up otherwise 120c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 121c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Lhs, typename Rhs, typename Dest> 122c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan KamathEIGEN_DONT_INLINE void skyline_row_major_time_dense_product(const Lhs& lhs, const Rhs& rhs, Dest& dst) { 123c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef typename remove_all<Lhs>::type _Lhs; 124c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef typename remove_all<Rhs>::type _Rhs; 125c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef typename traits<Lhs>::Scalar Scalar; 126c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 127c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath enum { 128c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath LhsIsRowMajor = (_Lhs::Flags & RowMajorBit) == RowMajorBit, 129c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath LhsIsSelfAdjoint = (_Lhs::Flags & SelfAdjointBit) == SelfAdjointBit, 130c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ProcessFirstHalf = LhsIsSelfAdjoint 131c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath && (((_Lhs::Flags & (UpperTriangularBit | LowerTriangularBit)) == 0) 132c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath || ((_Lhs::Flags & UpperTriangularBit) && !LhsIsRowMajor) 133c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath || ((_Lhs::Flags & LowerTriangularBit) && LhsIsRowMajor)), 134c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ProcessSecondHalf = LhsIsSelfAdjoint && (!ProcessFirstHalf) 135c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath }; 136c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 137c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath //Use matrix diagonal part <- Improvement : use inner iterator on dense matrix. 138c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath for (Index col = 0; col < rhs.cols(); col++) { 139c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath for (Index row = 0; row < lhs.rows(); row++) { 140c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath dst(row, col) = lhs.coeffDiag(row) * rhs(row, col); 141c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 142c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 143c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath //Use matrix lower triangular part 144c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath for (Index row = 0; row < lhs.rows(); row++) { 145c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typename _Lhs::InnerLowerIterator lIt(lhs, row); 146c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath const Index stop = lIt.col() + lIt.size(); 147c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath for (Index col = 0; col < rhs.cols(); col++) { 148c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 149c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index k = lIt.col(); 150c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Scalar tmp = 0; 151c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath while (k < stop) { 152c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath tmp += 153c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath lIt.value() * 154c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath rhs(k++, col); 155c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ++lIt; 156c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 157c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath dst(row, col) += tmp; 158c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath lIt += -lIt.size(); 159c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 160c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 161c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 162c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 163c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath //Use matrix upper triangular part 164c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath for (Index lhscol = 0; lhscol < lhs.cols(); lhscol++) { 165c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typename _Lhs::InnerUpperIterator uIt(lhs, lhscol); 166c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath const Index stop = uIt.size() + uIt.row(); 167c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath for (Index rhscol = 0; rhscol < rhs.cols(); rhscol++) { 168c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 169c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 170c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath const Scalar rhsCoeff = rhs.coeff(lhscol, rhscol); 171c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index k = uIt.row(); 172c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath while (k < stop) { 173c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath dst(k++, rhscol) += 174c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath uIt.value() * 175c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath rhsCoeff; 176c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ++uIt; 177c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 178c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath uIt += -uIt.size(); 179c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 180c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 181c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 182c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} 183c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 184c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Lhs, typename Rhs, typename Dest> 185c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan KamathEIGEN_DONT_INLINE void skyline_col_major_time_dense_product(const Lhs& lhs, const Rhs& rhs, Dest& dst) { 186c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef typename remove_all<Lhs>::type _Lhs; 187c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef typename remove_all<Rhs>::type _Rhs; 188c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef typename traits<Lhs>::Scalar Scalar; 189c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 190c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath enum { 191c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath LhsIsRowMajor = (_Lhs::Flags & RowMajorBit) == RowMajorBit, 192c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath LhsIsSelfAdjoint = (_Lhs::Flags & SelfAdjointBit) == SelfAdjointBit, 193c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ProcessFirstHalf = LhsIsSelfAdjoint 194c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath && (((_Lhs::Flags & (UpperTriangularBit | LowerTriangularBit)) == 0) 195c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath || ((_Lhs::Flags & UpperTriangularBit) && !LhsIsRowMajor) 196c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath || ((_Lhs::Flags & LowerTriangularBit) && LhsIsRowMajor)), 197c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ProcessSecondHalf = LhsIsSelfAdjoint && (!ProcessFirstHalf) 198c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath }; 199c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 200c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath //Use matrix diagonal part <- Improvement : use inner iterator on dense matrix. 201c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath for (Index col = 0; col < rhs.cols(); col++) { 202c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath for (Index row = 0; row < lhs.rows(); row++) { 203c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath dst(row, col) = lhs.coeffDiag(row) * rhs(row, col); 204c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 205c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 206c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 207c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath //Use matrix upper triangular part 208c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath for (Index row = 0; row < lhs.rows(); row++) { 209c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typename _Lhs::InnerUpperIterator uIt(lhs, row); 210c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath const Index stop = uIt.col() + uIt.size(); 211c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath for (Index col = 0; col < rhs.cols(); col++) { 212c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 213c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index k = uIt.col(); 214c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Scalar tmp = 0; 215c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath while (k < stop) { 216c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath tmp += 217c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath uIt.value() * 218c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath rhs(k++, col); 219c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ++uIt; 220c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 221c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 222c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 223c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath dst(row, col) += tmp; 224c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath uIt += -uIt.size(); 225c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 226c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 227c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 228c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath //Use matrix lower triangular part 229c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath for (Index lhscol = 0; lhscol < lhs.cols(); lhscol++) { 230c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typename _Lhs::InnerLowerIterator lIt(lhs, lhscol); 231c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath const Index stop = lIt.size() + lIt.row(); 232c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath for (Index rhscol = 0; rhscol < rhs.cols(); rhscol++) { 233c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 234c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath const Scalar rhsCoeff = rhs.coeff(lhscol, rhscol); 235c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index k = lIt.row(); 236c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath while (k < stop) { 237c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath dst(k++, rhscol) += 238c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath lIt.value() * 239c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath rhsCoeff; 240c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ++lIt; 241c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 242c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath lIt += -lIt.size(); 243c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 244c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 245c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 246c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} 247c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 248c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Lhs, typename Rhs, typename ResultType, 249c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath int LhsStorageOrder = traits<Lhs>::Flags&RowMajorBit> 250c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath struct skyline_product_selector; 251c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 252c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Lhs, typename Rhs, typename ResultType> 253c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct skyline_product_selector<Lhs, Rhs, ResultType, RowMajor> { 254c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef typename traits<typename remove_all<Lhs>::type>::Scalar Scalar; 255c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 256c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath static void run(const Lhs& lhs, const Rhs& rhs, ResultType & res) { 257c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath skyline_row_major_time_dense_product<Lhs, Rhs, ResultType > (lhs, rhs, res); 258c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 259c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 260c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 261c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Lhs, typename Rhs, typename ResultType> 262c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct skyline_product_selector<Lhs, Rhs, ResultType, ColMajor> { 263c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef typename traits<typename remove_all<Lhs>::type>::Scalar Scalar; 264c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 265c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath static void run(const Lhs& lhs, const Rhs& rhs, ResultType & res) { 266c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath skyline_col_major_time_dense_product<Lhs, Rhs, ResultType > (lhs, rhs, res); 267c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 268c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 269c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 270c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} // end namespace internal 271c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 272c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// template<typename Derived> 273c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// template<typename Lhs, typename Rhs > 274c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// Derived & MatrixBase<Derived>::lazyAssign(const SkylineProduct<Lhs, Rhs, SkylineTimeDenseProduct>& product) { 275c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// typedef typename internal::remove_all<Lhs>::type _Lhs; 276c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// internal::skyline_product_selector<typename internal::remove_all<Lhs>::type, 277c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// typename internal::remove_all<Rhs>::type, 278c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// Derived>::run(product.lhs(), product.rhs(), derived()); 279c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// 280c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// return derived(); 281c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// } 282c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 283c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// skyline * dense 284c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 285c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Derived> 286c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename OtherDerived > 287c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan KamathEIGEN_STRONG_INLINE const typename SkylineProductReturnType<Derived, OtherDerived>::Type 288c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan KamathSkylineMatrixBase<Derived>::operator*(const MatrixBase<OtherDerived> &other) const { 289c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 290c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return typename SkylineProductReturnType<Derived, OtherDerived>::Type(derived(), other.derived()); 291c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} 292c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 293c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} // end namespace Eigen 294c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 295c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#endif // EIGEN_SKYLINEPRODUCT_H 296