10#ifndef EIGEN_TRIANGULARMATRIXVECTOR_H
11#define EIGEN_TRIANGULARMATRIXVECTOR_H
17template<
typename Index,
int Mode,
typename LhsScalar,
bool ConjLhs,
typename RhsScalar,
bool ConjRhs,
int StorageOrder,
int Version=Specialized>
18struct triangular_matrix_vector_product;
20template<
typename Index,
int Mode,
typename LhsScalar,
bool ConjLhs,
typename RhsScalar,
bool ConjRhs,
int Version>
21struct triangular_matrix_vector_product<
Index,Mode,LhsScalar,ConjLhs,RhsScalar,ConjRhs,
ColMajor,Version>
23 typedef typename ScalarBinaryOpTraits<LhsScalar, RhsScalar>::ReturnType ResScalar;
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 RhsScalar& alpha);
33template<
typename Index,
int Mode,
typename LhsScalar,
bool ConjLhs,
typename RhsScalar,
bool ConjRhs,
int Version>
34EIGEN_DONT_INLINE
void triangular_matrix_vector_product<Index,Mode,LhsScalar,ConjLhs,RhsScalar,ConjRhs,ColMajor,Version>
36 const RhsScalar* _rhs,
Index rhsIncr, ResScalar* _res,
Index resIncr,
const RhsScalar& alpha)
38 static const Index PanelWidth = EIGEN_TUNE_TRIANGULAR_PANEL_WIDTH;
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;
43 typedef Map<const Matrix<LhsScalar,Dynamic,Dynamic,ColMajor>, 0, OuterStride<> > LhsMap;
44 const LhsMap lhs(_lhs,rows,cols,OuterStride<>(lhsStride));
45 typename conj_expr_if<ConjLhs,LhsMap>::type cjLhs(lhs);
47 typedef Map<const Matrix<RhsScalar,Dynamic,1>, 0, InnerStride<> > RhsMap;
48 const RhsMap rhs(_rhs,cols,InnerStride<>(rhsIncr));
49 typename conj_expr_if<ConjRhs,RhsMap>::type cjRhs(rhs);
51 typedef Map<Matrix<ResScalar,Dynamic,1> > ResMap;
52 ResMap res(_res,rows);
54 typedef const_blas_data_mapper<LhsScalar,Index,ColMajor> LhsMapper;
55 typedef const_blas_data_mapper<RhsScalar,Index,RowMajor> RhsMapper;
57 for (
Index pi=0; pi<size; pi+=PanelWidth)
59 Index actualPanelWidth = (std::min)(PanelWidth, size-pi);
60 for (
Index k=0; k<actualPanelWidth; ++k)
63 Index s = IsLower ? ((HasUnitDiag||HasZeroDiag) ? i+1 : i ) : pi;
64 Index r = IsLower ? actualPanelWidth-k : k+1;
65 if ((!(HasUnitDiag||HasZeroDiag)) || (--r)>0)
66 res.segment(s,r) += (alpha * cjRhs.coeff(i)) * cjLhs.col(i).segment(s,r);
68 res.coeffRef(i) += alpha * cjRhs.coeff(i);
70 Index r = IsLower ? rows - pi - actualPanelWidth : pi;
73 Index s = IsLower ? pi+actualPanelWidth : 0;
74 general_matrix_vector_product<Index,LhsScalar,LhsMapper,ColMajor,ConjLhs,RhsScalar,RhsMapper,ConjRhs,BuiltIn>::run(
76 LhsMapper(&lhs.coeffRef(s,pi), lhsStride),
77 RhsMapper(&rhs.coeffRef(pi), rhsIncr),
78 &res.coeffRef(s), resIncr, alpha);
81 if((!IsLower) && cols>size)
83 general_matrix_vector_product<Index,LhsScalar,LhsMapper,ColMajor,ConjLhs,RhsScalar,RhsMapper,ConjRhs>::run(
85 LhsMapper(&lhs.coeffRef(0,size), lhsStride),
86 RhsMapper(&rhs.coeffRef(size), rhsIncr),
87 _res, resIncr, alpha);
91template<
typename Index,
int Mode,
typename LhsScalar,
bool ConjLhs,
typename RhsScalar,
bool ConjRhs,
int Version>
92struct triangular_matrix_vector_product<
Index,Mode,LhsScalar,ConjLhs,RhsScalar,ConjRhs,
RowMajor,Version>
94 typedef typename ScalarBinaryOpTraits<LhsScalar, RhsScalar>::ReturnType ResScalar;
100 static EIGEN_DONT_INLINE
void run(
Index _rows,
Index _cols,
const LhsScalar* _lhs,
Index lhsStride,
101 const RhsScalar* _rhs,
Index rhsIncr, ResScalar* _res,
Index resIncr,
const ResScalar& alpha);
104template<
typename Index,
int Mode,
typename LhsScalar,
bool ConjLhs,
typename RhsScalar,
bool ConjRhs,
int Version>
105EIGEN_DONT_INLINE
void triangular_matrix_vector_product<Index,Mode,LhsScalar,ConjLhs,RhsScalar,ConjRhs,RowMajor,Version>
106 ::run(
Index _rows,
Index _cols,
const LhsScalar* _lhs,
Index lhsStride,
107 const RhsScalar* _rhs,
Index rhsIncr, ResScalar* _res,
Index resIncr,
const ResScalar& alpha)
109 static const Index PanelWidth = EIGEN_TUNE_TRIANGULAR_PANEL_WIDTH;
110 Index diagSize = (std::min)(_rows,_cols);
111 Index rows = IsLower ? _rows : diagSize;
112 Index cols = IsLower ? diagSize : _cols;
114 typedef Map<const Matrix<LhsScalar,Dynamic,Dynamic,RowMajor>, 0, OuterStride<> > LhsMap;
115 const LhsMap lhs(_lhs,rows,cols,OuterStride<>(lhsStride));
116 typename conj_expr_if<ConjLhs,LhsMap>::type cjLhs(lhs);
118 typedef Map<const Matrix<RhsScalar,Dynamic,1> > RhsMap;
119 const RhsMap rhs(_rhs,cols);
120 typename conj_expr_if<ConjRhs,RhsMap>::type cjRhs(rhs);
122 typedef Map<Matrix<ResScalar,Dynamic,1>, 0, InnerStride<> > ResMap;
123 ResMap res(_res,rows,InnerStride<>(resIncr));
125 typedef const_blas_data_mapper<LhsScalar,Index,RowMajor> LhsMapper;
126 typedef const_blas_data_mapper<RhsScalar,Index,RowMajor> RhsMapper;
128 for (
Index pi=0; pi<diagSize; pi+=PanelWidth)
130 Index actualPanelWidth = (std::min)(PanelWidth, diagSize-pi);
131 for (
Index k=0; k<actualPanelWidth; ++k)
134 Index s = IsLower ? pi : ((HasUnitDiag||HasZeroDiag) ? i+1 : i);
135 Index r = IsLower ? k+1 : actualPanelWidth-k;
136 if ((!(HasUnitDiag||HasZeroDiag)) || (--r)>0)
137 res.coeffRef(i) += alpha * (cjLhs.row(i).segment(s,r).cwiseProduct(cjRhs.segment(s,r).transpose())).sum();
139 res.coeffRef(i) += alpha * cjRhs.coeff(i);
141 Index r = IsLower ? pi : cols - pi - actualPanelWidth;
144 Index s = IsLower ? 0 : pi + actualPanelWidth;
145 general_matrix_vector_product<Index,LhsScalar,LhsMapper,RowMajor,ConjLhs,RhsScalar,RhsMapper,ConjRhs,BuiltIn>::run(
147 LhsMapper(&lhs.coeffRef(pi,s), lhsStride),
148 RhsMapper(&rhs.coeffRef(s), rhsIncr),
149 &res.coeffRef(pi), resIncr, alpha);
152 if(IsLower && rows>diagSize)
154 general_matrix_vector_product<Index,LhsScalar,LhsMapper,RowMajor,ConjLhs,RhsScalar,RhsMapper,ConjRhs>::run(
156 LhsMapper(&lhs.coeffRef(diagSize,0), lhsStride),
157 RhsMapper(&rhs.coeffRef(0), rhsIncr),
158 &res.coeffRef(diagSize), resIncr, alpha);
166template<
int Mode,
int StorageOrder>
173template<
int Mode,
typename Lhs,
typename Rhs>
174struct triangular_product_impl<Mode,true,Lhs,false,Rhs,true>
176 template<
typename Dest>
static void run(Dest& dst,
const Lhs &lhs,
const Rhs &rhs,
const typename Dest::Scalar& alpha)
178 eigen_assert(dst.rows()==lhs.rows() && dst.cols()==rhs.cols());
184template<
int Mode,
typename Lhs,
typename Rhs>
185struct triangular_product_impl<Mode,false,Lhs,true,Rhs,false>
187 template<
typename Dest>
static void run(Dest& dst,
const Lhs &lhs,
const Rhs &rhs,
const typename Dest::Scalar& alpha)
189 eigen_assert(dst.rows()==lhs.rows() && dst.cols()==rhs.cols());
191 Transpose<Dest> dstT(dst);
194 ::run(rhs.transpose(),lhs.transpose(), dstT, alpha);
204template<
int Mode>
struct trmv_selector<Mode,
ColMajor>
206 template<
typename Lhs,
typename Rhs,
typename Dest>
207 static void run(
const Lhs &lhs,
const Rhs &rhs, Dest& dest,
const typename Dest::Scalar& alpha)
209 typedef typename Lhs::Scalar LhsScalar;
210 typedef typename Rhs::Scalar RhsScalar;
211 typedef typename Dest::Scalar ResScalar;
212 typedef typename Dest::RealScalar RealScalar;
214 typedef internal::blas_traits<Lhs> LhsBlasTraits;
215 typedef typename LhsBlasTraits::DirectLinearAccessType ActualLhsType;
216 typedef internal::blas_traits<Rhs> RhsBlasTraits;
217 typedef typename RhsBlasTraits::DirectLinearAccessType ActualRhsType;
219 typedef Map<Matrix<ResScalar,Dynamic,1>, EIGEN_PLAIN_ENUM_MIN(AlignedMax,internal::packet_traits<ResScalar>::size)> MappedDest;
221 typename internal::add_const_on_value_type<ActualLhsType>::type actualLhs = LhsBlasTraits::extract(lhs);
222 typename internal::add_const_on_value_type<ActualRhsType>::type actualRhs = RhsBlasTraits::extract(rhs);
224 LhsScalar lhs_alpha = LhsBlasTraits::extractScalarFactor(lhs);
225 RhsScalar rhs_alpha = RhsBlasTraits::extractScalarFactor(rhs);
226 ResScalar actualAlpha = alpha * lhs_alpha * rhs_alpha;
231 EvalToDestAtCompileTime = Dest::InnerStrideAtCompileTime==1,
232 ComplexByReal = (NumTraits<LhsScalar>::IsComplex) && (!NumTraits<RhsScalar>::IsComplex),
233 MightCannotUseDest = (Dest::InnerStrideAtCompileTime!=1) || ComplexByReal
236 gemv_static_vector_if<ResScalar,Dest::SizeAtCompileTime,Dest::MaxSizeAtCompileTime,MightCannotUseDest> static_dest;
238 bool alphaIsCompatible = (!ComplexByReal) || (numext::imag(actualAlpha)==RealScalar(0));
239 bool evalToDest = EvalToDestAtCompileTime && alphaIsCompatible;
241 RhsScalar compatibleAlpha = get_factor<ResScalar,RhsScalar>::run(actualAlpha);
243 ei_declare_aligned_stack_constructed_variable(ResScalar,actualDestPtr,dest.size(),
244 evalToDest ? dest.data() : static_dest.data());
248 #ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN
249 Index size = dest.size();
250 EIGEN_DENSE_STORAGE_CTOR_PLUGIN
252 if(!alphaIsCompatible)
254 MappedDest(actualDestPtr, dest.size()).setZero();
255 compatibleAlpha = RhsScalar(1);
258 MappedDest(actualDestPtr, dest.size()) = dest;
261 internal::triangular_matrix_vector_product
263 LhsScalar, LhsBlasTraits::NeedToConjugate,
264 RhsScalar, RhsBlasTraits::NeedToConjugate,
266 ::run(actualLhs.rows(),actualLhs.cols(),
267 actualLhs.data(),actualLhs.outerStride(),
268 actualRhs.data(),actualRhs.innerStride(),
269 actualDestPtr,1,compatibleAlpha);
273 if(!alphaIsCompatible)
274 dest += actualAlpha * MappedDest(actualDestPtr, dest.size());
276 dest = MappedDest(actualDestPtr, dest.size());
281 Index diagSize = (std::min)(lhs.rows(),lhs.cols());
282 dest.head(diagSize) -= (lhs_alpha-LhsScalar(1))*rhs.head(diagSize);
287template<
int Mode>
struct trmv_selector<Mode,
RowMajor>
289 template<
typename Lhs,
typename Rhs,
typename Dest>
290 static void run(
const Lhs &lhs,
const Rhs &rhs, Dest& dest,
const typename Dest::Scalar& alpha)
292 typedef typename Lhs::Scalar LhsScalar;
293 typedef typename Rhs::Scalar RhsScalar;
294 typedef typename Dest::Scalar ResScalar;
296 typedef internal::blas_traits<Lhs> LhsBlasTraits;
297 typedef typename LhsBlasTraits::DirectLinearAccessType ActualLhsType;
298 typedef internal::blas_traits<Rhs> RhsBlasTraits;
299 typedef typename RhsBlasTraits::DirectLinearAccessType ActualRhsType;
300 typedef typename internal::remove_all<ActualRhsType>::type ActualRhsTypeCleaned;
302 typename add_const<ActualLhsType>::type actualLhs = LhsBlasTraits::extract(lhs);
303 typename add_const<ActualRhsType>::type actualRhs = RhsBlasTraits::extract(rhs);
305 LhsScalar lhs_alpha = LhsBlasTraits::extractScalarFactor(lhs);
306 RhsScalar rhs_alpha = RhsBlasTraits::extractScalarFactor(rhs);
307 ResScalar actualAlpha = alpha * lhs_alpha * rhs_alpha;
310 DirectlyUseRhs = ActualRhsTypeCleaned::InnerStrideAtCompileTime==1
313 gemv_static_vector_if<RhsScalar,ActualRhsTypeCleaned::SizeAtCompileTime,ActualRhsTypeCleaned::MaxSizeAtCompileTime,!DirectlyUseRhs> static_rhs;
315 ei_declare_aligned_stack_constructed_variable(RhsScalar,actualRhsPtr,actualRhs.size(),
316 DirectlyUseRhs ?
const_cast<RhsScalar*
>(actualRhs.data()) : static_rhs.data());
320 #ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN
321 Index size = actualRhs.size();
322 EIGEN_DENSE_STORAGE_CTOR_PLUGIN
324 Map<typename ActualRhsTypeCleaned::PlainObject>(actualRhsPtr, actualRhs.size()) = actualRhs;
327 internal::triangular_matrix_vector_product
329 LhsScalar, LhsBlasTraits::NeedToConjugate,
330 RhsScalar, RhsBlasTraits::NeedToConjugate,
332 ::run(actualLhs.rows(),actualLhs.cols(),
333 actualLhs.data(),actualLhs.outerStride(),
335 dest.data(),dest.innerStride(),
340 Index diagSize = (std::min)(lhs.rows(),lhs.cols());
341 dest.head(diagSize) -= (lhs_alpha-LhsScalar(1))*rhs.head(diagSize);
@ UnitDiag
Definition Constants.h:208
@ ZeroDiag
Definition Constants.h:210
@ Lower
Definition Constants.h:204
@ Upper
Definition Constants.h:206
@ ColMajor
Definition Constants.h:320
@ RowMajor
Definition Constants.h:322
const unsigned int RowMajorBit
Definition Constants.h:61
Namespace containing all symbols from the Eigen library.
Definition A05_PortingFrom2To3.dox:1
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition Meta.h:65