1c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// This file is part of Eigen, a lightweight C++ template library
2c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// for linear algebra.
3c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath//
4c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.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_TRIANGULARMATRIXVECTOR_H
11c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#define EIGEN_TRIANGULARMATRIXVECTOR_H
12c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
13c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathnamespace Eigen {
14c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
15c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathnamespace internal {
16c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
17c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Index, int Mode, typename LhsScalar, bool ConjLhs, typename RhsScalar, bool ConjRhs, int StorageOrder, int Version=Specialized>
18c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct triangular_matrix_vector_product;
19c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
20c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Index, int Mode, typename LhsScalar, bool ConjLhs, typename RhsScalar, bool ConjRhs, int Version>
21c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct triangular_matrix_vector_product<Index,Mode,LhsScalar,ConjLhs,RhsScalar,ConjRhs,ColMajor,Version>
22c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
23c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef typename scalar_product_traits<LhsScalar, RhsScalar>::ReturnType ResScalar;
24c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  enum {
25c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    IsLower = ((Mode&Lower)==Lower),
26c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    HasUnitDiag = (Mode & UnitDiag)==UnitDiag,
27c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    HasZeroDiag = (Mode & ZeroDiag)==ZeroDiag
28c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  };
29c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  static EIGEN_DONT_INLINE  void run(Index _rows, Index _cols, const LhsScalar* _lhs, Index lhsStride,
307faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez                                     const RhsScalar* _rhs, Index rhsIncr, ResScalar* _res, Index resIncr, const ResScalar& alpha);
317faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez};
327faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
337faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandeztemplate<typename Index, int Mode, typename LhsScalar, bool ConjLhs, typename RhsScalar, bool ConjRhs, int Version>
347faaa9f3f0df9d23790277834d426c3d992ac3baCarlos HernandezEIGEN_DONT_INLINE void triangular_matrix_vector_product<Index,Mode,LhsScalar,ConjLhs,RhsScalar,ConjRhs,ColMajor,Version>
357faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  ::run(Index _rows, Index _cols, const LhsScalar* _lhs, Index lhsStride,
367faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        const RhsScalar* _rhs, Index rhsIncr, ResScalar* _res, Index resIncr, const ResScalar& alpha)
37c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
38c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    static const Index PanelWidth = EIGEN_TUNE_TRIANGULAR_PANEL_WIDTH;
39c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    Index size = (std::min)(_rows,_cols);
40c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    Index rows = IsLower ? _rows : (std::min)(_rows,_cols);
41c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    Index cols = IsLower ? (std::min)(_rows,_cols) : _cols;
42c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
43c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef Map<const Matrix<LhsScalar,Dynamic,Dynamic,ColMajor>, 0, OuterStride<> > LhsMap;
44c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    const LhsMap lhs(_lhs,rows,cols,OuterStride<>(lhsStride));
45c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typename conj_expr_if<ConjLhs,LhsMap>::type cjLhs(lhs);
46c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
47c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef Map<const Matrix<RhsScalar,Dynamic,1>, 0, InnerStride<> > RhsMap;
48c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    const RhsMap rhs(_rhs,cols,InnerStride<>(rhsIncr));
49c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typename conj_expr_if<ConjRhs,RhsMap>::type cjRhs(rhs);
50c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
51c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef Map<Matrix<ResScalar,Dynamic,1> > ResMap;
52c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    ResMap res(_res,rows);
53c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
54c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    for (Index pi=0; pi<size; pi+=PanelWidth)
55c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
56c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      Index actualPanelWidth = (std::min)(PanelWidth, size-pi);
57c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      for (Index k=0; k<actualPanelWidth; ++k)
58c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      {
59c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        Index i = pi + k;
60c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        Index s = IsLower ? ((HasUnitDiag||HasZeroDiag) ? i+1 : i ) : pi;
61c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        Index r = IsLower ? actualPanelWidth-k : k+1;
62c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        if ((!(HasUnitDiag||HasZeroDiag)) || (--r)>0)
63c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath          res.segment(s,r) += (alpha * cjRhs.coeff(i)) * cjLhs.col(i).segment(s,r);
64c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        if (HasUnitDiag)
65c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath          res.coeffRef(i) += alpha * cjRhs.coeff(i);
66c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      }
67c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      Index r = IsLower ? rows - pi - actualPanelWidth : pi;
68c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      if (r>0)
69c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      {
70c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        Index s = IsLower ? pi+actualPanelWidth : 0;
71c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        general_matrix_vector_product<Index,LhsScalar,ColMajor,ConjLhs,RhsScalar,ConjRhs,BuiltIn>::run(
72c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath            r, actualPanelWidth,
73c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath            &lhs.coeffRef(s,pi), lhsStride,
74c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath            &rhs.coeffRef(pi), rhsIncr,
75c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath            &res.coeffRef(s), resIncr, alpha);
76c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      }
77c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
78c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    if((!IsLower) && cols>size)
79c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
80c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      general_matrix_vector_product<Index,LhsScalar,ColMajor,ConjLhs,RhsScalar,ConjRhs>::run(
81c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath          rows, cols-size,
82c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath          &lhs.coeffRef(0,size), lhsStride,
83c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath          &rhs.coeffRef(size), rhsIncr,
84c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath          _res, resIncr, alpha);
85c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
86c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
87c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
88c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Index, int Mode, typename LhsScalar, bool ConjLhs, typename RhsScalar, bool ConjRhs,int Version>
89c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct triangular_matrix_vector_product<Index,Mode,LhsScalar,ConjLhs,RhsScalar,ConjRhs,RowMajor,Version>
90c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
91c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  typedef typename scalar_product_traits<LhsScalar, RhsScalar>::ReturnType ResScalar;
92c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  enum {
93c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    IsLower = ((Mode&Lower)==Lower),
94c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    HasUnitDiag = (Mode & UnitDiag)==UnitDiag,
95c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    HasZeroDiag = (Mode & ZeroDiag)==ZeroDiag
96c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  };
977faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  static EIGEN_DONT_INLINE void run(Index _rows, Index _cols, const LhsScalar* _lhs, Index lhsStride,
987faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez                                    const RhsScalar* _rhs, Index rhsIncr, ResScalar* _res, Index resIncr, const ResScalar& alpha);
997faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez};
1007faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez
1017faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandeztemplate<typename Index, int Mode, typename LhsScalar, bool ConjLhs, typename RhsScalar, bool ConjRhs,int Version>
1027faaa9f3f0df9d23790277834d426c3d992ac3baCarlos HernandezEIGEN_DONT_INLINE void triangular_matrix_vector_product<Index,Mode,LhsScalar,ConjLhs,RhsScalar,ConjRhs,RowMajor,Version>
1037faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  ::run(Index _rows, Index _cols, const LhsScalar* _lhs, Index lhsStride,
1047faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez        const RhsScalar* _rhs, Index rhsIncr, ResScalar* _res, Index resIncr, const ResScalar& alpha)
105c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
106c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    static const Index PanelWidth = EIGEN_TUNE_TRIANGULAR_PANEL_WIDTH;
107c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    Index diagSize = (std::min)(_rows,_cols);
108c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    Index rows = IsLower ? _rows : diagSize;
109c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    Index cols = IsLower ? diagSize : _cols;
110c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
111c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef Map<const Matrix<LhsScalar,Dynamic,Dynamic,RowMajor>, 0, OuterStride<> > LhsMap;
112c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    const LhsMap lhs(_lhs,rows,cols,OuterStride<>(lhsStride));
113c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typename conj_expr_if<ConjLhs,LhsMap>::type cjLhs(lhs);
114c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
115c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef Map<const Matrix<RhsScalar,Dynamic,1> > RhsMap;
116c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    const RhsMap rhs(_rhs,cols);
117c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typename conj_expr_if<ConjRhs,RhsMap>::type cjRhs(rhs);
118c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
119c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef Map<Matrix<ResScalar,Dynamic,1>, 0, InnerStride<> > ResMap;
120c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    ResMap res(_res,rows,InnerStride<>(resIncr));
121c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
122c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    for (Index pi=0; pi<diagSize; pi+=PanelWidth)
123c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
124c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      Index actualPanelWidth = (std::min)(PanelWidth, diagSize-pi);
125c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      for (Index k=0; k<actualPanelWidth; ++k)
126c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      {
127c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        Index i = pi + k;
128c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        Index s = IsLower ? pi  : ((HasUnitDiag||HasZeroDiag) ? i+1 : i);
129c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        Index r = IsLower ? k+1 : actualPanelWidth-k;
130c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        if ((!(HasUnitDiag||HasZeroDiag)) || (--r)>0)
131c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath          res.coeffRef(i) += alpha * (cjLhs.row(i).segment(s,r).cwiseProduct(cjRhs.segment(s,r).transpose())).sum();
132c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        if (HasUnitDiag)
133c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath          res.coeffRef(i) += alpha * cjRhs.coeff(i);
134c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      }
135c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      Index r = IsLower ? pi : cols - pi - actualPanelWidth;
136c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      if (r>0)
137c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      {
138c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        Index s = IsLower ? 0 : pi + actualPanelWidth;
139c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        general_matrix_vector_product<Index,LhsScalar,RowMajor,ConjLhs,RhsScalar,ConjRhs,BuiltIn>::run(
140c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath            actualPanelWidth, r,
141c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath            &lhs.coeffRef(pi,s), lhsStride,
142c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath            &rhs.coeffRef(s), rhsIncr,
143c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath            &res.coeffRef(pi), resIncr, alpha);
144c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      }
145c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
146c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    if(IsLower && rows>diagSize)
147c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
148c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      general_matrix_vector_product<Index,LhsScalar,RowMajor,ConjLhs,RhsScalar,ConjRhs>::run(
149c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath            rows-diagSize, cols,
150c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath            &lhs.coeffRef(diagSize,0), lhsStride,
151c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath            &rhs.coeffRef(0), rhsIncr,
152c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath            &res.coeffRef(diagSize), resIncr, alpha);
153c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
154c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
155c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
156c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/***************************************************************************
157c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath* Wrapper to product_triangular_vector
158c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath***************************************************************************/
159c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
160c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<int Mode, bool LhsIsTriangular, typename Lhs, typename Rhs>
161c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct traits<TriangularProduct<Mode,LhsIsTriangular,Lhs,false,Rhs,true> >
162c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath : traits<ProductBase<TriangularProduct<Mode,LhsIsTriangular,Lhs,false,Rhs,true>, Lhs, Rhs> >
163c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{};
164c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
165c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<int Mode, bool LhsIsTriangular, typename Lhs, typename Rhs>
166c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct traits<TriangularProduct<Mode,LhsIsTriangular,Lhs,true,Rhs,false> >
167c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath : traits<ProductBase<TriangularProduct<Mode,LhsIsTriangular,Lhs,true,Rhs,false>, Lhs, Rhs> >
168c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{};
169c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
170c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
171c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<int StorageOrder>
172c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct trmv_selector;
173c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
174c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} // end namespace internal
175c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
176c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<int Mode, typename Lhs, typename Rhs>
177c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct TriangularProduct<Mode,true,Lhs,false,Rhs,true>
178c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  : public ProductBase<TriangularProduct<Mode,true,Lhs,false,Rhs,true>, Lhs, Rhs >
179c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
180c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  EIGEN_PRODUCT_PUBLIC_INTERFACE(TriangularProduct)
181c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
182c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  TriangularProduct(const Lhs& lhs, const Rhs& rhs) : Base(lhs,rhs) {}
183c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
1847faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  template<typename Dest> void scaleAndAddTo(Dest& dst, const Scalar& alpha) const
185c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
186c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    eigen_assert(dst.rows()==m_lhs.rows() && dst.cols()==m_rhs.cols());
187c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
188c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    internal::trmv_selector<(int(internal::traits<Lhs>::Flags)&RowMajorBit) ? RowMajor : ColMajor>::run(*this, dst, alpha);
189c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
190c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
191c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
192c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<int Mode, typename Lhs, typename Rhs>
193c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct TriangularProduct<Mode,false,Lhs,true,Rhs,false>
194c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  : public ProductBase<TriangularProduct<Mode,false,Lhs,true,Rhs,false>, Lhs, Rhs >
195c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
196c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  EIGEN_PRODUCT_PUBLIC_INTERFACE(TriangularProduct)
197c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
198c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  TriangularProduct(const Lhs& lhs, const Rhs& rhs) : Base(lhs,rhs) {}
199c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
2007faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  template<typename Dest> void scaleAndAddTo(Dest& dst, const Scalar& alpha) const
201c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
202c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    eigen_assert(dst.rows()==m_lhs.rows() && dst.cols()==m_rhs.cols());
203c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
204c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef TriangularProduct<(Mode & (UnitDiag|ZeroDiag)) | ((Mode & Lower) ? Upper : Lower),true,Transpose<const Rhs>,false,Transpose<const Lhs>,true> TriangularProductTranspose;
205c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    Transpose<Dest> dstT(dst);
206c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    internal::trmv_selector<(int(internal::traits<Rhs>::Flags)&RowMajorBit) ? ColMajor : RowMajor>::run(
207c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      TriangularProductTranspose(m_rhs.transpose(),m_lhs.transpose()), dstT, alpha);
208c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
209c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
210c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
211c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathnamespace internal {
212c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
213c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// TODO: find a way to factorize this piece of code with gemv_selector since the logic is exactly the same.
214c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
215c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<> struct trmv_selector<ColMajor>
216c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
217c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  template<int Mode, typename Lhs, typename Rhs, typename Dest>
2187faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  static void run(const TriangularProduct<Mode,true,Lhs,false,Rhs,true>& prod, Dest& dest, const typename TriangularProduct<Mode,true,Lhs,false,Rhs,true>::Scalar& alpha)
219c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
220c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef TriangularProduct<Mode,true,Lhs,false,Rhs,true> ProductType;
221c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename ProductType::Index Index;
222c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename ProductType::LhsScalar   LhsScalar;
223c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename ProductType::RhsScalar   RhsScalar;
224c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename ProductType::Scalar      ResScalar;
225c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename ProductType::RealScalar  RealScalar;
226c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename ProductType::ActualLhsType ActualLhsType;
227c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename ProductType::ActualRhsType ActualRhsType;
228c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename ProductType::LhsBlasTraits LhsBlasTraits;
229c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename ProductType::RhsBlasTraits RhsBlasTraits;
230c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef Map<Matrix<ResScalar,Dynamic,1>, Aligned> MappedDest;
231c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
232c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typename internal::add_const_on_value_type<ActualLhsType>::type actualLhs = LhsBlasTraits::extract(prod.lhs());
233c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typename internal::add_const_on_value_type<ActualRhsType>::type actualRhs = RhsBlasTraits::extract(prod.rhs());
234c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
235c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    ResScalar actualAlpha = alpha * LhsBlasTraits::extractScalarFactor(prod.lhs())
236c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                                  * RhsBlasTraits::extractScalarFactor(prod.rhs());
237c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
238c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    enum {
239c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      // FIXME find a way to allow an inner stride on the result if packet_traits<Scalar>::size==1
240c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      // on, the other hand it is good for the cache to pack the vector anyways...
241c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      EvalToDestAtCompileTime = Dest::InnerStrideAtCompileTime==1,
242c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      ComplexByReal = (NumTraits<LhsScalar>::IsComplex) && (!NumTraits<RhsScalar>::IsComplex),
243c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      MightCannotUseDest = (Dest::InnerStrideAtCompileTime!=1) || ComplexByReal
244c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    };
245c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
246c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    gemv_static_vector_if<ResScalar,Dest::SizeAtCompileTime,Dest::MaxSizeAtCompileTime,MightCannotUseDest> static_dest;
247c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
2487faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez    bool alphaIsCompatible = (!ComplexByReal) || (numext::imag(actualAlpha)==RealScalar(0));
249c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    bool evalToDest = EvalToDestAtCompileTime && alphaIsCompatible;
250c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
251c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    RhsScalar compatibleAlpha = get_factor<ResScalar,RhsScalar>::run(actualAlpha);
252c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
253c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    ei_declare_aligned_stack_constructed_variable(ResScalar,actualDestPtr,dest.size(),
254c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                                                  evalToDest ? dest.data() : static_dest.data());
255c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
256c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    if(!evalToDest)
257c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
258c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      #ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN
2597faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez      Index size = dest.size();
260c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      EIGEN_DENSE_STORAGE_CTOR_PLUGIN
261c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      #endif
262c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      if(!alphaIsCompatible)
263c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      {
264c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        MappedDest(actualDestPtr, dest.size()).setZero();
265c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        compatibleAlpha = RhsScalar(1);
266c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      }
267c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      else
268c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        MappedDest(actualDestPtr, dest.size()) = dest;
269c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
270c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
271c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    internal::triangular_matrix_vector_product
272c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      <Index,Mode,
273c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath       LhsScalar, LhsBlasTraits::NeedToConjugate,
274c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath       RhsScalar, RhsBlasTraits::NeedToConjugate,
275c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath       ColMajor>
276c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      ::run(actualLhs.rows(),actualLhs.cols(),
277c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath            actualLhs.data(),actualLhs.outerStride(),
278c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath            actualRhs.data(),actualRhs.innerStride(),
279c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath            actualDestPtr,1,compatibleAlpha);
280c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
281c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    if (!evalToDest)
282c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
283c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      if(!alphaIsCompatible)
284c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        dest += actualAlpha * MappedDest(actualDestPtr, dest.size());
285c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      else
286c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        dest = MappedDest(actualDestPtr, dest.size());
287c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
288c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
289c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
290c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
291c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<> struct trmv_selector<RowMajor>
292c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{
293c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  template<int Mode, typename Lhs, typename Rhs, typename Dest>
2947faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez  static void run(const TriangularProduct<Mode,true,Lhs,false,Rhs,true>& prod, Dest& dest, const typename TriangularProduct<Mode,true,Lhs,false,Rhs,true>::Scalar& alpha)
295c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  {
296c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef TriangularProduct<Mode,true,Lhs,false,Rhs,true> ProductType;
297c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename ProductType::LhsScalar LhsScalar;
298c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename ProductType::RhsScalar RhsScalar;
299c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename ProductType::Scalar    ResScalar;
300c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename ProductType::Index Index;
301c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename ProductType::ActualLhsType ActualLhsType;
302c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename ProductType::ActualRhsType ActualRhsType;
303c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename ProductType::_ActualRhsType _ActualRhsType;
304c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename ProductType::LhsBlasTraits LhsBlasTraits;
305c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typedef typename ProductType::RhsBlasTraits RhsBlasTraits;
306c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
307c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typename add_const<ActualLhsType>::type actualLhs = LhsBlasTraits::extract(prod.lhs());
308c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    typename add_const<ActualRhsType>::type actualRhs = RhsBlasTraits::extract(prod.rhs());
309c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
310c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    ResScalar actualAlpha = alpha * LhsBlasTraits::extractScalarFactor(prod.lhs())
311c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath                                  * RhsBlasTraits::extractScalarFactor(prod.rhs());
312c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
313c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    enum {
314c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      DirectlyUseRhs = _ActualRhsType::InnerStrideAtCompileTime==1
315c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    };
316c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
317c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    gemv_static_vector_if<RhsScalar,_ActualRhsType::SizeAtCompileTime,_ActualRhsType::MaxSizeAtCompileTime,!DirectlyUseRhs> static_rhs;
318c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
319c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    ei_declare_aligned_stack_constructed_variable(RhsScalar,actualRhsPtr,actualRhs.size(),
320c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath        DirectlyUseRhs ? const_cast<RhsScalar*>(actualRhs.data()) : static_rhs.data());
321c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
322c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    if(!DirectlyUseRhs)
323c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    {
324c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      #ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN
325c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      int size = actualRhs.size();
326c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      EIGEN_DENSE_STORAGE_CTOR_PLUGIN
327c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      #endif
328c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      Map<typename _ActualRhsType::PlainObject>(actualRhsPtr, actualRhs.size()) = actualRhs;
329c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    }
330c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
331c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath    internal::triangular_matrix_vector_product
332c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      <Index,Mode,
333c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath       LhsScalar, LhsBlasTraits::NeedToConjugate,
334c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath       RhsScalar, RhsBlasTraits::NeedToConjugate,
335c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath       RowMajor>
336c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath      ::run(actualLhs.rows(),actualLhs.cols(),
337c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath            actualLhs.data(),actualLhs.outerStride(),
338c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath            actualRhsPtr,1,
339c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath            dest.data(),dest.innerStride(),
340c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath            actualAlpha);
341c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath  }
342c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath};
343c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
344c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} // end namespace internal
345c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
346c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} // end namespace Eigen
347c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath
348c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#endif // EIGEN_TRIANGULARMATRIXVECTOR_H
349