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