// This file is part of Eigen, a lightweight C++ template library // for linear algebra. Eigen itself is part of the KDE project. // // Copyright (C) 2008 Gael Guennebaud // // Eigen is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 3 of the License, or (at your option) any later version. // // Alternatively, you can redistribute it and/or // modify it under the terms of the GNU General Public License as // published by the Free Software Foundation; either version 2 of // the License, or (at your option) any later version. // // Eigen is distributed in the hope that it will be useful, but WITHOUT ANY // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the // GNU General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License and a copy of the GNU General Public License along with // Eigen. If not, see . #ifndef EIGEN_SPARSEMATRIX_H #define EIGEN_SPARSEMATRIX_H template class SparseMatrix; /** \class SparseMatrix * * \brief Sparse matrix * * \param _Scalar the scalar type, i.e. the type of the coefficients * * See http://www.netlib.org/linalg/html_templates/node91.html for details on the storage scheme. * */ template struct ei_traits > { typedef _Scalar Scalar; enum { RowsAtCompileTime = Dynamic, ColsAtCompileTime = Dynamic, MaxRowsAtCompileTime = Dynamic, MaxColsAtCompileTime = Dynamic, Flags = 0, CoeffReadCost = NumTraits::ReadCost }; }; template class SparseMatrix : public MatrixBase > { public: EIGEN_GENERIC_PUBLIC_INTERFACE(SparseMatrix) protected: int* m_colPtrs; SparseArray m_data; int m_rows; int m_cols; inline int _rows() const { return m_rows; } inline int _cols() const { return m_cols; } inline const Scalar& _coeff(int row, int col) const { int id = m_colPtrs[col]; int end = m_colPtrs[col+1]; while (id=0 && m_colPtrs[i]==0) { m_colPtrs[i] = m_data.size(); --i; } m_colPtrs[col+1] = m_colPtrs[col]; } assert(m_colPtrs[col+1] == m_data.size()); int id = m_colPtrs[col+1]; m_colPtrs[col+1]++; m_data.append(0, row); return m_data.value(id); } inline void endFill() { int size = m_data.size(); int i = m_cols; // find the last filled column while (i>=0 && m_colPtrs[i]==0) --i; i++; while (i<=m_cols) { m_colPtrs[i] = size; ++i; } } void resize(int rows, int cols) { if (m_cols != cols) { delete[] m_colPtrs; m_colPtrs = new int [cols+1]; m_rows = rows; m_cols = cols; } } inline SparseMatrix(int rows, int cols) : m_rows(0), m_cols(0), m_colPtrs(0) { resize(rows, cols); } inline SparseMatrix& operator=(const SparseMatrix& other) { resize(other.rows(), other.cols()); m_colPtrs = other.m_colPtrs; for (int col=0; col<=cols(); ++col) m_colPtrs[col] = other.m_colPtrs[col]; m_data = other.m_data; return *this; } template inline SparseMatrix& operator=(const MatrixBase& other) { resize(other.rows(), other.cols()); startFill(std::max(m_rows,m_cols)*2); for (int col=0; col // SparseMatrix operator+(const Other& other) // { // SparseMatrix res(rows(), cols()); // res.startFill(nonZeros()*3); // for (int col=0; col()); // } // WARNING for efficiency reason it currently outputs the transposed matrix friend std::ostream & operator << (std::ostream & s, const SparseMatrix& m) { s << "Nonzero entries:\n"; for (uint i=0; i class SparseMatrix::InnerIterator { public: InnerIterator(const SparseMatrix& mat, int col) : m_matrix(mat), m_id(mat.m_colPtrs[col]), m_start(m_id), m_end(mat.m_colPtrs[col+1]) {} InnerIterator& operator++() { m_id++; return *this; } Scalar value() { return m_matrix.m_data.value(m_id); } int index() const { return m_matrix.m_data.index(m_id); } operator bool() const { return (m_id < m_end) && (m_id>=m_start); } protected: const SparseMatrix& m_matrix; int m_id; const int m_start; const int m_end; }; #endif // EIGEN_SPARSEMATRIX_H