// This file is part of Eigen, a lightweight C++ template library // for linear algebra. // // Copyright (C) 2008-2010 Gael Guennebaud // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. #ifndef EIGEN_TRIANGULAR_SOLVER_VECTOR_H #define EIGEN_TRIANGULAR_SOLVER_VECTOR_H namespace Eigen { namespace internal { template struct triangular_solve_vector { static void run(Index size, const LhsScalar* _lhs, Index lhsStride, RhsScalar* rhs) { triangular_solve_vector::run(size, _lhs, lhsStride, rhs); } }; // forward and backward substitution, row-major, rhs is a vector template struct triangular_solve_vector { enum { IsLower = ((Mode&Lower)==Lower) }; static void run(Index size, const LhsScalar* _lhs, Index lhsStride, RhsScalar* rhs) { typedef Map, 0, OuterStride<> > LhsMap; const LhsMap lhs(_lhs,size,size,OuterStride<>(lhsStride)); typename internal::conditional< Conjugate, const CwiseUnaryOp,LhsMap>, const LhsMap&> ::type cjLhs(lhs); static const Index PanelWidth = EIGEN_TUNE_TRIANGULAR_PANEL_WIDTH; for(Index pi=IsLower ? 0 : size; IsLower ? pi0; IsLower ? pi+=PanelWidth : pi-=PanelWidth) { Index actualPanelWidth = (std::min)(IsLower ? size - pi : pi, PanelWidth); Index r = IsLower ? pi : size - pi; // remaining size if (r > 0) { // let's directly call the low level product function because: // 1 - it is faster to compile // 2 - it is slighlty faster at runtime Index startRow = IsLower ? pi : pi-actualPanelWidth; Index startCol = IsLower ? 0 : pi; general_matrix_vector_product::run( actualPanelWidth, r, &lhs.coeffRef(startRow,startCol), lhsStride, rhs + startCol, 1, rhs + startRow, 1, RhsScalar(-1)); } for(Index k=0; k0) rhs[i] -= (cjLhs.row(i).segment(s,k).transpose().cwiseProduct(Map >(rhs+s,k))).sum(); if(!(Mode & UnitDiag)) rhs[i] /= cjLhs(i,i); } } } }; // forward and backward substitution, column-major, rhs is a vector template struct triangular_solve_vector { enum { IsLower = ((Mode&Lower)==Lower) }; static void run(Index size, const LhsScalar* _lhs, Index lhsStride, RhsScalar* rhs) { typedef Map, 0, OuterStride<> > LhsMap; const LhsMap lhs(_lhs,size,size,OuterStride<>(lhsStride)); typename internal::conditional,LhsMap>, const LhsMap& >::type cjLhs(lhs); static const Index PanelWidth = EIGEN_TUNE_TRIANGULAR_PANEL_WIDTH; for(Index pi=IsLower ? 0 : size; IsLower ? pi0; IsLower ? pi+=PanelWidth : pi-=PanelWidth) { Index actualPanelWidth = (std::min)(IsLower ? size - pi : pi, PanelWidth); Index startBlock = IsLower ? pi : pi-actualPanelWidth; Index endBlock = IsLower ? pi + actualPanelWidth : 0; for(Index k=0; k0) Map >(rhs+s,r) -= rhs[i] * cjLhs.col(i).segment(s,r); } Index r = IsLower ? size - endBlock : startBlock; // remaining size if (r > 0) { // let's directly call the low level product function because: // 1 - it is faster to compile // 2 - it is slighlty faster at runtime general_matrix_vector_product::run( r, actualPanelWidth, &lhs.coeffRef(endBlock,startBlock), lhsStride, rhs+startBlock, 1, rhs+endBlock, 1, RhsScalar(-1)); } } } }; } // end namespace internal } // end namespace Eigen #endif // EIGEN_TRIANGULAR_SOLVER_VECTOR_H