00001
00002
00003
00004
00005
00006
00007
00008
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
00050 template<typename _Scalar, int _Options, typename _Index>
00051 class SparseVector
00052 : public SparseMatrixBase<SparseVector<_Scalar, _Options, _Index> >
00053 {
00054 public:
00055 EIGEN_SPARSE_PUBLIC_INTERFACE(SparseVector)
00056 EIGEN_SPARSE_INHERIT_ASSIGNMENT_OPERATOR(SparseVector, +=)
00057 EIGEN_SPARSE_INHERIT_ASSIGNMENT_OPERATOR(SparseVector, -=)
00058
00059 protected:
00060 public:
00061
00062 typedef SparseMatrixBase<SparseVector> SparseBase;
00063 enum { IsColVector = internal::traits<SparseVector>::IsColVector };
00064
00065 enum {
00066 Options = _Options
00067 };
00068
00069 internal::CompressedStorage<Scalar,Index> m_data;
00070 Index m_size;
00071
00072 internal::CompressedStorage<Scalar,Index>& _data() { return m_data; }
00073 internal::CompressedStorage<Scalar,Index>& _data() const { return m_data; }
00074
00075 public:
00076
00077 EIGEN_STRONG_INLINE Index rows() const { return IsColVector ? m_size : 1; }
00078 EIGEN_STRONG_INLINE Index cols() const { return IsColVector ? 1 : m_size; }
00079 EIGEN_STRONG_INLINE Index innerSize() const { return m_size; }
00080 EIGEN_STRONG_INLINE Index outerSize() const { return 1; }
00081
00082 EIGEN_STRONG_INLINE const Scalar* valuePtr() const { return &m_data.value(0); }
00083 EIGEN_STRONG_INLINE Scalar* valuePtr() { return &m_data.value(0); }
00084
00085 EIGEN_STRONG_INLINE const Index* innerIndexPtr() const { return &m_data.index(0); }
00086 EIGEN_STRONG_INLINE Index* innerIndexPtr() { return &m_data.index(0); }
00087
00088 inline Scalar coeff(Index row, Index col) const
00089 {
00090 eigen_assert((IsColVector ? col : row)==0);
00091 return coeff(IsColVector ? row : col);
00092 }
00093 inline Scalar coeff(Index i) const { return m_data.at(i); }
00094
00095 inline Scalar& coeffRef(Index row, Index col)
00096 {
00097 eigen_assert((IsColVector ? col : row)==0);
00098 return coeff(IsColVector ? row : col);
00099 }
00100
00107 inline Scalar& coeffRef(Index i)
00108 {
00109 return m_data.atWithInsertion(i);
00110 }
00111
00112 public:
00113
00114 class InnerIterator;
00115 class ReverseInnerIterator;
00116
00117 inline void setZero() { m_data.clear(); }
00118
00120 inline Index nonZeros() const { return static_cast<Index>(m_data.size()); }
00121
00122 inline void startVec(Index outer)
00123 {
00124 EIGEN_UNUSED_VARIABLE(outer);
00125 eigen_assert(outer==0);
00126 }
00127
00128 inline Scalar& insertBackByOuterInner(Index outer, Index inner)
00129 {
00130 EIGEN_UNUSED_VARIABLE(outer);
00131 eigen_assert(outer==0);
00132 return insertBack(inner);
00133 }
00134 inline Scalar& insertBack(Index i)
00135 {
00136 m_data.append(0, i);
00137 return m_data.value(m_data.size()-1);
00138 }
00139
00140 inline Scalar& insert(Index row, Index col)
00141 {
00142 Index inner = IsColVector ? row : col;
00143 Index outer = IsColVector ? col : row;
00144 eigen_assert(outer==0);
00145 return insert(inner);
00146 }
00147 Scalar& insert(Index i)
00148 {
00149 Index startId = 0;
00150 Index p = Index(m_data.size()) - 1;
00151
00152 m_data.resize(p+2,1);
00153
00154 while ( (p >= startId) && (m_data.index(p) > i) )
00155 {
00156 m_data.index(p+1) = m_data.index(p);
00157 m_data.value(p+1) = m_data.value(p);
00158 --p;
00159 }
00160 m_data.index(p+1) = i;
00161 m_data.value(p+1) = 0;
00162 return m_data.value(p+1);
00163 }
00164
00167 inline void reserve(Index reserveSize) { m_data.reserve(reserveSize); }
00168
00169
00170 inline void finalize() {}
00171
00172 void prune(Scalar reference, RealScalar epsilon = NumTraits<RealScalar>::dummy_precision())
00173 {
00174 m_data.prune(reference,epsilon);
00175 }
00176
00177 void resize(Index rows, Index cols)
00178 {
00179 eigen_assert(rows==1 || cols==1);
00180 resize(IsColVector ? rows : cols);
00181 }
00182
00183 void resize(Index newSize)
00184 {
00185 m_size = newSize;
00186 m_data.clear();
00187 }
00188
00189 void resizeNonZeros(Index size) { m_data.resize(size); }
00190
00191 inline SparseVector() : m_size(0) { resize(0); }
00192
00193 inline SparseVector(Index size) : m_size(0) { resize(size); }
00194
00195 inline SparseVector(Index rows, Index cols) : m_size(0) { resize(rows,cols); }
00196
00197 template<typename OtherDerived>
00198 inline SparseVector(const SparseMatrixBase<OtherDerived>& other)
00199 : m_size(0)
00200 {
00201 *this = other.derived();
00202 }
00203
00204 inline SparseVector(const SparseVector& other)
00205 : m_size(0)
00206 {
00207 *this = other.derived();
00208 }
00209
00210 inline void swap(SparseVector& other)
00211 {
00212 std::swap(m_size, other.m_size);
00213 m_data.swap(other.m_data);
00214 }
00215
00216 inline SparseVector& operator=(const SparseVector& other)
00217 {
00218 if (other.isRValue())
00219 {
00220 swap(other.const_cast_derived());
00221 }
00222 else
00223 {
00224 resize(other.size());
00225 m_data = other.m_data;
00226 }
00227 return *this;
00228 }
00229
00230 template<typename OtherDerived>
00231 inline SparseVector& operator=(const SparseMatrixBase<OtherDerived>& other)
00232 {
00233 if (int(RowsAtCompileTime)!=int(OtherDerived::RowsAtCompileTime))
00234 return assign(other.transpose());
00235 else
00236 return assign(other);
00237 }
00238
00239 #ifndef EIGEN_PARSED_BY_DOXYGEN
00240 template<typename Lhs, typename Rhs>
00241 inline SparseVector& operator=(const SparseSparseProduct<Lhs,Rhs>& product)
00242 {
00243 return Base::operator=(product);
00244 }
00245 #endif
00246
00247 friend std::ostream & operator << (std::ostream & s, const SparseVector& m)
00248 {
00249 for (Index i=0; i<m.nonZeros(); ++i)
00250 s << "(" << m.m_data.value(i) << "," << m.m_data.index(i) << ") ";
00251 s << std::endl;
00252 return s;
00253 }
00254
00256 inline ~SparseVector() {}
00257
00259 Scalar sum() const;
00260
00261 public:
00262
00264 EIGEN_DEPRECATED void startFill(Index reserve)
00265 {
00266 setZero();
00267 m_data.reserve(reserve);
00268 }
00269
00271 EIGEN_DEPRECATED Scalar& fill(Index r, Index c)
00272 {
00273 eigen_assert(r==0 || c==0);
00274 return fill(IsColVector ? r : c);
00275 }
00276
00278 EIGEN_DEPRECATED Scalar& fill(Index i)
00279 {
00280 m_data.append(0, i);
00281 return m_data.value(m_data.size()-1);
00282 }
00283
00285 EIGEN_DEPRECATED Scalar& fillrand(Index r, Index c)
00286 {
00287 eigen_assert(r==0 || c==0);
00288 return fillrand(IsColVector ? r : c);
00289 }
00290
00292 EIGEN_DEPRECATED Scalar& fillrand(Index i)
00293 {
00294 return insert(i);
00295 }
00296
00298 EIGEN_DEPRECATED void endFill() {}
00299
00300 # ifdef EIGEN_SPARSEVECTOR_PLUGIN
00301 # include EIGEN_SPARSEVECTOR_PLUGIN
00302 # endif
00303
00304 protected:
00305 template<typename OtherDerived>
00306 EIGEN_DONT_INLINE SparseVector& assign(const SparseMatrixBase<OtherDerived>& _other)
00307 {
00308 const OtherDerived& other(_other.derived());
00309 const bool needToTranspose = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit);
00310 if(needToTranspose)
00311 {
00312 Index size = other.size();
00313 Index nnz = other.nonZeros();
00314 resize(size);
00315 reserve(nnz);
00316 for(Index i=0; i<size; ++i)
00317 {
00318 typename OtherDerived::InnerIterator it(other, i);
00319 if(it)
00320 insert(i) = it.value();
00321 }
00322 return *this;
00323 }
00324 else
00325 {
00326
00327 return Base::operator=(other);
00328 }
00329 }
00330 };
00331
00332 template<typename Scalar, int _Options, typename _Index>
00333 class SparseVector<Scalar,_Options,_Index>::InnerIterator
00334 {
00335 public:
00336 InnerIterator(const SparseVector& vec, Index outer=0)
00337 : m_data(vec.m_data), m_id(0), m_end(static_cast<Index>(m_data.size()))
00338 {
00339 EIGEN_UNUSED_VARIABLE(outer);
00340 eigen_assert(outer==0);
00341 }
00342
00343 InnerIterator(const internal::CompressedStorage<Scalar,Index>& data)
00344 : m_data(data), m_id(0), m_end(static_cast<Index>(m_data.size()))
00345 {}
00346
00347 inline InnerIterator& operator++() { m_id++; return *this; }
00348
00349 inline Scalar value() const { return m_data.value(m_id); }
00350 inline Scalar& valueRef() { return const_cast<Scalar&>(m_data.value(m_id)); }
00351
00352 inline Index index() const { return m_data.index(m_id); }
00353 inline Index row() const { return IsColVector ? index() : 0; }
00354 inline Index col() const { return IsColVector ? 0 : index(); }
00355
00356 inline operator bool() const { return (m_id < m_end); }
00357
00358 protected:
00359 const internal::CompressedStorage<Scalar,Index>& m_data;
00360 Index m_id;
00361 const Index m_end;
00362 };
00363
00364 template<typename Scalar, int _Options, typename _Index>
00365 class SparseVector<Scalar,_Options,_Index>::ReverseInnerIterator
00366 {
00367 public:
00368 ReverseInnerIterator(const SparseVector& vec, Index outer=0)
00369 : m_data(vec.m_data), m_id(static_cast<Index>(m_data.size())), m_start(0)
00370 {
00371 EIGEN_UNUSED_VARIABLE(outer);
00372 eigen_assert(outer==0);
00373 }
00374
00375 ReverseInnerIterator(const internal::CompressedStorage<Scalar,Index>& data)
00376 : m_data(data), m_id(static_cast<Index>(m_data.size())), m_start(0)
00377 {}
00378
00379 inline ReverseInnerIterator& operator--() { m_id--; return *this; }
00380
00381 inline Scalar value() const { return m_data.value(m_id-1); }
00382 inline Scalar& valueRef() { return const_cast<Scalar&>(m_data.value(m_id-1)); }
00383
00384 inline Index index() const { return m_data.index(m_id-1); }
00385 inline Index row() const { return IsColVector ? index() : 0; }
00386 inline Index col() const { return IsColVector ? 0 : index(); }
00387
00388 inline operator bool() const { return (m_id > m_start); }
00389
00390 protected:
00391 const internal::CompressedStorage<Scalar,Index>& m_data;
00392 Index m_id;
00393 const Index m_start;
00394 };
00395
00396 }
00397
00398 #endif // EIGEN_SPARSEVECTOR_H