00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
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
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
00101
00102
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
00132
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
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
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
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
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
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
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 }
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
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