10 #ifndef EIGEN_SPARSE_BLOCK_H
11 #define EIGEN_SPARSE_BLOCK_H
16 template<
typename MatrixType,
int Size>
17 struct traits<SparseInnerVectorSet<MatrixType, Size> >
19 typedef typename traits<MatrixType>::Scalar Scalar;
20 typedef typename traits<MatrixType>::Index Index;
21 typedef typename traits<MatrixType>::StorageKind StorageKind;
22 typedef MatrixXpr XprKind;
25 Flags = MatrixType::Flags,
26 RowsAtCompileTime = IsRowMajor ? Size : MatrixType::RowsAtCompileTime,
27 ColsAtCompileTime = IsRowMajor ? MatrixType::ColsAtCompileTime : Size,
28 MaxRowsAtCompileTime = RowsAtCompileTime,
29 MaxColsAtCompileTime = ColsAtCompileTime,
30 CoeffReadCost = MatrixType::CoeffReadCost
35 template<
typename MatrixType,
int Size>
36 class SparseInnerVectorSet : internal::no_assignment_operator,
37 public SparseMatrixBase<SparseInnerVectorSet<MatrixType, Size> >
41 enum { IsRowMajor = internal::traits<SparseInnerVectorSet>::IsRowMajor };
43 EIGEN_SPARSE_PUBLIC_INTERFACE(SparseInnerVectorSet)
44 class InnerIterator: public MatrixType::InnerIterator
47 inline InnerIterator(
const SparseInnerVectorSet& xpr, Index outer)
48 : MatrixType::InnerIterator(xpr.m_matrix, xpr.m_outerStart + outer), m_outer(outer)
50 inline Index row()
const {
return IsRowMajor ? m_outer : this->index(); }
51 inline Index col()
const {
return IsRowMajor ? this->index() : m_outer; }
55 class ReverseInnerIterator:
public MatrixType::ReverseInnerIterator
58 inline ReverseInnerIterator(
const SparseInnerVectorSet& xpr, Index outer)
59 : MatrixType::ReverseInnerIterator(xpr.m_matrix, xpr.m_outerStart + outer), m_outer(outer)
61 inline Index row()
const {
return IsRowMajor ? m_outer : this->index(); }
62 inline Index col()
const {
return IsRowMajor ? this->index() : m_outer; }
67 inline SparseInnerVectorSet(
const MatrixType& matrix, Index outerStart, Index outerSize)
68 : m_matrix(matrix), m_outerStart(outerStart), m_outerSize(outerSize)
70 eigen_assert( (outerStart>=0) && ((outerStart+outerSize)<=matrix.outerSize()) );
73 inline SparseInnerVectorSet(
const MatrixType& matrix, Index outer)
74 : m_matrix(matrix), m_outerStart(outer), m_outerSize(Size)
77 eigen_assert( (outer>=0) && (outer<matrix.outerSize()) );
92 EIGEN_STRONG_INLINE Index rows()
const {
return IsRowMajor ? m_outerSize.value() : m_matrix.rows(); }
93 EIGEN_STRONG_INLINE Index cols()
const {
return IsRowMajor ? m_matrix.cols() : m_outerSize.value(); }
97 const typename MatrixType::Nested m_matrix;
99 const internal::variable_if_dynamic<Index, Size> m_outerSize;
107 template<
typename _Scalar,
int _Options,
typename _Index,
int Size>
108 class SparseInnerVectorSet<SparseMatrix<_Scalar, _Options, _Index>, Size>
109 :
public SparseMatrixBase<SparseInnerVectorSet<SparseMatrix<_Scalar, _Options, _Index>, Size> >
111 typedef SparseMatrix<_Scalar, _Options, _Index> MatrixType;
114 enum { IsRowMajor = internal::traits<SparseInnerVectorSet>::IsRowMajor };
116 EIGEN_SPARSE_PUBLIC_INTERFACE(SparseInnerVectorSet)
117 class InnerIterator: public MatrixType::InnerIterator
120 inline InnerIterator(
const SparseInnerVectorSet& xpr, Index outer)
121 : MatrixType::InnerIterator(xpr.m_matrix, xpr.m_outerStart + outer), m_outer(outer)
123 inline Index row()
const {
return IsRowMajor ? m_outer : this->index(); }
124 inline Index col()
const {
return IsRowMajor ? this->index() : m_outer; }
128 class ReverseInnerIterator:
public MatrixType::ReverseInnerIterator
131 inline ReverseInnerIterator(
const SparseInnerVectorSet& xpr, Index outer)
132 : MatrixType::ReverseInnerIterator(xpr.m_matrix, xpr.m_outerStart + outer), m_outer(outer)
134 inline Index row()
const {
return IsRowMajor ? m_outer : this->index(); }
135 inline Index col()
const {
return IsRowMajor ? this->index() : m_outer; }
140 inline SparseInnerVectorSet(
const MatrixType& matrix, Index outerStart, Index outerSize)
141 : m_matrix(matrix), m_outerStart(outerStart), m_outerSize(outerSize)
143 eigen_assert( (outerStart>=0) && ((outerStart+outerSize)<=matrix.outerSize()) );
146 inline SparseInnerVectorSet(
const MatrixType& matrix, Index outer)
147 : m_matrix(matrix), m_outerStart(outer), m_outerSize(Size)
149 eigen_assert(Size==1);
150 eigen_assert( (outer>=0) && (outer<matrix.outerSize()) );
153 template<
typename OtherDerived>
154 inline SparseInnerVectorSet& operator=(
const SparseMatrixBase<OtherDerived>& other)
156 typedef typename internal::remove_all<typename MatrixType::Nested>::type _NestedMatrixType;
157 _NestedMatrixType& matrix =
const_cast<_NestedMatrixType&
>(m_matrix);;
162 SparseMatrix<Scalar, IsRowMajor ? RowMajor : ColMajor, Index> tmp(other);
165 Index nnz = tmp.nonZeros();
166 Index nnz_previous = nonZeros();
167 Index free_size = Index(matrix.data().allocatedSize()) + nnz_previous;
168 Index nnz_head = m_outerStart==0 ? 0 : matrix.outerIndexPtr()[m_outerStart];
169 Index tail = m_matrix.outerIndexPtr()[m_outerStart+m_outerSize.value()];
170 Index nnz_tail = matrix.nonZeros() - tail;
175 typename MatrixType::Storage newdata(m_matrix.nonZeros() - nnz_previous + nnz);
177 std::memcpy(&newdata.value(0), &m_matrix.data().value(0), nnz_head*
sizeof(Scalar));
178 std::memcpy(&newdata.index(0), &m_matrix.data().index(0), nnz_head*
sizeof(Index));
180 std::memcpy(&newdata.value(nnz_head), &tmp.data().value(0), nnz*
sizeof(Scalar));
181 std::memcpy(&newdata.index(nnz_head), &tmp.data().index(0), nnz*
sizeof(Index));
183 std::memcpy(&newdata.value(nnz_head+nnz), &matrix.data().value(tail), nnz_tail*
sizeof(Scalar));
184 std::memcpy(&newdata.index(nnz_head+nnz), &matrix.data().index(tail), nnz_tail*
sizeof(Index));
186 matrix.data().swap(newdata);
191 matrix.data().resize(nnz_head + nnz + nnz_tail);
195 std::memcpy(&matrix.data().value(nnz_head+nnz), &matrix.data().value(tail), nnz_tail*
sizeof(Scalar));
196 std::memcpy(&matrix.data().index(nnz_head+nnz), &matrix.data().index(tail), nnz_tail*
sizeof(Index));
200 for(Index i=nnz_tail-1; i>=0; --i)
202 matrix.data().value(nnz_head+nnz+i) = matrix.data().value(tail+i);
203 matrix.data().index(nnz_head+nnz+i) = matrix.data().index(tail+i);
207 std::memcpy(&matrix.data().value(nnz_head), &tmp.data().value(0), nnz*
sizeof(Scalar));
208 std::memcpy(&matrix.data().index(nnz_head), &tmp.data().index(0), nnz*
sizeof(Index));
213 for(Index k=0; k<m_outerSize.value(); ++k)
215 matrix.outerIndexPtr()[m_outerStart+k] = p;
216 p += tmp.innerVector(k).nonZeros();
218 std::ptrdiff_t offset = nnz - nnz_previous;
219 for(Index k = m_outerStart + m_outerSize.value(); k<=matrix.outerSize(); ++k)
221 matrix.outerIndexPtr()[k] += offset;
227 inline SparseInnerVectorSet& operator=(
const SparseInnerVectorSet& other)
229 return operator=<SparseInnerVectorSet>(other);
232 inline const Scalar* valuePtr()
const
233 {
return m_matrix.valuePtr() + m_matrix.outerIndexPtr()[m_outerStart]; }
234 inline Scalar* valuePtr()
235 {
return m_matrix.const_cast_derived().valuePtr() + m_matrix.outerIndexPtr()[m_outerStart]; }
237 inline const Index* innerIndexPtr()
const
238 {
return m_matrix.innerIndexPtr() + m_matrix.outerIndexPtr()[m_outerStart]; }
239 inline Index* innerIndexPtr()
240 {
return m_matrix.const_cast_derived().innerIndexPtr() + m_matrix.outerIndexPtr()[m_outerStart]; }
242 inline const Index* outerIndexPtr()
const
243 {
return m_matrix.outerIndexPtr() + m_outerStart; }
244 inline Index* outerIndexPtr()
245 {
return m_matrix.const_cast_derived().outerIndexPtr() + m_outerStart; }
247 Index nonZeros()
const
249 if(m_matrix.isCompressed())
250 return std::size_t(m_matrix.outerIndexPtr()[m_outerStart+m_outerSize.value()])
251 - std::size_t(m_matrix.outerIndexPtr()[m_outerStart]);
252 else if(m_outerSize.value()==0)
255 return Map<const Matrix<Index,Size,1> >(m_matrix.innerNonZeroPtr()+m_outerStart, m_outerSize.value()).sum();
258 const Scalar& lastCoeff()
const
260 EIGEN_STATIC_ASSERT_VECTOR_ONLY(SparseInnerVectorSet);
261 eigen_assert(nonZeros()>0);
262 if(m_matrix.isCompressed())
263 return m_matrix.valuePtr()[m_matrix.outerIndexPtr()[m_outerStart+1]-1];
265 return m_matrix.valuePtr()[m_matrix.outerIndexPtr()[m_outerStart]+m_matrix.innerNonZeroPtr()[m_outerStart]-1];
274 EIGEN_STRONG_INLINE Index rows()
const {
return IsRowMajor ? m_outerSize.value() : m_matrix.rows(); }
275 EIGEN_STRONG_INLINE Index cols()
const {
return IsRowMajor ? m_matrix.cols() : m_outerSize.value(); }
279 typename MatrixType::Nested m_matrix;
281 const internal::variable_if_dynamic<Index, Size> m_outerSize;
288 template<
typename Derived>
291 EIGEN_STATIC_ASSERT(IsRowMajor,THIS_METHOD_IS_ONLY_FOR_ROW_MAJOR_MATRICES);
292 return innerVector(i);
297 template<
typename Derived>
300 EIGEN_STATIC_ASSERT(IsRowMajor,THIS_METHOD_IS_ONLY_FOR_ROW_MAJOR_MATRICES);
301 return innerVector(i);
305 template<
typename Derived>
308 EIGEN_STATIC_ASSERT(!IsRowMajor,THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES);
309 return innerVector(i);
314 template<
typename Derived>
317 EIGEN_STATIC_ASSERT(!IsRowMajor,THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES);
318 return innerVector(i);
324 template<
typename Derived>
326 {
return SparseInnerVectorSet<Derived,1>(derived(), outer); }
331 template<
typename Derived>
333 {
return SparseInnerVectorSet<Derived,1>(derived(), outer); }
336 template<
typename Derived>
339 EIGEN_STATIC_ASSERT(IsRowMajor,THIS_METHOD_IS_ONLY_FOR_ROW_MAJOR_MATRICES);
340 return innerVectors(start, size);
345 template<
typename Derived>
348 EIGEN_STATIC_ASSERT(IsRowMajor,THIS_METHOD_IS_ONLY_FOR_ROW_MAJOR_MATRICES);
349 return innerVectors(start, size);
353 template<
typename Derived>
356 EIGEN_STATIC_ASSERT(!IsRowMajor,THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES);
357 return innerVectors(start, size);
362 template<
typename Derived>
365 EIGEN_STATIC_ASSERT(!IsRowMajor,THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES);
366 return innerVectors(start, size);
374 template<
typename Derived>
376 {
return SparseInnerVectorSet<Derived,Dynamic>(derived(), outerStart, outerSize); }
381 template<
typename Derived>
383 {
return SparseInnerVectorSet<Derived,Dynamic>(derived(), outerStart, outerSize); }
387 #endif // EIGEN_SPARSE_BLOCK_H