// This file is part of Eigen, a lightweight C++ template library // for linear algebra. // // Copyright (C) 2009 Gael Guennebaud // // Eigen is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 3 of the License, or (at your option) any later version. // // Alternatively, you can redistribute it and/or // modify it under the terms of the GNU General Public License as // published by the Free Software Foundation; either version 2 of // the License, or (at your option) any later version. // // Eigen is distributed in the hope that it will be useful, but WITHOUT ANY // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the // GNU General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License and a copy of the GNU General Public License along with // Eigen. If not, see . #ifndef EIGEN_TRIANGULARMATRIXVECTOR_H #define EIGEN_TRIANGULARMATRIXVECTOR_H template struct ei_product_triangular_vector_selector; template struct ei_product_triangular_vector_selector { typedef typename Rhs::Scalar Scalar; enum { IsLower = ((Mode&Lower)==Lower), HasUnitDiag = (Mode & UnitDiag)==UnitDiag }; static EIGEN_DONT_INLINE void run(const Lhs& lhs, const Rhs& rhs, Result& res, typename ei_traits::Scalar alpha) { static const int PanelWidth = EIGEN_TUNE_TRIANGULAR_PANEL_WIDTH; typename ei_conj_expr_if::ret cjLhs(lhs); typename ei_conj_expr_if::ret cjRhs(rhs); int size = lhs.cols(); for (int pi=0; pi0) res.segment(s,r) += (alpha * cjRhs.coeff(i)) * cjLhs.col(i).segment(s,r); if (HasUnitDiag) res.coeffRef(i) += alpha * cjRhs.coeff(i); } int r = IsLower ? size - pi - actualPanelWidth : pi; if (r>0) { int s = IsLower ? pi+actualPanelWidth : 0; ei_cache_friendly_product_colmajor_times_vector( r, &(lhs.const_cast_derived().coeffRef(s,pi)), lhs.outerStride(), rhs.segment(pi, actualPanelWidth), &(res.coeffRef(s)), alpha); } } } }; template struct ei_product_triangular_vector_selector { typedef typename Rhs::Scalar Scalar; enum { IsLower = ((Mode&Lower)==Lower), HasUnitDiag = (Mode & UnitDiag)==UnitDiag }; static void run(const Lhs& lhs, const Rhs& rhs, Result& res, typename ei_traits::Scalar alpha) { static const int PanelWidth = EIGEN_TUNE_TRIANGULAR_PANEL_WIDTH; typename ei_conj_expr_if::ret cjLhs(lhs); typename ei_conj_expr_if::ret cjRhs(rhs); int size = lhs.cols(); for (int pi=0; pi0) 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); } int r = IsLower ? pi : size - pi - actualPanelWidth; if (r>0) { int s = IsLower ? 0 : pi + actualPanelWidth; Block target(res,pi,0,actualPanelWidth,1); ei_cache_friendly_product_rowmajor_times_vector( &(lhs.const_cast_derived().coeffRef(pi,s)), lhs.outerStride(), &(rhs.const_cast_derived().coeffRef(s)), r, target, alpha); } } } }; /*************************************************************************** * Wrapper to ei_product_triangular_vector ***************************************************************************/ template struct ei_traits > : ei_traits, Lhs, Rhs> > {}; template struct TriangularProduct : public ProductBase, Lhs, Rhs > { EIGEN_PRODUCT_PUBLIC_INTERFACE(TriangularProduct) TriangularProduct(const Lhs& lhs, const Rhs& rhs) : Base(lhs,rhs) {} template void scaleAndAddTo(Dest& dst, Scalar alpha) const { ei_assert(dst.rows()==m_lhs.rows() && dst.cols()==m_rhs.cols()); const ActualLhsType lhs = LhsBlasTraits::extract(m_lhs); const ActualRhsType rhs = RhsBlasTraits::extract(m_rhs); Scalar actualAlpha = alpha * LhsBlasTraits::extractScalarFactor(m_lhs) * RhsBlasTraits::extractScalarFactor(m_rhs); ei_product_triangular_vector_selector <_ActualLhsType,_ActualRhsType,Dest, Mode, LhsBlasTraits::NeedToConjugate, RhsBlasTraits::NeedToConjugate, (int(ei_traits::Flags)&RowMajorBit) ? RowMajor : ColMajor> ::run(lhs,rhs,dst,actualAlpha); } }; #endif // EIGEN_TRIANGULARMATRIXVECTOR_H