• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 // 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_MAPPED_SPARSEMATRIX_H
11 #define EIGEN_MAPPED_SPARSEMATRIX_H
12 
13 namespace Eigen {
14 
15 /** \class MappedSparseMatrix
16   *
17   * \brief Sparse matrix
18   *
19   * \param _Scalar the scalar type, i.e. the type of the coefficients
20   *
21   * See http://www.netlib.org/linalg/html_templates/node91.html for details on the storage scheme.
22   *
23   */
24 namespace internal {
25 template<typename _Scalar, int _Flags, typename _Index>
26 struct traits<MappedSparseMatrix<_Scalar, _Flags, _Index> > : traits<SparseMatrix<_Scalar, _Flags, _Index> >
27 {};
28 }
29 
30 template<typename _Scalar, int _Flags, typename _Index>
31 class MappedSparseMatrix
32   : public SparseMatrixBase<MappedSparseMatrix<_Scalar, _Flags, _Index> >
33 {
34   public:
35     EIGEN_SPARSE_PUBLIC_INTERFACE(MappedSparseMatrix)
36     enum { IsRowMajor = Base::IsRowMajor };
37 
38   protected:
39 
40     Index   m_outerSize;
41     Index   m_innerSize;
42     Index   m_nnz;
43     Index*  m_outerIndex;
44     Index*  m_innerIndices;
45     Scalar* m_values;
46 
47   public:
48 
49     inline Index rows() const { return IsRowMajor ? m_outerSize : m_innerSize; }
50     inline Index cols() const { return IsRowMajor ? m_innerSize : m_outerSize; }
51     inline Index innerSize() const { return m_innerSize; }
52     inline Index outerSize() const { return m_outerSize; }
53 
54     //----------------------------------------
55     // direct access interface
56     inline const Scalar* valuePtr() const { return m_values; }
57     inline Scalar* valuePtr() { return m_values; }
58 
59     inline const Index* innerIndexPtr() const { return m_innerIndices; }
60     inline Index* innerIndexPtr() { return m_innerIndices; }
61 
62     inline const Index* outerIndexPtr() const { return m_outerIndex; }
63     inline Index* outerIndexPtr() { return m_outerIndex; }
64     //----------------------------------------
65 
66     inline Scalar coeff(Index row, Index col) const
67     {
68       const Index outer = IsRowMajor ? row : col;
69       const Index inner = IsRowMajor ? col : row;
70 
71       Index start = m_outerIndex[outer];
72       Index end = m_outerIndex[outer+1];
73       if (start==end)
74         return Scalar(0);
75       else if (end>0 && inner==m_innerIndices[end-1])
76         return m_values[end-1];
77       // ^^  optimization: let's first check if it is the last coefficient
78       // (very common in high level algorithms)
79 
80       const Index* r = std::lower_bound(&m_innerIndices[start],&m_innerIndices[end-1],inner);
81       const Index id = r-&m_innerIndices[0];
82       return ((*r==inner) && (id<end)) ? m_values[id] : Scalar(0);
83     }
84 
85     inline Scalar& coeffRef(Index row, Index col)
86     {
87       const Index outer = IsRowMajor ? row : col;
88       const Index inner = IsRowMajor ? col : row;
89 
90       Index start = m_outerIndex[outer];
91       Index end = m_outerIndex[outer+1];
92       eigen_assert(end>=start && "you probably called coeffRef on a non finalized matrix");
93       eigen_assert(end>start && "coeffRef cannot be called on a zero coefficient");
94       Index* r = std::lower_bound(&m_innerIndices[start],&m_innerIndices[end],inner);
95       const Index id = r-&m_innerIndices[0];
96       eigen_assert((*r==inner) && (id<end) && "coeffRef cannot be called on a zero coefficient");
97       return m_values[id];
98     }
99 
100     class InnerIterator;
101     class ReverseInnerIterator;
102 
103     /** \returns the number of non zero coefficients */
104     inline Index nonZeros() const  { return m_nnz; }
105 
106     inline MappedSparseMatrix(Index rows, Index cols, Index nnz, Index* outerIndexPtr, Index* innerIndexPtr, Scalar* valuePtr)
107       : m_outerSize(IsRowMajor?rows:cols), m_innerSize(IsRowMajor?cols:rows), m_nnz(nnz), m_outerIndex(outerIndexPtr),
108         m_innerIndices(innerIndexPtr), m_values(valuePtr)
109     {}
110 
111     /** Empty destructor */
112     inline ~MappedSparseMatrix() {}
113 };
114 
115 template<typename Scalar, int _Flags, typename _Index>
116 class MappedSparseMatrix<Scalar,_Flags,_Index>::InnerIterator
117 {
118   public:
119     InnerIterator(const MappedSparseMatrix& mat, Index outer)
120       : m_matrix(mat),
121         m_outer(outer),
122         m_id(mat.outerIndexPtr()[outer]),
123         m_start(m_id),
124         m_end(mat.outerIndexPtr()[outer+1])
125     {}
126 
127     inline InnerIterator& operator++() { m_id++; return *this; }
128 
129     inline Scalar value() const { return m_matrix.valuePtr()[m_id]; }
130     inline Scalar& valueRef() { return const_cast<Scalar&>(m_matrix.valuePtr()[m_id]); }
131 
132     inline Index index() const { return m_matrix.innerIndexPtr()[m_id]; }
133     inline Index row() const { return IsRowMajor ? m_outer : index(); }
134     inline Index col() const { return IsRowMajor ? index() : m_outer; }
135 
136     inline operator bool() const { return (m_id < m_end) && (m_id>=m_start); }
137 
138   protected:
139     const MappedSparseMatrix& m_matrix;
140     const Index m_outer;
141     Index m_id;
142     const Index m_start;
143     const Index m_end;
144 };
145 
146 template<typename Scalar, int _Flags, typename _Index>
147 class MappedSparseMatrix<Scalar,_Flags,_Index>::ReverseInnerIterator
148 {
149   public:
150     ReverseInnerIterator(const MappedSparseMatrix& mat, Index outer)
151       : m_matrix(mat),
152         m_outer(outer),
153         m_id(mat.outerIndexPtr()[outer+1]),
154         m_start(mat.outerIndexPtr()[outer]),
155         m_end(m_id)
156     {}
157 
158     inline ReverseInnerIterator& operator--() { m_id--; return *this; }
159 
160     inline Scalar value() const { return m_matrix.valuePtr()[m_id-1]; }
161     inline Scalar& valueRef() { return const_cast<Scalar&>(m_matrix.valuePtr()[m_id-1]); }
162 
163     inline Index index() const { return m_matrix.innerIndexPtr()[m_id-1]; }
164     inline Index row() const { return IsRowMajor ? m_outer : index(); }
165     inline Index col() const { return IsRowMajor ? index() : m_outer; }
166 
167     inline operator bool() const { return (m_id <= m_end) && (m_id>m_start); }
168 
169   protected:
170     const MappedSparseMatrix& m_matrix;
171     const Index m_outer;
172     Index m_id;
173     const Index m_start;
174     const Index m_end;
175 };
176 
177 } // end namespace Eigen
178 
179 #endif // EIGEN_MAPPED_SPARSEMATRIX_H
180