10 #ifndef EIGEN_TRIANGULARMATRIXVECTOR_H 11 #define EIGEN_TRIANGULARMATRIXVECTOR_H 17 template<
typename Index,
int Mode,
typename LhsScalar,
bool ConjLhs,
typename RhsScalar,
bool ConjRhs,
int StorageOrder,
int Version=Specialized>
20 template<
typename Index,
int Mode,
typename LhsScalar,
bool ConjLhs,
typename RhsScalar,
bool ConjRhs,
int Version>
29 static EIGEN_DONT_INLINE void run(Index _rows, Index _cols,
const LhsScalar* _lhs, Index lhsStride,
30 const RhsScalar* _rhs, Index rhsIncr, ResScalar* _res, Index resIncr,
const ResScalar& alpha);
33 template<
typename Index,
int Mode,
typename LhsScalar,
bool ConjLhs,
typename RhsScalar,
bool ConjRhs,
int Version>
35 ::run(Index _rows, Index _cols,
const LhsScalar* _lhs, Index lhsStride,
36 const RhsScalar* _rhs, Index rhsIncr, ResScalar* _res, Index resIncr,
const ResScalar& alpha)
39 Index size = (std::min)(_rows,_cols);
40 Index rows = IsLower ? _rows : (std::min)(_rows,_cols);
41 Index cols = IsLower ? (std::min)(_rows,_cols) : _cols;
52 ResMap res(_res,rows);
54 for (Index pi=0; pi<size; pi+=PanelWidth)
56 Index actualPanelWidth = (std::min)(PanelWidth, size-pi);
57 for (Index k=0; k<actualPanelWidth; ++k)
60 Index s = IsLower ? ((HasUnitDiag||HasZeroDiag) ? i+1 : i ) : pi;
61 Index r = IsLower ? actualPanelWidth-k : k+1;
62 if ((!(HasUnitDiag||HasZeroDiag)) || (--r)>0)
63 res.segment(s,r) += (alpha * cjRhs.coeff(i)) * cjLhs.col(i).segment(s,r);
65 res.coeffRef(i) += alpha * cjRhs.coeff(i);
67 Index r = IsLower ? rows - pi - actualPanelWidth : pi;
70 Index s = IsLower ? pi+actualPanelWidth : 0;
73 &lhs.coeffRef(s,pi), lhsStride,
74 &rhs.coeffRef(pi), rhsIncr,
75 &res.coeffRef(s), resIncr, alpha);
78 if((!IsLower) && cols>size)
82 &lhs.coeffRef(0,size), lhsStride,
83 &rhs.coeffRef(size), rhsIncr,
84 _res, resIncr, alpha);
88 template<
typename Index,
int Mode,
typename LhsScalar,
bool ConjLhs,
typename RhsScalar,
bool ConjRhs,
int Version>
97 static EIGEN_DONT_INLINE void run(Index _rows, Index _cols,
const LhsScalar* _lhs, Index lhsStride,
98 const RhsScalar* _rhs, Index rhsIncr, ResScalar* _res, Index resIncr,
const ResScalar& alpha);
101 template<
typename Index,
int Mode,
typename LhsScalar,
bool ConjLhs,
typename RhsScalar,
bool ConjRhs,
int Version>
103 ::run(Index _rows, Index _cols,
const LhsScalar* _lhs, Index lhsStride,
104 const RhsScalar* _rhs, Index rhsIncr, ResScalar* _res, Index resIncr,
const ResScalar& alpha)
107 Index diagSize = (std::min)(_rows,_cols);
108 Index rows = IsLower ? _rows : diagSize;
109 Index cols = IsLower ? diagSize : _cols;
116 const RhsMap
rhs(_rhs,cols);
122 for (Index pi=0; pi<diagSize; pi+=PanelWidth)
124 Index actualPanelWidth = (std::min)(PanelWidth, diagSize-pi);
125 for (Index k=0; k<actualPanelWidth; ++k)
128 Index s = IsLower ? pi : ((HasUnitDiag||HasZeroDiag) ? i+1 : i);
129 Index r = IsLower ? k+1 : actualPanelWidth-k;
130 if ((!(HasUnitDiag||HasZeroDiag)) || (--r)>0)
131 res.coeffRef(i) += alpha * (cjLhs.row(i).segment(s,r).cwiseProduct(cjRhs.segment(s,r).transpose())).sum();
133 res.coeffRef(i) += alpha * cjRhs.coeff(i);
135 Index r = IsLower ? pi : cols - pi - actualPanelWidth;
138 Index s = IsLower ? 0 : pi + actualPanelWidth;
141 &lhs.coeffRef(pi,s), lhsStride,
142 &rhs.coeffRef(s), rhsIncr,
143 &res.coeffRef(pi), resIncr, alpha);
146 if(IsLower && rows>diagSize)
150 &lhs.coeffRef(diagSize,0), lhsStride,
151 &rhs.coeffRef(0), rhsIncr,
152 &res.coeffRef(diagSize), resIncr, alpha);
160 template<
int Mode,
bool LhsIsTriangular,
typename Lhs,
typename Rhs>
162 :
traits<ProductBase<TriangularProduct<Mode,LhsIsTriangular,Lhs,false,Rhs,true>, Lhs, Rhs> >
165 template<
int Mode,
bool LhsIsTriangular,
typename Lhs,
typename Rhs>
167 :
traits<ProductBase<TriangularProduct<Mode,LhsIsTriangular,Lhs,true,Rhs,false>, Lhs, Rhs> >
171 template<
int StorageOrder>
176 template<
int Mode,
typename Lhs,
typename Rhs>
178 :
public ProductBase<TriangularProduct<Mode,true,Lhs,false,Rhs,true>, Lhs, Rhs >
186 eigen_assert(dst.rows()==m_lhs.rows() && dst.cols()==m_rhs.cols());
192 template<
int Mode,
typename Lhs,
typename Rhs>
194 :
public ProductBase<TriangularProduct<Mode,false,Lhs,true,Rhs,false>, Lhs, Rhs >
202 eigen_assert(dst.rows()==m_lhs.rows() && dst.cols()==m_rhs.cols());
207 TriangularProductTranspose(m_rhs.transpose(),m_lhs.transpose()), dstT, alpha);
217 template<
int Mode,
typename Lhs,
typename Rhs,
typename Dest>
218 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)
221 typedef typename ProductType::Index Index;
222 typedef typename ProductType::LhsScalar LhsScalar;
223 typedef typename ProductType::RhsScalar RhsScalar;
224 typedef typename ProductType::Scalar ResScalar;
225 typedef typename ProductType::RealScalar RealScalar;
226 typedef typename ProductType::ActualLhsType ActualLhsType;
227 typedef typename ProductType::ActualRhsType ActualRhsType;
228 typedef typename ProductType::LhsBlasTraits LhsBlasTraits;
229 typedef typename ProductType::RhsBlasTraits RhsBlasTraits;
235 ResScalar actualAlpha = alpha * LhsBlasTraits::extractScalarFactor(prod.
lhs())
236 * RhsBlasTraits::extractScalarFactor(prod.
rhs());
241 EvalToDestAtCompileTime = Dest::InnerStrideAtCompileTime==1,
243 MightCannotUseDest = (Dest::InnerStrideAtCompileTime!=1) || ComplexByReal
248 bool alphaIsCompatible = (!ComplexByReal) || (
numext::imag(actualAlpha)==RealScalar(0));
249 bool evalToDest = EvalToDestAtCompileTime && alphaIsCompatible;
254 evalToDest ? dest.data() : static_dest.data());
258 #ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN 259 Index size = dest.size();
260 EIGEN_DENSE_STORAGE_CTOR_PLUGIN
262 if(!alphaIsCompatible)
264 MappedDest(actualDestPtr, dest.size()).setZero();
265 compatibleAlpha = RhsScalar(1);
268 MappedDest(actualDestPtr, dest.size()) = dest;
273 LhsScalar, LhsBlasTraits::NeedToConjugate,
274 RhsScalar, RhsBlasTraits::NeedToConjugate,
276 ::run(actualLhs.rows(),actualLhs.cols(),
277 actualLhs.data(),actualLhs.outerStride(),
278 actualRhs.data(),actualRhs.innerStride(),
279 actualDestPtr,1,compatibleAlpha);
283 if(!alphaIsCompatible)
284 dest += actualAlpha * MappedDest(actualDestPtr, dest.size());
286 dest = MappedDest(actualDestPtr, dest.size());
293 template<
int Mode,
typename Lhs,
typename Rhs,
typename Dest>
294 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)
297 typedef typename ProductType::LhsScalar LhsScalar;
298 typedef typename ProductType::RhsScalar RhsScalar;
299 typedef typename ProductType::Scalar ResScalar;
300 typedef typename ProductType::Index Index;
301 typedef typename ProductType::ActualLhsType ActualLhsType;
302 typedef typename ProductType::ActualRhsType ActualRhsType;
303 typedef typename ProductType::_ActualRhsType _ActualRhsType;
304 typedef typename ProductType::LhsBlasTraits LhsBlasTraits;
305 typedef typename ProductType::RhsBlasTraits RhsBlasTraits;
310 ResScalar actualAlpha = alpha * LhsBlasTraits::extractScalarFactor(prod.
lhs())
311 * RhsBlasTraits::extractScalarFactor(prod.
rhs());
314 DirectlyUseRhs = _ActualRhsType::InnerStrideAtCompileTime==1
320 DirectlyUseRhs ?
const_cast<RhsScalar*
>(actualRhs.data()) : static_rhs.data());
324 #ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN 325 int size = actualRhs.size();
326 EIGEN_DENSE_STORAGE_CTOR_PLUGIN
333 LhsScalar, LhsBlasTraits::NeedToConjugate,
334 RhsScalar, RhsBlasTraits::NeedToConjugate,
336 ::run(actualLhs.
rows(),actualLhs.
cols(),
337 actualLhs.data(),actualLhs.outerStride(),
339 dest.data(),dest.innerStride(),
348 #endif // EIGEN_TRIANGULARMATRIXVECTOR_H
scalar_product_traits< LhsScalar, RhsScalar >::ReturnType ResScalar
#define EIGEN_PRODUCT_PUBLIC_INTERFACE(Derived)
void scaleAndAddTo(Dest &dst, const Scalar &alpha) const
internal::traits< Derived >::Scalar Scalar
#define ei_declare_aligned_stack_constructed_variable(TYPE, NAME, SIZE, BUFFER)
A matrix or vector expression mapping an existing array of data.
Expression of the transpose of a matrix.
iterative scaling algorithm to equilibrate rows and column norms in matrices
Holds information about the various numeric (i.e. scalar) types allowed by Eigen. ...
const unsigned int RowMajorBit
const ImagReturnType imag() const
scalar_product_traits< LhsScalar, RhsScalar >::ReturnType ResScalar
const _RhsNested & rhs() const
#define EIGEN_TUNE_TRIANGULAR_PANEL_WIDTH
Convenience specialization of Stride to specify only an inner stride See class Map for some examples...
void scaleAndAddTo(Dest &dst, const Scalar &alpha) const
const _LhsNested & lhs() const
void rhs(const real_t *x, real_t *f)
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)
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)
static EIGEN_STRONG_INLINE To run(const From &x)
#define EIGEN_DONT_INLINE
Convenience specialization of Stride to specify only an outer stride See class Map for some examples...