diff options
author | Gael Guennebaud <g.gael@free.fr> | 2015-02-07 22:03:25 +0100 |
---|---|---|
committer | Gael Guennebaud <g.gael@free.fr> | 2015-02-07 22:03:25 +0100 |
commit | f3be317614b6b6709737d6ef7bea0ffe96c285d4 (patch) | |
tree | 53b8a110897cf7ef33d9575cea84060d3051fbf3 /Eigen/src/SparseCore/SparseMap.h | |
parent | 08081f829397de11651d8d779b9eed916ccc88d7 (diff) |
Add a Map<SparseMatrix> specialization.
Diffstat (limited to 'Eigen/src/SparseCore/SparseMap.h')
-rw-r--r-- | Eigen/src/SparseCore/SparseMap.h | 211 |
1 files changed, 211 insertions, 0 deletions
diff --git a/Eigen/src/SparseCore/SparseMap.h b/Eigen/src/SparseCore/SparseMap.h new file mode 100644 index 000000000..91e8f7480 --- /dev/null +++ b/Eigen/src/SparseCore/SparseMap.h @@ -0,0 +1,211 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2015 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_MAP_H +#define EIGEN_SPARSE_MAP_H + +namespace Eigen { + +template<typename Derived, + int Level = internal::accessors_level<Derived>::has_write_access ? WriteAccessors : ReadOnlyAccessors +> class SparseMapBase; + +template<typename Derived> +class SparseMapBase<Derived,ReadOnlyAccessors> + : public SparseCompressedBase<Derived> +{ + public: + typedef SparseCompressedBase<Derived> Base; + typedef typename Base::Scalar Scalar; + typedef typename Base::Index Index; + enum { IsRowMajor = Base::IsRowMajor }; + + protected: + + typedef typename internal::conditional< + bool(internal::is_lvalue<Derived>::value), + Scalar *, const Scalar *>::type ScalarPointer; + typedef typename internal::conditional< + bool(internal::is_lvalue<Derived>::value), + Index *, const Index *>::type IndexPointer; + + Index m_outerSize; + Index m_innerSize; + Index m_nnz; + IndexPointer m_outerIndex; + IndexPointer m_innerIndices; + ScalarPointer m_values; + IndexPointer m_innerNonZeros; + + public: + + inline Index rows() const { return IsRowMajor ? m_outerSize : m_innerSize; } + inline Index cols() const { return IsRowMajor ? m_innerSize : m_outerSize; } + inline Index innerSize() const { return m_innerSize; } + inline Index outerSize() const { return m_outerSize; } + + bool isCompressed() const { return m_innerNonZeros==0; } + + //---------------------------------------- + // direct access interface + inline const Scalar* valuePtr() const { return m_values; } + inline const Index* innerIndexPtr() const { return m_innerIndices; } + inline const Index* outerIndexPtr() const { return m_outerIndex; } + inline const Index* innerNonZeroPtr() const { return m_innerNonZeros; } + //---------------------------------------- + + inline Scalar coeff(Index row, Index col) const + { + const Index outer = IsRowMajor ? row : col; + const Index inner = IsRowMajor ? col : row; + + Index start = m_outerIndex[outer]; + Index end = isCompressed() ? m_outerIndex[outer+1] : start + m_innerNonZeros[outer]; + if (start==end) + return Scalar(0); + else if (end>0 && inner==m_innerIndices[end-1]) + return m_values[end-1]; + // ^^ optimization: let's first check if it is the last coefficient + // (very common in high level algorithms) + + const Index* r = std::lower_bound(&m_innerIndices[start],&m_innerIndices[end-1],inner); + const Index id = r-&m_innerIndices[0]; + return ((*r==inner) && (id<end)) ? m_values[id] : Scalar(0); + } + + /** \returns the number of non zero coefficients */ + inline Index nonZeros() const { return m_nnz; } + + inline SparseMapBase(Index rows, Index cols, Index nnz, IndexPointer outerIndexPtr, IndexPointer innerIndexPtr, + ScalarPointer valuePtr, IndexPointer innerNonZerosPtr = 0) + : m_outerSize(IsRowMajor?rows:cols), m_innerSize(IsRowMajor?cols:rows), m_nnz(nnz), m_outerIndex(outerIndexPtr), + m_innerIndices(innerIndexPtr), m_values(valuePtr), m_innerNonZeros(innerNonZerosPtr) + {} + + /** Empty destructor */ + inline ~SparseMapBase() {} +}; + +template<typename Derived> +class SparseMapBase<Derived,WriteAccessors> + : public SparseMapBase<Derived,ReadOnlyAccessors> +{ + typedef MapBase<Derived, ReadOnlyAccessors> ReadOnlyMapBase; + + public: + typedef SparseMapBase<Derived, ReadOnlyAccessors> Base; + typedef typename Base::Scalar Scalar; + typedef typename Base::Index Index; + enum { IsRowMajor = Base::IsRowMajor }; + + public: + + //---------------------------------------- + // direct access interface + using Base::valuePtr; + using Base::innerIndexPtr; + using Base::outerIndexPtr; + using Base::innerNonZeroPtr; + inline Scalar* valuePtr() { return Base::m_values; } + inline Index* innerIndexPtr() { return Base::m_innerIndices; } + inline Index* outerIndexPtr() { return Base::m_outerIndex; } + inline Index* innerNonZeroPtr() { return Base::m_innerNonZeros; } + //---------------------------------------- + + inline Scalar& coeffRef(Index row, Index col) + { + const Index outer = IsRowMajor ? row : col; + const Index inner = IsRowMajor ? col : row; + + Index start = Base::m_outerIndex[outer]; + Index end = Base::isCompressed() ? Base::m_outerIndex[outer+1] : start + Base::m_innerNonZeros[outer]; + eigen_assert(end>=start && "you probably called coeffRef on a non finalized matrix"); + eigen_assert(end>start && "coeffRef cannot be called on a zero coefficient"); + Index* r = std::lower_bound(&Base::m_innerIndices[start],&Base::m_innerIndices[end],inner); + const Index id = r - &Base::m_innerIndices[0]; + eigen_assert((*r==inner) && (id<end) && "coeffRef cannot be called on a zero coefficient"); + return const_cast<Scalar*>(Base::m_values)[id]; + } + + inline SparseMapBase(Index rows, Index cols, Index nnz, Index* outerIndexPtr, Index* innerIndexPtr, + Scalar* valuePtr, Index* innerNonZerosPtr = 0) + : Base(rows, cols, nnz, outerIndexPtr, innerIndexPtr, valuePtr, innerNonZerosPtr) + {} + + /** Empty destructor */ + inline ~SparseMapBase() {} +}; + +template<typename MatScalar, int MatOptions, typename MatIndex, int Options, typename StrideType> +class Map<SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> + : public SparseMapBase<Map<SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> > +{ + public: + typedef SparseMapBase<Map<MatScalar, MatOptions, MatIndex> > Base; + _EIGEN_SPARSE_PUBLIC_INTERFACE(Map) + enum { IsRowMajor = Base::IsRowMajor }; + + public: + + inline Map(Index rows, Index cols, Index nnz, Index* outerIndexPtr, + Index* innerIndexPtr, Scalar* valuePtr, Index* innerNonZerosPtr = 0) + : Base(rows, cols, nnz, outerIndexPtr, innerIndexPtr, valuePtr, innerNonZerosPtr) + {} + + /** Empty destructor */ + inline ~Map() {} +}; + +template<typename MatScalar, int MatOptions, typename MatIndex, int Options, typename StrideType> +class Map<const SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> + : public SparseMapBase<Map<const SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> > +{ + public: + typedef SparseMapBase<Map<MatScalar, MatOptions, MatIndex> > Base; + _EIGEN_SPARSE_PUBLIC_INTERFACE(Map) + enum { IsRowMajor = Base::IsRowMajor }; + + public: + + inline Map(Index rows, Index cols, Index nnz, const Index* outerIndexPtr, + const Index* innerIndexPtr, const Scalar* valuePtr, const Index* innerNonZerosPtr = 0) + : Base(rows, cols, nnz, outerIndexPtr, innerIndexPtr, valuePtr, innerNonZerosPtr) + {} + + /** Empty destructor */ + inline ~Map() {} +}; + +namespace internal { + +template<typename MatScalar, int MatOptions, typename MatIndex, int Options, typename StrideType> +struct evaluator<Map<SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> > + : evaluator<SparseCompressedBase<Map<SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> > > +{ + typedef evaluator<SparseCompressedBase<Map<SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> > > Base; + typedef Map<SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> XprType; + evaluator() : Base() {} + explicit evaluator(const XprType &mat) : Base(mat) {} +}; + +template<typename MatScalar, int MatOptions, typename MatIndex, int Options, typename StrideType> +struct evaluator<Map<const SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> > + : evaluator<SparseCompressedBase<Map<const SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> > > +{ + typedef evaluator<SparseCompressedBase<Map<const SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> > > Base; + typedef Map<const SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> XprType; + evaluator() : Base() {} + explicit evaluator(const XprType &mat) : Base(mat) {} +}; + +} + +} // end namespace Eigen + +#endif // EIGEN_SPARSE_MAP_H |