Eigen  3.3.3
DenseCoeffsBase.h
00001 // This file is part of Eigen, a lightweight C++ template library
00002 // for linear algebra.
00003 //
00004 // Copyright (C) 2006-2010 Benoit Jacob <jacob.benoit.1@gmail.com>
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_DENSECOEFFSBASE_H
00011 #define EIGEN_DENSECOEFFSBASE_H
00012 
00013 namespace Eigen {
00014 
00015 namespace internal {
00016 template<typename T> struct add_const_on_value_type_if_arithmetic
00017 {
00018   typedef typename conditional<is_arithmetic<T>::value, T, typename add_const_on_value_type<T>::type>::type type;
00019 };
00020 }
00021 
00033 template<typename Derived>
00034 class DenseCoeffsBase<Derived,ReadOnlyAccessors> : public EigenBase<Derived>
00035 {
00036   public:
00037     typedef typename internal::traits<Derived>::StorageKind StorageKind;
00038     typedef typename internal::traits<Derived>::Scalar Scalar;
00039     typedef typename internal::packet_traits<Scalar>::type PacketScalar;
00040 
00041     // Explanation for this CoeffReturnType typedef.
00042     // - This is the return type of the coeff() method.
00043     // - The LvalueBit means exactly that we can offer a coeffRef() method, which means exactly that we can get references
00044     // to coeffs, which means exactly that we can have coeff() return a const reference (as opposed to returning a value).
00045     // - The is_artihmetic check is required since "const int", "const double", etc. will cause warnings on some systems
00046     // while the declaration of "const T", where T is a non arithmetic type does not. Always returning "const Scalar&" is
00047     // not possible, since the underlying expressions might not offer a valid address the reference could be referring to.
00048     typedef typename internal::conditional<bool(internal::traits<Derived>::Flags&LvalueBit),
00049                          const Scalar&,
00050                          typename internal::conditional<internal::is_arithmetic<Scalar>::value, Scalar, const Scalar>::type
00051                      >::type CoeffReturnType;
00052 
00053     typedef typename internal::add_const_on_value_type_if_arithmetic<
00054                          typename internal::packet_traits<Scalar>::type
00055                      >::type PacketReturnType;
00056 
00057     typedef EigenBase<Derived> Base;
00058     using Base::rows;
00059     using Base::cols;
00060     using Base::size;
00061     using Base::derived;
00062 
00063     EIGEN_DEVICE_FUNC
00064     EIGEN_STRONG_INLINE Index rowIndexByOuterInner(Index outer, Index inner) const
00065     {
00066       return int(Derived::RowsAtCompileTime) == 1 ? 0
00067           : int(Derived::ColsAtCompileTime) == 1 ? inner
00068           : int(Derived::Flags)&RowMajorBit ? outer
00069           : inner;
00070     }
00071 
00072     EIGEN_DEVICE_FUNC
00073     EIGEN_STRONG_INLINE Index colIndexByOuterInner(Index outer, Index inner) const
00074     {
00075       return int(Derived::ColsAtCompileTime) == 1 ? 0
00076           : int(Derived::RowsAtCompileTime) == 1 ? inner
00077           : int(Derived::Flags)&RowMajorBit ? inner
00078           : outer;
00079     }
00080 
00095     EIGEN_DEVICE_FUNC
00096     EIGEN_STRONG_INLINE CoeffReturnType coeff(Index row, Index col) const
00097     {
00098       eigen_internal_assert(row >= 0 && row < rows()
00099                          && col >= 0 && col < cols());
00100       return internal::evaluator<Derived>(derived()).coeff(row,col);
00101     }
00102 
00103     EIGEN_DEVICE_FUNC
00104     EIGEN_STRONG_INLINE CoeffReturnType coeffByOuterInner(Index outer, Index inner) const
00105     {
00106       return coeff(rowIndexByOuterInner(outer, inner),
00107                    colIndexByOuterInner(outer, inner));
00108     }
00109 
00114     EIGEN_DEVICE_FUNC
00115     EIGEN_STRONG_INLINE CoeffReturnType operator()(Index row, Index col) const
00116     {
00117       eigen_assert(row >= 0 && row < rows()
00118           && col >= 0 && col < cols());
00119       return coeff(row, col);
00120     }
00121 
00137     EIGEN_DEVICE_FUNC
00138     EIGEN_STRONG_INLINE CoeffReturnType
00139     coeff(Index index) const
00140     {
00141       EIGEN_STATIC_ASSERT(internal::evaluator<Derived>::Flags & LinearAccessBit,
00142                           THIS_COEFFICIENT_ACCESSOR_TAKING_ONE_ACCESS_IS_ONLY_FOR_EXPRESSIONS_ALLOWING_LINEAR_ACCESS)
00143       eigen_internal_assert(index >= 0 && index < size());
00144       return internal::evaluator<Derived>(derived()).coeff(index);
00145     }
00146 
00147 
00156     EIGEN_DEVICE_FUNC
00157     EIGEN_STRONG_INLINE CoeffReturnType
00158     operator[](Index index) const
00159     {
00160       EIGEN_STATIC_ASSERT(Derived::IsVectorAtCompileTime,
00161                           THE_BRACKET_OPERATOR_IS_ONLY_FOR_VECTORS__USE_THE_PARENTHESIS_OPERATOR_INSTEAD)
00162       eigen_assert(index >= 0 && index < size());
00163       return coeff(index);
00164     }
00165 
00176     EIGEN_DEVICE_FUNC
00177     EIGEN_STRONG_INLINE CoeffReturnType
00178     operator()(Index index) const
00179     {
00180       eigen_assert(index >= 0 && index < size());
00181       return coeff(index);
00182     }
00183 
00186     EIGEN_DEVICE_FUNC
00187     EIGEN_STRONG_INLINE CoeffReturnType
00188     x() const { return (*this)[0]; }
00189 
00192     EIGEN_DEVICE_FUNC
00193     EIGEN_STRONG_INLINE CoeffReturnType
00194     y() const
00195     {
00196       EIGEN_STATIC_ASSERT(Derived::SizeAtCompileTime==-1 || Derived::SizeAtCompileTime>=2, OUT_OF_RANGE_ACCESS);
00197       return (*this)[1];
00198     }
00199 
00202     EIGEN_DEVICE_FUNC
00203     EIGEN_STRONG_INLINE CoeffReturnType
00204     z() const
00205     {
00206       EIGEN_STATIC_ASSERT(Derived::SizeAtCompileTime==-1 || Derived::SizeAtCompileTime>=3, OUT_OF_RANGE_ACCESS);
00207       return (*this)[2];
00208     }
00209 
00212     EIGEN_DEVICE_FUNC
00213     EIGEN_STRONG_INLINE CoeffReturnType
00214     w() const
00215     {
00216       EIGEN_STATIC_ASSERT(Derived::SizeAtCompileTime==-1 || Derived::SizeAtCompileTime>=4, OUT_OF_RANGE_ACCESS);
00217       return (*this)[3];
00218     }
00219 
00230     template<int LoadMode>
00231     EIGEN_STRONG_INLINE PacketReturnType packet(Index row, Index col) const
00232     {
00233       typedef typename internal::packet_traits<Scalar>::type DefaultPacketType;
00234       eigen_internal_assert(row >= 0 && row < rows() && col >= 0 && col < cols());
00235       return internal::evaluator<Derived>(derived()).template packet<LoadMode,DefaultPacketType>(row,col);
00236     }
00237 
00238 
00240     template<int LoadMode>
00241     EIGEN_STRONG_INLINE PacketReturnType packetByOuterInner(Index outer, Index inner) const
00242     {
00243       return packet<LoadMode>(rowIndexByOuterInner(outer, inner),
00244                               colIndexByOuterInner(outer, inner));
00245     }
00246 
00257     template<int LoadMode>
00258     EIGEN_STRONG_INLINE PacketReturnType packet(Index index) const
00259     {
00260       EIGEN_STATIC_ASSERT(internal::evaluator<Derived>::Flags & LinearAccessBit,
00261                           THIS_COEFFICIENT_ACCESSOR_TAKING_ONE_ACCESS_IS_ONLY_FOR_EXPRESSIONS_ALLOWING_LINEAR_ACCESS)
00262       typedef typename internal::packet_traits<Scalar>::type DefaultPacketType;
00263       eigen_internal_assert(index >= 0 && index < size());
00264       return internal::evaluator<Derived>(derived()).template packet<LoadMode,DefaultPacketType>(index);
00265     }
00266 
00267   protected:
00268     // explanation: DenseBase is doing "using ..." on the methods from DenseCoeffsBase.
00269     // But some methods are only available in the DirectAccess case.
00270     // So we add dummy methods here with these names, so that "using... " doesn't fail.
00271     // It's not private so that the child class DenseBase can access them, and it's not public
00272     // either since it's an implementation detail, so has to be protected.
00273     void coeffRef();
00274     void coeffRefByOuterInner();
00275     void writePacket();
00276     void writePacketByOuterInner();
00277     void copyCoeff();
00278     void copyCoeffByOuterInner();
00279     void copyPacket();
00280     void copyPacketByOuterInner();
00281     void stride();
00282     void innerStride();
00283     void outerStride();
00284     void rowStride();
00285     void colStride();
00286 };
00287 
00299 template<typename Derived>
00300 class DenseCoeffsBase<Derived, WriteAccessors> : public DenseCoeffsBase<Derived, ReadOnlyAccessors>
00301 {
00302   public:
00303 
00304     typedef DenseCoeffsBase<Derived, ReadOnlyAccessors> Base;
00305 
00306     typedef typename internal::traits<Derived>::StorageKind StorageKind;
00307     typedef typename internal::traits<Derived>::Scalar Scalar;
00308     typedef typename internal::packet_traits<Scalar>::type PacketScalar;
00309     typedef typename NumTraits<Scalar>::Real RealScalar;
00310 
00311     using Base::coeff;
00312     using Base::rows;
00313     using Base::cols;
00314     using Base::size;
00315     using Base::derived;
00316     using Base::rowIndexByOuterInner;
00317     using Base::colIndexByOuterInner;
00318     using Base::operator[];
00319     using Base::operator();
00320     using Base::x;
00321     using Base::y;
00322     using Base::z;
00323     using Base::w;
00324 
00339     EIGEN_DEVICE_FUNC
00340     EIGEN_STRONG_INLINE Scalar& coeffRef(Index row, Index col)
00341     {
00342       eigen_internal_assert(row >= 0 && row < rows()
00343                          && col >= 0 && col < cols());
00344       return internal::evaluator<Derived>(derived()).coeffRef(row,col);
00345     }
00346 
00347     EIGEN_DEVICE_FUNC
00348     EIGEN_STRONG_INLINE Scalar&
00349     coeffRefByOuterInner(Index outer, Index inner)
00350     {
00351       return coeffRef(rowIndexByOuterInner(outer, inner),
00352                       colIndexByOuterInner(outer, inner));
00353     }
00354 
00360     EIGEN_DEVICE_FUNC
00361     EIGEN_STRONG_INLINE Scalar&
00362     operator()(Index row, Index col)
00363     {
00364       eigen_assert(row >= 0 && row < rows()
00365           && col >= 0 && col < cols());
00366       return coeffRef(row, col);
00367     }
00368 
00369 
00385     EIGEN_DEVICE_FUNC
00386     EIGEN_STRONG_INLINE Scalar&
00387     coeffRef(Index index)
00388     {
00389       EIGEN_STATIC_ASSERT(internal::evaluator<Derived>::Flags & LinearAccessBit,
00390                           THIS_COEFFICIENT_ACCESSOR_TAKING_ONE_ACCESS_IS_ONLY_FOR_EXPRESSIONS_ALLOWING_LINEAR_ACCESS)
00391       eigen_internal_assert(index >= 0 && index < size());
00392       return internal::evaluator<Derived>(derived()).coeffRef(index);
00393     }
00394 
00402     EIGEN_DEVICE_FUNC
00403     EIGEN_STRONG_INLINE Scalar&
00404     operator[](Index index)
00405     {
00406       EIGEN_STATIC_ASSERT(Derived::IsVectorAtCompileTime,
00407                           THE_BRACKET_OPERATOR_IS_ONLY_FOR_VECTORS__USE_THE_PARENTHESIS_OPERATOR_INSTEAD)
00408       eigen_assert(index >= 0 && index < size());
00409       return coeffRef(index);
00410     }
00411 
00421     EIGEN_DEVICE_FUNC
00422     EIGEN_STRONG_INLINE Scalar&
00423     operator()(Index index)
00424     {
00425       eigen_assert(index >= 0 && index < size());
00426       return coeffRef(index);
00427     }
00428 
00431     EIGEN_DEVICE_FUNC
00432     EIGEN_STRONG_INLINE Scalar&
00433     x() { return (*this)[0]; }
00434 
00437     EIGEN_DEVICE_FUNC
00438     EIGEN_STRONG_INLINE Scalar&
00439     y()
00440     {
00441       EIGEN_STATIC_ASSERT(Derived::SizeAtCompileTime==-1 || Derived::SizeAtCompileTime>=2, OUT_OF_RANGE_ACCESS);
00442       return (*this)[1];
00443     }
00444 
00447     EIGEN_DEVICE_FUNC
00448     EIGEN_STRONG_INLINE Scalar&
00449     z()
00450     {
00451       EIGEN_STATIC_ASSERT(Derived::SizeAtCompileTime==-1 || Derived::SizeAtCompileTime>=3, OUT_OF_RANGE_ACCESS);
00452       return (*this)[2];
00453     }
00454 
00457     EIGEN_DEVICE_FUNC
00458     EIGEN_STRONG_INLINE Scalar&
00459     w()
00460     {
00461       EIGEN_STATIC_ASSERT(Derived::SizeAtCompileTime==-1 || Derived::SizeAtCompileTime>=4, OUT_OF_RANGE_ACCESS);
00462       return (*this)[3];
00463     }
00464 };
00465 
00477 template<typename Derived>
00478 class DenseCoeffsBase<Derived, DirectAccessors> : public DenseCoeffsBase<Derived, ReadOnlyAccessors>
00479 {
00480   public:
00481 
00482     typedef DenseCoeffsBase<Derived, ReadOnlyAccessors> Base;
00483     typedef typename internal::traits<Derived>::Scalar Scalar;
00484     typedef typename NumTraits<Scalar>::Real RealScalar;
00485 
00486     using Base::rows;
00487     using Base::cols;
00488     using Base::size;
00489     using Base::derived;
00490 
00495     EIGEN_DEVICE_FUNC
00496     inline Index innerStride() const
00497     {
00498       return derived().innerStride();
00499     }
00500 
00506     EIGEN_DEVICE_FUNC
00507     inline Index outerStride() const
00508     {
00509       return derived().outerStride();
00510     }
00511 
00512     // FIXME shall we remove it ?
00513     inline Index stride() const
00514     {
00515       return Derived::IsVectorAtCompileTime ? innerStride() : outerStride();
00516     }
00517 
00522     EIGEN_DEVICE_FUNC
00523     inline Index rowStride() const
00524     {
00525       return Derived::IsRowMajor ? outerStride() : innerStride();
00526     }
00527 
00532     EIGEN_DEVICE_FUNC
00533     inline Index colStride() const
00534     {
00535       return Derived::IsRowMajor ? innerStride() : outerStride();
00536     }
00537 };
00538 
00550 template<typename Derived>
00551 class DenseCoeffsBase<Derived, DirectWriteAccessors>
00552   : public DenseCoeffsBase<Derived, WriteAccessors>
00553 {
00554   public:
00555 
00556     typedef DenseCoeffsBase<Derived, WriteAccessors> Base;
00557     typedef typename internal::traits<Derived>::Scalar Scalar;
00558     typedef typename NumTraits<Scalar>::Real RealScalar;
00559 
00560     using Base::rows;
00561     using Base::cols;
00562     using Base::size;
00563     using Base::derived;
00564 
00569     EIGEN_DEVICE_FUNC
00570     inline Index innerStride() const
00571     {
00572       return derived().innerStride();
00573     }
00574 
00580     EIGEN_DEVICE_FUNC
00581     inline Index outerStride() const
00582     {
00583       return derived().outerStride();
00584     }
00585 
00586     // FIXME shall we remove it ?
00587     inline Index stride() const
00588     {
00589       return Derived::IsVectorAtCompileTime ? innerStride() : outerStride();
00590     }
00591 
00596     EIGEN_DEVICE_FUNC
00597     inline Index rowStride() const
00598     {
00599       return Derived::IsRowMajor ? outerStride() : innerStride();
00600     }
00601 
00606     EIGEN_DEVICE_FUNC
00607     inline Index colStride() const
00608     {
00609       return Derived::IsRowMajor ? innerStride() : outerStride();
00610     }
00611 };
00612 
00613 namespace internal {
00614 
00615 template<int Alignment, typename Derived, bool JustReturnZero>
00616 struct first_aligned_impl
00617 {
00618   static inline Index run(const Derived&)
00619   { return 0; }
00620 };
00621 
00622 template<int Alignment, typename Derived>
00623 struct first_aligned_impl<Alignment, Derived, false>
00624 {
00625   static inline Index run(const Derived& m)
00626   {
00627     return internal::first_aligned<Alignment>(m.data(), m.size());
00628   }
00629 };
00630 
00638 template<int Alignment, typename Derived>
00639 static inline Index first_aligned(const DenseBase<Derived>& m)
00640 {
00641   enum { ReturnZero = (int(evaluator<Derived>::Alignment) >= Alignment) || !(Derived::Flags & DirectAccessBit) };
00642   return first_aligned_impl<Alignment, Derived, ReturnZero>::run(m.derived());
00643 }
00644 
00645 template<typename Derived>
00646 static inline Index first_default_aligned(const DenseBase<Derived>& m)
00647 {
00648   typedef typename Derived::Scalar Scalar;
00649   typedef typename packet_traits<Scalar>::type DefaultPacketType;
00650   return internal::first_aligned<int(unpacket_traits<DefaultPacketType>::alignment),Derived>(m);
00651 }
00652 
00653 template<typename Derived, bool HasDirectAccess = has_direct_access<Derived>::ret>
00654 struct inner_stride_at_compile_time
00655 {
00656   enum { ret = traits<Derived>::InnerStrideAtCompileTime };
00657 };
00658 
00659 template<typename Derived>
00660 struct inner_stride_at_compile_time<Derived, false>
00661 {
00662   enum { ret = 0 };
00663 };
00664 
00665 template<typename Derived, bool HasDirectAccess = has_direct_access<Derived>::ret>
00666 struct outer_stride_at_compile_time
00667 {
00668   enum { ret = traits<Derived>::OuterStrideAtCompileTime };
00669 };
00670 
00671 template<typename Derived>
00672 struct outer_stride_at_compile_time<Derived, false>
00673 {
00674   enum { ret = 0 };
00675 };
00676 
00677 } // end namespace internal
00678 
00679 } // end namespace Eigen
00680 
00681 #endif // EIGEN_DENSECOEFFSBASE_H
 All Classes Functions Variables Typedefs Enumerations Enumerator Friends