Eigen  3.3.3
SparseRef.h
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
 All Classes Functions Variables Typedefs Enumerations Enumerator Friends