$treeview $search $mathjax
Eigen
3.2.5
$projectbrief
|
$projectbrief
|
$searchbox |
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>::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 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 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 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 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 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 00179 EIGEN_STRONG_INLINE CoeffReturnType 00180 x() const { return (*this)[0]; } 00181 00184 EIGEN_STRONG_INLINE CoeffReturnType 00185 y() const { return (*this)[1]; } 00186 00189 EIGEN_STRONG_INLINE CoeffReturnType 00190 z() const { return (*this)[2]; } 00191 00194 EIGEN_STRONG_INLINE CoeffReturnType 00195 w() const { return (*this)[3]; } 00196 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 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 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 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 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 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 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 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 00391 EIGEN_STRONG_INLINE Scalar& 00392 operator()(Index index) 00393 { 00394 eigen_assert(index >= 0 && index < size()); 00395 return derived().coeffRef(index); 00396 } 00397 00400 EIGEN_STRONG_INLINE Scalar& 00401 x() { return (*this)[0]; } 00402 00405 EIGEN_STRONG_INLINE Scalar& 00406 y() { return (*this)[1]; } 00407 00410 EIGEN_STRONG_INLINE Scalar& 00411 z() { return (*this)[2]; } 00412 00415 EIGEN_STRONG_INLINE Scalar& 00416 w() { return (*this)[3]; } 00417 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 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 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 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 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 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 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 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 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 00584 inline Index innerStride() const 00585 { 00586 return derived().innerStride(); 00587 } 00588 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 00609 inline Index rowStride() const 00610 { 00611 return Derived::IsRowMajor ? outerStride() : innerStride(); 00612 } 00613 00618 inline Index colStride() const 00619 { 00620 return Derived::IsRowMajor ? innerStride() : outerStride(); 00621 } 00622 }; 00623 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 00655 inline Index innerStride() const 00656 { 00657 return derived().innerStride(); 00658 } 00659 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 00680 inline Index rowStride() const 00681 { 00682 return Derived::IsRowMajor ? outerStride() : innerStride(); 00683 } 00684 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 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