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 132b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangnamespace 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{ 232b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename ScalarBinaryOpTraits<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, 302b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang const RhsScalar* _rhs, Index rhsIncr, ResScalar* _res, Index resIncr, const RhsScalar& 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, 362b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang const RhsScalar* _rhs, Index rhsIncr, ResScalar* _res, Index resIncr, const RhsScalar& 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); 462b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 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 542b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef const_blas_data_mapper<LhsScalar,Index,ColMajor> LhsMapper; 552b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef const_blas_data_mapper<RhsScalar,Index,RowMajor> RhsMapper; 562b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 57c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath for (Index pi=0; pi<size; pi+=PanelWidth) 58c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 59c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index actualPanelWidth = (std::min)(PanelWidth, size-pi); 60c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath for (Index k=0; k<actualPanelWidth; ++k) 61c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 62c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index i = pi + k; 63c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index s = IsLower ? ((HasUnitDiag||HasZeroDiag) ? i+1 : i ) : pi; 64c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index r = IsLower ? actualPanelWidth-k : k+1; 65c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if ((!(HasUnitDiag||HasZeroDiag)) || (--r)>0) 66c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath res.segment(s,r) += (alpha * cjRhs.coeff(i)) * cjLhs.col(i).segment(s,r); 67c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if (HasUnitDiag) 68c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath res.coeffRef(i) += alpha * cjRhs.coeff(i); 69c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 70c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index r = IsLower ? rows - pi - actualPanelWidth : pi; 71c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if (r>0) 72c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 73c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index s = IsLower ? pi+actualPanelWidth : 0; 742b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang general_matrix_vector_product<Index,LhsScalar,LhsMapper,ColMajor,ConjLhs,RhsScalar,RhsMapper,ConjRhs,BuiltIn>::run( 75c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath r, actualPanelWidth, 762b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang LhsMapper(&lhs.coeffRef(s,pi), lhsStride), 772b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang RhsMapper(&rhs.coeffRef(pi), rhsIncr), 78c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath &res.coeffRef(s), resIncr, alpha); 79c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 80c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 81c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if((!IsLower) && cols>size) 82c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 832b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang general_matrix_vector_product<Index,LhsScalar,LhsMapper,ColMajor,ConjLhs,RhsScalar,RhsMapper,ConjRhs>::run( 84c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath rows, cols-size, 852b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang LhsMapper(&lhs.coeffRef(0,size), lhsStride), 862b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang RhsMapper(&rhs.coeffRef(size), rhsIncr), 87c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath _res, resIncr, alpha); 88c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 89c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 90c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 91c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Index, int Mode, typename LhsScalar, bool ConjLhs, typename RhsScalar, bool ConjRhs,int Version> 92c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct triangular_matrix_vector_product<Index,Mode,LhsScalar,ConjLhs,RhsScalar,ConjRhs,RowMajor,Version> 93c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 942b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename ScalarBinaryOpTraits<LhsScalar, RhsScalar>::ReturnType ResScalar; 95c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath enum { 96c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath IsLower = ((Mode&Lower)==Lower), 97c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath HasUnitDiag = (Mode & UnitDiag)==UnitDiag, 98c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath HasZeroDiag = (Mode & ZeroDiag)==ZeroDiag 99c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath }; 1007faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez static EIGEN_DONT_INLINE void run(Index _rows, Index _cols, const LhsScalar* _lhs, Index lhsStride, 1017faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez const RhsScalar* _rhs, Index rhsIncr, ResScalar* _res, Index resIncr, const ResScalar& alpha); 1027faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez}; 1037faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 1047faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandeztemplate<typename Index, int Mode, typename LhsScalar, bool ConjLhs, typename RhsScalar, bool ConjRhs,int Version> 1057faaa9f3f0df9d23790277834d426c3d992ac3baCarlos HernandezEIGEN_DONT_INLINE void triangular_matrix_vector_product<Index,Mode,LhsScalar,ConjLhs,RhsScalar,ConjRhs,RowMajor,Version> 1067faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez ::run(Index _rows, Index _cols, const LhsScalar* _lhs, Index lhsStride, 1077faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez const RhsScalar* _rhs, Index rhsIncr, ResScalar* _res, Index resIncr, const ResScalar& alpha) 108c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 109c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath static const Index PanelWidth = EIGEN_TUNE_TRIANGULAR_PANEL_WIDTH; 110c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index diagSize = (std::min)(_rows,_cols); 111c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index rows = IsLower ? _rows : diagSize; 112c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index cols = IsLower ? diagSize : _cols; 113c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 114c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef Map<const Matrix<LhsScalar,Dynamic,Dynamic,RowMajor>, 0, OuterStride<> > LhsMap; 115c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath const LhsMap lhs(_lhs,rows,cols,OuterStride<>(lhsStride)); 116c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typename conj_expr_if<ConjLhs,LhsMap>::type cjLhs(lhs); 117c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 118c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef Map<const Matrix<RhsScalar,Dynamic,1> > RhsMap; 119c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath const RhsMap rhs(_rhs,cols); 120c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typename conj_expr_if<ConjRhs,RhsMap>::type cjRhs(rhs); 121c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 122c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef Map<Matrix<ResScalar,Dynamic,1>, 0, InnerStride<> > ResMap; 123c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ResMap res(_res,rows,InnerStride<>(resIncr)); 1242b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 1252b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef const_blas_data_mapper<LhsScalar,Index,RowMajor> LhsMapper; 1262b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef const_blas_data_mapper<RhsScalar,Index,RowMajor> RhsMapper; 1272b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 128c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath for (Index pi=0; pi<diagSize; pi+=PanelWidth) 129c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 130c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index actualPanelWidth = (std::min)(PanelWidth, diagSize-pi); 131c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath for (Index k=0; k<actualPanelWidth; ++k) 132c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 133c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index i = pi + k; 134c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index s = IsLower ? pi : ((HasUnitDiag||HasZeroDiag) ? i+1 : i); 135c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index r = IsLower ? k+1 : actualPanelWidth-k; 136c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if ((!(HasUnitDiag||HasZeroDiag)) || (--r)>0) 137c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath res.coeffRef(i) += alpha * (cjLhs.row(i).segment(s,r).cwiseProduct(cjRhs.segment(s,r).transpose())).sum(); 138c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if (HasUnitDiag) 139c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath res.coeffRef(i) += alpha * cjRhs.coeff(i); 140c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 141c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index r = IsLower ? pi : cols - pi - actualPanelWidth; 142c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if (r>0) 143c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 144c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index s = IsLower ? 0 : pi + actualPanelWidth; 1452b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang general_matrix_vector_product<Index,LhsScalar,LhsMapper,RowMajor,ConjLhs,RhsScalar,RhsMapper,ConjRhs,BuiltIn>::run( 146c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath actualPanelWidth, r, 1472b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang LhsMapper(&lhs.coeffRef(pi,s), lhsStride), 1482b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang RhsMapper(&rhs.coeffRef(s), rhsIncr), 149c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath &res.coeffRef(pi), resIncr, alpha); 150c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 151c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 152c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if(IsLower && rows>diagSize) 153c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 1542b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang general_matrix_vector_product<Index,LhsScalar,LhsMapper,RowMajor,ConjLhs,RhsScalar,RhsMapper,ConjRhs>::run( 155c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath rows-diagSize, cols, 1562b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang LhsMapper(&lhs.coeffRef(diagSize,0), lhsStride), 1572b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang RhsMapper(&rhs.coeffRef(0), rhsIncr), 158c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath &res.coeffRef(diagSize), resIncr, alpha); 159c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 160c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 161c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 162c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/*************************************************************************** 163c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath* Wrapper to product_triangular_vector 164c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath***************************************************************************/ 165c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 1662b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<int Mode,int StorageOrder> 167c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct trmv_selector; 168c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 169c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} // end namespace internal 170c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 1712b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangnamespace internal { 1722b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 173c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<int Mode, typename Lhs, typename Rhs> 1742b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct triangular_product_impl<Mode,true,Lhs,false,Rhs,true> 175c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 1762b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang template<typename Dest> static void run(Dest& dst, const Lhs &lhs, const Rhs &rhs, const typename Dest::Scalar& alpha) 177c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 1782b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang eigen_assert(dst.rows()==lhs.rows() && dst.cols()==rhs.cols()); 179c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 1802b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang internal::trmv_selector<Mode,(int(internal::traits<Lhs>::Flags)&RowMajorBit) ? RowMajor : ColMajor>::run(lhs, rhs, dst, alpha); 181c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 182c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 183c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 184c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<int Mode, typename Lhs, typename Rhs> 1852b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangstruct triangular_product_impl<Mode,false,Lhs,true,Rhs,false> 186c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 1872b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang template<typename Dest> static void run(Dest& dst, const Lhs &lhs, const Rhs &rhs, const typename Dest::Scalar& alpha) 188c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 1892b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang eigen_assert(dst.rows()==lhs.rows() && dst.cols()==rhs.cols()); 190c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 191c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Transpose<Dest> dstT(dst); 1922b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang internal::trmv_selector<(Mode & (UnitDiag|ZeroDiag)) | ((Mode & Lower) ? Upper : Lower), 1932b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang (int(internal::traits<Rhs>::Flags)&RowMajorBit) ? ColMajor : RowMajor> 1942b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang ::run(rhs.transpose(),lhs.transpose(), dstT, alpha); 195c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 196c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 197c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 1982b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang} // end namespace internal 1992b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 200c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathnamespace internal { 201c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 202c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath// TODO: find a way to factorize this piece of code with gemv_selector since the logic is exactly the same. 203c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 2042b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<int Mode> struct trmv_selector<Mode,ColMajor> 205c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 2062b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang template<typename Lhs, typename Rhs, typename Dest> 2072b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang static void run(const Lhs &lhs, const Rhs &rhs, Dest& dest, const typename Dest::Scalar& alpha) 208c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 2092b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename Lhs::Scalar LhsScalar; 2102b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename Rhs::Scalar RhsScalar; 2112b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename Dest::Scalar ResScalar; 2122b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename Dest::RealScalar RealScalar; 2132b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 2142b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef internal::blas_traits<Lhs> LhsBlasTraits; 2152b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename LhsBlasTraits::DirectLinearAccessType ActualLhsType; 2162b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef internal::blas_traits<Rhs> RhsBlasTraits; 2172b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename RhsBlasTraits::DirectLinearAccessType ActualRhsType; 2182b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 2192b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef Map<Matrix<ResScalar,Dynamic,1>, EIGEN_PLAIN_ENUM_MIN(AlignedMax,internal::packet_traits<ResScalar>::size)> MappedDest; 2202b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 2212b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typename internal::add_const_on_value_type<ActualLhsType>::type actualLhs = LhsBlasTraits::extract(lhs); 2222b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typename internal::add_const_on_value_type<ActualRhsType>::type actualRhs = RhsBlasTraits::extract(rhs); 2232b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 2242b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang ResScalar actualAlpha = alpha * LhsBlasTraits::extractScalarFactor(lhs) 2252b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * RhsBlasTraits::extractScalarFactor(rhs); 226c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 227c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath enum { 228c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // FIXME find a way to allow an inner stride on the result if packet_traits<Scalar>::size==1 229c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // on, the other hand it is good for the cache to pack the vector anyways... 230c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath EvalToDestAtCompileTime = Dest::InnerStrideAtCompileTime==1, 231c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ComplexByReal = (NumTraits<LhsScalar>::IsComplex) && (!NumTraits<RhsScalar>::IsComplex), 232c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath MightCannotUseDest = (Dest::InnerStrideAtCompileTime!=1) || ComplexByReal 233c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath }; 234c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 235c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath gemv_static_vector_if<ResScalar,Dest::SizeAtCompileTime,Dest::MaxSizeAtCompileTime,MightCannotUseDest> static_dest; 236c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 2377faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez bool alphaIsCompatible = (!ComplexByReal) || (numext::imag(actualAlpha)==RealScalar(0)); 238c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath bool evalToDest = EvalToDestAtCompileTime && alphaIsCompatible; 2392b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 240c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath RhsScalar compatibleAlpha = get_factor<ResScalar,RhsScalar>::run(actualAlpha); 241c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 242c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ei_declare_aligned_stack_constructed_variable(ResScalar,actualDestPtr,dest.size(), 243c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath evalToDest ? dest.data() : static_dest.data()); 244c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 245c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if(!evalToDest) 246c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 247c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath #ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN 2487faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez Index size = dest.size(); 249c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath EIGEN_DENSE_STORAGE_CTOR_PLUGIN 250c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath #endif 251c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if(!alphaIsCompatible) 252c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 253c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath MappedDest(actualDestPtr, dest.size()).setZero(); 254c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath compatibleAlpha = RhsScalar(1); 255c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 256c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath else 257c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath MappedDest(actualDestPtr, dest.size()) = dest; 258c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 2592b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 260c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath internal::triangular_matrix_vector_product 261c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath <Index,Mode, 262c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath LhsScalar, LhsBlasTraits::NeedToConjugate, 263c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath RhsScalar, RhsBlasTraits::NeedToConjugate, 264c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ColMajor> 265c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ::run(actualLhs.rows(),actualLhs.cols(), 266c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath actualLhs.data(),actualLhs.outerStride(), 267c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath actualRhs.data(),actualRhs.innerStride(), 268c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath actualDestPtr,1,compatibleAlpha); 269c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 270c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if (!evalToDest) 271c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 272c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if(!alphaIsCompatible) 273c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath dest += actualAlpha * MappedDest(actualDestPtr, dest.size()); 274c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath else 275c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath dest = MappedDest(actualDestPtr, dest.size()); 276c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 277c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 278c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 279c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 2802b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wangtemplate<int Mode> struct trmv_selector<Mode,RowMajor> 281c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 2822b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang template<typename Lhs, typename Rhs, typename Dest> 2832b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang static void run(const Lhs &lhs, const Rhs &rhs, Dest& dest, const typename Dest::Scalar& alpha) 284c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 2852b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename Lhs::Scalar LhsScalar; 2862b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename Rhs::Scalar RhsScalar; 2872b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename Dest::Scalar ResScalar; 2882b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 2892b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef internal::blas_traits<Lhs> LhsBlasTraits; 2902b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename LhsBlasTraits::DirectLinearAccessType ActualLhsType; 2912b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef internal::blas_traits<Rhs> RhsBlasTraits; 2922b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename RhsBlasTraits::DirectLinearAccessType ActualRhsType; 2932b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typedef typename internal::remove_all<ActualRhsType>::type ActualRhsTypeCleaned; 2942b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 2952b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typename add_const<ActualLhsType>::type actualLhs = LhsBlasTraits::extract(lhs); 2962b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang typename add_const<ActualRhsType>::type actualRhs = RhsBlasTraits::extract(rhs); 2972b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 2982b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang ResScalar actualAlpha = alpha * LhsBlasTraits::extractScalarFactor(lhs) 2992b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang * RhsBlasTraits::extractScalarFactor(rhs); 300c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 301c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath enum { 3022b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang DirectlyUseRhs = ActualRhsTypeCleaned::InnerStrideAtCompileTime==1 303c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath }; 304c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 3052b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang gemv_static_vector_if<RhsScalar,ActualRhsTypeCleaned::SizeAtCompileTime,ActualRhsTypeCleaned::MaxSizeAtCompileTime,!DirectlyUseRhs> static_rhs; 306c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 307c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ei_declare_aligned_stack_constructed_variable(RhsScalar,actualRhsPtr,actualRhs.size(), 308c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath DirectlyUseRhs ? const_cast<RhsScalar*>(actualRhs.data()) : static_rhs.data()); 309c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 310c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if(!DirectlyUseRhs) 311c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 312c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath #ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN 3132b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang Index size = actualRhs.size(); 314c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath EIGEN_DENSE_STORAGE_CTOR_PLUGIN 315c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath #endif 3162b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang Map<typename ActualRhsTypeCleaned::PlainObject>(actualRhsPtr, actualRhs.size()) = actualRhs; 317c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 3182b8756b6f1de65d3f8bffab45be6c44ceb7411fcMiao Wang 319c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath internal::triangular_matrix_vector_product 320c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath <Index,Mode, 321c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath LhsScalar, LhsBlasTraits::NeedToConjugate, 322c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath RhsScalar, RhsBlasTraits::NeedToConjugate, 323c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath RowMajor> 324c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ::run(actualLhs.rows(),actualLhs.cols(), 325c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath actualLhs.data(),actualLhs.outerStride(), 326c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath actualRhsPtr,1, 327c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath dest.data(),dest.innerStride(), 328c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath actualAlpha); 329c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 330c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 331c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 332c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} // end namespace internal 333c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 334c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} // end namespace Eigen 335c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 336c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#endif // EIGEN_TRIANGULARMATRIXVECTOR_H 337