![]() |
Eigen
3.3.3
|
00001 // This file is part of Eigen, a lightweight C++ template library 00002 // for linear algebra. 00003 // 00004 // Copyright (C) 2011-2014 Gael Guennebaud <gael.guennebaud@inria.fr> 00005 // Copyright (C) 2010 Daniel Lowengrub <lowdanie@gmail.com> 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 00044 template<typename MatrixType> 00045 class SparseView : public SparseMatrixBase<SparseView<MatrixType> > 00046 { 00047 typedef typename MatrixType::Nested MatrixTypeNested; 00048 typedef typename internal::remove_all<MatrixTypeNested>::type _MatrixTypeNested; 00049 typedef SparseMatrixBase<SparseView > Base; 00050 public: 00051 EIGEN_SPARSE_PUBLIC_INTERFACE(SparseView) 00052 typedef typename internal::remove_all<MatrixType>::type NestedExpression; 00053 00054 explicit SparseView(const MatrixType& mat, const Scalar& reference = Scalar(0), 00055 const RealScalar &epsilon = NumTraits<Scalar>::dummy_precision()) 00056 : m_matrix(mat), m_reference(reference), m_epsilon(epsilon) {} 00057 00058 inline Index rows() const { return m_matrix.rows(); } 00059 inline Index cols() const { return m_matrix.cols(); } 00060 00061 inline Index innerSize() const { return m_matrix.innerSize(); } 00062 inline Index outerSize() const { return m_matrix.outerSize(); } 00063 00065 const typename internal::remove_all<MatrixTypeNested>::type& 00066 nestedExpression() const { return m_matrix; } 00067 00068 Scalar reference() const { return m_reference; } 00069 RealScalar epsilon() const { return m_epsilon; } 00070 00071 protected: 00072 MatrixTypeNested m_matrix; 00073 Scalar m_reference; 00074 RealScalar m_epsilon; 00075 }; 00076 00077 namespace internal { 00078 00079 // TODO find a way to unify the two following variants 00080 // This is tricky because implementing an inner iterator on top of an IndexBased evaluator is 00081 // not easy because the evaluators do not expose the sizes of the underlying expression. 00082 00083 template<typename ArgType> 00084 struct unary_evaluator<SparseView<ArgType>, IteratorBased> 00085 : public evaluator_base<SparseView<ArgType> > 00086 { 00087 typedef typename evaluator<ArgType>::InnerIterator EvalIterator; 00088 public: 00089 typedef SparseView<ArgType> XprType; 00090 00091 class InnerIterator : public EvalIterator 00092 { 00093 typedef typename XprType::Scalar Scalar; 00094 public: 00095 00096 EIGEN_STRONG_INLINE InnerIterator(const unary_evaluator& sve, Index outer) 00097 : EvalIterator(sve.m_argImpl,outer), m_view(sve.m_view) 00098 { 00099 incrementToNonZero(); 00100 } 00101 00102 EIGEN_STRONG_INLINE InnerIterator& operator++() 00103 { 00104 EvalIterator::operator++(); 00105 incrementToNonZero(); 00106 return *this; 00107 } 00108 00109 using EvalIterator::value; 00110 00111 protected: 00112 const XprType &m_view; 00113 00114 private: 00115 void incrementToNonZero() 00116 { 00117 while((bool(*this)) && internal::isMuchSmallerThan(value(), m_view.reference(), m_view.epsilon())) 00118 { 00119 EvalIterator::operator++(); 00120 } 00121 } 00122 }; 00123 00124 enum { 00125 CoeffReadCost = evaluator<ArgType>::CoeffReadCost, 00126 Flags = XprType::Flags 00127 }; 00128 00129 explicit unary_evaluator(const XprType& xpr) : m_argImpl(xpr.nestedExpression()), m_view(xpr) {} 00130 00131 protected: 00132 evaluator<ArgType> m_argImpl; 00133 const XprType &m_view; 00134 }; 00135 00136 template<typename ArgType> 00137 struct unary_evaluator<SparseView<ArgType>, IndexBased> 00138 : public evaluator_base<SparseView<ArgType> > 00139 { 00140 public: 00141 typedef SparseView<ArgType> XprType; 00142 protected: 00143 enum { IsRowMajor = (XprType::Flags&RowMajorBit)==RowMajorBit }; 00144 typedef typename XprType::Scalar Scalar; 00145 typedef typename XprType::StorageIndex StorageIndex; 00146 public: 00147 00148 class InnerIterator 00149 { 00150 public: 00151 00152 EIGEN_STRONG_INLINE InnerIterator(const unary_evaluator& sve, Index outer) 00153 : m_sve(sve), m_inner(0), m_outer(outer), m_end(sve.m_view.innerSize()) 00154 { 00155 incrementToNonZero(); 00156 } 00157 00158 EIGEN_STRONG_INLINE InnerIterator& operator++() 00159 { 00160 m_inner++; 00161 incrementToNonZero(); 00162 return *this; 00163 } 00164 00165 EIGEN_STRONG_INLINE Scalar value() const 00166 { 00167 return (IsRowMajor) ? m_sve.m_argImpl.coeff(m_outer, m_inner) 00168 : m_sve.m_argImpl.coeff(m_inner, m_outer); 00169 } 00170 00171 EIGEN_STRONG_INLINE StorageIndex index() const { return m_inner; } 00172 inline Index row() const { return IsRowMajor ? m_outer : index(); } 00173 inline Index col() const { return IsRowMajor ? index() : m_outer; } 00174 00175 EIGEN_STRONG_INLINE operator bool() const { return m_inner < m_end && m_inner>=0; } 00176 00177 protected: 00178 const unary_evaluator &m_sve; 00179 Index m_inner; 00180 const Index m_outer; 00181 const Index m_end; 00182 00183 private: 00184 void incrementToNonZero() 00185 { 00186 while((bool(*this)) && internal::isMuchSmallerThan(value(), m_sve.m_view.reference(), m_sve.m_view.epsilon())) 00187 { 00188 m_inner++; 00189 } 00190 } 00191 }; 00192 00193 enum { 00194 CoeffReadCost = evaluator<ArgType>::CoeffReadCost, 00195 Flags = XprType::Flags 00196 }; 00197 00198 explicit unary_evaluator(const XprType& xpr) : m_argImpl(xpr.nestedExpression()), m_view(xpr) {} 00199 00200 protected: 00201 evaluator<ArgType> m_argImpl; 00202 const XprType &m_view; 00203 }; 00204 00205 } // end namespace internal 00206 00224 template<typename Derived> 00225 const SparseView<Derived> MatrixBase<Derived>::sparseView(const Scalar& reference, 00226 const typename NumTraits<Scalar>::Real& epsilon) const 00227 { 00228 return SparseView<Derived>(derived(), reference, epsilon); 00229 } 00230 00243 template<typename Derived> 00244 const SparseView<Derived> 00245 SparseMatrixBase<Derived>::pruned(const Scalar& reference, 00246 const RealScalar& epsilon) const 00247 { 00248 return SparseView<Derived>(derived(), reference, epsilon); 00249 } 00250 00251 } // end namespace Eigen 00252 00253 #endif