00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #ifndef EIGEN_SPARSEPRODUCT_H
00011 #define EIGEN_SPARSEPRODUCT_H
00012
00013 namespace Eigen {
00014
00015 template<typename Lhs, typename Rhs>
00016 struct SparseSparseProductReturnType
00017 {
00018 typedef typename internal::traits<Lhs>::Scalar Scalar;
00019 enum {
00020 LhsRowMajor = internal::traits<Lhs>::Flags & RowMajorBit,
00021 RhsRowMajor = internal::traits<Rhs>::Flags & RowMajorBit,
00022 TransposeRhs = (!LhsRowMajor) && RhsRowMajor,
00023 TransposeLhs = LhsRowMajor && (!RhsRowMajor)
00024 };
00025
00026 typedef typename internal::conditional<TransposeLhs,
00027 SparseMatrix<Scalar,0>,
00028 typename internal::nested<Lhs,Rhs::RowsAtCompileTime>::type>::type LhsNested;
00029
00030 typedef typename internal::conditional<TransposeRhs,
00031 SparseMatrix<Scalar,0>,
00032 typename internal::nested<Rhs,Lhs::RowsAtCompileTime>::type>::type RhsNested;
00033
00034 typedef SparseSparseProduct<LhsNested, RhsNested> Type;
00035 };
00036
00037 namespace internal {
00038 template<typename LhsNested, typename RhsNested>
00039 struct traits<SparseSparseProduct<LhsNested, RhsNested> >
00040 {
00041 typedef MatrixXpr XprKind;
00042
00043 typedef typename remove_all<LhsNested>::type _LhsNested;
00044 typedef typename remove_all<RhsNested>::type _RhsNested;
00045 typedef typename _LhsNested::Scalar Scalar;
00046 typedef typename promote_index_type<typename traits<_LhsNested>::Index,
00047 typename traits<_RhsNested>::Index>::type Index;
00048
00049 enum {
00050 LhsCoeffReadCost = _LhsNested::CoeffReadCost,
00051 RhsCoeffReadCost = _RhsNested::CoeffReadCost,
00052 LhsFlags = _LhsNested::Flags,
00053 RhsFlags = _RhsNested::Flags,
00054
00055 RowsAtCompileTime = _LhsNested::RowsAtCompileTime,
00056 ColsAtCompileTime = _RhsNested::ColsAtCompileTime,
00057 MaxRowsAtCompileTime = _LhsNested::MaxRowsAtCompileTime,
00058 MaxColsAtCompileTime = _RhsNested::MaxColsAtCompileTime,
00059
00060 InnerSize = EIGEN_SIZE_MIN_PREFER_FIXED(_LhsNested::ColsAtCompileTime, _RhsNested::RowsAtCompileTime),
00061
00062 EvalToRowMajor = (RhsFlags & LhsFlags & RowMajorBit),
00063
00064 RemovedBits = ~(EvalToRowMajor ? 0 : RowMajorBit),
00065
00066 Flags = (int(LhsFlags | RhsFlags) & HereditaryBits & RemovedBits)
00067 | EvalBeforeAssigningBit
00068 | EvalBeforeNestingBit,
00069
00070 CoeffReadCost = Dynamic
00071 };
00072
00073 typedef Sparse StorageKind;
00074 };
00075
00076 }
00077
00078 template<typename LhsNested, typename RhsNested>
00079 class SparseSparseProduct : internal::no_assignment_operator,
00080 public SparseMatrixBase<SparseSparseProduct<LhsNested, RhsNested> >
00081 {
00082 public:
00083
00084 typedef SparseMatrixBase<SparseSparseProduct> Base;
00085 EIGEN_DENSE_PUBLIC_INTERFACE(SparseSparseProduct)
00086
00087 private:
00088
00089 typedef typename internal::traits<SparseSparseProduct>::_LhsNested _LhsNested;
00090 typedef typename internal::traits<SparseSparseProduct>::_RhsNested _RhsNested;
00091
00092 public:
00093
00094 template<typename Lhs, typename Rhs>
00095 EIGEN_STRONG_INLINE SparseSparseProduct(const Lhs& lhs, const Rhs& rhs)
00096 : m_lhs(lhs), m_rhs(rhs), m_tolerance(0), m_conservative(true)
00097 {
00098 init();
00099 }
00100
00101 template<typename Lhs, typename Rhs>
00102 EIGEN_STRONG_INLINE SparseSparseProduct(const Lhs& lhs, const Rhs& rhs, const RealScalar& tolerance)
00103 : m_lhs(lhs), m_rhs(rhs), m_tolerance(tolerance), m_conservative(false)
00104 {
00105 init();
00106 }
00107
00108 SparseSparseProduct pruned(const Scalar& reference = 0, const RealScalar& epsilon = NumTraits<RealScalar>::dummy_precision()) const
00109 {
00110 using std::abs;
00111 return SparseSparseProduct(m_lhs,m_rhs,abs(reference)*epsilon);
00112 }
00113
00114 template<typename Dest>
00115 void evalTo(Dest& result) const
00116 {
00117 if(m_conservative)
00118 internal::conservative_sparse_sparse_product_selector<_LhsNested, _RhsNested, Dest>::run(lhs(),rhs(),result);
00119 else
00120 internal::sparse_sparse_product_with_pruning_selector<_LhsNested, _RhsNested, Dest>::run(lhs(),rhs(),result,m_tolerance);
00121 }
00122
00123 EIGEN_STRONG_INLINE Index rows() const { return m_lhs.rows(); }
00124 EIGEN_STRONG_INLINE Index cols() const { return m_rhs.cols(); }
00125
00126 EIGEN_STRONG_INLINE const _LhsNested& lhs() const { return m_lhs; }
00127 EIGEN_STRONG_INLINE const _RhsNested& rhs() const { return m_rhs; }
00128
00129 protected:
00130 void init()
00131 {
00132 eigen_assert(m_lhs.cols() == m_rhs.rows());
00133
00134 enum {
00135 ProductIsValid = _LhsNested::ColsAtCompileTime==Dynamic
00136 || _RhsNested::RowsAtCompileTime==Dynamic
00137 || int(_LhsNested::ColsAtCompileTime)==int(_RhsNested::RowsAtCompileTime),
00138 AreVectors = _LhsNested::IsVectorAtCompileTime && _RhsNested::IsVectorAtCompileTime,
00139 SameSizes = EIGEN_PREDICATE_SAME_MATRIX_SIZE(_LhsNested,_RhsNested)
00140 };
00141
00142
00143
00144 EIGEN_STATIC_ASSERT(ProductIsValid || !(AreVectors && SameSizes),
00145 INVALID_VECTOR_VECTOR_PRODUCT__IF_YOU_WANTED_A_DOT_OR_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTIONS)
00146 EIGEN_STATIC_ASSERT(ProductIsValid || !(SameSizes && !AreVectors),
00147 INVALID_MATRIX_PRODUCT__IF_YOU_WANTED_A_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTION)
00148 EIGEN_STATIC_ASSERT(ProductIsValid || SameSizes, INVALID_MATRIX_PRODUCT)
00149 }
00150
00151 LhsNested m_lhs;
00152 RhsNested m_rhs;
00153 RealScalar m_tolerance;
00154 bool m_conservative;
00155 };
00156
00157
00158 template<typename Derived>
00159 template<typename Lhs, typename Rhs>
00160 inline Derived& SparseMatrixBase<Derived>::operator=(const SparseSparseProduct<Lhs,Rhs>& product)
00161 {
00162 product.evalTo(derived());
00163 return derived();
00164 }
00165
00177 template<typename Derived>
00178 template<typename OtherDerived>
00179 inline const typename SparseSparseProductReturnType<Derived,OtherDerived>::Type
00180 SparseMatrixBase<Derived>::operator*(const SparseMatrixBase<OtherDerived> &other) const
00181 {
00182 return typename SparseSparseProductReturnType<Derived,OtherDerived>::Type(derived(), other.derived());
00183 }
00184
00185 }
00186
00187 #endif // EIGEN_SPARSEPRODUCT_H