DenseCoeffsBase.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) 2006-2010 Benoit Jacob <jacob.benoit.1@gmail.com>
00005 //
00006 // Eigen is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 3 of the License, or (at your option) any later version.
00010 //
00011 // Alternatively, you can redistribute it and/or
00012 // modify it under the terms of the GNU General Public License as
00013 // published by the Free Software Foundation; either version 2 of
00014 // the License, or (at your option) any later version.
00015 //
00016 // Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
00017 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00018 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
00019 // GNU General Public License for more details.
00020 //
00021 // You should have received a copy of the GNU Lesser General Public
00022 // License and a copy of the GNU General Public License along with
00023 // Eigen. If not, see <http://www.gnu.org/licenses/>.
00024 
00025 #ifndef EIGEN_DENSECOEFFSBASE_H
00026 #define EIGEN_DENSECOEFFSBASE_H
00027 
00028 namespace internal {
00029 template<typename T> struct add_const_on_value_type_if_arithmetic
00030 {
00031   typedef typename conditional<is_arithmetic<T>::value, T, typename add_const_on_value_type<T>::type>::type type;
00032 };
00033 }
00034 
00046 template<typename Derived>
00047 class DenseCoeffsBase<Derived,ReadOnlyAccessors> : public EigenBase<Derived>
00048 {
00049   public:
00050     typedef typename internal::traits<Derived>::StorageKind StorageKind;
00051     typedef typename internal::traits<Derived>::Index Index;
00052     typedef typename internal::traits<Derived>::Scalar Scalar;
00053     typedef typename internal::packet_traits<Scalar>::type PacketScalar;
00054 
00055     // Explanation for this CoeffReturnType typedef.
00056     // - This is the return type of the coeff() method.
00057     // - The LvalueBit means exactly that we can offer a coeffRef() method, which means exactly that we can get references
00058     // to coeffs, which means exactly that we can have coeff() return a const reference (as opposed to returning a value).
00059     // - The is_artihmetic check is required since "const int", "const double", etc. will cause warnings on some systems
00060     // while the declaration of "const T", where T is a non arithmetic type does not. Always returning "const Scalar&" is
00061     // not possible, since the underlying expressions might not offer a valid address the reference could be referring to.
00062     typedef typename internal::conditional<bool(internal::traits<Derived>::Flags&LvalueBit),
00063                          const Scalar&,
00064                          typename internal::conditional<internal::is_arithmetic<Scalar>::value, Scalar, const Scalar>::type
00065                      >::type CoeffReturnType;
00066 
00067     typedef typename internal::add_const_on_value_type_if_arithmetic<
00068                          typename internal::packet_traits<Scalar>::type
00069                      >::type PacketReturnType;
00070 
00071     typedef EigenBase<Derived> Base;
00072     using Base::rows;
00073     using Base::cols;
00074     using Base::size;
00075     using Base::derived;
00076 
00077     EIGEN_STRONG_INLINE Index rowIndexByOuterInner(Index outer, Index inner) const
00078     {
00079       return int(Derived::RowsAtCompileTime) == 1 ? 0
00080           : int(Derived::ColsAtCompileTime) == 1 ? inner
00081           : int(Derived::Flags)&RowMajorBit ? outer
00082           : inner;
00083     }
00084 
00085     EIGEN_STRONG_INLINE Index colIndexByOuterInner(Index outer, Index inner) const
00086     {
00087       return int(Derived::ColsAtCompileTime) == 1 ? 0
00088           : int(Derived::RowsAtCompileTime) == 1 ? inner
00089           : int(Derived::Flags)&RowMajorBit ? inner
00090           : outer;
00091     }
00092 
00107     EIGEN_STRONG_INLINE CoeffReturnType coeff(Index row, Index col) const
00108     {
00109       eigen_internal_assert(row >= 0 && row < rows()
00110                         && col >= 0 && col < cols());
00111       return derived().coeff(row, col);
00112     }
00113 
00114     EIGEN_STRONG_INLINE CoeffReturnType coeffByOuterInner(Index outer, Index inner) const
00115     {
00116       return coeff(rowIndexByOuterInner(outer, inner),
00117                    colIndexByOuterInner(outer, inner));
00118     }
00119 
00124     EIGEN_STRONG_INLINE CoeffReturnType operator()(Index row, Index col) const
00125     {
00126       eigen_assert(row >= 0 && row < rows()
00127           && col >= 0 && col < cols());
00128       return derived().coeff(row, col);
00129     }
00130 
00146     EIGEN_STRONG_INLINE CoeffReturnType
00147     coeff(Index index) const
00148     {
00149       eigen_internal_assert(index >= 0 && index < size());
00150       return derived().coeff(index);
00151     }
00152 
00153 
00162     EIGEN_STRONG_INLINE CoeffReturnType
00163     operator[](Index index) const
00164     {
00165       #ifndef EIGEN2_SUPPORT
00166       EIGEN_STATIC_ASSERT(Derived::IsVectorAtCompileTime,
00167                           THE_BRACKET_OPERATOR_IS_ONLY_FOR_VECTORS__USE_THE_PARENTHESIS_OPERATOR_INSTEAD)
00168       #endif
00169       eigen_assert(index >= 0 && index < size());
00170       return derived().coeff(index);
00171     }
00172 
00183     EIGEN_STRONG_INLINE CoeffReturnType
00184     operator()(Index index) const
00185     {
00186       eigen_assert(index >= 0 && index < size());
00187       return derived().coeff(index);
00188     }
00189 
00192     EIGEN_STRONG_INLINE CoeffReturnType
00193     x() const { return (*this)[0]; }
00194 
00197     EIGEN_STRONG_INLINE CoeffReturnType
00198     y() const { return (*this)[1]; }
00199 
00202     EIGEN_STRONG_INLINE CoeffReturnType
00203     z() const { return (*this)[2]; }
00204 
00207     EIGEN_STRONG_INLINE CoeffReturnType
00208     w() const { return (*this)[3]; }
00209 
00220     template<int LoadMode>
00221     EIGEN_STRONG_INLINE PacketReturnType packet(Index row, Index col) const
00222     {
00223       eigen_internal_assert(row >= 0 && row < rows()
00224                       && col >= 0 && col < cols());
00225       return derived().template packet<LoadMode>(row,col);
00226     }
00227 
00228 
00230     template<int LoadMode>
00231     EIGEN_STRONG_INLINE PacketReturnType packetByOuterInner(Index outer, Index inner) const
00232     {
00233       return packet<LoadMode>(rowIndexByOuterInner(outer, inner),
00234                               colIndexByOuterInner(outer, inner));
00235     }
00236 
00247     template<int LoadMode>
00248     EIGEN_STRONG_INLINE PacketReturnType packet(Index index) const
00249     {
00250       eigen_internal_assert(index >= 0 && index < size());
00251       return derived().template packet<LoadMode>(index);
00252     }
00253 
00254   protected:
00255     // explanation: DenseBase is doing "using ..." on the methods from DenseCoeffsBase.
00256     // But some methods are only available in the DirectAccess case.
00257     // So we add dummy methods here with these names, so that "using... " doesn't fail.
00258     // It's not private so that the child class DenseBase can access them, and it's not public
00259     // either since it's an implementation detail, so has to be protected.
00260     void coeffRef();
00261     void coeffRefByOuterInner();
00262     void writePacket();
00263     void writePacketByOuterInner();
00264     void copyCoeff();
00265     void copyCoeffByOuterInner();
00266     void copyPacket();
00267     void copyPacketByOuterInner();
00268     void stride();
00269     void innerStride();
00270     void outerStride();
00271     void rowStride();
00272     void colStride();
00273 };
00274 
00286 template<typename Derived>
00287 class DenseCoeffsBase<Derived, WriteAccessors> : public DenseCoeffsBase<Derived, ReadOnlyAccessors>
00288 {
00289   public:
00290 
00291     typedef DenseCoeffsBase<Derived, ReadOnlyAccessors> Base;
00292 
00293     typedef typename internal::traits<Derived>::StorageKind StorageKind;
00294     typedef typename internal::traits<Derived>::Index Index;
00295     typedef typename internal::traits<Derived>::Scalar Scalar;
00296     typedef typename internal::packet_traits<Scalar>::type PacketScalar;
00297     typedef typename NumTraits<Scalar>::Real RealScalar;
00298 
00299     using Base::coeff;
00300     using Base::rows;
00301     using Base::cols;
00302     using Base::size;
00303     using Base::derived;
00304     using Base::rowIndexByOuterInner;
00305     using Base::colIndexByOuterInner;
00306     using Base::operator[];
00307     using Base::operator();
00308     using Base::x;
00309     using Base::y;
00310     using Base::z;
00311     using Base::w;
00312 
00327     EIGEN_STRONG_INLINE Scalar& coeffRef(Index row, Index col)
00328     {
00329       eigen_internal_assert(row >= 0 && row < rows()
00330                         && col >= 0 && col < cols());
00331       return derived().coeffRef(row, col);
00332     }
00333 
00334     EIGEN_STRONG_INLINE Scalar&
00335     coeffRefByOuterInner(Index outer, Index inner)
00336     {
00337       return coeffRef(rowIndexByOuterInner(outer, inner),
00338                       colIndexByOuterInner(outer, inner));
00339     }
00340 
00346     EIGEN_STRONG_INLINE Scalar&
00347     operator()(Index row, Index col)
00348     {
00349       eigen_assert(row >= 0 && row < rows()
00350           && col >= 0 && col < cols());
00351       return derived().coeffRef(row, col);
00352     }
00353 
00354 
00370     EIGEN_STRONG_INLINE Scalar&
00371     coeffRef(Index index)
00372     {
00373       eigen_internal_assert(index >= 0 && index < size());
00374       return derived().coeffRef(index);
00375     }
00376 
00384     EIGEN_STRONG_INLINE Scalar&
00385     operator[](Index index)
00386     {
00387       #ifndef EIGEN2_SUPPORT
00388       EIGEN_STATIC_ASSERT(Derived::IsVectorAtCompileTime,
00389                           THE_BRACKET_OPERATOR_IS_ONLY_FOR_VECTORS__USE_THE_PARENTHESIS_OPERATOR_INSTEAD)
00390       #endif
00391       eigen_assert(index >= 0 && index < size());
00392       return derived().coeffRef(index);
00393     }
00394 
00404     EIGEN_STRONG_INLINE Scalar&
00405     operator()(Index index)
00406     {
00407       eigen_assert(index >= 0 && index < size());
00408       return derived().coeffRef(index);
00409     }
00410 
00413     EIGEN_STRONG_INLINE Scalar&
00414     x() { return (*this)[0]; }
00415 
00418     EIGEN_STRONG_INLINE Scalar&
00419     y() { return (*this)[1]; }
00420 
00423     EIGEN_STRONG_INLINE Scalar&
00424     z() { return (*this)[2]; }
00425 
00428     EIGEN_STRONG_INLINE Scalar&
00429     w() { return (*this)[3]; }
00430 
00441     template<int StoreMode>
00442     EIGEN_STRONG_INLINE void writePacket
00443     (Index row, Index col, const typename internal::packet_traits<Scalar>::type& x)
00444     {
00445       eigen_internal_assert(row >= 0 && row < rows()
00446                         && col >= 0 && col < cols());
00447       derived().template writePacket<StoreMode>(row,col,x);
00448     }
00449 
00450 
00452     template<int StoreMode>
00453     EIGEN_STRONG_INLINE void writePacketByOuterInner
00454     (Index outer, Index inner, const typename internal::packet_traits<Scalar>::type& x)
00455     {
00456       writePacket<StoreMode>(rowIndexByOuterInner(outer, inner),
00457                             colIndexByOuterInner(outer, inner),
00458                             x);
00459     }
00460 
00470     template<int StoreMode>
00471     EIGEN_STRONG_INLINE void writePacket
00472     (Index index, const typename internal::packet_traits<Scalar>::type& x)
00473     {
00474       eigen_internal_assert(index >= 0 && index < size());
00475       derived().template writePacket<StoreMode>(index,x);
00476     }
00477 
00478 #ifndef EIGEN_PARSED_BY_DOXYGEN
00479 
00488     template<typename OtherDerived>
00489     EIGEN_STRONG_INLINE void copyCoeff(Index row, Index col, const DenseBase<OtherDerived>& other)
00490     {
00491       eigen_internal_assert(row >= 0 && row < rows()
00492                         && col >= 0 && col < cols());
00493       derived().coeffRef(row, col) = other.derived().coeff(row, col);
00494     }
00495 
00504     template<typename OtherDerived>
00505     EIGEN_STRONG_INLINE void copyCoeff(Index index, const DenseBase<OtherDerived>& other)
00506     {
00507       eigen_internal_assert(index >= 0 && index < size());
00508       derived().coeffRef(index) = other.derived().coeff(index);
00509     }
00510 
00511 
00512     template<typename OtherDerived>
00513     EIGEN_STRONG_INLINE void copyCoeffByOuterInner(Index outer, Index inner, const DenseBase<OtherDerived>& other)
00514     {
00515       const Index row = rowIndexByOuterInner(outer,inner);
00516       const Index col = colIndexByOuterInner(outer,inner);
00517       // derived() is important here: copyCoeff() may be reimplemented in Derived!
00518       derived().copyCoeff(row, col, other);
00519     }
00520 
00529     template<typename OtherDerived, int StoreMode, int LoadMode>
00530     EIGEN_STRONG_INLINE void copyPacket(Index row, Index col, const DenseBase<OtherDerived>& other)
00531     {
00532       eigen_internal_assert(row >= 0 && row < rows()
00533                         && col >= 0 && col < cols());
00534       derived().template writePacket<StoreMode>(row, col,
00535         other.derived().template packet<LoadMode>(row, col));
00536     }
00537 
00546     template<typename OtherDerived, int StoreMode, int LoadMode>
00547     EIGEN_STRONG_INLINE void copyPacket(Index index, const DenseBase<OtherDerived>& other)
00548     {
00549       eigen_internal_assert(index >= 0 && index < size());
00550       derived().template writePacket<StoreMode>(index,
00551         other.derived().template packet<LoadMode>(index));
00552     }
00553 
00555     template<typename OtherDerived, int StoreMode, int LoadMode>
00556     EIGEN_STRONG_INLINE void copyPacketByOuterInner(Index outer, Index inner, const DenseBase<OtherDerived>& other)
00557     {
00558       const Index row = rowIndexByOuterInner(outer,inner);
00559       const Index col = colIndexByOuterInner(outer,inner);
00560       // derived() is important here: copyCoeff() may be reimplemented in Derived!
00561       derived().template copyPacket< OtherDerived, StoreMode, LoadMode>(row, col, other);
00562     }
00563 #endif
00564 
00565 };
00566 
00578 template<typename Derived>
00579 class DenseCoeffsBase<Derived, DirectAccessors> : public DenseCoeffsBase<Derived, ReadOnlyAccessors>
00580 {
00581   public:
00582 
00583     typedef DenseCoeffsBase<Derived, ReadOnlyAccessors> Base;
00584     typedef typename internal::traits<Derived>::Index Index;
00585     typedef typename internal::traits<Derived>::Scalar Scalar;
00586     typedef typename NumTraits<Scalar>::Real RealScalar;
00587 
00588     using Base::rows;
00589     using Base::cols;
00590     using Base::size;
00591     using Base::derived;
00592 
00597     inline Index innerStride() const
00598     {
00599       return derived().innerStride();
00600     }
00601 
00607     inline Index outerStride() const
00608     {
00609       return derived().outerStride();
00610     }
00611 
00612     // FIXME shall we remove it ?
00613     inline Index stride() const
00614     {
00615       return Derived::IsVectorAtCompileTime ? innerStride() : outerStride();
00616     }
00617 
00622     inline Index rowStride() const
00623     {
00624       return Derived::IsRowMajor ? outerStride() : innerStride();
00625     }
00626 
00631     inline Index colStride() const
00632     {
00633       return Derived::IsRowMajor ? innerStride() : outerStride();
00634     }
00635 };
00636 
00648 template<typename Derived>
00649 class DenseCoeffsBase<Derived, DirectWriteAccessors>
00650   : public DenseCoeffsBase<Derived, WriteAccessors>
00651 {
00652   public:
00653 
00654     typedef DenseCoeffsBase<Derived, WriteAccessors> Base;
00655     typedef typename internal::traits<Derived>::Index Index;
00656     typedef typename internal::traits<Derived>::Scalar Scalar;
00657     typedef typename NumTraits<Scalar>::Real RealScalar;
00658 
00659     using Base::rows;
00660     using Base::cols;
00661     using Base::size;
00662     using Base::derived;
00663 
00668     inline Index innerStride() const
00669     {
00670       return derived().innerStride();
00671     }
00672 
00678     inline Index outerStride() const
00679     {
00680       return derived().outerStride();
00681     }
00682 
00683     // FIXME shall we remove it ?
00684     inline Index stride() const
00685     {
00686       return Derived::IsVectorAtCompileTime ? innerStride() : outerStride();
00687     }
00688 
00693     inline Index rowStride() const
00694     {
00695       return Derived::IsRowMajor ? outerStride() : innerStride();
00696     }
00697 
00702     inline Index colStride() const
00703     {
00704       return Derived::IsRowMajor ? innerStride() : outerStride();
00705     }
00706 };
00707 
00708 namespace internal {
00709 
00710 template<typename Derived, bool JustReturnZero>
00711 struct first_aligned_impl
00712 {
00713   inline static typename Derived::Index run(const Derived&)
00714   { return 0; }
00715 };
00716 
00717 template<typename Derived>
00718 struct first_aligned_impl<Derived, false>
00719 {
00720   inline static typename Derived::Index run(const Derived& m)
00721   {
00722     return first_aligned(&m.const_cast_derived().coeffRef(0,0), m.size());
00723   }
00724 };
00725 
00731 template<typename Derived>
00732 inline static typename Derived::Index first_aligned(const Derived& m)
00733 {
00734   return first_aligned_impl
00735           <Derived, (Derived::Flags & AlignedBit) || !(Derived::Flags & DirectAccessBit)>
00736           ::run(m);
00737 }
00738 
00739 template<typename Derived, bool HasDirectAccess = has_direct_access<Derived>::ret>
00740 struct inner_stride_at_compile_time
00741 {
00742   enum { ret = traits<Derived>::InnerStrideAtCompileTime };
00743 };
00744 
00745 template<typename Derived>
00746 struct inner_stride_at_compile_time<Derived, false>
00747 {
00748   enum { ret = 0 };
00749 };
00750 
00751 template<typename Derived, bool HasDirectAccess = has_direct_access<Derived>::ret>
00752 struct outer_stride_at_compile_time
00753 {
00754   enum { ret = traits<Derived>::OuterStrideAtCompileTime };
00755 };
00756 
00757 template<typename Derived>
00758 struct outer_stride_at_compile_time<Derived, false>
00759 {
00760   enum { ret = 0 };
00761 };
00762 
00763 } // end namespace internal
00764 
00765 #endif // EIGEN_DENSECOEFFSBASE_H


libicr
Author(s): Robert Krug
autogenerated on Mon Jan 6 2014 11:32:37