MOAB
4.9.3pre
|
00001 // This file is part of Eigen, a lightweight C++ template library 00002 // for linear algebra. 00003 // 00004 // Copyright (C) 2015 Gael Guennebaud <[email protected]> 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) 00189 { 00190 construct(expr.derived(), typename Traits::template match<Derived>::type()); 00191 } 00192 00193 inline Ref(const Ref& other) : Base(other) { 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) { 00199 construct(other.derived(), typename Traits::template match<OtherRef>::type()); 00200 } 00201 00202 protected: 00203 00204 template<typename Expression> 00205 void construct(const Expression& expr,internal::true_type) 00206 { 00207 if((Options & int(StandardCompressedFormat)) && (!expr.isCompressed())) 00208 { 00209 TPlainObjectType* obj = reinterpret_cast<TPlainObjectType*>(m_object_bytes); 00210 ::new (obj) TPlainObjectType(expr); 00211 Base::construct(*obj); 00212 } 00213 else 00214 { 00215 Base::construct(expr); 00216 } 00217 } 00218 00219 template<typename Expression> 00220 void construct(const Expression& expr, internal::false_type) 00221 { 00222 TPlainObjectType* obj = reinterpret_cast<TPlainObjectType*>(m_object_bytes); 00223 ::new (obj) TPlainObjectType(expr); 00224 Base::construct(*obj); 00225 } 00226 00227 protected: 00228 char m_object_bytes[sizeof(TPlainObjectType)]; 00229 }; 00230 00231 00232 00242 #ifndef EIGEN_PARSED_BY_DOXYGEN 00243 template<typename MatScalar, int MatOptions, typename MatIndex, int Options, typename StrideType> 00244 class Ref<SparseVector<MatScalar,MatOptions,MatIndex>, Options, StrideType > 00245 : public internal::SparseRefBase<Ref<SparseVector<MatScalar,MatOptions,MatIndex>, Options, StrideType > > 00246 #else 00247 template<typename SparseVectorType> 00248 class Ref<SparseVectorType> 00249 : public SparseMapBase<Derived,WriteAccessors> 00250 #endif 00251 { 00252 typedef SparseVector<MatScalar,MatOptions,MatIndex> PlainObjectType; 00253 typedef internal::traits<Ref> Traits; 00254 template<int OtherOptions> 00255 inline Ref(const SparseVector<MatScalar,OtherOptions,MatIndex>& expr); 00256 public: 00257 00258 typedef internal::SparseRefBase<Ref> Base; 00259 EIGEN_SPARSE_PUBLIC_INTERFACE(Ref) 00260 00261 #ifndef EIGEN_PARSED_BY_DOXYGEN 00262 template<int OtherOptions> 00263 inline Ref(SparseVector<MatScalar,OtherOptions,MatIndex>& expr) 00264 { 00265 EIGEN_STATIC_ASSERT(bool(Traits::template match<SparseVector<MatScalar,OtherOptions,MatIndex> >::MatchAtCompileTime), STORAGE_LAYOUT_DOES_NOT_MATCH); 00266 Base::construct(expr.derived()); 00267 } 00268 00269 template<typename Derived> 00270 inline Ref(const SparseCompressedBase<Derived>& expr) 00271 #else 00272 00273 template<typename Derived> 00274 inline Ref(SparseCompressedBase<Derived>& expr) 00275 #endif 00276 { 00277 EIGEN_STATIC_ASSERT(bool(internal::is_lvalue<Derived>::value), THIS_EXPRESSION_IS_NOT_A_LVALUE__IT_IS_READ_ONLY); 00278 EIGEN_STATIC_ASSERT(bool(Traits::template match<Derived>::MatchAtCompileTime), STORAGE_LAYOUT_DOES_NOT_MATCH); 00279 Base::construct(expr.const_cast_derived()); 00280 } 00281 }; 00282 00283 // this is the const ref version 00284 template<typename MatScalar, int MatOptions, typename MatIndex, int Options, typename StrideType> 00285 class Ref<const SparseVector<MatScalar,MatOptions,MatIndex>, Options, StrideType> 00286 : public internal::SparseRefBase<Ref<const SparseVector<MatScalar,MatOptions,MatIndex>, Options, StrideType> > 00287 { 00288 typedef SparseVector<MatScalar,MatOptions,MatIndex> TPlainObjectType; 00289 typedef internal::traits<Ref> Traits; 00290 public: 00291 00292 typedef internal::SparseRefBase<Ref> Base; 00293 EIGEN_SPARSE_PUBLIC_INTERFACE(Ref) 00294 00295 template<typename Derived> 00296 inline Ref(const SparseMatrixBase<Derived>& expr) 00297 { 00298 construct(expr.derived(), typename Traits::template match<Derived>::type()); 00299 } 00300 00301 inline Ref(const Ref& other) : Base(other) { 00302 // copy constructor shall not copy the m_object, to avoid unnecessary malloc and copy 00303 } 00304 00305 template<typename OtherRef> 00306 inline Ref(const RefBase<OtherRef>& other) { 00307 construct(other.derived(), typename Traits::template match<OtherRef>::type()); 00308 } 00309 00310 protected: 00311 00312 template<typename Expression> 00313 void construct(const Expression& expr,internal::true_type) 00314 { 00315 Base::construct(expr); 00316 } 00317 00318 template<typename Expression> 00319 void construct(const Expression& expr, internal::false_type) 00320 { 00321 TPlainObjectType* obj = reinterpret_cast<TPlainObjectType*>(m_object_bytes); 00322 ::new (obj) TPlainObjectType(expr); 00323 Base::construct(*obj); 00324 } 00325 00326 protected: 00327 char m_object_bytes[sizeof(TPlainObjectType)]; 00328 }; 00329 00330 namespace internal { 00331 00332 // FIXME shall we introduce a general evaluatior_ref that we can specialize for any sparse object once, and thus remove this copy-pasta thing... 00333 00334 template<typename MatScalar, int MatOptions, typename MatIndex, int Options, typename StrideType> 00335 struct evaluator<Ref<SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> > 00336 : evaluator<SparseCompressedBase<Ref<SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> > > 00337 { 00338 typedef evaluator<SparseCompressedBase<Ref<SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> > > Base; 00339 typedef Ref<SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> XprType; 00340 evaluator() : Base() {} 00341 explicit evaluator(const XprType &mat) : Base(mat) {} 00342 }; 00343 00344 template<typename MatScalar, int MatOptions, typename MatIndex, int Options, typename StrideType> 00345 struct evaluator<Ref<const SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> > 00346 : evaluator<SparseCompressedBase<Ref<const SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> > > 00347 { 00348 typedef evaluator<SparseCompressedBase<Ref<const SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> > > Base; 00349 typedef Ref<const SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> XprType; 00350 evaluator() : Base() {} 00351 explicit evaluator(const XprType &mat) : Base(mat) {} 00352 }; 00353 00354 template<typename MatScalar, int MatOptions, typename MatIndex, int Options, typename StrideType> 00355 struct evaluator<Ref<SparseVector<MatScalar,MatOptions,MatIndex>, Options, StrideType> > 00356 : evaluator<SparseCompressedBase<Ref<SparseVector<MatScalar,MatOptions,MatIndex>, Options, StrideType> > > 00357 { 00358 typedef evaluator<SparseCompressedBase<Ref<SparseVector<MatScalar,MatOptions,MatIndex>, Options, StrideType> > > Base; 00359 typedef Ref<SparseVector<MatScalar,MatOptions,MatIndex>, Options, StrideType> XprType; 00360 evaluator() : Base() {} 00361 explicit evaluator(const XprType &mat) : Base(mat) {} 00362 }; 00363 00364 template<typename MatScalar, int MatOptions, typename MatIndex, int Options, typename StrideType> 00365 struct evaluator<Ref<const SparseVector<MatScalar,MatOptions,MatIndex>, Options, StrideType> > 00366 : evaluator<SparseCompressedBase<Ref<const SparseVector<MatScalar,MatOptions,MatIndex>, Options, StrideType> > > 00367 { 00368 typedef evaluator<SparseCompressedBase<Ref<const SparseVector<MatScalar,MatOptions,MatIndex>, Options, StrideType> > > Base; 00369 typedef Ref<const SparseVector<MatScalar,MatOptions,MatIndex>, Options, StrideType> XprType; 00370 evaluator() : Base() {} 00371 explicit evaluator(const XprType &mat) : Base(mat) {} 00372 }; 00373 00374 } 00375 00376 } // end namespace Eigen 00377 00378 #endif // EIGEN_SPARSE_REF_H