![]() |
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_REF_H 00011 #define EIGEN_SPARSE_REF_H 00012 00013 namespace Eigen { 00014 00015 enum { 00016 StandardCompressedFormat = 2 00017 }; 00018 00019 namespace internal { 00020 00021 template<typename Derived> class SparseRefBase; 00022 00023 template<typename MatScalar, int MatOptions, typename MatIndex, int _Options, typename _StrideType> 00024 struct traits<Ref<SparseMatrix<MatScalar,MatOptions,MatIndex>, _Options, _StrideType> > 00025 : public traits<SparseMatrix<MatScalar,MatOptions,MatIndex> > 00026 { 00027 typedef SparseMatrix<MatScalar,MatOptions,MatIndex> PlainObjectType; 00028 enum { 00029 Options = _Options, 00030 Flags = traits<PlainObjectType>::Flags | CompressedAccessBit | NestByRefBit 00031 }; 00032 00033 template<typename Derived> struct match { 00034 enum { 00035 StorageOrderMatch = PlainObjectType::IsVectorAtCompileTime || Derived::IsVectorAtCompileTime || ((PlainObjectType::Flags&RowMajorBit)==(Derived::Flags&RowMajorBit)), 00036 MatchAtCompileTime = (Derived::Flags&CompressedAccessBit) && StorageOrderMatch 00037 }; 00038 typedef typename internal::conditional<MatchAtCompileTime,internal::true_type,internal::false_type>::type type; 00039 }; 00040 00041 }; 00042 00043 template<typename MatScalar, int MatOptions, typename MatIndex, int _Options, typename _StrideType> 00044 struct traits<Ref<const SparseMatrix<MatScalar,MatOptions,MatIndex>, _Options, _StrideType> > 00045 : public traits<Ref<SparseMatrix<MatScalar,MatOptions,MatIndex>, _Options, _StrideType> > 00046 { 00047 enum { 00048 Flags = (traits<SparseMatrix<MatScalar,MatOptions,MatIndex> >::Flags | CompressedAccessBit | NestByRefBit) & ~LvalueBit 00049 }; 00050 }; 00051 00052 template<typename MatScalar, int MatOptions, typename MatIndex, int _Options, typename _StrideType> 00053 struct traits<Ref<SparseVector<MatScalar,MatOptions,MatIndex>, _Options, _StrideType> > 00054 : public traits<SparseVector<MatScalar,MatOptions,MatIndex> > 00055 { 00056 typedef SparseVector<MatScalar,MatOptions,MatIndex> PlainObjectType; 00057 enum { 00058 Options = _Options, 00059 Flags = traits<PlainObjectType>::Flags | CompressedAccessBit | NestByRefBit 00060 }; 00061 00062 template<typename Derived> struct match { 00063 enum { 00064 MatchAtCompileTime = (Derived::Flags&CompressedAccessBit) && Derived::IsVectorAtCompileTime 00065 }; 00066 typedef typename internal::conditional<MatchAtCompileTime,internal::true_type,internal::false_type>::type type; 00067 }; 00068 00069 }; 00070 00071 template<typename MatScalar, int MatOptions, typename MatIndex, int _Options, typename _StrideType> 00072 struct traits<Ref<const SparseVector<MatScalar,MatOptions,MatIndex>, _Options, _StrideType> > 00073 : public traits<Ref<SparseVector<MatScalar,MatOptions,MatIndex>, _Options, _StrideType> > 00074 { 00075 enum { 00076 Flags = (traits<SparseVector<MatScalar,MatOptions,MatIndex> >::Flags | CompressedAccessBit | NestByRefBit) & ~LvalueBit 00077 }; 00078 }; 00079 00080 template<typename Derived> 00081 struct traits<SparseRefBase<Derived> > : public traits<Derived> {}; 00082 00083 template<typename Derived> class SparseRefBase 00084 : public SparseMapBase<Derived> 00085 { 00086 public: 00087 00088 typedef SparseMapBase<Derived> Base; 00089 EIGEN_SPARSE_PUBLIC_INTERFACE(SparseRefBase) 00090 00091 SparseRefBase() 00092 : Base(RowsAtCompileTime==Dynamic?0:RowsAtCompileTime,ColsAtCompileTime==Dynamic?0:ColsAtCompileTime, 0, 0, 0, 0, 0) 00093 {} 00094 00095 protected: 00096 00097 template<typename Expression> 00098 void construct(Expression& expr) 00099 { 00100 if(expr.outerIndexPtr()==0) 00101 ::new (static_cast<Base*>(this)) Base(expr.size(), expr.nonZeros(), expr.innerIndexPtr(), expr.valuePtr()); 00102 else 00103 ::new (static_cast<Base*>(this)) Base(expr.rows(), expr.cols(), expr.nonZeros(), expr.outerIndexPtr(), expr.innerIndexPtr(), expr.valuePtr(), expr.innerNonZeroPtr()); 00104 } 00105 }; 00106 00107 } // namespace internal 00108 00109 00121 #ifndef EIGEN_PARSED_BY_DOXYGEN 00122 template<typename MatScalar, int MatOptions, typename MatIndex, int Options, typename StrideType> 00123 class Ref<SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType > 00124 : public internal::SparseRefBase<Ref<SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType > > 00125 #else 00126 template<typename SparseMatrixType, int Options> 00127 class Ref<SparseMatrixType, Options> 00128 : public SparseMapBase<Derived,WriteAccessors> // yes, that's weird to use Derived here, but that works! 00129 #endif 00130 { 00131 typedef SparseMatrix<MatScalar,MatOptions,MatIndex> PlainObjectType; 00132 typedef internal::traits<Ref> Traits; 00133 template<int OtherOptions> 00134 inline Ref(const SparseMatrix<MatScalar,OtherOptions,MatIndex>& expr); 00135 template<int OtherOptions> 00136 inline Ref(const MappedSparseMatrix<MatScalar,OtherOptions,MatIndex>& expr); 00137 public: 00138 00139 typedef internal::SparseRefBase<Ref> Base; 00140 EIGEN_SPARSE_PUBLIC_INTERFACE(Ref) 00141 00142 00143 #ifndef EIGEN_PARSED_BY_DOXYGEN 00144 template<int OtherOptions> 00145 inline Ref(SparseMatrix<MatScalar,OtherOptions,MatIndex>& expr) 00146 { 00147 EIGEN_STATIC_ASSERT(bool(Traits::template match<SparseMatrix<MatScalar,OtherOptions,MatIndex> >::MatchAtCompileTime), STORAGE_LAYOUT_DOES_NOT_MATCH); 00148 eigen_assert( ((Options & int(StandardCompressedFormat))==0) || (expr.isCompressed()) ); 00149 Base::construct(expr.derived()); 00150 } 00151 00152 template<int OtherOptions> 00153 inline Ref(MappedSparseMatrix<MatScalar,OtherOptions,MatIndex>& expr) 00154 { 00155 EIGEN_STATIC_ASSERT(bool(Traits::template match<SparseMatrix<MatScalar,OtherOptions,MatIndex> >::MatchAtCompileTime), STORAGE_LAYOUT_DOES_NOT_MATCH); 00156 eigen_assert( ((Options & int(StandardCompressedFormat))==0) || (expr.isCompressed()) ); 00157 Base::construct(expr.derived()); 00158 } 00159 00160 template<typename Derived> 00161 inline Ref(const SparseCompressedBase<Derived>& expr) 00162 #else 00163 00164 template<typename Derived> 00165 inline Ref(SparseCompressedBase<Derived>& expr) 00166 #endif 00167 { 00168 EIGEN_STATIC_ASSERT(bool(internal::is_lvalue<Derived>::value), THIS_EXPRESSION_IS_NOT_A_LVALUE__IT_IS_READ_ONLY); 00169 EIGEN_STATIC_ASSERT(bool(Traits::template match<Derived>::MatchAtCompileTime), STORAGE_LAYOUT_DOES_NOT_MATCH); 00170 eigen_assert( ((Options & int(StandardCompressedFormat))==0) || (expr.isCompressed()) ); 00171 Base::construct(expr.const_cast_derived()); 00172 } 00173 }; 00174 00175 // this is the const ref version 00176 template<typename MatScalar, int MatOptions, typename MatIndex, int Options, typename StrideType> 00177 class Ref<const SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> 00178 : public internal::SparseRefBase<Ref<const SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> > 00179 { 00180 typedef SparseMatrix<MatScalar,MatOptions,MatIndex> TPlainObjectType; 00181 typedef internal::traits<Ref> Traits; 00182 public: 00183 00184 typedef internal::SparseRefBase<Ref> Base; 00185 EIGEN_SPARSE_PUBLIC_INTERFACE(Ref) 00186 00187 template<typename Derived> 00188 inline Ref(const SparseMatrixBase<Derived>& expr) : m_hasCopy(false) 00189 { 00190 construct(expr.derived(), typename Traits::template match<Derived>::type()); 00191 } 00192 00193 inline Ref(const Ref& other) : Base(other), m_hasCopy(false) { 00194 // copy constructor shall not copy the m_object, to avoid unnecessary malloc and copy 00195 } 00196 00197 template<typename OtherRef> 00198 inline Ref(const RefBase<OtherRef>& other) : m_hasCopy(false) { 00199 construct(other.derived(), typename Traits::template match<OtherRef>::type()); 00200 } 00201 00202 ~Ref() { 00203 if(m_hasCopy) { 00204 TPlainObjectType* obj = reinterpret_cast<TPlainObjectType*>(m_object_bytes); 00205 obj->~TPlainObjectType(); 00206 } 00207 } 00208 00209 protected: 00210 00211 template<typename Expression> 00212 void construct(const Expression& expr,internal::true_type) 00213 { 00214 if((Options & int(StandardCompressedFormat)) && (!expr.isCompressed())) 00215 { 00216 TPlainObjectType* obj = reinterpret_cast<TPlainObjectType*>(m_object_bytes); 00217 ::new (obj) TPlainObjectType(expr); 00218 m_hasCopy = true; 00219 Base::construct(*obj); 00220 } 00221 else 00222 { 00223 Base::construct(expr); 00224 } 00225 } 00226 00227 template<typename Expression> 00228 void construct(const Expression& expr, internal::false_type) 00229 { 00230 TPlainObjectType* obj = reinterpret_cast<TPlainObjectType*>(m_object_bytes); 00231 ::new (obj) TPlainObjectType(expr); 00232 m_hasCopy = true; 00233 Base::construct(*obj); 00234 } 00235 00236 protected: 00237 char m_object_bytes[sizeof(TPlainObjectType)]; 00238 bool m_hasCopy; 00239 }; 00240 00241 00242 00252 #ifndef EIGEN_PARSED_BY_DOXYGEN 00253 template<typename MatScalar, int MatOptions, typename MatIndex, int Options, typename StrideType> 00254 class Ref<SparseVector<MatScalar,MatOptions,MatIndex>, Options, StrideType > 00255 : public internal::SparseRefBase<Ref<SparseVector<MatScalar,MatOptions,MatIndex>, Options, StrideType > > 00256 #else 00257 template<typename SparseVectorType> 00258 class Ref<SparseVectorType> 00259 : public SparseMapBase<Derived,WriteAccessors> 00260 #endif 00261 { 00262 typedef SparseVector<MatScalar,MatOptions,MatIndex> PlainObjectType; 00263 typedef internal::traits<Ref> Traits; 00264 template<int OtherOptions> 00265 inline Ref(const SparseVector<MatScalar,OtherOptions,MatIndex>& expr); 00266 public: 00267 00268 typedef internal::SparseRefBase<Ref> Base; 00269 EIGEN_SPARSE_PUBLIC_INTERFACE(Ref) 00270 00271 #ifndef EIGEN_PARSED_BY_DOXYGEN 00272 template<int OtherOptions> 00273 inline Ref(SparseVector<MatScalar,OtherOptions,MatIndex>& expr) 00274 { 00275 EIGEN_STATIC_ASSERT(bool(Traits::template match<SparseVector<MatScalar,OtherOptions,MatIndex> >::MatchAtCompileTime), STORAGE_LAYOUT_DOES_NOT_MATCH); 00276 Base::construct(expr.derived()); 00277 } 00278 00279 template<typename Derived> 00280 inline Ref(const SparseCompressedBase<Derived>& expr) 00281 #else 00282 00283 template<typename Derived> 00284 inline Ref(SparseCompressedBase<Derived>& expr) 00285 #endif 00286 { 00287 EIGEN_STATIC_ASSERT(bool(internal::is_lvalue<Derived>::value), THIS_EXPRESSION_IS_NOT_A_LVALUE__IT_IS_READ_ONLY); 00288 EIGEN_STATIC_ASSERT(bool(Traits::template match<Derived>::MatchAtCompileTime), STORAGE_LAYOUT_DOES_NOT_MATCH); 00289 Base::construct(expr.const_cast_derived()); 00290 } 00291 }; 00292 00293 // this is the const ref version 00294 template<typename MatScalar, int MatOptions, typename MatIndex, int Options, typename StrideType> 00295 class Ref<const SparseVector<MatScalar,MatOptions,MatIndex>, Options, StrideType> 00296 : public internal::SparseRefBase<Ref<const SparseVector<MatScalar,MatOptions,MatIndex>, Options, StrideType> > 00297 { 00298 typedef SparseVector<MatScalar,MatOptions,MatIndex> TPlainObjectType; 00299 typedef internal::traits<Ref> Traits; 00300 public: 00301 00302 typedef internal::SparseRefBase<Ref> Base; 00303 EIGEN_SPARSE_PUBLIC_INTERFACE(Ref) 00304 00305 template<typename Derived> 00306 inline Ref(const SparseMatrixBase<Derived>& expr) : m_hasCopy(false) 00307 { 00308 construct(expr.derived(), typename Traits::template match<Derived>::type()); 00309 } 00310 00311 inline Ref(const Ref& other) : Base(other), m_hasCopy(false) { 00312 // copy constructor shall not copy the m_object, to avoid unnecessary malloc and copy 00313 } 00314 00315 template<typename OtherRef> 00316 inline Ref(const RefBase<OtherRef>& other) : m_hasCopy(false) { 00317 construct(other.derived(), typename Traits::template match<OtherRef>::type()); 00318 } 00319 00320 ~Ref() { 00321 if(m_hasCopy) { 00322 TPlainObjectType* obj = reinterpret_cast<TPlainObjectType*>(m_object_bytes); 00323 obj->~TPlainObjectType(); 00324 } 00325 } 00326 00327 protected: 00328 00329 template<typename Expression> 00330 void construct(const Expression& expr,internal::true_type) 00331 { 00332 Base::construct(expr); 00333 } 00334 00335 template<typename Expression> 00336 void construct(const Expression& expr, internal::false_type) 00337 { 00338 TPlainObjectType* obj = reinterpret_cast<TPlainObjectType*>(m_object_bytes); 00339 ::new (obj) TPlainObjectType(expr); 00340 m_hasCopy = true; 00341 Base::construct(*obj); 00342 } 00343 00344 protected: 00345 char m_object_bytes[sizeof(TPlainObjectType)]; 00346 bool m_hasCopy; 00347 }; 00348 00349 namespace internal { 00350 00351 // FIXME shall we introduce a general evaluatior_ref that we can specialize for any sparse object once, and thus remove this copy-pasta thing... 00352 00353 template<typename MatScalar, int MatOptions, typename MatIndex, int Options, typename StrideType> 00354 struct evaluator<Ref<SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> > 00355 : evaluator<SparseCompressedBase<Ref<SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> > > 00356 { 00357 typedef evaluator<SparseCompressedBase<Ref<SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> > > Base; 00358 typedef Ref<SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> XprType; 00359 evaluator() : Base() {} 00360 explicit evaluator(const XprType &mat) : Base(mat) {} 00361 }; 00362 00363 template<typename MatScalar, int MatOptions, typename MatIndex, int Options, typename StrideType> 00364 struct evaluator<Ref<const SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> > 00365 : evaluator<SparseCompressedBase<Ref<const SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> > > 00366 { 00367 typedef evaluator<SparseCompressedBase<Ref<const SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> > > Base; 00368 typedef Ref<const SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> XprType; 00369 evaluator() : Base() {} 00370 explicit evaluator(const XprType &mat) : Base(mat) {} 00371 }; 00372 00373 template<typename MatScalar, int MatOptions, typename MatIndex, int Options, typename StrideType> 00374 struct evaluator<Ref<SparseVector<MatScalar,MatOptions,MatIndex>, Options, StrideType> > 00375 : evaluator<SparseCompressedBase<Ref<SparseVector<MatScalar,MatOptions,MatIndex>, Options, StrideType> > > 00376 { 00377 typedef evaluator<SparseCompressedBase<Ref<SparseVector<MatScalar,MatOptions,MatIndex>, Options, StrideType> > > Base; 00378 typedef Ref<SparseVector<MatScalar,MatOptions,MatIndex>, Options, StrideType> XprType; 00379 evaluator() : Base() {} 00380 explicit evaluator(const XprType &mat) : Base(mat) {} 00381 }; 00382 00383 template<typename MatScalar, int MatOptions, typename MatIndex, int Options, typename StrideType> 00384 struct evaluator<Ref<const SparseVector<MatScalar,MatOptions,MatIndex>, Options, StrideType> > 00385 : evaluator<SparseCompressedBase<Ref<const SparseVector<MatScalar,MatOptions,MatIndex>, Options, StrideType> > > 00386 { 00387 typedef evaluator<SparseCompressedBase<Ref<const SparseVector<MatScalar,MatOptions,MatIndex>, Options, StrideType> > > Base; 00388 typedef Ref<const SparseVector<MatScalar,MatOptions,MatIndex>, Options, StrideType> XprType; 00389 evaluator() : Base() {} 00390 explicit evaluator(const XprType &mat) : Base(mat) {} 00391 }; 00392 00393 } 00394 00395 } // end namespace Eigen 00396 00397 #endif // EIGEN_SPARSE_REF_H