File indexing completed on 2025-01-18 09:57:07
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef EIGEN_SKYLINEPRODUCT_H
0011 #define EIGEN_SKYLINEPRODUCT_H
0012
0013 namespace Eigen {
0014
0015 template<typename Lhs, typename Rhs, int ProductMode>
0016 struct SkylineProductReturnType {
0017 typedef const typename internal::nested_eval<Lhs, Rhs::RowsAtCompileTime>::type LhsNested;
0018 typedef const typename internal::nested_eval<Rhs, Lhs::RowsAtCompileTime>::type RhsNested;
0019
0020 typedef SkylineProduct<LhsNested, RhsNested, ProductMode> Type;
0021 };
0022
0023 template<typename LhsNested, typename RhsNested, int ProductMode>
0024 struct internal::traits<SkylineProduct<LhsNested, RhsNested, ProductMode> > {
0025
0026 typedef typename internal::remove_all<LhsNested>::type _LhsNested;
0027 typedef typename internal::remove_all<RhsNested>::type _RhsNested;
0028 typedef typename _LhsNested::Scalar Scalar;
0029
0030 enum {
0031 LhsCoeffReadCost = _LhsNested::CoeffReadCost,
0032 RhsCoeffReadCost = _RhsNested::CoeffReadCost,
0033 LhsFlags = _LhsNested::Flags,
0034 RhsFlags = _RhsNested::Flags,
0035
0036 RowsAtCompileTime = _LhsNested::RowsAtCompileTime,
0037 ColsAtCompileTime = _RhsNested::ColsAtCompileTime,
0038 InnerSize = EIGEN_SIZE_MIN_PREFER_FIXED(_LhsNested::ColsAtCompileTime, _RhsNested::RowsAtCompileTime),
0039
0040 MaxRowsAtCompileTime = _LhsNested::MaxRowsAtCompileTime,
0041 MaxColsAtCompileTime = _RhsNested::MaxColsAtCompileTime,
0042
0043 EvalToRowMajor = (RhsFlags & LhsFlags & RowMajorBit),
0044 ResultIsSkyline = ProductMode == SkylineTimeSkylineProduct,
0045
0046 RemovedBits = ~((EvalToRowMajor ? 0 : RowMajorBit) | (ResultIsSkyline ? 0 : SkylineBit)),
0047
0048 Flags = (int(LhsFlags | RhsFlags) & HereditaryBits & RemovedBits)
0049 | EvalBeforeAssigningBit
0050 | EvalBeforeNestingBit,
0051
0052 CoeffReadCost = HugeCost
0053 };
0054
0055 typedef typename internal::conditional<ResultIsSkyline,
0056 SkylineMatrixBase<SkylineProduct<LhsNested, RhsNested, ProductMode> >,
0057 MatrixBase<SkylineProduct<LhsNested, RhsNested, ProductMode> > >::type Base;
0058 };
0059
0060 namespace internal {
0061 template<typename LhsNested, typename RhsNested, int ProductMode>
0062 class SkylineProduct : no_assignment_operator,
0063 public traits<SkylineProduct<LhsNested, RhsNested, ProductMode> >::Base {
0064 public:
0065
0066 EIGEN_GENERIC_PUBLIC_INTERFACE(SkylineProduct)
0067
0068 private:
0069
0070 typedef typename traits<SkylineProduct>::_LhsNested _LhsNested;
0071 typedef typename traits<SkylineProduct>::_RhsNested _RhsNested;
0072
0073 public:
0074
0075 template<typename Lhs, typename Rhs>
0076 EIGEN_STRONG_INLINE SkylineProduct(const Lhs& lhs, const Rhs& rhs)
0077 : m_lhs(lhs), m_rhs(rhs) {
0078 eigen_assert(lhs.cols() == rhs.rows());
0079
0080 enum {
0081 ProductIsValid = _LhsNested::ColsAtCompileTime == Dynamic
0082 || _RhsNested::RowsAtCompileTime == Dynamic
0083 || int(_LhsNested::ColsAtCompileTime) == int(_RhsNested::RowsAtCompileTime),
0084 AreVectors = _LhsNested::IsVectorAtCompileTime && _RhsNested::IsVectorAtCompileTime,
0085 SameSizes = EIGEN_PREDICATE_SAME_MATRIX_SIZE(_LhsNested, _RhsNested)
0086 };
0087
0088
0089
0090 EIGEN_STATIC_ASSERT(ProductIsValid || !(AreVectors && SameSizes),
0091 INVALID_VECTOR_VECTOR_PRODUCT__IF_YOU_WANTED_A_DOT_OR_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTIONS)
0092 EIGEN_STATIC_ASSERT(ProductIsValid || !(SameSizes && !AreVectors),
0093 INVALID_MATRIX_PRODUCT__IF_YOU_WANTED_A_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTION)
0094 EIGEN_STATIC_ASSERT(ProductIsValid || SameSizes, INVALID_MATRIX_PRODUCT)
0095 }
0096
0097 EIGEN_STRONG_INLINE Index rows() const {
0098 return m_lhs.rows();
0099 }
0100
0101 EIGEN_STRONG_INLINE Index cols() const {
0102 return m_rhs.cols();
0103 }
0104
0105 EIGEN_STRONG_INLINE const _LhsNested& lhs() const {
0106 return m_lhs;
0107 }
0108
0109 EIGEN_STRONG_INLINE const _RhsNested& rhs() const {
0110 return m_rhs;
0111 }
0112
0113 protected:
0114 LhsNested m_lhs;
0115 RhsNested m_rhs;
0116 };
0117
0118
0119
0120
0121 template<typename Lhs, typename Rhs, typename Dest>
0122 EIGEN_DONT_INLINE void skyline_row_major_time_dense_product(const Lhs& lhs, const Rhs& rhs, Dest& dst) {
0123 typedef typename remove_all<Lhs>::type _Lhs;
0124 typedef typename remove_all<Rhs>::type _Rhs;
0125 typedef typename traits<Lhs>::Scalar Scalar;
0126
0127 enum {
0128 LhsIsRowMajor = (_Lhs::Flags & RowMajorBit) == RowMajorBit,
0129 LhsIsSelfAdjoint = (_Lhs::Flags & SelfAdjointBit) == SelfAdjointBit,
0130 ProcessFirstHalf = LhsIsSelfAdjoint
0131 && (((_Lhs::Flags & (UpperTriangularBit | LowerTriangularBit)) == 0)
0132 || ((_Lhs::Flags & UpperTriangularBit) && !LhsIsRowMajor)
0133 || ((_Lhs::Flags & LowerTriangularBit) && LhsIsRowMajor)),
0134 ProcessSecondHalf = LhsIsSelfAdjoint && (!ProcessFirstHalf)
0135 };
0136
0137
0138 for (Index col = 0; col < rhs.cols(); col++) {
0139 for (Index row = 0; row < lhs.rows(); row++) {
0140 dst(row, col) = lhs.coeffDiag(row) * rhs(row, col);
0141 }
0142 }
0143
0144 for (Index row = 0; row < lhs.rows(); row++) {
0145 typename _Lhs::InnerLowerIterator lIt(lhs, row);
0146 const Index stop = lIt.col() + lIt.size();
0147 for (Index col = 0; col < rhs.cols(); col++) {
0148
0149 Index k = lIt.col();
0150 Scalar tmp = 0;
0151 while (k < stop) {
0152 tmp +=
0153 lIt.value() *
0154 rhs(k++, col);
0155 ++lIt;
0156 }
0157 dst(row, col) += tmp;
0158 lIt += -lIt.size();
0159 }
0160
0161 }
0162
0163
0164 for (Index lhscol = 0; lhscol < lhs.cols(); lhscol++) {
0165 typename _Lhs::InnerUpperIterator uIt(lhs, lhscol);
0166 const Index stop = uIt.size() + uIt.row();
0167 for (Index rhscol = 0; rhscol < rhs.cols(); rhscol++) {
0168
0169
0170 const Scalar rhsCoeff = rhs.coeff(lhscol, rhscol);
0171 Index k = uIt.row();
0172 while (k < stop) {
0173 dst(k++, rhscol) +=
0174 uIt.value() *
0175 rhsCoeff;
0176 ++uIt;
0177 }
0178 uIt += -uIt.size();
0179 }
0180 }
0181
0182 }
0183
0184 template<typename Lhs, typename Rhs, typename Dest>
0185 EIGEN_DONT_INLINE void skyline_col_major_time_dense_product(const Lhs& lhs, const Rhs& rhs, Dest& dst) {
0186 typedef typename remove_all<Lhs>::type _Lhs;
0187 typedef typename remove_all<Rhs>::type _Rhs;
0188 typedef typename traits<Lhs>::Scalar Scalar;
0189
0190 enum {
0191 LhsIsRowMajor = (_Lhs::Flags & RowMajorBit) == RowMajorBit,
0192 LhsIsSelfAdjoint = (_Lhs::Flags & SelfAdjointBit) == SelfAdjointBit,
0193 ProcessFirstHalf = LhsIsSelfAdjoint
0194 && (((_Lhs::Flags & (UpperTriangularBit | LowerTriangularBit)) == 0)
0195 || ((_Lhs::Flags & UpperTriangularBit) && !LhsIsRowMajor)
0196 || ((_Lhs::Flags & LowerTriangularBit) && LhsIsRowMajor)),
0197 ProcessSecondHalf = LhsIsSelfAdjoint && (!ProcessFirstHalf)
0198 };
0199
0200
0201 for (Index col = 0; col < rhs.cols(); col++) {
0202 for (Index row = 0; row < lhs.rows(); row++) {
0203 dst(row, col) = lhs.coeffDiag(row) * rhs(row, col);
0204 }
0205 }
0206
0207
0208 for (Index row = 0; row < lhs.rows(); row++) {
0209 typename _Lhs::InnerUpperIterator uIt(lhs, row);
0210 const Index stop = uIt.col() + uIt.size();
0211 for (Index col = 0; col < rhs.cols(); col++) {
0212
0213 Index k = uIt.col();
0214 Scalar tmp = 0;
0215 while (k < stop) {
0216 tmp +=
0217 uIt.value() *
0218 rhs(k++, col);
0219 ++uIt;
0220 }
0221
0222
0223 dst(row, col) += tmp;
0224 uIt += -uIt.size();
0225 }
0226 }
0227
0228
0229 for (Index lhscol = 0; lhscol < lhs.cols(); lhscol++) {
0230 typename _Lhs::InnerLowerIterator lIt(lhs, lhscol);
0231 const Index stop = lIt.size() + lIt.row();
0232 for (Index rhscol = 0; rhscol < rhs.cols(); rhscol++) {
0233
0234 const Scalar rhsCoeff = rhs.coeff(lhscol, rhscol);
0235 Index k = lIt.row();
0236 while (k < stop) {
0237 dst(k++, rhscol) +=
0238 lIt.value() *
0239 rhsCoeff;
0240 ++lIt;
0241 }
0242 lIt += -lIt.size();
0243 }
0244 }
0245
0246 }
0247
0248 template<typename Lhs, typename Rhs, typename ResultType,
0249 int LhsStorageOrder = traits<Lhs>::Flags&RowMajorBit>
0250 struct skyline_product_selector;
0251
0252 template<typename Lhs, typename Rhs, typename ResultType>
0253 struct skyline_product_selector<Lhs, Rhs, ResultType, RowMajor> {
0254 typedef typename traits<typename remove_all<Lhs>::type>::Scalar Scalar;
0255
0256 static void run(const Lhs& lhs, const Rhs& rhs, ResultType & res) {
0257 skyline_row_major_time_dense_product<Lhs, Rhs, ResultType > (lhs, rhs, res);
0258 }
0259 };
0260
0261 template<typename Lhs, typename Rhs, typename ResultType>
0262 struct skyline_product_selector<Lhs, Rhs, ResultType, ColMajor> {
0263 typedef typename traits<typename remove_all<Lhs>::type>::Scalar Scalar;
0264
0265 static void run(const Lhs& lhs, const Rhs& rhs, ResultType & res) {
0266 skyline_col_major_time_dense_product<Lhs, Rhs, ResultType > (lhs, rhs, res);
0267 }
0268 };
0269
0270 }
0271
0272
0273
0274
0275
0276
0277
0278
0279
0280
0281
0282
0283
0284
0285 template<typename Derived>
0286 template<typename OtherDerived >
0287 EIGEN_STRONG_INLINE const typename SkylineProductReturnType<Derived, OtherDerived>::Type
0288 SkylineMatrixBase<Derived>::operator*(const MatrixBase<OtherDerived> &other) const {
0289
0290 return typename SkylineProductReturnType<Derived, OtherDerived>::Type(derived(), other.derived());
0291 }
0292
0293 }
0294
0295 #endif