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, RealScalar tolerance)
00103 : m_lhs(lhs), m_rhs(rhs), m_tolerance(tolerance), m_conservative(false)
00104 {
00105 init();
00106 }
00107
00108 SparseSparseProduct pruned(Scalar reference = 0, RealScalar epsilon = NumTraits<RealScalar>::dummy_precision()) const
00109 {
00110 return SparseSparseProduct(m_lhs,m_rhs,internal::abs(reference)*epsilon);
00111 }
00112
00113 template<typename Dest>
00114 void evalTo(Dest& result) const
00115 {
00116 if(m_conservative)
00117 internal::conservative_sparse_sparse_product_selector<_LhsNested, _RhsNested, Dest>::run(lhs(),rhs(),result);
00118 else
00119 internal::sparse_sparse_product_with_pruning_selector<_LhsNested, _RhsNested, Dest>::run(lhs(),rhs(),result,m_tolerance);
00120 }
00121
00122 EIGEN_STRONG_INLINE Index rows() const { return m_lhs.rows(); }
00123 EIGEN_STRONG_INLINE Index cols() const { return m_rhs.cols(); }
00124
00125 EIGEN_STRONG_INLINE const _LhsNested& lhs() const { return m_lhs; }
00126 EIGEN_STRONG_INLINE const _RhsNested& rhs() const { return m_rhs; }
00127
00128 protected:
00129 void init()
00130 {
00131 eigen_assert(m_lhs.cols() == m_rhs.rows());
00132
00133 enum {
00134 ProductIsValid = _LhsNested::ColsAtCompileTime==Dynamic
00135 || _RhsNested::RowsAtCompileTime==Dynamic
00136 || int(_LhsNested::ColsAtCompileTime)==int(_RhsNested::RowsAtCompileTime),
00137 AreVectors = _LhsNested::IsVectorAtCompileTime && _RhsNested::IsVectorAtCompileTime,
00138 SameSizes = EIGEN_PREDICATE_SAME_MATRIX_SIZE(_LhsNested,_RhsNested)
00139 };
00140
00141
00142
00143 EIGEN_STATIC_ASSERT(ProductIsValid || !(AreVectors && SameSizes),
00144 INVALID_VECTOR_VECTOR_PRODUCT__IF_YOU_WANTED_A_DOT_OR_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTIONS)
00145 EIGEN_STATIC_ASSERT(ProductIsValid || !(SameSizes && !AreVectors),
00146 INVALID_MATRIX_PRODUCT__IF_YOU_WANTED_A_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTION)
00147 EIGEN_STATIC_ASSERT(ProductIsValid || SameSizes, INVALID_MATRIX_PRODUCT)
00148 }
00149
00150 LhsNested m_lhs;
00151 RhsNested m_rhs;
00152 RealScalar m_tolerance;
00153 bool m_conservative;
00154 };
00155
00156
00157 template<typename Derived>
00158 template<typename Lhs, typename Rhs>
00159 inline Derived& SparseMatrixBase<Derived>::operator=(const SparseSparseProduct<Lhs,Rhs>& product)
00160 {
00161 product.evalTo(derived());
00162 return derived();
00163 }
00164
00176 template<typename Derived>
00177 template<typename OtherDerived>
00178 inline const typename SparseSparseProductReturnType<Derived,OtherDerived>::Type
00179 SparseMatrixBase<Derived>::operator*(const SparseMatrixBase<OtherDerived> &other) const
00180 {
00181 return typename SparseSparseProductReturnType<Derived,OtherDerived>::Type(derived(), other.derived());
00182 }
00183
00184 }
00185
00186 #endif // EIGEN_SPARSEPRODUCT_H