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