Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Block.h
00001 // This file is part of Eigen, a lightweight C++ template library 00002 // for linear algebra. 00003 // 00004 // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> 00005 // Copyright (C) 2006-2010 Benoit Jacob <jacob.benoit.1@gmail.com> 00006 // 00007 // This Source Code Form is subject to the terms of the Mozilla 00008 // Public License v. 2.0. If a copy of the MPL was not distributed 00009 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 00010 00011 #ifndef EIGEN_BLOCK_H 00012 #define EIGEN_BLOCK_H 00013 00014 namespace Eigen { 00015 00016 /** \class Block 00017 * \ingroup Core_Module 00018 * 00019 * \brief Expression of a fixed-size or dynamic-size block 00020 * 00021 * \param XprType the type of the expression in which we are taking a block 00022 * \param BlockRows the number of rows of the block we are taking at compile time (optional) 00023 * \param BlockCols the number of columns of the block we are taking at compile time (optional) 00024 * 00025 * This class represents an expression of either a fixed-size or dynamic-size block. It is the return 00026 * type of DenseBase::block(Index,Index,Index,Index) and DenseBase::block<int,int>(Index,Index) and 00027 * most of the time this is the only way it is used. 00028 * 00029 * However, if you want to directly maniputate block expressions, 00030 * for instance if you want to write a function returning such an expression, you 00031 * will need to use this class. 00032 * 00033 * Here is an example illustrating the dynamic case: 00034 * \include class_Block.cpp 00035 * Output: \verbinclude class_Block.out 00036 * 00037 * \note Even though this expression has dynamic size, in the case where \a XprType 00038 * has fixed size, this expression inherits a fixed maximal size which means that evaluating 00039 * it does not cause a dynamic memory allocation. 00040 * 00041 * Here is an example illustrating the fixed-size case: 00042 * \include class_FixedBlock.cpp 00043 * Output: \verbinclude class_FixedBlock.out 00044 * 00045 * \sa DenseBase::block(Index,Index,Index,Index), DenseBase::block(Index,Index), class VectorBlock 00046 */ 00047 00048 namespace internal { 00049 template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel> 00050 struct traits<Block<XprType, BlockRows, BlockCols, InnerPanel> > : traits<XprType> 00051 { 00052 typedef typename traits<XprType>::Scalar Scalar; 00053 typedef typename traits<XprType>::StorageKind StorageKind; 00054 typedef typename traits<XprType>::XprKind XprKind; 00055 typedef typename nested<XprType>::type XprTypeNested; 00056 typedef typename remove_reference<XprTypeNested>::type _XprTypeNested; 00057 enum{ 00058 MatrixRows = traits<XprType>::RowsAtCompileTime, 00059 MatrixCols = traits<XprType>::ColsAtCompileTime, 00060 RowsAtCompileTime = MatrixRows == 0 ? 0 : BlockRows, 00061 ColsAtCompileTime = MatrixCols == 0 ? 0 : BlockCols, 00062 MaxRowsAtCompileTime = BlockRows==0 ? 0 00063 : RowsAtCompileTime != Dynamic ? int(RowsAtCompileTime) 00064 : int(traits<XprType>::MaxRowsAtCompileTime), 00065 MaxColsAtCompileTime = BlockCols==0 ? 0 00066 : ColsAtCompileTime != Dynamic ? int(ColsAtCompileTime) 00067 : int(traits<XprType>::MaxColsAtCompileTime), 00068 XprTypeIsRowMajor = (int(traits<XprType>::Flags)&RowMajorBit) != 0, 00069 IsDense = is_same<StorageKind,Dense>::value, 00070 IsRowMajor = (IsDense&&MaxRowsAtCompileTime==1&&MaxColsAtCompileTime!=1) ? 1 00071 : (IsDense&&MaxColsAtCompileTime==1&&MaxRowsAtCompileTime!=1) ? 0 00072 : XprTypeIsRowMajor, 00073 HasSameStorageOrderAsXprType = (IsRowMajor == XprTypeIsRowMajor), 00074 InnerSize = IsRowMajor ? int(ColsAtCompileTime) : int(RowsAtCompileTime), 00075 InnerStrideAtCompileTime = HasSameStorageOrderAsXprType 00076 ? int(inner_stride_at_compile_time<XprType>::ret) 00077 : int(outer_stride_at_compile_time<XprType>::ret), 00078 OuterStrideAtCompileTime = HasSameStorageOrderAsXprType 00079 ? int(outer_stride_at_compile_time<XprType>::ret) 00080 : int(inner_stride_at_compile_time<XprType>::ret), 00081 MaskPacketAccessBit = (InnerSize == Dynamic || (InnerSize % packet_traits<Scalar>::size) == 0) 00082 && (InnerStrideAtCompileTime == 1) 00083 ? PacketAccessBit : 0, 00084 MaskAlignedBit = (InnerPanel && (OuterStrideAtCompileTime!=Dynamic) && (((OuterStrideAtCompileTime * int(sizeof(Scalar))) % 16) == 0)) ? AlignedBit : 0, 00085 FlagsLinearAccessBit = (RowsAtCompileTime == 1 || ColsAtCompileTime == 1 || (InnerPanel && (traits<XprType>::Flags&LinearAccessBit))) ? LinearAccessBit : 0, 00086 FlagsLvalueBit = is_lvalue<XprType>::value ? LvalueBit : 0, 00087 FlagsRowMajorBit = IsRowMajor ? RowMajorBit : 0, 00088 Flags0 = traits<XprType>::Flags & ( (HereditaryBits & ~RowMajorBit) | 00089 DirectAccessBit | 00090 MaskPacketAccessBit | 00091 MaskAlignedBit), 00092 Flags = Flags0 | FlagsLinearAccessBit | FlagsLvalueBit | FlagsRowMajorBit 00093 }; 00094 }; 00095 00096 template<typename XprType, int BlockRows=Dynamic, int BlockCols=Dynamic, bool InnerPanel = false, 00097 bool HasDirectAccess = internal::has_direct_access<XprType>::ret> class BlockImpl_dense; 00098 00099 } // end namespace internal 00100 00101 template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel, typename StorageKind> class BlockImpl; 00102 00103 template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel> class Block 00104 : public BlockImpl<XprType, BlockRows, BlockCols, InnerPanel, typename internal::traits<XprType>::StorageKind> 00105 { 00106 typedef BlockImpl<XprType, BlockRows, BlockCols, InnerPanel, typename internal::traits<XprType>::StorageKind> Impl; 00107 public: 00108 //typedef typename Impl::Base Base; 00109 typedef Impl Base; 00110 EIGEN_GENERIC_PUBLIC_INTERFACE(Block) 00111 EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Block) 00112 00113 /** Column or Row constructor 00114 */ 00115 inline Block(XprType& xpr, Index i) : Impl(xpr,i) 00116 { 00117 eigen_assert( (i>=0) && ( 00118 ((BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) && i<xpr.rows()) 00119 ||((BlockRows==XprType::RowsAtCompileTime) && (BlockCols==1) && i<xpr.cols()))); 00120 } 00121 00122 /** Fixed-size constructor 00123 */ 00124 inline Block(XprType& xpr, Index a_startRow, Index a_startCol) 00125 : Impl(xpr, a_startRow, a_startCol) 00126 { 00127 EIGEN_STATIC_ASSERT(RowsAtCompileTime!=Dynamic && ColsAtCompileTime!=Dynamic,THIS_METHOD_IS_ONLY_FOR_FIXED_SIZE) 00128 eigen_assert(a_startRow >= 0 && BlockRows >= 1 && a_startRow + BlockRows <= xpr.rows() 00129 && a_startCol >= 0 && BlockCols >= 1 && a_startCol + BlockCols <= xpr.cols()); 00130 } 00131 00132 /** Dynamic-size constructor 00133 */ 00134 inline Block(XprType& xpr, 00135 Index a_startRow, Index a_startCol, 00136 Index blockRows, Index blockCols) 00137 : Impl(xpr, a_startRow, a_startCol, blockRows, blockCols) 00138 { 00139 eigen_assert((RowsAtCompileTime==Dynamic || RowsAtCompileTime==blockRows) 00140 && (ColsAtCompileTime==Dynamic || ColsAtCompileTime==blockCols)); 00141 eigen_assert(a_startRow >= 0 && blockRows >= 0 && a_startRow <= xpr.rows() - blockRows 00142 && a_startCol >= 0 && blockCols >= 0 && a_startCol <= xpr.cols() - blockCols); 00143 } 00144 }; 00145 00146 // The generic default implementation for dense block simplu forward to the internal::BlockImpl_dense 00147 // that must be specialized for direct and non-direct access... 00148 template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel> 00149 class BlockImpl<XprType, BlockRows, BlockCols, InnerPanel, Dense> 00150 : public internal::BlockImpl_dense<XprType, BlockRows, BlockCols, InnerPanel> 00151 { 00152 typedef internal::BlockImpl_dense<XprType, BlockRows, BlockCols, InnerPanel> Impl; 00153 typedef typename XprType::Index Index; 00154 public: 00155 typedef Impl Base; 00156 EIGEN_INHERIT_ASSIGNMENT_OPERATORS(BlockImpl) 00157 inline BlockImpl(XprType& xpr, Index i) : Impl(xpr,i) {} 00158 inline BlockImpl(XprType& xpr, Index a_startRow, Index a_startCol) : Impl(xpr, a_startRow, a_startCol) {} 00159 inline BlockImpl(XprType& xpr, Index a_startRow, Index a_startCol, Index blockRows, Index blockCols) 00160 : Impl(xpr, a_startRow, a_startCol, blockRows, blockCols) {} 00161 }; 00162 00163 namespace internal { 00164 00165 /** \internal Internal implementation of dense Blocks in the general case. */ 00166 template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel, bool HasDirectAccess> class BlockImpl_dense 00167 : public internal::dense_xpr_base<Block<XprType, BlockRows, BlockCols, InnerPanel> >::type 00168 { 00169 typedef Block<XprType, BlockRows, BlockCols, InnerPanel> BlockType; 00170 public: 00171 00172 typedef typename internal::dense_xpr_base<BlockType>::type Base; 00173 EIGEN_DENSE_PUBLIC_INTERFACE(BlockType) 00174 EIGEN_INHERIT_ASSIGNMENT_OPERATORS(BlockImpl_dense) 00175 00176 class InnerIterator; 00177 00178 /** Column or Row constructor 00179 */ 00180 inline BlockImpl_dense(XprType& xpr, Index i) 00181 : m_xpr(xpr), 00182 // It is a row if and only if BlockRows==1 and BlockCols==XprType::ColsAtCompileTime, 00183 // and it is a column if and only if BlockRows==XprType::RowsAtCompileTime and BlockCols==1, 00184 // all other cases are invalid. 00185 // The case a 1x1 matrix seems ambiguous, but the result is the same anyway. 00186 m_startRow( (BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) ? i : 0), 00187 m_startCol( (BlockRows==XprType::RowsAtCompileTime) && (BlockCols==1) ? i : 0), 00188 m_blockRows(BlockRows==1 ? 1 : xpr.rows()), 00189 m_blockCols(BlockCols==1 ? 1 : xpr.cols()) 00190 {} 00191 00192 /** Fixed-size constructor 00193 */ 00194 inline BlockImpl_dense(XprType& xpr, Index a_startRow, Index a_startCol) 00195 : m_xpr(xpr), m_startRow(a_startRow), m_startCol(a_startCol), 00196 m_blockRows(BlockRows), m_blockCols(BlockCols) 00197 {} 00198 00199 /** Dynamic-size constructor 00200 */ 00201 inline BlockImpl_dense(XprType& xpr, 00202 Index a_startRow, Index a_startCol, 00203 Index blockRows, Index blockCols) 00204 : m_xpr(xpr), m_startRow(a_startRow), m_startCol(a_startCol), 00205 m_blockRows(blockRows), m_blockCols(blockCols) 00206 {} 00207 00208 inline Index rows() const { return m_blockRows.value(); } 00209 inline Index cols() const { return m_blockCols.value(); } 00210 00211 inline Scalar& coeffRef(Index rowId, Index colId) 00212 { 00213 EIGEN_STATIC_ASSERT_LVALUE(XprType) 00214 return m_xpr.const_cast_derived() 00215 .coeffRef(rowId + m_startRow.value(), colId + m_startCol.value()); 00216 } 00217 00218 inline const Scalar& coeffRef(Index rowId, Index colId) const 00219 { 00220 return m_xpr.derived() 00221 .coeffRef(rowId + m_startRow.value(), colId + m_startCol.value()); 00222 } 00223 00224 EIGEN_STRONG_INLINE const CoeffReturnType coeff(Index rowId, Index colId) const 00225 { 00226 return m_xpr.coeff(rowId + m_startRow.value(), colId + m_startCol.value()); 00227 } 00228 00229 inline Scalar& coeffRef(Index index) 00230 { 00231 EIGEN_STATIC_ASSERT_LVALUE(XprType) 00232 return m_xpr.const_cast_derived() 00233 .coeffRef(m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index), 00234 m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0)); 00235 } 00236 00237 inline const Scalar& coeffRef(Index index) const 00238 { 00239 return m_xpr.const_cast_derived() 00240 .coeffRef(m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index), 00241 m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0)); 00242 } 00243 00244 inline const CoeffReturnType coeff(Index index) const 00245 { 00246 return m_xpr 00247 .coeff(m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index), 00248 m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0)); 00249 } 00250 00251 template<int LoadMode> 00252 inline PacketScalar packet(Index rowId, Index colId) const 00253 { 00254 return m_xpr.template packet<Unaligned> 00255 (rowId + m_startRow.value(), colId + m_startCol.value()); 00256 } 00257 00258 template<int LoadMode> 00259 inline void writePacket(Index rowId, Index colId, const PacketScalar& val) 00260 { 00261 m_xpr.const_cast_derived().template writePacket<Unaligned> 00262 (rowId + m_startRow.value(), colId + m_startCol.value(), val); 00263 } 00264 00265 template<int LoadMode> 00266 inline PacketScalar packet(Index index) const 00267 { 00268 return m_xpr.template packet<Unaligned> 00269 (m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index), 00270 m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0)); 00271 } 00272 00273 template<int LoadMode> 00274 inline void writePacket(Index index, const PacketScalar& val) 00275 { 00276 m_xpr.const_cast_derived().template writePacket<Unaligned> 00277 (m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index), 00278 m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0), val); 00279 } 00280 00281 #ifdef EIGEN_PARSED_BY_DOXYGEN 00282 /** \sa MapBase::data() */ 00283 inline const Scalar* data() const; 00284 inline Index innerStride() const; 00285 inline Index outerStride() const; 00286 #endif 00287 00288 const typename internal::remove_all<typename XprType::Nested>::type& nestedExpression() const 00289 { 00290 return m_xpr; 00291 } 00292 00293 Index startRow() const 00294 { 00295 return m_startRow.value(); 00296 } 00297 00298 Index startCol() const 00299 { 00300 return m_startCol.value(); 00301 } 00302 00303 protected: 00304 00305 const typename XprType::Nested m_xpr; 00306 const internal::variable_if_dynamic<Index, XprType::RowsAtCompileTime == 1 ? 0 : Dynamic> m_startRow; 00307 const internal::variable_if_dynamic<Index, XprType::ColsAtCompileTime == 1 ? 0 : Dynamic> m_startCol; 00308 const internal::variable_if_dynamic<Index, RowsAtCompileTime> m_blockRows; 00309 const internal::variable_if_dynamic<Index, ColsAtCompileTime> m_blockCols; 00310 }; 00311 00312 /** \internal Internal implementation of dense Blocks in the direct access case.*/ 00313 template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel> 00314 class BlockImpl_dense<XprType,BlockRows,BlockCols, InnerPanel,true> 00315 : public MapBase<Block<XprType, BlockRows, BlockCols, InnerPanel> > 00316 { 00317 typedef Block<XprType, BlockRows, BlockCols, InnerPanel> BlockType; 00318 public: 00319 00320 typedef MapBase<BlockType> Base; 00321 EIGEN_DENSE_PUBLIC_INTERFACE(BlockType) 00322 EIGEN_INHERIT_ASSIGNMENT_OPERATORS(BlockImpl_dense) 00323 00324 /** Column or Row constructor 00325 */ 00326 inline BlockImpl_dense(XprType& xpr, Index i) 00327 : Base(internal::const_cast_ptr(&xpr.coeffRef( 00328 (BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) ? i : 0, 00329 (BlockRows==XprType::RowsAtCompileTime) && (BlockCols==1) ? i : 0)), 00330 BlockRows==1 ? 1 : xpr.rows(), 00331 BlockCols==1 ? 1 : xpr.cols()), 00332 m_xpr(xpr) 00333 { 00334 init(); 00335 } 00336 00337 /** Fixed-size constructor 00338 */ 00339 inline BlockImpl_dense(XprType& xpr, Index startRow, Index startCol) 00340 : Base(internal::const_cast_ptr(&xpr.coeffRef(startRow,startCol))), m_xpr(xpr) 00341 { 00342 init(); 00343 } 00344 00345 /** Dynamic-size constructor 00346 */ 00347 inline BlockImpl_dense(XprType& xpr, 00348 Index startRow, Index startCol, 00349 Index blockRows, Index blockCols) 00350 : Base(internal::const_cast_ptr(&xpr.coeffRef(startRow,startCol)), blockRows, blockCols), 00351 m_xpr(xpr) 00352 { 00353 init(); 00354 } 00355 00356 const typename internal::remove_all<typename XprType::Nested>::type& nestedExpression() const 00357 { 00358 return m_xpr; 00359 } 00360 00361 /** \sa MapBase::innerStride() */ 00362 inline Index innerStride() const 00363 { 00364 return internal::traits<BlockType>::HasSameStorageOrderAsXprType 00365 ? m_xpr.innerStride() 00366 : m_xpr.outerStride(); 00367 } 00368 00369 /** \sa MapBase::outerStride() */ 00370 inline Index outerStride() const 00371 { 00372 return m_outerStride; 00373 } 00374 00375 #ifndef __SUNPRO_CC 00376 // FIXME sunstudio is not friendly with the above friend... 00377 // META-FIXME there is no 'friend' keyword around here. Is this obsolete? 00378 protected: 00379 #endif 00380 00381 #ifndef EIGEN_PARSED_BY_DOXYGEN 00382 /** \internal used by allowAligned() */ 00383 inline BlockImpl_dense(XprType& xpr, const Scalar* data, Index blockRows, Index blockCols) 00384 : Base(data, blockRows, blockCols), m_xpr(xpr) 00385 { 00386 init(); 00387 } 00388 #endif 00389 00390 protected: 00391 void init() 00392 { 00393 m_outerStride = internal::traits<BlockType>::HasSameStorageOrderAsXprType 00394 ? m_xpr.outerStride() 00395 : m_xpr.innerStride(); 00396 } 00397 00398 typename XprType::Nested m_xpr; 00399 Index m_outerStride; 00400 }; 00401 00402 } // end namespace internal 00403 00404 } // end namespace Eigen 00405 00406 #endif // EIGEN_BLOCK_H
Generated on Thu Nov 17 2022 22:01:27 by
1.7.2