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_SPARSE_BLOCK_H
00026 #define EIGEN_SPARSE_BLOCK_H
00027
00028 namespace internal {
00029 template<typename MatrixType, int Size>
00030 struct traits<SparseInnerVectorSet<MatrixType, Size> >
00031 {
00032 typedef typename traits<MatrixType>::Scalar Scalar;
00033 typedef typename traits<MatrixType>::Index Index;
00034 typedef typename traits<MatrixType>::StorageKind StorageKind;
00035 typedef MatrixXpr XprKind;
00036 enum {
00037 IsRowMajor = (int(MatrixType::Flags)&RowMajorBit)==RowMajorBit,
00038 Flags = MatrixType::Flags,
00039 RowsAtCompileTime = IsRowMajor ? Size : MatrixType::RowsAtCompileTime,
00040 ColsAtCompileTime = IsRowMajor ? MatrixType::ColsAtCompileTime : Size,
00041 MaxRowsAtCompileTime = RowsAtCompileTime,
00042 MaxColsAtCompileTime = ColsAtCompileTime,
00043 CoeffReadCost = MatrixType::CoeffReadCost
00044 };
00045 };
00046 }
00047
00048 template<typename MatrixType, int Size>
00049 class SparseInnerVectorSet : internal::no_assignment_operator,
00050 public SparseMatrixBase<SparseInnerVectorSet<MatrixType, Size> >
00051 {
00052 public:
00053
00054 enum { IsRowMajor = internal::traits<SparseInnerVectorSet>::IsRowMajor };
00055
00056 EIGEN_SPARSE_PUBLIC_INTERFACE(SparseInnerVectorSet)
00057 class InnerIterator: public MatrixType::InnerIterator
00058 {
00059 public:
00060 inline InnerIterator(const SparseInnerVectorSet& xpr, Index outer)
00061 : MatrixType::InnerIterator(xpr.m_matrix, xpr.m_outerStart + outer), m_outer(outer)
00062 {}
00063 inline Index row() const { return IsRowMajor ? m_outer : this->index(); }
00064 inline Index col() const { return IsRowMajor ? this->index() : m_outer; }
00065 protected:
00066 Index m_outer;
00067 };
00068
00069 inline SparseInnerVectorSet(const MatrixType& matrix, Index outerStart, Index outerSize)
00070 : m_matrix(matrix), m_outerStart(outerStart), m_outerSize(outerSize)
00071 {
00072 eigen_assert( (outerStart>=0) && ((outerStart+outerSize)<=matrix.outerSize()) );
00073 }
00074
00075 inline SparseInnerVectorSet(const MatrixType& matrix, Index outer)
00076 : m_matrix(matrix), m_outerStart(outer), m_outerSize(Size)
00077 {
00078 eigen_assert(Size!=Dynamic);
00079 eigen_assert( (outer>=0) && (outer<matrix.outerSize()) );
00080 }
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094 EIGEN_STRONG_INLINE Index rows() const { return IsRowMajor ? m_outerSize.value() : m_matrix.rows(); }
00095 EIGEN_STRONG_INLINE Index cols() const { return IsRowMajor ? m_matrix.cols() : m_outerSize.value(); }
00096
00097 protected:
00098
00099 const typename MatrixType::Nested m_matrix;
00100 Index m_outerStart;
00101 const internal::variable_if_dynamic<Index, Size> m_outerSize;
00102 };
00103
00104
00105
00106
00107
00108 template<typename _Scalar, int _Options, int Size>
00109 class SparseInnerVectorSet<DynamicSparseMatrix<_Scalar, _Options>, Size>
00110 : public SparseMatrixBase<SparseInnerVectorSet<DynamicSparseMatrix<_Scalar, _Options>, Size> >
00111 {
00112 typedef DynamicSparseMatrix<_Scalar, _Options> MatrixType;
00113 public:
00114
00115 enum { IsRowMajor = internal::traits<SparseInnerVectorSet>::IsRowMajor };
00116
00117 EIGEN_SPARSE_PUBLIC_INTERFACE(SparseInnerVectorSet)
00118 class InnerIterator: public MatrixType::InnerIterator
00119 {
00120 public:
00121 inline InnerIterator(const SparseInnerVectorSet& xpr, Index outer)
00122 : MatrixType::InnerIterator(xpr.m_matrix, xpr.m_outerStart + outer), m_outer(outer)
00123 {}
00124 inline Index row() const { return IsRowMajor ? m_outer : this->index(); }
00125 inline Index col() const { return IsRowMajor ? this->index() : m_outer; }
00126 protected:
00127 Index m_outer;
00128 };
00129
00130 inline SparseInnerVectorSet(const MatrixType& matrix, Index outerStart, Index outerSize)
00131 : m_matrix(matrix), m_outerStart(outerStart), m_outerSize(outerSize)
00132 {
00133 eigen_assert( (outerStart>=0) && ((outerStart+outerSize)<=matrix.outerSize()) );
00134 }
00135
00136 inline SparseInnerVectorSet(const MatrixType& matrix, Index outer)
00137 : m_matrix(matrix), m_outerStart(outer), m_outerSize(Size)
00138 {
00139 eigen_assert(Size!=Dynamic);
00140 eigen_assert( (outer>=0) && (outer<matrix.outerSize()) );
00141 }
00142
00143 template<typename OtherDerived>
00144 inline SparseInnerVectorSet& operator=(const SparseMatrixBase<OtherDerived>& other)
00145 {
00146 if (IsRowMajor != ((OtherDerived::Flags&RowMajorBit)==RowMajorBit))
00147 {
00148
00149 DynamicSparseMatrix<Scalar,IsRowMajor?RowMajorBit:0> aux(other);
00150 *this = aux.markAsRValue();
00151 }
00152 else
00153 {
00154
00155 for (Index j=0; j<m_outerSize.value(); ++j)
00156 {
00157 SparseVector<Scalar,IsRowMajor ? RowMajorBit : 0> aux(other.innerVector(j));
00158 m_matrix.const_cast_derived()._data()[m_outerStart+j].swap(aux._data());
00159 }
00160 }
00161 return *this;
00162 }
00163
00164 inline SparseInnerVectorSet& operator=(const SparseInnerVectorSet& other)
00165 {
00166 return operator=<SparseInnerVectorSet>(other);
00167 }
00168
00169 Index nonZeros() const
00170 {
00171 Index count = 0;
00172 for (Index j=0; j<m_outerSize.value(); ++j)
00173 count += m_matrix._data()[m_outerStart+j].size();
00174 return count;
00175 }
00176
00177 const Scalar& lastCoeff() const
00178 {
00179 EIGEN_STATIC_ASSERT_VECTOR_ONLY(SparseInnerVectorSet);
00180 eigen_assert(m_matrix.data()[m_outerStart].size()>0);
00181 return m_matrix.data()[m_outerStart].vale(m_matrix.data()[m_outerStart].size()-1);
00182 }
00183
00184
00185
00186
00187
00188
00189
00190 EIGEN_STRONG_INLINE Index rows() const { return IsRowMajor ? m_outerSize.value() : m_matrix.rows(); }
00191 EIGEN_STRONG_INLINE Index cols() const { return IsRowMajor ? m_matrix.cols() : m_outerSize.value(); }
00192
00193 protected:
00194
00195 const typename MatrixType::Nested m_matrix;
00196 Index m_outerStart;
00197 const internal::variable_if_dynamic<Index, Size> m_outerSize;
00198
00199 };
00200
00201
00202
00203
00204
00205
00206 template<typename _Scalar, int _Options, typename _Index, int Size>
00207 class SparseInnerVectorSet<SparseMatrix<_Scalar, _Options, _Index>, Size>
00208 : public SparseMatrixBase<SparseInnerVectorSet<SparseMatrix<_Scalar, _Options>, Size> >
00209 {
00210 typedef SparseMatrix<_Scalar, _Options> MatrixType;
00211 public:
00212
00213 enum { IsRowMajor = internal::traits<SparseInnerVectorSet>::IsRowMajor };
00214
00215 EIGEN_SPARSE_PUBLIC_INTERFACE(SparseInnerVectorSet)
00216 class InnerIterator: public MatrixType::InnerIterator
00217 {
00218 public:
00219 inline InnerIterator(const SparseInnerVectorSet& xpr, Index outer)
00220 : MatrixType::InnerIterator(xpr.m_matrix, xpr.m_outerStart + outer), m_outer(outer)
00221 {}
00222 inline Index row() const { return IsRowMajor ? m_outer : this->index(); }
00223 inline Index col() const { return IsRowMajor ? this->index() : m_outer; }
00224 protected:
00225 Index m_outer;
00226 };
00227
00228 inline SparseInnerVectorSet(const MatrixType& matrix, Index outerStart, Index outerSize)
00229 : m_matrix(matrix), m_outerStart(outerStart), m_outerSize(outerSize)
00230 {
00231 eigen_assert( (outerStart>=0) && ((outerStart+outerSize)<=matrix.outerSize()) );
00232 }
00233
00234 inline SparseInnerVectorSet(const MatrixType& matrix, Index outer)
00235 : m_matrix(matrix), m_outerStart(outer), m_outerSize(Size)
00236 {
00237 eigen_assert(Size==1);
00238 eigen_assert( (outer>=0) && (outer<matrix.outerSize()) );
00239 }
00240
00241 template<typename OtherDerived>
00242 inline SparseInnerVectorSet& operator=(const SparseMatrixBase<OtherDerived>& other)
00243 {
00244 typedef typename internal::remove_all<typename MatrixType::Nested>::type _NestedMatrixType;
00245 _NestedMatrixType& matrix = const_cast<_NestedMatrixType&>(m_matrix);;
00246
00247
00248
00249
00250 SparseMatrix<Scalar, IsRowMajor ? RowMajor : ColMajor, Index> tmp(other);
00251
00252
00253 Index nnz = tmp.nonZeros();
00254 Index nnz_previous = nonZeros();
00255 Index free_size = matrix.data().allocatedSize() - nnz_previous;
00256 std::size_t nnz_head = m_outerStart==0 ? 0 : matrix._outerIndexPtr()[m_outerStart];
00257 std::size_t tail = m_matrix._outerIndexPtr()[m_outerStart+m_outerSize.value()];
00258 std::size_t nnz_tail = matrix.nonZeros() - tail;
00259
00260 if(nnz>free_size)
00261 {
00262
00263 typename MatrixType::Storage newdata(m_matrix.nonZeros() - nnz_previous + nnz);
00264
00265 std::memcpy(&newdata.value(0), &m_matrix.data().value(0), nnz_head*sizeof(Scalar));
00266 std::memcpy(&newdata.index(0), &m_matrix.data().index(0), nnz_head*sizeof(Index));
00267
00268 std::memcpy(&newdata.value(nnz_head), &tmp.data().value(0), nnz*sizeof(Scalar));
00269 std::memcpy(&newdata.index(nnz_head), &tmp.data().index(0), nnz*sizeof(Index));
00270
00271 std::memcpy(&newdata.value(nnz_head+nnz), &matrix.data().value(tail), nnz_tail*sizeof(Scalar));
00272 std::memcpy(&newdata.index(nnz_head+nnz), &matrix.data().index(tail), nnz_tail*sizeof(Index));
00273
00274 matrix.data().swap(newdata);
00275 }
00276 else
00277 {
00278
00279 matrix.data().resize(nnz_head + nnz + nnz_tail);
00280
00281 if(nnz<nnz_previous)
00282 {
00283 std::memcpy(&matrix.data().value(nnz_head+nnz), &matrix.data().value(tail), nnz_tail*sizeof(Scalar));
00284 std::memcpy(&matrix.data().index(nnz_head+nnz), &matrix.data().index(tail), nnz_tail*sizeof(Index));
00285 }
00286 else
00287 {
00288 for(Index i=nnz_tail-1; i>=0; --i)
00289 {
00290 matrix.data().value(nnz_head+nnz+i) = matrix.data().value(tail+i);
00291 matrix.data().index(nnz_head+nnz+i) = matrix.data().index(tail+i);
00292 }
00293 }
00294
00295 std::memcpy(&matrix.data().value(nnz_head), &tmp.data().value(0), nnz*sizeof(Scalar));
00296 std::memcpy(&matrix.data().index(nnz_head), &tmp.data().index(0), nnz*sizeof(Index));
00297 }
00298
00299
00300 Index p = nnz_head;
00301 for(Index k=1; k<m_outerSize.value(); ++k)
00302 {
00303 matrix._outerIndexPtr()[m_outerStart+k] = p;
00304 p += tmp.innerVector(k).nonZeros();
00305 }
00306 std::ptrdiff_t offset = nnz - nnz_previous;
00307 for(Index k = m_outerStart + m_outerSize.value(); k<=matrix.outerSize(); ++k)
00308 {
00309 matrix._outerIndexPtr()[k] += offset;
00310 }
00311
00312 return *this;
00313 }
00314
00315 inline SparseInnerVectorSet& operator=(const SparseInnerVectorSet& other)
00316 {
00317 return operator=<SparseInnerVectorSet>(other);
00318 }
00319
00320 inline const Scalar* _valuePtr() const
00321 { return m_matrix._valuePtr() + m_matrix._outerIndexPtr()[m_outerStart]; }
00322 inline Scalar* _valuePtr()
00323 { return m_matrix.const_cast_derived()._valuePtr() + m_matrix._outerIndexPtr()[m_outerStart]; }
00324
00325 inline const Index* _innerIndexPtr() const
00326 { return m_matrix._innerIndexPtr() + m_matrix._outerIndexPtr()[m_outerStart]; }
00327 inline Index* _innerIndexPtr()
00328 { return m_matrix.const_cast_derived()._innerIndexPtr() + m_matrix._outerIndexPtr()[m_outerStart]; }
00329
00330 inline const Index* _outerIndexPtr() const
00331 { return m_matrix._outerIndexPtr() + m_outerStart; }
00332 inline Index* _outerIndexPtr()
00333 { return m_matrix.const_cast_derived()._outerIndexPtr() + m_outerStart; }
00334
00335 Index nonZeros() const
00336 {
00337 return std::size_t(m_matrix._outerIndexPtr()[m_outerStart+m_outerSize.value()])
00338 - std::size_t(m_matrix._outerIndexPtr()[m_outerStart]);
00339 }
00340
00341 const Scalar& lastCoeff() const
00342 {
00343 EIGEN_STATIC_ASSERT_VECTOR_ONLY(SparseInnerVectorSet);
00344 eigen_assert(nonZeros()>0);
00345 return m_matrix._valuePtr()[m_matrix._outerIndexPtr()[m_outerStart+1]-1];
00346 }
00347
00348
00349
00350
00351
00352
00353
00354 EIGEN_STRONG_INLINE Index rows() const { return IsRowMajor ? m_outerSize.value() : m_matrix.rows(); }
00355 EIGEN_STRONG_INLINE Index cols() const { return IsRowMajor ? m_matrix.cols() : m_outerSize.value(); }
00356
00357 protected:
00358
00359 const typename MatrixType::Nested m_matrix;
00360 Index m_outerStart;
00361 const internal::variable_if_dynamic<Index, Size> m_outerSize;
00362
00363 };
00364
00365
00366
00368 template<typename Derived>
00369 SparseInnerVectorSet<Derived,1> SparseMatrixBase<Derived>::row(Index i)
00370 {
00371 EIGEN_STATIC_ASSERT(IsRowMajor,THIS_METHOD_IS_ONLY_FOR_ROW_MAJOR_MATRICES);
00372 return innerVector(i);
00373 }
00374
00377 template<typename Derived>
00378 const SparseInnerVectorSet<Derived,1> SparseMatrixBase<Derived>::row(Index i) const
00379 {
00380 EIGEN_STATIC_ASSERT(IsRowMajor,THIS_METHOD_IS_ONLY_FOR_ROW_MAJOR_MATRICES);
00381 return innerVector(i);
00382 }
00383
00385 template<typename Derived>
00386 SparseInnerVectorSet<Derived,1> SparseMatrixBase<Derived>::col(Index i)
00387 {
00388 EIGEN_STATIC_ASSERT(!IsRowMajor,THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES);
00389 return innerVector(i);
00390 }
00391
00394 template<typename Derived>
00395 const SparseInnerVectorSet<Derived,1> SparseMatrixBase<Derived>::col(Index i) const
00396 {
00397 EIGEN_STATIC_ASSERT(!IsRowMajor,THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES);
00398 return innerVector(i);
00399 }
00400
00404 template<typename Derived>
00405 SparseInnerVectorSet<Derived,1> SparseMatrixBase<Derived>::innerVector(Index outer)
00406 { return SparseInnerVectorSet<Derived,1>(derived(), outer); }
00407
00411 template<typename Derived>
00412 const SparseInnerVectorSet<Derived,1> SparseMatrixBase<Derived>::innerVector(Index outer) const
00413 { return SparseInnerVectorSet<Derived,1>(derived(), outer); }
00414
00415
00416
00418 template<typename Derived>
00419 SparseInnerVectorSet<Derived,Dynamic> SparseMatrixBase<Derived>::subrows(Index start, Index size)
00420 {
00421 EIGEN_STATIC_ASSERT(IsRowMajor,THIS_METHOD_IS_ONLY_FOR_ROW_MAJOR_MATRICES);
00422 return innerVectors(start, size);
00423 }
00424
00427 template<typename Derived>
00428 const SparseInnerVectorSet<Derived,Dynamic> SparseMatrixBase<Derived>::subrows(Index start, Index size) const
00429 {
00430 EIGEN_STATIC_ASSERT(IsRowMajor,THIS_METHOD_IS_ONLY_FOR_ROW_MAJOR_MATRICES);
00431 return innerVectors(start, size);
00432 }
00433
00435 template<typename Derived>
00436 SparseInnerVectorSet<Derived,Dynamic> SparseMatrixBase<Derived>::subcols(Index start, Index size)
00437 {
00438 EIGEN_STATIC_ASSERT(!IsRowMajor,THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES);
00439 return innerVectors(start, size);
00440 }
00441
00444 template<typename Derived>
00445 const SparseInnerVectorSet<Derived,Dynamic> SparseMatrixBase<Derived>::subcols(Index start, Index size) const
00446 {
00447 EIGEN_STATIC_ASSERT(!IsRowMajor,THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES);
00448 return innerVectors(start, size);
00449 }
00450
00454 template<typename Derived>
00455 SparseInnerVectorSet<Derived,Dynamic> SparseMatrixBase<Derived>::innerVectors(Index outerStart, Index outerSize)
00456 { return SparseInnerVectorSet<Derived,Dynamic>(derived(), outerStart, outerSize); }
00457
00461 template<typename Derived>
00462 const SparseInnerVectorSet<Derived,Dynamic> SparseMatrixBase<Derived>::innerVectors(Index outerStart, Index outerSize) const
00463 { return SparseInnerVectorSet<Derived,Dynamic>(derived(), outerStart, outerSize); }
00464
00465 #endif // EIGEN_SPARSE_BLOCK_H