00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef EIGEN_DYNAMIC_SPARSEMATRIX_H
00026 #define EIGEN_DYNAMIC_SPARSEMATRIX_H
00027
00045 template<typename _Scalar, int _Flags>
00046 struct ei_traits<DynamicSparseMatrix<_Scalar, _Flags> >
00047 {
00048 typedef _Scalar Scalar;
00049 enum {
00050 RowsAtCompileTime = Dynamic,
00051 ColsAtCompileTime = Dynamic,
00052 MaxRowsAtCompileTime = Dynamic,
00053 MaxColsAtCompileTime = Dynamic,
00054 Flags = SparseBit | _Flags,
00055 CoeffReadCost = NumTraits<Scalar>::ReadCost,
00056 SupportedAccessPatterns = OuterRandomAccessPattern
00057 };
00058 };
00059
00060 template<typename _Scalar, int _Flags>
00061 class DynamicSparseMatrix
00062 : public SparseMatrixBase<DynamicSparseMatrix<_Scalar, _Flags> >
00063 {
00064 public:
00065 EIGEN_SPARSE_GENERIC_PUBLIC_INTERFACE(DynamicSparseMatrix)
00066
00067
00068
00069 typedef MappedSparseMatrix<Scalar,Flags> Map;
00070
00071 protected:
00072
00073 enum { IsRowMajor = Base::IsRowMajor };
00074 typedef DynamicSparseMatrix<Scalar,(Flags&~RowMajorBit)|(IsRowMajor?RowMajorBit:0)> TransposedSparseMatrix;
00075
00076 int m_innerSize;
00077 std::vector<CompressedStorage<Scalar> > m_data;
00078
00079 public:
00080
00081 inline int rows() const { return IsRowMajor ? outerSize() : m_innerSize; }
00082 inline int cols() const { return IsRowMajor ? m_innerSize : outerSize(); }
00083 inline int innerSize() const { return m_innerSize; }
00084 inline int outerSize() const { return m_data.size(); }
00085 inline int innerNonZeros(int j) const { return m_data[j].size(); }
00086
00087 std::vector<CompressedStorage<Scalar> >& _data() { return m_data; }
00088 const std::vector<CompressedStorage<Scalar> >& _data() const { return m_data; }
00089
00093 inline Scalar coeff(int row, int col) const
00094 {
00095 const int outer = IsRowMajor ? row : col;
00096 const int inner = IsRowMajor ? col : row;
00097 return m_data[outer].at(inner);
00098 }
00099
00104 inline Scalar& coeffRef(int row, int col)
00105 {
00106 const int outer = IsRowMajor ? row : col;
00107 const int inner = IsRowMajor ? col : row;
00108 return m_data[outer].atWithInsertion(inner);
00109 }
00110
00111 class InnerIterator;
00112
00113 inline void setZero()
00114 {
00115 for (int j=0; j<outerSize(); ++j)
00116 m_data[j].clear();
00117 }
00118
00120 inline int nonZeros() const
00121 {
00122 int res = 0;
00123 for (int j=0; j<outerSize(); ++j)
00124 res += m_data[j].size();
00125 return res;
00126 }
00127
00129 inline void startFill(int reserveSize = 1000)
00130 {
00131 if (outerSize()>0)
00132 {
00133 int reserveSizePerVector = std::max(reserveSize/outerSize(),4);
00134 for (int j=0; j<outerSize(); ++j)
00135 {
00136 m_data[j].clear();
00137 m_data[j].reserve(reserveSizePerVector);
00138 }
00139 }
00140 }
00141
00150 inline Scalar& fill(int row, int col)
00151 {
00152 const int outer = IsRowMajor ? row : col;
00153 const int inner = IsRowMajor ? col : row;
00154 ei_assert(outer<int(m_data.size()) && inner<m_innerSize);
00155 ei_assert((m_data[outer].size()==0) || (m_data[outer].index(m_data[outer].size()-1)<inner));
00156 m_data[outer].append(0, inner);
00157 return m_data[outer].value(m_data[outer].size()-1);
00158 }
00159
00164 inline Scalar& fillrand(int row, int col)
00165 {
00166 const int outer = IsRowMajor ? row : col;
00167 const int inner = IsRowMajor ? col : row;
00168
00169 int startId = 0;
00170 int id = m_data[outer].size() - 1;
00171 m_data[outer].resize(id+2,1);
00172
00173 while ( (id >= startId) && (m_data[outer].index(id) > inner) )
00174 {
00175 m_data[outer].index(id+1) = m_data[outer].index(id);
00176 m_data[outer].value(id+1) = m_data[outer].value(id);
00177 --id;
00178 }
00179 m_data[outer].index(id+1) = inner;
00180 m_data[outer].value(id+1) = 0;
00181 return m_data[outer].value(id+1);
00182 }
00183
00185 inline void endFill() {}
00186
00187 void prune(Scalar reference, RealScalar epsilon = precision<RealScalar>())
00188 {
00189 for (int j=0; j<outerSize(); ++j)
00190 m_data[j].prune(reference,epsilon);
00191 }
00192
00195 void resize(int rows, int cols)
00196 {
00197 const int outerSize = IsRowMajor ? rows : cols;
00198 m_innerSize = IsRowMajor ? cols : rows;
00199 setZero();
00200 if (int(m_data.size()) != outerSize)
00201 {
00202 m_data.resize(outerSize);
00203 }
00204 }
00205
00206 void resizeAndKeepData(int rows, int cols)
00207 {
00208 const int outerSize = IsRowMajor ? rows : cols;
00209 const int innerSize = IsRowMajor ? cols : rows;
00210 if (m_innerSize>innerSize)
00211 {
00212
00213
00214 std::cerr << "not implemented yet\n";
00215 std::exit(2);
00216 }
00217 if (m_data.size() != outerSize)
00218 {
00219 m_data.resize(outerSize);
00220 }
00221 }
00222
00223 inline DynamicSparseMatrix()
00224 : m_innerSize(0), m_data(0)
00225 {
00226 ei_assert(innerSize()==0 && outerSize()==0);
00227 }
00228
00229 inline DynamicSparseMatrix(int rows, int cols)
00230 : m_innerSize(0)
00231 {
00232 resize(rows, cols);
00233 }
00234
00235 template<typename OtherDerived>
00236 inline DynamicSparseMatrix(const SparseMatrixBase<OtherDerived>& other)
00237 : m_innerSize(0)
00238 {
00239 *this = other.derived();
00240 }
00241
00242 inline DynamicSparseMatrix(const DynamicSparseMatrix& other)
00243 : Base(), m_innerSize(0)
00244 {
00245 *this = other.derived();
00246 }
00247
00248 inline void swap(DynamicSparseMatrix& other)
00249 {
00250
00251 std::swap(m_innerSize, other.m_innerSize);
00252
00253 m_data.swap(other.m_data);
00254 }
00255
00256 inline DynamicSparseMatrix& operator=(const DynamicSparseMatrix& other)
00257 {
00258 if (other.isRValue())
00259 {
00260 swap(other.const_cast_derived());
00261 }
00262 else
00263 {
00264 resize(other.rows(), other.cols());
00265 m_data = other.m_data;
00266 }
00267 return *this;
00268 }
00269
00270 template<typename OtherDerived>
00271 inline DynamicSparseMatrix& operator=(const SparseMatrixBase<OtherDerived>& other)
00272 {
00273 return SparseMatrixBase<DynamicSparseMatrix>::operator=(other.derived());
00274 }
00275
00277 inline ~DynamicSparseMatrix() {}
00278 };
00279
00280 template<typename Scalar, int _Flags>
00281 class DynamicSparseMatrix<Scalar,_Flags>::InnerIterator : public SparseVector<Scalar,_Flags>::InnerIterator
00282 {
00283 typedef typename SparseVector<Scalar,_Flags>::InnerIterator Base;
00284 public:
00285 InnerIterator(const DynamicSparseMatrix& mat, int outer)
00286 : Base(mat.m_data[outer]), m_outer(outer)
00287 {}
00288
00289 inline int row() const { return IsRowMajor ? m_outer : Base::index(); }
00290 inline int col() const { return IsRowMajor ? Base::index() : m_outer; }
00291
00292 protected:
00293 const int m_outer;
00294
00295 private:
00296 InnerIterator& operator=(const InnerIterator&);
00297 };
00298
00299 #endif // EIGEN_DYNAMIC_SPARSEMATRIX_H