diff options
| author | Stanislaw Halik <sthalik@misaki.pl> | 2019-03-03 21:09:10 +0100 |
|---|---|---|
| committer | Stanislaw Halik <sthalik@misaki.pl> | 2019-03-03 21:10:13 +0100 |
| commit | f0238cfb6997c4acfc2bd200de7295f3fa36968f (patch) | |
| tree | b215183760e4f615b9c1dabc1f116383b72a1b55 /eigen/unsupported/Eigen/src/SparseExtra | |
| parent | 543edd372a5193d04b3de9f23c176ab439e51b31 (diff) | |
don't index Eigen
Diffstat (limited to 'eigen/unsupported/Eigen/src/SparseExtra')
6 files changed, 0 insertions, 2454 deletions
diff --git a/eigen/unsupported/Eigen/src/SparseExtra/BlockOfDynamicSparseMatrix.h b/eigen/unsupported/Eigen/src/SparseExtra/BlockOfDynamicSparseMatrix.h deleted file mode 100644 index e9ec746..0000000 --- a/eigen/unsupported/Eigen/src/SparseExtra/BlockOfDynamicSparseMatrix.h +++ /dev/null @@ -1,122 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr> -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_SPARSE_BLOCKFORDYNAMICMATRIX_H -#define EIGEN_SPARSE_BLOCKFORDYNAMICMATRIX_H - -namespace Eigen { - -#if 0 - -// NOTE Have to be reimplemented as a specialization of BlockImpl< DynamicSparseMatrix<_Scalar, _Options, _Index>, ... > -// See SparseBlock.h for an example - - -/*************************************************************************** -* specialisation for DynamicSparseMatrix -***************************************************************************/ - -template<typename _Scalar, int _Options, typename _Index, int Size> -class SparseInnerVectorSet<DynamicSparseMatrix<_Scalar, _Options, _Index>, Size> - : public SparseMatrixBase<SparseInnerVectorSet<DynamicSparseMatrix<_Scalar, _Options, _Index>, Size> > -{ - typedef DynamicSparseMatrix<_Scalar, _Options, _Index> MatrixType; - public: - - enum { IsRowMajor = internal::traits<SparseInnerVectorSet>::IsRowMajor }; - - EIGEN_SPARSE_PUBLIC_INTERFACE(SparseInnerVectorSet) - class InnerIterator: public MatrixType::InnerIterator - { - public: - inline InnerIterator(const SparseInnerVectorSet& xpr, Index outer) - : MatrixType::InnerIterator(xpr.m_matrix, xpr.m_outerStart + outer), m_outer(outer) - {} - inline Index row() const { return IsRowMajor ? m_outer : this->index(); } - inline Index col() const { return IsRowMajor ? this->index() : m_outer; } - protected: - Index m_outer; - }; - - inline SparseInnerVectorSet(const MatrixType& matrix, Index outerStart, Index outerSize) - : m_matrix(matrix), m_outerStart(outerStart), m_outerSize(outerSize) - { - eigen_assert( (outerStart>=0) && ((outerStart+outerSize)<=matrix.outerSize()) ); - } - - inline SparseInnerVectorSet(const MatrixType& matrix, Index outer) - : m_matrix(matrix), m_outerStart(outer), m_outerSize(Size) - { - eigen_assert(Size!=Dynamic); - eigen_assert( (outer>=0) && (outer<matrix.outerSize()) ); - } - - template<typename OtherDerived> - inline SparseInnerVectorSet& operator=(const SparseMatrixBase<OtherDerived>& other) - { - if (IsRowMajor != ((OtherDerived::Flags&RowMajorBit)==RowMajorBit)) - { - // need to transpose => perform a block evaluation followed by a big swap - DynamicSparseMatrix<Scalar,IsRowMajor?RowMajorBit:0> aux(other); - *this = aux.markAsRValue(); - } - else - { - // evaluate/copy vector per vector - for (Index j=0; j<m_outerSize.value(); ++j) - { - SparseVector<Scalar,IsRowMajor ? RowMajorBit : 0> aux(other.innerVector(j)); - m_matrix.const_cast_derived()._data()[m_outerStart+j].swap(aux._data()); - } - } - return *this; - } - - inline SparseInnerVectorSet& operator=(const SparseInnerVectorSet& other) - { - return operator=<SparseInnerVectorSet>(other); - } - - Index nonZeros() const - { - Index count = 0; - for (Index j=0; j<m_outerSize.value(); ++j) - count += m_matrix._data()[m_outerStart+j].size(); - return count; - } - - const Scalar& lastCoeff() const - { - EIGEN_STATIC_ASSERT_VECTOR_ONLY(SparseInnerVectorSet); - eigen_assert(m_matrix.data()[m_outerStart].size()>0); - return m_matrix.data()[m_outerStart].vale(m_matrix.data()[m_outerStart].size()-1); - } - -// template<typename Sparse> -// inline SparseInnerVectorSet& operator=(const SparseMatrixBase<OtherDerived>& other) -// { -// return *this; -// } - - EIGEN_STRONG_INLINE Index rows() const { return IsRowMajor ? m_outerSize.value() : m_matrix.rows(); } - EIGEN_STRONG_INLINE Index cols() const { return IsRowMajor ? m_matrix.cols() : m_outerSize.value(); } - - protected: - - const typename MatrixType::Nested m_matrix; - Index m_outerStart; - const internal::variable_if_dynamic<Index, Size> m_outerSize; - -}; - -#endif - -} // end namespace Eigen - -#endif // EIGEN_SPARSE_BLOCKFORDYNAMICMATRIX_H diff --git a/eigen/unsupported/Eigen/src/SparseExtra/BlockSparseMatrix.h b/eigen/unsupported/Eigen/src/SparseExtra/BlockSparseMatrix.h deleted file mode 100644 index 536a0c3..0000000 --- a/eigen/unsupported/Eigen/src/SparseExtra/BlockSparseMatrix.h +++ /dev/null @@ -1,1079 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2013 Desire Nuentsa <desire.nuentsa_wakam@inria.fr> -// Copyright (C) 2013 Gael Guennebaud <gael.guennebaud@inria.fr> -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_SPARSEBLOCKMATRIX_H -#define EIGEN_SPARSEBLOCKMATRIX_H - -namespace Eigen { -/** \ingroup SparseCore_Module - * - * \class BlockSparseMatrix - * - * \brief A versatile sparse matrix representation where each element is a block - * - * This class provides routines to manipulate block sparse matrices stored in a - * BSR-like representation. There are two main types : - * - * 1. All blocks have the same number of rows and columns, called block size - * in the following. In this case, if this block size is known at compile time, - * it can be given as a template parameter like - * \code - * BlockSparseMatrix<Scalar, 3, ColMajor> bmat(b_rows, b_cols); - * \endcode - * Here, bmat is a b_rows x b_cols block sparse matrix - * where each coefficient is a 3x3 dense matrix. - * If the block size is fixed but will be given at runtime, - * \code - * BlockSparseMatrix<Scalar, Dynamic, ColMajor> bmat(b_rows, b_cols); - * bmat.setBlockSize(block_size); - * \endcode - * - * 2. The second case is for variable-block sparse matrices. - * Here each block has its own dimensions. The only restriction is that all the blocks - * in a row (resp. a column) should have the same number of rows (resp. of columns). - * It is thus required in this case to describe the layout of the matrix by calling - * setBlockLayout(rowBlocks, colBlocks). - * - * In any of the previous case, the matrix can be filled by calling setFromTriplets(). - * A regular sparse matrix can be converted to a block sparse matrix and vice versa. - * It is obviously required to describe the block layout beforehand by calling either - * setBlockSize() for fixed-size blocks or setBlockLayout for variable-size blocks. - * - * \tparam _Scalar The Scalar type - * \tparam _BlockAtCompileTime The block layout option. It takes the following values - * Dynamic : block size known at runtime - * a numeric number : fixed-size block known at compile time - */ -template<typename _Scalar, int _BlockAtCompileTime=Dynamic, int _Options=ColMajor, typename _StorageIndex=int> class BlockSparseMatrix; - -template<typename BlockSparseMatrixT> class BlockSparseMatrixView; - -namespace internal { -template<typename _Scalar, int _BlockAtCompileTime, int _Options, typename _Index> -struct traits<BlockSparseMatrix<_Scalar,_BlockAtCompileTime,_Options, _Index> > -{ - typedef _Scalar Scalar; - typedef _Index Index; - typedef Sparse StorageKind; // FIXME Where is it used ?? - typedef MatrixXpr XprKind; - enum { - RowsAtCompileTime = Dynamic, - ColsAtCompileTime = Dynamic, - MaxRowsAtCompileTime = Dynamic, - MaxColsAtCompileTime = Dynamic, - BlockSize = _BlockAtCompileTime, - Flags = _Options | NestByRefBit | LvalueBit, - CoeffReadCost = NumTraits<Scalar>::ReadCost, - SupportedAccessPatterns = InnerRandomAccessPattern - }; -}; -template<typename BlockSparseMatrixT> -struct traits<BlockSparseMatrixView<BlockSparseMatrixT> > -{ - typedef Ref<Matrix<typename BlockSparseMatrixT::Scalar, BlockSparseMatrixT::BlockSize, BlockSparseMatrixT::BlockSize> > Scalar; - typedef Ref<Matrix<typename BlockSparseMatrixT::RealScalar, BlockSparseMatrixT::BlockSize, BlockSparseMatrixT::BlockSize> > RealScalar; - -}; - -// Function object to sort a triplet list -template<typename Iterator, bool IsColMajor> -struct TripletComp -{ - typedef typename Iterator::value_type Triplet; - bool operator()(const Triplet& a, const Triplet& b) - { if(IsColMajor) - return ((a.col() == b.col() && a.row() < b.row()) || (a.col() < b.col())); - else - return ((a.row() == b.row() && a.col() < b.col()) || (a.row() < b.row())); - } -}; -} // end namespace internal - - -/* Proxy to view the block sparse matrix as a regular sparse matrix */ -template<typename BlockSparseMatrixT> -class BlockSparseMatrixView : public SparseMatrixBase<BlockSparseMatrixT> -{ - public: - typedef Ref<typename BlockSparseMatrixT::BlockScalar> Scalar; - typedef Ref<typename BlockSparseMatrixT::BlockRealScalar> RealScalar; - typedef typename BlockSparseMatrixT::Index Index; - typedef BlockSparseMatrixT Nested; - enum { - Flags = BlockSparseMatrixT::Options, - Options = BlockSparseMatrixT::Options, - RowsAtCompileTime = BlockSparseMatrixT::RowsAtCompileTime, - ColsAtCompileTime = BlockSparseMatrixT::ColsAtCompileTime, - MaxColsAtCompileTime = BlockSparseMatrixT::MaxColsAtCompileTime, - MaxRowsAtCompileTime = BlockSparseMatrixT::MaxRowsAtCompileTime - }; - public: - BlockSparseMatrixView(const BlockSparseMatrixT& spblockmat) - : m_spblockmat(spblockmat) - {} - - Index outerSize() const - { - return (Flags&RowMajorBit) == 1 ? this->rows() : this->cols(); - } - Index cols() const - { - return m_spblockmat.blockCols(); - } - Index rows() const - { - return m_spblockmat.blockRows(); - } - Scalar coeff(Index row, Index col) - { - return m_spblockmat.coeff(row, col); - } - Scalar coeffRef(Index row, Index col) - { - return m_spblockmat.coeffRef(row, col); - } - // Wrapper to iterate over all blocks - class InnerIterator : public BlockSparseMatrixT::BlockInnerIterator - { - public: - InnerIterator(const BlockSparseMatrixView& mat, Index outer) - : BlockSparseMatrixT::BlockInnerIterator(mat.m_spblockmat, outer) - {} - - }; - - protected: - const BlockSparseMatrixT& m_spblockmat; -}; - -// Proxy to view a regular vector as a block vector -template<typename BlockSparseMatrixT, typename VectorType> -class BlockVectorView -{ - public: - enum { - BlockSize = BlockSparseMatrixT::BlockSize, - ColsAtCompileTime = VectorType::ColsAtCompileTime, - RowsAtCompileTime = VectorType::RowsAtCompileTime, - Flags = VectorType::Flags - }; - typedef Ref<const Matrix<typename BlockSparseMatrixT::Scalar, (RowsAtCompileTime==1)? 1 : BlockSize, (ColsAtCompileTime==1)? 1 : BlockSize> >Scalar; - typedef typename BlockSparseMatrixT::Index Index; - public: - BlockVectorView(const BlockSparseMatrixT& spblockmat, const VectorType& vec) - : m_spblockmat(spblockmat),m_vec(vec) - { } - inline Index cols() const - { - return m_vec.cols(); - } - inline Index size() const - { - return m_spblockmat.blockRows(); - } - inline Scalar coeff(Index bi) const - { - Index startRow = m_spblockmat.blockRowsIndex(bi); - Index rowSize = m_spblockmat.blockRowsIndex(bi+1) - startRow; - return m_vec.middleRows(startRow, rowSize); - } - inline Scalar coeff(Index bi, Index j) const - { - Index startRow = m_spblockmat.blockRowsIndex(bi); - Index rowSize = m_spblockmat.blockRowsIndex(bi+1) - startRow; - return m_vec.block(startRow, j, rowSize, 1); - } - protected: - const BlockSparseMatrixT& m_spblockmat; - const VectorType& m_vec; -}; - -template<typename VectorType, typename Index> class BlockVectorReturn; - - -// Proxy to view a regular vector as a block vector -template<typename BlockSparseMatrixT, typename VectorType> -class BlockVectorReturn -{ - public: - enum { - ColsAtCompileTime = VectorType::ColsAtCompileTime, - RowsAtCompileTime = VectorType::RowsAtCompileTime, - Flags = VectorType::Flags - }; - typedef Ref<Matrix<typename VectorType::Scalar, RowsAtCompileTime, ColsAtCompileTime> > Scalar; - typedef typename BlockSparseMatrixT::Index Index; - public: - BlockVectorReturn(const BlockSparseMatrixT& spblockmat, VectorType& vec) - : m_spblockmat(spblockmat),m_vec(vec) - { } - inline Index size() const - { - return m_spblockmat.blockRows(); - } - inline Scalar coeffRef(Index bi) - { - Index startRow = m_spblockmat.blockRowsIndex(bi); - Index rowSize = m_spblockmat.blockRowsIndex(bi+1) - startRow; - return m_vec.middleRows(startRow, rowSize); - } - inline Scalar coeffRef(Index bi, Index j) - { - Index startRow = m_spblockmat.blockRowsIndex(bi); - Index rowSize = m_spblockmat.blockRowsIndex(bi+1) - startRow; - return m_vec.block(startRow, j, rowSize, 1); - } - - protected: - const BlockSparseMatrixT& m_spblockmat; - VectorType& m_vec; -}; - -// Block version of the sparse dense product -template<typename Lhs, typename Rhs> -class BlockSparseTimeDenseProduct; - -namespace internal { - -template<typename BlockSparseMatrixT, typename VecType> -struct traits<BlockSparseTimeDenseProduct<BlockSparseMatrixT, VecType> > -{ - typedef Dense StorageKind; - typedef MatrixXpr XprKind; - typedef typename BlockSparseMatrixT::Scalar Scalar; - typedef typename BlockSparseMatrixT::Index Index; - enum { - RowsAtCompileTime = Dynamic, - ColsAtCompileTime = Dynamic, - MaxRowsAtCompileTime = Dynamic, - MaxColsAtCompileTime = Dynamic, - Flags = 0, - CoeffReadCost = internal::traits<BlockSparseMatrixT>::CoeffReadCost - }; -}; -} // end namespace internal - -template<typename Lhs, typename Rhs> -class BlockSparseTimeDenseProduct - : public ProductBase<BlockSparseTimeDenseProduct<Lhs,Rhs>, Lhs, Rhs> -{ - public: - EIGEN_PRODUCT_PUBLIC_INTERFACE(BlockSparseTimeDenseProduct) - - BlockSparseTimeDenseProduct(const Lhs& lhs, const Rhs& rhs) : Base(lhs,rhs) - {} - - template<typename Dest> void scaleAndAddTo(Dest& dest, const typename Rhs::Scalar& alpha) const - { - BlockVectorReturn<Lhs,Dest> tmpDest(m_lhs, dest); - internal::sparse_time_dense_product( BlockSparseMatrixView<Lhs>(m_lhs), BlockVectorView<Lhs, Rhs>(m_lhs, m_rhs), tmpDest, alpha); - } - - private: - BlockSparseTimeDenseProduct& operator=(const BlockSparseTimeDenseProduct&); -}; - -template<typename _Scalar, int _BlockAtCompileTime, int _Options, typename _StorageIndex> -class BlockSparseMatrix : public SparseMatrixBase<BlockSparseMatrix<_Scalar,_BlockAtCompileTime, _Options,_StorageIndex> > -{ - public: - typedef _Scalar Scalar; - typedef typename NumTraits<Scalar>::Real RealScalar; - typedef _StorageIndex StorageIndex; - typedef typename internal::ref_selector<BlockSparseMatrix<_Scalar, _BlockAtCompileTime, _Options, _StorageIndex> >::type Nested; - - enum { - Options = _Options, - Flags = Options, - BlockSize=_BlockAtCompileTime, - RowsAtCompileTime = Dynamic, - ColsAtCompileTime = Dynamic, - MaxRowsAtCompileTime = Dynamic, - MaxColsAtCompileTime = Dynamic, - IsVectorAtCompileTime = 0, - IsColMajor = Flags&RowMajorBit ? 0 : 1 - }; - typedef Matrix<Scalar, _BlockAtCompileTime, _BlockAtCompileTime,IsColMajor ? ColMajor : RowMajor> BlockScalar; - typedef Matrix<RealScalar, _BlockAtCompileTime, _BlockAtCompileTime,IsColMajor ? ColMajor : RowMajor> BlockRealScalar; - typedef typename internal::conditional<_BlockAtCompileTime==Dynamic, Scalar, BlockScalar>::type BlockScalarReturnType; - typedef BlockSparseMatrix<Scalar, BlockSize, IsColMajor ? ColMajor : RowMajor, StorageIndex> PlainObject; - public: - // Default constructor - BlockSparseMatrix() - : m_innerBSize(0),m_outerBSize(0),m_innerOffset(0),m_outerOffset(0), - m_nonzerosblocks(0),m_values(0),m_blockPtr(0),m_indices(0), - m_outerIndex(0),m_blockSize(BlockSize) - { } - - - /** - * \brief Construct and resize - * - */ - BlockSparseMatrix(Index brow, Index bcol) - : m_innerBSize(IsColMajor ? brow : bcol), - m_outerBSize(IsColMajor ? bcol : brow), - m_innerOffset(0),m_outerOffset(0),m_nonzerosblocks(0), - m_values(0),m_blockPtr(0),m_indices(0), - m_outerIndex(0),m_blockSize(BlockSize) - { } - - /** - * \brief Copy-constructor - */ - BlockSparseMatrix(const BlockSparseMatrix& other) - : m_innerBSize(other.m_innerBSize),m_outerBSize(other.m_outerBSize), - m_nonzerosblocks(other.m_nonzerosblocks),m_nonzeros(other.m_nonzeros), - m_blockPtr(0),m_blockSize(other.m_blockSize) - { - // should we allow copying between variable-size blocks and fixed-size blocks ?? - eigen_assert(m_blockSize == BlockSize && " CAN NOT COPY BETWEEN FIXED-SIZE AND VARIABLE-SIZE BLOCKS"); - - std::copy(other.m_innerOffset, other.m_innerOffset+m_innerBSize+1, m_innerOffset); - std::copy(other.m_outerOffset, other.m_outerOffset+m_outerBSize+1, m_outerOffset); - std::copy(other.m_values, other.m_values+m_nonzeros, m_values); - - if(m_blockSize != Dynamic) - std::copy(other.m_blockPtr, other.m_blockPtr+m_nonzerosblocks, m_blockPtr); - - std::copy(other.m_indices, other.m_indices+m_nonzerosblocks, m_indices); - std::copy(other.m_outerIndex, other.m_outerIndex+m_outerBSize, m_outerIndex); - } - - friend void swap(BlockSparseMatrix& first, BlockSparseMatrix& second) - { - std::swap(first.m_innerBSize, second.m_innerBSize); - std::swap(first.m_outerBSize, second.m_outerBSize); - std::swap(first.m_innerOffset, second.m_innerOffset); - std::swap(first.m_outerOffset, second.m_outerOffset); - std::swap(first.m_nonzerosblocks, second.m_nonzerosblocks); - std::swap(first.m_nonzeros, second.m_nonzeros); - std::swap(first.m_values, second.m_values); - std::swap(first.m_blockPtr, second.m_blockPtr); - std::swap(first.m_indices, second.m_indices); - std::swap(first.m_outerIndex, second.m_outerIndex); - std::swap(first.m_BlockSize, second.m_blockSize); - } - - BlockSparseMatrix& operator=(BlockSparseMatrix other) - { - //Copy-and-swap paradigm ... avoid leaked data if thrown - swap(*this, other); - return *this; - } - - // Destructor - ~BlockSparseMatrix() - { - delete[] m_outerIndex; - delete[] m_innerOffset; - delete[] m_outerOffset; - delete[] m_indices; - delete[] m_blockPtr; - delete[] m_values; - } - - - /** - * \brief Constructor from a sparse matrix - * - */ - template<typename MatrixType> - inline BlockSparseMatrix(const MatrixType& spmat) : m_blockSize(BlockSize) - { - EIGEN_STATIC_ASSERT((m_blockSize != Dynamic), THIS_METHOD_IS_ONLY_FOR_FIXED_SIZE); - - *this = spmat; - } - - /** - * \brief Assignment from a sparse matrix with the same storage order - * - * Convert from a sparse matrix to block sparse matrix. - * \warning Before calling this function, tt is necessary to call - * either setBlockLayout() (matrices with variable-size blocks) - * or setBlockSize() (for fixed-size blocks). - */ - template<typename MatrixType> - inline BlockSparseMatrix& operator=(const MatrixType& spmat) - { - eigen_assert((m_innerBSize != 0 && m_outerBSize != 0) - && "Trying to assign to a zero-size matrix, call resize() first"); - eigen_assert(((MatrixType::Options&RowMajorBit) != IsColMajor) && "Wrong storage order"); - typedef SparseMatrix<bool,MatrixType::Options,typename MatrixType::Index> MatrixPatternType; - MatrixPatternType blockPattern(blockRows(), blockCols()); - m_nonzeros = 0; - - // First, compute the number of nonzero blocks and their locations - for(StorageIndex bj = 0; bj < m_outerBSize; ++bj) - { - // Browse each outer block and compute the structure - std::vector<bool> nzblocksFlag(m_innerBSize,false); // Record the existing blocks - blockPattern.startVec(bj); - for(StorageIndex j = blockOuterIndex(bj); j < blockOuterIndex(bj+1); ++j) - { - typename MatrixType::InnerIterator it_spmat(spmat, j); - for(; it_spmat; ++it_spmat) - { - StorageIndex bi = innerToBlock(it_spmat.index()); // Index of the current nonzero block - if(!nzblocksFlag[bi]) - { - // Save the index of this nonzero block - nzblocksFlag[bi] = true; - blockPattern.insertBackByOuterInnerUnordered(bj, bi) = true; - // Compute the total number of nonzeros (including explicit zeros in blocks) - m_nonzeros += blockOuterSize(bj) * blockInnerSize(bi); - } - } - } // end current outer block - } - blockPattern.finalize(); - - // Allocate the internal arrays - setBlockStructure(blockPattern); - - for(StorageIndex nz = 0; nz < m_nonzeros; ++nz) m_values[nz] = Scalar(0); - for(StorageIndex bj = 0; bj < m_outerBSize; ++bj) - { - // Now copy the values - for(StorageIndex j = blockOuterIndex(bj); j < blockOuterIndex(bj+1); ++j) - { - // Browse the outer block column by column (for column-major matrices) - typename MatrixType::InnerIterator it_spmat(spmat, j); - for(; it_spmat; ++it_spmat) - { - StorageIndex idx = 0; // Position of this block in the column block - StorageIndex bi = innerToBlock(it_spmat.index()); // Index of the current nonzero block - // Go to the inner block where this element belongs to - while(bi > m_indices[m_outerIndex[bj]+idx]) ++idx; // Not expensive for ordered blocks - StorageIndex idxVal;// Get the right position in the array of values for this element - if(m_blockSize == Dynamic) - { - // Offset from all blocks before ... - idxVal = m_blockPtr[m_outerIndex[bj]+idx]; - // ... and offset inside the block - idxVal += (j - blockOuterIndex(bj)) * blockOuterSize(bj) + it_spmat.index() - m_innerOffset[bi]; - } - else - { - // All blocks before - idxVal = (m_outerIndex[bj] + idx) * m_blockSize * m_blockSize; - // inside the block - idxVal += (j - blockOuterIndex(bj)) * m_blockSize + (it_spmat.index()%m_blockSize); - } - // Insert the value - m_values[idxVal] = it_spmat.value(); - } // end of this column - } // end of this block - } // end of this outer block - - return *this; - } - - /** - * \brief Set the nonzero block pattern of the matrix - * - * Given a sparse matrix describing the nonzero block pattern, - * this function prepares the internal pointers for values. - * After calling this function, any *nonzero* block (bi, bj) can be set - * with a simple call to coeffRef(bi,bj). - * - * - * \warning Before calling this function, tt is necessary to call - * either setBlockLayout() (matrices with variable-size blocks) - * or setBlockSize() (for fixed-size blocks). - * - * \param blockPattern Sparse matrix of boolean elements describing the block structure - * - * \sa setBlockLayout() \sa setBlockSize() - */ - template<typename MatrixType> - void setBlockStructure(const MatrixType& blockPattern) - { - resize(blockPattern.rows(), blockPattern.cols()); - reserve(blockPattern.nonZeros()); - - // Browse the block pattern and set up the various pointers - m_outerIndex[0] = 0; - if(m_blockSize == Dynamic) m_blockPtr[0] = 0; - for(StorageIndex nz = 0; nz < m_nonzeros; ++nz) m_values[nz] = Scalar(0); - for(StorageIndex bj = 0; bj < m_outerBSize; ++bj) - { - //Browse each outer block - - //First, copy and save the indices of nonzero blocks - //FIXME : find a way to avoid this ... - std::vector<int> nzBlockIdx; - typename MatrixType::InnerIterator it(blockPattern, bj); - for(; it; ++it) - { - nzBlockIdx.push_back(it.index()); - } - std::sort(nzBlockIdx.begin(), nzBlockIdx.end()); - - // Now, fill block indices and (eventually) pointers to blocks - for(StorageIndex idx = 0; idx < nzBlockIdx.size(); ++idx) - { - StorageIndex offset = m_outerIndex[bj]+idx; // offset in m_indices - m_indices[offset] = nzBlockIdx[idx]; - if(m_blockSize == Dynamic) - m_blockPtr[offset] = m_blockPtr[offset-1] + blockInnerSize(nzBlockIdx[idx]) * blockOuterSize(bj); - // There is no blockPtr for fixed-size blocks... not needed !??? - } - // Save the pointer to the next outer block - m_outerIndex[bj+1] = m_outerIndex[bj] + nzBlockIdx.size(); - } - } - - /** - * \brief Set the number of rows and columns blocks - */ - inline void resize(Index brow, Index bcol) - { - m_innerBSize = IsColMajor ? brow : bcol; - m_outerBSize = IsColMajor ? bcol : brow; - } - - /** - * \brief set the block size at runtime for fixed-size block layout - * - * Call this only for fixed-size blocks - */ - inline void setBlockSize(Index blockSize) - { - m_blockSize = blockSize; - } - - /** - * \brief Set the row and column block layouts, - * - * This function set the size of each row and column block. - * So this function should be used only for blocks with variable size. - * \param rowBlocks : Number of rows per row block - * \param colBlocks : Number of columns per column block - * \sa resize(), setBlockSize() - */ - inline void setBlockLayout(const VectorXi& rowBlocks, const VectorXi& colBlocks) - { - const VectorXi& innerBlocks = IsColMajor ? rowBlocks : colBlocks; - const VectorXi& outerBlocks = IsColMajor ? colBlocks : rowBlocks; - eigen_assert(m_innerBSize == innerBlocks.size() && "CHECK THE NUMBER OF ROW OR COLUMN BLOCKS"); - eigen_assert(m_outerBSize == outerBlocks.size() && "CHECK THE NUMBER OF ROW OR COLUMN BLOCKS"); - m_outerBSize = outerBlocks.size(); - // starting index of blocks... cumulative sums - m_innerOffset = new StorageIndex[m_innerBSize+1]; - m_outerOffset = new StorageIndex[m_outerBSize+1]; - m_innerOffset[0] = 0; - m_outerOffset[0] = 0; - std::partial_sum(&innerBlocks[0], &innerBlocks[m_innerBSize-1]+1, &m_innerOffset[1]); - std::partial_sum(&outerBlocks[0], &outerBlocks[m_outerBSize-1]+1, &m_outerOffset[1]); - - // Compute the total number of nonzeros - m_nonzeros = 0; - for(StorageIndex bj = 0; bj < m_outerBSize; ++bj) - for(StorageIndex bi = 0; bi < m_innerBSize; ++bi) - m_nonzeros += outerBlocks[bj] * innerBlocks[bi]; - - } - - /** - * \brief Allocate the internal array of pointers to blocks and their inner indices - * - * \note For fixed-size blocks, call setBlockSize() to set the block. - * And For variable-size blocks, call setBlockLayout() before using this function - * - * \param nonzerosblocks Number of nonzero blocks. The total number of nonzeros is - * is computed in setBlockLayout() for variable-size blocks - * \sa setBlockSize() - */ - inline void reserve(const Index nonzerosblocks) - { - eigen_assert((m_innerBSize != 0 && m_outerBSize != 0) && - "TRYING TO RESERVE ZERO-SIZE MATRICES, CALL resize() first"); - - //FIXME Should free if already allocated - m_outerIndex = new StorageIndex[m_outerBSize+1]; - - m_nonzerosblocks = nonzerosblocks; - if(m_blockSize != Dynamic) - { - m_nonzeros = nonzerosblocks * (m_blockSize * m_blockSize); - m_blockPtr = 0; - } - else - { - // m_nonzeros is already computed in setBlockLayout() - m_blockPtr = new StorageIndex[m_nonzerosblocks+1]; - } - m_indices = new StorageIndex[m_nonzerosblocks+1]; - m_values = new Scalar[m_nonzeros]; - } - - - /** - * \brief Fill values in a matrix from a triplet list. - * - * Each triplet item has a block stored in an Eigen dense matrix. - * The InputIterator class should provide the functions row(), col() and value() - * - * \note For fixed-size blocks, call setBlockSize() before this function. - * - * FIXME Do not accept duplicates - */ - template<typename InputIterator> - void setFromTriplets(const InputIterator& begin, const InputIterator& end) - { - eigen_assert((m_innerBSize!=0 && m_outerBSize !=0) && "ZERO BLOCKS, PLEASE CALL resize() before"); - - /* First, sort the triplet list - * FIXME This can be unnecessarily expensive since only the inner indices have to be sorted - * The best approach is like in SparseMatrix::setFromTriplets() - */ - internal::TripletComp<InputIterator, IsColMajor> tripletcomp; - std::sort(begin, end, tripletcomp); - - /* Count the number of rows and column blocks, - * and the number of nonzero blocks per outer dimension - */ - VectorXi rowBlocks(m_innerBSize); // Size of each block row - VectorXi colBlocks(m_outerBSize); // Size of each block column - rowBlocks.setZero(); colBlocks.setZero(); - VectorXi nzblock_outer(m_outerBSize); // Number of nz blocks per outer vector - VectorXi nz_outer(m_outerBSize); // Number of nz per outer vector...for variable-size blocks - nzblock_outer.setZero(); - nz_outer.setZero(); - for(InputIterator it(begin); it !=end; ++it) - { - eigen_assert(it->row() >= 0 && it->row() < this->blockRows() && it->col() >= 0 && it->col() < this->blockCols()); - eigen_assert((it->value().rows() == it->value().cols() && (it->value().rows() == m_blockSize)) - || (m_blockSize == Dynamic)); - - if(m_blockSize == Dynamic) - { - eigen_assert((rowBlocks[it->row()] == 0 || rowBlocks[it->row()] == it->value().rows()) && - "NON CORRESPONDING SIZES FOR ROW BLOCKS"); - eigen_assert((colBlocks[it->col()] == 0 || colBlocks[it->col()] == it->value().cols()) && - "NON CORRESPONDING SIZES FOR COLUMN BLOCKS"); - rowBlocks[it->row()] =it->value().rows(); - colBlocks[it->col()] = it->value().cols(); - } - nz_outer(IsColMajor ? it->col() : it->row()) += it->value().rows() * it->value().cols(); - nzblock_outer(IsColMajor ? it->col() : it->row())++; - } - // Allocate member arrays - if(m_blockSize == Dynamic) setBlockLayout(rowBlocks, colBlocks); - StorageIndex nzblocks = nzblock_outer.sum(); - reserve(nzblocks); - - // Temporary markers - VectorXi block_id(m_outerBSize); // To be used as a block marker during insertion - - // Setup outer index pointers and markers - m_outerIndex[0] = 0; - if (m_blockSize == Dynamic) m_blockPtr[0] = 0; - for(StorageIndex bj = 0; bj < m_outerBSize; ++bj) - { - m_outerIndex[bj+1] = m_outerIndex[bj] + nzblock_outer(bj); - block_id(bj) = m_outerIndex[bj]; - if(m_blockSize==Dynamic) - { - m_blockPtr[m_outerIndex[bj+1]] = m_blockPtr[m_outerIndex[bj]] + nz_outer(bj); - } - } - - // Fill the matrix - for(InputIterator it(begin); it!=end; ++it) - { - StorageIndex outer = IsColMajor ? it->col() : it->row(); - StorageIndex inner = IsColMajor ? it->row() : it->col(); - m_indices[block_id(outer)] = inner; - StorageIndex block_size = it->value().rows()*it->value().cols(); - StorageIndex nz_marker = blockPtr(block_id[outer]); - memcpy(&(m_values[nz_marker]), it->value().data(), block_size * sizeof(Scalar)); - if(m_blockSize == Dynamic) - { - m_blockPtr[block_id(outer)+1] = m_blockPtr[block_id(outer)] + block_size; - } - block_id(outer)++; - } - - // An alternative when the outer indices are sorted...no need to use an array of markers -// for(Index bcol = 0; bcol < m_outerBSize; ++bcol) -// { -// Index id = 0, id_nz = 0, id_nzblock = 0; -// for(InputIterator it(begin); it!=end; ++it) -// { -// while (id<bcol) // one pass should do the job unless there are empty columns -// { -// id++; -// m_outerIndex[id+1]=m_outerIndex[id]; -// } -// m_outerIndex[id+1] += 1; -// m_indices[id_nzblock]=brow; -// Index block_size = it->value().rows()*it->value().cols(); -// m_blockPtr[id_nzblock+1] = m_blockPtr[id_nzblock] + block_size; -// id_nzblock++; -// memcpy(&(m_values[id_nz]),it->value().data(), block_size*sizeof(Scalar)); -// id_nz += block_size; -// } -// while(id < m_outerBSize-1) // Empty columns at the end -// { -// id++; -// m_outerIndex[id+1]=m_outerIndex[id]; -// } -// } - } - - - /** - * \returns the number of rows - */ - inline Index rows() const - { -// return blockRows(); - return (IsColMajor ? innerSize() : outerSize()); - } - - /** - * \returns the number of cols - */ - inline Index cols() const - { -// return blockCols(); - return (IsColMajor ? outerSize() : innerSize()); - } - - inline Index innerSize() const - { - if(m_blockSize == Dynamic) return m_innerOffset[m_innerBSize]; - else return (m_innerBSize * m_blockSize) ; - } - - inline Index outerSize() const - { - if(m_blockSize == Dynamic) return m_outerOffset[m_outerBSize]; - else return (m_outerBSize * m_blockSize) ; - } - /** \returns the number of rows grouped by blocks */ - inline Index blockRows() const - { - return (IsColMajor ? m_innerBSize : m_outerBSize); - } - /** \returns the number of columns grouped by blocks */ - inline Index blockCols() const - { - return (IsColMajor ? m_outerBSize : m_innerBSize); - } - - inline Index outerBlocks() const { return m_outerBSize; } - inline Index innerBlocks() const { return m_innerBSize; } - - /** \returns the block index where outer belongs to */ - inline Index outerToBlock(Index outer) const - { - eigen_assert(outer < outerSize() && "OUTER INDEX OUT OF BOUNDS"); - - if(m_blockSize != Dynamic) - return (outer / m_blockSize); // Integer division - - StorageIndex b_outer = 0; - while(m_outerOffset[b_outer] <= outer) ++b_outer; - return b_outer - 1; - } - /** \returns the block index where inner belongs to */ - inline Index innerToBlock(Index inner) const - { - eigen_assert(inner < innerSize() && "OUTER INDEX OUT OF BOUNDS"); - - if(m_blockSize != Dynamic) - return (inner / m_blockSize); // Integer division - - StorageIndex b_inner = 0; - while(m_innerOffset[b_inner] <= inner) ++b_inner; - return b_inner - 1; - } - - /** - *\returns a reference to the (i,j) block as an Eigen Dense Matrix - */ - Ref<BlockScalar> coeffRef(Index brow, Index bcol) - { - eigen_assert(brow < blockRows() && "BLOCK ROW INDEX OUT OF BOUNDS"); - eigen_assert(bcol < blockCols() && "BLOCK nzblocksFlagCOLUMN OUT OF BOUNDS"); - - StorageIndex rsize = IsColMajor ? blockInnerSize(brow): blockOuterSize(bcol); - StorageIndex csize = IsColMajor ? blockOuterSize(bcol) : blockInnerSize(brow); - StorageIndex inner = IsColMajor ? brow : bcol; - StorageIndex outer = IsColMajor ? bcol : brow; - StorageIndex offset = m_outerIndex[outer]; - while(offset < m_outerIndex[outer+1] && m_indices[offset] != inner) - offset++; - if(m_indices[offset] == inner) - { - return Map<BlockScalar>(&(m_values[blockPtr(offset)]), rsize, csize); - } - else - { - //FIXME the block does not exist, Insert it !!!!!!!!! - eigen_assert("DYNAMIC INSERTION IS NOT YET SUPPORTED"); - } - } - - /** - * \returns the value of the (i,j) block as an Eigen Dense Matrix - */ - Map<const BlockScalar> coeff(Index brow, Index bcol) const - { - eigen_assert(brow < blockRows() && "BLOCK ROW INDEX OUT OF BOUNDS"); - eigen_assert(bcol < blockCols() && "BLOCK COLUMN OUT OF BOUNDS"); - - StorageIndex rsize = IsColMajor ? blockInnerSize(brow): blockOuterSize(bcol); - StorageIndex csize = IsColMajor ? blockOuterSize(bcol) : blockInnerSize(brow); - StorageIndex inner = IsColMajor ? brow : bcol; - StorageIndex outer = IsColMajor ? bcol : brow; - StorageIndex offset = m_outerIndex[outer]; - while(offset < m_outerIndex[outer+1] && m_indices[offset] != inner) offset++; - if(m_indices[offset] == inner) - { - return Map<const BlockScalar> (&(m_values[blockPtr(offset)]), rsize, csize); - } - else -// return BlockScalar::Zero(rsize, csize); - eigen_assert("NOT YET SUPPORTED"); - } - - // Block Matrix times vector product - template<typename VecType> - BlockSparseTimeDenseProduct<BlockSparseMatrix, VecType> operator*(const VecType& lhs) const - { - return BlockSparseTimeDenseProduct<BlockSparseMatrix, VecType>(*this, lhs); - } - - /** \returns the number of nonzero blocks */ - inline Index nonZerosBlocks() const { return m_nonzerosblocks; } - /** \returns the total number of nonzero elements, including eventual explicit zeros in blocks */ - inline Index nonZeros() const { return m_nonzeros; } - - inline BlockScalarReturnType *valuePtr() {return static_cast<BlockScalarReturnType *>(m_values);} -// inline Scalar *valuePtr(){ return m_values; } - inline StorageIndex *innerIndexPtr() {return m_indices; } - inline const StorageIndex *innerIndexPtr() const {return m_indices; } - inline StorageIndex *outerIndexPtr() {return m_outerIndex; } - inline const StorageIndex* outerIndexPtr() const {return m_outerIndex; } - - /** \brief for compatibility purposes with the SparseMatrix class */ - inline bool isCompressed() const {return true;} - /** - * \returns the starting index of the bi row block - */ - inline Index blockRowsIndex(Index bi) const - { - return IsColMajor ? blockInnerIndex(bi) : blockOuterIndex(bi); - } - - /** - * \returns the starting index of the bj col block - */ - inline Index blockColsIndex(Index bj) const - { - return IsColMajor ? blockOuterIndex(bj) : blockInnerIndex(bj); - } - - inline Index blockOuterIndex(Index bj) const - { - return (m_blockSize == Dynamic) ? m_outerOffset[bj] : (bj * m_blockSize); - } - inline Index blockInnerIndex(Index bi) const - { - return (m_blockSize == Dynamic) ? m_innerOffset[bi] : (bi * m_blockSize); - } - - // Not needed ??? - inline Index blockInnerSize(Index bi) const - { - return (m_blockSize == Dynamic) ? (m_innerOffset[bi+1] - m_innerOffset[bi]) : m_blockSize; - } - inline Index blockOuterSize(Index bj) const - { - return (m_blockSize == Dynamic) ? (m_outerOffset[bj+1]- m_outerOffset[bj]) : m_blockSize; - } - - /** - * \brief Browse the matrix by outer index - */ - class InnerIterator; // Browse column by column - - /** - * \brief Browse the matrix by block outer index - */ - class BlockInnerIterator; // Browse block by block - - friend std::ostream & operator << (std::ostream & s, const BlockSparseMatrix& m) - { - for (StorageIndex j = 0; j < m.outerBlocks(); ++j) - { - BlockInnerIterator itb(m, j); - for(; itb; ++itb) - { - s << "("<<itb.row() << ", " << itb.col() << ")\n"; - s << itb.value() <<"\n"; - } - } - s << std::endl; - return s; - } - - /** - * \returns the starting position of the block \p id in the array of values - */ - Index blockPtr(Index id) const - { - if(m_blockSize == Dynamic) return m_blockPtr[id]; - else return id * m_blockSize * m_blockSize; - //return blockDynIdx(id, typename internal::conditional<(BlockSize==Dynamic), internal::true_type, internal::false_type>::type()); - } - - - protected: -// inline Index blockDynIdx(Index id, internal::true_type) const -// { -// return m_blockPtr[id]; -// } -// inline Index blockDynIdx(Index id, internal::false_type) const -// { -// return id * BlockSize * BlockSize; -// } - - // To be implemented - // Insert a block at a particular location... need to make a room for that - Map<BlockScalar> insert(Index brow, Index bcol); - - Index m_innerBSize; // Number of block rows - Index m_outerBSize; // Number of block columns - StorageIndex *m_innerOffset; // Starting index of each inner block (size m_innerBSize+1) - StorageIndex *m_outerOffset; // Starting index of each outer block (size m_outerBSize+1) - Index m_nonzerosblocks; // Total nonzeros blocks (lower than m_innerBSize x m_outerBSize) - Index m_nonzeros; // Total nonzeros elements - Scalar *m_values; //Values stored block column after block column (size m_nonzeros) - StorageIndex *m_blockPtr; // Pointer to the beginning of each block in m_values, size m_nonzeroblocks ... null for fixed-size blocks - StorageIndex *m_indices; //Inner block indices, size m_nonzerosblocks ... OK - StorageIndex *m_outerIndex; // Starting pointer of each block column in m_indices (size m_outerBSize)... OK - Index m_blockSize; // Size of a block for fixed-size blocks, otherwise -1 -}; - -template<typename _Scalar, int _BlockAtCompileTime, int _Options, typename _StorageIndex> -class BlockSparseMatrix<_Scalar, _BlockAtCompileTime, _Options, _StorageIndex>::BlockInnerIterator -{ - public: - - enum{ - Flags = _Options - }; - - BlockInnerIterator(const BlockSparseMatrix& mat, const Index outer) - : m_mat(mat),m_outer(outer), - m_id(mat.m_outerIndex[outer]), - m_end(mat.m_outerIndex[outer+1]) - { - } - - inline BlockInnerIterator& operator++() {m_id++; return *this; } - - inline const Map<const BlockScalar> value() const - { - return Map<const BlockScalar>(&(m_mat.m_values[m_mat.blockPtr(m_id)]), - rows(),cols()); - } - inline Map<BlockScalar> valueRef() - { - return Map<BlockScalar>(&(m_mat.m_values[m_mat.blockPtr(m_id)]), - rows(),cols()); - } - // Block inner index - inline Index index() const {return m_mat.m_indices[m_id]; } - inline Index outer() const { return m_outer; } - // block row index - inline Index row() const {return index(); } - // block column index - inline Index col() const {return outer(); } - // FIXME Number of rows in the current block - inline Index rows() const { return (m_mat.m_blockSize==Dynamic) ? (m_mat.m_innerOffset[index()+1] - m_mat.m_innerOffset[index()]) : m_mat.m_blockSize; } - // Number of columns in the current block ... - inline Index cols() const { return (m_mat.m_blockSize==Dynamic) ? (m_mat.m_outerOffset[m_outer+1]-m_mat.m_outerOffset[m_outer]) : m_mat.m_blockSize;} - inline operator bool() const { return (m_id < m_end); } - - protected: - const BlockSparseMatrix<_Scalar, _BlockAtCompileTime, _Options, StorageIndex>& m_mat; - const Index m_outer; - Index m_id; - Index m_end; -}; - -template<typename _Scalar, int _BlockAtCompileTime, int _Options, typename _StorageIndex> -class BlockSparseMatrix<_Scalar, _BlockAtCompileTime, _Options, _StorageIndex>::InnerIterator -{ - public: - InnerIterator(const BlockSparseMatrix& mat, Index outer) - : m_mat(mat),m_outerB(mat.outerToBlock(outer)),m_outer(outer), - itb(mat, mat.outerToBlock(outer)), - m_offset(outer - mat.blockOuterIndex(m_outerB)) - { - if (itb) - { - m_id = m_mat.blockInnerIndex(itb.index()); - m_start = m_id; - m_end = m_mat.blockInnerIndex(itb.index()+1); - } - } - inline InnerIterator& operator++() - { - m_id++; - if (m_id >= m_end) - { - ++itb; - if (itb) - { - m_id = m_mat.blockInnerIndex(itb.index()); - m_start = m_id; - m_end = m_mat.blockInnerIndex(itb.index()+1); - } - } - return *this; - } - inline const Scalar& value() const - { - return itb.value().coeff(m_id - m_start, m_offset); - } - inline Scalar& valueRef() - { - return itb.valueRef().coeff(m_id - m_start, m_offset); - } - inline Index index() const { return m_id; } - inline Index outer() const {return m_outer; } - inline Index col() const {return outer(); } - inline Index row() const { return index();} - inline operator bool() const - { - return itb; - } - protected: - const BlockSparseMatrix& m_mat; - const Index m_outer; - const Index m_outerB; - BlockInnerIterator itb; // Iterator through the blocks - const Index m_offset; // Position of this column in the block - Index m_start; // starting inner index of this block - Index m_id; // current inner index in the block - Index m_end; // starting inner index of the next block - -}; -} // end namespace Eigen - -#endif // EIGEN_SPARSEBLOCKMATRIX_H diff --git a/eigen/unsupported/Eigen/src/SparseExtra/DynamicSparseMatrix.h b/eigen/unsupported/Eigen/src/SparseExtra/DynamicSparseMatrix.h deleted file mode 100644 index 0ffbc43..0000000 --- a/eigen/unsupported/Eigen/src/SparseExtra/DynamicSparseMatrix.h +++ /dev/null @@ -1,404 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008-2009 Gael Guennebaud <gael.guennebaud@inria.fr> -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_DYNAMIC_SPARSEMATRIX_H -#define EIGEN_DYNAMIC_SPARSEMATRIX_H - -namespace Eigen { - -/** \deprecated use a SparseMatrix in an uncompressed mode - * - * \class DynamicSparseMatrix - * - * \brief A sparse matrix class designed for matrix assembly purpose - * - * \param _Scalar the scalar type, i.e. the type of the coefficients - * - * Unlike SparseMatrix, this class provides a much higher degree of flexibility. In particular, it allows - * random read/write accesses in log(rho*outer_size) where \c rho is the probability that a coefficient is - * nonzero and outer_size is the number of columns if the matrix is column-major and the number of rows - * otherwise. - * - * Internally, the data are stored as a std::vector of compressed vector. The performances of random writes might - * decrease as the number of nonzeros per inner-vector increase. In practice, we observed very good performance - * till about 100 nonzeros/vector, and the performance remains relatively good till 500 nonzeros/vectors. - * - * \see SparseMatrix - */ - -namespace internal { -template<typename _Scalar, int _Options, typename _StorageIndex> -struct traits<DynamicSparseMatrix<_Scalar, _Options, _StorageIndex> > -{ - typedef _Scalar Scalar; - typedef _StorageIndex StorageIndex; - typedef Sparse StorageKind; - typedef MatrixXpr XprKind; - enum { - RowsAtCompileTime = Dynamic, - ColsAtCompileTime = Dynamic, - MaxRowsAtCompileTime = Dynamic, - MaxColsAtCompileTime = Dynamic, - Flags = _Options | NestByRefBit | LvalueBit, - CoeffReadCost = NumTraits<Scalar>::ReadCost, - SupportedAccessPatterns = OuterRandomAccessPattern - }; -}; -} - -template<typename _Scalar, int _Options, typename _StorageIndex> - class DynamicSparseMatrix - : public SparseMatrixBase<DynamicSparseMatrix<_Scalar, _Options, _StorageIndex> > -{ - typedef SparseMatrixBase<DynamicSparseMatrix> Base; - using Base::convert_index; - public: - EIGEN_SPARSE_PUBLIC_INTERFACE(DynamicSparseMatrix) - // FIXME: why are these operator already alvailable ??? - // EIGEN_SPARSE_INHERIT_ASSIGNMENT_OPERATOR(DynamicSparseMatrix, +=) - // EIGEN_SPARSE_INHERIT_ASSIGNMENT_OPERATOR(DynamicSparseMatrix, -=) - typedef MappedSparseMatrix<Scalar,Flags> Map; - using Base::IsRowMajor; - using Base::operator=; - enum { - Options = _Options - }; - - protected: - - typedef DynamicSparseMatrix<Scalar,(Flags&~RowMajorBit)|(IsRowMajor?RowMajorBit:0), StorageIndex> TransposedSparseMatrix; - - Index m_innerSize; - std::vector<internal::CompressedStorage<Scalar,StorageIndex> > m_data; - - public: - - inline Index rows() const { return IsRowMajor ? outerSize() : m_innerSize; } - inline Index cols() const { return IsRowMajor ? m_innerSize : outerSize(); } - inline Index innerSize() const { return m_innerSize; } - inline Index outerSize() const { return convert_index(m_data.size()); } - inline Index innerNonZeros(Index j) const { return m_data[j].size(); } - - std::vector<internal::CompressedStorage<Scalar,StorageIndex> >& _data() { return m_data; } - const std::vector<internal::CompressedStorage<Scalar,StorageIndex> >& _data() const { return m_data; } - - /** \returns the coefficient value at given position \a row, \a col - * This operation involes a log(rho*outer_size) binary search. - */ - inline Scalar coeff(Index row, Index col) const - { - const Index outer = IsRowMajor ? row : col; - const Index inner = IsRowMajor ? col : row; - return m_data[outer].at(inner); - } - - /** \returns a reference to the coefficient value at given position \a row, \a col - * This operation involes a log(rho*outer_size) binary search. If the coefficient does not - * exist yet, then a sorted insertion into a sequential buffer is performed. - */ - inline Scalar& coeffRef(Index row, Index col) - { - const Index outer = IsRowMajor ? row : col; - const Index inner = IsRowMajor ? col : row; - return m_data[outer].atWithInsertion(inner); - } - - class InnerIterator; - class ReverseInnerIterator; - - void setZero() - { - for (Index j=0; j<outerSize(); ++j) - m_data[j].clear(); - } - - /** \returns the number of non zero coefficients */ - Index nonZeros() const - { - Index res = 0; - for (Index j=0; j<outerSize(); ++j) - res += m_data[j].size(); - return res; - } - - - - void reserve(Index reserveSize = 1000) - { - if (outerSize()>0) - { - Index reserveSizePerVector = (std::max)(reserveSize/outerSize(),Index(4)); - for (Index j=0; j<outerSize(); ++j) - { - m_data[j].reserve(reserveSizePerVector); - } - } - } - - /** Does nothing: provided for compatibility with SparseMatrix */ - inline void startVec(Index /*outer*/) {} - - /** \returns a reference to the non zero coefficient at position \a row, \a col assuming that: - * - the nonzero does not already exist - * - the new coefficient is the last one of the given inner vector. - * - * \sa insert, insertBackByOuterInner */ - inline Scalar& insertBack(Index row, Index col) - { - return insertBackByOuterInner(IsRowMajor?row:col, IsRowMajor?col:row); - } - - /** \sa insertBack */ - inline Scalar& insertBackByOuterInner(Index outer, Index inner) - { - eigen_assert(outer<Index(m_data.size()) && inner<m_innerSize && "out of range"); - eigen_assert(((m_data[outer].size()==0) || (m_data[outer].index(m_data[outer].size()-1)<inner)) - && "wrong sorted insertion"); - m_data[outer].append(0, inner); - return m_data[outer].value(m_data[outer].size()-1); - } - - inline Scalar& insert(Index row, Index col) - { - const Index outer = IsRowMajor ? row : col; - const Index inner = IsRowMajor ? col : row; - - Index startId = 0; - Index id = static_cast<Index>(m_data[outer].size()) - 1; - m_data[outer].resize(id+2,1); - - while ( (id >= startId) && (m_data[outer].index(id) > inner) ) - { - m_data[outer].index(id+1) = m_data[outer].index(id); - m_data[outer].value(id+1) = m_data[outer].value(id); - --id; - } - m_data[outer].index(id+1) = inner; - m_data[outer].value(id+1) = 0; - return m_data[outer].value(id+1); - } - - /** Does nothing: provided for compatibility with SparseMatrix */ - inline void finalize() {} - - /** Suppress all nonzeros which are smaller than \a reference under the tolerence \a epsilon */ - void prune(Scalar reference, RealScalar epsilon = NumTraits<RealScalar>::dummy_precision()) - { - for (Index j=0; j<outerSize(); ++j) - m_data[j].prune(reference,epsilon); - } - - /** Resize the matrix without preserving the data (the matrix is set to zero) - */ - void resize(Index rows, Index cols) - { - const Index outerSize = IsRowMajor ? rows : cols; - m_innerSize = convert_index(IsRowMajor ? cols : rows); - setZero(); - if (Index(m_data.size()) != outerSize) - { - m_data.resize(outerSize); - } - } - - void resizeAndKeepData(Index rows, Index cols) - { - const Index outerSize = IsRowMajor ? rows : cols; - const Index innerSize = IsRowMajor ? cols : rows; - if (m_innerSize>innerSize) - { - // remove all coefficients with innerCoord>=innerSize - // TODO - //std::cerr << "not implemented yet\n"; - exit(2); - } - if (m_data.size() != outerSize) - { - m_data.resize(outerSize); - } - } - - /** The class DynamicSparseMatrix is deprectaed */ - EIGEN_DEPRECATED inline DynamicSparseMatrix() - : m_innerSize(0), m_data(0) - { - #ifdef EIGEN_SPARSE_CREATE_TEMPORARY_PLUGIN - EIGEN_SPARSE_CREATE_TEMPORARY_PLUGIN - #endif - eigen_assert(innerSize()==0 && outerSize()==0); - } - - /** The class DynamicSparseMatrix is deprectaed */ - EIGEN_DEPRECATED inline DynamicSparseMatrix(Index rows, Index cols) - : m_innerSize(0) - { - #ifdef EIGEN_SPARSE_CREATE_TEMPORARY_PLUGIN - EIGEN_SPARSE_CREATE_TEMPORARY_PLUGIN - #endif - resize(rows, cols); - } - - /** The class DynamicSparseMatrix is deprectaed */ - template<typename OtherDerived> - EIGEN_DEPRECATED explicit inline DynamicSparseMatrix(const SparseMatrixBase<OtherDerived>& other) - : m_innerSize(0) - { - #ifdef EIGEN_SPARSE_CREATE_TEMPORARY_PLUGIN - EIGEN_SPARSE_CREATE_TEMPORARY_PLUGIN - #endif - Base::operator=(other.derived()); - } - - inline DynamicSparseMatrix(const DynamicSparseMatrix& other) - : Base(), m_innerSize(0) - { - #ifdef EIGEN_SPARSE_CREATE_TEMPORARY_PLUGIN - EIGEN_SPARSE_CREATE_TEMPORARY_PLUGIN - #endif - *this = other.derived(); - } - - inline void swap(DynamicSparseMatrix& other) - { - //EIGEN_DBG_SPARSE(std::cout << "SparseMatrix:: swap\n"); - std::swap(m_innerSize, other.m_innerSize); - //std::swap(m_outerSize, other.m_outerSize); - m_data.swap(other.m_data); - } - - inline DynamicSparseMatrix& operator=(const DynamicSparseMatrix& other) - { - if (other.isRValue()) - { - swap(other.const_cast_derived()); - } - else - { - resize(other.rows(), other.cols()); - m_data = other.m_data; - } - return *this; - } - - /** Destructor */ - inline ~DynamicSparseMatrix() {} - - public: - - /** \deprecated - * Set the matrix to zero and reserve the memory for \a reserveSize nonzero coefficients. */ - EIGEN_DEPRECATED void startFill(Index reserveSize = 1000) - { - setZero(); - reserve(reserveSize); - } - - /** \deprecated use insert() - * inserts a nonzero coefficient at given coordinates \a row, \a col and returns its reference assuming that: - * 1 - the coefficient does not exist yet - * 2 - this the coefficient with greater inner coordinate for the given outer coordinate. - * In other words, assuming \c *this is column-major, then there must not exists any nonzero coefficient of coordinates - * \c i \c x \a col such that \c i >= \a row. Otherwise the matrix is invalid. - * - * \see fillrand(), coeffRef() - */ - EIGEN_DEPRECATED Scalar& fill(Index row, Index col) - { - const Index outer = IsRowMajor ? row : col; - const Index inner = IsRowMajor ? col : row; - return insertBack(outer,inner); - } - - /** \deprecated use insert() - * Like fill() but with random inner coordinates. - * Compared to the generic coeffRef(), the unique limitation is that we assume - * the coefficient does not exist yet. - */ - EIGEN_DEPRECATED Scalar& fillrand(Index row, Index col) - { - return insert(row,col); - } - - /** \deprecated use finalize() - * Does nothing. Provided for compatibility with SparseMatrix. */ - EIGEN_DEPRECATED void endFill() {} - -# ifdef EIGEN_DYNAMICSPARSEMATRIX_PLUGIN -# include EIGEN_DYNAMICSPARSEMATRIX_PLUGIN -# endif - }; - -template<typename Scalar, int _Options, typename _StorageIndex> -class DynamicSparseMatrix<Scalar,_Options,_StorageIndex>::InnerIterator : public SparseVector<Scalar,_Options,_StorageIndex>::InnerIterator -{ - typedef typename SparseVector<Scalar,_Options,_StorageIndex>::InnerIterator Base; - public: - InnerIterator(const DynamicSparseMatrix& mat, Index outer) - : Base(mat.m_data[outer]), m_outer(outer) - {} - - inline Index row() const { return IsRowMajor ? m_outer : Base::index(); } - inline Index col() const { return IsRowMajor ? Base::index() : m_outer; } - inline Index outer() const { return m_outer; } - - protected: - const Index m_outer; -}; - -template<typename Scalar, int _Options, typename _StorageIndex> -class DynamicSparseMatrix<Scalar,_Options,_StorageIndex>::ReverseInnerIterator : public SparseVector<Scalar,_Options,_StorageIndex>::ReverseInnerIterator -{ - typedef typename SparseVector<Scalar,_Options,_StorageIndex>::ReverseInnerIterator Base; - public: - ReverseInnerIterator(const DynamicSparseMatrix& mat, Index outer) - : Base(mat.m_data[outer]), m_outer(outer) - {} - - inline Index row() const { return IsRowMajor ? m_outer : Base::index(); } - inline Index col() const { return IsRowMajor ? Base::index() : m_outer; } - inline Index outer() const { return m_outer; } - - protected: - const Index m_outer; -}; - -namespace internal { - -template<typename _Scalar, int _Options, typename _StorageIndex> -struct evaluator<DynamicSparseMatrix<_Scalar,_Options,_StorageIndex> > - : evaluator_base<DynamicSparseMatrix<_Scalar,_Options,_StorageIndex> > -{ - typedef _Scalar Scalar; - typedef DynamicSparseMatrix<_Scalar,_Options,_StorageIndex> SparseMatrixType; - typedef typename SparseMatrixType::InnerIterator InnerIterator; - typedef typename SparseMatrixType::ReverseInnerIterator ReverseInnerIterator; - - enum { - CoeffReadCost = NumTraits<_Scalar>::ReadCost, - Flags = SparseMatrixType::Flags - }; - - evaluator() : m_matrix(0) {} - evaluator(const SparseMatrixType &mat) : m_matrix(&mat) {} - - operator SparseMatrixType&() { return m_matrix->const_cast_derived(); } - operator const SparseMatrixType&() const { return *m_matrix; } - - Scalar coeff(Index row, Index col) const { return m_matrix->coeff(row,col); } - - Index nonZerosEstimate() const { return m_matrix->nonZeros(); } - - const SparseMatrixType *m_matrix; -}; - -} - -} // end namespace Eigen - -#endif // EIGEN_DYNAMIC_SPARSEMATRIX_H diff --git a/eigen/unsupported/Eigen/src/SparseExtra/MarketIO.h b/eigen/unsupported/Eigen/src/SparseExtra/MarketIO.h deleted file mode 100644 index 04b7d69..0000000 --- a/eigen/unsupported/Eigen/src/SparseExtra/MarketIO.h +++ /dev/null @@ -1,275 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2011 Gael Guennebaud <gael.guennebaud@inria.fr> -// Copyright (C) 2012 Desire NUENTSA WAKAM <desire.nuentsa_wakam@inria.fr> -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_SPARSE_MARKET_IO_H -#define EIGEN_SPARSE_MARKET_IO_H - -#include <iostream> - -namespace Eigen { - -namespace internal -{ - template <typename Scalar,typename IndexType> - inline bool GetMarketLine (std::stringstream& line, IndexType& M, IndexType& N, IndexType& i, IndexType& j, Scalar& value) - { - line >> i >> j >> value; - i--; - j--; - if(i>=0 && j>=0 && i<M && j<N) - { - return true; - } - else - return false; - } - template <typename Scalar,typename IndexType> - inline bool GetMarketLine (std::stringstream& line, IndexType& M, IndexType& N, IndexType& i, IndexType& j, std::complex<Scalar>& value) - { - Scalar valR, valI; - line >> i >> j >> valR >> valI; - i--; - j--; - if(i>=0 && j>=0 && i<M && j<N) - { - value = std::complex<Scalar>(valR, valI); - return true; - } - else - return false; - } - - template <typename RealScalar> - inline void GetVectorElt (const std::string& line, RealScalar& val) - { - std::istringstream newline(line); - newline >> val; - } - - template <typename RealScalar> - inline void GetVectorElt (const std::string& line, std::complex<RealScalar>& val) - { - RealScalar valR, valI; - std::istringstream newline(line); - newline >> valR >> valI; - val = std::complex<RealScalar>(valR, valI); - } - - template<typename Scalar> - inline void putMarketHeader(std::string& header,int sym) - { - header= "%%MatrixMarket matrix coordinate "; - if(internal::is_same<Scalar, std::complex<float> >::value || internal::is_same<Scalar, std::complex<double> >::value) - { - header += " complex"; - if(sym == Symmetric) header += " symmetric"; - else if (sym == SelfAdjoint) header += " Hermitian"; - else header += " general"; - } - else - { - header += " real"; - if(sym == Symmetric) header += " symmetric"; - else header += " general"; - } - } - - template<typename Scalar> - inline void PutMatrixElt(Scalar value, int row, int col, std::ofstream& out) - { - out << row << " "<< col << " " << value << "\n"; - } - template<typename Scalar> - inline void PutMatrixElt(std::complex<Scalar> value, int row, int col, std::ofstream& out) - { - out << row << " " << col << " " << value.real() << " " << value.imag() << "\n"; - } - - - template<typename Scalar> - inline void putVectorElt(Scalar value, std::ofstream& out) - { - out << value << "\n"; - } - template<typename Scalar> - inline void putVectorElt(std::complex<Scalar> value, std::ofstream& out) - { - out << value.real << " " << value.imag()<< "\n"; - } - -} // end namepsace internal - -inline bool getMarketHeader(const std::string& filename, int& sym, bool& iscomplex, bool& isvector) -{ - sym = 0; - iscomplex = false; - isvector = false; - std::ifstream in(filename.c_str(),std::ios::in); - if(!in) - return false; - - std::string line; - // The matrix header is always the first line in the file - std::getline(in, line); eigen_assert(in.good()); - - std::stringstream fmtline(line); - std::string substr[5]; - fmtline>> substr[0] >> substr[1] >> substr[2] >> substr[3] >> substr[4]; - if(substr[2].compare("array") == 0) isvector = true; - if(substr[3].compare("complex") == 0) iscomplex = true; - if(substr[4].compare("symmetric") == 0) sym = Symmetric; - else if (substr[4].compare("Hermitian") == 0) sym = SelfAdjoint; - - return true; -} - -template<typename SparseMatrixType> -bool loadMarket(SparseMatrixType& mat, const std::string& filename) -{ - typedef typename SparseMatrixType::Scalar Scalar; - typedef typename SparseMatrixType::StorageIndex StorageIndex; - std::ifstream input(filename.c_str(),std::ios::in); - if(!input) - return false; - - const int maxBuffersize = 2048; - char buffer[maxBuffersize]; - - bool readsizes = false; - - typedef Triplet<Scalar,StorageIndex> T; - std::vector<T> elements; - - StorageIndex M(-1), N(-1), NNZ(-1); - StorageIndex count = 0; - while(input.getline(buffer, maxBuffersize)) - { - // skip comments - //NOTE An appropriate test should be done on the header to get the symmetry - if(buffer[0]=='%') - continue; - - std::stringstream line(buffer); - - if(!readsizes) - { - line >> M >> N >> NNZ; - if(M > 0 && N > 0 && NNZ > 0) - { - readsizes = true; - //std::cout << "sizes: " << M << "," << N << "," << NNZ << "\n"; - mat.resize(M,N); - mat.reserve(NNZ); - } - } - else - { - StorageIndex i(-1), j(-1); - Scalar value; - if( internal::GetMarketLine(line, M, N, i, j, value) ) - { - ++ count; - elements.push_back(T(i,j,value)); - } - else - std::cerr << "Invalid read: " << i << "," << j << "\n"; - } - } - mat.setFromTriplets(elements.begin(), elements.end()); - if(count!=NNZ) - std::cerr << count << "!=" << NNZ << "\n"; - - input.close(); - return true; -} - -template<typename VectorType> -bool loadMarketVector(VectorType& vec, const std::string& filename) -{ - typedef typename VectorType::Scalar Scalar; - std::ifstream in(filename.c_str(), std::ios::in); - if(!in) - return false; - - std::string line; - int n(0), col(0); - do - { // Skip comments - std::getline(in, line); eigen_assert(in.good()); - } while (line[0] == '%'); - std::istringstream newline(line); - newline >> n >> col; - eigen_assert(n>0 && col>0); - vec.resize(n); - int i = 0; - Scalar value; - while ( std::getline(in, line) && (i < n) ){ - internal::GetVectorElt(line, value); - vec(i++) = value; - } - in.close(); - if (i!=n){ - std::cerr<< "Unable to read all elements from file " << filename << "\n"; - return false; - } - return true; -} - -template<typename SparseMatrixType> -bool saveMarket(const SparseMatrixType& mat, const std::string& filename, int sym = 0) -{ - typedef typename SparseMatrixType::Scalar Scalar; - std::ofstream out(filename.c_str(),std::ios::out); - if(!out) - return false; - - out.flags(std::ios_base::scientific); - out.precision(64); - std::string header; - internal::putMarketHeader<Scalar>(header, sym); - out << header << std::endl; - out << mat.rows() << " " << mat.cols() << " " << mat.nonZeros() << "\n"; - int count = 0; - for(int j=0; j<mat.outerSize(); ++j) - for(typename SparseMatrixType::InnerIterator it(mat,j); it; ++it) - { - ++ count; - internal::PutMatrixElt(it.value(), it.row()+1, it.col()+1, out); - // out << it.row()+1 << " " << it.col()+1 << " " << it.value() << "\n"; - } - out.close(); - return true; -} - -template<typename VectorType> -bool saveMarketVector (const VectorType& vec, const std::string& filename) -{ - typedef typename VectorType::Scalar Scalar; - std::ofstream out(filename.c_str(),std::ios::out); - if(!out) - return false; - - out.flags(std::ios_base::scientific); - out.precision(64); - if(internal::is_same<Scalar, std::complex<float> >::value || internal::is_same<Scalar, std::complex<double> >::value) - out << "%%MatrixMarket matrix array complex general\n"; - else - out << "%%MatrixMarket matrix array real general\n"; - out << vec.size() << " "<< 1 << "\n"; - for (int i=0; i < vec.size(); i++){ - internal::putVectorElt(vec(i), out); - } - out.close(); - return true; -} - -} // end namespace Eigen - -#endif // EIGEN_SPARSE_MARKET_IO_H diff --git a/eigen/unsupported/Eigen/src/SparseExtra/MatrixMarketIterator.h b/eigen/unsupported/Eigen/src/SparseExtra/MatrixMarketIterator.h deleted file mode 100644 index 02916ea..0000000 --- a/eigen/unsupported/Eigen/src/SparseExtra/MatrixMarketIterator.h +++ /dev/null @@ -1,247 +0,0 @@ - -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2012 Desire NUENTSA WAKAM <desire.nuentsa_wakam@inria.fr> -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_BROWSE_MATRICES_H -#define EIGEN_BROWSE_MATRICES_H - -namespace Eigen { - -enum { - SPD = 0x100, - NonSymmetric = 0x0 -}; - -/** - * @brief Iterator to browse matrices from a specified folder - * - * This is used to load all the matrices from a folder. - * The matrices should be in Matrix Market format - * It is assumed that the matrices are named as matname.mtx - * and matname_SPD.mtx if the matrix is Symmetric and positive definite (or Hermitian) - * The right hand side vectors are loaded as well, if they exist. - * They should be named as matname_b.mtx. - * Note that the right hand side for a SPD matrix is named as matname_SPD_b.mtx - * - * Sometimes a reference solution is available. In this case, it should be named as matname_x.mtx - * - * Sample code - * \code - * - * \endcode - * - * \tparam Scalar The scalar type - */ -template <typename Scalar> -class MatrixMarketIterator -{ - typedef typename NumTraits<Scalar>::Real RealScalar; - public: - typedef Matrix<Scalar,Dynamic,1> VectorType; - typedef SparseMatrix<Scalar,ColMajor> MatrixType; - - public: - MatrixMarketIterator(const std::string &folder) - : m_sym(0), m_isvalid(false), m_matIsLoaded(false), m_hasRhs(false), m_hasrefX(false), m_folder(folder) - { - m_folder_id = opendir(folder.c_str()); - if(m_folder_id) - Getnextvalidmatrix(); - } - - ~MatrixMarketIterator() - { - if (m_folder_id) closedir(m_folder_id); - } - - inline MatrixMarketIterator& operator++() - { - m_matIsLoaded = false; - m_hasrefX = false; - m_hasRhs = false; - Getnextvalidmatrix(); - return *this; - } - inline operator bool() const { return m_isvalid;} - - /** Return the sparse matrix corresponding to the current file */ - inline MatrixType& matrix() - { - // Read the matrix - if (m_matIsLoaded) return m_mat; - - std::string matrix_file = m_folder + "/" + m_matname + ".mtx"; - if ( !loadMarket(m_mat, matrix_file)) - { - std::cerr << "Warning loadMarket failed when loading \"" << matrix_file << "\"" << std::endl; - m_matIsLoaded = false; - return m_mat; - } - m_matIsLoaded = true; - - if (m_sym != NonSymmetric) - { - // Check whether we need to restore a full matrix: - RealScalar diag_norm = m_mat.diagonal().norm(); - RealScalar lower_norm = m_mat.template triangularView<Lower>().norm(); - RealScalar upper_norm = m_mat.template triangularView<Upper>().norm(); - if(lower_norm>diag_norm && upper_norm==diag_norm) - { - // only the lower part is stored - MatrixType tmp(m_mat); - m_mat = tmp.template selfadjointView<Lower>(); - } - else if(upper_norm>diag_norm && lower_norm==diag_norm) - { - // only the upper part is stored - MatrixType tmp(m_mat); - m_mat = tmp.template selfadjointView<Upper>(); - } - } - return m_mat; - } - - /** Return the right hand side corresponding to the current matrix. - * If the rhs file is not provided, a random rhs is generated - */ - inline VectorType& rhs() - { - // Get the right hand side - if (m_hasRhs) return m_rhs; - - std::string rhs_file; - rhs_file = m_folder + "/" + m_matname + "_b.mtx"; // The pattern is matname_b.mtx - m_hasRhs = Fileexists(rhs_file); - if (m_hasRhs) - { - m_rhs.resize(m_mat.cols()); - m_hasRhs = loadMarketVector(m_rhs, rhs_file); - } - if (!m_hasRhs) - { - // Generate a random right hand side - if (!m_matIsLoaded) this->matrix(); - m_refX.resize(m_mat.cols()); - m_refX.setRandom(); - m_rhs = m_mat * m_refX; - m_hasrefX = true; - m_hasRhs = true; - } - return m_rhs; - } - - /** Return a reference solution - * If it is not provided and if the right hand side is not available - * then refX is randomly generated such that A*refX = b - * where A and b are the matrix and the rhs. - * Note that when a rhs is provided, refX is not available - */ - inline VectorType& refX() - { - // Check if a reference solution is provided - if (m_hasrefX) return m_refX; - - std::string lhs_file; - lhs_file = m_folder + "/" + m_matname + "_x.mtx"; - m_hasrefX = Fileexists(lhs_file); - if (m_hasrefX) - { - m_refX.resize(m_mat.cols()); - m_hasrefX = loadMarketVector(m_refX, lhs_file); - } - else - m_refX.resize(0); - return m_refX; - } - - inline std::string& matname() { return m_matname; } - - inline int sym() { return m_sym; } - - bool hasRhs() {return m_hasRhs; } - bool hasrefX() {return m_hasrefX; } - bool isFolderValid() { return bool(m_folder_id); } - - protected: - - inline bool Fileexists(std::string file) - { - std::ifstream file_id(file.c_str()); - if (!file_id.good() ) - { - return false; - } - else - { - file_id.close(); - return true; - } - } - - void Getnextvalidmatrix( ) - { - m_isvalid = false; - // Here, we return with the next valid matrix in the folder - while ( (m_curs_id = readdir(m_folder_id)) != NULL) { - m_isvalid = false; - std::string curfile; - curfile = m_folder + "/" + m_curs_id->d_name; - // Discard if it is a folder - if (m_curs_id->d_type == DT_DIR) continue; //FIXME This may not be available on non BSD systems -// struct stat st_buf; -// stat (curfile.c_str(), &st_buf); -// if (S_ISDIR(st_buf.st_mode)) continue; - - // Determine from the header if it is a matrix or a right hand side - bool isvector,iscomplex=false; - if(!getMarketHeader(curfile,m_sym,iscomplex,isvector)) continue; - if(isvector) continue; - if (!iscomplex) - { - if(internal::is_same<Scalar, std::complex<float> >::value || internal::is_same<Scalar, std::complex<double> >::value) - continue; - } - if (iscomplex) - { - if(internal::is_same<Scalar, float>::value || internal::is_same<Scalar, double>::value) - continue; - } - - - // Get the matrix name - std::string filename = m_curs_id->d_name; - m_matname = filename.substr(0, filename.length()-4); - - // Find if the matrix is SPD - size_t found = m_matname.find("SPD"); - if( (found!=std::string::npos) && (m_sym != NonSymmetric) ) - m_sym = SPD; - - m_isvalid = true; - break; - } - } - int m_sym; // Symmetry of the matrix - MatrixType m_mat; // Current matrix - VectorType m_rhs; // Current vector - VectorType m_refX; // The reference solution, if exists - std::string m_matname; // Matrix Name - bool m_isvalid; - bool m_matIsLoaded; // Determine if the matrix has already been loaded from the file - bool m_hasRhs; // The right hand side exists - bool m_hasrefX; // A reference solution is provided - std::string m_folder; - DIR * m_folder_id; - struct dirent *m_curs_id; - -}; - -} // end namespace Eigen - -#endif diff --git a/eigen/unsupported/Eigen/src/SparseExtra/RandomSetter.h b/eigen/unsupported/Eigen/src/SparseExtra/RandomSetter.h deleted file mode 100644 index ee97299..0000000 --- a/eigen/unsupported/Eigen/src/SparseExtra/RandomSetter.h +++ /dev/null @@ -1,327 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> -// -// This Source Code Form is subject to the terms of the Mozilla -// Public License v. 2.0. If a copy of the MPL was not distributed -// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. - -#ifndef EIGEN_RANDOMSETTER_H -#define EIGEN_RANDOMSETTER_H - -namespace Eigen { - -/** Represents a std::map - * - * \see RandomSetter - */ -template<typename Scalar> struct StdMapTraits -{ - typedef int KeyType; - typedef std::map<KeyType,Scalar> Type; - enum { - IsSorted = 1 - }; - - static void setInvalidKey(Type&, const KeyType&) {} -}; - -#ifdef EIGEN_UNORDERED_MAP_SUPPORT -/** Represents a std::unordered_map - * - * To use it you need to both define EIGEN_UNORDERED_MAP_SUPPORT and include the unordered_map header file - * yourself making sure that unordered_map is defined in the std namespace. - * - * For instance, with current version of gcc you can either enable C++0x standard (-std=c++0x) or do: - * \code - * #include <tr1/unordered_map> - * #define EIGEN_UNORDERED_MAP_SUPPORT - * namespace std { - * using std::tr1::unordered_map; - * } - * \endcode - * - * \see RandomSetter - */ -template<typename Scalar> struct StdUnorderedMapTraits -{ - typedef int KeyType; - typedef std::unordered_map<KeyType,Scalar> Type; - enum { - IsSorted = 0 - }; - - static void setInvalidKey(Type&, const KeyType&) {} -}; -#endif // EIGEN_UNORDERED_MAP_SUPPORT - -#ifdef _DENSE_HASH_MAP_H_ -/** Represents a google::dense_hash_map - * - * \see RandomSetter - */ -template<typename Scalar> struct GoogleDenseHashMapTraits -{ - typedef int KeyType; - typedef google::dense_hash_map<KeyType,Scalar> Type; - enum { - IsSorted = 0 - }; - - static void setInvalidKey(Type& map, const KeyType& k) - { map.set_empty_key(k); } -}; -#endif - -#ifdef _SPARSE_HASH_MAP_H_ -/** Represents a google::sparse_hash_map - * - * \see RandomSetter - */ -template<typename Scalar> struct GoogleSparseHashMapTraits -{ - typedef int KeyType; - typedef google::sparse_hash_map<KeyType,Scalar> Type; - enum { - IsSorted = 0 - }; - - static void setInvalidKey(Type&, const KeyType&) {} -}; -#endif - -/** \class RandomSetter - * - * \brief The RandomSetter is a wrapper object allowing to set/update a sparse matrix with random access - * - * \tparam SparseMatrixType the type of the sparse matrix we are updating - * \tparam MapTraits a traits class representing the map implementation used for the temporary sparse storage. - * Its default value depends on the system. - * \tparam OuterPacketBits defines the number of rows (or columns) manage by a single map object - * as a power of two exponent. - * - * This class temporarily represents a sparse matrix object using a generic map implementation allowing for - * efficient random access. The conversion from the compressed representation to a hash_map object is performed - * in the RandomSetter constructor, while the sparse matrix is updated back at destruction time. This strategy - * suggest the use of nested blocks as in this example: - * - * \code - * SparseMatrix<double> m(rows,cols); - * { - * RandomSetter<SparseMatrix<double> > w(m); - * // don't use m but w instead with read/write random access to the coefficients: - * for(;;) - * w(rand(),rand()) = rand; - * } - * // when w is deleted, the data are copied back to m - * // and m is ready to use. - * \endcode - * - * Since hash_map objects are not fully sorted, representing a full matrix as a single hash_map would - * involve a big and costly sort to update the compressed matrix back. To overcome this issue, a RandomSetter - * use multiple hash_map, each representing 2^OuterPacketBits columns or rows according to the storage order. - * To reach optimal performance, this value should be adjusted according to the average number of nonzeros - * per rows/columns. - * - * The possible values for the template parameter MapTraits are: - * - \b StdMapTraits: corresponds to std::map. (does not perform very well) - * - \b GnuHashMapTraits: corresponds to __gnu_cxx::hash_map (available only with GCC) - * - \b GoogleDenseHashMapTraits: corresponds to google::dense_hash_map (best efficiency, reasonable memory consumption) - * - \b GoogleSparseHashMapTraits: corresponds to google::sparse_hash_map (best memory consumption, relatively good performance) - * - * The default map implementation depends on the availability, and the preferred order is: - * GoogleSparseHashMapTraits, GnuHashMapTraits, and finally StdMapTraits. - * - * For performance and memory consumption reasons it is highly recommended to use one of - * the Google's hash_map implementation. To enable the support for them, you have two options: - * - \#include <google/dense_hash_map> yourself \b before Eigen/Sparse header - * - define EIGEN_GOOGLEHASH_SUPPORT - * In the later case the inclusion of <google/dense_hash_map> is made for you. - * - * \see http://code.google.com/p/google-sparsehash/ - */ -template<typename SparseMatrixType, - template <typename T> class MapTraits = -#if defined _DENSE_HASH_MAP_H_ - GoogleDenseHashMapTraits -#elif defined _HASH_MAP - GnuHashMapTraits -#else - StdMapTraits -#endif - ,int OuterPacketBits = 6> -class RandomSetter -{ - typedef typename SparseMatrixType::Scalar Scalar; - typedef typename SparseMatrixType::StorageIndex StorageIndex; - - struct ScalarWrapper - { - ScalarWrapper() : value(0) {} - Scalar value; - }; - typedef typename MapTraits<ScalarWrapper>::KeyType KeyType; - typedef typename MapTraits<ScalarWrapper>::Type HashMapType; - static const int OuterPacketMask = (1 << OuterPacketBits) - 1; - enum { - SwapStorage = 1 - MapTraits<ScalarWrapper>::IsSorted, - TargetRowMajor = (SparseMatrixType::Flags & RowMajorBit) ? 1 : 0, - SetterRowMajor = SwapStorage ? 1-TargetRowMajor : TargetRowMajor - }; - - public: - - /** Constructs a random setter object from the sparse matrix \a target - * - * Note that the initial value of \a target are imported. If you want to re-set - * a sparse matrix from scratch, then you must set it to zero first using the - * setZero() function. - */ - inline RandomSetter(SparseMatrixType& target) - : mp_target(&target) - { - const Index outerSize = SwapStorage ? target.innerSize() : target.outerSize(); - const Index innerSize = SwapStorage ? target.outerSize() : target.innerSize(); - m_outerPackets = outerSize >> OuterPacketBits; - if (outerSize&OuterPacketMask) - m_outerPackets += 1; - m_hashmaps = new HashMapType[m_outerPackets]; - // compute number of bits needed to store inner indices - Index aux = innerSize - 1; - m_keyBitsOffset = 0; - while (aux) - { - ++m_keyBitsOffset; - aux = aux >> 1; - } - KeyType ik = (1<<(OuterPacketBits+m_keyBitsOffset)); - for (Index k=0; k<m_outerPackets; ++k) - MapTraits<ScalarWrapper>::setInvalidKey(m_hashmaps[k],ik); - - // insert current coeffs - for (Index j=0; j<mp_target->outerSize(); ++j) - for (typename SparseMatrixType::InnerIterator it(*mp_target,j); it; ++it) - (*this)(TargetRowMajor?j:it.index(), TargetRowMajor?it.index():j) = it.value(); - } - - /** Destructor updating back the sparse matrix target */ - ~RandomSetter() - { - KeyType keyBitsMask = (1<<m_keyBitsOffset)-1; - if (!SwapStorage) // also means the map is sorted - { - mp_target->setZero(); - mp_target->makeCompressed(); - mp_target->reserve(nonZeros()); - Index prevOuter = -1; - for (Index k=0; k<m_outerPackets; ++k) - { - const Index outerOffset = (1<<OuterPacketBits) * k; - typename HashMapType::iterator end = m_hashmaps[k].end(); - for (typename HashMapType::iterator it = m_hashmaps[k].begin(); it!=end; ++it) - { - const Index outer = (it->first >> m_keyBitsOffset) + outerOffset; - const Index inner = it->first & keyBitsMask; - if (prevOuter!=outer) - { - for (Index j=prevOuter+1;j<=outer;++j) - mp_target->startVec(j); - prevOuter = outer; - } - mp_target->insertBackByOuterInner(outer, inner) = it->second.value; - } - } - mp_target->finalize(); - } - else - { - VectorXi positions(mp_target->outerSize()); - positions.setZero(); - // pass 1 - for (Index k=0; k<m_outerPackets; ++k) - { - typename HashMapType::iterator end = m_hashmaps[k].end(); - for (typename HashMapType::iterator it = m_hashmaps[k].begin(); it!=end; ++it) - { - const Index outer = it->first & keyBitsMask; - ++positions[outer]; - } - } - // prefix sum - Index count = 0; - for (Index j=0; j<mp_target->outerSize(); ++j) - { - Index tmp = positions[j]; - mp_target->outerIndexPtr()[j] = count; - positions[j] = count; - count += tmp; - } - mp_target->makeCompressed(); - mp_target->outerIndexPtr()[mp_target->outerSize()] = count; - mp_target->resizeNonZeros(count); - // pass 2 - for (Index k=0; k<m_outerPackets; ++k) - { - const Index outerOffset = (1<<OuterPacketBits) * k; - typename HashMapType::iterator end = m_hashmaps[k].end(); - for (typename HashMapType::iterator it = m_hashmaps[k].begin(); it!=end; ++it) - { - const Index inner = (it->first >> m_keyBitsOffset) + outerOffset; - const Index outer = it->first & keyBitsMask; - // sorted insertion - // Note that we have to deal with at most 2^OuterPacketBits unsorted coefficients, - // moreover those 2^OuterPacketBits coeffs are likely to be sparse, an so only a - // small fraction of them have to be sorted, whence the following simple procedure: - Index posStart = mp_target->outerIndexPtr()[outer]; - Index i = (positions[outer]++) - 1; - while ( (i >= posStart) && (mp_target->innerIndexPtr()[i] > inner) ) - { - mp_target->valuePtr()[i+1] = mp_target->valuePtr()[i]; - mp_target->innerIndexPtr()[i+1] = mp_target->innerIndexPtr()[i]; - --i; - } - mp_target->innerIndexPtr()[i+1] = inner; - mp_target->valuePtr()[i+1] = it->second.value; - } - } - } - delete[] m_hashmaps; - } - - /** \returns a reference to the coefficient at given coordinates \a row, \a col */ - Scalar& operator() (Index row, Index col) - { - const Index outer = SetterRowMajor ? row : col; - const Index inner = SetterRowMajor ? col : row; - const Index outerMajor = outer >> OuterPacketBits; // index of the packet/map - const Index outerMinor = outer & OuterPacketMask; // index of the inner vector in the packet - const KeyType key = internal::convert_index<KeyType>((outerMinor<<m_keyBitsOffset) | inner); - return m_hashmaps[outerMajor][key].value; - } - - /** \returns the number of non zero coefficients - * - * \note According to the underlying map/hash_map implementation, - * this function might be quite expensive. - */ - Index nonZeros() const - { - Index nz = 0; - for (Index k=0; k<m_outerPackets; ++k) - nz += static_cast<Index>(m_hashmaps[k].size()); - return nz; - } - - - protected: - - HashMapType* m_hashmaps; - SparseMatrixType* mp_target; - Index m_outerPackets; - unsigned char m_keyBitsOffset; -}; - -} // end namespace Eigen - -#endif // EIGEN_RANDOMSETTER_H |
