Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-02-22 10:34:44

0001 // This file is part of Eigen, a lightweight C++ template library
0002 // for linear algebra.
0003 //
0004 // Copyright (C) 2015 Gael Guennebaud <gael.guennebaud@inria.fr>
0005 //
0006 // This Source Code Form is subject to the terms of the Mozilla
0007 // Public License v. 2.0. If a copy of the MPL was not distributed
0008 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
0009 
0010 #ifndef EIGEN_SPARSE_REF_H
0011 #define EIGEN_SPARSE_REF_H
0012 
0013 namespace Eigen {
0014 
0015 enum {
0016   StandardCompressedFormat = 2 /**< used by Ref<SparseMatrix> to specify whether the input storage must be in standard compressed form */
0017 };
0018   
0019 namespace internal {
0020 
0021 template<typename Derived> class SparseRefBase;
0022 
0023 template<typename MatScalar, int MatOptions, typename MatIndex, int _Options, typename _StrideType>
0024 struct traits<Ref<SparseMatrix<MatScalar,MatOptions,MatIndex>, _Options, _StrideType> >
0025   : public traits<SparseMatrix<MatScalar,MatOptions,MatIndex> >
0026 {
0027   typedef SparseMatrix<MatScalar,MatOptions,MatIndex> PlainObjectType;
0028   enum {
0029     Options = _Options,
0030     Flags = traits<PlainObjectType>::Flags | CompressedAccessBit | NestByRefBit
0031   };
0032 
0033   template<typename Derived> struct match {
0034     enum {
0035       StorageOrderMatch = PlainObjectType::IsVectorAtCompileTime || Derived::IsVectorAtCompileTime || ((PlainObjectType::Flags&RowMajorBit)==(Derived::Flags&RowMajorBit)),
0036       MatchAtCompileTime = (Derived::Flags&CompressedAccessBit) && StorageOrderMatch
0037     };
0038     typedef typename internal::conditional<MatchAtCompileTime,internal::true_type,internal::false_type>::type type;
0039   };
0040   
0041 };
0042 
0043 template<typename MatScalar, int MatOptions, typename MatIndex, int _Options, typename _StrideType>
0044 struct traits<Ref<const SparseMatrix<MatScalar,MatOptions,MatIndex>, _Options, _StrideType> >
0045   : public traits<Ref<SparseMatrix<MatScalar,MatOptions,MatIndex>, _Options, _StrideType> >
0046 {
0047   enum {
0048     Flags = (traits<SparseMatrix<MatScalar,MatOptions,MatIndex> >::Flags | CompressedAccessBit | NestByRefBit) & ~LvalueBit
0049   };
0050 };
0051 
0052 template<typename MatScalar, int MatOptions, typename MatIndex, int _Options, typename _StrideType>
0053 struct traits<Ref<SparseVector<MatScalar,MatOptions,MatIndex>, _Options, _StrideType> >
0054   : public traits<SparseVector<MatScalar,MatOptions,MatIndex> >
0055 {
0056   typedef SparseVector<MatScalar,MatOptions,MatIndex> PlainObjectType;
0057   enum {
0058     Options = _Options,
0059     Flags = traits<PlainObjectType>::Flags | CompressedAccessBit | NestByRefBit
0060   };
0061 
0062   template<typename Derived> struct match {
0063     enum {
0064       MatchAtCompileTime = (Derived::Flags&CompressedAccessBit) && Derived::IsVectorAtCompileTime
0065     };
0066     typedef typename internal::conditional<MatchAtCompileTime,internal::true_type,internal::false_type>::type type;
0067   };
0068 
0069 };
0070 
0071 template<typename MatScalar, int MatOptions, typename MatIndex, int _Options, typename _StrideType>
0072 struct traits<Ref<const SparseVector<MatScalar,MatOptions,MatIndex>, _Options, _StrideType> >
0073   : public traits<Ref<SparseVector<MatScalar,MatOptions,MatIndex>, _Options, _StrideType> >
0074 {
0075   enum {
0076     Flags = (traits<SparseVector<MatScalar,MatOptions,MatIndex> >::Flags | CompressedAccessBit | NestByRefBit) & ~LvalueBit
0077   };
0078 };
0079 
0080 template<typename Derived>
0081 struct traits<SparseRefBase<Derived> > : public traits<Derived> {};
0082 
0083 template<typename Derived> class SparseRefBase
0084   : public SparseMapBase<Derived>
0085 {
0086 public:
0087 
0088   typedef SparseMapBase<Derived> Base;
0089   EIGEN_SPARSE_PUBLIC_INTERFACE(SparseRefBase)
0090 
0091   SparseRefBase()
0092     : Base(RowsAtCompileTime==Dynamic?0:RowsAtCompileTime,ColsAtCompileTime==Dynamic?0:ColsAtCompileTime, 0, 0, 0, 0, 0)
0093   {}
0094   
0095 protected:
0096 
0097   template<typename Expression>
0098   void construct(Expression& expr)
0099   {
0100     if(expr.outerIndexPtr()==0)
0101       ::new (static_cast<Base*>(this)) Base(expr.size(), expr.nonZeros(), expr.innerIndexPtr(), expr.valuePtr());
0102     else
0103       ::new (static_cast<Base*>(this)) Base(expr.rows(), expr.cols(), expr.nonZeros(), expr.outerIndexPtr(), expr.innerIndexPtr(), expr.valuePtr(), expr.innerNonZeroPtr());
0104   }
0105 };
0106 
0107 } // namespace internal
0108 
0109 
0110 /** 
0111   * \ingroup SparseCore_Module
0112   *
0113   * \brief A sparse matrix expression referencing an existing sparse expression
0114   *
0115   * \tparam SparseMatrixType the equivalent sparse matrix type of the referenced data, it must be a template instance of class SparseMatrix.
0116   * \tparam Options specifies whether the a standard compressed format is required \c Options is  \c #StandardCompressedFormat, or \c 0.
0117   *                The default is \c 0.
0118   *
0119   * \sa class Ref
0120   */
0121 #ifndef EIGEN_PARSED_BY_DOXYGEN
0122 template<typename MatScalar, int MatOptions, typename MatIndex, int Options, typename StrideType>
0123 class Ref<SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType >
0124   : public internal::SparseRefBase<Ref<SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType > >
0125 #else
0126 template<typename SparseMatrixType, int Options>
0127 class Ref<SparseMatrixType, Options>
0128   : public SparseMapBase<Derived,WriteAccessors> // yes, that's weird to use Derived here, but that works!
0129 #endif
0130 {
0131     typedef SparseMatrix<MatScalar,MatOptions,MatIndex> PlainObjectType;
0132     typedef internal::traits<Ref> Traits;
0133     template<int OtherOptions>
0134     inline Ref(const SparseMatrix<MatScalar,OtherOptions,MatIndex>& expr);
0135     template<int OtherOptions>
0136     inline Ref(const MappedSparseMatrix<MatScalar,OtherOptions,MatIndex>& expr);
0137   public:
0138 
0139     typedef internal::SparseRefBase<Ref> Base;
0140     EIGEN_SPARSE_PUBLIC_INTERFACE(Ref)
0141 
0142 
0143     #ifndef EIGEN_PARSED_BY_DOXYGEN
0144     template<int OtherOptions>
0145     inline Ref(SparseMatrix<MatScalar,OtherOptions,MatIndex>& expr)
0146     {
0147       EIGEN_STATIC_ASSERT(bool(Traits::template match<SparseMatrix<MatScalar,OtherOptions,MatIndex> >::MatchAtCompileTime), STORAGE_LAYOUT_DOES_NOT_MATCH);
0148       eigen_assert( ((Options & int(StandardCompressedFormat))==0) || (expr.isCompressed()) );
0149       Base::construct(expr.derived());
0150     }
0151     
0152     template<int OtherOptions>
0153     inline Ref(MappedSparseMatrix<MatScalar,OtherOptions,MatIndex>& expr)
0154     {
0155       EIGEN_STATIC_ASSERT(bool(Traits::template match<SparseMatrix<MatScalar,OtherOptions,MatIndex> >::MatchAtCompileTime), STORAGE_LAYOUT_DOES_NOT_MATCH);
0156       eigen_assert( ((Options & int(StandardCompressedFormat))==0) || (expr.isCompressed()) );
0157       Base::construct(expr.derived());
0158     }
0159     
0160     template<typename Derived>
0161     inline Ref(const SparseCompressedBase<Derived>& expr)
0162     #else
0163     /** Implicit constructor from any sparse expression (2D matrix or 1D vector) */
0164     template<typename Derived>
0165     inline Ref(SparseCompressedBase<Derived>& expr)
0166     #endif
0167     {
0168       EIGEN_STATIC_ASSERT(bool(internal::is_lvalue<Derived>::value), THIS_EXPRESSION_IS_NOT_A_LVALUE__IT_IS_READ_ONLY);
0169       EIGEN_STATIC_ASSERT(bool(Traits::template match<Derived>::MatchAtCompileTime), STORAGE_LAYOUT_DOES_NOT_MATCH);
0170       eigen_assert( ((Options & int(StandardCompressedFormat))==0) || (expr.isCompressed()) );
0171       Base::construct(expr.const_cast_derived());
0172     }
0173 };
0174 
0175 // this is the const ref version
0176 template<typename MatScalar, int MatOptions, typename MatIndex, int Options, typename StrideType>
0177 class Ref<const SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType>
0178   : public internal::SparseRefBase<Ref<const SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> >
0179 {
0180     typedef SparseMatrix<MatScalar,MatOptions,MatIndex> TPlainObjectType;
0181     typedef internal::traits<Ref> Traits;
0182   public:
0183 
0184     typedef internal::SparseRefBase<Ref> Base;
0185     EIGEN_SPARSE_PUBLIC_INTERFACE(Ref)
0186 
0187     template<typename Derived>
0188     inline Ref(const SparseMatrixBase<Derived>& expr) : m_hasCopy(false)
0189     {
0190       construct(expr.derived(), typename Traits::template match<Derived>::type());
0191     }
0192 
0193     inline Ref(const Ref& other) : Base(other), m_hasCopy(false) {
0194       // copy constructor shall not copy the m_object, to avoid unnecessary malloc and copy
0195     }
0196 
0197     template<typename OtherRef>
0198     inline Ref(const RefBase<OtherRef>& other) : m_hasCopy(false) {
0199       construct(other.derived(), typename Traits::template match<OtherRef>::type());
0200     }
0201 
0202     ~Ref() {
0203       if(m_hasCopy) {
0204         TPlainObjectType* obj = reinterpret_cast<TPlainObjectType*>(&m_storage);
0205         obj->~TPlainObjectType();
0206       }
0207     }
0208 
0209   protected:
0210 
0211     template<typename Expression>
0212     void construct(const Expression& expr,internal::true_type)
0213     {
0214       if((Options & int(StandardCompressedFormat)) && (!expr.isCompressed()))
0215       {
0216         TPlainObjectType* obj = reinterpret_cast<TPlainObjectType*>(&m_storage);
0217         ::new (obj) TPlainObjectType(expr);
0218         m_hasCopy = true;
0219         Base::construct(*obj);
0220       }
0221       else
0222       {
0223         Base::construct(expr);
0224       }
0225     }
0226 
0227     template<typename Expression>
0228     void construct(const Expression& expr, internal::false_type)
0229     {
0230       TPlainObjectType* obj = reinterpret_cast<TPlainObjectType*>(&m_storage);
0231       ::new (obj) TPlainObjectType(expr);
0232       m_hasCopy = true;
0233       Base::construct(*obj);
0234     }
0235 
0236   protected:
0237     typename internal::aligned_storage<sizeof(TPlainObjectType), EIGEN_ALIGNOF(TPlainObjectType)>::type m_storage;
0238     bool m_hasCopy;
0239 };
0240 
0241 
0242 
0243 /**
0244   * \ingroup SparseCore_Module
0245   *
0246   * \brief A sparse vector expression referencing an existing sparse vector expression
0247   *
0248   * \tparam SparseVectorType the equivalent sparse vector type of the referenced data, it must be a template instance of class SparseVector.
0249   *
0250   * \sa class Ref
0251   */
0252 #ifndef EIGEN_PARSED_BY_DOXYGEN
0253 template<typename MatScalar, int MatOptions, typename MatIndex, int Options, typename StrideType>
0254 class Ref<SparseVector<MatScalar,MatOptions,MatIndex>, Options, StrideType >
0255   : public internal::SparseRefBase<Ref<SparseVector<MatScalar,MatOptions,MatIndex>, Options, StrideType > >
0256 #else
0257 template<typename SparseVectorType>
0258 class Ref<SparseVectorType>
0259   : public SparseMapBase<Derived,WriteAccessors>
0260 #endif
0261 {
0262     typedef SparseVector<MatScalar,MatOptions,MatIndex> PlainObjectType;
0263     typedef internal::traits<Ref> Traits;
0264     template<int OtherOptions>
0265     inline Ref(const SparseVector<MatScalar,OtherOptions,MatIndex>& expr);
0266   public:
0267 
0268     typedef internal::SparseRefBase<Ref> Base;
0269     EIGEN_SPARSE_PUBLIC_INTERFACE(Ref)
0270 
0271     #ifndef EIGEN_PARSED_BY_DOXYGEN
0272     template<int OtherOptions>
0273     inline Ref(SparseVector<MatScalar,OtherOptions,MatIndex>& expr)
0274     {
0275       EIGEN_STATIC_ASSERT(bool(Traits::template match<SparseVector<MatScalar,OtherOptions,MatIndex> >::MatchAtCompileTime), STORAGE_LAYOUT_DOES_NOT_MATCH);
0276       Base::construct(expr.derived());
0277     }
0278 
0279     template<typename Derived>
0280     inline Ref(const SparseCompressedBase<Derived>& expr)
0281     #else
0282     /** Implicit constructor from any 1D sparse vector expression */
0283     template<typename Derived>
0284     inline Ref(SparseCompressedBase<Derived>& expr)
0285     #endif
0286     {
0287       EIGEN_STATIC_ASSERT(bool(internal::is_lvalue<Derived>::value), THIS_EXPRESSION_IS_NOT_A_LVALUE__IT_IS_READ_ONLY);
0288       EIGEN_STATIC_ASSERT(bool(Traits::template match<Derived>::MatchAtCompileTime), STORAGE_LAYOUT_DOES_NOT_MATCH);
0289       Base::construct(expr.const_cast_derived());
0290     }
0291 };
0292 
0293 // this is the const ref version
0294 template<typename MatScalar, int MatOptions, typename MatIndex, int Options, typename StrideType>
0295 class Ref<const SparseVector<MatScalar,MatOptions,MatIndex>, Options, StrideType>
0296   : public internal::SparseRefBase<Ref<const SparseVector<MatScalar,MatOptions,MatIndex>, Options, StrideType> >
0297 {
0298     typedef SparseVector<MatScalar,MatOptions,MatIndex> TPlainObjectType;
0299     typedef internal::traits<Ref> Traits;
0300   public:
0301 
0302     typedef internal::SparseRefBase<Ref> Base;
0303     EIGEN_SPARSE_PUBLIC_INTERFACE(Ref)
0304 
0305     template<typename Derived>
0306     inline Ref(const SparseMatrixBase<Derived>& expr) : m_hasCopy(false)
0307     {
0308       construct(expr.derived(), typename Traits::template match<Derived>::type());
0309     }
0310 
0311     inline Ref(const Ref& other) : Base(other), m_hasCopy(false) {
0312       // copy constructor shall not copy the m_object, to avoid unnecessary malloc and copy
0313     }
0314 
0315     template<typename OtherRef>
0316     inline Ref(const RefBase<OtherRef>& other) : m_hasCopy(false) {
0317       construct(other.derived(), typename Traits::template match<OtherRef>::type());
0318     }
0319 
0320     ~Ref() {
0321       if(m_hasCopy) {
0322         TPlainObjectType* obj = reinterpret_cast<TPlainObjectType*>(&m_storage);
0323         obj->~TPlainObjectType();
0324       }
0325     }
0326 
0327   protected:
0328 
0329     template<typename Expression>
0330     void construct(const Expression& expr,internal::true_type)
0331     {
0332       Base::construct(expr);
0333     }
0334 
0335     template<typename Expression>
0336     void construct(const Expression& expr, internal::false_type)
0337     {
0338       TPlainObjectType* obj = reinterpret_cast<TPlainObjectType*>(&m_storage);
0339       ::new (obj) TPlainObjectType(expr);
0340       m_hasCopy = true;
0341       Base::construct(*obj);
0342     }
0343 
0344   protected:
0345     typename internal::aligned_storage<sizeof(TPlainObjectType), EIGEN_ALIGNOF(TPlainObjectType)>::type m_storage;
0346     bool m_hasCopy;
0347 };
0348 
0349 namespace internal {
0350 
0351 // FIXME shall we introduce a general evaluatior_ref that we can specialize for any sparse object once, and thus remove this copy-pasta thing...
0352 
0353 template<typename MatScalar, int MatOptions, typename MatIndex, int Options, typename StrideType>
0354 struct evaluator<Ref<SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> >
0355   : evaluator<SparseCompressedBase<Ref<SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> > >
0356 {
0357   typedef evaluator<SparseCompressedBase<Ref<SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> > > Base;
0358   typedef Ref<SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> XprType;  
0359   evaluator() : Base() {}
0360   explicit evaluator(const XprType &mat) : Base(mat) {}
0361 };
0362 
0363 template<typename MatScalar, int MatOptions, typename MatIndex, int Options, typename StrideType>
0364 struct evaluator<Ref<const SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> >
0365   : evaluator<SparseCompressedBase<Ref<const SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> > >
0366 {
0367   typedef evaluator<SparseCompressedBase<Ref<const SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> > > Base;
0368   typedef Ref<const SparseMatrix<MatScalar,MatOptions,MatIndex>, Options, StrideType> XprType;  
0369   evaluator() : Base() {}
0370   explicit evaluator(const XprType &mat) : Base(mat) {}
0371 };
0372 
0373 template<typename MatScalar, int MatOptions, typename MatIndex, int Options, typename StrideType>
0374 struct evaluator<Ref<SparseVector<MatScalar,MatOptions,MatIndex>, Options, StrideType> >
0375   : evaluator<SparseCompressedBase<Ref<SparseVector<MatScalar,MatOptions,MatIndex>, Options, StrideType> > >
0376 {
0377   typedef evaluator<SparseCompressedBase<Ref<SparseVector<MatScalar,MatOptions,MatIndex>, Options, StrideType> > > Base;
0378   typedef Ref<SparseVector<MatScalar,MatOptions,MatIndex>, Options, StrideType> XprType;
0379   evaluator() : Base() {}
0380   explicit evaluator(const XprType &mat) : Base(mat) {}
0381 };
0382 
0383 template<typename MatScalar, int MatOptions, typename MatIndex, int Options, typename StrideType>
0384 struct evaluator<Ref<const SparseVector<MatScalar,MatOptions,MatIndex>, Options, StrideType> >
0385   : evaluator<SparseCompressedBase<Ref<const SparseVector<MatScalar,MatOptions,MatIndex>, Options, StrideType> > >
0386 {
0387   typedef evaluator<SparseCompressedBase<Ref<const SparseVector<MatScalar,MatOptions,MatIndex>, Options, StrideType> > > Base;
0388   typedef Ref<const SparseVector<MatScalar,MatOptions,MatIndex>, Options, StrideType> XprType;
0389   evaluator() : Base() {}
0390   explicit evaluator(const XprType &mat) : Base(mat) {}
0391 };
0392 
0393 }
0394 
0395 } // end namespace Eigen
0396 
0397 #endif // EIGEN_SPARSE_REF_H