![]() |
Eigen-unsupported
3.3.3
|
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_DYNAMIC_SPARSEMATRIX_H 00011 #define EIGEN_DYNAMIC_SPARSEMATRIX_H 00012 00013 namespace Eigen { 00014 00035 namespace internal { 00036 template<typename _Scalar, int _Options, typename _StorageIndex> 00037 struct traits<DynamicSparseMatrix<_Scalar, _Options, _StorageIndex> > 00038 { 00039 typedef _Scalar Scalar; 00040 typedef _StorageIndex StorageIndex; 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 _StorageIndex> 00056 class DynamicSparseMatrix 00057 : public SparseMatrixBase<DynamicSparseMatrix<_Scalar, _Options, _StorageIndex> > 00058 { 00059 typedef SparseMatrixBase<DynamicSparseMatrix> Base; 00060 using Base::convert_index; 00061 public: 00062 EIGEN_SPARSE_PUBLIC_INTERFACE(DynamicSparseMatrix) 00063 // FIXME: why are these operator already alvailable ??? 00064 // EIGEN_SPARSE_INHERIT_ASSIGNMENT_OPERATOR(DynamicSparseMatrix, +=) 00065 // EIGEN_SPARSE_INHERIT_ASSIGNMENT_OPERATOR(DynamicSparseMatrix, -=) 00066 typedef MappedSparseMatrix<Scalar,Flags> Map; 00067 using Base::IsRowMajor; 00068 using Base::operator=; 00069 enum { 00070 Options = _Options 00071 }; 00072 00073 protected: 00074 00075 typedef DynamicSparseMatrix<Scalar,(Flags&~RowMajorBit)|(IsRowMajor?RowMajorBit:0), StorageIndex> TransposedSparseMatrix; 00076 00077 Index m_innerSize; 00078 std::vector<internal::CompressedStorage<Scalar,StorageIndex> > m_data; 00079 00080 public: 00081 00082 inline Index rows() const { return IsRowMajor ? outerSize() : m_innerSize; } 00083 inline Index cols() const { return IsRowMajor ? m_innerSize : outerSize(); } 00084 inline Index innerSize() const { return m_innerSize; } 00085 inline Index outerSize() const { return convert_index(m_data.size()); } 00086 inline Index innerNonZeros(Index j) const { return m_data[j].size(); } 00087 00088 std::vector<internal::CompressedStorage<Scalar,StorageIndex> >& _data() { return m_data; } 00089 const std::vector<internal::CompressedStorage<Scalar,StorageIndex> >& _data() const { return m_data; } 00090 00094 inline Scalar coeff(Index row, Index col) const 00095 { 00096 const Index outer = IsRowMajor ? row : col; 00097 const Index inner = IsRowMajor ? col : row; 00098 return m_data[outer].at(inner); 00099 } 00100 00105 inline Scalar& coeffRef(Index row, Index col) 00106 { 00107 const Index outer = IsRowMajor ? row : col; 00108 const Index inner = IsRowMajor ? col : row; 00109 return m_data[outer].atWithInsertion(inner); 00110 } 00111 00112 class InnerIterator; 00113 class ReverseInnerIterator; 00114 00115 void setZero() 00116 { 00117 for (Index j=0; j<outerSize(); ++j) 00118 m_data[j].clear(); 00119 } 00120 00122 Index nonZeros() const 00123 { 00124 Index res = 0; 00125 for (Index j=0; j<outerSize(); ++j) 00126 res += m_data[j].size(); 00127 return res; 00128 } 00129 00130 00131 00132 void reserve(Index reserveSize = 1000) 00133 { 00134 if (outerSize()>0) 00135 { 00136 Index reserveSizePerVector = (std::max)(reserveSize/outerSize(),Index(4)); 00137 for (Index j=0; j<outerSize(); ++j) 00138 { 00139 m_data[j].reserve(reserveSizePerVector); 00140 } 00141 } 00142 } 00143 00145 inline void startVec(Index /*outer*/) {} 00146 00152 inline Scalar& insertBack(Index row, Index col) 00153 { 00154 return insertBackByOuterInner(IsRowMajor?row:col, IsRowMajor?col:row); 00155 } 00156 00158 inline Scalar& insertBackByOuterInner(Index outer, Index inner) 00159 { 00160 eigen_assert(outer<Index(m_data.size()) && inner<m_innerSize && "out of range"); 00161 eigen_assert(((m_data[outer].size()==0) || (m_data[outer].index(m_data[outer].size()-1)<inner)) 00162 && "wrong sorted insertion"); 00163 m_data[outer].append(0, inner); 00164 return m_data[outer].value(m_data[outer].size()-1); 00165 } 00166 00167 inline Scalar& insert(Index row, Index col) 00168 { 00169 const Index outer = IsRowMajor ? row : col; 00170 const Index inner = IsRowMajor ? col : row; 00171 00172 Index startId = 0; 00173 Index id = static_cast<Index>(m_data[outer].size()) - 1; 00174 m_data[outer].resize(id+2,1); 00175 00176 while ( (id >= startId) && (m_data[outer].index(id) > inner) ) 00177 { 00178 m_data[outer].index(id+1) = m_data[outer].index(id); 00179 m_data[outer].value(id+1) = m_data[outer].value(id); 00180 --id; 00181 } 00182 m_data[outer].index(id+1) = inner; 00183 m_data[outer].value(id+1) = 0; 00184 return m_data[outer].value(id+1); 00185 } 00186 00188 inline void finalize() {} 00189 00191 void prune(Scalar reference, RealScalar epsilon = NumTraits<RealScalar>::dummy_precision()) 00192 { 00193 for (Index j=0; j<outerSize(); ++j) 00194 m_data[j].prune(reference,epsilon); 00195 } 00196 00199 void resize(Index rows, Index cols) 00200 { 00201 const Index outerSize = IsRowMajor ? rows : cols; 00202 m_innerSize = convert_index(IsRowMajor ? cols : rows); 00203 setZero(); 00204 if (Index(m_data.size()) != outerSize) 00205 { 00206 m_data.resize(outerSize); 00207 } 00208 } 00209 00210 void resizeAndKeepData(Index rows, Index cols) 00211 { 00212 const Index outerSize = IsRowMajor ? rows : cols; 00213 const Index innerSize = IsRowMajor ? cols : rows; 00214 if (m_innerSize>innerSize) 00215 { 00216 // remove all coefficients with innerCoord>=innerSize 00217 // TODO 00218 //std::cerr << "not implemented yet\n"; 00219 exit(2); 00220 } 00221 if (m_data.size() != outerSize) 00222 { 00223 m_data.resize(outerSize); 00224 } 00225 } 00226 00228 EIGEN_DEPRECATED inline DynamicSparseMatrix() 00229 : m_innerSize(0), m_data(0) 00230 { 00231 eigen_assert(innerSize()==0 && outerSize()==0); 00232 } 00233 00235 EIGEN_DEPRECATED inline DynamicSparseMatrix(Index rows, Index cols) 00236 : m_innerSize(0) 00237 { 00238 resize(rows, cols); 00239 } 00240 00242 template<typename OtherDerived> 00243 EIGEN_DEPRECATED explicit inline DynamicSparseMatrix(const SparseMatrixBase<OtherDerived>& other) 00244 : m_innerSize(0) 00245 { 00246 Base::operator=(other.derived()); 00247 } 00248 00249 inline DynamicSparseMatrix(const DynamicSparseMatrix& other) 00250 : Base(), m_innerSize(0) 00251 { 00252 *this = other.derived(); 00253 } 00254 00255 inline void swap(DynamicSparseMatrix& other) 00256 { 00257 //EIGEN_DBG_SPARSE(std::cout << "SparseMatrix:: swap\n"); 00258 std::swap(m_innerSize, other.m_innerSize); 00259 //std::swap(m_outerSize, other.m_outerSize); 00260 m_data.swap(other.m_data); 00261 } 00262 00263 inline DynamicSparseMatrix& operator=(const DynamicSparseMatrix& other) 00264 { 00265 if (other.isRValue()) 00266 { 00267 swap(other.const_cast_derived()); 00268 } 00269 else 00270 { 00271 resize(other.rows(), other.cols()); 00272 m_data = other.m_data; 00273 } 00274 return *this; 00275 } 00276 00278 inline ~DynamicSparseMatrix() {} 00279 00280 public: 00281 00284 EIGEN_DEPRECATED void startFill(Index reserveSize = 1000) 00285 { 00286 setZero(); 00287 reserve(reserveSize); 00288 } 00289 00299 EIGEN_DEPRECATED Scalar& fill(Index row, Index col) 00300 { 00301 const Index outer = IsRowMajor ? row : col; 00302 const Index inner = IsRowMajor ? col : row; 00303 return insertBack(outer,inner); 00304 } 00305 00311 EIGEN_DEPRECATED Scalar& fillrand(Index row, Index col) 00312 { 00313 return insert(row,col); 00314 } 00315 00318 EIGEN_DEPRECATED void endFill() {} 00319 00320 # ifdef EIGEN_DYNAMICSPARSEMATRIX_PLUGIN 00321 # include EIGEN_DYNAMICSPARSEMATRIX_PLUGIN 00322 # endif 00323 }; 00324 00325 template<typename Scalar, int _Options, typename _StorageIndex> 00326 class DynamicSparseMatrix<Scalar,_Options,_StorageIndex>::InnerIterator : public SparseVector<Scalar,_Options,_StorageIndex>::InnerIterator 00327 { 00328 typedef typename SparseVector<Scalar,_Options,_StorageIndex>::InnerIterator Base; 00329 public: 00330 InnerIterator(const DynamicSparseMatrix& mat, Index outer) 00331 : Base(mat.m_data[outer]), m_outer(outer) 00332 {} 00333 00334 inline Index row() const { return IsRowMajor ? m_outer : Base::index(); } 00335 inline Index col() const { return IsRowMajor ? Base::index() : m_outer; } 00336 inline Index outer() const { return m_outer; } 00337 00338 protected: 00339 const Index m_outer; 00340 }; 00341 00342 template<typename Scalar, int _Options, typename _StorageIndex> 00343 class DynamicSparseMatrix<Scalar,_Options,_StorageIndex>::ReverseInnerIterator : public SparseVector<Scalar,_Options,_StorageIndex>::ReverseInnerIterator 00344 { 00345 typedef typename SparseVector<Scalar,_Options,_StorageIndex>::ReverseInnerIterator Base; 00346 public: 00347 ReverseInnerIterator(const DynamicSparseMatrix& mat, Index outer) 00348 : Base(mat.m_data[outer]), m_outer(outer) 00349 {} 00350 00351 inline Index row() const { return IsRowMajor ? m_outer : Base::index(); } 00352 inline Index col() const { return IsRowMajor ? Base::index() : m_outer; } 00353 inline Index outer() const { return m_outer; } 00354 00355 protected: 00356 const Index m_outer; 00357 }; 00358 00359 namespace internal { 00360 00361 template<typename _Scalar, int _Options, typename _StorageIndex> 00362 struct evaluator<DynamicSparseMatrix<_Scalar,_Options,_StorageIndex> > 00363 : evaluator_base<DynamicSparseMatrix<_Scalar,_Options,_StorageIndex> > 00364 { 00365 typedef _Scalar Scalar; 00366 typedef DynamicSparseMatrix<_Scalar,_Options,_StorageIndex> SparseMatrixType; 00367 typedef typename SparseMatrixType::InnerIterator InnerIterator; 00368 typedef typename SparseMatrixType::ReverseInnerIterator ReverseInnerIterator; 00369 00370 enum { 00371 CoeffReadCost = NumTraits<_Scalar>::ReadCost, 00372 Flags = SparseMatrixType::Flags 00373 }; 00374 00375 evaluator() : m_matrix(0) {} 00376 evaluator(const SparseMatrixType &mat) : m_matrix(&mat) {} 00377 00378 operator SparseMatrixType&() { return m_matrix->const_cast_derived(); } 00379 operator const SparseMatrixType&() const { return *m_matrix; } 00380 00381 Scalar coeff(Index row, Index col) const { return m_matrix->coeff(row,col); } 00382 00383 Index nonZerosEstimate() const { return m_matrix->nonZeros(); } 00384 00385 const SparseMatrixType *m_matrix; 00386 }; 00387 00388 } 00389 00390 } // end namespace Eigen 00391 00392 #endif // EIGEN_DYNAMIC_SPARSEMATRIX_H