00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #ifndef EIGEN_BLOCK_H
00012 #define EIGEN_BLOCK_H
00013
00014 namespace Eigen {
00015
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 IsRowMajor = (MaxRowsAtCompileTime==1&&MaxColsAtCompileTime!=1) ? 1
00070 : (MaxColsAtCompileTime==1&&MaxRowsAtCompileTime!=1) ? 0
00071 : XprTypeIsRowMajor,
00072 HasSameStorageOrderAsXprType = (IsRowMajor == XprTypeIsRowMajor),
00073 InnerSize = IsRowMajor ? int(ColsAtCompileTime) : int(RowsAtCompileTime),
00074 InnerStrideAtCompileTime = HasSameStorageOrderAsXprType
00075 ? int(inner_stride_at_compile_time<XprType>::ret)
00076 : int(outer_stride_at_compile_time<XprType>::ret),
00077 OuterStrideAtCompileTime = HasSameStorageOrderAsXprType
00078 ? int(outer_stride_at_compile_time<XprType>::ret)
00079 : int(inner_stride_at_compile_time<XprType>::ret),
00080 MaskPacketAccessBit = (InnerSize == Dynamic || (InnerSize % packet_traits<Scalar>::size) == 0)
00081 && (InnerStrideAtCompileTime == 1)
00082 ? PacketAccessBit : 0,
00083 MaskAlignedBit = (InnerPanel && (OuterStrideAtCompileTime!=Dynamic) && (((OuterStrideAtCompileTime * int(sizeof(Scalar))) % 16) == 0)) ? AlignedBit : 0,
00084 FlagsLinearAccessBit = (RowsAtCompileTime == 1 || ColsAtCompileTime == 1) ? LinearAccessBit : 0,
00085 FlagsLvalueBit = is_lvalue<XprType>::value ? LvalueBit : 0,
00086 FlagsRowMajorBit = IsRowMajor ? RowMajorBit : 0,
00087 Flags0 = traits<XprType>::Flags & ( (HereditaryBits & ~RowMajorBit) |
00088 DirectAccessBit |
00089 MaskPacketAccessBit |
00090 MaskAlignedBit),
00091 Flags = Flags0 | FlagsLinearAccessBit | FlagsLvalueBit | FlagsRowMajorBit
00092 };
00093 };
00094
00095 template<typename XprType, int BlockRows=Dynamic, int BlockCols=Dynamic, bool InnerPanel = false,
00096 bool HasDirectAccess = internal::has_direct_access<XprType>::ret> class BlockImpl_dense;
00097
00098 }
00099
00100 template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel, typename StorageKind> class BlockImpl;
00101
00102 template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel> class Block
00103 : public BlockImpl<XprType, BlockRows, BlockCols, InnerPanel, typename internal::traits<XprType>::StorageKind>
00104 {
00105 typedef BlockImpl<XprType, BlockRows, BlockCols, InnerPanel, typename internal::traits<XprType>::StorageKind> Impl;
00106 public:
00107
00108 typedef Impl Base;
00109 EIGEN_GENERIC_PUBLIC_INTERFACE(Block)
00110 EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Block)
00111
00114 inline Block(XprType& xpr, Index i) : Impl(xpr,i)
00115 {
00116 eigen_assert( (i>=0) && (
00117 ((BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) && i<xpr.rows())
00118 ||((BlockRows==XprType::RowsAtCompileTime) && (BlockCols==1) && i<xpr.cols())));
00119 }
00120
00123 inline Block(XprType& xpr, Index a_startRow, Index a_startCol)
00124 : Impl(xpr, a_startRow, a_startCol)
00125 {
00126 EIGEN_STATIC_ASSERT(RowsAtCompileTime!=Dynamic && ColsAtCompileTime!=Dynamic,THIS_METHOD_IS_ONLY_FOR_FIXED_SIZE)
00127 eigen_assert(a_startRow >= 0 && BlockRows >= 1 && a_startRow + BlockRows <= xpr.rows()
00128 && a_startCol >= 0 && BlockCols >= 1 && a_startCol + BlockCols <= xpr.cols());
00129 }
00130
00133 inline Block(XprType& xpr,
00134 Index a_startRow, Index a_startCol,
00135 Index blockRows, Index blockCols)
00136 : Impl(xpr, a_startRow, a_startCol, blockRows, blockCols)
00137 {
00138 eigen_assert((RowsAtCompileTime==Dynamic || RowsAtCompileTime==blockRows)
00139 && (ColsAtCompileTime==Dynamic || ColsAtCompileTime==blockCols));
00140 eigen_assert(a_startRow >= 0 && blockRows >= 0 && a_startRow <= xpr.rows() - blockRows
00141 && a_startCol >= 0 && blockCols >= 0 && a_startCol <= xpr.cols() - blockCols);
00142 }
00143 };
00144
00145
00146
00147 template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel>
00148 class BlockImpl<XprType, BlockRows, BlockCols, InnerPanel, Dense>
00149 : public internal::BlockImpl_dense<XprType, BlockRows, BlockCols, InnerPanel>
00150 {
00151 typedef internal::BlockImpl_dense<XprType, BlockRows, BlockCols, InnerPanel> Impl;
00152 typedef typename XprType::Index Index;
00153 public:
00154 typedef Impl Base;
00155 EIGEN_INHERIT_ASSIGNMENT_OPERATORS(BlockImpl)
00156 inline BlockImpl(XprType& xpr, Index i) : Impl(xpr,i) {}
00157 inline BlockImpl(XprType& xpr, Index a_startRow, Index a_startCol) : Impl(xpr, a_startRow, a_startCol) {}
00158 inline BlockImpl(XprType& xpr, Index a_startRow, Index a_startCol, Index blockRows, Index blockCols)
00159 : Impl(xpr, a_startRow, a_startCol, blockRows, blockCols) {}
00160 };
00161
00162 namespace internal {
00163
00165 template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel, bool HasDirectAccess> class BlockImpl_dense
00166 : public internal::dense_xpr_base<Block<XprType, BlockRows, BlockCols, InnerPanel> >::type
00167 {
00168 typedef Block<XprType, BlockRows, BlockCols, InnerPanel> BlockType;
00169 public:
00170
00171 typedef typename internal::dense_xpr_base<BlockType>::type Base;
00172 EIGEN_DENSE_PUBLIC_INTERFACE(BlockType)
00173 EIGEN_INHERIT_ASSIGNMENT_OPERATORS(BlockImpl_dense)
00174
00175 class InnerIterator;
00176
00179 inline BlockImpl_dense(XprType& xpr, Index i)
00180 : m_xpr(xpr),
00181
00182
00183
00184
00185 m_startRow( (BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) ? i : 0),
00186 m_startCol( (BlockRows==XprType::RowsAtCompileTime) && (BlockCols==1) ? i : 0),
00187 m_blockRows(BlockRows==1 ? 1 : xpr.rows()),
00188 m_blockCols(BlockCols==1 ? 1 : xpr.cols())
00189 {}
00190
00193 inline BlockImpl_dense(XprType& xpr, Index a_startRow, Index a_startCol)
00194 : m_xpr(xpr), m_startRow(a_startRow), m_startCol(a_startCol),
00195 m_blockRows(BlockRows), m_blockCols(BlockCols)
00196 {}
00197
00200 inline BlockImpl_dense(XprType& xpr,
00201 Index a_startRow, Index a_startCol,
00202 Index blockRows, Index blockCols)
00203 : m_xpr(xpr), m_startRow(a_startRow), m_startCol(a_startCol),
00204 m_blockRows(blockRows), m_blockCols(blockCols)
00205 {}
00206
00207 inline Index rows() const { return m_blockRows.value(); }
00208 inline Index cols() const { return m_blockCols.value(); }
00209
00210 inline Scalar& coeffRef(Index rowId, Index colId)
00211 {
00212 EIGEN_STATIC_ASSERT_LVALUE(XprType)
00213 return m_xpr.const_cast_derived()
00214 .coeffRef(rowId + m_startRow.value(), colId + m_startCol.value());
00215 }
00216
00217 inline const Scalar& coeffRef(Index rowId, Index colId) const
00218 {
00219 return m_xpr.derived()
00220 .coeffRef(rowId + m_startRow.value(), colId + m_startCol.value());
00221 }
00222
00223 EIGEN_STRONG_INLINE const CoeffReturnType coeff(Index rowId, Index colId) const
00224 {
00225 return m_xpr.coeff(rowId + m_startRow.value(), colId + m_startCol.value());
00226 }
00227
00228 inline Scalar& coeffRef(Index index)
00229 {
00230 EIGEN_STATIC_ASSERT_LVALUE(XprType)
00231 return m_xpr.const_cast_derived()
00232 .coeffRef(m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index),
00233 m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0));
00234 }
00235
00236 inline const Scalar& coeffRef(Index index) const
00237 {
00238 return m_xpr.const_cast_derived()
00239 .coeffRef(m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index),
00240 m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0));
00241 }
00242
00243 inline const CoeffReturnType coeff(Index index) const
00244 {
00245 return m_xpr
00246 .coeff(m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index),
00247 m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0));
00248 }
00249
00250 template<int LoadMode>
00251 inline PacketScalar packet(Index rowId, Index colId) const
00252 {
00253 return m_xpr.template packet<Unaligned>
00254 (rowId + m_startRow.value(), colId + m_startCol.value());
00255 }
00256
00257 template<int LoadMode>
00258 inline void writePacket(Index rowId, Index colId, const PacketScalar& val)
00259 {
00260 m_xpr.const_cast_derived().template writePacket<Unaligned>
00261 (rowId + m_startRow.value(), colId + m_startCol.value(), val);
00262 }
00263
00264 template<int LoadMode>
00265 inline PacketScalar packet(Index index) const
00266 {
00267 return m_xpr.template packet<Unaligned>
00268 (m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index),
00269 m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0));
00270 }
00271
00272 template<int LoadMode>
00273 inline void writePacket(Index index, const PacketScalar& val)
00274 {
00275 m_xpr.const_cast_derived().template writePacket<Unaligned>
00276 (m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index),
00277 m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0), val);
00278 }
00279
00280 #ifdef EIGEN_PARSED_BY_DOXYGEN
00281
00282 inline const Scalar* data() const;
00283 inline Index innerStride() const;
00284 inline Index outerStride() const;
00285 #endif
00286
00287 const typename internal::remove_all<typename XprType::Nested>::type& nestedExpression() const
00288 {
00289 return m_xpr;
00290 }
00291
00292 Index startRow() const
00293 {
00294 return m_startRow.value();
00295 }
00296
00297 Index startCol() const
00298 {
00299 return m_startCol.value();
00300 }
00301
00302 protected:
00303
00304 const typename XprType::Nested m_xpr;
00305 const internal::variable_if_dynamic<Index, XprType::RowsAtCompileTime == 1 ? 0 : Dynamic> m_startRow;
00306 const internal::variable_if_dynamic<Index, XprType::ColsAtCompileTime == 1 ? 0 : Dynamic> m_startCol;
00307 const internal::variable_if_dynamic<Index, RowsAtCompileTime> m_blockRows;
00308 const internal::variable_if_dynamic<Index, ColsAtCompileTime> m_blockCols;
00309 };
00310
00312 template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel>
00313 class BlockImpl_dense<XprType,BlockRows,BlockCols, InnerPanel,true>
00314 : public MapBase<Block<XprType, BlockRows, BlockCols, InnerPanel> >
00315 {
00316 typedef Block<XprType, BlockRows, BlockCols, InnerPanel> BlockType;
00317 public:
00318
00319 typedef MapBase<BlockType> Base;
00320 EIGEN_DENSE_PUBLIC_INTERFACE(BlockType)
00321 EIGEN_INHERIT_ASSIGNMENT_OPERATORS(BlockImpl_dense)
00322
00325 inline BlockImpl_dense(XprType& xpr, Index i)
00326 : Base(internal::const_cast_ptr(&xpr.coeffRef(
00327 (BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) ? i : 0,
00328 (BlockRows==XprType::RowsAtCompileTime) && (BlockCols==1) ? i : 0)),
00329 BlockRows==1 ? 1 : xpr.rows(),
00330 BlockCols==1 ? 1 : xpr.cols()),
00331 m_xpr(xpr)
00332 {
00333 init();
00334 }
00335
00338 inline BlockImpl_dense(XprType& xpr, Index startRow, Index startCol)
00339 : Base(internal::const_cast_ptr(&xpr.coeffRef(startRow,startCol))), m_xpr(xpr)
00340 {
00341 init();
00342 }
00343
00346 inline BlockImpl_dense(XprType& xpr,
00347 Index startRow, Index startCol,
00348 Index blockRows, Index blockCols)
00349 : Base(internal::const_cast_ptr(&xpr.coeffRef(startRow,startCol)), blockRows, blockCols),
00350 m_xpr(xpr)
00351 {
00352 init();
00353 }
00354
00355 const typename internal::remove_all<typename XprType::Nested>::type& nestedExpression() const
00356 {
00357 return m_xpr;
00358 }
00359
00361 inline Index innerStride() const
00362 {
00363 return internal::traits<BlockType>::HasSameStorageOrderAsXprType
00364 ? m_xpr.innerStride()
00365 : m_xpr.outerStride();
00366 }
00367
00369 inline Index outerStride() const
00370 {
00371 return m_outerStride;
00372 }
00373
00374 #ifndef __SUNPRO_CC
00375
00376
00377 protected:
00378 #endif
00379
00380 #ifndef EIGEN_PARSED_BY_DOXYGEN
00381
00382 inline BlockImpl_dense(XprType& xpr, const Scalar* data, Index blockRows, Index blockCols)
00383 : Base(data, blockRows, blockCols), m_xpr(xpr)
00384 {
00385 init();
00386 }
00387 #endif
00388
00389 protected:
00390 void init()
00391 {
00392 m_outerStride = internal::traits<BlockType>::HasSameStorageOrderAsXprType
00393 ? m_xpr.outerStride()
00394 : m_xpr.innerStride();
00395 }
00396
00397 typename XprType::Nested m_xpr;
00398 Index m_outerStride;
00399 };
00400
00401 }
00402
00403 }
00404
00405 #endif // EIGEN_BLOCK_H