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 13namespace 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 */ 24namespace internal { 25template<typename _Scalar, int _Flags, typename _Index> 26struct traits<MappedSparseMatrix<_Scalar, _Flags, _Index> > : traits<SparseMatrix<_Scalar, _Flags, _Index> > 27{}; 28} 29 30template<typename _Scalar, int _Flags, typename _Index> 31class 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 bool isCompressed() const { return true; } 55 56 //---------------------------------------- 57 // direct access interface 58 inline const Scalar* valuePtr() const { return m_values; } 59 inline Scalar* valuePtr() { return m_values; } 60 61 inline const Index* innerIndexPtr() const { return m_innerIndices; } 62 inline Index* innerIndexPtr() { return m_innerIndices; } 63 64 inline const Index* outerIndexPtr() const { return m_outerIndex; } 65 inline Index* outerIndexPtr() { return m_outerIndex; } 66 //---------------------------------------- 67 68 inline Scalar coeff(Index row, Index col) const 69 { 70 const Index outer = IsRowMajor ? row : col; 71 const Index inner = IsRowMajor ? col : row; 72 73 Index start = m_outerIndex[outer]; 74 Index end = m_outerIndex[outer+1]; 75 if (start==end) 76 return Scalar(0); 77 else if (end>0 && inner==m_innerIndices[end-1]) 78 return m_values[end-1]; 79 // ^^ optimization: let's first check if it is the last coefficient 80 // (very common in high level algorithms) 81 82 const Index* r = std::lower_bound(&m_innerIndices[start],&m_innerIndices[end-1],inner); 83 const Index id = r-&m_innerIndices[0]; 84 return ((*r==inner) && (id<end)) ? m_values[id] : Scalar(0); 85 } 86 87 inline Scalar& coeffRef(Index row, Index col) 88 { 89 const Index outer = IsRowMajor ? row : col; 90 const Index inner = IsRowMajor ? col : row; 91 92 Index start = m_outerIndex[outer]; 93 Index end = m_outerIndex[outer+1]; 94 eigen_assert(end>=start && "you probably called coeffRef on a non finalized matrix"); 95 eigen_assert(end>start && "coeffRef cannot be called on a zero coefficient"); 96 Index* r = std::lower_bound(&m_innerIndices[start],&m_innerIndices[end],inner); 97 const Index id = r-&m_innerIndices[0]; 98 eigen_assert((*r==inner) && (id<end) && "coeffRef cannot be called on a zero coefficient"); 99 return m_values[id]; 100 } 101 102 class InnerIterator; 103 class ReverseInnerIterator; 104 105 /** \returns the number of non zero coefficients */ 106 inline Index nonZeros() const { return m_nnz; } 107 108 inline MappedSparseMatrix(Index rows, Index cols, Index nnz, Index* outerIndexPtr, Index* innerIndexPtr, Scalar* valuePtr) 109 : m_outerSize(IsRowMajor?rows:cols), m_innerSize(IsRowMajor?cols:rows), m_nnz(nnz), m_outerIndex(outerIndexPtr), 110 m_innerIndices(innerIndexPtr), m_values(valuePtr) 111 {} 112 113 /** Empty destructor */ 114 inline ~MappedSparseMatrix() {} 115}; 116 117template<typename Scalar, int _Flags, typename _Index> 118class MappedSparseMatrix<Scalar,_Flags,_Index>::InnerIterator 119{ 120 public: 121 InnerIterator(const MappedSparseMatrix& mat, Index outer) 122 : m_matrix(mat), 123 m_outer(outer), 124 m_id(mat.outerIndexPtr()[outer]), 125 m_start(m_id), 126 m_end(mat.outerIndexPtr()[outer+1]) 127 {} 128 129 inline InnerIterator& operator++() { m_id++; return *this; } 130 131 inline Scalar value() const { return m_matrix.valuePtr()[m_id]; } 132 inline Scalar& valueRef() { return const_cast<Scalar&>(m_matrix.valuePtr()[m_id]); } 133 134 inline Index index() const { return m_matrix.innerIndexPtr()[m_id]; } 135 inline Index row() const { return IsRowMajor ? m_outer : index(); } 136 inline Index col() const { return IsRowMajor ? index() : m_outer; } 137 138 inline operator bool() const { return (m_id < m_end) && (m_id>=m_start); } 139 140 protected: 141 const MappedSparseMatrix& m_matrix; 142 const Index m_outer; 143 Index m_id; 144 const Index m_start; 145 const Index m_end; 146}; 147 148template<typename Scalar, int _Flags, typename _Index> 149class MappedSparseMatrix<Scalar,_Flags,_Index>::ReverseInnerIterator 150{ 151 public: 152 ReverseInnerIterator(const MappedSparseMatrix& mat, Index outer) 153 : m_matrix(mat), 154 m_outer(outer), 155 m_id(mat.outerIndexPtr()[outer+1]), 156 m_start(mat.outerIndexPtr()[outer]), 157 m_end(m_id) 158 {} 159 160 inline ReverseInnerIterator& operator--() { m_id--; return *this; } 161 162 inline Scalar value() const { return m_matrix.valuePtr()[m_id-1]; } 163 inline Scalar& valueRef() { return const_cast<Scalar&>(m_matrix.valuePtr()[m_id-1]); } 164 165 inline Index index() const { return m_matrix.innerIndexPtr()[m_id-1]; } 166 inline Index row() const { return IsRowMajor ? m_outer : index(); } 167 inline Index col() const { return IsRowMajor ? index() : m_outer; } 168 169 inline operator bool() const { return (m_id <= m_end) && (m_id>m_start); } 170 171 protected: 172 const MappedSparseMatrix& m_matrix; 173 const Index m_outer; 174 Index m_id; 175 const Index m_start; 176 const Index m_end; 177}; 178 179} // end namespace Eigen 180 181#endif // EIGEN_MAPPED_SPARSEMATRIX_H 182