MOAB
4.9.3pre
|
00001 // This file is part of Eigen, a lightweight C++ template library 00002 // for linear algebra. 00003 // 00004 // Copyright (C) 2011-2014 Gael Guennebaud <[email protected]> 00005 // Copyright (C) 2010 Daniel Lowengrub <[email protected]> 00006 // 00007 // This Source Code Form is subject to the terms of the Mozilla 00008 // Public License v. 2.0. If a copy of the MPL was not distributed 00009 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 00010 00011 #ifndef EIGEN_SPARSEVIEW_H 00012 #define EIGEN_SPARSEVIEW_H 00013 00014 namespace Eigen { 00015 00016 namespace internal { 00017 00018 template<typename MatrixType> 00019 struct traits<SparseView<MatrixType> > : traits<MatrixType> 00020 { 00021 typedef typename MatrixType::StorageIndex StorageIndex; 00022 typedef Sparse StorageKind; 00023 enum { 00024 Flags = int(traits<MatrixType>::Flags) & (RowMajorBit) 00025 }; 00026 }; 00027 00028 } // end namespace internal 00029 00030 template<typename MatrixType> 00031 class SparseView : public SparseMatrixBase<SparseView<MatrixType> > 00032 { 00033 typedef typename MatrixType::Nested MatrixTypeNested; 00034 typedef typename internal::remove_all<MatrixTypeNested>::type _MatrixTypeNested; 00035 typedef SparseMatrixBase<SparseView > Base; 00036 public: 00037 EIGEN_SPARSE_PUBLIC_INTERFACE(SparseView) 00038 typedef typename internal::remove_all<MatrixType>::type NestedExpression; 00039 00040 explicit SparseView(const MatrixType& mat, const Scalar& reference = Scalar(0), 00041 const RealScalar &epsilon = NumTraits<Scalar>::dummy_precision()) 00042 : m_matrix(mat), m_reference(reference), m_epsilon(epsilon) {} 00043 00044 inline Index rows() const { return m_matrix.rows(); } 00045 inline Index cols() const { return m_matrix.cols(); } 00046 00047 inline Index innerSize() const { return m_matrix.innerSize(); } 00048 inline Index outerSize() const { return m_matrix.outerSize(); } 00049 00051 const typename internal::remove_all<MatrixTypeNested>::type& 00052 nestedExpression() const { return m_matrix; } 00053 00054 Scalar reference() const { return m_reference; } 00055 RealScalar epsilon() const { return m_epsilon; } 00056 00057 protected: 00058 MatrixTypeNested m_matrix; 00059 Scalar m_reference; 00060 RealScalar m_epsilon; 00061 }; 00062 00063 namespace internal { 00064 00065 // TODO find a way to unify the two following variants 00066 // This is tricky because implementing an inner iterator on top of an IndexBased evaluator is 00067 // not easy because the evaluators do not expose the sizes of the underlying expression. 00068 00069 template<typename ArgType> 00070 struct unary_evaluator<SparseView<ArgType>, IteratorBased> 00071 : public evaluator_base<SparseView<ArgType> > 00072 { 00073 typedef typename evaluator<ArgType>::InnerIterator EvalIterator; 00074 public: 00075 typedef SparseView<ArgType> XprType; 00076 00077 class InnerIterator : public EvalIterator 00078 { 00079 typedef typename XprType::Scalar Scalar; 00080 public: 00081 00082 EIGEN_STRONG_INLINE InnerIterator(const unary_evaluator& sve, Index outer) 00083 : EvalIterator(sve.m_argImpl,outer), m_view(sve.m_view) 00084 { 00085 incrementToNonZero(); 00086 } 00087 00088 EIGEN_STRONG_INLINE InnerIterator& operator++() 00089 { 00090 EvalIterator::operator++(); 00091 incrementToNonZero(); 00092 return *this; 00093 } 00094 00095 using EvalIterator::value; 00096 00097 protected: 00098 const XprType &m_view; 00099 00100 private: 00101 void incrementToNonZero() 00102 { 00103 while((bool(*this)) && internal::isMuchSmallerThan(value(), m_view.reference(), m_view.epsilon())) 00104 { 00105 EvalIterator::operator++(); 00106 } 00107 } 00108 }; 00109 00110 enum { 00111 CoeffReadCost = evaluator<ArgType>::CoeffReadCost, 00112 Flags = XprType::Flags 00113 }; 00114 00115 explicit unary_evaluator(const XprType& xpr) : m_argImpl(xpr.nestedExpression()), m_view(xpr) {} 00116 00117 protected: 00118 evaluator<ArgType> m_argImpl; 00119 const XprType &m_view; 00120 }; 00121 00122 template<typename ArgType> 00123 struct unary_evaluator<SparseView<ArgType>, IndexBased> 00124 : public evaluator_base<SparseView<ArgType> > 00125 { 00126 public: 00127 typedef SparseView<ArgType> XprType; 00128 protected: 00129 enum { IsRowMajor = (XprType::Flags&RowMajorBit)==RowMajorBit }; 00130 typedef typename XprType::Scalar Scalar; 00131 typedef typename XprType::StorageIndex StorageIndex; 00132 public: 00133 00134 class InnerIterator 00135 { 00136 public: 00137 00138 EIGEN_STRONG_INLINE InnerIterator(const unary_evaluator& sve, Index outer) 00139 : m_sve(sve), m_inner(0), m_outer(outer), m_end(sve.m_view.innerSize()) 00140 { 00141 incrementToNonZero(); 00142 } 00143 00144 EIGEN_STRONG_INLINE InnerIterator& operator++() 00145 { 00146 m_inner++; 00147 incrementToNonZero(); 00148 return *this; 00149 } 00150 00151 EIGEN_STRONG_INLINE Scalar value() const 00152 { 00153 return (IsRowMajor) ? m_sve.m_argImpl.coeff(m_outer, m_inner) 00154 : m_sve.m_argImpl.coeff(m_inner, m_outer); 00155 } 00156 00157 EIGEN_STRONG_INLINE StorageIndex index() const { return m_inner; } 00158 inline Index row() const { return IsRowMajor ? m_outer : index(); } 00159 inline Index col() const { return IsRowMajor ? index() : m_outer; } 00160 00161 EIGEN_STRONG_INLINE operator bool() const { return m_inner < m_end && m_inner>=0; } 00162 00163 protected: 00164 const unary_evaluator &m_sve; 00165 Index m_inner; 00166 const Index m_outer; 00167 const Index m_end; 00168 00169 private: 00170 void incrementToNonZero() 00171 { 00172 while((bool(*this)) && internal::isMuchSmallerThan(value(), m_sve.m_view.reference(), m_sve.m_view.epsilon())) 00173 { 00174 m_inner++; 00175 } 00176 } 00177 }; 00178 00179 enum { 00180 CoeffReadCost = evaluator<ArgType>::CoeffReadCost, 00181 Flags = XprType::Flags 00182 }; 00183 00184 explicit unary_evaluator(const XprType& xpr) : m_argImpl(xpr.nestedExpression()), m_view(xpr) {} 00185 00186 protected: 00187 evaluator<ArgType> m_argImpl; 00188 const XprType &m_view; 00189 }; 00190 00191 } // end namespace internal 00192 00193 template<typename Derived> 00194 const SparseView<Derived> MatrixBase<Derived>::sparseView(const Scalar& reference, 00195 const typename NumTraits<Scalar>::Real& epsilon) const 00196 { 00197 return SparseView<Derived>(derived(), reference, epsilon); 00198 } 00199 00212 template<typename Derived> 00213 const SparseView<Derived> 00214 SparseMatrixBase<Derived>::pruned(const Scalar& reference, 00215 const RealScalar& epsilon) const 00216 { 00217 return SparseView<Derived>(derived(), reference, epsilon); 00218 } 00219 00220 } // end namespace Eigen 00221 00222 #endif