00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #ifndef EIGEN_DYNAMIC_SPARSEMATRIX_H
00011 #define EIGEN_DYNAMIC_SPARSEMATRIX_H
00012
00013 namespace Eigen {
00014
00035 namespace internal {
00036 template<typename _Scalar, int _Options, typename _Index>
00037 struct traits<DynamicSparseMatrix<_Scalar, _Options, _Index> >
00038 {
00039 typedef _Scalar Scalar;
00040 typedef _Index Index;
00041 typedef Sparse StorageKind;
00042 typedef MatrixXpr XprKind;
00043 enum {
00044 RowsAtCompileTime = Dynamic,
00045 ColsAtCompileTime = Dynamic,
00046 MaxRowsAtCompileTime = Dynamic,
00047 MaxColsAtCompileTime = Dynamic,
00048 Flags = _Options | NestByRefBit | LvalueBit,
00049 CoeffReadCost = NumTraits<Scalar>::ReadCost,
00050 SupportedAccessPatterns = OuterRandomAccessPattern
00051 };
00052 };
00053 }
00054
00055 template<typename _Scalar, int _Options, typename _Index>
00056 class DynamicSparseMatrix
00057 : public SparseMatrixBase<DynamicSparseMatrix<_Scalar, _Options, _Index> >
00058 {
00059 public:
00060 EIGEN_SPARSE_PUBLIC_INTERFACE(DynamicSparseMatrix)
00061
00062
00063
00064 typedef MappedSparseMatrix<Scalar,Flags> Map;
00065 using Base::IsRowMajor;
00066 using Base::operator=;
00067 enum {
00068 Options = _Options
00069 };
00070
00071 protected:
00072
00073 typedef DynamicSparseMatrix<Scalar,(Flags&~RowMajorBit)|(IsRowMajor?RowMajorBit:0)> TransposedSparseMatrix;
00074
00075 Index m_innerSize;
00076 std::vector<internal::CompressedStorage<Scalar,Index> > m_data;
00077
00078 public:
00079
00080 inline Index rows() const { return IsRowMajor ? outerSize() : m_innerSize; }
00081 inline Index cols() const { return IsRowMajor ? m_innerSize : outerSize(); }
00082 inline Index innerSize() const { return m_innerSize; }
00083 inline Index outerSize() const { return static_cast<Index>(m_data.size()); }
00084 inline Index innerNonZeros(Index j) const { return m_data[j].size(); }
00085
00086 std::vector<internal::CompressedStorage<Scalar,Index> >& _data() { return m_data; }
00087 const std::vector<internal::CompressedStorage<Scalar,Index> >& _data() const { return m_data; }
00088
00092 inline Scalar coeff(Index row, Index col) const
00093 {
00094 const Index outer = IsRowMajor ? row : col;
00095 const Index inner = IsRowMajor ? col : row;
00096 return m_data[outer].at(inner);
00097 }
00098
00103 inline Scalar& coeffRef(Index row, Index col)
00104 {
00105 const Index outer = IsRowMajor ? row : col;
00106 const Index inner = IsRowMajor ? col : row;
00107 return m_data[outer].atWithInsertion(inner);
00108 }
00109
00110 class InnerIterator;
00111 class ReverseInnerIterator;
00112
00113 void setZero()
00114 {
00115 for (Index j=0; j<outerSize(); ++j)
00116 m_data[j].clear();
00117 }
00118
00120 Index nonZeros() const
00121 {
00122 Index res = 0;
00123 for (Index j=0; j<outerSize(); ++j)
00124 res += static_cast<Index>(m_data[j].size());
00125 return res;
00126 }
00127
00128
00129
00130 void reserve(Index reserveSize = 1000)
00131 {
00132 if (outerSize()>0)
00133 {
00134 Index reserveSizePerVector = (std::max)(reserveSize/outerSize(),Index(4));
00135 for (Index j=0; j<outerSize(); ++j)
00136 {
00137 m_data[j].reserve(reserveSizePerVector);
00138 }
00139 }
00140 }
00141
00143 inline void startVec(Index ) {}
00144
00150 inline Scalar& insertBack(Index row, Index col)
00151 {
00152 return insertBackByOuterInner(IsRowMajor?row:col, IsRowMajor?col:row);
00153 }
00154
00156 inline Scalar& insertBackByOuterInner(Index outer, Index inner)
00157 {
00158 eigen_assert(outer<Index(m_data.size()) && inner<m_innerSize && "out of range");
00159 eigen_assert(((m_data[outer].size()==0) || (m_data[outer].index(m_data[outer].size()-1)<inner))
00160 && "wrong sorted insertion");
00161 m_data[outer].append(0, inner);
00162 return m_data[outer].value(m_data[outer].size()-1);
00163 }
00164
00165 inline Scalar& insert(Index row, Index col)
00166 {
00167 const Index outer = IsRowMajor ? row : col;
00168 const Index inner = IsRowMajor ? col : row;
00169
00170 Index startId = 0;
00171 Index id = static_cast<Index>(m_data[outer].size()) - 1;
00172 m_data[outer].resize(id+2,1);
00173
00174 while ( (id >= startId) && (m_data[outer].index(id) > inner) )
00175 {
00176 m_data[outer].index(id+1) = m_data[outer].index(id);
00177 m_data[outer].value(id+1) = m_data[outer].value(id);
00178 --id;
00179 }
00180 m_data[outer].index(id+1) = inner;
00181 m_data[outer].value(id+1) = 0;
00182 return m_data[outer].value(id+1);
00183 }
00184
00186 inline void finalize() {}
00187
00189 void prune(Scalar reference, RealScalar epsilon = NumTraits<RealScalar>::dummy_precision())
00190 {
00191 for (Index j=0; j<outerSize(); ++j)
00192 m_data[j].prune(reference,epsilon);
00193 }
00194
00197 void resize(Index rows, Index cols)
00198 {
00199 const Index outerSize = IsRowMajor ? rows : cols;
00200 m_innerSize = IsRowMajor ? cols : rows;
00201 setZero();
00202 if (Index(m_data.size()) != outerSize)
00203 {
00204 m_data.resize(outerSize);
00205 }
00206 }
00207
00208 void resizeAndKeepData(Index rows, Index cols)
00209 {
00210 const Index outerSize = IsRowMajor ? rows : cols;
00211 const Index innerSize = IsRowMajor ? cols : rows;
00212 if (m_innerSize>innerSize)
00213 {
00214
00215
00216
00217 exit(2);
00218 }
00219 if (m_data.size() != outerSize)
00220 {
00221 m_data.resize(outerSize);
00222 }
00223 }
00224
00226 EIGEN_DEPRECATED inline DynamicSparseMatrix()
00227 : m_innerSize(0), m_data(0)
00228 {
00229 eigen_assert(innerSize()==0 && outerSize()==0);
00230 }
00231
00233 EIGEN_DEPRECATED inline DynamicSparseMatrix(Index rows, Index cols)
00234 : m_innerSize(0)
00235 {
00236 resize(rows, cols);
00237 }
00238
00240 template<typename OtherDerived>
00241 EIGEN_DEPRECATED explicit inline DynamicSparseMatrix(const SparseMatrixBase<OtherDerived>& other)
00242 : m_innerSize(0)
00243 {
00244 Base::operator=(other.derived());
00245 }
00246
00247 inline DynamicSparseMatrix(const DynamicSparseMatrix& other)
00248 : Base(), m_innerSize(0)
00249 {
00250 *this = other.derived();
00251 }
00252
00253 inline void swap(DynamicSparseMatrix& other)
00254 {
00255
00256 std::swap(m_innerSize, other.m_innerSize);
00257
00258 m_data.swap(other.m_data);
00259 }
00260
00261 inline DynamicSparseMatrix& operator=(const DynamicSparseMatrix& other)
00262 {
00263 if (other.isRValue())
00264 {
00265 swap(other.const_cast_derived());
00266 }
00267 else
00268 {
00269 resize(other.rows(), other.cols());
00270 m_data = other.m_data;
00271 }
00272 return *this;
00273 }
00274
00276 inline ~DynamicSparseMatrix() {}
00277
00278 public:
00279
00282 EIGEN_DEPRECATED void startFill(Index reserveSize = 1000)
00283 {
00284 setZero();
00285 reserve(reserveSize);
00286 }
00287
00297 EIGEN_DEPRECATED Scalar& fill(Index row, Index col)
00298 {
00299 const Index outer = IsRowMajor ? row : col;
00300 const Index inner = IsRowMajor ? col : row;
00301 return insertBack(outer,inner);
00302 }
00303
00309 EIGEN_DEPRECATED Scalar& fillrand(Index row, Index col)
00310 {
00311 return insert(row,col);
00312 }
00313
00316 EIGEN_DEPRECATED void endFill() {}
00317
00318 # ifdef EIGEN_DYNAMICSPARSEMATRIX_PLUGIN
00319 # include EIGEN_DYNAMICSPARSEMATRIX_PLUGIN
00320 # endif
00321 };
00322
00323 template<typename Scalar, int _Options, typename _Index>
00324 class DynamicSparseMatrix<Scalar,_Options,_Index>::InnerIterator : public SparseVector<Scalar,_Options,_Index>::InnerIterator
00325 {
00326 typedef typename SparseVector<Scalar,_Options,_Index>::InnerIterator Base;
00327 public:
00328 InnerIterator(const DynamicSparseMatrix& mat, Index outer)
00329 : Base(mat.m_data[outer]), m_outer(outer)
00330 {}
00331
00332 inline Index row() const { return IsRowMajor ? m_outer : Base::index(); }
00333 inline Index col() const { return IsRowMajor ? Base::index() : m_outer; }
00334
00335 protected:
00336 const Index m_outer;
00337 };
00338
00339 template<typename Scalar, int _Options, typename _Index>
00340 class DynamicSparseMatrix<Scalar,_Options,_Index>::ReverseInnerIterator : public SparseVector<Scalar,_Options,_Index>::ReverseInnerIterator
00341 {
00342 typedef typename SparseVector<Scalar,_Options,_Index>::ReverseInnerIterator Base;
00343 public:
00344 ReverseInnerIterator(const DynamicSparseMatrix& mat, Index outer)
00345 : Base(mat.m_data[outer]), m_outer(outer)
00346 {}
00347
00348 inline Index row() const { return IsRowMajor ? m_outer : Base::index(); }
00349 inline Index col() const { return IsRowMajor ? Base::index() : m_outer; }
00350
00351 protected:
00352 const Index m_outer;
00353 };
00354
00355 }
00356
00357 #endif // EIGEN_DYNAMIC_SPARSEMATRIX_H