![]() |
Eigen
3.3.3
|
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 namespace internal { 00017 template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel> 00018 struct traits<Block<XprType, BlockRows, BlockCols, InnerPanel> > : traits<XprType> 00019 { 00020 typedef typename traits<XprType>::Scalar Scalar; 00021 typedef typename traits<XprType>::StorageKind StorageKind; 00022 typedef typename traits<XprType>::XprKind XprKind; 00023 typedef typename ref_selector<XprType>::type XprTypeNested; 00024 typedef typename remove_reference<XprTypeNested>::type _XprTypeNested; 00025 enum{ 00026 MatrixRows = traits<XprType>::RowsAtCompileTime, 00027 MatrixCols = traits<XprType>::ColsAtCompileTime, 00028 RowsAtCompileTime = MatrixRows == 0 ? 0 : BlockRows, 00029 ColsAtCompileTime = MatrixCols == 0 ? 0 : BlockCols, 00030 MaxRowsAtCompileTime = BlockRows==0 ? 0 00031 : RowsAtCompileTime != Dynamic ? int(RowsAtCompileTime) 00032 : int(traits<XprType>::MaxRowsAtCompileTime), 00033 MaxColsAtCompileTime = BlockCols==0 ? 0 00034 : ColsAtCompileTime != Dynamic ? int(ColsAtCompileTime) 00035 : int(traits<XprType>::MaxColsAtCompileTime), 00036 00037 XprTypeIsRowMajor = (int(traits<XprType>::Flags)&RowMajorBit) != 0, 00038 IsRowMajor = (MaxRowsAtCompileTime==1&&MaxColsAtCompileTime!=1) ? 1 00039 : (MaxColsAtCompileTime==1&&MaxRowsAtCompileTime!=1) ? 0 00040 : XprTypeIsRowMajor, 00041 HasSameStorageOrderAsXprType = (IsRowMajor == XprTypeIsRowMajor), 00042 InnerSize = IsRowMajor ? int(ColsAtCompileTime) : int(RowsAtCompileTime), 00043 InnerStrideAtCompileTime = HasSameStorageOrderAsXprType 00044 ? int(inner_stride_at_compile_time<XprType>::ret) 00045 : int(outer_stride_at_compile_time<XprType>::ret), 00046 OuterStrideAtCompileTime = HasSameStorageOrderAsXprType 00047 ? int(outer_stride_at_compile_time<XprType>::ret) 00048 : int(inner_stride_at_compile_time<XprType>::ret), 00049 00050 // FIXME, this traits is rather specialized for dense object and it needs to be cleaned further 00051 FlagsLvalueBit = is_lvalue<XprType>::value ? LvalueBit : 0, 00052 FlagsRowMajorBit = IsRowMajor ? RowMajorBit : 0, 00053 Flags = (traits<XprType>::Flags & (DirectAccessBit | (InnerPanel?CompressedAccessBit:0))) | FlagsLvalueBit | FlagsRowMajorBit, 00054 // FIXME DirectAccessBit should not be handled by expressions 00055 // 00056 // Alignment is needed by MapBase's assertions 00057 // We can sefely set it to false here. Internal alignment errors will be detected by an eigen_internal_assert in the respective evaluator 00058 Alignment = 0 00059 }; 00060 }; 00061 00062 template<typename XprType, int BlockRows=Dynamic, int BlockCols=Dynamic, bool InnerPanel = false, 00063 bool HasDirectAccess = internal::has_direct_access<XprType>::ret> class BlockImpl_dense; 00064 00065 } // end namespace internal 00066 00067 template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel, typename StorageKind> class BlockImpl; 00068 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 typedef typename internal::remove_all<XprType>::type NestedExpression; 00114 00117 EIGEN_DEVICE_FUNC 00118 inline Block(XprType& xpr, Index i) : Impl(xpr,i) 00119 { 00120 eigen_assert( (i>=0) && ( 00121 ((BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) && i<xpr.rows()) 00122 ||((BlockRows==XprType::RowsAtCompileTime) && (BlockCols==1) && i<xpr.cols()))); 00123 } 00124 00127 EIGEN_DEVICE_FUNC 00128 inline Block(XprType& xpr, Index startRow, Index startCol) 00129 : Impl(xpr, startRow, startCol) 00130 { 00131 EIGEN_STATIC_ASSERT(RowsAtCompileTime!=Dynamic && ColsAtCompileTime!=Dynamic,THIS_METHOD_IS_ONLY_FOR_FIXED_SIZE) 00132 eigen_assert(startRow >= 0 && BlockRows >= 0 && startRow + BlockRows <= xpr.rows() 00133 && startCol >= 0 && BlockCols >= 0 && startCol + BlockCols <= xpr.cols()); 00134 } 00135 00138 EIGEN_DEVICE_FUNC 00139 inline Block(XprType& xpr, 00140 Index startRow, Index startCol, 00141 Index blockRows, Index blockCols) 00142 : Impl(xpr, startRow, startCol, blockRows, blockCols) 00143 { 00144 eigen_assert((RowsAtCompileTime==Dynamic || RowsAtCompileTime==blockRows) 00145 && (ColsAtCompileTime==Dynamic || ColsAtCompileTime==blockCols)); 00146 eigen_assert(startRow >= 0 && blockRows >= 0 && startRow <= xpr.rows() - blockRows 00147 && startCol >= 0 && blockCols >= 0 && startCol <= xpr.cols() - blockCols); 00148 } 00149 }; 00150 00151 // The generic default implementation for dense block simplu forward to the internal::BlockImpl_dense 00152 // that must be specialized for direct and non-direct access... 00153 template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel> 00154 class BlockImpl<XprType, BlockRows, BlockCols, InnerPanel, Dense> 00155 : public internal::BlockImpl_dense<XprType, BlockRows, BlockCols, InnerPanel> 00156 { 00157 typedef internal::BlockImpl_dense<XprType, BlockRows, BlockCols, InnerPanel> Impl; 00158 typedef typename XprType::StorageIndex StorageIndex; 00159 public: 00160 typedef Impl Base; 00161 EIGEN_INHERIT_ASSIGNMENT_OPERATORS(BlockImpl) 00162 EIGEN_DEVICE_FUNC inline BlockImpl(XprType& xpr, Index i) : Impl(xpr,i) {} 00163 EIGEN_DEVICE_FUNC inline BlockImpl(XprType& xpr, Index startRow, Index startCol) : Impl(xpr, startRow, startCol) {} 00164 EIGEN_DEVICE_FUNC 00165 inline BlockImpl(XprType& xpr, Index startRow, Index startCol, Index blockRows, Index blockCols) 00166 : Impl(xpr, startRow, startCol, blockRows, blockCols) {} 00167 }; 00168 00169 namespace internal { 00170 00172 template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel, bool HasDirectAccess> class BlockImpl_dense 00173 : public internal::dense_xpr_base<Block<XprType, BlockRows, BlockCols, InnerPanel> >::type 00174 { 00175 typedef Block<XprType, BlockRows, BlockCols, InnerPanel> BlockType; 00176 typedef typename internal::ref_selector<XprType>::non_const_type XprTypeNested; 00177 public: 00178 00179 typedef typename internal::dense_xpr_base<BlockType>::type Base; 00180 EIGEN_DENSE_PUBLIC_INTERFACE(BlockType) 00181 EIGEN_INHERIT_ASSIGNMENT_OPERATORS(BlockImpl_dense) 00182 00183 // class InnerIterator; // FIXME apparently never used 00184 00187 EIGEN_DEVICE_FUNC 00188 inline BlockImpl_dense(XprType& xpr, Index i) 00189 : m_xpr(xpr), 00190 // It is a row if and only if BlockRows==1 and BlockCols==XprType::ColsAtCompileTime, 00191 // and it is a column if and only if BlockRows==XprType::RowsAtCompileTime and BlockCols==1, 00192 // all other cases are invalid. 00193 // The case a 1x1 matrix seems ambiguous, but the result is the same anyway. 00194 m_startRow( (BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) ? i : 0), 00195 m_startCol( (BlockRows==XprType::RowsAtCompileTime) && (BlockCols==1) ? i : 0), 00196 m_blockRows(BlockRows==1 ? 1 : xpr.rows()), 00197 m_blockCols(BlockCols==1 ? 1 : xpr.cols()) 00198 {} 00199 00202 EIGEN_DEVICE_FUNC 00203 inline BlockImpl_dense(XprType& xpr, Index startRow, Index startCol) 00204 : m_xpr(xpr), m_startRow(startRow), m_startCol(startCol), 00205 m_blockRows(BlockRows), m_blockCols(BlockCols) 00206 {} 00207 00210 EIGEN_DEVICE_FUNC 00211 inline BlockImpl_dense(XprType& xpr, 00212 Index startRow, Index startCol, 00213 Index blockRows, Index blockCols) 00214 : m_xpr(xpr), m_startRow(startRow), m_startCol(startCol), 00215 m_blockRows(blockRows), m_blockCols(blockCols) 00216 {} 00217 00218 EIGEN_DEVICE_FUNC inline Index rows() const { return m_blockRows.value(); } 00219 EIGEN_DEVICE_FUNC inline Index cols() const { return m_blockCols.value(); } 00220 00221 EIGEN_DEVICE_FUNC 00222 inline Scalar& coeffRef(Index rowId, Index colId) 00223 { 00224 EIGEN_STATIC_ASSERT_LVALUE(XprType) 00225 return m_xpr.coeffRef(rowId + m_startRow.value(), colId + m_startCol.value()); 00226 } 00227 00228 EIGEN_DEVICE_FUNC 00229 inline const Scalar& coeffRef(Index rowId, Index colId) const 00230 { 00231 return m_xpr.derived().coeffRef(rowId + m_startRow.value(), colId + m_startCol.value()); 00232 } 00233 00234 EIGEN_DEVICE_FUNC 00235 EIGEN_STRONG_INLINE const CoeffReturnType coeff(Index rowId, Index colId) const 00236 { 00237 return m_xpr.coeff(rowId + m_startRow.value(), colId + m_startCol.value()); 00238 } 00239 00240 EIGEN_DEVICE_FUNC 00241 inline Scalar& coeffRef(Index index) 00242 { 00243 EIGEN_STATIC_ASSERT_LVALUE(XprType) 00244 return m_xpr.coeffRef(m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index), 00245 m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0)); 00246 } 00247 00248 EIGEN_DEVICE_FUNC 00249 inline const Scalar& coeffRef(Index index) const 00250 { 00251 return m_xpr.coeffRef(m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index), 00252 m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0)); 00253 } 00254 00255 EIGEN_DEVICE_FUNC 00256 inline const CoeffReturnType coeff(Index index) const 00257 { 00258 return m_xpr.coeff(m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index), 00259 m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0)); 00260 } 00261 00262 template<int LoadMode> 00263 inline PacketScalar packet(Index rowId, Index colId) const 00264 { 00265 return m_xpr.template packet<Unaligned>(rowId + m_startRow.value(), colId + m_startCol.value()); 00266 } 00267 00268 template<int LoadMode> 00269 inline void writePacket(Index rowId, Index colId, const PacketScalar& val) 00270 { 00271 m_xpr.template writePacket<Unaligned>(rowId + m_startRow.value(), colId + m_startCol.value(), val); 00272 } 00273 00274 template<int LoadMode> 00275 inline PacketScalar packet(Index index) const 00276 { 00277 return m_xpr.template packet<Unaligned> 00278 (m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index), 00279 m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0)); 00280 } 00281 00282 template<int LoadMode> 00283 inline void writePacket(Index index, const PacketScalar& val) 00284 { 00285 m_xpr.template writePacket<Unaligned> 00286 (m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index), 00287 m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0), val); 00288 } 00289 00290 #ifdef EIGEN_PARSED_BY_DOXYGEN 00291 00292 EIGEN_DEVICE_FUNC inline const Scalar* data() const; 00293 EIGEN_DEVICE_FUNC inline Index innerStride() const; 00294 EIGEN_DEVICE_FUNC inline Index outerStride() const; 00295 #endif 00296 00297 EIGEN_DEVICE_FUNC 00298 const typename internal::remove_all<XprTypeNested>::type& nestedExpression() const 00299 { 00300 return m_xpr; 00301 } 00302 00303 EIGEN_DEVICE_FUNC 00304 XprType& nestedExpression() { return m_xpr; } 00305 00306 EIGEN_DEVICE_FUNC 00307 StorageIndex startRow() const 00308 { 00309 return m_startRow.value(); 00310 } 00311 00312 EIGEN_DEVICE_FUNC 00313 StorageIndex startCol() const 00314 { 00315 return m_startCol.value(); 00316 } 00317 00318 protected: 00319 00320 XprTypeNested m_xpr; 00321 const internal::variable_if_dynamic<StorageIndex, (XprType::RowsAtCompileTime == 1 && BlockRows==1) ? 0 : Dynamic> m_startRow; 00322 const internal::variable_if_dynamic<StorageIndex, (XprType::ColsAtCompileTime == 1 && BlockCols==1) ? 0 : Dynamic> m_startCol; 00323 const internal::variable_if_dynamic<StorageIndex, RowsAtCompileTime> m_blockRows; 00324 const internal::variable_if_dynamic<StorageIndex, ColsAtCompileTime> m_blockCols; 00325 }; 00326 00328 template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel> 00329 class BlockImpl_dense<XprType,BlockRows,BlockCols, InnerPanel,true> 00330 : public MapBase<Block<XprType, BlockRows, BlockCols, InnerPanel> > 00331 { 00332 typedef Block<XprType, BlockRows, BlockCols, InnerPanel> BlockType; 00333 typedef typename internal::ref_selector<XprType>::non_const_type XprTypeNested; 00334 enum { 00335 XprTypeIsRowMajor = (int(traits<XprType>::Flags)&RowMajorBit) != 0 00336 }; 00337 public: 00338 00339 typedef MapBase<BlockType> Base; 00340 EIGEN_DENSE_PUBLIC_INTERFACE(BlockType) 00341 EIGEN_INHERIT_ASSIGNMENT_OPERATORS(BlockImpl_dense) 00342 00345 EIGEN_DEVICE_FUNC 00346 inline BlockImpl_dense(XprType& xpr, Index i) 00347 : Base(xpr.data() + i * ( ((BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) && (!XprTypeIsRowMajor)) 00348 || ((BlockRows==XprType::RowsAtCompileTime) && (BlockCols==1) && ( XprTypeIsRowMajor)) ? xpr.innerStride() : xpr.outerStride()), 00349 BlockRows==1 ? 1 : xpr.rows(), 00350 BlockCols==1 ? 1 : xpr.cols()), 00351 m_xpr(xpr), 00352 m_startRow( (BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) ? i : 0), 00353 m_startCol( (BlockRows==XprType::RowsAtCompileTime) && (BlockCols==1) ? i : 0) 00354 { 00355 init(); 00356 } 00357 00360 EIGEN_DEVICE_FUNC 00361 inline BlockImpl_dense(XprType& xpr, Index startRow, Index startCol) 00362 : Base(xpr.data()+xpr.innerStride()*(XprTypeIsRowMajor?startCol:startRow) + xpr.outerStride()*(XprTypeIsRowMajor?startRow:startCol)), 00363 m_xpr(xpr), m_startRow(startRow), m_startCol(startCol) 00364 { 00365 init(); 00366 } 00367 00370 EIGEN_DEVICE_FUNC 00371 inline BlockImpl_dense(XprType& xpr, 00372 Index startRow, Index startCol, 00373 Index blockRows, Index blockCols) 00374 : Base(xpr.data()+xpr.innerStride()*(XprTypeIsRowMajor?startCol:startRow) + xpr.outerStride()*(XprTypeIsRowMajor?startRow:startCol), blockRows, blockCols), 00375 m_xpr(xpr), m_startRow(startRow), m_startCol(startCol) 00376 { 00377 init(); 00378 } 00379 00380 EIGEN_DEVICE_FUNC 00381 const typename internal::remove_all<XprTypeNested>::type& nestedExpression() const 00382 { 00383 return m_xpr; 00384 } 00385 00386 EIGEN_DEVICE_FUNC 00387 XprType& nestedExpression() { return m_xpr; } 00388 00390 EIGEN_DEVICE_FUNC 00391 inline Index innerStride() const 00392 { 00393 return internal::traits<BlockType>::HasSameStorageOrderAsXprType 00394 ? m_xpr.innerStride() 00395 : m_xpr.outerStride(); 00396 } 00397 00399 EIGEN_DEVICE_FUNC 00400 inline Index outerStride() const 00401 { 00402 return m_outerStride; 00403 } 00404 00405 EIGEN_DEVICE_FUNC 00406 StorageIndex startRow() const 00407 { 00408 return m_startRow.value(); 00409 } 00410 00411 EIGEN_DEVICE_FUNC 00412 StorageIndex startCol() const 00413 { 00414 return m_startCol.value(); 00415 } 00416 00417 #ifndef __SUNPRO_CC 00418 // FIXME sunstudio is not friendly with the above friend... 00419 // META-FIXME there is no 'friend' keyword around here. Is this obsolete? 00420 protected: 00421 #endif 00422 00423 #ifndef EIGEN_PARSED_BY_DOXYGEN 00424 00425 EIGEN_DEVICE_FUNC 00426 inline BlockImpl_dense(XprType& xpr, const Scalar* data, Index blockRows, Index blockCols) 00427 : Base(data, blockRows, blockCols), m_xpr(xpr) 00428 { 00429 init(); 00430 } 00431 #endif 00432 00433 protected: 00434 EIGEN_DEVICE_FUNC 00435 void init() 00436 { 00437 m_outerStride = internal::traits<BlockType>::HasSameStorageOrderAsXprType 00438 ? m_xpr.outerStride() 00439 : m_xpr.innerStride(); 00440 } 00441 00442 XprTypeNested m_xpr; 00443 const internal::variable_if_dynamic<StorageIndex, (XprType::RowsAtCompileTime == 1 && BlockRows==1) ? 0 : Dynamic> m_startRow; 00444 const internal::variable_if_dynamic<StorageIndex, (XprType::ColsAtCompileTime == 1 && BlockCols==1) ? 0 : Dynamic> m_startCol; 00445 Index m_outerStride; 00446 }; 00447 00448 } // end namespace internal 00449 00450 } // end namespace Eigen 00451 00452 #endif // EIGEN_BLOCK_H