BlockOfDynamicSparseMatrix.h
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 // Eigen is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 3 of the License, or (at your option) any later version.
10 //
11 // Alternatively, you can redistribute it and/or
12 // modify it under the terms of the GNU General Public License as
13 // published by the Free Software Foundation; either version 2 of
14 // the License, or (at your option) any later version.
15 //
16 // Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
17 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
19 // GNU General Public License for more details.
20 //
21 // You should have received a copy of the GNU Lesser General Public
22 // License and a copy of the GNU General Public License along with
23 // Eigen. If not, see <http://www.gnu.org/licenses/>.
24 
25 #ifndef EIGEN_SPARSE_BLOCKFORDYNAMICMATRIX_H
26 #define EIGEN_SPARSE_BLOCKFORDYNAMICMATRIX_H
27 
28 namespace Eigen {
29 
30 /***************************************************************************
31 * specialisation for DynamicSparseMatrix
32 ***************************************************************************/
33 
34 template<typename _Scalar, int _Options, typename _Index, int Size>
35 class SparseInnerVectorSet<DynamicSparseMatrix<_Scalar, _Options, _Index>, Size>
36  : public SparseMatrixBase<SparseInnerVectorSet<DynamicSparseMatrix<_Scalar, _Options, _Index>, Size> >
37 {
38  typedef DynamicSparseMatrix<_Scalar, _Options, _Index> MatrixType;
39  public:
40 
41  enum { IsRowMajor = internal::traits<SparseInnerVectorSet>::IsRowMajor };
42 
43  EIGEN_SPARSE_PUBLIC_INTERFACE(SparseInnerVectorSet)
44  class InnerIterator: public MatrixType::InnerIterator
45  {
46  public:
47  inline InnerIterator(const SparseInnerVectorSet& xpr, Index outer)
48  : MatrixType::InnerIterator(xpr.m_matrix, xpr.m_outerStart + outer), m_outer(outer)
49  {}
50  inline Index row() const { return IsRowMajor ? m_outer : this->index(); }
51  inline Index col() const { return IsRowMajor ? this->index() : m_outer; }
52  protected:
53  Index m_outer;
54  };
55 
56  inline SparseInnerVectorSet(const MatrixType& matrix, Index outerStart, Index outerSize)
57  : m_matrix(matrix), m_outerStart(outerStart), m_outerSize(outerSize)
58  {
59  eigen_assert( (outerStart>=0) && ((outerStart+outerSize)<=matrix.outerSize()) );
60  }
61 
62  inline SparseInnerVectorSet(const MatrixType& matrix, Index outer)
63  : m_matrix(matrix), m_outerStart(outer), m_outerSize(Size)
64  {
65  eigen_assert(Size!=Dynamic);
66  eigen_assert( (outer>=0) && (outer<matrix.outerSize()) );
67  }
68 
69  template<typename OtherDerived>
70  inline SparseInnerVectorSet& operator=(const SparseMatrixBase<OtherDerived>& other)
71  {
72  if (IsRowMajor != ((OtherDerived::Flags&RowMajorBit)==RowMajorBit))
73  {
74  // need to transpose => perform a block evaluation followed by a big swap
75  DynamicSparseMatrix<Scalar,IsRowMajor?RowMajorBit:0> aux(other);
76  *this = aux.markAsRValue();
77  }
78  else
79  {
80  // evaluate/copy vector per vector
81  for (Index j=0; j<m_outerSize.value(); ++j)
82  {
83  SparseVector<Scalar,IsRowMajor ? RowMajorBit : 0> aux(other.innerVector(j));
84  m_matrix.const_cast_derived()._data()[m_outerStart+j].swap(aux._data());
85  }
86  }
87  return *this;
88  }
89 
90  inline SparseInnerVectorSet& operator=(const SparseInnerVectorSet& other)
91  {
92  return operator=<SparseInnerVectorSet>(other);
93  }
94 
95  Index nonZeros() const
96  {
97  Index count = 0;
98  for (Index j=0; j<m_outerSize.value(); ++j)
99  count += m_matrix._data()[m_outerStart+j].size();
100  return count;
101  }
102 
103  const Scalar& lastCoeff() const
104  {
105  EIGEN_STATIC_ASSERT_VECTOR_ONLY(SparseInnerVectorSet);
106  eigen_assert(m_matrix.data()[m_outerStart].size()>0);
107  return m_matrix.data()[m_outerStart].vale(m_matrix.data()[m_outerStart].size()-1);
108  }
109 
110 // template<typename Sparse>
111 // inline SparseInnerVectorSet& operator=(const SparseMatrixBase<OtherDerived>& other)
112 // {
113 // return *this;
114 // }
115 
116  EIGEN_STRONG_INLINE Index rows() const { return IsRowMajor ? m_outerSize.value() : m_matrix.rows(); }
117  EIGEN_STRONG_INLINE Index cols() const { return IsRowMajor ? m_matrix.cols() : m_outerSize.value(); }
118 
119  protected:
120 
121  const typename MatrixType::Nested m_matrix;
122  Index m_outerStart;
123  const internal::variable_if_dynamic<Index, Size> m_outerSize;
124 
125 };
126 
127 } // end namespace Eigen
128 
129 #endif // EIGEN_SPARSE_BLOCKFORDYNAMICMATRIX_H