MappedSparseMatrix.h
Go to the documentation of this file.
1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra.
3 //
4 // Copyright (C) 2008 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_MAPPED_SPARSEMATRIX_H
26 #define EIGEN_MAPPED_SPARSEMATRIX_H
27 
28 namespace Eigen {
29 
39 namespace internal {
40 template<typename _Scalar, int _Flags, typename _Index>
41 struct traits<MappedSparseMatrix<_Scalar, _Flags, _Index> > : traits<SparseMatrix<_Scalar, _Flags, _Index> >
42 {};
43 }
44 
45 template<typename _Scalar, int _Flags, typename _Index>
47  : public SparseMatrixBase<MappedSparseMatrix<_Scalar, _Flags, _Index> >
48 {
49  public:
51  enum { IsRowMajor = Base::IsRowMajor };
52 
53  protected:
54 
61 
62  public:
63 
64  inline Index rows() const { return IsRowMajor ? m_outerSize : m_innerSize; }
65  inline Index cols() const { return IsRowMajor ? m_innerSize : m_outerSize; }
66  inline Index innerSize() const { return m_innerSize; }
67  inline Index outerSize() const { return m_outerSize; }
68 
69  //----------------------------------------
70  // direct access interface
71  inline const Scalar* valuePtr() const { return m_values; }
72  inline Scalar* valuePtr() { return m_values; }
73 
74  inline const Index* innerIndexPtr() const { return m_innerIndices; }
75  inline Index* innerIndexPtr() { return m_innerIndices; }
76 
77  inline const Index* outerIndexPtr() const { return m_outerIndex; }
78  inline Index* outerIndexPtr() { return m_outerIndex; }
79  //----------------------------------------
80 
81  inline Scalar coeff(Index row, Index col) const
82  {
83  const Index outer = IsRowMajor ? row : col;
84  const Index inner = IsRowMajor ? col : row;
85 
86  Index start = m_outerIndex[outer];
87  Index end = m_outerIndex[outer+1];
88  if (start==end)
89  return Scalar(0);
90  else if (end>0 && inner==m_innerIndices[end-1])
91  return m_values[end-1];
92  // ^^ optimization: let's first check if it is the last coefficient
93  // (very common in high level algorithms)
94 
95  const Index* r = std::lower_bound(&m_innerIndices[start],&m_innerIndices[end-1],inner);
96  const Index id = r-&m_innerIndices[0];
97  return ((*r==inner) && (id<end)) ? m_values[id] : Scalar(0);
98  }
99 
101  {
102  const Index outer = IsRowMajor ? row : col;
103  const Index inner = IsRowMajor ? col : row;
104 
105  Index start = m_outerIndex[outer];
106  Index end = m_outerIndex[outer+1];
107  eigen_assert(end>=start && "you probably called coeffRef on a non finalized matrix");
108  eigen_assert(end>start && "coeffRef cannot be called on a zero coefficient");
109  Index* r = std::lower_bound(&m_innerIndices[start],&m_innerIndices[end],inner);
110  const Index id = r-&m_innerIndices[0];
111  eigen_assert((*r==inner) && (id<end) && "coeffRef cannot be called on a zero coefficient");
112  return m_values[id];
113  }
114 
115  class InnerIterator;
116  class ReverseInnerIterator;
117 
119  inline Index nonZeros() const { return m_nnz; }
120 
122  : m_outerSize(IsRowMajor?rows:cols), m_innerSize(IsRowMajor?cols:rows), m_nnz(nnz), m_outerIndex(outerIndexPtr),
123  m_innerIndices(innerIndexPtr), m_values(valuePtr)
124  {}
125 
128 };
129 
130 template<typename Scalar, int _Flags, typename _Index>
131 class MappedSparseMatrix<Scalar,_Flags,_Index>::InnerIterator
132 {
133  public:
134  InnerIterator(const MappedSparseMatrix& mat, Index outer)
135  : m_matrix(mat),
136  m_outer(outer),
137  m_id(mat.outerIndexPtr()[outer]),
138  m_start(m_id),
139  m_end(mat.outerIndexPtr()[outer+1])
140  {}
141 
142  inline InnerIterator& operator++() { m_id++; return *this; }
143 
144  inline Scalar value() const { return m_matrix.valuePtr()[m_id]; }
145  inline Scalar& valueRef() { return const_cast<Scalar&>(m_matrix.valuePtr()[m_id]); }
146 
147  inline Index index() const { return m_matrix.innerIndexPtr()[m_id]; }
148  inline Index row() const { return IsRowMajor ? m_outer : index(); }
149  inline Index col() const { return IsRowMajor ? index() : m_outer; }
150 
151  inline operator bool() const { return (m_id < m_end) && (m_id>=m_start); }
152 
153  protected:
154  const MappedSparseMatrix& m_matrix;
155  const Index m_outer;
156  Index m_id;
157  const Index m_start;
158  const Index m_end;
159 };
160 
161 template<typename Scalar, int _Flags, typename _Index>
162 class MappedSparseMatrix<Scalar,_Flags,_Index>::ReverseInnerIterator
163 {
164  public:
165  ReverseInnerIterator(const MappedSparseMatrix& mat, Index outer)
166  : m_matrix(mat),
167  m_outer(outer),
168  m_id(mat.outerIndexPtr()[outer+1]),
169  m_start(mat.outerIndexPtr()[outer]),
170  m_end(m_id)
171  {}
172 
173  inline ReverseInnerIterator& operator--() { m_id--; return *this; }
174 
175  inline Scalar value() const { return m_matrix.valuePtr()[m_id-1]; }
176  inline Scalar& valueRef() { return const_cast<Scalar&>(m_matrix.valuePtr()[m_id-1]); }
177 
178  inline Index index() const { return m_matrix.innerIndexPtr()[m_id-1]; }
179  inline Index row() const { return IsRowMajor ? m_outer : index(); }
180  inline Index col() const { return IsRowMajor ? index() : m_outer; }
181 
182  inline operator bool() const { return (m_id <= m_end) && (m_id>m_start); }
183 
184  protected:
185  const MappedSparseMatrix& m_matrix;
186  const Index m_outer;
187  Index m_id;
188  const Index m_start;
189  const Index m_end;
190 };
191 
192 } // end namespace Eigen
193 
194 #endif // EIGEN_MAPPED_SPARSEMATRIX_H