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