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
00040 namespace internal {
00041
00042 template<typename Lhs, typename Rhs>
00043 struct traits<SparseDiagonalProduct<Lhs, Rhs> >
00044 {
00045 typedef typename remove_all<Lhs>::type _Lhs;
00046 typedef typename remove_all<Rhs>::type _Rhs;
00047 typedef typename _Lhs::Scalar Scalar;
00048 typedef typename promote_index_type<typename traits<Lhs>::Index,
00049 typename traits<Rhs>::Index>::type Index;
00050 typedef Sparse StorageKind;
00051 typedef MatrixXpr XprKind;
00052 enum {
00053 RowsAtCompileTime = _Lhs::RowsAtCompileTime,
00054 ColsAtCompileTime = _Rhs::ColsAtCompileTime,
00055
00056 MaxRowsAtCompileTime = _Lhs::MaxRowsAtCompileTime,
00057 MaxColsAtCompileTime = _Rhs::MaxColsAtCompileTime,
00058
00059 SparseFlags = is_diagonal<_Lhs>::ret ? int(_Rhs::Flags) : int(_Lhs::Flags),
00060 Flags = (SparseFlags&RowMajorBit),
00061 CoeffReadCost = Dynamic
00062 };
00063 };
00064
00065 enum {SDP_IsDiagonal, SDP_IsSparseRowMajor, SDP_IsSparseColMajor};
00066 template<typename Lhs, typename Rhs, typename SparseDiagonalProductType, int RhsMode, int LhsMode>
00067 class sparse_diagonal_product_inner_iterator_selector;
00068
00069 }
00070
00071 template<typename Lhs, typename Rhs>
00072 class SparseDiagonalProduct
00073 : public SparseMatrixBase<SparseDiagonalProduct<Lhs,Rhs> >,
00074 internal::no_assignment_operator
00075 {
00076 typedef typename Lhs::Nested LhsNested;
00077 typedef typename Rhs::Nested RhsNested;
00078
00079 typedef typename internal::remove_all<LhsNested>::type _LhsNested;
00080 typedef typename internal::remove_all<RhsNested>::type _RhsNested;
00081
00082 enum {
00083 LhsMode = internal::is_diagonal<_LhsNested>::ret ? internal::SDP_IsDiagonal
00084 : (_LhsNested::Flags&RowMajorBit) ? internal::SDP_IsSparseRowMajor : internal::SDP_IsSparseColMajor,
00085 RhsMode = internal::is_diagonal<_RhsNested>::ret ? internal::SDP_IsDiagonal
00086 : (_RhsNested::Flags&RowMajorBit) ? internal::SDP_IsSparseRowMajor : internal::SDP_IsSparseColMajor
00087 };
00088
00089 public:
00090
00091 EIGEN_SPARSE_PUBLIC_INTERFACE(SparseDiagonalProduct)
00092
00093 typedef internal::sparse_diagonal_product_inner_iterator_selector
00094 <_LhsNested,_RhsNested,SparseDiagonalProduct,LhsMode,RhsMode> InnerIterator;
00095
00096 EIGEN_STRONG_INLINE SparseDiagonalProduct(const Lhs& lhs, const Rhs& rhs)
00097 : m_lhs(lhs), m_rhs(rhs)
00098 {
00099 eigen_assert(lhs.cols() == rhs.rows() && "invalid sparse matrix * diagonal matrix product");
00100 }
00101
00102 EIGEN_STRONG_INLINE Index rows() const { return m_lhs.rows(); }
00103 EIGEN_STRONG_INLINE Index cols() const { return m_rhs.cols(); }
00104
00105 EIGEN_STRONG_INLINE const _LhsNested& lhs() const { return m_lhs; }
00106 EIGEN_STRONG_INLINE const _RhsNested& rhs() const { return m_rhs; }
00107
00108 protected:
00109 LhsNested m_lhs;
00110 RhsNested m_rhs;
00111 };
00112
00113 namespace internal {
00114
00115 template<typename Lhs, typename Rhs, typename SparseDiagonalProductType>
00116 class sparse_diagonal_product_inner_iterator_selector
00117 <Lhs,Rhs,SparseDiagonalProductType,SDP_IsDiagonal,SDP_IsSparseRowMajor>
00118 : public CwiseUnaryOp<scalar_multiple_op<typename Lhs::Scalar>,const Rhs>::InnerIterator
00119 {
00120 typedef typename CwiseUnaryOp<scalar_multiple_op<typename Lhs::Scalar>,const Rhs>::InnerIterator Base;
00121 typedef typename Lhs::Index Index;
00122 public:
00123 inline sparse_diagonal_product_inner_iterator_selector(
00124 const SparseDiagonalProductType& expr, Index outer)
00125 : Base(expr.rhs()*(expr.lhs().diagonal().coeff(outer)), outer)
00126 {}
00127 };
00128
00129 template<typename Lhs, typename Rhs, typename SparseDiagonalProductType>
00130 class sparse_diagonal_product_inner_iterator_selector
00131 <Lhs,Rhs,SparseDiagonalProductType,SDP_IsDiagonal,SDP_IsSparseColMajor>
00132 : public CwiseBinaryOp<
00133 scalar_product_op<typename Lhs::Scalar>,
00134 SparseInnerVectorSet<Rhs,1>,
00135 typename Lhs::DiagonalVectorType>::InnerIterator
00136 {
00137 typedef typename CwiseBinaryOp<
00138 scalar_product_op<typename Lhs::Scalar>,
00139 SparseInnerVectorSet<Rhs,1>,
00140 typename Lhs::DiagonalVectorType>::InnerIterator Base;
00141 typedef typename Lhs::Index Index;
00142 public:
00143 inline sparse_diagonal_product_inner_iterator_selector(
00144 const SparseDiagonalProductType& expr, Index outer)
00145 : Base(expr.rhs().innerVector(outer) .cwiseProduct(expr.lhs().diagonal()), 0)
00146 {}
00147 };
00148
00149 template<typename Lhs, typename Rhs, typename SparseDiagonalProductType>
00150 class sparse_diagonal_product_inner_iterator_selector
00151 <Lhs,Rhs,SparseDiagonalProductType,SDP_IsSparseColMajor,SDP_IsDiagonal>
00152 : public CwiseUnaryOp<scalar_multiple_op<typename Rhs::Scalar>,const Lhs>::InnerIterator
00153 {
00154 typedef typename CwiseUnaryOp<scalar_multiple_op<typename Rhs::Scalar>,const Lhs>::InnerIterator Base;
00155 typedef typename Lhs::Index Index;
00156 public:
00157 inline sparse_diagonal_product_inner_iterator_selector(
00158 const SparseDiagonalProductType& expr, Index outer)
00159 : Base(expr.lhs()*expr.rhs().diagonal().coeff(outer), outer)
00160 {}
00161 };
00162
00163 template<typename Lhs, typename Rhs, typename SparseDiagonalProductType>
00164 class sparse_diagonal_product_inner_iterator_selector
00165 <Lhs,Rhs,SparseDiagonalProductType,SDP_IsSparseRowMajor,SDP_IsDiagonal>
00166 : public CwiseBinaryOp<
00167 scalar_product_op<typename Rhs::Scalar>,
00168 SparseInnerVectorSet<Lhs,1>,
00169 Transpose<const typename Rhs::DiagonalVectorType> >::InnerIterator
00170 {
00171 typedef typename CwiseBinaryOp<
00172 scalar_product_op<typename Rhs::Scalar>,
00173 SparseInnerVectorSet<Lhs,1>,
00174 Transpose<const typename Rhs::DiagonalVectorType> >::InnerIterator Base;
00175 typedef typename Lhs::Index Index;
00176 public:
00177 inline sparse_diagonal_product_inner_iterator_selector(
00178 const SparseDiagonalProductType& expr, Index outer)
00179 : Base(expr.lhs().innerVector(outer) .cwiseProduct(expr.rhs().diagonal().transpose()), 0)
00180 {}
00181 };
00182
00183 }
00184
00185
00186
00187 template<typename Derived>
00188 template<typename OtherDerived>
00189 const SparseDiagonalProduct<Derived,OtherDerived>
00190 SparseMatrixBase<Derived>::operator*(const DiagonalBase<OtherDerived> &other) const
00191 {
00192 return SparseDiagonalProduct<Derived,OtherDerived>(this->derived(), other.derived());
00193 }
00194
00195 #endif // EIGEN_SPARSE_DIAGONAL_PRODUCT_H