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_SPARSE_DIAGONAL_PRODUCT_H
00026 #define EIGEN_SPARSE_DIAGONAL_PRODUCT_H
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 template<typename Lhs, typename Rhs>
00040 struct ei_traits<SparseDiagonalProduct<Lhs, Rhs> > : ei_traits<SparseProduct<Lhs, Rhs, DiagonalProduct> >
00041 {
00042 typedef typename ei_cleantype<Lhs>::type _Lhs;
00043 typedef typename ei_cleantype<Rhs>::type _Rhs;
00044 enum {
00045 SparseFlags = ((int(_Lhs::Flags)&Diagonal)==Diagonal) ? int(_Rhs::Flags) : int(_Lhs::Flags),
00046 Flags = SparseBit | (SparseFlags&RowMajorBit)
00047 };
00048 };
00049
00050 enum {SDP_IsDiagonal, SDP_IsSparseRowMajor, SDP_IsSparseColMajor};
00051 template<typename Lhs, typename Rhs, typename SparseDiagonalProductType, int RhsMode, int LhsMode>
00052 class ei_sparse_diagonal_product_inner_iterator_selector;
00053
00054 template<typename LhsNested, typename RhsNested>
00055 class SparseDiagonalProduct : public SparseMatrixBase<SparseDiagonalProduct<LhsNested,RhsNested> >, ei_no_assignment_operator
00056 {
00057 typedef typename ei_traits<SparseDiagonalProduct>::_LhsNested _LhsNested;
00058 typedef typename ei_traits<SparseDiagonalProduct>::_RhsNested _RhsNested;
00059
00060 enum {
00061 LhsMode = (_LhsNested::Flags&Diagonal)==Diagonal ? SDP_IsDiagonal
00062 : (_LhsNested::Flags&RowMajorBit) ? SDP_IsSparseRowMajor : SDP_IsSparseColMajor,
00063 RhsMode = (_RhsNested::Flags&Diagonal)==Diagonal ? SDP_IsDiagonal
00064 : (_RhsNested::Flags&RowMajorBit) ? SDP_IsSparseRowMajor : SDP_IsSparseColMajor
00065 };
00066
00067 public:
00068
00069 EIGEN_SPARSE_GENERIC_PUBLIC_INTERFACE(SparseDiagonalProduct)
00070
00071 typedef ei_sparse_diagonal_product_inner_iterator_selector
00072 <_LhsNested,_RhsNested,SparseDiagonalProduct,LhsMode,RhsMode> InnerIterator;
00073
00074 template<typename Lhs, typename Rhs>
00075 EIGEN_STRONG_INLINE SparseDiagonalProduct(const Lhs& lhs, const Rhs& rhs)
00076 : m_lhs(lhs), m_rhs(rhs)
00077 {
00078 ei_assert(lhs.cols() == rhs.rows() && "invalid sparse matrix * diagonal matrix product");
00079 }
00080
00081 EIGEN_STRONG_INLINE int rows() const { return m_lhs.rows(); }
00082 EIGEN_STRONG_INLINE int cols() const { return m_rhs.cols(); }
00083
00084 EIGEN_STRONG_INLINE const _LhsNested& lhs() const { return m_lhs; }
00085 EIGEN_STRONG_INLINE const _RhsNested& rhs() const { return m_rhs; }
00086
00087 protected:
00088 LhsNested m_lhs;
00089 RhsNested m_rhs;
00090 };
00091
00092
00093 template<typename Lhs, typename Rhs, typename SparseDiagonalProductType>
00094 class ei_sparse_diagonal_product_inner_iterator_selector
00095 <Lhs,Rhs,SparseDiagonalProductType,SDP_IsDiagonal,SDP_IsSparseRowMajor>
00096 : public SparseCwiseUnaryOp<ei_scalar_multiple_op<typename Lhs::Scalar>,Rhs>::InnerIterator
00097 {
00098 typedef typename SparseCwiseUnaryOp<ei_scalar_multiple_op<typename Lhs::Scalar>,Rhs>::InnerIterator Base;
00099 public:
00100 inline ei_sparse_diagonal_product_inner_iterator_selector(
00101 const SparseDiagonalProductType& expr, int outer)
00102 : Base(expr.rhs()*(expr.lhs().diagonal().coeff(outer)), outer)
00103 {}
00104 };
00105
00106 template<typename Lhs, typename Rhs, typename SparseDiagonalProductType>
00107 class ei_sparse_diagonal_product_inner_iterator_selector
00108 <Lhs,Rhs,SparseDiagonalProductType,SDP_IsDiagonal,SDP_IsSparseColMajor>
00109 : public SparseCwiseBinaryOp<
00110 ei_scalar_product_op<typename Lhs::Scalar>,
00111 SparseInnerVectorSet<Rhs,1>,
00112 typename Lhs::_CoeffsVectorType>::InnerIterator
00113 {
00114 typedef typename SparseCwiseBinaryOp<
00115 ei_scalar_product_op<typename Lhs::Scalar>,
00116 SparseInnerVectorSet<Rhs,1>,
00117 typename Lhs::_CoeffsVectorType>::InnerIterator Base;
00118 public:
00119 inline ei_sparse_diagonal_product_inner_iterator_selector(
00120 const SparseDiagonalProductType& expr, int outer)
00121 : Base(expr.rhs().innerVector(outer) .cwise()* expr.lhs().diagonal(), 0)
00122 {}
00123 private:
00124 ei_sparse_diagonal_product_inner_iterator_selector& operator=(const ei_sparse_diagonal_product_inner_iterator_selector&);
00125 };
00126
00127 template<typename Lhs, typename Rhs, typename SparseDiagonalProductType>
00128 class ei_sparse_diagonal_product_inner_iterator_selector
00129 <Lhs,Rhs,SparseDiagonalProductType,SDP_IsSparseColMajor,SDP_IsDiagonal>
00130 : public SparseCwiseUnaryOp<ei_scalar_multiple_op<typename Rhs::Scalar>,Lhs>::InnerIterator
00131 {
00132 typedef typename SparseCwiseUnaryOp<ei_scalar_multiple_op<typename Rhs::Scalar>,Lhs>::InnerIterator Base;
00133 public:
00134 inline ei_sparse_diagonal_product_inner_iterator_selector(
00135 const SparseDiagonalProductType& expr, int outer)
00136 : Base(expr.lhs()*expr.rhs().diagonal().coeff(outer), outer)
00137 {}
00138 };
00139
00140 template<typename Lhs, typename Rhs, typename SparseDiagonalProductType>
00141 class ei_sparse_diagonal_product_inner_iterator_selector
00142 <Lhs,Rhs,SparseDiagonalProductType,SDP_IsSparseRowMajor,SDP_IsDiagonal>
00143 : public SparseCwiseBinaryOp<
00144 ei_scalar_product_op<typename Rhs::Scalar>,
00145 SparseInnerVectorSet<Lhs,1>,
00146 NestByValue<Transpose<typename Rhs::_CoeffsVectorType> > >::InnerIterator
00147 {
00148 typedef typename SparseCwiseBinaryOp<
00149 ei_scalar_product_op<typename Rhs::Scalar>,
00150 SparseInnerVectorSet<Lhs,1>,
00151 NestByValue<Transpose<typename Rhs::_CoeffsVectorType> > >::InnerIterator Base;
00152 public:
00153 inline ei_sparse_diagonal_product_inner_iterator_selector(
00154 const SparseDiagonalProductType& expr, int outer)
00155 : Base(expr.lhs().innerVector(outer) .cwise()* expr.rhs().diagonal().transpose().nestByValue(), 0)
00156 {}
00157 };
00158
00159 #endif // EIGEN_SPARSE_DIAGONAL_PRODUCT_H