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-2010 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_SPARSEMATRIX_H 11c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#define EIGEN_SPARSEMATRIX_H 12c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 13c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathnamespace Eigen { 14c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 15c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** \ingroup SparseCore_Module 16c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 17c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \class SparseMatrix 18c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 19c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \brief A versatible sparse matrix representation 20c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 21c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * This class implements a more versatile variants of the common \em compressed row/column storage format. 22c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * Each colmun's (resp. row) non zeros are stored as a pair of value with associated row (resp. colmiun) index. 23c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * All the non zeros are stored in a single large buffer. Unlike the \em compressed format, there might be extra 24c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * space inbetween the nonzeros of two successive colmuns (resp. rows) such that insertion of new non-zero 25c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * can be done with limited memory reallocation and copies. 26c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 27c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * A call to the function makeCompressed() turns the matrix into the standard \em compressed format 28c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * compatible with many library. 29c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 30c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * More details on this storage sceheme are given in the \ref TutorialSparse "manual pages". 31c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 32c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \tparam _Scalar the scalar type, i.e. the type of the coefficients 33c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \tparam _Options Union of bit flags controlling the storage scheme. Currently the only possibility 347faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez * is ColMajor or RowMajor. The default is 0 which means column-major. 35c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \tparam _Index the type of the indices. It has to be a \b signed type (e.g., short, int, std::ptrdiff_t). Default is \c int. 36c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 37c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * This class can be extended with the help of the plugin mechanism described on the page 38c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \ref TopicCustomizingEigen by defining the preprocessor symbol \c EIGEN_SPARSEMATRIX_PLUGIN. 39c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath */ 40c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 41c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathnamespace internal { 42c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename _Scalar, int _Options, typename _Index> 43c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct traits<SparseMatrix<_Scalar, _Options, _Index> > 44c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 45c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef _Scalar Scalar; 46c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef _Index Index; 47c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef Sparse StorageKind; 48c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef MatrixXpr XprKind; 49c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath enum { 50c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath RowsAtCompileTime = Dynamic, 51c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ColsAtCompileTime = Dynamic, 52c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath MaxRowsAtCompileTime = Dynamic, 53c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath MaxColsAtCompileTime = Dynamic, 54c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Flags = _Options | NestByRefBit | LvalueBit, 55c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath CoeffReadCost = NumTraits<Scalar>::ReadCost, 56c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath SupportedAccessPatterns = InnerRandomAccessPattern 57c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath }; 58c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 59c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 60c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename _Scalar, int _Options, typename _Index, int DiagIndex> 61c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathstruct traits<Diagonal<const SparseMatrix<_Scalar, _Options, _Index>, DiagIndex> > 62c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 63c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef SparseMatrix<_Scalar, _Options, _Index> MatrixType; 64c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef typename nested<MatrixType>::type MatrixTypeNested; 65c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef typename remove_reference<MatrixTypeNested>::type _MatrixTypeNested; 66c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 67c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef _Scalar Scalar; 68c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef Dense StorageKind; 69c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef _Index Index; 70c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef MatrixXpr XprKind; 71c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 72c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath enum { 73c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath RowsAtCompileTime = Dynamic, 74c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ColsAtCompileTime = 1, 75c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath MaxRowsAtCompileTime = Dynamic, 76c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath MaxColsAtCompileTime = 1, 77c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Flags = 0, 78c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath CoeffReadCost = _MatrixTypeNested::CoeffReadCost*10 79c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath }; 80c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 81c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 82c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} // end namespace internal 83c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 84c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename _Scalar, int _Options, typename _Index> 85c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathclass SparseMatrix 86c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath : public SparseMatrixBase<SparseMatrix<_Scalar, _Options, _Index> > 87c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 88c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath public: 89c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath EIGEN_SPARSE_PUBLIC_INTERFACE(SparseMatrix) 90c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath EIGEN_SPARSE_INHERIT_ASSIGNMENT_OPERATOR(SparseMatrix, +=) 91c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath EIGEN_SPARSE_INHERIT_ASSIGNMENT_OPERATOR(SparseMatrix, -=) 92c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 93c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef MappedSparseMatrix<Scalar,Flags> Map; 94c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath using Base::IsRowMajor; 95c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef internal::CompressedStorage<Scalar,Index> Storage; 96c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath enum { 97c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Options = _Options 98c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath }; 99c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 100c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath protected: 101c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 102c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef SparseMatrix<Scalar,(Flags&~RowMajorBit)|(IsRowMajor?RowMajorBit:0)> TransposedSparseMatrix; 103c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 104c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index m_outerSize; 105c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index m_innerSize; 106c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index* m_outerIndex; 107c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index* m_innerNonZeros; // optional, if null then the data is compressed 108c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Storage m_data; 109c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 110c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Eigen::Map<Matrix<Index,Dynamic,1> > innerNonZeros() { return Eigen::Map<Matrix<Index,Dynamic,1> >(m_innerNonZeros, m_innerNonZeros?m_outerSize:0); } 111c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath const Eigen::Map<const Matrix<Index,Dynamic,1> > innerNonZeros() const { return Eigen::Map<const Matrix<Index,Dynamic,1> >(m_innerNonZeros, m_innerNonZeros?m_outerSize:0); } 112c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 113c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath public: 114c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 115c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** \returns whether \c *this is in compressed form. */ 116c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath inline bool isCompressed() const { return m_innerNonZeros==0; } 117c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 118c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** \returns the number of rows of the matrix */ 119c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath inline Index rows() const { return IsRowMajor ? m_outerSize : m_innerSize; } 120c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** \returns the number of columns of the matrix */ 121c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath inline Index cols() const { return IsRowMajor ? m_innerSize : m_outerSize; } 122c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 123c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** \returns the number of rows (resp. columns) of the matrix if the storage order column major (resp. row major) */ 124c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath inline Index innerSize() const { return m_innerSize; } 125c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** \returns the number of columns (resp. rows) of the matrix if the storage order column major (resp. row major) */ 126c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath inline Index outerSize() const { return m_outerSize; } 127c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 128c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** \returns a const pointer to the array of values. 129c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * This function is aimed at interoperability with other libraries. 130c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \sa innerIndexPtr(), outerIndexPtr() */ 131c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath inline const Scalar* valuePtr() const { return &m_data.value(0); } 132c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** \returns a non-const pointer to the array of values. 133c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * This function is aimed at interoperability with other libraries. 134c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \sa innerIndexPtr(), outerIndexPtr() */ 135c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath inline Scalar* valuePtr() { return &m_data.value(0); } 136c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 137c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** \returns a const pointer to the array of inner indices. 138c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * This function is aimed at interoperability with other libraries. 139c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \sa valuePtr(), outerIndexPtr() */ 140c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath inline const Index* innerIndexPtr() const { return &m_data.index(0); } 141c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** \returns a non-const pointer to the array of inner indices. 142c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * This function is aimed at interoperability with other libraries. 143c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \sa valuePtr(), outerIndexPtr() */ 144c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath inline Index* innerIndexPtr() { return &m_data.index(0); } 145c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 146c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** \returns a const pointer to the array of the starting positions of the inner vectors. 147c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * This function is aimed at interoperability with other libraries. 148c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \sa valuePtr(), innerIndexPtr() */ 149c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath inline const Index* outerIndexPtr() const { return m_outerIndex; } 150c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** \returns a non-const pointer to the array of the starting positions of the inner vectors. 151c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * This function is aimed at interoperability with other libraries. 152c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \sa valuePtr(), innerIndexPtr() */ 153c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath inline Index* outerIndexPtr() { return m_outerIndex; } 154c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 155c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** \returns a const pointer to the array of the number of non zeros of the inner vectors. 156c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * This function is aimed at interoperability with other libraries. 157c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \warning it returns the null pointer 0 in compressed mode */ 158c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath inline const Index* innerNonZeroPtr() const { return m_innerNonZeros; } 159c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** \returns a non-const pointer to the array of the number of non zeros of the inner vectors. 160c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * This function is aimed at interoperability with other libraries. 161c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \warning it returns the null pointer 0 in compressed mode */ 162c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath inline Index* innerNonZeroPtr() { return m_innerNonZeros; } 163c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 164c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** \internal */ 165c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath inline Storage& data() { return m_data; } 166c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** \internal */ 167c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath inline const Storage& data() const { return m_data; } 168c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 169c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** \returns the value of the matrix at position \a i, \a j 170c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * This function returns Scalar(0) if the element is an explicit \em zero */ 171c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath inline Scalar coeff(Index row, Index col) const 172c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 1737faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez eigen_assert(row>=0 && row<rows() && col>=0 && col<cols()); 1747faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 175c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath const Index outer = IsRowMajor ? row : col; 176c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath const Index inner = IsRowMajor ? col : row; 177c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index end = m_innerNonZeros ? m_outerIndex[outer] + m_innerNonZeros[outer] : m_outerIndex[outer+1]; 178c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return m_data.atInRange(m_outerIndex[outer], end, inner); 179c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 180c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 181c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** \returns a non-const reference to the value of the matrix at position \a i, \a j 182c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 183c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * If the element does not exist then it is inserted via the insert(Index,Index) function 184c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * which itself turns the matrix into a non compressed form if that was not the case. 185c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 186c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * This is a O(log(nnz_j)) operation (binary search) plus the cost of insert(Index,Index) 187c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * function if the element does not already exist. 188c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath */ 189c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath inline Scalar& coeffRef(Index row, Index col) 190c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 1917faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez eigen_assert(row>=0 && row<rows() && col>=0 && col<cols()); 1927faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 193c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath const Index outer = IsRowMajor ? row : col; 194c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath const Index inner = IsRowMajor ? col : row; 195c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 196c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index start = m_outerIndex[outer]; 197c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index end = m_innerNonZeros ? m_outerIndex[outer] + m_innerNonZeros[outer] : m_outerIndex[outer+1]; 198c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath eigen_assert(end>=start && "you probably called coeffRef on a non finalized matrix"); 199c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if(end<=start) 200c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return insert(row,col); 201c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath const Index p = m_data.searchLowerIndex(start,end-1,inner); 202c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if((p<end) && (m_data.index(p)==inner)) 203c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return m_data.value(p); 204c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath else 205c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return insert(row,col); 206c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 207c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 208c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** \returns a reference to a novel non zero coefficient with coordinates \a row x \a col. 209c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * The non zero coefficient must \b not already exist. 210c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 211c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * If the matrix \c *this is in compressed mode, then \c *this is turned into uncompressed 212c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * mode while reserving room for 2 non zeros per inner vector. It is strongly recommended to first 213c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * call reserve(const SizesType &) to reserve a more appropriate number of elements per 214c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * inner vector that better match your scenario. 215c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 216c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * This function performs a sorted insertion in O(1) if the elements of each inner vector are 217c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * inserted in increasing inner index order, and in O(nnz_j) for a random insertion. 218c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 219c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath */ 2207faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez Scalar& insert(Index row, Index col) 221c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 2227faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez eigen_assert(row>=0 && row<rows() && col>=0 && col<cols()); 2237faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 224c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if(isCompressed()) 225c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 2267faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez reserve(Matrix<Index,Dynamic,1>::Constant(outerSize(), 2)); 227c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 228c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return insertUncompressed(row,col); 229c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 230c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 231c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath public: 232c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 233c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath class InnerIterator; 234c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath class ReverseInnerIterator; 235c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 236c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** Removes all non zeros but keep allocated memory */ 237c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath inline void setZero() 238c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 239c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_data.clear(); 240c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath memset(m_outerIndex, 0, (m_outerSize+1)*sizeof(Index)); 241c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if(m_innerNonZeros) 242c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath memset(m_innerNonZeros, 0, (m_outerSize)*sizeof(Index)); 243c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 244c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 245c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** \returns the number of non zero coefficients */ 246c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath inline Index nonZeros() const 247c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 248c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if(m_innerNonZeros) 249c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return innerNonZeros().sum(); 250c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return static_cast<Index>(m_data.size()); 251c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 252c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 253c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** Preallocates \a reserveSize non zeros. 254c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 255c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * Precondition: the matrix must be in compressed mode. */ 256c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath inline void reserve(Index reserveSize) 257c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 258c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath eigen_assert(isCompressed() && "This function does not make sense in non compressed mode."); 259c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_data.reserve(reserveSize); 260c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 261c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 262c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath #ifdef EIGEN_PARSED_BY_DOXYGEN 263c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** Preallocates \a reserveSize[\c j] non zeros for each column (resp. row) \c j. 264c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 265c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * This function turns the matrix in non-compressed mode */ 266c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath template<class SizesType> 267c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath inline void reserve(const SizesType& reserveSizes); 268c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath #else 269c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath template<class SizesType> 270c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath inline void reserve(const SizesType& reserveSizes, const typename SizesType::value_type& enableif = typename SizesType::value_type()) 271c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 272c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath EIGEN_UNUSED_VARIABLE(enableif); 273c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath reserveInnerVectors(reserveSizes); 274c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 275c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath template<class SizesType> 276c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath inline void reserve(const SizesType& reserveSizes, const typename SizesType::Scalar& enableif = 277c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath #if (!defined(_MSC_VER)) || (_MSC_VER>=1500) // MSVC 2005 fails to compile with this typename 278c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typename 279c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath #endif 280c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath SizesType::Scalar()) 281c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 282c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath EIGEN_UNUSED_VARIABLE(enableif); 283c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath reserveInnerVectors(reserveSizes); 284c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 285c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath #endif // EIGEN_PARSED_BY_DOXYGEN 286c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath protected: 287c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath template<class SizesType> 288c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath inline void reserveInnerVectors(const SizesType& reserveSizes) 289c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 290c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if(isCompressed()) 291c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 292c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath std::size_t totalReserveSize = 0; 293c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // turn the matrix into non-compressed mode 2947faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez m_innerNonZeros = static_cast<Index*>(std::malloc(m_outerSize * sizeof(Index))); 2957faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez if (!m_innerNonZeros) internal::throw_std_bad_alloc(); 296c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 297c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // temporarily use m_innerSizes to hold the new starting points. 298c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index* newOuterIndex = m_innerNonZeros; 299c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 300c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index count = 0; 301c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath for(Index j=0; j<m_outerSize; ++j) 302c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 303c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath newOuterIndex[j] = count; 304c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath count += reserveSizes[j] + (m_outerIndex[j+1]-m_outerIndex[j]); 305c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath totalReserveSize += reserveSizes[j]; 306c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 307c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_data.reserve(totalReserveSize); 3087faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez Index previousOuterIndex = m_outerIndex[m_outerSize]; 3097faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez for(Index j=m_outerSize-1; j>=0; --j) 310c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 3117faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez Index innerNNZ = previousOuterIndex - m_outerIndex[j]; 3127faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez for(Index i=innerNNZ-1; i>=0; --i) 313c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 314c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_data.index(newOuterIndex[j]+i) = m_data.index(m_outerIndex[j]+i); 315c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_data.value(newOuterIndex[j]+i) = m_data.value(m_outerIndex[j]+i); 316c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 317c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath previousOuterIndex = m_outerIndex[j]; 318c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_outerIndex[j] = newOuterIndex[j]; 319c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_innerNonZeros[j] = innerNNZ; 320c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 321c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_outerIndex[m_outerSize] = m_outerIndex[m_outerSize-1] + m_innerNonZeros[m_outerSize-1] + reserveSizes[m_outerSize-1]; 322c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 323c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_data.resize(m_outerIndex[m_outerSize]); 324c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 325c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath else 326c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 3277faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez Index* newOuterIndex = static_cast<Index*>(std::malloc((m_outerSize+1)*sizeof(Index))); 3287faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez if (!newOuterIndex) internal::throw_std_bad_alloc(); 3297faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 330c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index count = 0; 331c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath for(Index j=0; j<m_outerSize; ++j) 332c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 333c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath newOuterIndex[j] = count; 334c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index alreadyReserved = (m_outerIndex[j+1]-m_outerIndex[j]) - m_innerNonZeros[j]; 3357faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez Index toReserve = std::max<Index>(reserveSizes[j], alreadyReserved); 336c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath count += toReserve + m_innerNonZeros[j]; 337c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 338c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath newOuterIndex[m_outerSize] = count; 339c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 340c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_data.resize(count); 3417faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez for(Index j=m_outerSize-1; j>=0; --j) 342c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 3437faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez Index offset = newOuterIndex[j] - m_outerIndex[j]; 344c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if(offset>0) 345c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 3467faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez Index innerNNZ = m_innerNonZeros[j]; 3477faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez for(Index i=innerNNZ-1; i>=0; --i) 348c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 349c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_data.index(newOuterIndex[j]+i) = m_data.index(m_outerIndex[j]+i); 350c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_data.value(newOuterIndex[j]+i) = m_data.value(m_outerIndex[j]+i); 351c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 352c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 353c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 354c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 355c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath std::swap(m_outerIndex, newOuterIndex); 3567faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez std::free(newOuterIndex); 357c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 358c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 359c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 360c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath public: 361c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 362c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath //--- low level purely coherent filling --- 363c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 364c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** \internal 365c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \returns a reference to the non zero coefficient at position \a row, \a col assuming that: 366c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * - the nonzero does not already exist 367c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * - the new coefficient is the last one according to the storage order 368c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 369c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * Before filling a given inner vector you must call the statVec(Index) function. 370c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 371c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * After an insertion session, you should call the finalize() function. 372c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 373c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \sa insert, insertBackByOuterInner, startVec */ 374c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath inline Scalar& insertBack(Index row, Index col) 375c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 376c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return insertBackByOuterInner(IsRowMajor?row:col, IsRowMajor?col:row); 377c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 378c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 379c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** \internal 380c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \sa insertBack, startVec */ 381c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath inline Scalar& insertBackByOuterInner(Index outer, Index inner) 382c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 383c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath eigen_assert(size_t(m_outerIndex[outer+1]) == m_data.size() && "Invalid ordered insertion (invalid outer index)"); 384c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath eigen_assert( (m_outerIndex[outer+1]-m_outerIndex[outer]==0 || m_data.index(m_data.size()-1)<inner) && "Invalid ordered insertion (invalid inner index)"); 385c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index p = m_outerIndex[outer+1]; 386c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ++m_outerIndex[outer+1]; 387c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_data.append(0, inner); 388c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return m_data.value(p); 389c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 390c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 391c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** \internal 392c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \warning use it only if you know what you are doing */ 393c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath inline Scalar& insertBackByOuterInnerUnordered(Index outer, Index inner) 394c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 395c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index p = m_outerIndex[outer+1]; 396c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ++m_outerIndex[outer+1]; 397c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_data.append(0, inner); 398c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return m_data.value(p); 399c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 400c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 401c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** \internal 402c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \sa insertBack, insertBackByOuterInner */ 403c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath inline void startVec(Index outer) 404c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 4057faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez eigen_assert(m_outerIndex[outer]==Index(m_data.size()) && "You must call startVec for each inner vector sequentially"); 406c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath eigen_assert(m_outerIndex[outer+1]==0 && "You must call startVec for each inner vector sequentially"); 407c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_outerIndex[outer+1] = m_outerIndex[outer]; 408c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 409c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 410c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** \internal 411c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * Must be called after inserting a set of non zero entries using the low level compressed API. 412c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath */ 413c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath inline void finalize() 414c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 415c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if(isCompressed()) 416c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 417c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index size = static_cast<Index>(m_data.size()); 418c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index i = m_outerSize; 419c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // find the last filled column 420c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath while (i>=0 && m_outerIndex[i]==0) 421c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath --i; 422c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ++i; 423c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath while (i<=m_outerSize) 424c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 425c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_outerIndex[i] = size; 426c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ++i; 427c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 428c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 429c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 430c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 431c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath //--- 432c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 433c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath template<typename InputIterators> 434c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath void setFromTriplets(const InputIterators& begin, const InputIterators& end); 435c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 436c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath void sumupDuplicates(); 437c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 438c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath //--- 439c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 440c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** \internal 441c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * same as insert(Index,Index) except that the indices are given relative to the storage order */ 4427faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez Scalar& insertByOuterInner(Index j, Index i) 443c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 444c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return insert(IsRowMajor ? j : i, IsRowMajor ? i : j); 445c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 446c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 447c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** Turns the matrix into the \em compressed format. 448c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath */ 449c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath void makeCompressed() 450c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 451c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if(isCompressed()) 452c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return; 453c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 454c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index oldStart = m_outerIndex[1]; 455c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_outerIndex[1] = m_innerNonZeros[0]; 456c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath for(Index j=1; j<m_outerSize; ++j) 457c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 458c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index nextOldStart = m_outerIndex[j+1]; 4597faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez Index offset = oldStart - m_outerIndex[j]; 460c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if(offset>0) 461c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 462c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath for(Index k=0; k<m_innerNonZeros[j]; ++k) 463c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 464c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_data.index(m_outerIndex[j]+k) = m_data.index(oldStart+k); 465c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_data.value(m_outerIndex[j]+k) = m_data.value(oldStart+k); 466c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 467c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 468c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_outerIndex[j+1] = m_outerIndex[j] + m_innerNonZeros[j]; 469c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath oldStart = nextOldStart; 470c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 4717faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez std::free(m_innerNonZeros); 472c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_innerNonZeros = 0; 473c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_data.resize(m_outerIndex[m_outerSize]); 474c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_data.squeeze(); 475c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 476c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 4777faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez /** Turns the matrix into the uncompressed mode */ 4787faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez void uncompress() 4797faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez { 4807faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez if(m_innerNonZeros != 0) 4817faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez return; 4827faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez m_innerNonZeros = static_cast<Index*>(std::malloc(m_outerSize * sizeof(Index))); 4837faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez for (Index i = 0; i < m_outerSize; i++) 4847faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez { 4857faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez m_innerNonZeros[i] = m_outerIndex[i+1] - m_outerIndex[i]; 4867faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez } 4877faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez } 4887faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 489c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** Suppresses all nonzeros which are \b much \b smaller \b than \a reference under the tolerence \a epsilon */ 4907faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez void prune(const Scalar& reference, const RealScalar& epsilon = NumTraits<RealScalar>::dummy_precision()) 491c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 492c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath prune(default_prunning_func(reference,epsilon)); 493c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 494c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 495c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** Turns the matrix into compressed format, and suppresses all nonzeros which do not satisfy the predicate \a keep. 496c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * The functor type \a KeepFunc must implement the following function: 497c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \code 498c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * bool operator() (const Index& row, const Index& col, const Scalar& value) const; 499c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \endcode 500c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \sa prune(Scalar,RealScalar) 501c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath */ 502c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath template<typename KeepFunc> 503c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath void prune(const KeepFunc& keep = KeepFunc()) 504c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 505c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // TODO optimize the uncompressed mode to avoid moving and allocating the data twice 506c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // TODO also implement a unit test 507c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath makeCompressed(); 508c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 509c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index k = 0; 510c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath for(Index j=0; j<m_outerSize; ++j) 511c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 512c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index previousStart = m_outerIndex[j]; 513c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_outerIndex[j] = k; 514c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index end = m_outerIndex[j+1]; 515c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath for(Index i=previousStart; i<end; ++i) 516c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 517c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if(keep(IsRowMajor?j:m_data.index(i), IsRowMajor?m_data.index(i):j, m_data.value(i))) 518c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 519c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_data.value(k) = m_data.value(i); 520c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_data.index(k) = m_data.index(i); 521c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ++k; 522c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 523c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 524c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 525c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_outerIndex[m_outerSize] = k; 526c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_data.resize(k,0); 527c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 528c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 5297faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez /** Resizes the matrix to a \a rows x \a cols matrix leaving old values untouched. 5307faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez * \sa resizeNonZeros(Index), reserve(), setZero() 5317faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez */ 5327faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez void conservativeResize(Index rows, Index cols) 5337faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez { 5347faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez // No change 5357faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez if (this->rows() == rows && this->cols() == cols) return; 5367faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 5377faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez // If one dimension is null, then there is nothing to be preserved 5387faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez if(rows==0 || cols==0) return resize(rows,cols); 5397faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 5407faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez Index innerChange = IsRowMajor ? cols - this->cols() : rows - this->rows(); 5417faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez Index outerChange = IsRowMajor ? rows - this->rows() : cols - this->cols(); 5427faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez Index newInnerSize = IsRowMajor ? cols : rows; 5437faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 5447faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez // Deals with inner non zeros 5457faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez if (m_innerNonZeros) 5467faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez { 5477faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez // Resize m_innerNonZeros 5487faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez Index *newInnerNonZeros = static_cast<Index*>(std::realloc(m_innerNonZeros, (m_outerSize + outerChange) * sizeof(Index))); 5497faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez if (!newInnerNonZeros) internal::throw_std_bad_alloc(); 5507faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez m_innerNonZeros = newInnerNonZeros; 5517faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 5527faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez for(Index i=m_outerSize; i<m_outerSize+outerChange; i++) 5537faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez m_innerNonZeros[i] = 0; 5547faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez } 5557faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez else if (innerChange < 0) 5567faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez { 5577faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez // Inner size decreased: allocate a new m_innerNonZeros 5587faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez m_innerNonZeros = static_cast<Index*>(std::malloc((m_outerSize+outerChange+1) * sizeof(Index))); 5597faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez if (!m_innerNonZeros) internal::throw_std_bad_alloc(); 5607faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez for(Index i = 0; i < m_outerSize; i++) 5617faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez m_innerNonZeros[i] = m_outerIndex[i+1] - m_outerIndex[i]; 5627faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez } 5637faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 5647faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez // Change the m_innerNonZeros in case of a decrease of inner size 5657faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez if (m_innerNonZeros && innerChange < 0) 5667faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez { 5677faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez for(Index i = 0; i < m_outerSize + (std::min)(outerChange, Index(0)); i++) 5687faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez { 5697faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez Index &n = m_innerNonZeros[i]; 5707faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez Index start = m_outerIndex[i]; 5717faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez while (n > 0 && m_data.index(start+n-1) >= newInnerSize) --n; 5727faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez } 5737faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez } 5747faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 5757faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez m_innerSize = newInnerSize; 5767faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 5777faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez // Re-allocate outer index structure if necessary 5787faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez if (outerChange == 0) 5797faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez return; 5807faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 5817faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez Index *newOuterIndex = static_cast<Index*>(std::realloc(m_outerIndex, (m_outerSize + outerChange + 1) * sizeof(Index))); 5827faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez if (!newOuterIndex) internal::throw_std_bad_alloc(); 5837faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez m_outerIndex = newOuterIndex; 5847faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez if (outerChange > 0) 5857faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez { 5867faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez Index last = m_outerSize == 0 ? 0 : m_outerIndex[m_outerSize]; 5877faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez for(Index i=m_outerSize; i<m_outerSize+outerChange+1; i++) 5887faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez m_outerIndex[i] = last; 5897faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez } 5907faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez m_outerSize += outerChange; 5917faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez } 5927faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 593c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** Resizes the matrix to a \a rows x \a cols matrix and initializes it to zero. 594c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \sa resizeNonZeros(Index), reserve(), setZero() 595c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath */ 596c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath void resize(Index rows, Index cols) 597c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 598c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath const Index outerSize = IsRowMajor ? rows : cols; 599c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_innerSize = IsRowMajor ? cols : rows; 600c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_data.clear(); 601c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if (m_outerSize != outerSize || m_outerSize==0) 602c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 6037faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez std::free(m_outerIndex); 6047faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez m_outerIndex = static_cast<Index*>(std::malloc((outerSize + 1) * sizeof(Index))); 6057faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez if (!m_outerIndex) internal::throw_std_bad_alloc(); 6067faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 607c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_outerSize = outerSize; 608c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 609c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if(m_innerNonZeros) 610c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 6117faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez std::free(m_innerNonZeros); 612c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_innerNonZeros = 0; 613c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 614c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath memset(m_outerIndex, 0, (m_outerSize+1)*sizeof(Index)); 615c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 616c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 617c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** \internal 618c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * Resize the nonzero vector to \a size */ 619c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath void resizeNonZeros(Index size) 620c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 621c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // TODO remove this function 622c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_data.resize(size); 623c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 624c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 625c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** \returns a const expression of the diagonal coefficients */ 626c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath const Diagonal<const SparseMatrix> diagonal() const { return *this; } 627c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 628c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** Default constructor yielding an empty \c 0 \c x \c 0 matrix */ 629c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath inline SparseMatrix() 630c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath : m_outerSize(-1), m_innerSize(0), m_outerIndex(0), m_innerNonZeros(0) 631c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 632c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath check_template_parameters(); 633c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath resize(0, 0); 634c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 635c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 636c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** Constructs a \a rows \c x \a cols empty matrix */ 637c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath inline SparseMatrix(Index rows, Index cols) 638c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath : m_outerSize(0), m_innerSize(0), m_outerIndex(0), m_innerNonZeros(0) 639c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 640c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath check_template_parameters(); 641c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath resize(rows, cols); 642c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 643c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 644c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** Constructs a sparse matrix from the sparse expression \a other */ 645c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath template<typename OtherDerived> 646c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath inline SparseMatrix(const SparseMatrixBase<OtherDerived>& other) 647c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath : m_outerSize(0), m_innerSize(0), m_outerIndex(0), m_innerNonZeros(0) 648c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 6497faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez EIGEN_STATIC_ASSERT((internal::is_same<Scalar, typename OtherDerived::Scalar>::value), 6507faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY) 651c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath check_template_parameters(); 652c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath *this = other.derived(); 653c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 6547faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 6557faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez /** Constructs a sparse matrix from the sparse selfadjoint view \a other */ 6567faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez template<typename OtherDerived, unsigned int UpLo> 6577faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez inline SparseMatrix(const SparseSelfAdjointView<OtherDerived, UpLo>& other) 6587faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez : m_outerSize(0), m_innerSize(0), m_outerIndex(0), m_innerNonZeros(0) 6597faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez { 6607faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez check_template_parameters(); 6617faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez *this = other; 6627faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez } 663c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 664c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** Copy constructor (it performs a deep copy) */ 665c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath inline SparseMatrix(const SparseMatrix& other) 666c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath : Base(), m_outerSize(0), m_innerSize(0), m_outerIndex(0), m_innerNonZeros(0) 667c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 668c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath check_template_parameters(); 669c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath *this = other.derived(); 670c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 671c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 6727faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez /** \brief Copy constructor with in-place evaluation */ 6737faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez template<typename OtherDerived> 6747faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez SparseMatrix(const ReturnByValue<OtherDerived>& other) 6757faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez : Base(), m_outerSize(0), m_innerSize(0), m_outerIndex(0), m_innerNonZeros(0) 6767faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez { 6777faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez check_template_parameters(); 6787faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez initAssignment(other); 6797faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez other.evalTo(*this); 6807faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez } 6817faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 682c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** Swaps the content of two sparse matrices of the same type. 683c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * This is a fast operation that simply swaps the underlying pointers and parameters. */ 684c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath inline void swap(SparseMatrix& other) 685c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 686c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath //EIGEN_DBG_SPARSE(std::cout << "SparseMatrix:: swap\n"); 687c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath std::swap(m_outerIndex, other.m_outerIndex); 688c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath std::swap(m_innerSize, other.m_innerSize); 689c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath std::swap(m_outerSize, other.m_outerSize); 690c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath std::swap(m_innerNonZeros, other.m_innerNonZeros); 691c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_data.swap(other.m_data); 692c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 693c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 6947faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez /** Sets *this to the identity matrix */ 6957faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez inline void setIdentity() 6967faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez { 6977faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez eigen_assert(rows() == cols() && "ONLY FOR SQUARED MATRICES"); 6987faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez this->m_data.resize(rows()); 6997faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez Eigen::Map<Matrix<Index, Dynamic, 1> >(&this->m_data.index(0), rows()).setLinSpaced(0, rows()-1); 7007faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez Eigen::Map<Matrix<Scalar, Dynamic, 1> >(&this->m_data.value(0), rows()).setOnes(); 7017faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez Eigen::Map<Matrix<Index, Dynamic, 1> >(this->m_outerIndex, rows()+1).setLinSpaced(0, rows()); 7027faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez } 703c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath inline SparseMatrix& operator=(const SparseMatrix& other) 704c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 705c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if (other.isRValue()) 706c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 707c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath swap(other.const_cast_derived()); 708c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 7097faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez else if(this!=&other) 710c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 711c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath initAssignment(other); 712c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if(other.isCompressed()) 713c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 714c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath memcpy(m_outerIndex, other.m_outerIndex, (m_outerSize+1)*sizeof(Index)); 715c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_data = other.m_data; 716c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 717c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath else 718c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 719c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Base::operator=(other); 720c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 721c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 722c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return *this; 723c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 724c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 725c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath #ifndef EIGEN_PARSED_BY_DOXYGEN 726c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath template<typename Lhs, typename Rhs> 727c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath inline SparseMatrix& operator=(const SparseSparseProduct<Lhs,Rhs>& product) 728c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { return Base::operator=(product); } 729c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 730c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath template<typename OtherDerived> 731c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath inline SparseMatrix& operator=(const ReturnByValue<OtherDerived>& other) 7327faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez { 7337faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez initAssignment(other); 7347faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez return Base::operator=(other.derived()); 7357faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez } 736c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 737c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath template<typename OtherDerived> 738c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath inline SparseMatrix& operator=(const EigenBase<OtherDerived>& other) 739c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { return Base::operator=(other.derived()); } 740c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath #endif 741c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 742c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath template<typename OtherDerived> 7437faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez EIGEN_DONT_INLINE SparseMatrix& operator=(const SparseMatrixBase<OtherDerived>& other); 744c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 745c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath friend std::ostream & operator << (std::ostream & s, const SparseMatrix& m) 746c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 747c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath EIGEN_DBG_SPARSE( 748c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath s << "Nonzero entries:\n"; 749c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if(m.isCompressed()) 750c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath for (Index i=0; i<m.nonZeros(); ++i) 751c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath s << "(" << m.m_data.value(i) << "," << m.m_data.index(i) << ") "; 752c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath else 753c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath for (Index i=0; i<m.outerSize(); ++i) 754c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 7557faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez Index p = m.m_outerIndex[i]; 7567faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez Index pe = m.m_outerIndex[i]+m.m_innerNonZeros[i]; 757c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index k=p; 758c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath for (; k<pe; ++k) 759c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath s << "(" << m.m_data.value(k) << "," << m.m_data.index(k) << ") "; 760c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath for (; k<m.m_outerIndex[i+1]; ++k) 761c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath s << "(_,_) "; 762c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 763c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath s << std::endl; 764c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath s << std::endl; 765c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath s << "Outer pointers:\n"; 766c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath for (Index i=0; i<m.outerSize(); ++i) 767c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath s << m.m_outerIndex[i] << " "; 768c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath s << " $" << std::endl; 769c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if(!m.isCompressed()) 770c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 771c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath s << "Inner non zeros:\n"; 772c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath for (Index i=0; i<m.outerSize(); ++i) 773c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath s << m.m_innerNonZeros[i] << " "; 774c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath s << " $" << std::endl; 775c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 776c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath s << std::endl; 777c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ); 778c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath s << static_cast<const SparseMatrixBase<SparseMatrix>&>(m); 779c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return s; 780c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 781c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 782c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** Destructor */ 783c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath inline ~SparseMatrix() 784c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 7857faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez std::free(m_outerIndex); 7867faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez std::free(m_innerNonZeros); 787c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 788c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 789c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#ifndef EIGEN_PARSED_BY_DOXYGEN 790c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** Overloaded for performance */ 791c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Scalar sum() const; 792c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#endif 793c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 794c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath# ifdef EIGEN_SPARSEMATRIX_PLUGIN 795c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath# include EIGEN_SPARSEMATRIX_PLUGIN 796c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath# endif 797c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 798c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathprotected: 799c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 800c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath template<typename Other> 801c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath void initAssignment(const Other& other) 802c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 803c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath resize(other.rows(), other.cols()); 804c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if(m_innerNonZeros) 805c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 8067faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez std::free(m_innerNonZeros); 807c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_innerNonZeros = 0; 808c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 809c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 810c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 811c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** \internal 812c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \sa insert(Index,Index) */ 8137faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez EIGEN_DONT_INLINE Scalar& insertCompressed(Index row, Index col); 814c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 815c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** \internal 816c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * A vector object that is equal to 0 everywhere but v at the position i */ 817c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath class SingletonVector 818c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 819c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index m_index; 820c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index m_value; 821c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath public: 822c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef Index value_type; 823c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath SingletonVector(Index i, Index v) 824c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath : m_index(i), m_value(v) 825c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath {} 826c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 827c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index operator[](Index i) const { return i==m_index ? m_value : 0; } 828c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath }; 829c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 830c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** \internal 831c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \sa insert(Index,Index) */ 8327faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez EIGEN_DONT_INLINE Scalar& insertUncompressed(Index row, Index col); 833c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 834c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathpublic: 835c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath /** \internal 836c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \sa insert(Index,Index) */ 8377faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez EIGEN_STRONG_INLINE Scalar& insertBackUncompressed(Index row, Index col) 838c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 839c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath const Index outer = IsRowMajor ? row : col; 840c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath const Index inner = IsRowMajor ? col : row; 841c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 842c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath eigen_assert(!isCompressed()); 843c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath eigen_assert(m_innerNonZeros[outer]<=(m_outerIndex[outer+1] - m_outerIndex[outer])); 844c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 8457faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez Index p = m_outerIndex[outer] + m_innerNonZeros[outer]++; 846c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_data.index(p) = inner; 847c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return (m_data.value(p) = 0); 848c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 849c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 850c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathprivate: 851c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath static void check_template_parameters() 852c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 853c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath EIGEN_STATIC_ASSERT(NumTraits<Index>::IsSigned,THE_INDEX_TYPE_MUST_BE_A_SIGNED_TYPE); 8547faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez EIGEN_STATIC_ASSERT((Options&(ColMajor|RowMajor))==Options,INVALID_MATRIX_TEMPLATE_PARAMETERS); 855c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 856c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 857c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath struct default_prunning_func { 8587faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez default_prunning_func(const Scalar& ref, const RealScalar& eps) : reference(ref), epsilon(eps) {} 859c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath inline bool operator() (const Index&, const Index&, const Scalar& value) const 860c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 861c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath return !internal::isMuchSmallerThan(value, reference, epsilon); 862c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 863c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Scalar reference; 864c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath RealScalar epsilon; 865c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath }; 866c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 867c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 868c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Scalar, int _Options, typename _Index> 869c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathclass SparseMatrix<Scalar,_Options,_Index>::InnerIterator 870c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 871c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath public: 872c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath InnerIterator(const SparseMatrix& mat, Index outer) 873c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath : m_values(mat.valuePtr()), m_indices(mat.innerIndexPtr()), m_outer(outer), m_id(mat.m_outerIndex[outer]) 874c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 875c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if(mat.isCompressed()) 876c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_end = mat.m_outerIndex[outer+1]; 877c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath else 878c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_end = m_id + mat.m_innerNonZeros[outer]; 879c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 880c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 881c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath inline InnerIterator& operator++() { m_id++; return *this; } 882c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 883c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath inline const Scalar& value() const { return m_values[m_id]; } 884c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath inline Scalar& valueRef() { return const_cast<Scalar&>(m_values[m_id]); } 885c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 886c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath inline Index index() const { return m_indices[m_id]; } 887c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath inline Index outer() const { return m_outer; } 888c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath inline Index row() const { return IsRowMajor ? m_outer : index(); } 889c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath inline Index col() const { return IsRowMajor ? index() : m_outer; } 890c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 891c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath inline operator bool() const { return (m_id < m_end); } 892c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 893c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath protected: 894c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath const Scalar* m_values; 895c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath const Index* m_indices; 896c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath const Index m_outer; 897c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index m_id; 898c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index m_end; 899c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 900c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 901c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Scalar, int _Options, typename _Index> 902c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathclass SparseMatrix<Scalar,_Options,_Index>::ReverseInnerIterator 903c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 904c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath public: 905c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ReverseInnerIterator(const SparseMatrix& mat, Index outer) 906c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath : m_values(mat.valuePtr()), m_indices(mat.innerIndexPtr()), m_outer(outer), m_start(mat.m_outerIndex[outer]) 907c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 908c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if(mat.isCompressed()) 909c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_id = mat.m_outerIndex[outer+1]; 910c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath else 911c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_id = m_start + mat.m_innerNonZeros[outer]; 912c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 913c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 914c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath inline ReverseInnerIterator& operator--() { --m_id; return *this; } 915c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 916c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath inline const Scalar& value() const { return m_values[m_id-1]; } 917c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath inline Scalar& valueRef() { return const_cast<Scalar&>(m_values[m_id-1]); } 918c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 919c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath inline Index index() const { return m_indices[m_id-1]; } 920c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath inline Index outer() const { return m_outer; } 921c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath inline Index row() const { return IsRowMajor ? m_outer : index(); } 922c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath inline Index col() const { return IsRowMajor ? index() : m_outer; } 923c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 924c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath inline operator bool() const { return (m_id > m_start); } 925c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 926c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath protected: 927c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath const Scalar* m_values; 928c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath const Index* m_indices; 929c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath const Index m_outer; 930c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index m_id; 931c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath const Index m_start; 932c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath}; 933c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 934c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathnamespace internal { 935c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 936c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename InputIterator, typename SparseMatrixType> 937c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathvoid set_from_triplets(const InputIterator& begin, const InputIterator& end, SparseMatrixType& mat, int Options = 0) 938c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 939c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath EIGEN_UNUSED_VARIABLE(Options); 940c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath enum { IsRowMajor = SparseMatrixType::IsRowMajor }; 941c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef typename SparseMatrixType::Scalar Scalar; 942c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef typename SparseMatrixType::Index Index; 9437faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez SparseMatrix<Scalar,IsRowMajor?ColMajor:RowMajor,Index> trMat(mat.rows(),mat.cols()); 944c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 9457faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez if(begin!=end) 9467faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez { 9477faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez // pass 1: count the nnz per inner-vector 9487faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez Matrix<Index,Dynamic,1> wi(trMat.outerSize()); 9497faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez wi.setZero(); 9507faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez for(InputIterator it(begin); it!=end; ++it) 9517faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez { 9527faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez eigen_assert(it->row()>=0 && it->row()<mat.rows() && it->col()>=0 && it->col()<mat.cols()); 9537faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez wi(IsRowMajor ? it->col() : it->row())++; 9547faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez } 955c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 9567faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez // pass 2: insert all the elements into trMat 9577faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez trMat.reserve(wi); 9587faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez for(InputIterator it(begin); it!=end; ++it) 9597faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez trMat.insertBackUncompressed(it->row(),it->col()) = it->value(); 960c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 9617faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez // pass 3: 9627faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez trMat.sumupDuplicates(); 9637faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez } 964c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 965c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // pass 4: transposed copy -> implicit sorting 966c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath mat = trMat; 967c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} 968c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 969c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} 970c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 971c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 9727faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez/** Fill the matrix \c *this with the list of \em triplets defined by the iterator range \a begin - \a end. 973c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 974c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * A \em triplet is a tuple (i,j,value) defining a non-zero element. 975c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * The input list of triplets does not have to be sorted, and can contains duplicated elements. 976c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * In any case, the result is a \b sorted and \b compressed sparse matrix where the duplicates have been summed up. 977c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * This is a \em O(n) operation, with \em n the number of triplet elements. 978c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * The initial contents of \c *this is destroyed. 979c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * The matrix \c *this must be properly resized beforehand using the SparseMatrix(Index,Index) constructor, 980c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * or the resize(Index,Index) method. The sizes are not extracted from the triplet list. 981c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 982c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * The \a InputIterators value_type must provide the following interface: 983c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \code 984c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * Scalar value() const; // the value 985c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * Scalar row() const; // the row index i 986c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * Scalar col() const; // the column index j 987c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \endcode 988c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * See for instance the Eigen::Triplet template class. 989c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 990c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * Here is a typical usage example: 991c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \code 992c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath typedef Triplet<double> T; 993c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath std::vector<T> tripletList; 994c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath triplets.reserve(estimation_of_entries); 995c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath for(...) 996c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 997c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // ... 998c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath tripletList.push_back(T(i,j,v_ij)); 999c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 1000c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath SparseMatrixType m(rows,cols); 1001c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m.setFromTriplets(tripletList.begin(), tripletList.end()); 1002c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // m is ready to go! 1003c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \endcode 1004c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * 1005c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * \warning The list of triplets is read multiple times (at least twice). Therefore, it is not recommended to define 1006c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * an abstract iterator over a complex data-structure that would be expensive to evaluate. The triplets should rather 1007c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath * be explicitely stored into a std::vector for instance. 1008c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath */ 1009c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Scalar, int _Options, typename _Index> 1010c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename InputIterators> 1011c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathvoid SparseMatrix<Scalar,_Options,_Index>::setFromTriplets(const InputIterators& begin, const InputIterators& end) 1012c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 1013c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath internal::set_from_triplets(begin, end, *this); 1014c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} 1015c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 1016c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath/** \internal */ 1017c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathtemplate<typename Scalar, int _Options, typename _Index> 1018c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamathvoid SparseMatrix<Scalar,_Options,_Index>::sumupDuplicates() 1019c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath{ 1020c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath eigen_assert(!isCompressed()); 1021c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // TODO, in practice we should be able to use m_innerNonZeros for that task 10227faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez Matrix<Index,Dynamic,1> wi(innerSize()); 1023c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath wi.fill(-1); 1024c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index count = 0; 1025c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // for each inner-vector, wi[inner_index] will hold the position of first element into the index/value buffers 10267faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez for(Index j=0; j<outerSize(); ++j) 1027c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 1028c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index start = count; 1029c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index oldEnd = m_outerIndex[j]+m_innerNonZeros[j]; 1030c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath for(Index k=m_outerIndex[j]; k<oldEnd; ++k) 1031c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 1032c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath Index i = m_data.index(k); 1033c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath if(wi(i)>=start) 1034c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 1035c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // we already meet this entry => accumulate it 1036c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_data.value(wi(i)) += m_data.value(k); 1037c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 1038c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath else 1039c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath { 1040c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_data.value(count) = m_data.value(k); 1041c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_data.index(count) = m_data.index(k); 1042c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath wi(i) = count; 1043c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath ++count; 1044c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 1045c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 1046c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_outerIndex[j] = start; 1047c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath } 1048c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_outerIndex[m_outerSize] = count; 1049c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 1050c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath // turn the matrix into compressed form 10517faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez std::free(m_innerNonZeros); 1052c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_innerNonZeros = 0; 1053c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath m_data.resize(m_outerIndex[m_outerSize]); 1054c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} 1055c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 10567faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandeztemplate<typename Scalar, int _Options, typename _Index> 10577faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandeztemplate<typename OtherDerived> 10587faaa9f3f0df9d23790277834d426c3d992ac3baCarlos HernandezEIGEN_DONT_INLINE SparseMatrix<Scalar,_Options,_Index>& SparseMatrix<Scalar,_Options,_Index>::operator=(const SparseMatrixBase<OtherDerived>& other) 10597faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez{ 10607faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez EIGEN_STATIC_ASSERT((internal::is_same<Scalar, typename OtherDerived::Scalar>::value), 10617faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY) 10627faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 10637faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez const bool needToTranspose = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit); 10647faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez if (needToTranspose) 10657faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez { 10667faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez // two passes algorithm: 10677faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez // 1 - compute the number of coeffs per dest inner vector 10687faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez // 2 - do the actual copy/eval 10697faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez // Since each coeff of the rhs has to be evaluated twice, let's evaluate it if needed 10707faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez typedef typename internal::nested<OtherDerived,2>::type OtherCopy; 10717faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez typedef typename internal::remove_all<OtherCopy>::type _OtherCopy; 10727faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez OtherCopy otherCopy(other.derived()); 10737faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 10747faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez SparseMatrix dest(other.rows(),other.cols()); 10757faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez Eigen::Map<Matrix<Index, Dynamic, 1> > (dest.m_outerIndex,dest.outerSize()).setZero(); 10767faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 10777faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez // pass 1 10787faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez // FIXME the above copy could be merged with that pass 10797faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez for (Index j=0; j<otherCopy.outerSize(); ++j) 10807faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez for (typename _OtherCopy::InnerIterator it(otherCopy, j); it; ++it) 10817faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez ++dest.m_outerIndex[it.index()]; 10827faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 10837faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez // prefix sum 10847faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez Index count = 0; 10857faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez Matrix<Index,Dynamic,1> positions(dest.outerSize()); 10867faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez for (Index j=0; j<dest.outerSize(); ++j) 10877faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez { 10887faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez Index tmp = dest.m_outerIndex[j]; 10897faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez dest.m_outerIndex[j] = count; 10907faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez positions[j] = count; 10917faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez count += tmp; 10927faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez } 10937faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez dest.m_outerIndex[dest.outerSize()] = count; 10947faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez // alloc 10957faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez dest.m_data.resize(count); 10967faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez // pass 2 10977faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez for (Index j=0; j<otherCopy.outerSize(); ++j) 10987faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez { 10997faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez for (typename _OtherCopy::InnerIterator it(otherCopy, j); it; ++it) 11007faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez { 11017faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez Index pos = positions[it.index()]++; 11027faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez dest.m_data.index(pos) = j; 11037faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez dest.m_data.value(pos) = it.value(); 11047faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez } 11057faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez } 11067faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez this->swap(dest); 11077faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez return *this; 11087faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez } 11097faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez else 11107faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez { 11117faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez if(other.isRValue()) 11127faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez initAssignment(other.derived()); 11137faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez // there is no special optimization 11147faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez return Base::operator=(other.derived()); 11157faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez } 11167faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez} 11177faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 11187faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandeztemplate<typename _Scalar, int _Options, typename _Index> 11197faaa9f3f0df9d23790277834d426c3d992ac3baCarlos HernandezEIGEN_DONT_INLINE typename SparseMatrix<_Scalar,_Options,_Index>::Scalar& SparseMatrix<_Scalar,_Options,_Index>::insertUncompressed(Index row, Index col) 11207faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez{ 11217faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez eigen_assert(!isCompressed()); 11227faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 11237faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez const Index outer = IsRowMajor ? row : col; 11247faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez const Index inner = IsRowMajor ? col : row; 11257faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 11267faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez Index room = m_outerIndex[outer+1] - m_outerIndex[outer]; 11277faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez Index innerNNZ = m_innerNonZeros[outer]; 11287faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez if(innerNNZ>=room) 11297faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez { 11307faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez // this inner vector is full, we need to reallocate the whole buffer :( 11317faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez reserve(SingletonVector(outer,std::max<Index>(2,innerNNZ))); 11327faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez } 11337faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 11347faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez Index startId = m_outerIndex[outer]; 11357faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez Index p = startId + m_innerNonZeros[outer]; 11367faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez while ( (p > startId) && (m_data.index(p-1) > inner) ) 11377faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez { 11387faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez m_data.index(p) = m_data.index(p-1); 11397faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez m_data.value(p) = m_data.value(p-1); 11407faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez --p; 11417faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez } 11427faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez eigen_assert((p<=startId || m_data.index(p-1)!=inner) && "you cannot insert an element that already exist, you must call coeffRef to this end"); 11437faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 11447faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez m_innerNonZeros[outer]++; 11457faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 11467faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez m_data.index(p) = inner; 11477faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez return (m_data.value(p) = 0); 11487faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez} 11497faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 11507faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandeztemplate<typename _Scalar, int _Options, typename _Index> 11517faaa9f3f0df9d23790277834d426c3d992ac3baCarlos HernandezEIGEN_DONT_INLINE typename SparseMatrix<_Scalar,_Options,_Index>::Scalar& SparseMatrix<_Scalar,_Options,_Index>::insertCompressed(Index row, Index col) 11527faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez{ 11537faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez eigen_assert(isCompressed()); 11547faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 11557faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez const Index outer = IsRowMajor ? row : col; 11567faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez const Index inner = IsRowMajor ? col : row; 11577faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 11587faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez Index previousOuter = outer; 11597faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez if (m_outerIndex[outer+1]==0) 11607faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez { 11617faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez // we start a new inner vector 11627faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez while (previousOuter>=0 && m_outerIndex[previousOuter]==0) 11637faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez { 11647faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez m_outerIndex[previousOuter] = static_cast<Index>(m_data.size()); 11657faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez --previousOuter; 11667faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez } 11677faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez m_outerIndex[outer+1] = m_outerIndex[outer]; 11687faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez } 11697faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 11707faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez // here we have to handle the tricky case where the outerIndex array 11717faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez // starts with: [ 0 0 0 0 0 1 ...] and we are inserted in, e.g., 11727faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez // the 2nd inner vector... 11737faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez bool isLastVec = (!(previousOuter==-1 && m_data.size()!=0)) 11747faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez && (size_t(m_outerIndex[outer+1]) == m_data.size()); 11757faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 11767faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez size_t startId = m_outerIndex[outer]; 11777faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez // FIXME let's make sure sizeof(long int) == sizeof(size_t) 11787faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez size_t p = m_outerIndex[outer+1]; 11797faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez ++m_outerIndex[outer+1]; 11807faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 11817faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez double reallocRatio = 1; 11827faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez if (m_data.allocatedSize()<=m_data.size()) 11837faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez { 11847faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez // if there is no preallocated memory, let's reserve a minimum of 32 elements 11857faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez if (m_data.size()==0) 11867faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez { 11877faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez m_data.reserve(32); 11887faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez } 11897faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez else 11907faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez { 11917faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez // we need to reallocate the data, to reduce multiple reallocations 11927faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez // we use a smart resize algorithm based on the current filling ratio 11937faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez // in addition, we use double to avoid integers overflows 11947faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez double nnzEstimate = double(m_outerIndex[outer])*double(m_outerSize)/double(outer+1); 11957faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez reallocRatio = (nnzEstimate-double(m_data.size()))/double(m_data.size()); 11967faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez // furthermore we bound the realloc ratio to: 11977faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez // 1) reduce multiple minor realloc when the matrix is almost filled 11987faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez // 2) avoid to allocate too much memory when the matrix is almost empty 11997faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez reallocRatio = (std::min)((std::max)(reallocRatio,1.5),8.); 12007faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez } 12017faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez } 12027faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez m_data.resize(m_data.size()+1,reallocRatio); 12037faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 12047faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez if (!isLastVec) 12057faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez { 12067faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez if (previousOuter==-1) 12077faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez { 12087faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez // oops wrong guess. 12097faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez // let's correct the outer offsets 12107faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez for (Index k=0; k<=(outer+1); ++k) 12117faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez m_outerIndex[k] = 0; 12127faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez Index k=outer+1; 12137faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez while(m_outerIndex[k]==0) 12147faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez m_outerIndex[k++] = 1; 12157faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez while (k<=m_outerSize && m_outerIndex[k]!=0) 12167faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez m_outerIndex[k++]++; 12177faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez p = 0; 12187faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez --k; 12197faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez k = m_outerIndex[k]-1; 12207faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez while (k>0) 12217faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez { 12227faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez m_data.index(k) = m_data.index(k-1); 12237faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez m_data.value(k) = m_data.value(k-1); 12247faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez k--; 12257faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez } 12267faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez } 12277faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez else 12287faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez { 12297faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez // we are not inserting into the last inner vec 12307faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez // update outer indices: 12317faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez Index j = outer+2; 12327faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez while (j<=m_outerSize && m_outerIndex[j]!=0) 12337faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez m_outerIndex[j++]++; 12347faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez --j; 12357faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez // shift data of last vecs: 12367faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez Index k = m_outerIndex[j]-1; 12377faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez while (k>=Index(p)) 12387faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez { 12397faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez m_data.index(k) = m_data.index(k-1); 12407faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez m_data.value(k) = m_data.value(k-1); 12417faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez k--; 12427faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez } 12437faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez } 12447faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez } 12457faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 12467faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez while ( (p > startId) && (m_data.index(p-1) > inner) ) 12477faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez { 12487faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez m_data.index(p) = m_data.index(p-1); 12497faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez m_data.value(p) = m_data.value(p-1); 12507faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez --p; 12517faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez } 12527faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 12537faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez m_data.index(p) = inner; 12547faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez return (m_data.value(p) = 0); 12557faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez} 12567faaa9f3f0df9d23790277834d426c3d992ac3baCarlos Hernandez 1257c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath} // end namespace Eigen 1258c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath 1259c981c48f5bc9aefeffc0bcb0cc3934c2fae179ddNarayan Kamath#endif // EIGEN_SPARSEMATRIX_H 1260