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 : SparseBase(other), 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 ( (bool(OtherDerived::IsVectorAtCompileTime) && int(RowsAtCompileTime)!=int(OtherDerived::RowsAtCompileTime))
00234 || ((!bool(OtherDerived::IsVectorAtCompileTime)) && ( bool(IsColVector) ? other.cols()>1 : other.rows()>1 )))
00235 return assign(other.transpose());
00236 else
00237 return assign(other);
00238 }
00239
00240 #ifndef EIGEN_PARSED_BY_DOXYGEN
00241 template<typename Lhs, typename Rhs>
00242 inline SparseVector& operator=(const SparseSparseProduct<Lhs,Rhs>& product)
00243 {
00244 return Base::operator=(product);
00245 }
00246 #endif
00247
00248 friend std::ostream & operator << (std::ostream & s, const SparseVector& m)
00249 {
00250 for (Index i=0; i<m.nonZeros(); ++i)
00251 s << "(" << m.m_data.value(i) << "," << m.m_data.index(i) << ") ";
00252 s << std::endl;
00253 return s;
00254 }
00255
00257 inline ~SparseVector() {}
00258
00260 Scalar sum() const;
00261
00262 public:
00263
00265 EIGEN_DEPRECATED void startFill(Index reserve)
00266 {
00267 setZero();
00268 m_data.reserve(reserve);
00269 }
00270
00272 EIGEN_DEPRECATED Scalar& fill(Index r, Index c)
00273 {
00274 eigen_assert(r==0 || c==0);
00275 return fill(IsColVector ? r : c);
00276 }
00277
00279 EIGEN_DEPRECATED Scalar& fill(Index i)
00280 {
00281 m_data.append(0, i);
00282 return m_data.value(m_data.size()-1);
00283 }
00284
00286 EIGEN_DEPRECATED Scalar& fillrand(Index r, Index c)
00287 {
00288 eigen_assert(r==0 || c==0);
00289 return fillrand(IsColVector ? r : c);
00290 }
00291
00293 EIGEN_DEPRECATED Scalar& fillrand(Index i)
00294 {
00295 return insert(i);
00296 }
00297
00299 EIGEN_DEPRECATED void endFill() {}
00300
00301 # ifdef EIGEN_SPARSEVECTOR_PLUGIN
00302 # include EIGEN_SPARSEVECTOR_PLUGIN
00303 # endif
00304
00305 protected:
00306 template<typename OtherDerived>
00307 EIGEN_DONT_INLINE SparseVector& assign(const SparseMatrixBase<OtherDerived>& _other)
00308 {
00309 const OtherDerived& other(_other.derived());
00310 const bool needToTranspose = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit);
00311 if(needToTranspose)
00312 {
00313 Index size = other.size();
00314 Index nnz = other.nonZeros();
00315 resize(size);
00316 reserve(nnz);
00317 for(Index i=0; i<size; ++i)
00318 {
00319 typename OtherDerived::InnerIterator it(other, i);
00320 if(it)
00321 insert(i) = it.value();
00322 }
00323 return *this;
00324 }
00325 else
00326 {
00327
00328 return Base::operator=(other);
00329 }
00330 }
00331 };
00332
00333 template<typename Scalar, int _Options, typename _Index>
00334 class SparseVector<Scalar,_Options,_Index>::InnerIterator
00335 {
00336 public:
00337 InnerIterator(const SparseVector& vec, Index outer=0)
00338 : m_data(vec.m_data), m_id(0), m_end(static_cast<Index>(m_data.size()))
00339 {
00340 EIGEN_UNUSED_VARIABLE(outer);
00341 eigen_assert(outer==0);
00342 }
00343
00344 InnerIterator(const internal::CompressedStorage<Scalar,Index>& data)
00345 : m_data(data), m_id(0), m_end(static_cast<Index>(m_data.size()))
00346 {}
00347
00348 inline InnerIterator& operator++() { m_id++; return *this; }
00349
00350 inline Scalar value() const { return m_data.value(m_id); }
00351 inline Scalar& valueRef() { return const_cast<Scalar&>(m_data.value(m_id)); }
00352
00353 inline Index index() const { return m_data.index(m_id); }
00354 inline Index row() const { return IsColVector ? index() : 0; }
00355 inline Index col() const { return IsColVector ? 0 : index(); }
00356
00357 inline operator bool() const { return (m_id < m_end); }
00358
00359 protected:
00360 const internal::CompressedStorage<Scalar,Index>& m_data;
00361 Index m_id;
00362 const Index m_end;
00363 };
00364
00365 template<typename Scalar, int _Options, typename _Index>
00366 class SparseVector<Scalar,_Options,_Index>::ReverseInnerIterator
00367 {
00368 public:
00369 ReverseInnerIterator(const SparseVector& vec, Index outer=0)
00370 : m_data(vec.m_data), m_id(static_cast<Index>(m_data.size())), m_start(0)
00371 {
00372 EIGEN_UNUSED_VARIABLE(outer);
00373 eigen_assert(outer==0);
00374 }
00375
00376 ReverseInnerIterator(const internal::CompressedStorage<Scalar,Index>& data)
00377 : m_data(data), m_id(static_cast<Index>(m_data.size())), m_start(0)
00378 {}
00379
00380 inline ReverseInnerIterator& operator--() { m_id--; return *this; }
00381
00382 inline Scalar value() const { return m_data.value(m_id-1); }
00383 inline Scalar& valueRef() { return const_cast<Scalar&>(m_data.value(m_id-1)); }
00384
00385 inline Index index() const { return m_data.index(m_id-1); }
00386 inline Index row() const { return IsColVector ? index() : 0; }
00387 inline Index col() const { return IsColVector ? 0 : index(); }
00388
00389 inline operator bool() const { return (m_id > m_start); }
00390
00391 protected:
00392 const internal::CompressedStorage<Scalar,Index>& m_data;
00393 Index m_id;
00394 const Index m_start;
00395 };
00396
00397 }
00398
00399 #endif // EIGEN_SPARSEVECTOR_H