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