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