source: mmcs/Eigen/src/SparseCore/SparseBlock.h @ 68e57de

Last change on this file since 68e57de was 68e57de, checked in by rboet <rudmanmrrod@…>, 9 years ago

solucionado una dependencia de recurso para la imagen de cargar matriz

  • Property mode set to 100755
File size: 22.3 KB
Line 
1// This file is part of Eigen, a lightweight C++ template library
2// for linear algebra.
3//
4// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr>
5//
6// This Source Code Form is subject to the terms of the Mozilla
7// Public License v. 2.0. If a copy of the MPL was not distributed
8// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9
10#ifndef EIGEN_SPARSE_BLOCK_H
11#define EIGEN_SPARSE_BLOCK_H
12
13namespace Eigen { 
14
15template<typename XprType, int BlockRows, int BlockCols>
16class BlockImpl<XprType,BlockRows,BlockCols,true,Sparse>
17  : public SparseMatrixBase<Block<XprType,BlockRows,BlockCols,true> >
18{
19    typedef typename internal::remove_all<typename XprType::Nested>::type _MatrixTypeNested;
20    typedef Block<XprType, BlockRows, BlockCols, true> BlockType;
21public:
22    enum { IsRowMajor = internal::traits<BlockType>::IsRowMajor };
23protected:
24    enum { OuterSize = IsRowMajor ? BlockRows : BlockCols };
25public:
26    EIGEN_SPARSE_PUBLIC_INTERFACE(BlockType)
27   
28    class InnerIterator: public XprType::InnerIterator
29    {
30        typedef typename BlockImpl::Index Index;
31      public:
32        inline InnerIterator(const BlockType& xpr, Index outer)
33          : XprType::InnerIterator(xpr.m_matrix, xpr.m_outerStart + outer), m_outer(outer)
34        {}
35        inline Index row() const { return IsRowMajor ? m_outer : this->index(); }
36        inline Index col() const { return IsRowMajor ? this->index() : m_outer; }
37      protected:
38        Index m_outer;
39    };
40    class ReverseInnerIterator: public XprType::ReverseInnerIterator
41    {
42        typedef typename BlockImpl::Index Index;
43      public:
44        inline ReverseInnerIterator(const BlockType& xpr, Index outer)
45          : XprType::ReverseInnerIterator(xpr.m_matrix, xpr.m_outerStart + outer), m_outer(outer)
46        {}
47        inline Index row() const { return IsRowMajor ? m_outer : this->index(); }
48        inline Index col() const { return IsRowMajor ? this->index() : m_outer; }
49      protected:
50        Index m_outer;
51    };
52
53    inline BlockImpl(const XprType& xpr, int i)
54      : m_matrix(xpr), m_outerStart(i), m_outerSize(OuterSize)
55    {}
56
57    inline BlockImpl(const XprType& xpr, int startRow, int startCol, int blockRows, int blockCols)
58      : m_matrix(xpr), m_outerStart(IsRowMajor ? startRow : startCol), m_outerSize(IsRowMajor ? blockRows : blockCols)
59    {}
60   
61    inline const Scalar coeff(int row, int col) const
62    {
63      return m_matrix.coeff(row + IsRowMajor ? m_outerStart : 0, col +IsRowMajor ? 0 :  m_outerStart);
64    }
65   
66    inline const Scalar coeff(int index) const
67    {
68      return m_matrix.coeff(IsRowMajor ? m_outerStart : index, IsRowMajor ? index :  m_outerStart);
69    }
70
71    EIGEN_STRONG_INLINE Index rows() const { return IsRowMajor ? m_outerSize.value() : m_matrix.rows(); }
72    EIGEN_STRONG_INLINE Index cols() const { return IsRowMajor ? m_matrix.cols() : m_outerSize.value(); }
73
74  protected:
75
76    typename XprType::Nested m_matrix;
77    Index m_outerStart;
78    const internal::variable_if_dynamic<Index, OuterSize> m_outerSize;
79
80    EIGEN_INHERIT_ASSIGNMENT_OPERATORS(BlockImpl)
81  private:
82    Index nonZeros() const;
83};
84
85
86/***************************************************************************
87* specialisation for SparseMatrix
88***************************************************************************/
89
90template<typename _Scalar, int _Options, typename _Index, int BlockRows, int BlockCols>
91class BlockImpl<SparseMatrix<_Scalar, _Options, _Index>,BlockRows,BlockCols,true,Sparse>
92  : public SparseMatrixBase<Block<SparseMatrix<_Scalar, _Options, _Index>,BlockRows,BlockCols,true> >
93{
94    typedef SparseMatrix<_Scalar, _Options, _Index> SparseMatrixType;
95    typedef typename internal::remove_all<typename SparseMatrixType::Nested>::type _MatrixTypeNested;
96    typedef Block<SparseMatrixType, BlockRows, BlockCols, true> BlockType;
97    typedef Block<const SparseMatrixType, BlockRows, BlockCols, true> ConstBlockType;
98public:
99    enum { IsRowMajor = internal::traits<BlockType>::IsRowMajor };
100    EIGEN_SPARSE_PUBLIC_INTERFACE(BlockType)
101protected:
102    enum { OuterSize = IsRowMajor ? BlockRows : BlockCols };
103public:
104   
105    class InnerIterator: public SparseMatrixType::InnerIterator
106    {
107      public:
108        inline InnerIterator(const BlockType& xpr, Index outer)
109          : SparseMatrixType::InnerIterator(xpr.m_matrix, xpr.m_outerStart + outer), m_outer(outer)
110        {}
111        inline Index row() const { return IsRowMajor ? m_outer : this->index(); }
112        inline Index col() const { return IsRowMajor ? this->index() : m_outer; }
113      protected:
114        Index m_outer;
115    };
116    class ReverseInnerIterator: public SparseMatrixType::ReverseInnerIterator
117    {
118      public:
119        inline ReverseInnerIterator(const BlockType& xpr, Index outer)
120          : SparseMatrixType::ReverseInnerIterator(xpr.m_matrix, xpr.m_outerStart + outer), m_outer(outer)
121        {}
122        inline Index row() const { return IsRowMajor ? m_outer : this->index(); }
123        inline Index col() const { return IsRowMajor ? this->index() : m_outer; }
124      protected:
125        Index m_outer;
126    };
127
128    inline BlockImpl(const SparseMatrixType& xpr, int i)
129      : m_matrix(xpr), m_outerStart(i), m_outerSize(OuterSize)
130    {}
131
132    inline BlockImpl(const SparseMatrixType& xpr, int startRow, int startCol, int blockRows, int blockCols)
133      : m_matrix(xpr), m_outerStart(IsRowMajor ? startRow : startCol), m_outerSize(IsRowMajor ? blockRows : blockCols)
134    {}
135
136    template<typename OtherDerived>
137    inline BlockType& operator=(const SparseMatrixBase<OtherDerived>& other)
138    {
139      typedef typename internal::remove_all<typename SparseMatrixType::Nested>::type _NestedMatrixType;
140      _NestedMatrixType& matrix = const_cast<_NestedMatrixType&>(m_matrix);;
141      // This assignement is slow if this vector set is not empty
142      // and/or it is not at the end of the nonzeros of the underlying matrix.
143
144      // 1 - eval to a temporary to avoid transposition and/or aliasing issues
145      SparseMatrix<Scalar, IsRowMajor ? RowMajor : ColMajor, Index> tmp(other);
146
147      // 2 - let's check whether there is enough allocated memory
148      Index nnz           = tmp.nonZeros();
149      Index start         = m_outerStart==0 ? 0 : matrix.outerIndexPtr()[m_outerStart]; // starting position of the current block
150      Index end           = m_matrix.outerIndexPtr()[m_outerStart+m_outerSize.value()]; // ending posiiton of the current block
151      Index block_size    = end - start;                                                // available room in the current block
152      Index tail_size     = m_matrix.outerIndexPtr()[m_matrix.outerSize()] - end;
153     
154      Index free_size     = m_matrix.isCompressed()
155                          ? Index(matrix.data().allocatedSize()) + block_size
156                          : block_size;
157
158      if(nnz>free_size) 
159      {
160        // realloc manually to reduce copies
161        typename SparseMatrixType::Storage newdata(m_matrix.data().allocatedSize() - block_size + nnz);
162
163        std::memcpy(&newdata.value(0), &m_matrix.data().value(0), start*sizeof(Scalar));
164        std::memcpy(&newdata.index(0), &m_matrix.data().index(0), start*sizeof(Index));
165
166        std::memcpy(&newdata.value(start), &tmp.data().value(0), nnz*sizeof(Scalar));
167        std::memcpy(&newdata.index(start), &tmp.data().index(0), nnz*sizeof(Index));
168
169        std::memcpy(&newdata.value(start+nnz), &matrix.data().value(end), tail_size*sizeof(Scalar));
170        std::memcpy(&newdata.index(start+nnz), &matrix.data().index(end), tail_size*sizeof(Index));
171       
172        newdata.resize(m_matrix.outerIndexPtr()[m_matrix.outerSize()] - block_size + nnz);
173
174        matrix.data().swap(newdata);
175      }
176      else
177      {
178        // no need to realloc, simply copy the tail at its respective position and insert tmp
179        matrix.data().resize(start + nnz + tail_size);
180
181        std::memmove(&matrix.data().value(start+nnz), &matrix.data().value(end), tail_size*sizeof(Scalar));
182        std::memmove(&matrix.data().index(start+nnz), &matrix.data().index(end), tail_size*sizeof(Index));
183
184        std::memcpy(&matrix.data().value(start), &tmp.data().value(0), nnz*sizeof(Scalar));
185        std::memcpy(&matrix.data().index(start), &tmp.data().index(0), nnz*sizeof(Index));
186      }
187     
188      // update innerNonZeros
189      if(!m_matrix.isCompressed())
190        for(Index j=0; j<m_outerSize.value(); ++j)
191          matrix.innerNonZeroPtr()[m_outerStart+j] = tmp.innerVector(j).nonZeros();
192
193      // update outer index pointers
194      Index p = start;
195      for(Index k=0; k<m_outerSize.value(); ++k)
196      {
197        matrix.outerIndexPtr()[m_outerStart+k] = p;
198        p += tmp.innerVector(k).nonZeros();
199      }
200      std::ptrdiff_t offset = nnz - block_size;
201      for(Index k = m_outerStart + m_outerSize.value(); k<=matrix.outerSize(); ++k)
202      {
203        matrix.outerIndexPtr()[k] += offset;
204      }
205
206      return derived();
207    }
208
209    inline BlockType& operator=(const BlockType& other)
210    {
211      return operator=<BlockType>(other);
212    }
213
214    inline const Scalar* valuePtr() const
215    { return m_matrix.valuePtr() + m_matrix.outerIndexPtr()[m_outerStart]; }
216    inline Scalar* valuePtr()
217    { return m_matrix.const_cast_derived().valuePtr() + m_matrix.outerIndexPtr()[m_outerStart]; }
218
219    inline const Index* innerIndexPtr() const
220    { return m_matrix.innerIndexPtr() + m_matrix.outerIndexPtr()[m_outerStart]; }
221    inline Index* innerIndexPtr()
222    { return m_matrix.const_cast_derived().innerIndexPtr() + m_matrix.outerIndexPtr()[m_outerStart]; }
223
224    inline const Index* outerIndexPtr() const
225    { return m_matrix.outerIndexPtr() + m_outerStart; }
226    inline Index* outerIndexPtr()
227    { return m_matrix.const_cast_derived().outerIndexPtr() + m_outerStart; }
228
229    Index nonZeros() const
230    {
231      if(m_matrix.isCompressed())
232        return  std::size_t(m_matrix.outerIndexPtr()[m_outerStart+m_outerSize.value()])
233              - std::size_t(m_matrix.outerIndexPtr()[m_outerStart]);
234      else if(m_outerSize.value()==0)
235        return 0;
236      else
237        return Map<const Matrix<Index,OuterSize,1> >(m_matrix.innerNonZeroPtr()+m_outerStart, m_outerSize.value()).sum();
238    }
239   
240    inline Scalar& coeffRef(int row, int col)
241    {
242      return m_matrix.const_cast_derived().coeffRef(row + (IsRowMajor ? m_outerStart : 0), col + (IsRowMajor ? 0 :  m_outerStart));
243    }
244   
245    inline const Scalar coeff(int row, int col) const
246    {
247      return m_matrix.coeff(row + (IsRowMajor ? m_outerStart : 0), col + (IsRowMajor ? 0 :  m_outerStart));
248    }
249   
250    inline const Scalar coeff(int index) const
251    {
252      return m_matrix.coeff(IsRowMajor ? m_outerStart : index, IsRowMajor ? index :  m_outerStart);
253    }
254
255    const Scalar& lastCoeff() const
256    {
257      EIGEN_STATIC_ASSERT_VECTOR_ONLY(BlockImpl);
258      eigen_assert(nonZeros()>0);
259      if(m_matrix.isCompressed())
260        return m_matrix.valuePtr()[m_matrix.outerIndexPtr()[m_outerStart+1]-1];
261      else
262        return m_matrix.valuePtr()[m_matrix.outerIndexPtr()[m_outerStart]+m_matrix.innerNonZeroPtr()[m_outerStart]-1];
263    }
264
265    EIGEN_STRONG_INLINE Index rows() const { return IsRowMajor ? m_outerSize.value() : m_matrix.rows(); }
266    EIGEN_STRONG_INLINE Index cols() const { return IsRowMajor ? m_matrix.cols() : m_outerSize.value(); }
267
268  protected:
269
270    typename SparseMatrixType::Nested m_matrix;
271    Index m_outerStart;
272    const internal::variable_if_dynamic<Index, OuterSize> m_outerSize;
273
274};
275
276
277template<typename _Scalar, int _Options, typename _Index, int BlockRows, int BlockCols>
278class BlockImpl<const SparseMatrix<_Scalar, _Options, _Index>,BlockRows,BlockCols,true,Sparse>
279  : public SparseMatrixBase<Block<const SparseMatrix<_Scalar, _Options, _Index>,BlockRows,BlockCols,true> >
280{
281    typedef SparseMatrix<_Scalar, _Options, _Index> SparseMatrixType;
282    typedef typename internal::remove_all<typename SparseMatrixType::Nested>::type _MatrixTypeNested;
283    typedef Block<const SparseMatrixType, BlockRows, BlockCols, true> BlockType;
284public:
285    enum { IsRowMajor = internal::traits<BlockType>::IsRowMajor };
286    EIGEN_SPARSE_PUBLIC_INTERFACE(BlockType)
287protected:
288    enum { OuterSize = IsRowMajor ? BlockRows : BlockCols };
289public:
290   
291    class InnerIterator: public SparseMatrixType::InnerIterator
292    {
293      public:
294        inline InnerIterator(const BlockType& xpr, Index outer)
295          : SparseMatrixType::InnerIterator(xpr.m_matrix, xpr.m_outerStart + outer), m_outer(outer)
296        {}
297        inline Index row() const { return IsRowMajor ? m_outer : this->index(); }
298        inline Index col() const { return IsRowMajor ? this->index() : m_outer; }
299      protected:
300        Index m_outer;
301    };
302    class ReverseInnerIterator: public SparseMatrixType::ReverseInnerIterator
303    {
304      public:
305        inline ReverseInnerIterator(const BlockType& xpr, Index outer)
306          : SparseMatrixType::ReverseInnerIterator(xpr.m_matrix, xpr.m_outerStart + outer), m_outer(outer)
307        {}
308        inline Index row() const { return IsRowMajor ? m_outer : this->index(); }
309        inline Index col() const { return IsRowMajor ? this->index() : m_outer; }
310      protected:
311        Index m_outer;
312    };
313
314    inline BlockImpl(const SparseMatrixType& xpr, int i)
315      : m_matrix(xpr), m_outerStart(i), m_outerSize(OuterSize)
316    {}
317
318    inline BlockImpl(const SparseMatrixType& xpr, int startRow, int startCol, int blockRows, int blockCols)
319      : m_matrix(xpr), m_outerStart(IsRowMajor ? startRow : startCol), m_outerSize(IsRowMajor ? blockRows : blockCols)
320    {}
321
322    inline const Scalar* valuePtr() const
323    { return m_matrix.valuePtr() + m_matrix.outerIndexPtr()[m_outerStart]; }
324
325    inline const Index* innerIndexPtr() const
326    { return m_matrix.innerIndexPtr() + m_matrix.outerIndexPtr()[m_outerStart]; }
327
328    inline const Index* outerIndexPtr() const
329    { return m_matrix.outerIndexPtr() + m_outerStart; }
330
331    Index nonZeros() const
332    {
333      if(m_matrix.isCompressed())
334        return  std::size_t(m_matrix.outerIndexPtr()[m_outerStart+m_outerSize.value()])
335              - std::size_t(m_matrix.outerIndexPtr()[m_outerStart]);
336      else if(m_outerSize.value()==0)
337        return 0;
338      else
339        return Map<const Matrix<Index,OuterSize,1> >(m_matrix.innerNonZeroPtr()+m_outerStart, m_outerSize.value()).sum();
340    }
341   
342    inline const Scalar coeff(int row, int col) const
343    {
344      return m_matrix.coeff(row + (IsRowMajor ? m_outerStart : 0), col + (IsRowMajor ? 0 :  m_outerStart));
345    }
346   
347    inline const Scalar coeff(int index) const
348    {
349      return m_matrix.coeff(IsRowMajor ? m_outerStart : index, IsRowMajor ? index :  m_outerStart);
350    }
351
352    const Scalar& lastCoeff() const
353    {
354      EIGEN_STATIC_ASSERT_VECTOR_ONLY(BlockImpl);
355      eigen_assert(nonZeros()>0);
356      if(m_matrix.isCompressed())
357        return m_matrix.valuePtr()[m_matrix.outerIndexPtr()[m_outerStart+1]-1];
358      else
359        return m_matrix.valuePtr()[m_matrix.outerIndexPtr()[m_outerStart]+m_matrix.innerNonZeroPtr()[m_outerStart]-1];
360    }
361
362    EIGEN_STRONG_INLINE Index rows() const { return IsRowMajor ? m_outerSize.value() : m_matrix.rows(); }
363    EIGEN_STRONG_INLINE Index cols() const { return IsRowMajor ? m_matrix.cols() : m_outerSize.value(); }
364
365  protected:
366
367    typename SparseMatrixType::Nested m_matrix;
368    Index m_outerStart;
369    const internal::variable_if_dynamic<Index, OuterSize> m_outerSize;
370
371};
372
373//----------
374
375/** \returns the \a outer -th column (resp. row) of the matrix \c *this if \c *this
376  * is col-major (resp. row-major).
377  */
378template<typename Derived>
379typename SparseMatrixBase<Derived>::InnerVectorReturnType SparseMatrixBase<Derived>::innerVector(Index outer)
380{ return InnerVectorReturnType(derived(), outer); }
381
382/** \returns the \a outer -th column (resp. row) of the matrix \c *this if \c *this
383  * is col-major (resp. row-major). Read-only.
384  */
385template<typename Derived>
386const typename SparseMatrixBase<Derived>::ConstInnerVectorReturnType SparseMatrixBase<Derived>::innerVector(Index outer) const
387{ return ConstInnerVectorReturnType(derived(), outer); }
388
389/** \returns the \a outer -th column (resp. row) of the matrix \c *this if \c *this
390  * is col-major (resp. row-major).
391  */
392template<typename Derived>
393typename SparseMatrixBase<Derived>::InnerVectorsReturnType
394SparseMatrixBase<Derived>::innerVectors(Index outerStart, Index outerSize)
395{
396  return Block<Derived,Dynamic,Dynamic,true>(derived(),
397                                             IsRowMajor ? outerStart : 0, IsRowMajor ? 0 : outerStart,
398                                             IsRowMajor ? outerSize : rows(), IsRowMajor ? cols() : outerSize);
399 
400}
401
402/** \returns the \a outer -th column (resp. row) of the matrix \c *this if \c *this
403  * is col-major (resp. row-major). Read-only.
404  */
405template<typename Derived>
406const typename SparseMatrixBase<Derived>::ConstInnerVectorsReturnType
407SparseMatrixBase<Derived>::innerVectors(Index outerStart, Index outerSize) const
408{
409  return Block<const Derived,Dynamic,Dynamic,true>(derived(),
410                                                  IsRowMajor ? outerStart : 0, IsRowMajor ? 0 : outerStart,
411                                                  IsRowMajor ? outerSize : rows(), IsRowMajor ? cols() : outerSize);
412 
413}
414
415/** Generic implementation of sparse Block expression.
416  * Real-only.
417  */
418template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel>
419class BlockImpl<XprType,BlockRows,BlockCols,InnerPanel,Sparse>
420  : public SparseMatrixBase<Block<XprType,BlockRows,BlockCols,InnerPanel> >, internal::no_assignment_operator
421{
422  typedef typename internal::remove_all<typename XprType::Nested>::type _MatrixTypeNested;
423  typedef Block<XprType, BlockRows, BlockCols, InnerPanel> BlockType;
424public:
425    enum { IsRowMajor = internal::traits<BlockType>::IsRowMajor };
426    EIGEN_SPARSE_PUBLIC_INTERFACE(BlockType)
427
428    /** Column or Row constructor
429      */
430    inline BlockImpl(const XprType& xpr, int i)
431      : m_matrix(xpr),
432        m_startRow( (BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) ? i : 0),
433        m_startCol( (BlockRows==XprType::RowsAtCompileTime) && (BlockCols==1) ? i : 0),
434        m_blockRows(BlockRows==1 ? 1 : xpr.rows()),
435        m_blockCols(BlockCols==1 ? 1 : xpr.cols())
436    {}
437
438    /** Dynamic-size constructor
439      */
440    inline BlockImpl(const XprType& xpr, int startRow, int startCol, int blockRows, int blockCols)
441      : m_matrix(xpr), m_startRow(startRow), m_startCol(startCol), m_blockRows(blockRows), m_blockCols(blockCols)
442    {}
443
444    inline int rows() const { return m_blockRows.value(); }
445    inline int cols() const { return m_blockCols.value(); }
446
447    inline Scalar& coeffRef(int row, int col)
448    {
449      return m_matrix.const_cast_derived()
450               .coeffRef(row + m_startRow.value(), col + m_startCol.value());
451    }
452
453    inline const Scalar coeff(int row, int col) const
454    {
455      return m_matrix.coeff(row + m_startRow.value(), col + m_startCol.value());
456    }
457
458    inline Scalar& coeffRef(int index)
459    {
460      return m_matrix.const_cast_derived()
461             .coeffRef(m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index),
462                       m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0));
463    }
464
465    inline const Scalar coeff(int index) const
466    {
467      return m_matrix
468             .coeff(m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index),
469                    m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0));
470    }
471   
472    inline const _MatrixTypeNested& nestedExpression() const { return m_matrix; }
473   
474    class InnerIterator : public _MatrixTypeNested::InnerIterator
475    {
476      typedef typename _MatrixTypeNested::InnerIterator Base;
477      const BlockType& m_block;
478      Index m_end;
479    public:
480
481      EIGEN_STRONG_INLINE InnerIterator(const BlockType& block, Index outer)
482        : Base(block.derived().nestedExpression(), outer + (IsRowMajor ? block.m_startRow.value() : block.m_startCol.value())),
483          m_block(block),
484          m_end(IsRowMajor ? block.m_startCol.value()+block.m_blockCols.value() : block.m_startRow.value()+block.m_blockRows.value())
485      {
486        while( (Base::operator bool()) && (Base::index() < (IsRowMajor ? m_block.m_startCol.value() : m_block.m_startRow.value())) )
487          Base::operator++();
488      }
489
490      inline Index index()  const { return Base::index() - (IsRowMajor ? m_block.m_startCol.value() : m_block.m_startRow.value()); }
491      inline Index outer()  const { return Base::outer() - (IsRowMajor ? m_block.m_startRow.value() : m_block.m_startCol.value()); }
492      inline Index row()    const { return Base::row()   - m_block.m_startRow.value(); }
493      inline Index col()    const { return Base::col()   - m_block.m_startCol.value(); }
494     
495      inline operator bool() const { return Base::operator bool() && Base::index() < m_end; }
496    };
497    class ReverseInnerIterator : public _MatrixTypeNested::ReverseInnerIterator
498    {
499      typedef typename _MatrixTypeNested::ReverseInnerIterator Base;
500      const BlockType& m_block;
501      Index m_begin;
502    public:
503
504      EIGEN_STRONG_INLINE ReverseInnerIterator(const BlockType& block, Index outer)
505        : Base(block.derived().nestedExpression(), outer + (IsRowMajor ? block.m_startRow.value() : block.m_startCol.value())),
506          m_block(block),
507          m_begin(IsRowMajor ? block.m_startCol.value() : block.m_startRow.value())
508      {
509        while( (Base::operator bool()) && (Base::index() >= (IsRowMajor ? m_block.m_startCol.value()+block.m_blockCols.value() : m_block.m_startRow.value()+block.m_blockRows.value())) )
510          Base::operator--();
511      }
512
513      inline Index index()  const { return Base::index() - (IsRowMajor ? m_block.m_startCol.value() : m_block.m_startRow.value()); }
514      inline Index outer()  const { return Base::outer() - (IsRowMajor ? m_block.m_startRow.value() : m_block.m_startCol.value()); }
515      inline Index row()    const { return Base::row()   - m_block.m_startRow.value(); }
516      inline Index col()    const { return Base::col()   - m_block.m_startCol.value(); }
517     
518      inline operator bool() const { return Base::operator bool() && Base::index() >= m_begin; }
519    };
520  protected:
521    friend class InnerIterator;
522    friend class ReverseInnerIterator;
523   
524    EIGEN_INHERIT_ASSIGNMENT_OPERATORS(BlockImpl)
525
526    typename XprType::Nested m_matrix;
527    const internal::variable_if_dynamic<Index, XprType::RowsAtCompileTime == 1 ? 0 : Dynamic> m_startRow;
528    const internal::variable_if_dynamic<Index, XprType::ColsAtCompileTime == 1 ? 0 : Dynamic> m_startCol;
529    const internal::variable_if_dynamic<Index, RowsAtCompileTime> m_blockRows;
530    const internal::variable_if_dynamic<Index, ColsAtCompileTime> m_blockCols;
531
532};
533
534} // end namespace Eigen
535
536#endif // EIGEN_SPARSE_BLOCK_H
537
Note: See TracBrowser for help on using the repository browser.