Main MRPT website > C++ reference
MRPT logo

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 
00035 /** \brief Base class providing read-only coefficient access to matrices and arrays.
00036   * \ingroup Core_Module
00037   * \tparam Derived Type of the derived class
00038   * \tparam ReadOnlyAccessors Constant indicating read-only access
00039   *
00040   * This class defines the \c operator() \c const function and friends, which can be used to read specific
00041   * entries of a matrix or array.
00042   * 
00043   * \sa DenseCoeffsBase<Derived, WriteAccessors>, DenseCoeffsBase<Derived, DirectAccessors>,
00044   *     \ref TopicClassHierarchy
00045   */
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 
00093     /** Short version: don't use this function, use
00094       * \link operator()(Index,Index) const \endlink instead.
00095       *
00096       * Long version: this function is similar to
00097       * \link operator()(Index,Index) const \endlink, but without the assertion.
00098       * Use this for limiting the performance cost of debugging code when doing
00099       * repeated coefficient access. Only use this when it is guaranteed that the
00100       * parameters \a row and \a col are in range.
00101       *
00102       * If EIGEN_INTERNAL_DEBUGGING is defined, an assertion will be made, making this
00103       * function equivalent to \link operator()(Index,Index) const \endlink.
00104       *
00105       * \sa operator()(Index,Index) const, coeffRef(Index,Index), coeff(Index) const
00106       */
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 
00120     /** \returns the coefficient at given the given row and column.
00121       *
00122       * \sa operator()(Index,Index), operator[](Index)
00123       */
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 
00131     /** Short version: don't use this function, use
00132       * \link operator[](Index) const \endlink instead.
00133       *
00134       * Long version: this function is similar to
00135       * \link operator[](Index) const \endlink, but without the assertion.
00136       * Use this for limiting the performance cost of debugging code when doing
00137       * repeated coefficient access. Only use this when it is guaranteed that the
00138       * parameter \a index is in range.
00139       *
00140       * If EIGEN_INTERNAL_DEBUGGING is defined, an assertion will be made, making this
00141       * function equivalent to \link operator[](Index) const \endlink.
00142       *
00143       * \sa operator[](Index) const, coeffRef(Index), coeff(Index,Index) const
00144       */
00145 
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 
00154     /** \returns the coefficient at given index.
00155       *
00156       * This method is allowed only for vector expressions, and for matrix expressions having the LinearAccessBit.
00157       *
00158       * \sa operator[](Index), operator()(Index,Index) const, x() const, y() const,
00159       * z() const, w() const
00160       */
00161 
00162     EIGEN_STRONG_INLINE CoeffReturnType
00163     operator[](Index index) const
00164     {
00165       EIGEN_STATIC_ASSERT(Derived::IsVectorAtCompileTime,
00166                           THE_BRACKET_OPERATOR_IS_ONLY_FOR_VECTORS__USE_THE_PARENTHESIS_OPERATOR_INSTEAD)
00167       eigen_assert(index >= 0 && index < size());
00168       return derived().coeff(index);
00169     }
00170 
00171     /** \returns the coefficient at given index.
00172       *
00173       * This is synonymous to operator[](Index) const.
00174       *
00175       * This method is allowed only for vector expressions, and for matrix expressions having the LinearAccessBit.
00176       *
00177       * \sa operator[](Index), operator()(Index,Index) const, x() const, y() const,
00178       * z() const, w() const
00179       */
00180 
00181     EIGEN_STRONG_INLINE CoeffReturnType
00182     operator()(Index index) const
00183     {
00184       eigen_assert(index >= 0 && index < size());
00185       return derived().coeff(index);
00186     }
00187 
00188     /** equivalent to operator[](0).  */
00189 
00190     EIGEN_STRONG_INLINE CoeffReturnType
00191     x() const { return (*this)[0]; }
00192 
00193     /** equivalent to operator[](1).  */
00194 
00195     EIGEN_STRONG_INLINE CoeffReturnType
00196     y() const { return (*this)[1]; }
00197 
00198     /** equivalent to operator[](2).  */
00199 
00200     EIGEN_STRONG_INLINE CoeffReturnType
00201     z() const { return (*this)[2]; }
00202 
00203     /** equivalent to operator[](3).  */
00204 
00205     EIGEN_STRONG_INLINE CoeffReturnType
00206     w() const { return (*this)[3]; }
00207 
00208     /** \returns the packet of coefficients starting at the given row and column. It is your responsibility
00209       * to ensure that a packet really starts there. This method is only available on expressions having the
00210       * PacketAccessBit.
00211       *
00212       * The \a LoadMode parameter may have the value \a Aligned or \a Unaligned. Its effect is to select
00213       * the appropriate vectorization instruction. Aligned access is faster, but is only possible for packets
00214       * starting at an address which is a multiple of the packet size.
00215       */
00216 
00217     template<int LoadMode>
00218     EIGEN_STRONG_INLINE PacketReturnType packet(Index row, Index col) const
00219     {
00220       eigen_internal_assert(row >= 0 && row < rows()
00221                       && col >= 0 && col < cols());
00222       return derived().template packet<LoadMode>(row,col);
00223     }
00224 
00225 
00226     template<int LoadMode>
00227     EIGEN_STRONG_INLINE PacketReturnType packetByOuterInner(Index outer, Index inner) const
00228     {
00229       return packet<LoadMode>(rowIndexByOuterInner(outer, inner),
00230                               colIndexByOuterInner(outer, inner));
00231     }
00232 
00233     /** \returns the packet of coefficients starting at the given index. It is your responsibility
00234       * to ensure that a packet really starts there. This method is only available on expressions having the
00235       * PacketAccessBit and the LinearAccessBit.
00236       *
00237       * The \a LoadMode parameter may have the value \a Aligned or \a Unaligned. Its effect is to select
00238       * the appropriate vectorization instruction. Aligned access is faster, but is only possible for packets
00239       * starting at an address which is a multiple of the packet size.
00240       */
00241 
00242     template<int LoadMode>
00243     EIGEN_STRONG_INLINE PacketReturnType packet(Index index) const
00244     {
00245       eigen_internal_assert(index >= 0 && index < size());
00246       return derived().template packet<LoadMode>(index);
00247     }
00248 
00249   protected:
00250     // explanation: DenseBase is doing "using ..." on the methods from DenseCoeffsBase.
00251     // But some methods are only available in the DirectAccess case.
00252     // So we add dummy methods here with these names, so that "using... " doesn't fail.
00253     // It's not private so that the child class DenseBase can access them, and it's not public
00254     // either since it's an implementation detail, so has to be protected.
00255     void coeffRef();
00256     void coeffRefByOuterInner();
00257     void writePacket();
00258     void writePacketByOuterInner();
00259     void copyCoeff();
00260     void copyCoeffByOuterInner();
00261     void copyPacket();
00262     void copyPacketByOuterInner();
00263     void stride();
00264     void innerStride();
00265     void outerStride();
00266     void rowStride();
00267     void colStride();
00268 };
00269 
00270 /** \brief Base class providing read/write coefficient access to matrices and arrays.
00271   * \ingroup Core_Module
00272   * \tparam Derived Type of the derived class
00273   * \tparam WriteAccessors Constant indicating read/write access
00274   *
00275   * This class defines the non-const \c operator() function and friends, which can be used to write specific
00276   * entries of a matrix or array. This class inherits DenseCoeffsBase<Derived, ReadOnlyAccessors> which
00277   * defines the const variant for reading specific entries.
00278   * 
00279   * \sa DenseCoeffsBase<Derived, DirectAccessors>, \ref TopicClassHierarchy
00280   */
00281 template<typename Derived>
00282 class DenseCoeffsBase<Derived, WriteAccessors> : public DenseCoeffsBase<Derived, ReadOnlyAccessors>
00283 {
00284   public:
00285 
00286     typedef DenseCoeffsBase<Derived, ReadOnlyAccessors> Base;
00287 
00288     typedef typename internal::traits<Derived>::StorageKind StorageKind;
00289     typedef typename internal::traits<Derived>::Index Index;
00290     typedef typename internal::traits<Derived>::Scalar Scalar;
00291     typedef typename internal::packet_traits<Scalar>::type PacketScalar;
00292     typedef typename NumTraits<Scalar>::Real RealScalar;
00293 
00294     using Base::coeff;
00295     using Base::rows;
00296     using Base::cols;
00297     using Base::size;
00298     using Base::derived;
00299     using Base::rowIndexByOuterInner;
00300     using Base::colIndexByOuterInner;
00301     using Base::operator[];
00302     using Base::operator();
00303     using Base::x;
00304     using Base::y;
00305     using Base::z;
00306     using Base::w;
00307 
00308     /** Short version: don't use this function, use
00309       * \link operator()(Index,Index) \endlink instead.
00310       *
00311       * Long version: this function is similar to
00312       * \link operator()(Index,Index) \endlink, but without the assertion.
00313       * Use this for limiting the performance cost of debugging code when doing
00314       * repeated coefficient access. Only use this when it is guaranteed that the
00315       * parameters \a row and \a col are in range.
00316       *
00317       * If EIGEN_INTERNAL_DEBUGGING is defined, an assertion will be made, making this
00318       * function equivalent to \link operator()(Index,Index) \endlink.
00319       *
00320       * \sa operator()(Index,Index), coeff(Index, Index) const, coeffRef(Index)
00321       */
00322     EIGEN_STRONG_INLINE Scalar& coeffRef(Index row, Index col)
00323     {
00324       eigen_internal_assert(row >= 0 && row < rows()
00325                         && col >= 0 && col < cols());
00326       return derived().coeffRef(row, col);
00327     }
00328 
00329     EIGEN_STRONG_INLINE Scalar&
00330     coeffRefByOuterInner(Index outer, Index inner)
00331     {
00332       return coeffRef(rowIndexByOuterInner(outer, inner),
00333                       colIndexByOuterInner(outer, inner));
00334     }
00335 
00336     /** \returns a reference to the coefficient at given the given row and column.
00337       *
00338       * \sa operator[](Index)
00339       */
00340 
00341     EIGEN_STRONG_INLINE Scalar&
00342     operator()(Index row, Index col)
00343     {
00344       eigen_assert(row >= 0 && row < rows()
00345           && col >= 0 && col < cols());
00346       return derived().coeffRef(row, col);
00347     }
00348 
00349 
00350     /** Short version: don't use this function, use
00351       * \link operator[](Index) \endlink instead.
00352       *
00353       * Long version: this function is similar to
00354       * \link operator[](Index) \endlink, but without the assertion.
00355       * Use this for limiting the performance cost of debugging code when doing
00356       * repeated coefficient access. Only use this when it is guaranteed that the
00357       * parameters \a row and \a col are in range.
00358       *
00359       * If EIGEN_INTERNAL_DEBUGGING is defined, an assertion will be made, making this
00360       * function equivalent to \link operator[](Index) \endlink.
00361       *
00362       * \sa operator[](Index), coeff(Index) const, coeffRef(Index,Index)
00363       */
00364 
00365     EIGEN_STRONG_INLINE Scalar&
00366     coeffRef(Index index)
00367     {
00368       eigen_internal_assert(index >= 0 && index < size());
00369       return derived().coeffRef(index);
00370     }
00371 
00372     /** \returns a reference to the coefficient at given index.
00373       *
00374       * This method is allowed only for vector expressions, and for matrix expressions having the LinearAccessBit.
00375       *
00376       * \sa operator[](Index) const, operator()(Index,Index), x(), y(), z(), w()
00377       */
00378 
00379     EIGEN_STRONG_INLINE Scalar&
00380     operator[](Index index)
00381     {
00382       EIGEN_STATIC_ASSERT(Derived::IsVectorAtCompileTime,
00383                           THE_BRACKET_OPERATOR_IS_ONLY_FOR_VECTORS__USE_THE_PARENTHESIS_OPERATOR_INSTEAD)
00384       eigen_assert(index >= 0 && index < size());
00385       return derived().coeffRef(index);
00386     }
00387 
00388     /** \returns a reference to the coefficient at given index.
00389       *
00390       * This is synonymous to operator[](Index).
00391       *
00392       * This method is allowed only for vector expressions, and for matrix expressions having the LinearAccessBit.
00393       *
00394       * \sa operator[](Index) const, operator()(Index,Index), x(), y(), z(), w()
00395       */
00396 
00397     EIGEN_STRONG_INLINE Scalar&
00398     operator()(Index index)
00399     {
00400       eigen_assert(index >= 0 && index < size());
00401       return derived().coeffRef(index);
00402     }
00403 
00404     /** equivalent to operator[](0).  */
00405 
00406     EIGEN_STRONG_INLINE Scalar&
00407     x() { return (*this)[0]; }
00408 
00409     /** equivalent to operator[](1).  */
00410 
00411     EIGEN_STRONG_INLINE Scalar&
00412     y() { return (*this)[1]; }
00413 
00414     /** equivalent to operator[](2).  */
00415 
00416     EIGEN_STRONG_INLINE Scalar&
00417     z() { return (*this)[2]; }
00418 
00419     /** equivalent to operator[](3).  */
00420 
00421     EIGEN_STRONG_INLINE Scalar&
00422     w() { return (*this)[3]; }
00423 
00424     /** Stores the given packet of coefficients, at the given row and column of this expression. It is your responsibility
00425       * to ensure that a packet really starts there. This method is only available on expressions having the
00426       * PacketAccessBit.
00427       *
00428       * The \a LoadMode parameter may have the value \a Aligned or \a Unaligned. Its effect is to select
00429       * the appropriate vectorization instruction. Aligned access is faster, but is only possible for packets
00430       * starting at an address which is a multiple of the packet size.
00431       */
00432 
00433     template<int StoreMode>
00434     EIGEN_STRONG_INLINE void writePacket
00435     (Index row, Index col, const typename internal::packet_traits<Scalar>::type& x)
00436     {
00437       eigen_internal_assert(row >= 0 && row < rows()
00438                         && col >= 0 && col < cols());
00439       derived().template writePacket<StoreMode>(row,col,x);
00440     }
00441 
00442 
00443     template<int StoreMode>
00444     EIGEN_STRONG_INLINE void writePacketByOuterInner
00445     (Index outer, Index inner, const typename internal::packet_traits<Scalar>::type& x)
00446     {
00447       writePacket<StoreMode>(rowIndexByOuterInner(outer, inner),
00448                             colIndexByOuterInner(outer, inner),
00449                             x);
00450     }
00451 
00452     /** Stores the given packet of coefficients, at the given index in this expression. It is your responsibility
00453       * to ensure that a packet really starts there. This method is only available on expressions having the
00454       * PacketAccessBit and the LinearAccessBit.
00455       *
00456       * The \a LoadMode parameter may have the value \a Aligned or \a Unaligned. Its effect is to select
00457       * the appropriate vectorization instruction. Aligned access is faster, but is only possible for packets
00458       * starting at an address which is a multiple of the packet size.
00459       */
00460 
00461     template<int StoreMode>
00462     EIGEN_STRONG_INLINE void writePacket
00463     (Index index, const typename internal::packet_traits<Scalar>::type& x)
00464     {
00465       eigen_internal_assert(index >= 0 && index < size());
00466       derived().template writePacket<StoreMode>(index,x);
00467     }
00468 
00469 #ifndef EIGEN_PARSED_BY_DOXYGEN
00470 
00471     /** \internal Copies the coefficient at position (row,col) of other into *this.
00472       *
00473       * This method is overridden in SwapWrapper, allowing swap() assignments to share 99% of their code
00474       * with usual assignments.
00475       *
00476       * Outside of this internal usage, this method has probably no usefulness. It is hidden in the public API dox.
00477       */
00478 
00479     template<typename OtherDerived>
00480     EIGEN_STRONG_INLINE void copyCoeff(Index row, Index col, const DenseBase<OtherDerived>& other)
00481     {
00482       eigen_internal_assert(row >= 0 && row < rows()
00483                         && col >= 0 && col < cols());
00484       derived().coeffRef(row, col) = other.derived().coeff(row, col);
00485     }
00486 
00487     /** \internal Copies the coefficient at the given index of other into *this.
00488       *
00489       * This method is overridden in SwapWrapper, allowing swap() assignments to share 99% of their code
00490       * with usual assignments.
00491       *
00492       * Outside of this internal usage, this method has probably no usefulness. It is hidden in the public API dox.
00493       */
00494 
00495     template<typename OtherDerived>
00496     EIGEN_STRONG_INLINE void copyCoeff(Index index, const DenseBase<OtherDerived>& other)
00497     {
00498       eigen_internal_assert(index >= 0 && index < size());
00499       derived().coeffRef(index) = other.derived().coeff(index);
00500     }
00501 
00502 
00503     template<typename OtherDerived>
00504     EIGEN_STRONG_INLINE void copyCoeffByOuterInner(Index outer, Index inner, const DenseBase<OtherDerived>& other)
00505     {
00506       const Index row = rowIndexByOuterInner(outer,inner);
00507       const Index col = colIndexByOuterInner(outer,inner);
00508       // derived() is important here: copyCoeff() may be reimplemented in Derived!
00509       derived().copyCoeff(row, col, other);
00510     }
00511 
00512     /** \internal Copies the packet at position (row,col) of other into *this.
00513       *
00514       * This method is overridden in SwapWrapper, allowing swap() assignments to share 99% of their code
00515       * with usual assignments.
00516       *
00517       * Outside of this internal usage, this method has probably no usefulness. It is hidden in the public API dox.
00518       */
00519 
00520     template<typename OtherDerived, int StoreMode, int LoadMode>
00521     EIGEN_STRONG_INLINE void copyPacket(Index row, Index col, const DenseBase<OtherDerived>& other)
00522     {
00523       eigen_internal_assert(row >= 0 && row < rows()
00524                         && col >= 0 && col < cols());
00525       derived().template writePacket<StoreMode>(row, col,
00526         other.derived().template packet<LoadMode>(row, col));
00527     }
00528 
00529     /** \internal Copies the packet at the given index of other into *this.
00530       *
00531       * This method is overridden in SwapWrapper, allowing swap() assignments to share 99% of their code
00532       * with usual assignments.
00533       *
00534       * Outside of this internal usage, this method has probably no usefulness. It is hidden in the public API dox.
00535       */
00536 
00537     template<typename OtherDerived, int StoreMode, int LoadMode>
00538     EIGEN_STRONG_INLINE void copyPacket(Index index, const DenseBase<OtherDerived>& other)
00539     {
00540       eigen_internal_assert(index >= 0 && index < size());
00541       derived().template writePacket<StoreMode>(index,
00542         other.derived().template packet<LoadMode>(index));
00543     }
00544 
00545     template<typename OtherDerived, int StoreMode, int LoadMode>
00546     EIGEN_STRONG_INLINE void copyPacketByOuterInner(Index outer, Index inner, const DenseBase<OtherDerived>& other)
00547     {
00548       const Index row = rowIndexByOuterInner(outer,inner);
00549       const Index col = colIndexByOuterInner(outer,inner);
00550       // derived() is important here: copyCoeff() may be reimplemented in Derived!
00551       derived().template copyPacket< OtherDerived, StoreMode, LoadMode>(row, col, other);
00552     }
00553 #endif
00554 
00555 };
00556 
00557 /** \brief Base class providing direct read-only coefficient access to matrices and arrays.
00558   * \ingroup Core_Module
00559   * \tparam Derived Type of the derived class
00560   * \tparam DirectAccessors Constant indicating direct access
00561   *
00562   * This class defines functions to work with strides which can be used to access entries directly. This class
00563   * inherits DenseCoeffsBase<Derived, ReadOnlyAccessors> which defines functions to access entries read-only using
00564   * \c operator() .
00565   *
00566   * \sa \ref TopicClassHierarchy
00567   */
00568 template<typename Derived>
00569 class DenseCoeffsBase<Derived, DirectAccessors> : public DenseCoeffsBase<Derived, ReadOnlyAccessors>
00570 {
00571   public:
00572 
00573     typedef DenseCoeffsBase<Derived, ReadOnlyAccessors> Base;
00574     typedef typename internal::traits<Derived>::Index Index;
00575     typedef typename internal::traits<Derived>::Scalar Scalar;
00576     typedef typename NumTraits<Scalar>::Real RealScalar;
00577 
00578     using Base::rows;
00579     using Base::cols;
00580     using Base::size;
00581     using Base::derived;
00582 
00583     /** \returns the pointer increment between two consecutive elements within a slice in the inner direction.
00584       *
00585       * \sa outerStride(), rowStride(), colStride()
00586       */
00587     inline Index innerStride() const
00588     {
00589       return derived().innerStride();
00590     }
00591 
00592     /** \returns the pointer increment between two consecutive inner slices (for example, between two consecutive columns
00593       *          in a column-major matrix).
00594       *
00595       * \sa innerStride(), rowStride(), colStride()
00596       */
00597     inline Index outerStride() const
00598     {
00599       return derived().outerStride();
00600     }
00601 
00602     // FIXME shall we remove it ?
00603     inline Index stride() const
00604     {
00605       return Derived::IsVectorAtCompileTime ? innerStride() : outerStride();
00606     }
00607 
00608     /** \returns the pointer increment between two consecutive rows.
00609       *
00610       * \sa innerStride(), outerStride(), colStride()
00611       */
00612     inline Index rowStride() const
00613     {
00614       return Derived::IsRowMajor ? outerStride() : innerStride();
00615     }
00616 
00617     /** \returns the pointer increment between two consecutive columns.
00618       *
00619       * \sa innerStride(), outerStride(), rowStride()
00620       */
00621     inline Index colStride() const
00622     {
00623       return Derived::IsRowMajor ? innerStride() : outerStride();
00624     }
00625 };
00626 
00627 /** \brief Base class providing direct read/write coefficient access to matrices and arrays.
00628   * \ingroup Core_Module
00629   * \tparam Derived Type of the derived class
00630   * \tparam DirectAccessors Constant indicating direct access
00631   *
00632   * This class defines functions to work with strides which can be used to access entries directly. This class
00633   * inherits DenseCoeffsBase<Derived, WriteAccessors> which defines functions to access entries read/write using
00634   * \c operator().
00635   *
00636   * \sa \ref TopicClassHierarchy
00637   */
00638 template<typename Derived>
00639 class DenseCoeffsBase<Derived, DirectWriteAccessors>
00640   : public DenseCoeffsBase<Derived, WriteAccessors>
00641 {
00642   public:
00643 
00644     typedef DenseCoeffsBase<Derived, WriteAccessors> Base;
00645     typedef typename internal::traits<Derived>::Index Index;
00646     typedef typename internal::traits<Derived>::Scalar Scalar;
00647     typedef typename NumTraits<Scalar>::Real RealScalar;
00648 
00649     using Base::rows;
00650     using Base::cols;
00651     using Base::size;
00652     using Base::derived;
00653 
00654     /** \returns the pointer increment between two consecutive elements within a slice in the inner direction.
00655       *
00656       * \sa outerStride(), rowStride(), colStride()
00657       */
00658     inline Index innerStride() const
00659     {
00660       return derived().innerStride();
00661     }
00662 
00663     /** \returns the pointer increment between two consecutive inner slices (for example, between two consecutive columns
00664       *          in a column-major matrix).
00665       *
00666       * \sa innerStride(), rowStride(), colStride()
00667       */
00668     inline Index outerStride() const
00669     {
00670       return derived().outerStride();
00671     }
00672 
00673     // FIXME shall we remove it ?
00674     inline Index stride() const
00675     {
00676       return Derived::IsVectorAtCompileTime ? innerStride() : outerStride();
00677     }
00678 
00679     /** \returns the pointer increment between two consecutive rows.
00680       *
00681       * \sa innerStride(), outerStride(), colStride()
00682       */
00683     inline Index rowStride() const
00684     {
00685       return Derived::IsRowMajor ? outerStride() : innerStride();
00686     }
00687 
00688     /** \returns the pointer increment between two consecutive columns.
00689       *
00690       * \sa innerStride(), outerStride(), rowStride()
00691       */
00692     inline Index colStride() const
00693     {
00694       return Derived::IsRowMajor ? innerStride() : outerStride();
00695     }
00696 };
00697 
00698 namespace internal {
00699 
00700 template<typename Derived, bool JustReturnZero>
00701 struct first_aligned_impl
00702 {
00703   inline static typename Derived::Index run(const Derived&)
00704   { return 0; }
00705 };
00706 
00707 template<typename Derived>
00708 struct first_aligned_impl<Derived, false>
00709 {
00710   inline static typename Derived::Index run(const Derived& m)
00711   {
00712     return first_aligned(&m.const_cast_derived().coeffRef(0,0), m.size());
00713   }
00714 };
00715 
00716 /** \internal \returns the index of the first element of the array that is well aligned for vectorization.
00717   *
00718   * There is also the variant first_aligned(const Scalar*, Integer) defined in Memory.h. See it for more
00719   * documentation.
00720   */
00721 template<typename Derived>
00722 inline static typename Derived::Index first_aligned(const Derived& m)
00723 {
00724   return first_aligned_impl
00725           <Derived, (Derived::Flags & AlignedBit) || !(Derived::Flags & DirectAccessBit)>
00726           ::run(m);
00727 }
00728 
00729 template<typename Derived, bool HasDirectAccess = has_direct_access<Derived>::ret>
00730 struct inner_stride_at_compile_time
00731 {
00732   enum { ret = traits<Derived>::InnerStrideAtCompileTime };
00733 };
00734 
00735 template<typename Derived>
00736 struct inner_stride_at_compile_time<Derived, false>
00737 {
00738   enum { ret = 0 };
00739 };
00740 
00741 template<typename Derived, bool HasDirectAccess = has_direct_access<Derived>::ret>
00742 struct outer_stride_at_compile_time
00743 {
00744   enum { ret = traits<Derived>::OuterStrideAtCompileTime };
00745 };
00746 
00747 template<typename Derived>
00748 struct outer_stride_at_compile_time<Derived, false>
00749 {
00750   enum { ret = 0 };
00751 };
00752 
00753 } // end namespace internal
00754 
00755 #endif // EIGEN_DENSECOEFFSBASE_H



Page generated by Doxygen 1.7.3 for MRPT 0.9.4 SVN:exported at Tue Jan 25 21:56:31 UTC 2011