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