![]() |
Eigen
3.2.8
|
00001 // This file is part of Eigen, a lightweight C++ template library 00002 // for linear algebra. 00003 // 00004 // Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr> 00005 // 00006 // This Source Code Form is subject to the terms of the Mozilla 00007 // Public License v. 2.0. If a copy of the MPL was not distributed 00008 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 00009 00010 #ifndef EIGEN_SPARSEVECTOR_H 00011 #define EIGEN_SPARSEVECTOR_H 00012 00013 namespace Eigen { 00014 00028 namespace internal { 00029 template<typename _Scalar, int _Options, typename _Index> 00030 struct traits<SparseVector<_Scalar, _Options, _Index> > 00031 { 00032 typedef _Scalar Scalar; 00033 typedef _Index Index; 00034 typedef Sparse StorageKind; 00035 typedef MatrixXpr XprKind; 00036 enum { 00037 IsColVector = (_Options & RowMajorBit) ? 0 : 1, 00038 00039 RowsAtCompileTime = IsColVector ? Dynamic : 1, 00040 ColsAtCompileTime = IsColVector ? 1 : Dynamic, 00041 MaxRowsAtCompileTime = RowsAtCompileTime, 00042 MaxColsAtCompileTime = ColsAtCompileTime, 00043 Flags = _Options | NestByRefBit | LvalueBit | (IsColVector ? 0 : RowMajorBit), 00044 CoeffReadCost = NumTraits<Scalar>::ReadCost, 00045 SupportedAccessPatterns = InnerRandomAccessPattern 00046 }; 00047 }; 00048 00049 // Sparse-Vector-Assignment kinds: 00050 enum { 00051 SVA_RuntimeSwitch, 00052 SVA_Inner, 00053 SVA_Outer 00054 }; 00055 00056 template< typename Dest, typename Src, 00057 int AssignmentKind = !bool(Src::IsVectorAtCompileTime) ? SVA_RuntimeSwitch 00058 : Src::InnerSizeAtCompileTime==1 ? SVA_Outer 00059 : SVA_Inner> 00060 struct sparse_vector_assign_selector; 00061 00062 } 00063 00064 template<typename _Scalar, int _Options, typename _Index> 00065 class SparseVector 00066 : public SparseMatrixBase<SparseVector<_Scalar, _Options, _Index> > 00067 { 00068 typedef SparseMatrixBase<SparseVector> SparseBase; 00069 00070 public: 00071 EIGEN_SPARSE_PUBLIC_INTERFACE(SparseVector) 00072 EIGEN_SPARSE_INHERIT_ASSIGNMENT_OPERATOR(SparseVector, +=) 00073 EIGEN_SPARSE_INHERIT_ASSIGNMENT_OPERATOR(SparseVector, -=) 00074 00075 typedef internal::CompressedStorage<Scalar,Index> Storage; 00076 enum { IsColVector = internal::traits<SparseVector>::IsColVector }; 00077 00078 enum { 00079 Options = _Options 00080 }; 00081 00082 EIGEN_STRONG_INLINE Index rows() const { return IsColVector ? m_size : 1; } 00083 EIGEN_STRONG_INLINE Index cols() const { return IsColVector ? 1 : m_size; } 00084 EIGEN_STRONG_INLINE Index innerSize() const { return m_size; } 00085 EIGEN_STRONG_INLINE Index outerSize() const { return 1; } 00086 00087 EIGEN_STRONG_INLINE const Scalar* valuePtr() const { return &m_data.value(0); } 00088 EIGEN_STRONG_INLINE Scalar* valuePtr() { return &m_data.value(0); } 00089 00090 EIGEN_STRONG_INLINE const Index* innerIndexPtr() const { return &m_data.index(0); } 00091 EIGEN_STRONG_INLINE Index* innerIndexPtr() { return &m_data.index(0); } 00092 00094 inline Storage& data() { return m_data; } 00096 inline const Storage& data() const { return m_data; } 00097 00098 inline Scalar coeff(Index row, Index col) const 00099 { 00100 eigen_assert(IsColVector ? (col==0 && row>=0 && row<m_size) : (row==0 && col>=0 && col<m_size)); 00101 return coeff(IsColVector ? row : col); 00102 } 00103 inline Scalar coeff(Index i) const 00104 { 00105 eigen_assert(i>=0 && i<m_size); 00106 return m_data.at(i); 00107 } 00108 00109 inline Scalar& coeffRef(Index row, Index col) 00110 { 00111 eigen_assert(IsColVector ? (col==0 && row>=0 && row<m_size) : (row==0 && col>=0 && col<m_size)); 00112 return coeff(IsColVector ? row : col); 00113 } 00114 00121 inline Scalar& coeffRef(Index i) 00122 { 00123 eigen_assert(i>=0 && i<m_size); 00124 return m_data.atWithInsertion(i); 00125 } 00126 00127 public: 00128 00129 class InnerIterator; 00130 class ReverseInnerIterator; 00131 00132 inline void setZero() { m_data.clear(); } 00133 00135 inline Index nonZeros() const { return static_cast<Index>(m_data.size()); } 00136 00137 inline void startVec(Index outer) 00138 { 00139 EIGEN_UNUSED_VARIABLE(outer); 00140 eigen_assert(outer==0); 00141 } 00142 00143 inline Scalar& insertBackByOuterInner(Index outer, Index inner) 00144 { 00145 EIGEN_UNUSED_VARIABLE(outer); 00146 eigen_assert(outer==0); 00147 return insertBack(inner); 00148 } 00149 inline Scalar& insertBack(Index i) 00150 { 00151 m_data.append(0, i); 00152 return m_data.value(m_data.size()-1); 00153 } 00154 00155 inline Scalar& insert(Index row, Index col) 00156 { 00157 eigen_assert(IsColVector ? (col==0 && row>=0 && row<m_size) : (row==0 && col>=0 && col<m_size)); 00158 00159 Index inner = IsColVector ? row : col; 00160 Index outer = IsColVector ? col : row; 00161 EIGEN_ONLY_USED_FOR_DEBUG(outer); 00162 eigen_assert(outer==0); 00163 return insert(inner); 00164 } 00165 Scalar& insert(Index i) 00166 { 00167 eigen_assert(i>=0 && i<m_size); 00168 00169 Index startId = 0; 00170 Index p = Index(m_data.size()) - 1; 00171 // TODO smart realloc 00172 m_data.resize(p+2,1); 00173 00174 while ( (p >= startId) && (m_data.index(p) > i) ) 00175 { 00176 m_data.index(p+1) = m_data.index(p); 00177 m_data.value(p+1) = m_data.value(p); 00178 --p; 00179 } 00180 m_data.index(p+1) = i; 00181 m_data.value(p+1) = 0; 00182 return m_data.value(p+1); 00183 } 00184 00187 inline void reserve(Index reserveSize) { m_data.reserve(reserveSize); } 00188 00189 00190 inline void finalize() {} 00191 00192 void prune(const Scalar& reference, const RealScalar& epsilon = NumTraits<RealScalar>::dummy_precision()) 00193 { 00194 m_data.prune(reference,epsilon); 00195 } 00196 00197 void resize(Index rows, Index cols) 00198 { 00199 eigen_assert(rows==1 || cols==1); 00200 resize(IsColVector ? rows : cols); 00201 } 00202 00203 void resize(Index newSize) 00204 { 00205 m_size = newSize; 00206 m_data.clear(); 00207 } 00208 00209 void resizeNonZeros(Index size) { m_data.resize(size); } 00210 00211 inline SparseVector() : m_size(0) { check_template_parameters(); resize(0); } 00212 00213 inline SparseVector(Index size) : m_size(0) { check_template_parameters(); resize(size); } 00214 00215 inline SparseVector(Index rows, Index cols) : m_size(0) { check_template_parameters(); resize(rows,cols); } 00216 00217 template<typename OtherDerived> 00218 inline SparseVector(const SparseMatrixBase<OtherDerived>& other) 00219 : m_size(0) 00220 { 00221 check_template_parameters(); 00222 *this = other.derived(); 00223 } 00224 00225 inline SparseVector(const SparseVector& other) 00226 : SparseBase(other), m_size(0) 00227 { 00228 check_template_parameters(); 00229 *this = other.derived(); 00230 } 00231 00236 inline void swap(SparseVector& other) 00237 { 00238 std::swap(m_size, other.m_size); 00239 m_data.swap(other.m_data); 00240 } 00241 00242 inline SparseVector& operator=(const SparseVector& other) 00243 { 00244 if (other.isRValue()) 00245 { 00246 swap(other.const_cast_derived()); 00247 } 00248 else 00249 { 00250 resize(other.size()); 00251 m_data = other.m_data; 00252 } 00253 return *this; 00254 } 00255 00256 template<typename OtherDerived> 00257 inline SparseVector& operator=(const SparseMatrixBase<OtherDerived>& other) 00258 { 00259 SparseVector tmp(other.size()); 00260 internal::sparse_vector_assign_selector<SparseVector,OtherDerived>::run(tmp,other.derived()); 00261 this->swap(tmp); 00262 return *this; 00263 } 00264 00265 #ifndef EIGEN_PARSED_BY_DOXYGEN 00266 template<typename Lhs, typename Rhs> 00267 inline SparseVector& operator=(const SparseSparseProduct<Lhs,Rhs>& product) 00268 { 00269 return Base::operator=(product); 00270 } 00271 #endif 00272 00273 friend std::ostream & operator << (std::ostream & s, const SparseVector& m) 00274 { 00275 for (Index i=0; i<m.nonZeros(); ++i) 00276 s << "(" << m.m_data.value(i) << "," << m.m_data.index(i) << ") "; 00277 s << std::endl; 00278 return s; 00279 } 00280 00282 inline ~SparseVector() {} 00283 00285 Scalar sum() const; 00286 00287 public: 00288 00290 EIGEN_DEPRECATED void startFill(Index reserve) 00291 { 00292 setZero(); 00293 m_data.reserve(reserve); 00294 } 00295 00297 EIGEN_DEPRECATED Scalar& fill(Index r, Index c) 00298 { 00299 eigen_assert(r==0 || c==0); 00300 return fill(IsColVector ? r : c); 00301 } 00302 00304 EIGEN_DEPRECATED Scalar& fill(Index i) 00305 { 00306 m_data.append(0, i); 00307 return m_data.value(m_data.size()-1); 00308 } 00309 00311 EIGEN_DEPRECATED Scalar& fillrand(Index r, Index c) 00312 { 00313 eigen_assert(r==0 || c==0); 00314 return fillrand(IsColVector ? r : c); 00315 } 00316 00318 EIGEN_DEPRECATED Scalar& fillrand(Index i) 00319 { 00320 return insert(i); 00321 } 00322 00324 EIGEN_DEPRECATED void endFill() {} 00325 00326 // These two functions were here in the 3.1 release, so let's keep them in case some code rely on them. 00328 EIGEN_DEPRECATED Storage& _data() { return m_data; } 00330 EIGEN_DEPRECATED const Storage& _data() const { return m_data; } 00331 00332 # ifdef EIGEN_SPARSEVECTOR_PLUGIN 00333 # include EIGEN_SPARSEVECTOR_PLUGIN 00334 # endif 00335 00336 protected: 00337 00338 static void check_template_parameters() 00339 { 00340 EIGEN_STATIC_ASSERT(NumTraits<Index>::IsSigned,THE_INDEX_TYPE_MUST_BE_A_SIGNED_TYPE); 00341 EIGEN_STATIC_ASSERT((_Options&(ColMajor|RowMajor))==Options,INVALID_MATRIX_TEMPLATE_PARAMETERS); 00342 } 00343 00344 Storage m_data; 00345 Index m_size; 00346 }; 00347 00348 template<typename Scalar, int _Options, typename _Index> 00349 class SparseVector<Scalar,_Options,_Index>::InnerIterator 00350 { 00351 public: 00352 InnerIterator(const SparseVector& vec, Index outer=0) 00353 : m_data(vec.m_data), m_id(0), m_end(static_cast<Index>(m_data.size())) 00354 { 00355 EIGEN_UNUSED_VARIABLE(outer); 00356 eigen_assert(outer==0); 00357 } 00358 00359 InnerIterator(const internal::CompressedStorage<Scalar,Index>& data) 00360 : m_data(data), m_id(0), m_end(static_cast<Index>(m_data.size())) 00361 {} 00362 00363 inline InnerIterator& operator++() { m_id++; return *this; } 00364 00365 inline Scalar value() const { return m_data.value(m_id); } 00366 inline Scalar& valueRef() { return const_cast<Scalar&>(m_data.value(m_id)); } 00367 00368 inline Index index() const { return m_data.index(m_id); } 00369 inline Index row() const { return IsColVector ? index() : 0; } 00370 inline Index col() const { return IsColVector ? 0 : index(); } 00371 00372 inline operator bool() const { return (m_id < m_end); } 00373 00374 protected: 00375 const internal::CompressedStorage<Scalar,Index>& m_data; 00376 Index m_id; 00377 const Index m_end; 00378 }; 00379 00380 template<typename Scalar, int _Options, typename _Index> 00381 class SparseVector<Scalar,_Options,_Index>::ReverseInnerIterator 00382 { 00383 public: 00384 ReverseInnerIterator(const SparseVector& vec, Index outer=0) 00385 : m_data(vec.m_data), m_id(static_cast<Index>(m_data.size())), m_start(0) 00386 { 00387 EIGEN_UNUSED_VARIABLE(outer); 00388 eigen_assert(outer==0); 00389 } 00390 00391 ReverseInnerIterator(const internal::CompressedStorage<Scalar,Index>& data) 00392 : m_data(data), m_id(static_cast<Index>(m_data.size())), m_start(0) 00393 {} 00394 00395 inline ReverseInnerIterator& operator--() { m_id--; return *this; } 00396 00397 inline Scalar value() const { return m_data.value(m_id-1); } 00398 inline Scalar& valueRef() { return const_cast<Scalar&>(m_data.value(m_id-1)); } 00399 00400 inline Index index() const { return m_data.index(m_id-1); } 00401 inline Index row() const { return IsColVector ? index() : 0; } 00402 inline Index col() const { return IsColVector ? 0 : index(); } 00403 00404 inline operator bool() const { return (m_id > m_start); } 00405 00406 protected: 00407 const internal::CompressedStorage<Scalar,Index>& m_data; 00408 Index m_id; 00409 const Index m_start; 00410 }; 00411 00412 namespace internal { 00413 00414 template< typename Dest, typename Src> 00415 struct sparse_vector_assign_selector<Dest,Src,SVA_Inner> { 00416 static void run(Dest& dst, const Src& src) { 00417 eigen_internal_assert(src.innerSize()==src.size()); 00418 for(typename Src::InnerIterator it(src, 0); it; ++it) 00419 dst.insert(it.index()) = it.value(); 00420 } 00421 }; 00422 00423 template< typename Dest, typename Src> 00424 struct sparse_vector_assign_selector<Dest,Src,SVA_Outer> { 00425 static void run(Dest& dst, const Src& src) { 00426 eigen_internal_assert(src.outerSize()==src.size()); 00427 for(typename Dest::Index i=0; i<src.size(); ++i) 00428 { 00429 typename Src::InnerIterator it(src, i); 00430 if(it) 00431 dst.insert(i) = it.value(); 00432 } 00433 } 00434 }; 00435 00436 template< typename Dest, typename Src> 00437 struct sparse_vector_assign_selector<Dest,Src,SVA_RuntimeSwitch> { 00438 static void run(Dest& dst, const Src& src) { 00439 if(src.outerSize()==1) sparse_vector_assign_selector<Dest,Src,SVA_Inner>::run(dst, src); 00440 else sparse_vector_assign_selector<Dest,Src,SVA_Outer>::run(dst, src); 00441 } 00442 }; 00443 00444 } 00445 00446 } // end namespace Eigen 00447 00448 #endif // EIGEN_SPARSEVECTOR_H