00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef EIGEN_BLOCK_H
00027 #define EIGEN_BLOCK_H
00028
00065 template<typename MatrixType, int BlockRows, int BlockCols, int _PacketAccess, int _DirectAccessStatus>
00066 struct ei_traits<Block<MatrixType, BlockRows, BlockCols, _PacketAccess, _DirectAccessStatus> >
00067 {
00068 typedef typename ei_traits<MatrixType>::Scalar Scalar;
00069 typedef typename ei_nested<MatrixType>::type MatrixTypeNested;
00070 typedef typename ei_unref<MatrixTypeNested>::type _MatrixTypeNested;
00071 enum{
00072 RowsAtCompileTime = ei_traits<MatrixType>::RowsAtCompileTime == 1 ? 1 : BlockRows,
00073 ColsAtCompileTime = ei_traits<MatrixType>::ColsAtCompileTime == 1 ? 1 : BlockCols,
00074 MaxRowsAtCompileTime = RowsAtCompileTime == 1 ? 1
00075 : (BlockRows==Dynamic ? int(ei_traits<MatrixType>::MaxRowsAtCompileTime) : BlockRows),
00076 MaxColsAtCompileTime = ColsAtCompileTime == 1 ? 1
00077 : (BlockCols==Dynamic ? int(ei_traits<MatrixType>::MaxColsAtCompileTime) : BlockCols),
00078 RowMajor = int(ei_traits<MatrixType>::Flags)&RowMajorBit,
00079 InnerSize = RowMajor ? int(ColsAtCompileTime) : int(RowsAtCompileTime),
00080 InnerMaxSize = RowMajor ? int(MaxColsAtCompileTime) : int(MaxRowsAtCompileTime),
00081 MaskPacketAccessBit = (InnerMaxSize == Dynamic || (InnerSize >= ei_packet_traits<Scalar>::size))
00082 ? PacketAccessBit : 0,
00083 FlagsLinearAccessBit = (RowsAtCompileTime == 1 || ColsAtCompileTime == 1) ? LinearAccessBit : 0,
00084 Flags = (ei_traits<MatrixType>::Flags & (HereditaryBits | MaskPacketAccessBit | DirectAccessBit)) | FlagsLinearAccessBit,
00085 CoeffReadCost = ei_traits<MatrixType>::CoeffReadCost,
00086 PacketAccess = _PacketAccess
00087 };
00088 typedef typename ei_meta_if<int(PacketAccess)==ForceAligned,
00089 Block<MatrixType, BlockRows, BlockCols, _PacketAccess, _DirectAccessStatus>&,
00090 Block<MatrixType, BlockRows, BlockCols, ForceAligned, _DirectAccessStatus> >::ret AlignedDerivedType;
00091 };
00092
00093 template<typename MatrixType, int BlockRows, int BlockCols, int PacketAccess, int _DirectAccessStatus> class Block
00094 : public MatrixBase<Block<MatrixType, BlockRows, BlockCols, PacketAccess, _DirectAccessStatus> >
00095 {
00096 public:
00097
00098 EIGEN_GENERIC_PUBLIC_INTERFACE(Block)
00099
00100 class InnerIterator;
00101
00104 inline Block(const MatrixType& matrix, int i)
00105 : m_matrix(matrix),
00106
00107
00108
00109
00110 m_startRow( (BlockRows==1) && (BlockCols==MatrixType::ColsAtCompileTime) ? i : 0),
00111 m_startCol( (BlockRows==MatrixType::RowsAtCompileTime) && (BlockCols==1) ? i : 0),
00112 m_blockRows(matrix.rows()),
00113 m_blockCols(matrix.cols())
00114 {
00115 ei_assert( (i>=0) && (
00116 ((BlockRows==1) && (BlockCols==MatrixType::ColsAtCompileTime) && i<matrix.rows())
00117 ||((BlockRows==MatrixType::RowsAtCompileTime) && (BlockCols==1) && i<matrix.cols())));
00118 }
00119
00122 inline Block(const MatrixType& matrix, int startRow, int startCol)
00123 : m_matrix(matrix), m_startRow(startRow), m_startCol(startCol),
00124 m_blockRows(matrix.rows()), m_blockCols(matrix.cols())
00125 {
00126 EIGEN_STATIC_ASSERT(RowsAtCompileTime!=Dynamic && ColsAtCompileTime!=Dynamic,THIS_METHOD_IS_ONLY_FOR_FIXED_SIZE)
00127 ei_assert(startRow >= 0 && BlockRows >= 1 && startRow + BlockRows <= matrix.rows()
00128 && startCol >= 0 && BlockCols >= 1 && startCol + BlockCols <= matrix.cols());
00129 }
00130
00133 inline Block(const MatrixType& matrix,
00134 int startRow, int startCol,
00135 int blockRows, int blockCols)
00136 : m_matrix(matrix), m_startRow(startRow), m_startCol(startCol),
00137 m_blockRows(blockRows), m_blockCols(blockCols)
00138 {
00139 ei_assert((RowsAtCompileTime==Dynamic || RowsAtCompileTime==blockRows)
00140 && (ColsAtCompileTime==Dynamic || ColsAtCompileTime==blockCols));
00141 ei_assert(startRow >= 0 && blockRows >= 1 && startRow + blockRows <= matrix.rows()
00142 && startCol >= 0 && blockCols >= 1 && startCol + blockCols <= matrix.cols());
00143 }
00144
00145 EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Block)
00146
00147 inline int rows() const { return m_blockRows.value(); }
00148 inline int cols() const { return m_blockCols.value(); }
00149
00150 inline Scalar& coeffRef(int row, int col)
00151 {
00152 return m_matrix.const_cast_derived()
00153 .coeffRef(row + m_startRow.value(), col + m_startCol.value());
00154 }
00155
00156 inline const Scalar coeff(int row, int col) const
00157 {
00158 return m_matrix.coeff(row + m_startRow.value(), col + m_startCol.value());
00159 }
00160
00161 inline Scalar& coeffRef(int index)
00162 {
00163 return m_matrix.const_cast_derived()
00164 .coeffRef(m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index),
00165 m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0));
00166 }
00167
00168 inline const Scalar coeff(int index) const
00169 {
00170 return m_matrix
00171 .coeff(m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index),
00172 m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0));
00173 }
00174
00175 template<int LoadMode>
00176 inline PacketScalar packet(int row, int col) const
00177 {
00178 return m_matrix.template packet<Unaligned>
00179 (row + m_startRow.value(), col + m_startCol.value());
00180 }
00181
00182 template<int LoadMode>
00183 inline void writePacket(int row, int col, const PacketScalar& x)
00184 {
00185 m_matrix.const_cast_derived().template writePacket<Unaligned>
00186 (row + m_startRow.value(), col + m_startCol.value(), x);
00187 }
00188
00189 template<int LoadMode>
00190 inline PacketScalar packet(int index) const
00191 {
00192 return m_matrix.template packet<Unaligned>
00193 (m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index),
00194 m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0));
00195 }
00196
00197 template<int LoadMode>
00198 inline void writePacket(int index, const PacketScalar& x)
00199 {
00200 m_matrix.const_cast_derived().template writePacket<Unaligned>
00201 (m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index),
00202 m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0), x);
00203 }
00204
00205 protected:
00206
00207 const typename MatrixType::Nested m_matrix;
00208 const ei_int_if_dynamic<MatrixType::RowsAtCompileTime == 1 ? 0 : Dynamic> m_startRow;
00209 const ei_int_if_dynamic<MatrixType::ColsAtCompileTime == 1 ? 0 : Dynamic> m_startCol;
00210 const ei_int_if_dynamic<RowsAtCompileTime> m_blockRows;
00211 const ei_int_if_dynamic<ColsAtCompileTime> m_blockCols;
00212 };
00213
00215 template<typename MatrixType, int BlockRows, int BlockCols, int PacketAccess>
00216 class Block<MatrixType,BlockRows,BlockCols,PacketAccess,HasDirectAccess>
00217 : public MapBase<Block<MatrixType, BlockRows, BlockCols,PacketAccess,HasDirectAccess> >
00218 {
00219 public:
00220
00221 _EIGEN_GENERIC_PUBLIC_INTERFACE(Block, MapBase<Block>)
00222
00223 class InnerIterator;
00224 typedef typename ei_traits<Block>::AlignedDerivedType AlignedDerivedType;
00225 friend class Block<MatrixType,BlockRows,BlockCols,PacketAccess==int(AsRequested)?ForceAligned:AsRequested,HasDirectAccess>;
00226
00227 EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Block)
00228
00229 AlignedDerivedType _convertToForceAligned()
00230 {
00231 return Block<MatrixType,BlockRows,BlockCols,ForceAligned,HasDirectAccess>
00232 (m_matrix, Base::m_data, Base::m_rows.value(), Base::m_cols.value());
00233 }
00234
00237 inline Block(const MatrixType& matrix, int i)
00238 : Base(&matrix.const_cast_derived().coeffRef(
00239 (BlockRows==1) && (BlockCols==MatrixType::ColsAtCompileTime) ? i : 0,
00240 (BlockRows==MatrixType::RowsAtCompileTime) && (BlockCols==1) ? i : 0),
00241 BlockRows==1 ? 1 : matrix.rows(),
00242 BlockCols==1 ? 1 : matrix.cols()),
00243 m_matrix(matrix)
00244 {
00245 ei_assert( (i>=0) && (
00246 ((BlockRows==1) && (BlockCols==MatrixType::ColsAtCompileTime) && i<matrix.rows())
00247 ||((BlockRows==MatrixType::RowsAtCompileTime) && (BlockCols==1) && i<matrix.cols())));
00248 }
00249
00252 inline Block(const MatrixType& matrix, int startRow, int startCol)
00253 : Base(&matrix.const_cast_derived().coeffRef(startRow,startCol)), m_matrix(matrix)
00254 {
00255 ei_assert(startRow >= 0 && BlockRows >= 1 && startRow + BlockRows <= matrix.rows()
00256 && startCol >= 0 && BlockCols >= 1 && startCol + BlockCols <= matrix.cols());
00257 }
00258
00261 inline Block(const MatrixType& matrix,
00262 int startRow, int startCol,
00263 int blockRows, int blockCols)
00264 : Base(&matrix.const_cast_derived().coeffRef(startRow,startCol), blockRows, blockCols),
00265 m_matrix(matrix)
00266 {
00267 ei_assert((RowsAtCompileTime==Dynamic || RowsAtCompileTime==blockRows)
00268 && (ColsAtCompileTime==Dynamic || ColsAtCompileTime==blockCols));
00269 ei_assert(startRow >= 0 && blockRows >= 1 && startRow + blockRows <= matrix.rows()
00270 && startCol >= 0 && blockCols >= 1 && startCol + blockCols <= matrix.cols());
00271 }
00272
00273 inline int stride(void) const { return m_matrix.stride(); }
00274
00275 protected:
00276
00278 inline Block(const MatrixType& matrix, const Scalar* data, int blockRows, int blockCols)
00279 : Base(data, blockRows, blockCols), m_matrix(matrix)
00280 {}
00281
00282 const typename MatrixType::Nested m_matrix;
00283 };
00284
00303 template<typename Derived>
00304 inline typename BlockReturnType<Derived>::Type MatrixBase<Derived>
00305 ::block(int startRow, int startCol, int blockRows, int blockCols)
00306 {
00307 return typename BlockReturnType<Derived>::Type(derived(), startRow, startCol, blockRows, blockCols);
00308 }
00309
00311 template<typename Derived>
00312 inline const typename BlockReturnType<Derived>::Type MatrixBase<Derived>
00313 ::block(int startRow, int startCol, int blockRows, int blockCols) const
00314 {
00315 return typename BlockReturnType<Derived>::Type(derived(), startRow, startCol, blockRows, blockCols);
00316 }
00317
00336 template<typename Derived>
00337 inline typename BlockReturnType<Derived>::SubVectorType MatrixBase<Derived>
00338 ::segment(int start, int size)
00339 {
00340 EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
00341 return typename BlockReturnType<Derived>::SubVectorType(derived(), RowsAtCompileTime == 1 ? 0 : start,
00342 ColsAtCompileTime == 1 ? 0 : start,
00343 RowsAtCompileTime == 1 ? 1 : size,
00344 ColsAtCompileTime == 1 ? 1 : size);
00345 }
00346
00348 template<typename Derived>
00349 inline const typename BlockReturnType<Derived>::SubVectorType
00350 MatrixBase<Derived>::segment(int start, int size) const
00351 {
00352 EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
00353 return typename BlockReturnType<Derived>::SubVectorType(derived(), RowsAtCompileTime == 1 ? 0 : start,
00354 ColsAtCompileTime == 1 ? 0 : start,
00355 RowsAtCompileTime == 1 ? 1 : size,
00356 ColsAtCompileTime == 1 ? 1 : size);
00357 }
00358
00376 template<typename Derived>
00377 inline typename BlockReturnType<Derived,Dynamic>::SubVectorType
00378 MatrixBase<Derived>::start(int size)
00379 {
00380 EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
00381 return Block<Derived,
00382 RowsAtCompileTime == 1 ? 1 : Dynamic,
00383 ColsAtCompileTime == 1 ? 1 : Dynamic>
00384 (derived(), 0, 0,
00385 RowsAtCompileTime == 1 ? 1 : size,
00386 ColsAtCompileTime == 1 ? 1 : size);
00387 }
00388
00390 template<typename Derived>
00391 inline const typename BlockReturnType<Derived,Dynamic>::SubVectorType
00392 MatrixBase<Derived>::start(int size) const
00393 {
00394 EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
00395 return Block<Derived,
00396 RowsAtCompileTime == 1 ? 1 : Dynamic,
00397 ColsAtCompileTime == 1 ? 1 : Dynamic>
00398 (derived(), 0, 0,
00399 RowsAtCompileTime == 1 ? 1 : size,
00400 ColsAtCompileTime == 1 ? 1 : size);
00401 }
00402
00420 template<typename Derived>
00421 inline typename BlockReturnType<Derived,Dynamic>::SubVectorType
00422 MatrixBase<Derived>::end(int size)
00423 {
00424 EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
00425 return Block<Derived,
00426 RowsAtCompileTime == 1 ? 1 : Dynamic,
00427 ColsAtCompileTime == 1 ? 1 : Dynamic>
00428 (derived(),
00429 RowsAtCompileTime == 1 ? 0 : rows() - size,
00430 ColsAtCompileTime == 1 ? 0 : cols() - size,
00431 RowsAtCompileTime == 1 ? 1 : size,
00432 ColsAtCompileTime == 1 ? 1 : size);
00433 }
00434
00436 template<typename Derived>
00437 inline const typename BlockReturnType<Derived,Dynamic>::SubVectorType
00438 MatrixBase<Derived>::end(int size) const
00439 {
00440 EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
00441 return Block<Derived,
00442 RowsAtCompileTime == 1 ? 1 : Dynamic,
00443 ColsAtCompileTime == 1 ? 1 : Dynamic>
00444 (derived(),
00445 RowsAtCompileTime == 1 ? 0 : rows() - size,
00446 ColsAtCompileTime == 1 ? 0 : cols() - size,
00447 RowsAtCompileTime == 1 ? 1 : size,
00448 ColsAtCompileTime == 1 ? 1 : size);
00449 }
00450
00464 template<typename Derived>
00465 template<int Size>
00466 inline typename BlockReturnType<Derived,Size>::SubVectorType
00467 MatrixBase<Derived>::segment(int start)
00468 {
00469 EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
00470 return Block<Derived, (RowsAtCompileTime == 1 ? 1 : Size),
00471 (ColsAtCompileTime == 1 ? 1 : Size)>
00472 (derived(), RowsAtCompileTime == 1 ? 0 : start,
00473 ColsAtCompileTime == 1 ? 0 : start);
00474 }
00475
00477 template<typename Derived>
00478 template<int Size>
00479 inline const typename BlockReturnType<Derived,Size>::SubVectorType
00480 MatrixBase<Derived>::segment(int start) const
00481 {
00482 EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
00483 return Block<Derived, (RowsAtCompileTime == 1 ? 1 : Size),
00484 (ColsAtCompileTime == 1 ? 1 : Size)>
00485 (derived(), RowsAtCompileTime == 1 ? 0 : start,
00486 ColsAtCompileTime == 1 ? 0 : start);
00487 }
00488
00502 template<typename Derived>
00503 template<int Size>
00504 inline typename BlockReturnType<Derived,Size>::SubVectorType
00505 MatrixBase<Derived>::start()
00506 {
00507 EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
00508 return Block<Derived, (RowsAtCompileTime == 1 ? 1 : Size),
00509 (ColsAtCompileTime == 1 ? 1 : Size)>(derived(), 0, 0);
00510 }
00511
00513 template<typename Derived>
00514 template<int Size>
00515 inline const typename BlockReturnType<Derived,Size>::SubVectorType
00516 MatrixBase<Derived>::start() const
00517 {
00518 EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
00519 return Block<Derived, (RowsAtCompileTime == 1 ? 1 : Size),
00520 (ColsAtCompileTime == 1 ? 1 : Size)>(derived(), 0, 0);
00521 }
00522
00534 template<typename Derived>
00535 template<int Size>
00536 inline typename BlockReturnType<Derived,Size>::SubVectorType
00537 MatrixBase<Derived>::end()
00538 {
00539 EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
00540 return Block<Derived, RowsAtCompileTime == 1 ? 1 : Size,
00541 ColsAtCompileTime == 1 ? 1 : Size>
00542 (derived(),
00543 RowsAtCompileTime == 1 ? 0 : rows() - Size,
00544 ColsAtCompileTime == 1 ? 0 : cols() - Size);
00545 }
00546
00548 template<typename Derived>
00549 template<int Size>
00550 inline const typename BlockReturnType<Derived,Size>::SubVectorType
00551 MatrixBase<Derived>::end() const
00552 {
00553 EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
00554 return Block<Derived, RowsAtCompileTime == 1 ? 1 : Size,
00555 ColsAtCompileTime == 1 ? 1 : Size>
00556 (derived(),
00557 RowsAtCompileTime == 1 ? 0 : rows() - Size,
00558 ColsAtCompileTime == 1 ? 0 : cols() - Size);
00559 }
00560
00579 template<typename Derived>
00580 inline typename BlockReturnType<Derived>::Type MatrixBase<Derived>
00581 ::corner(CornerType type, int cRows, int cCols)
00582 {
00583 switch(type)
00584 {
00585 default:
00586 ei_assert(false && "Bad corner type.");
00587 case TopLeft:
00588 return typename BlockReturnType<Derived>::Type(derived(), 0, 0, cRows, cCols);
00589 case TopRight:
00590 return typename BlockReturnType<Derived>::Type(derived(), 0, cols() - cCols, cRows, cCols);
00591 case BottomLeft:
00592 return typename BlockReturnType<Derived>::Type(derived(), rows() - cRows, 0, cRows, cCols);
00593 case BottomRight:
00594 return typename BlockReturnType<Derived>::Type(derived(), rows() - cRows, cols() - cCols, cRows, cCols);
00595 }
00596 }
00597
00599 template<typename Derived>
00600 inline const typename BlockReturnType<Derived>::Type
00601 MatrixBase<Derived>::corner(CornerType type, int cRows, int cCols) const
00602 {
00603 switch(type)
00604 {
00605 default:
00606 ei_assert(false && "Bad corner type.");
00607 case TopLeft:
00608 return typename BlockReturnType<Derived>::Type(derived(), 0, 0, cRows, cCols);
00609 case TopRight:
00610 return typename BlockReturnType<Derived>::Type(derived(), 0, cols() - cCols, cRows, cCols);
00611 case BottomLeft:
00612 return typename BlockReturnType<Derived>::Type(derived(), rows() - cRows, 0, cRows, cCols);
00613 case BottomRight:
00614 return typename BlockReturnType<Derived>::Type(derived(), rows() - cRows, cols() - cCols, cRows, cCols);
00615 }
00616 }
00617
00630 template<typename Derived>
00631 template<int CRows, int CCols>
00632 inline typename BlockReturnType<Derived, CRows, CCols>::Type
00633 MatrixBase<Derived>::corner(CornerType type)
00634 {
00635 switch(type)
00636 {
00637 default:
00638 ei_assert(false && "Bad corner type.");
00639 case TopLeft:
00640 return Block<Derived, CRows, CCols>(derived(), 0, 0);
00641 case TopRight:
00642 return Block<Derived, CRows, CCols>(derived(), 0, cols() - CCols);
00643 case BottomLeft:
00644 return Block<Derived, CRows, CCols>(derived(), rows() - CRows, 0);
00645 case BottomRight:
00646 return Block<Derived, CRows, CCols>(derived(), rows() - CRows, cols() - CCols);
00647 }
00648 }
00649
00651 template<typename Derived>
00652 template<int CRows, int CCols>
00653 inline const typename BlockReturnType<Derived, CRows, CCols>::Type
00654 MatrixBase<Derived>::corner(CornerType type) const
00655 {
00656 switch(type)
00657 {
00658 default:
00659 ei_assert(false && "Bad corner type.");
00660 case TopLeft:
00661 return Block<Derived, CRows, CCols>(derived(), 0, 0);
00662 case TopRight:
00663 return Block<Derived, CRows, CCols>(derived(), 0, cols() - CCols);
00664 case BottomLeft:
00665 return Block<Derived, CRows, CCols>(derived(), rows() - CRows, 0);
00666 case BottomRight:
00667 return Block<Derived, CRows, CCols>(derived(), rows() - CRows, cols() - CCols);
00668 }
00669 }
00670
00689 template<typename Derived>
00690 template<int BlockRows, int BlockCols>
00691 inline typename BlockReturnType<Derived, BlockRows, BlockCols>::Type
00692 MatrixBase<Derived>::block(int startRow, int startCol)
00693 {
00694 return Block<Derived, BlockRows, BlockCols>(derived(), startRow, startCol);
00695 }
00696
00698 template<typename Derived>
00699 template<int BlockRows, int BlockCols>
00700 inline const typename BlockReturnType<Derived, BlockRows, BlockCols>::Type
00701 MatrixBase<Derived>::block(int startRow, int startCol) const
00702 {
00703 return Block<Derived, BlockRows, BlockCols>(derived(), startRow, startCol);
00704 }
00705
00714 template<typename Derived>
00715 inline typename MatrixBase<Derived>::ColXpr
00716 MatrixBase<Derived>::col(int i)
00717 {
00718 return ColXpr(derived(), i);
00719 }
00720
00722 template<typename Derived>
00723 inline const typename MatrixBase<Derived>::ColXpr
00724 MatrixBase<Derived>::col(int i) const
00725 {
00726 return ColXpr(derived(), i);
00727 }
00728
00737 template<typename Derived>
00738 inline typename MatrixBase<Derived>::RowXpr
00739 MatrixBase<Derived>::row(int i)
00740 {
00741 return RowXpr(derived(), i);
00742 }
00743
00745 template<typename Derived>
00746 inline const typename MatrixBase<Derived>::RowXpr
00747 MatrixBase<Derived>::row(int i) const
00748 {
00749 return RowXpr(derived(), i);
00750 }
00751
00752 #endif // EIGEN_BLOCK_H