From 6feb1d3c0b103ef753b67ab0815be6f9cf7f4f28 Mon Sep 17 00:00:00 2001 From: Gael Guennebaud Date: Mon, 28 Mar 2011 17:42:26 +0200 Subject: [PATCH] fix trmv for Strictly* triangular matrices and trapezoidal matrices --- .../Core/products/TriangularMatrixVector.h | 52 ++++++++++++++----- 1 file changed, 38 insertions(+), 14 deletions(-) diff --git a/Eigen/src/Core/products/TriangularMatrixVector.h b/Eigen/src/Core/products/TriangularMatrixVector.h index 1dd2fafa4..2633d691a 100644 --- a/Eigen/src/Core/products/TriangularMatrixVector.h +++ b/Eigen/src/Core/products/TriangularMatrixVector.h @@ -36,12 +36,16 @@ struct product_triangular_matrix_vector::ReturnType ResScalar; enum { IsLower = ((Mode&Lower)==Lower), - HasUnitDiag = (Mode & UnitDiag)==UnitDiag + HasUnitDiag = (Mode & UnitDiag)==UnitDiag, + HasZeroDiag = (Mode & ZeroDiag)==ZeroDiag }; - static EIGEN_DONT_INLINE void run(Index rows, Index cols, const LhsScalar* _lhs, Index lhsStride, + static EIGEN_DONT_INLINE void run(Index _rows, Index _cols, const LhsScalar* _lhs, Index lhsStride, const RhsScalar* _rhs, Index rhsIncr, ResScalar* _res, Index resIncr, ResScalar alpha) { static const Index PanelWidth = EIGEN_TUNE_TRIANGULAR_PANEL_WIDTH; + Index size = std::min(_rows,_cols); + Index rows = IsLower ? _rows : std::min(_rows,_cols); + Index cols = IsLower ? std::min(_rows,_cols) : _cols; typedef Map, 0, OuterStride<> > LhsMap; const LhsMap lhs(_lhs,rows,cols,OuterStride<>(lhsStride)); @@ -54,20 +58,20 @@ struct product_triangular_matrix_vector > ResMap; ResMap res(_res,rows); - for (Index pi=0; pi0) + if ((!(HasUnitDiag||HasZeroDiag)) || (--r)>0) res.segment(s,r) += (alpha * cjRhs.coeff(i)) * cjLhs.col(i).segment(s,r); if (HasUnitDiag) res.coeffRef(i) += alpha * cjRhs.coeff(i); } - Index r = IsLower ? cols - pi - actualPanelWidth : pi; + Index r = IsLower ? rows - pi - actualPanelWidth : pi; if (r>0) { Index s = IsLower ? pi+actualPanelWidth : 0; @@ -78,6 +82,14 @@ struct product_triangular_matrix_vectorsize) + { + general_matrix_vector_product::run( + rows, cols-size, + &lhs.coeffRef(0,size), lhsStride, + &rhs.coeffRef(size), rhsIncr, + _res, resIncr, alpha); + } } }; @@ -87,12 +99,16 @@ struct product_triangular_matrix_vector::ReturnType ResScalar; enum { IsLower = ((Mode&Lower)==Lower), - HasUnitDiag = (Mode & UnitDiag)==UnitDiag + HasUnitDiag = (Mode & UnitDiag)==UnitDiag, + HasZeroDiag = (Mode & ZeroDiag)==ZeroDiag }; - static void run(Index rows, Index cols, const LhsScalar* _lhs, Index lhsStride, + static void run(Index _rows, Index _cols, const LhsScalar* _lhs, Index lhsStride, const RhsScalar* _rhs, Index rhsIncr, ResScalar* _res, Index resIncr, ResScalar alpha) { static const Index PanelWidth = EIGEN_TUNE_TRIANGULAR_PANEL_WIDTH; + Index diagSize = std::min(_rows,_cols); + Index rows = IsLower ? _rows : diagSize; + Index cols = IsLower ? diagSize : _cols; typedef Map, 0, OuterStride<> > LhsMap; const LhsMap lhs(_lhs,rows,cols,OuterStride<>(lhsStride)); @@ -105,15 +121,15 @@ struct product_triangular_matrix_vector, 0, InnerStride<> > ResMap; ResMap res(_res,rows,InnerStride<>(resIncr)); - for (Index pi=0; pi0) + if ((!(HasUnitDiag||HasZeroDiag)) || (--r)>0) res.coeffRef(i) += alpha * (cjLhs.row(i).segment(s,r).cwiseProduct(cjRhs.segment(s,r).transpose())).sum(); if (HasUnitDiag) res.coeffRef(i) += alpha * cjRhs.coeff(i); @@ -129,6 +145,14 @@ struct product_triangular_matrix_vectordiagSize) + { + general_matrix_vector_product::run( + rows-diagSize, cols, + &lhs.coeffRef(diagSize,0), lhsStride, + &rhs.coeffRef(0), rhsIncr, + &res.coeffRef(diagSize), resIncr, alpha); + } } }; @@ -180,7 +204,7 @@ struct TriangularProduct { eigen_assert(dst.rows()==m_lhs.rows() && dst.cols()==m_rhs.cols()); - typedef TriangularProduct<(Mode & UnitDiag) | ((Mode & Lower) ? Upper : Lower),true,Transpose,false,Transpose,true> TriangularProductTranspose; + typedef TriangularProduct<(Mode & (UnitDiag|ZeroDiag)) | ((Mode & Lower) ? Upper : Lower),true,Transpose,false,Transpose,true> TriangularProductTranspose; Transpose dstT(dst); internal::trmv_selector<(int(internal::traits::Flags)&RowMajorBit) ? ColMajor : RowMajor>::run( TriangularProductTranspose(m_rhs.transpose(),m_lhs.transpose()), dstT, alpha);