MOAB  4.9.3pre
SparseRef.h
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines