SkylineProduct.h
Go to the documentation of this file.
00001 // This file is part of Eigen, a lightweight C++ template library
00002 // for linear algebra.
00003 //
00004 // Copyright (C) 2008-2009 Guillaume Saupin <guillaume.saupin@cea.fr>
00005 //
00006 // Eigen is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 3 of the License, or (at your option) any later version.
00010 //
00011 // Alternatively, you can redistribute it and/or
00012 // modify it under the terms of the GNU General Public License as
00013 // published by the Free Software Foundation; either version 2 of
00014 // the License, or (at your option) any later version.
00015 //
00016 // Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
00017 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00018 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
00019 // GNU General Public License for more details.
00020 //
00021 // You should have received a copy of the GNU Lesser General Public
00022 // License and a copy of the GNU General Public License along with
00023 // Eigen. If not, see <http://www.gnu.org/licenses/>.
00024 
00025 #ifndef EIGEN_SKYLINEPRODUCT_H
00026 #define EIGEN_SKYLINEPRODUCT_H
00027 
00028 template<typename Lhs, typename Rhs, int ProductMode>
00029 struct SkylineProductReturnType {
00030     typedef const typename internal::nested<Lhs, Rhs::RowsAtCompileTime>::type LhsNested;
00031     typedef const typename internal::nested<Rhs, Lhs::RowsAtCompileTime>::type RhsNested;
00032 
00033     typedef SkylineProduct<LhsNested, RhsNested, ProductMode> Type;
00034 };
00035 
00036 template<typename LhsNested, typename RhsNested, int ProductMode>
00037 struct internal::traits<SkylineProduct<LhsNested, RhsNested, ProductMode> > {
00038     // clean the nested types:
00039     typedef typename internal::remove_all<LhsNested>::type _LhsNested;
00040     typedef typename internal::remove_all<RhsNested>::type _RhsNested;
00041     typedef typename _LhsNested::Scalar Scalar;
00042 
00043     enum {
00044         LhsCoeffReadCost = _LhsNested::CoeffReadCost,
00045         RhsCoeffReadCost = _RhsNested::CoeffReadCost,
00046         LhsFlags = _LhsNested::Flags,
00047         RhsFlags = _RhsNested::Flags,
00048 
00049         RowsAtCompileTime = _LhsNested::RowsAtCompileTime,
00050         ColsAtCompileTime = _RhsNested::ColsAtCompileTime,
00051         InnerSize = EIGEN_SIZE_MIN_PREFER_FIXED(_LhsNested::ColsAtCompileTime, _RhsNested::RowsAtCompileTime),
00052 
00053         MaxRowsAtCompileTime = _LhsNested::MaxRowsAtCompileTime,
00054         MaxColsAtCompileTime = _RhsNested::MaxColsAtCompileTime,
00055 
00056         EvalToRowMajor = (RhsFlags & LhsFlags & RowMajorBit),
00057         ResultIsSkyline = ProductMode == SkylineTimeSkylineProduct,
00058 
00059         RemovedBits = ~((EvalToRowMajor ? 0 : RowMajorBit) | (ResultIsSkyline ? 0 : SkylineBit)),
00060 
00061         Flags = (int(LhsFlags | RhsFlags) & HereditaryBits & RemovedBits)
00062         | EvalBeforeAssigningBit
00063         | EvalBeforeNestingBit,
00064 
00065         CoeffReadCost = Dynamic
00066     };
00067 
00068     typedef typename internal::conditional<ResultIsSkyline,
00069             SkylineMatrixBase<SkylineProduct<LhsNested, RhsNested, ProductMode> >,
00070             MatrixBase<SkylineProduct<LhsNested, RhsNested, ProductMode> > >::type Base;
00071 };
00072 
00073 namespace internal {
00074 template<typename LhsNested, typename RhsNested, int ProductMode>
00075 class SkylineProduct : no_assignment_operator,
00076 public traits<SkylineProduct<LhsNested, RhsNested, ProductMode> >::Base {
00077 public:
00078 
00079     EIGEN_GENERIC_PUBLIC_INTERFACE(SkylineProduct)
00080 
00081 private:
00082 
00083     typedef typename traits<SkylineProduct>::_LhsNested _LhsNested;
00084     typedef typename traits<SkylineProduct>::_RhsNested _RhsNested;
00085 
00086 public:
00087 
00088     template<typename Lhs, typename Rhs>
00089     EIGEN_STRONG_INLINE SkylineProduct(const Lhs& lhs, const Rhs& rhs)
00090     : m_lhs(lhs), m_rhs(rhs) {
00091         eigen_assert(lhs.cols() == rhs.rows());
00092 
00093         enum {
00094             ProductIsValid = _LhsNested::ColsAtCompileTime == Dynamic
00095             || _RhsNested::RowsAtCompileTime == Dynamic
00096             || int(_LhsNested::ColsAtCompileTime) == int(_RhsNested::RowsAtCompileTime),
00097             AreVectors = _LhsNested::IsVectorAtCompileTime && _RhsNested::IsVectorAtCompileTime,
00098             SameSizes = EIGEN_PREDICATE_SAME_MATRIX_SIZE(_LhsNested, _RhsNested)
00099         };
00100         // note to the lost user:
00101         //    * for a dot product use: v1.dot(v2)
00102         //    * for a coeff-wise product use: v1.cwise()*v2
00103         EIGEN_STATIC_ASSERT(ProductIsValid || !(AreVectors && SameSizes),
00104                 INVALID_VECTOR_VECTOR_PRODUCT__IF_YOU_WANTED_A_DOT_OR_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTIONS)
00105                 EIGEN_STATIC_ASSERT(ProductIsValid || !(SameSizes && !AreVectors),
00106                 INVALID_MATRIX_PRODUCT__IF_YOU_WANTED_A_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTION)
00107                 EIGEN_STATIC_ASSERT(ProductIsValid || SameSizes, INVALID_MATRIX_PRODUCT)
00108     }
00109 
00110     EIGEN_STRONG_INLINE Index rows() const {
00111         return m_lhs.rows();
00112     }
00113 
00114     EIGEN_STRONG_INLINE Index cols() const {
00115         return m_rhs.cols();
00116     }
00117 
00118     EIGEN_STRONG_INLINE const _LhsNested& lhs() const {
00119         return m_lhs;
00120     }
00121 
00122     EIGEN_STRONG_INLINE const _RhsNested& rhs() const {
00123         return m_rhs;
00124     }
00125 
00126 protected:
00127     LhsNested m_lhs;
00128     RhsNested m_rhs;
00129 };
00130 
00131 // dense = skyline * dense
00132 // Note that here we force no inlining and separate the setZero() because GCC messes up otherwise
00133 
00134 template<typename Lhs, typename Rhs, typename Dest>
00135 EIGEN_DONT_INLINE void skyline_row_major_time_dense_product(const Lhs& lhs, const Rhs& rhs, Dest& dst) {
00136     typedef typename remove_all<Lhs>::type _Lhs;
00137     typedef typename remove_all<Rhs>::type _Rhs;
00138     typedef typename traits<Lhs>::Scalar Scalar;
00139 
00140     enum {
00141         LhsIsRowMajor = (_Lhs::Flags & RowMajorBit) == RowMajorBit,
00142         LhsIsSelfAdjoint = (_Lhs::Flags & SelfAdjointBit) == SelfAdjointBit,
00143         ProcessFirstHalf = LhsIsSelfAdjoint
00144         && (((_Lhs::Flags & (UpperTriangularBit | LowerTriangularBit)) == 0)
00145         || ((_Lhs::Flags & UpperTriangularBit) && !LhsIsRowMajor)
00146         || ((_Lhs::Flags & LowerTriangularBit) && LhsIsRowMajor)),
00147         ProcessSecondHalf = LhsIsSelfAdjoint && (!ProcessFirstHalf)
00148     };
00149 
00150     //Use matrix diagonal part <- Improvement : use inner iterator on dense matrix.
00151     for (Index col = 0; col < rhs.cols(); col++) {
00152         for (Index row = 0; row < lhs.rows(); row++) {
00153             dst(row, col) = lhs.coeffDiag(row) * rhs(row, col);
00154         }
00155     }
00156     //Use matrix lower triangular part
00157     for (Index row = 0; row < lhs.rows(); row++) {
00158         typename _Lhs::InnerLowerIterator lIt(lhs, row);
00159         const Index stop = lIt.col() + lIt.size();
00160         for (Index col = 0; col < rhs.cols(); col++) {
00161 
00162             Index k = lIt.col();
00163             Scalar tmp = 0;
00164             while (k < stop) {
00165                 tmp +=
00166                         lIt.value() *
00167                         rhs(k++, col);
00168                 ++lIt;
00169             }
00170             dst(row, col) += tmp;
00171             lIt += -lIt.size();
00172         }
00173 
00174     }
00175 
00176     //Use matrix upper triangular part
00177     for (Index lhscol = 0; lhscol < lhs.cols(); lhscol++) {
00178         typename _Lhs::InnerUpperIterator uIt(lhs, lhscol);
00179         const Index stop = uIt.size() + uIt.row();
00180         for (Index rhscol = 0; rhscol < rhs.cols(); rhscol++) {
00181 
00182 
00183             const Scalar rhsCoeff = rhs.coeff(lhscol, rhscol);
00184             Index k = uIt.row();
00185             while (k < stop) {
00186                 dst(k++, rhscol) +=
00187                         uIt.value() *
00188                         rhsCoeff;
00189                 ++uIt;
00190             }
00191             uIt += -uIt.size();
00192         }
00193     }
00194 
00195 }
00196 
00197 template<typename Lhs, typename Rhs, typename Dest>
00198 EIGEN_DONT_INLINE void skyline_col_major_time_dense_product(const Lhs& lhs, const Rhs& rhs, Dest& dst) {
00199     typedef typename remove_all<Lhs>::type _Lhs;
00200     typedef typename remove_all<Rhs>::type _Rhs;
00201     typedef typename traits<Lhs>::Scalar Scalar;
00202 
00203     enum {
00204         LhsIsRowMajor = (_Lhs::Flags & RowMajorBit) == RowMajorBit,
00205         LhsIsSelfAdjoint = (_Lhs::Flags & SelfAdjointBit) == SelfAdjointBit,
00206         ProcessFirstHalf = LhsIsSelfAdjoint
00207         && (((_Lhs::Flags & (UpperTriangularBit | LowerTriangularBit)) == 0)
00208         || ((_Lhs::Flags & UpperTriangularBit) && !LhsIsRowMajor)
00209         || ((_Lhs::Flags & LowerTriangularBit) && LhsIsRowMajor)),
00210         ProcessSecondHalf = LhsIsSelfAdjoint && (!ProcessFirstHalf)
00211     };
00212 
00213     //Use matrix diagonal part <- Improvement : use inner iterator on dense matrix.
00214     for (Index col = 0; col < rhs.cols(); col++) {
00215         for (Index row = 0; row < lhs.rows(); row++) {
00216             dst(row, col) = lhs.coeffDiag(row) * rhs(row, col);
00217         }
00218     }
00219 
00220     //Use matrix upper triangular part
00221     for (Index row = 0; row < lhs.rows(); row++) {
00222         typename _Lhs::InnerUpperIterator uIt(lhs, row);
00223         const Index stop = uIt.col() + uIt.size();
00224         for (Index col = 0; col < rhs.cols(); col++) {
00225 
00226             Index k = uIt.col();
00227             Scalar tmp = 0;
00228             while (k < stop) {
00229                 tmp +=
00230                         uIt.value() *
00231                         rhs(k++, col);
00232                 ++uIt;
00233             }
00234 
00235 
00236             dst(row, col) += tmp;
00237             uIt += -uIt.size();
00238         }
00239     }
00240 
00241     //Use matrix lower triangular part
00242     for (Index lhscol = 0; lhscol < lhs.cols(); lhscol++) {
00243         typename _Lhs::InnerLowerIterator lIt(lhs, lhscol);
00244         const Index stop = lIt.size() + lIt.row();
00245         for (Index rhscol = 0; rhscol < rhs.cols(); rhscol++) {
00246 
00247             const Scalar rhsCoeff = rhs.coeff(lhscol, rhscol);
00248             Index k = lIt.row();
00249             while (k < stop) {
00250                 dst(k++, rhscol) +=
00251                         lIt.value() *
00252                         rhsCoeff;
00253                 ++lIt;
00254             }
00255             lIt += -lIt.size();
00256         }
00257     }
00258 
00259 }
00260 
00261 template<typename Lhs, typename Rhs, typename ResultType,
00262         int LhsStorageOrder = traits<Lhs>::Flags&RowMajorBit>
00263         struct skyline_product_selector;
00264 
00265 template<typename Lhs, typename Rhs, typename ResultType>
00266 struct skyline_product_selector<Lhs, Rhs, ResultType, RowMajor> {
00267     typedef typename traits<typename remove_all<Lhs>::type>::Scalar Scalar;
00268 
00269     static void run(const Lhs& lhs, const Rhs& rhs, ResultType & res) {
00270         skyline_row_major_time_dense_product<Lhs, Rhs, ResultType > (lhs, rhs, res);
00271     }
00272 };
00273 
00274 template<typename Lhs, typename Rhs, typename ResultType>
00275 struct skyline_product_selector<Lhs, Rhs, ResultType, ColMajor> {
00276     typedef typename traits<typename remove_all<Lhs>::type>::Scalar Scalar;
00277 
00278     static void run(const Lhs& lhs, const Rhs& rhs, ResultType & res) {
00279         skyline_col_major_time_dense_product<Lhs, Rhs, ResultType > (lhs, rhs, res);
00280     }
00281 };
00282 
00283 } // end namespace internal
00284 
00285 // template<typename Derived>
00286 // template<typename Lhs, typename Rhs >
00287 // Derived & MatrixBase<Derived>::lazyAssign(const SkylineProduct<Lhs, Rhs, SkylineTimeDenseProduct>& product) {
00288 //     typedef typename internal::remove_all<Lhs>::type _Lhs;
00289 //     internal::skyline_product_selector<typename internal::remove_all<Lhs>::type,
00290 //             typename internal::remove_all<Rhs>::type,
00291 //             Derived>::run(product.lhs(), product.rhs(), derived());
00292 // 
00293 //     return derived();
00294 // }
00295 
00296 // skyline * dense
00297 
00298 template<typename Derived>
00299 template<typename OtherDerived >
00300 EIGEN_STRONG_INLINE const typename SkylineProductReturnType<Derived, OtherDerived>::Type
00301 SkylineMatrixBase<Derived>::operator*(const MatrixBase<OtherDerived> &other) const {
00302 
00303     return typename SkylineProductReturnType<Derived, OtherDerived>::Type(derived(), other.derived());
00304 }
00305 
00306 #endif // EIGEN_SKYLINEPRODUCT_H


re_vision
Author(s): Dorian Galvez-Lopez
autogenerated on Sun Jan 5 2014 11:32:32