Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:57:07

0001 // This file is part of Eigen, a lightweight C++ template library
0002 // for linear algebra.
0003 //
0004 // Copyright (C) 2008-2009 Guillaume Saupin <guillaume.saupin@cea.fr>
0005 //
0006 // This Source Code Form is subject to the terms of the Mozilla
0007 // Public License v. 2.0. If a copy of the MPL was not distributed
0008 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
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     // clean the nested types:
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         // note to the lost user:
0088         //    * for a dot product use: v1.dot(v2)
0089         //    * for a coeff-wise product use: v1.cwise()*v2
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 // dense = skyline * dense
0119 // Note that here we force no inlining and separate the setZero() because GCC messes up otherwise
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     //Use matrix diagonal part <- Improvement : use inner iterator on dense matrix.
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     //Use matrix lower triangular part
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     //Use matrix upper triangular part
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     //Use matrix diagonal part <- Improvement : use inner iterator on dense matrix.
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     //Use matrix upper triangular part
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     //Use matrix lower triangular part
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 } // end namespace internal
0271 
0272 // template<typename Derived>
0273 // template<typename Lhs, typename Rhs >
0274 // Derived & MatrixBase<Derived>::lazyAssign(const SkylineProduct<Lhs, Rhs, SkylineTimeDenseProduct>& product) {
0275 //     typedef typename internal::remove_all<Lhs>::type _Lhs;
0276 //     internal::skyline_product_selector<typename internal::remove_all<Lhs>::type,
0277 //             typename internal::remove_all<Rhs>::type,
0278 //             Derived>::run(product.lhs(), product.rhs(), derived());
0279 // 
0280 //     return derived();
0281 // }
0282 
0283 // skyline * dense
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 } // end namespace Eigen
0294 
0295 #endif // EIGEN_SKYLINEPRODUCT_H