![]() |
Eigen
3.3.3
|
00001 // This file is part of Eigen, a lightweight C++ template library 00002 // for linear algebra. 00003 // 00004 // Copyright (C) 2015 Gael Guennebaud <gael.guennebaud@inria.fr> 00005 // 00006 // This Source Code Form is subject to the terms of the Mozilla 00007 // Public License v. 2.0. If a copy of the MPL was not distributed 00008 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 00009 00010 #ifndef EIGEN_SPARSE_MAP_H 00011 #define EIGEN_SPARSE_MAP_H 00012 00013 namespace Eigen { 00014 00015 namespace internal { 00016 00017 template<typename MatScalar, int MatOptions, typename MatIndex, int Options, typename StrideType> 00018 struct traits<Map<SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> > 00019 : public traits<SparseMatrix<MatScalar,MatOptions,MatIndex> > 00020 { 00021 typedef SparseMatrix<MatScalar,MatOptions,MatIndex> PlainObjectType; 00022 typedef traits<PlainObjectType> TraitsBase; 00023 enum { 00024 Flags = TraitsBase::Flags & (~NestByRefBit) 00025 }; 00026 }; 00027 00028 template<typename MatScalar, int MatOptions, typename MatIndex, int Options, typename StrideType> 00029 struct traits<Map<const SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> > 00030 : public traits<SparseMatrix<MatScalar,MatOptions,MatIndex> > 00031 { 00032 typedef SparseMatrix<MatScalar,MatOptions,MatIndex> PlainObjectType; 00033 typedef traits<PlainObjectType> TraitsBase; 00034 enum { 00035 Flags = TraitsBase::Flags & (~ (NestByRefBit | LvalueBit)) 00036 }; 00037 }; 00038 00039 } // end namespace internal 00040 00041 template<typename Derived, 00042 int Level = internal::accessors_level<Derived>::has_write_access ? WriteAccessors : ReadOnlyAccessors 00043 > class SparseMapBase; 00044 00049 template<typename Derived> 00050 class SparseMapBase<Derived,ReadOnlyAccessors> 00051 : public SparseCompressedBase<Derived> 00052 { 00053 public: 00054 typedef SparseCompressedBase<Derived> Base; 00055 typedef typename Base::Scalar Scalar; 00056 typedef typename Base::StorageIndex StorageIndex; 00057 enum { IsRowMajor = Base::IsRowMajor }; 00058 using Base::operator=; 00059 protected: 00060 00061 typedef typename internal::conditional< 00062 bool(internal::is_lvalue<Derived>::value), 00063 Scalar *, const Scalar *>::type ScalarPointer; 00064 typedef typename internal::conditional< 00065 bool(internal::is_lvalue<Derived>::value), 00066 StorageIndex *, const StorageIndex *>::type IndexPointer; 00067 00068 Index m_outerSize; 00069 Index m_innerSize; 00070 Array<StorageIndex,2,1> m_zero_nnz; 00071 IndexPointer m_outerIndex; 00072 IndexPointer m_innerIndices; 00073 ScalarPointer m_values; 00074 IndexPointer m_innerNonZeros; 00075 00076 public: 00077 00079 inline Index rows() const { return IsRowMajor ? m_outerSize : m_innerSize; } 00081 inline Index cols() const { return IsRowMajor ? m_innerSize : m_outerSize; } 00083 inline Index innerSize() const { return m_innerSize; } 00085 inline Index outerSize() const { return m_outerSize; } 00087 inline Index nonZeros() const { return m_zero_nnz[1]; } 00088 00090 bool isCompressed() const { return m_innerNonZeros==0; } 00091 00092 //---------------------------------------- 00093 // direct access interface 00095 inline const Scalar* valuePtr() const { return m_values; } 00097 inline const StorageIndex* innerIndexPtr() const { return m_innerIndices; } 00099 inline const StorageIndex* outerIndexPtr() const { return m_outerIndex; } 00101 inline const StorageIndex* innerNonZeroPtr() const { return m_innerNonZeros; } 00102 //---------------------------------------- 00103 00105 inline Scalar coeff(Index row, Index col) const 00106 { 00107 const Index outer = IsRowMajor ? row : col; 00108 const Index inner = IsRowMajor ? col : row; 00109 00110 Index start = m_outerIndex[outer]; 00111 Index end = isCompressed() ? m_outerIndex[outer+1] : start + m_innerNonZeros[outer]; 00112 if (start==end) 00113 return Scalar(0); 00114 else if (end>0 && inner==m_innerIndices[end-1]) 00115 return m_values[end-1]; 00116 // ^^ optimization: let's first check if it is the last coefficient 00117 // (very common in high level algorithms) 00118 00119 const StorageIndex* r = std::lower_bound(&m_innerIndices[start],&m_innerIndices[end-1],inner); 00120 const Index id = r-&m_innerIndices[0]; 00121 return ((*r==inner) && (id<end)) ? m_values[id] : Scalar(0); 00122 } 00123 00124 inline SparseMapBase(Index rows, Index cols, Index nnz, IndexPointer outerIndexPtr, IndexPointer innerIndexPtr, 00125 ScalarPointer valuePtr, IndexPointer innerNonZerosPtr = 0) 00126 : m_outerSize(IsRowMajor?rows:cols), m_innerSize(IsRowMajor?cols:rows), m_zero_nnz(0,internal::convert_index<StorageIndex>(nnz)), m_outerIndex(outerIndexPtr), 00127 m_innerIndices(innerIndexPtr), m_values(valuePtr), m_innerNonZeros(innerNonZerosPtr) 00128 {} 00129 00130 // for vectors 00131 inline SparseMapBase(Index size, Index nnz, IndexPointer innerIndexPtr, ScalarPointer valuePtr) 00132 : m_outerSize(1), m_innerSize(size), m_zero_nnz(0,internal::convert_index<StorageIndex>(nnz)), m_outerIndex(m_zero_nnz.data()), 00133 m_innerIndices(innerIndexPtr), m_values(valuePtr), m_innerNonZeros(0) 00134 {} 00135 00137 inline ~SparseMapBase() {} 00138 00139 protected: 00140 inline SparseMapBase() {} 00141 }; 00142 00147 template<typename Derived> 00148 class SparseMapBase<Derived,WriteAccessors> 00149 : public SparseMapBase<Derived,ReadOnlyAccessors> 00150 { 00151 typedef MapBase<Derived, ReadOnlyAccessors> ReadOnlyMapBase; 00152 00153 public: 00154 typedef SparseMapBase<Derived, ReadOnlyAccessors> Base; 00155 typedef typename Base::Scalar Scalar; 00156 typedef typename Base::StorageIndex StorageIndex; 00157 enum { IsRowMajor = Base::IsRowMajor }; 00158 00159 using Base::operator=; 00160 00161 public: 00162 00163 //---------------------------------------- 00164 // direct access interface 00165 using Base::valuePtr; 00166 using Base::innerIndexPtr; 00167 using Base::outerIndexPtr; 00168 using Base::innerNonZeroPtr; 00170 inline Scalar* valuePtr() { return Base::m_values; } 00172 inline StorageIndex* innerIndexPtr() { return Base::m_innerIndices; } 00174 inline StorageIndex* outerIndexPtr() { return Base::m_outerIndex; } 00176 inline StorageIndex* innerNonZeroPtr() { return Base::m_innerNonZeros; } 00177 //---------------------------------------- 00178 00180 inline Scalar& coeffRef(Index row, Index col) 00181 { 00182 const Index outer = IsRowMajor ? row : col; 00183 const Index inner = IsRowMajor ? col : row; 00184 00185 Index start = Base::m_outerIndex[outer]; 00186 Index end = Base::isCompressed() ? Base::m_outerIndex[outer+1] : start + Base::m_innerNonZeros[outer]; 00187 eigen_assert(end>=start && "you probably called coeffRef on a non finalized matrix"); 00188 eigen_assert(end>start && "coeffRef cannot be called on a zero coefficient"); 00189 StorageIndex* r = std::lower_bound(&Base::m_innerIndices[start],&Base::m_innerIndices[end],inner); 00190 const Index id = r - &Base::m_innerIndices[0]; 00191 eigen_assert((*r==inner) && (id<end) && "coeffRef cannot be called on a zero coefficient"); 00192 return const_cast<Scalar*>(Base::m_values)[id]; 00193 } 00194 00195 inline SparseMapBase(Index rows, Index cols, Index nnz, StorageIndex* outerIndexPtr, StorageIndex* innerIndexPtr, 00196 Scalar* valuePtr, StorageIndex* innerNonZerosPtr = 0) 00197 : Base(rows, cols, nnz, outerIndexPtr, innerIndexPtr, valuePtr, innerNonZerosPtr) 00198 {} 00199 00200 // for vectors 00201 inline SparseMapBase(Index size, Index nnz, StorageIndex* innerIndexPtr, Scalar* valuePtr) 00202 : Base(size, nnz, innerIndexPtr, valuePtr) 00203 {} 00204 00206 inline ~SparseMapBase() {} 00207 00208 protected: 00209 inline SparseMapBase() {} 00210 }; 00211 00220 #ifndef EIGEN_PARSED_BY_DOXYGEN 00221 template<typename MatScalar, int MatOptions, typename MatIndex, int Options, typename StrideType> 00222 class Map<SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> 00223 : public SparseMapBase<Map<SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> > 00224 #else 00225 template<typename SparseMatrixType> 00226 class Map<SparseMatrixType> 00227 : public SparseMapBase<Derived,WriteAccessors> 00228 #endif 00229 { 00230 public: 00231 typedef SparseMapBase<Map> Base; 00232 EIGEN_SPARSE_PUBLIC_INTERFACE(Map) 00233 enum { IsRowMajor = Base::IsRowMajor }; 00234 00235 public: 00236 00245 inline Map(Index rows, Index cols, Index nnz, StorageIndex* outerIndexPtr, 00246 StorageIndex* innerIndexPtr, Scalar* valuePtr, StorageIndex* innerNonZerosPtr = 0) 00247 : Base(rows, cols, nnz, outerIndexPtr, innerIndexPtr, valuePtr, innerNonZerosPtr) 00248 {} 00249 #ifndef EIGEN_PARSED_BY_DOXYGEN 00250 00251 inline ~Map() {} 00252 }; 00253 00254 template<typename MatScalar, int MatOptions, typename MatIndex, int Options, typename StrideType> 00255 class Map<const SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> 00256 : public SparseMapBase<Map<const SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> > 00257 { 00258 public: 00259 typedef SparseMapBase<Map> Base; 00260 EIGEN_SPARSE_PUBLIC_INTERFACE(Map) 00261 enum { IsRowMajor = Base::IsRowMajor }; 00262 00263 public: 00264 #endif 00265 00270 inline Map(Index rows, Index cols, Index nnz, const StorageIndex* outerIndexPtr, 00271 const StorageIndex* innerIndexPtr, const Scalar* valuePtr, const StorageIndex* innerNonZerosPtr = 0) 00272 : Base(rows, cols, nnz, outerIndexPtr, innerIndexPtr, valuePtr, innerNonZerosPtr) 00273 {} 00274 00276 inline ~Map() {} 00277 }; 00278 00279 namespace internal { 00280 00281 template<typename MatScalar, int MatOptions, typename MatIndex, int Options, typename StrideType> 00282 struct evaluator<Map<SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> > 00283 : evaluator<SparseCompressedBase<Map<SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> > > 00284 { 00285 typedef evaluator<SparseCompressedBase<Map<SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> > > Base; 00286 typedef Map<SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> XprType; 00287 evaluator() : Base() {} 00288 explicit evaluator(const XprType &mat) : Base(mat) {} 00289 }; 00290 00291 template<typename MatScalar, int MatOptions, typename MatIndex, int Options, typename StrideType> 00292 struct evaluator<Map<const SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> > 00293 : evaluator<SparseCompressedBase<Map<const SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> > > 00294 { 00295 typedef evaluator<SparseCompressedBase<Map<const SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> > > Base; 00296 typedef Map<const SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> XprType; 00297 evaluator() : Base() {} 00298 explicit evaluator(const XprType &mat) : Base(mat) {} 00299 }; 00300 00301 } 00302 00303 } // end namespace Eigen 00304 00305 #endif // EIGEN_SPARSE_MAP_H