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 Benoit Jacob <jacob.benoit.1@gmail.com>
5c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>
6c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//
7c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// This Source Code Form is subject to the terms of the Mozilla
8c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// Public License v. 2.0. If a copy of the MPL was not distributed
9c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
10c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
11c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#ifndef EIGEN_TRIANGULARMATRIX_H
12c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#define EIGEN_TRIANGULARMATRIX_H
13c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
14c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathnamespace Eigen {
15c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
16c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathnamespace internal {
17c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
18c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<int Side, typename TriangularType, typename Rhs> struct triangular_solve_retval;
19c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
20c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
21c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
22c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** \internal
23c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  *
24c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * \class TriangularBase
25c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * \ingroup Core_Module
26c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  *
27c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * \brief Base class for triangular part in a matrix
28c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  */
29c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Derived> class TriangularBase : public EigenBase<Derived>
30c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
31c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  public:
32c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
33c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    enum {
34c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      Mode = internal::traits<Derived>::Mode,
35c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      CoeffReadCost = internal::traits<Derived>::CoeffReadCost,
36c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      RowsAtCompileTime = internal::traits<Derived>::RowsAtCompileTime,
37c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      ColsAtCompileTime = internal::traits<Derived>::ColsAtCompileTime,
38c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      MaxRowsAtCompileTime = internal::traits<Derived>::MaxRowsAtCompileTime,
39c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      MaxColsAtCompileTime = internal::traits<Derived>::MaxColsAtCompileTime
40c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    };
41c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename internal::traits<Derived>::Scalar Scalar;
42c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename internal::traits<Derived>::StorageKind StorageKind;
43c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename internal::traits<Derived>::Index Index;
44c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename internal::traits<Derived>::DenseMatrixType DenseMatrixType;
45c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef DenseMatrixType DenseType;
46c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
47c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    inline TriangularBase() { eigen_assert(!((Mode&UnitDiag) && (Mode&ZeroDiag))); }
48c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
49c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    inline Index rows() const { return derived().rows(); }
50c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    inline Index cols() const { return derived().cols(); }
51c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    inline Index outerStride() const { return derived().outerStride(); }
52c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    inline Index innerStride() const { return derived().innerStride(); }
53c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
54c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    inline Scalar coeff(Index row, Index col) const  { return derived().coeff(row,col); }
55c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    inline Scalar& coeffRef(Index row, Index col) { return derived().coeffRef(row,col); }
56c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
57c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    /** \see MatrixBase::copyCoeff(row,col)
58c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      */
59c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    template<typename Other>
60c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_STRONG_INLINE void copyCoeff(Index row, Index col, Other& other)
61c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
62c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      derived().coeffRef(row, col) = other.coeff(row, col);
63c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
64c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
65c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    inline Scalar operator()(Index row, Index col) const
66c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
67c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      check_coordinates(row, col);
68c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      return coeff(row,col);
69c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
70c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    inline Scalar& operator()(Index row, Index col)
71c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
72c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      check_coordinates(row, col);
73c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      return coeffRef(row,col);
74c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
75c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
76c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    #ifndef EIGEN_PARSED_BY_DOXYGEN
77c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    inline const Derived& derived() const { return *static_cast<const Derived*>(this); }
78c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    inline Derived& derived() { return *static_cast<Derived*>(this); }
79c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    #endif // not EIGEN_PARSED_BY_DOXYGEN
80c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
81c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    template<typename DenseDerived>
82c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    void evalTo(MatrixBase<DenseDerived> &other) const;
83c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    template<typename DenseDerived>
84c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    void evalToLazy(MatrixBase<DenseDerived> &other) const;
85c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
86c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    DenseMatrixType toDenseMatrix() const
87c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
88c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      DenseMatrixType res(rows(), cols());
89c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      evalToLazy(res);
90c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      return res;
91c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
92c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
93c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  protected:
94c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
95c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    void check_coordinates(Index row, Index col) const
96c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
97c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      EIGEN_ONLY_USED_FOR_DEBUG(row);
98c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      EIGEN_ONLY_USED_FOR_DEBUG(col);
99c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      eigen_assert(col>=0 && col<cols() && row>=0 && row<rows());
100c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      const int mode = int(Mode) & ~SelfAdjoint;
101c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      EIGEN_ONLY_USED_FOR_DEBUG(mode);
102c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      eigen_assert((mode==Upper && col>=row)
103c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                || (mode==Lower && col<=row)
104c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                || ((mode==StrictlyUpper || mode==UnitUpper) && col>row)
105c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                || ((mode==StrictlyLower || mode==UnitLower) && col<row));
106c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
107c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
108c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    #ifdef EIGEN_INTERNAL_DEBUGGING
109c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    void check_coordinates_internal(Index row, Index col) const
110c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
111c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      check_coordinates(row, col);
112c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
113c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    #else
114c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    void check_coordinates_internal(Index , Index ) const {}
115c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    #endif
116c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
117c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
118c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
119c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** \class TriangularView
120c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * \ingroup Core_Module
121c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  *
122c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * \brief Base class for triangular part in a matrix
123c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  *
124c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * \param MatrixType the type of the object in which we are taking the triangular part
125c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * \param Mode the kind of triangular matrix expression to construct. Can be #Upper,
126c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  *             #Lower, #UnitUpper, #UnitLower, #StrictlyUpper, or #StrictlyLower.
127c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  *             This is in fact a bit field; it must have either #Upper or #Lower,
128c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  *             and additionnaly it may have #UnitDiag or #ZeroDiag or neither.
129c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  *
130c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * This class represents a triangular part of a matrix, not necessarily square. Strictly speaking, for rectangular
131c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * matrices one should speak of "trapezoid" parts. This class is the return type
132c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * of MatrixBase::triangularView() and most of the time this is the only way it is used.
133c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  *
134c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * \sa MatrixBase::triangularView()
135c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  */
136c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathnamespace internal {
137c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename MatrixType, unsigned int _Mode>
138c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct traits<TriangularView<MatrixType, _Mode> > : traits<MatrixType>
139c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
140c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef typename nested<MatrixType>::type MatrixTypeNested;
141c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef typename remove_reference<MatrixTypeNested>::type MatrixTypeNestedNonRef;
142c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef typename remove_all<MatrixTypeNested>::type MatrixTypeNestedCleaned;
143c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef MatrixType ExpressionType;
144c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef typename MatrixType::PlainObject DenseMatrixType;
145c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  enum {
146c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    Mode = _Mode,
147c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    Flags = (MatrixTypeNestedCleaned::Flags & (HereditaryBits) & (~(PacketAccessBit | DirectAccessBit | LinearAccessBit))) | Mode,
148c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    CoeffReadCost = MatrixTypeNestedCleaned::CoeffReadCost
149c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  };
150c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
151c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
152c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
153c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<int Mode, bool LhsIsTriangular,
154c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath         typename Lhs, bool LhsIsVector,
155c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath         typename Rhs, bool RhsIsVector>
156c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct TriangularProduct;
157c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
158c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename _MatrixType, unsigned int _Mode> class TriangularView
159c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  : public TriangularBase<TriangularView<_MatrixType, _Mode> >
160c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
161c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  public:
162c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
163c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef TriangularBase<TriangularView> Base;
164c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename internal::traits<TriangularView>::Scalar Scalar;
165c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
166c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef _MatrixType MatrixType;
167c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename internal::traits<TriangularView>::DenseMatrixType DenseMatrixType;
168c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef DenseMatrixType PlainObject;
169c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
170c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  protected:
171c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename internal::traits<TriangularView>::MatrixTypeNested MatrixTypeNested;
172c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename internal::traits<TriangularView>::MatrixTypeNestedNonRef MatrixTypeNestedNonRef;
173c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename internal::traits<TriangularView>::MatrixTypeNestedCleaned MatrixTypeNestedCleaned;
174c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
175c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename internal::remove_all<typename MatrixType::ConjugateReturnType>::type MatrixConjugateReturnType;
176c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
177c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  public:
178c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    using Base::evalToLazy;
179c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
180c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
181c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename internal::traits<TriangularView>::StorageKind StorageKind;
182c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename internal::traits<TriangularView>::Index Index;
183c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
184c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    enum {
185c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      Mode = _Mode,
186c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      TransposeMode = (Mode & Upper ? Lower : 0)
187c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                    | (Mode & Lower ? Upper : 0)
188c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                    | (Mode & (UnitDiag))
189c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                    | (Mode & (ZeroDiag))
190c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    };
191c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
192c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    inline TriangularView(const MatrixType& matrix) : m_matrix(matrix)
193c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {}
194c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
195c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    inline Index rows() const { return m_matrix.rows(); }
196c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    inline Index cols() const { return m_matrix.cols(); }
197c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    inline Index outerStride() const { return m_matrix.outerStride(); }
198c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    inline Index innerStride() const { return m_matrix.innerStride(); }
199c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
200c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    /** \sa MatrixBase::operator+=() */
201c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    template<typename Other> TriangularView&  operator+=(const DenseBase<Other>& other) { return *this = m_matrix + other.derived(); }
202c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    /** \sa MatrixBase::operator-=() */
203c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    template<typename Other> TriangularView&  operator-=(const DenseBase<Other>& other) { return *this = m_matrix - other.derived(); }
204c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    /** \sa MatrixBase::operator*=() */
205c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    TriangularView&  operator*=(const typename internal::traits<MatrixType>::Scalar& other) { return *this = m_matrix * other; }
206c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    /** \sa MatrixBase::operator/=() */
207c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    TriangularView&  operator/=(const typename internal::traits<MatrixType>::Scalar& other) { return *this = m_matrix / other; }
208c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
209c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    /** \sa MatrixBase::fill() */
210c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    void fill(const Scalar& value) { setConstant(value); }
211c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    /** \sa MatrixBase::setConstant() */
212c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    TriangularView& setConstant(const Scalar& value)
213c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    { return *this = MatrixType::Constant(rows(), cols(), value); }
214c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    /** \sa MatrixBase::setZero() */
215c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    TriangularView& setZero() { return setConstant(Scalar(0)); }
216c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    /** \sa MatrixBase::setOnes() */
217c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    TriangularView& setOnes() { return setConstant(Scalar(1)); }
218c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
219c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    /** \sa MatrixBase::coeff()
220c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * \warning the coordinates must fit into the referenced triangular part
221c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      */
222c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    inline Scalar coeff(Index row, Index col) const
223c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
224c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      Base::check_coordinates_internal(row, col);
225c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      return m_matrix.coeff(row, col);
226c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
227c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
228c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    /** \sa MatrixBase::coeffRef()
229c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      * \warning the coordinates must fit into the referenced triangular part
230c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      */
231c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    inline Scalar& coeffRef(Index row, Index col)
232c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
233c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      Base::check_coordinates_internal(row, col);
234c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      return m_matrix.const_cast_derived().coeffRef(row, col);
235c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
236c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
237c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    const MatrixTypeNestedCleaned& nestedExpression() const { return m_matrix; }
238c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    MatrixTypeNestedCleaned& nestedExpression() { return *const_cast<MatrixTypeNestedCleaned*>(&m_matrix); }
239c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
240c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    /** Assigns a triangular matrix to a triangular part of a dense matrix */
241c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    template<typename OtherDerived>
242c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    TriangularView& operator=(const TriangularBase<OtherDerived>& other);
243c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
244c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    template<typename OtherDerived>
245c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    TriangularView& operator=(const MatrixBase<OtherDerived>& other);
246c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
247c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    TriangularView& operator=(const TriangularView& other)
248c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    { return *this = other.nestedExpression(); }
249c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
250c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    template<typename OtherDerived>
251c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    void lazyAssign(const TriangularBase<OtherDerived>& other);
252c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
253c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    template<typename OtherDerived>
254c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    void lazyAssign(const MatrixBase<OtherDerived>& other);
255c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
256c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    /** \sa MatrixBase::conjugate() */
257c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    inline TriangularView<MatrixConjugateReturnType,Mode> conjugate()
258c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    { return m_matrix.conjugate(); }
259c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    /** \sa MatrixBase::conjugate() const */
260c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    inline const TriangularView<MatrixConjugateReturnType,Mode> conjugate() const
261c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    { return m_matrix.conjugate(); }
262c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
263c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    /** \sa MatrixBase::adjoint() const */
264c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    inline const TriangularView<const typename MatrixType::AdjointReturnType,TransposeMode> adjoint() const
265c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    { return m_matrix.adjoint(); }
266c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
267c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    /** \sa MatrixBase::transpose() */
268c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    inline TriangularView<Transpose<MatrixType>,TransposeMode> transpose()
269c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
270c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      EIGEN_STATIC_ASSERT_LVALUE(MatrixType)
271c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      return m_matrix.const_cast_derived().transpose();
272c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
273c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    /** \sa MatrixBase::transpose() const */
274c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    inline const TriangularView<Transpose<MatrixType>,TransposeMode> transpose() const
275c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
276c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      return m_matrix.transpose();
277c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
278c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
279c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    /** Efficient triangular matrix times vector/matrix product */
280c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    template<typename OtherDerived>
2817faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    TriangularProduct<Mode, true, MatrixType, false, OtherDerived, OtherDerived::ColsAtCompileTime==1>
282c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    operator*(const MatrixBase<OtherDerived>& rhs) const
283c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
284c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      return TriangularProduct
2857faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez              <Mode, true, MatrixType, false, OtherDerived, OtherDerived::ColsAtCompileTime==1>
286c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath              (m_matrix, rhs.derived());
287c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
288c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
289c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    /** Efficient vector/matrix times triangular matrix product */
290c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    template<typename OtherDerived> friend
2917faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    TriangularProduct<Mode, false, OtherDerived, OtherDerived::RowsAtCompileTime==1, MatrixType, false>
292c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    operator*(const MatrixBase<OtherDerived>& lhs, const TriangularView& rhs)
293c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
294c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      return TriangularProduct
2957faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez              <Mode, false, OtherDerived, OtherDerived::RowsAtCompileTime==1, MatrixType, false>
296c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath              (lhs.derived(),rhs.m_matrix);
297c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
298c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
299c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    #ifdef EIGEN2_SUPPORT
300c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    template<typename OtherDerived>
301c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    struct eigen2_product_return_type
302c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
303c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      typedef typename TriangularView<MatrixType,Mode>::DenseMatrixType DenseMatrixType;
304c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      typedef typename OtherDerived::PlainObject::DenseType OtherPlainObject;
305c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      typedef typename ProductReturnType<DenseMatrixType, OtherPlainObject>::Type ProdRetType;
306c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      typedef typename ProdRetType::PlainObject type;
307c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    };
308c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    template<typename OtherDerived>
309c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    const typename eigen2_product_return_type<OtherDerived>::type
310c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    operator*(const EigenBase<OtherDerived>& rhs) const
311c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
312c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      typename OtherDerived::PlainObject::DenseType rhsPlainObject;
313c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      rhs.evalTo(rhsPlainObject);
314c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      return this->toDenseMatrix() * rhsPlainObject;
315c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
316c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    template<typename OtherMatrixType>
317c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    bool isApprox(const TriangularView<OtherMatrixType, Mode>& other, typename NumTraits<Scalar>::Real precision = NumTraits<Scalar>::dummy_precision()) const
318c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
319c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      return this->toDenseMatrix().isApprox(other.toDenseMatrix(), precision);
320c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
321c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    template<typename OtherDerived>
322c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    bool isApprox(const MatrixBase<OtherDerived>& other, typename NumTraits<Scalar>::Real precision = NumTraits<Scalar>::dummy_precision()) const
323c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
324c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      return this->toDenseMatrix().isApprox(other, precision);
325c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
326c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    #endif // EIGEN2_SUPPORT
327c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
328c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    template<int Side, typename Other>
329c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    inline const internal::triangular_solve_retval<Side,TriangularView, Other>
330c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    solve(const MatrixBase<Other>& other) const;
331c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
332c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    template<int Side, typename OtherDerived>
333c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    void solveInPlace(const MatrixBase<OtherDerived>& other) const;
334c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
335c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    template<typename Other>
336c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    inline const internal::triangular_solve_retval<OnTheLeft,TriangularView, Other>
337c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    solve(const MatrixBase<Other>& other) const
338c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    { return solve<OnTheLeft>(other); }
339c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
340c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    template<typename OtherDerived>
341c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    void solveInPlace(const MatrixBase<OtherDerived>& other) const
342c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    { return solveInPlace<OnTheLeft>(other); }
343c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
344c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    const SelfAdjointView<MatrixTypeNestedNonRef,Mode> selfadjointView() const
345c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
346c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      EIGEN_STATIC_ASSERT((Mode&UnitDiag)==0,PROGRAMMING_ERROR);
347c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      return SelfAdjointView<MatrixTypeNestedNonRef,Mode>(m_matrix);
348c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
349c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    SelfAdjointView<MatrixTypeNestedNonRef,Mode> selfadjointView()
350c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
351c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      EIGEN_STATIC_ASSERT((Mode&UnitDiag)==0,PROGRAMMING_ERROR);
352c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      return SelfAdjointView<MatrixTypeNestedNonRef,Mode>(m_matrix);
353c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
354c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
355c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    template<typename OtherDerived>
356c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    void swap(TriangularBase<OtherDerived> const & other)
357c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
358c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      TriangularView<SwapWrapper<MatrixType>,Mode>(const_cast<MatrixType&>(m_matrix)).lazyAssign(other.derived());
359c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
360c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
361c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    template<typename OtherDerived>
362c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    void swap(MatrixBase<OtherDerived> const & other)
363c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
364c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      SwapWrapper<MatrixType> swaper(const_cast<MatrixType&>(m_matrix));
365c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      TriangularView<SwapWrapper<MatrixType>,Mode>(swaper).lazyAssign(other.derived());
366c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
367c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
368c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    Scalar determinant() const
369c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
370c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      if (Mode & UnitDiag)
371c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        return 1;
372c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      else if (Mode & ZeroDiag)
373c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        return 0;
374c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      else
375c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        return m_matrix.diagonal().prod();
376c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
377c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
378c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    // TODO simplify the following:
379c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    template<typename ProductDerived, typename Lhs, typename Rhs>
380c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_STRONG_INLINE TriangularView& operator=(const ProductBase<ProductDerived, Lhs,Rhs>& other)
381c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
382c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      setZero();
383c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      return assignProduct(other,1);
384c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
385c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
386c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    template<typename ProductDerived, typename Lhs, typename Rhs>
387c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_STRONG_INLINE TriangularView& operator+=(const ProductBase<ProductDerived, Lhs,Rhs>& other)
388c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
389c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      return assignProduct(other,1);
390c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
391c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
392c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    template<typename ProductDerived, typename Lhs, typename Rhs>
393c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_STRONG_INLINE TriangularView& operator-=(const ProductBase<ProductDerived, Lhs,Rhs>& other)
394c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
395c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      return assignProduct(other,-1);
396c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
397c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
398c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
399c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    template<typename ProductDerived>
400c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_STRONG_INLINE TriangularView& operator=(const ScaledProduct<ProductDerived>& other)
401c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
402c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      setZero();
403c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      return assignProduct(other,other.alpha());
404c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
405c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
406c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    template<typename ProductDerived>
407c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_STRONG_INLINE TriangularView& operator+=(const ScaledProduct<ProductDerived>& other)
408c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
409c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      return assignProduct(other,other.alpha());
410c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
411c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
412c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    template<typename ProductDerived>
413c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_STRONG_INLINE TriangularView& operator-=(const ScaledProduct<ProductDerived>& other)
414c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
415c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      return assignProduct(other,-other.alpha());
416c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
417c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
418c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  protected:
419c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
420c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    template<typename ProductDerived, typename Lhs, typename Rhs>
421c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    EIGEN_STRONG_INLINE TriangularView& assignProduct(const ProductBase<ProductDerived, Lhs,Rhs>& prod, const Scalar& alpha);
422c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
423c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    MatrixTypeNested m_matrix;
424c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
425c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
426c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/***************************************************************************
427c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath* Implementation of triangular evaluation/assignment
428c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath***************************************************************************/
429c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
430c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathnamespace internal {
431c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
432c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Derived1, typename Derived2, unsigned int Mode, int UnrollCount, bool ClearOpposite>
433c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct triangular_assignment_selector
434c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
435c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  enum {
436c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    col = (UnrollCount-1) / Derived1::RowsAtCompileTime,
437c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    row = (UnrollCount-1) % Derived1::RowsAtCompileTime
438c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  };
439c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
440c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef typename Derived1::Scalar Scalar;
441c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
442c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static inline void run(Derived1 &dst, const Derived2 &src)
443c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
444c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    triangular_assignment_selector<Derived1, Derived2, Mode, UnrollCount-1, ClearOpposite>::run(dst, src);
445c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
446c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    eigen_assert( Mode == Upper || Mode == Lower
447c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath            || Mode == StrictlyUpper || Mode == StrictlyLower
448c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath            || Mode == UnitUpper || Mode == UnitLower);
449c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    if((Mode == Upper && row <= col)
450c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    || (Mode == Lower && row >= col)
451c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    || (Mode == StrictlyUpper && row < col)
452c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    || (Mode == StrictlyLower && row > col)
453c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    || (Mode == UnitUpper && row < col)
454c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    || (Mode == UnitLower && row > col))
455c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      dst.copyCoeff(row, col, src);
456c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    else if(ClearOpposite)
457c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
458c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      if (Mode&UnitDiag && row==col)
459c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        dst.coeffRef(row, col) = Scalar(1);
460c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      else
461c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        dst.coeffRef(row, col) = Scalar(0);
462c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
463c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
464c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
465c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
466c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// prevent buggy user code from causing an infinite recursion
467c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Derived1, typename Derived2, unsigned int Mode, bool ClearOpposite>
468c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct triangular_assignment_selector<Derived1, Derived2, Mode, 0, ClearOpposite>
469c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
470c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static inline void run(Derived1 &, const Derived2 &) {}
471c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
472c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
473c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Derived1, typename Derived2, bool ClearOpposite>
474c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct triangular_assignment_selector<Derived1, Derived2, Upper, Dynamic, ClearOpposite>
475c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
476c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef typename Derived1::Index Index;
477c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef typename Derived1::Scalar Scalar;
478c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static inline void run(Derived1 &dst, const Derived2 &src)
479c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
480c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    for(Index j = 0; j < dst.cols(); ++j)
481c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
482c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      Index maxi = (std::min)(j, dst.rows()-1);
483c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      for(Index i = 0; i <= maxi; ++i)
484c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        dst.copyCoeff(i, j, src);
485c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      if (ClearOpposite)
486c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        for(Index i = maxi+1; i < dst.rows(); ++i)
487c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath          dst.coeffRef(i, j) = Scalar(0);
488c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
489c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
490c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
491c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
492c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Derived1, typename Derived2, bool ClearOpposite>
493c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct triangular_assignment_selector<Derived1, Derived2, Lower, Dynamic, ClearOpposite>
494c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
495c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef typename Derived1::Index Index;
496c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static inline void run(Derived1 &dst, const Derived2 &src)
497c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
498c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    for(Index j = 0; j < dst.cols(); ++j)
499c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
500c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      for(Index i = j; i < dst.rows(); ++i)
501c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        dst.copyCoeff(i, j, src);
502c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      Index maxi = (std::min)(j, dst.rows());
503c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      if (ClearOpposite)
504c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        for(Index i = 0; i < maxi; ++i)
505c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath          dst.coeffRef(i, j) = static_cast<typename Derived1::Scalar>(0);
506c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
507c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
508c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
509c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
510c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Derived1, typename Derived2, bool ClearOpposite>
511c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct triangular_assignment_selector<Derived1, Derived2, StrictlyUpper, Dynamic, ClearOpposite>
512c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
513c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef typename Derived1::Index Index;
5147faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  typedef typename Derived1::Scalar Scalar;
515c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static inline void run(Derived1 &dst, const Derived2 &src)
516c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
517c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    for(Index j = 0; j < dst.cols(); ++j)
518c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
519c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      Index maxi = (std::min)(j, dst.rows());
520c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      for(Index i = 0; i < maxi; ++i)
521c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        dst.copyCoeff(i, j, src);
522c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      if (ClearOpposite)
523c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        for(Index i = maxi; i < dst.rows(); ++i)
5247faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez          dst.coeffRef(i, j) = Scalar(0);
525c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
526c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
527c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
528c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
529c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Derived1, typename Derived2, bool ClearOpposite>
530c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct triangular_assignment_selector<Derived1, Derived2, StrictlyLower, Dynamic, ClearOpposite>
531c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
532c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef typename Derived1::Index Index;
533c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static inline void run(Derived1 &dst, const Derived2 &src)
534c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
535c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    for(Index j = 0; j < dst.cols(); ++j)
536c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
537c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      for(Index i = j+1; i < dst.rows(); ++i)
538c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        dst.copyCoeff(i, j, src);
539c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      Index maxi = (std::min)(j, dst.rows()-1);
540c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      if (ClearOpposite)
541c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        for(Index i = 0; i <= maxi; ++i)
542c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath          dst.coeffRef(i, j) = static_cast<typename Derived1::Scalar>(0);
543c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
544c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
545c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
546c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
547c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Derived1, typename Derived2, bool ClearOpposite>
548c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct triangular_assignment_selector<Derived1, Derived2, UnitUpper, Dynamic, ClearOpposite>
549c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
550c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef typename Derived1::Index Index;
551c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static inline void run(Derived1 &dst, const Derived2 &src)
552c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
553c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    for(Index j = 0; j < dst.cols(); ++j)
554c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
555c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      Index maxi = (std::min)(j, dst.rows());
556c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      for(Index i = 0; i < maxi; ++i)
557c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        dst.copyCoeff(i, j, src);
558c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      if (ClearOpposite)
559c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      {
560c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        for(Index i = maxi+1; i < dst.rows(); ++i)
561c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath          dst.coeffRef(i, j) = 0;
562c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      }
563c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
564c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    dst.diagonal().setOnes();
565c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
566c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
567c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Derived1, typename Derived2, bool ClearOpposite>
568c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct triangular_assignment_selector<Derived1, Derived2, UnitLower, Dynamic, ClearOpposite>
569c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
570c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef typename Derived1::Index Index;
571c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static inline void run(Derived1 &dst, const Derived2 &src)
572c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
573c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    for(Index j = 0; j < dst.cols(); ++j)
574c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
575c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      Index maxi = (std::min)(j, dst.rows());
576c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      for(Index i = maxi+1; i < dst.rows(); ++i)
577c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        dst.copyCoeff(i, j, src);
578c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      if (ClearOpposite)
579c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      {
580c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        for(Index i = 0; i < maxi; ++i)
581c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath          dst.coeffRef(i, j) = 0;
582c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      }
583c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
584c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    dst.diagonal().setOnes();
585c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
586c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
587c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
588c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} // end namespace internal
589c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
590c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// FIXME should we keep that possibility
591c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename MatrixType, unsigned int Mode>
592c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename OtherDerived>
593c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathinline TriangularView<MatrixType, Mode>&
594c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan KamathTriangularView<MatrixType, Mode>::operator=(const MatrixBase<OtherDerived>& other)
595c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
596c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  if(OtherDerived::Flags & EvalBeforeAssigningBit)
597c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
598c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typename internal::plain_matrix_type<OtherDerived>::type other_evaluated(other.rows(), other.cols());
599c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    other_evaluated.template triangularView<Mode>().lazyAssign(other.derived());
600c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    lazyAssign(other_evaluated);
601c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
602c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else
603c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    lazyAssign(other.derived());
604c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  return *this;
605c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
606c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
607c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// FIXME should we keep that possibility
608c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename MatrixType, unsigned int Mode>
609c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename OtherDerived>
610c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathvoid TriangularView<MatrixType, Mode>::lazyAssign(const MatrixBase<OtherDerived>& other)
611c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
612c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  enum {
613c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    unroll = MatrixType::SizeAtCompileTime != Dynamic
614c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath          && internal::traits<OtherDerived>::CoeffReadCost != Dynamic
615c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath          && MatrixType::SizeAtCompileTime*internal::traits<OtherDerived>::CoeffReadCost/2 <= EIGEN_UNROLLING_LIMIT
616c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  };
617c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  eigen_assert(m_matrix.rows() == other.rows() && m_matrix.cols() == other.cols());
618c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
619c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  internal::triangular_assignment_selector
620c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    <MatrixType, OtherDerived, int(Mode),
621c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    unroll ? int(MatrixType::SizeAtCompileTime) : Dynamic,
622c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    false // do not change the opposite triangular part
623c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    >::run(m_matrix.const_cast_derived(), other.derived());
624c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
625c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
626c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
627c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
628c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename MatrixType, unsigned int Mode>
629c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename OtherDerived>
630c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathinline TriangularView<MatrixType, Mode>&
631c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan KamathTriangularView<MatrixType, Mode>::operator=(const TriangularBase<OtherDerived>& other)
632c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
633c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  eigen_assert(Mode == int(OtherDerived::Mode));
634c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  if(internal::traits<OtherDerived>::Flags & EvalBeforeAssigningBit)
635c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
636c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typename OtherDerived::DenseMatrixType other_evaluated(other.rows(), other.cols());
637c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    other_evaluated.template triangularView<Mode>().lazyAssign(other.derived().nestedExpression());
638c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    lazyAssign(other_evaluated);
639c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
640c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else
641c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    lazyAssign(other.derived().nestedExpression());
642c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  return *this;
643c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
644c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
645c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename MatrixType, unsigned int Mode>
646c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename OtherDerived>
647c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathvoid TriangularView<MatrixType, Mode>::lazyAssign(const TriangularBase<OtherDerived>& other)
648c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
649c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  enum {
650c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    unroll = MatrixType::SizeAtCompileTime != Dynamic
651c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                   && internal::traits<OtherDerived>::CoeffReadCost != Dynamic
652c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                   && MatrixType::SizeAtCompileTime * internal::traits<OtherDerived>::CoeffReadCost / 2
653c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                        <= EIGEN_UNROLLING_LIMIT
654c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  };
655c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  eigen_assert(m_matrix.rows() == other.rows() && m_matrix.cols() == other.cols());
656c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
657c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  internal::triangular_assignment_selector
658c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    <MatrixType, OtherDerived, int(Mode),
659c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    unroll ? int(MatrixType::SizeAtCompileTime) : Dynamic,
660c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    false // preserve the opposite triangular part
661c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    >::run(m_matrix.const_cast_derived(), other.derived().nestedExpression());
662c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
663c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
664c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/***************************************************************************
665c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath* Implementation of TriangularBase methods
666c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath***************************************************************************/
667c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
668c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** Assigns a triangular or selfadjoint matrix to a dense matrix.
669c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * If the matrix is triangular, the opposite part is set to zero. */
670c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Derived>
671c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename DenseDerived>
672c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathvoid TriangularBase<Derived>::evalTo(MatrixBase<DenseDerived> &other) const
673c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
674c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  if(internal::traits<Derived>::Flags & EvalBeforeAssigningBit)
675c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
676c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typename internal::plain_matrix_type<Derived>::type other_evaluated(rows(), cols());
677c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    evalToLazy(other_evaluated);
678c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    other.derived().swap(other_evaluated);
679c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
680c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  else
681c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    evalToLazy(other.derived());
682c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}
683c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
684c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** Assigns a triangular or selfadjoint matrix to a dense matrix.
685c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  * If the matrix is triangular, the opposite part is set to zero. */
686c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Derived>
687c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename DenseDerived>
688c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathvoid TriangularBase<Derived>::evalToLazy(MatrixBase<DenseDerived> &other) const
689c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
690c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  enum {
691c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    unroll = DenseDerived::SizeAtCompileTime != Dynamic
692c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                   && internal::traits<Derived>::CoeffReadCost != Dynamic
693c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                   && DenseDerived::SizeAtCompileTime * internal::traits<Derived>::CoeffReadCost / 2
694c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                        <= EIGEN_UNROLLING_LIMIT
695c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  };
696c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  other.derived().resize(this->rows(), this->cols());
697c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
698c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  internal::triangular_assignment_selector
699c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    <DenseDerived, typename internal::traits<Derived>::MatrixTypeNestedCleaned, Derived::Mode,
700c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    unroll ? int(DenseDerived::SizeAtCompileTime) : Dynamic,
701c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    true // clear the opposite triangular part
702