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
00062 namespace internal {
00063 template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel, bool HasDirectAccess>
00064 struct traits<Block<XprType, BlockRows, BlockCols, InnerPanel, HasDirectAccess> > : traits<XprType>
00065 {
00066 typedef typename traits<XprType>::Scalar Scalar;
00067 typedef typename traits<XprType>::StorageKind StorageKind;
00068 typedef typename traits<XprType>::XprKind XprKind;
00069 typedef typename nested<XprType>::type XprTypeNested;
00070 typedef typename remove_reference<XprTypeNested>::type _XprTypeNested;
00071 enum{
00072 MatrixRows = traits<XprType>::RowsAtCompileTime,
00073 MatrixCols = traits<XprType>::ColsAtCompileTime,
00074 RowsAtCompileTime = MatrixRows == 0 ? 0 : BlockRows,
00075 ColsAtCompileTime = MatrixCols == 0 ? 0 : BlockCols,
00076 MaxRowsAtCompileTime = BlockRows==0 ? 0
00077 : RowsAtCompileTime != Dynamic ? int(RowsAtCompileTime)
00078 : int(traits<XprType>::MaxRowsAtCompileTime),
00079 MaxColsAtCompileTime = BlockCols==0 ? 0
00080 : ColsAtCompileTime != Dynamic ? int(ColsAtCompileTime)
00081 : int(traits<XprType>::MaxColsAtCompileTime),
00082 XprTypeIsRowMajor = (int(traits<XprType>::Flags)&RowMajorBit) != 0,
00083 IsRowMajor = (MaxRowsAtCompileTime==1&&MaxColsAtCompileTime!=1) ? 1
00084 : (MaxColsAtCompileTime==1&&MaxRowsAtCompileTime!=1) ? 0
00085 : XprTypeIsRowMajor,
00086 HasSameStorageOrderAsXprType = (IsRowMajor == XprTypeIsRowMajor),
00087 InnerSize = IsRowMajor ? int(ColsAtCompileTime) : int(RowsAtCompileTime),
00088 InnerStrideAtCompileTime = HasSameStorageOrderAsXprType
00089 ? int(inner_stride_at_compile_time<XprType>::ret)
00090 : int(outer_stride_at_compile_time<XprType>::ret),
00091 OuterStrideAtCompileTime = HasSameStorageOrderAsXprType
00092 ? int(outer_stride_at_compile_time<XprType>::ret)
00093 : int(inner_stride_at_compile_time<XprType>::ret),
00094 MaskPacketAccessBit = (InnerSize == Dynamic || (InnerSize % packet_traits<Scalar>::size) == 0)
00095 && (InnerStrideAtCompileTime == 1)
00096 ? PacketAccessBit : 0,
00097 MaskAlignedBit = (InnerPanel && (OuterStrideAtCompileTime!=Dynamic) && ((OuterStrideAtCompileTime % packet_traits<Scalar>::size) == 0)) ? AlignedBit : 0,
00098 FlagsLinearAccessBit = (RowsAtCompileTime == 1 || ColsAtCompileTime == 1) ? LinearAccessBit : 0,
00099 FlagsLvalueBit = is_lvalue<XprType>::value ? LvalueBit : 0,
00100 FlagsRowMajorBit = IsRowMajor ? RowMajorBit : 0,
00101 Flags0 = traits<XprType>::Flags & ( (HereditaryBits & ~RowMajorBit) |
00102 DirectAccessBit |
00103 MaskPacketAccessBit |
00104 MaskAlignedBit),
00105 Flags = Flags0 | FlagsLinearAccessBit | FlagsLvalueBit | FlagsRowMajorBit
00106 };
00107 };
00108 }
00109
00110 template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel, bool HasDirectAccess> class Block
00111 : public internal::dense_xpr_base<Block<XprType, BlockRows, BlockCols, InnerPanel, HasDirectAccess> >::type
00112 {
00113 public:
00114
00115 typedef typename internal::dense_xpr_base<Block>::type Base;
00116 EIGEN_DENSE_PUBLIC_INTERFACE(Block)
00117
00118 class InnerIterator;
00119
00122 inline Block(XprType& xpr, Index i)
00123 : m_xpr(xpr),
00124
00125
00126
00127
00128 m_startRow( (BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) ? i : 0),
00129 m_startCol( (BlockRows==XprType::RowsAtCompileTime) && (BlockCols==1) ? i : 0),
00130 m_blockRows(BlockRows==1 ? 1 : xpr.rows()),
00131 m_blockCols(BlockCols==1 ? 1 : xpr.cols())
00132 {
00133 eigen_assert( (i>=0) && (
00134 ((BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) && i<xpr.rows())
00135 ||((BlockRows==XprType::RowsAtCompileTime) && (BlockCols==1) && i<xpr.cols())));
00136 }
00137
00140 inline Block(XprType& xpr, Index startRow, Index startCol)
00141 : m_xpr(xpr), m_startRow(startRow), m_startCol(startCol),
00142 m_blockRows(BlockRows), m_blockCols(BlockCols)
00143 {
00144 EIGEN_STATIC_ASSERT(RowsAtCompileTime!=Dynamic && ColsAtCompileTime!=Dynamic,THIS_METHOD_IS_ONLY_FOR_FIXED_SIZE)
00145 eigen_assert(startRow >= 0 && BlockRows >= 1 && startRow + BlockRows <= xpr.rows()
00146 && startCol >= 0 && BlockCols >= 1 && startCol + BlockCols <= xpr.cols());
00147 }
00148
00151 inline Block(XprType& xpr,
00152 Index startRow, Index startCol,
00153 Index blockRows, Index blockCols)
00154 : m_xpr(xpr), m_startRow(startRow), m_startCol(startCol),
00155 m_blockRows(blockRows), m_blockCols(blockCols)
00156 {
00157 eigen_assert((RowsAtCompileTime==Dynamic || RowsAtCompileTime==blockRows)
00158 && (ColsAtCompileTime==Dynamic || ColsAtCompileTime==blockCols));
00159 eigen_assert(startRow >= 0 && blockRows >= 0 && startRow + blockRows <= xpr.rows()
00160 && startCol >= 0 && blockCols >= 0 && startCol + blockCols <= xpr.cols());
00161 }
00162
00163 EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Block)
00164
00165 inline Index rows() const { return m_blockRows.value(); }
00166 inline Index cols() const { return m_blockCols.value(); }
00167
00168 inline Scalar& coeffRef(Index row, Index col)
00169 {
00170 EIGEN_STATIC_ASSERT_LVALUE(XprType)
00171 return m_xpr.const_cast_derived()
00172 .coeffRef(row + m_startRow.value(), col + m_startCol.value());
00173 }
00174
00175 inline const Scalar& coeffRef(Index row, Index col) const
00176 {
00177 return m_xpr.derived()
00178 .coeffRef(row + m_startRow.value(), col + m_startCol.value());
00179 }
00180
00181 EIGEN_STRONG_INLINE const CoeffReturnType coeff(Index row, Index col) const
00182 {
00183 return m_xpr.coeff(row + m_startRow.value(), col + m_startCol.value());
00184 }
00185
00186 inline Scalar& coeffRef(Index index)
00187 {
00188 EIGEN_STATIC_ASSERT_LVALUE(XprType)
00189 return m_xpr.const_cast_derived()
00190 .coeffRef(m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index),
00191 m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0));
00192 }
00193
00194 inline const Scalar& coeffRef(Index index) const
00195 {
00196 return m_xpr.const_cast_derived()
00197 .coeffRef(m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index),
00198 m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0));
00199 }
00200
00201 inline const CoeffReturnType coeff(Index index) const
00202 {
00203 return m_xpr
00204 .coeff(m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index),
00205 m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0));
00206 }
00207
00208 template<int LoadMode>
00209 inline PacketScalar packet(Index row, Index col) const
00210 {
00211 return m_xpr.template packet<Unaligned>
00212 (row + m_startRow.value(), col + m_startCol.value());
00213 }
00214
00215 template<int LoadMode>
00216 inline void writePacket(Index row, Index col, const PacketScalar& x)
00217 {
00218 m_xpr.const_cast_derived().template writePacket<Unaligned>
00219 (row + m_startRow.value(), col + m_startCol.value(), x);
00220 }
00221
00222 template<int LoadMode>
00223 inline PacketScalar packet(Index index) const
00224 {
00225 return m_xpr.template packet<Unaligned>
00226 (m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index),
00227 m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0));
00228 }
00229
00230 template<int LoadMode>
00231 inline void writePacket(Index index, const PacketScalar& x)
00232 {
00233 m_xpr.const_cast_derived().template writePacket<Unaligned>
00234 (m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index),
00235 m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0), x);
00236 }
00237
00238 #ifdef EIGEN_PARSED_BY_DOXYGEN
00239
00240 inline const Scalar* data() const;
00241 inline Index innerStride() const;
00242 inline Index outerStride() const;
00243 #endif
00244
00245 protected:
00246
00247 const typename XprType::Nested m_xpr;
00248 const internal::variable_if_dynamic<Index, XprType::RowsAtCompileTime == 1 ? 0 : Dynamic> m_startRow;
00249 const internal::variable_if_dynamic<Index, XprType::ColsAtCompileTime == 1 ? 0 : Dynamic> m_startCol;
00250 const internal::variable_if_dynamic<Index, RowsAtCompileTime> m_blockRows;
00251 const internal::variable_if_dynamic<Index, ColsAtCompileTime> m_blockCols;
00252 };
00253
00255 template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel>
00256 class Block<XprType,BlockRows,BlockCols, InnerPanel,true>
00257 : public MapBase<Block<XprType, BlockRows, BlockCols, InnerPanel, true> >
00258 {
00259 public:
00260
00261 typedef MapBase<Block> Base;
00262 EIGEN_DENSE_PUBLIC_INTERFACE(Block)
00263
00264 EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Block)
00265
00268 inline Block(XprType& xpr, Index i)
00269 : Base(internal::const_cast_ptr(&xpr.coeffRef(
00270 (BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) ? i : 0,
00271 (BlockRows==XprType::RowsAtCompileTime) && (BlockCols==1) ? i : 0)),
00272 BlockRows==1 ? 1 : xpr.rows(),
00273 BlockCols==1 ? 1 : xpr.cols()),
00274 m_xpr(xpr)
00275 {
00276 eigen_assert( (i>=0) && (
00277 ((BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) && i<xpr.rows())
00278 ||((BlockRows==XprType::RowsAtCompileTime) && (BlockCols==1) && i<xpr.cols())));
00279 init();
00280 }
00281
00284 inline Block(XprType& xpr, Index startRow, Index startCol)
00285 : Base(internal::const_cast_ptr(&xpr.coeffRef(startRow,startCol))), m_xpr(xpr)
00286 {
00287 eigen_assert(startRow >= 0 && BlockRows >= 1 && startRow + BlockRows <= xpr.rows()
00288 && startCol >= 0 && BlockCols >= 1 && startCol + BlockCols <= xpr.cols());
00289 init();
00290 }
00291
00294 inline Block(XprType& xpr,
00295 Index startRow, Index startCol,
00296 Index blockRows, Index blockCols)
00297 : Base(internal::const_cast_ptr(&xpr.coeffRef(startRow,startCol)), blockRows, blockCols),
00298 m_xpr(xpr)
00299 {
00300 eigen_assert((RowsAtCompileTime==Dynamic || RowsAtCompileTime==blockRows)
00301 && (ColsAtCompileTime==Dynamic || ColsAtCompileTime==blockCols));
00302 eigen_assert(startRow >= 0 && blockRows >= 0 && startRow + blockRows <= xpr.rows()
00303 && startCol >= 0 && blockCols >= 0 && startCol + blockCols <= xpr.cols());
00304 init();
00305 }
00306
00308 inline Index innerStride() const
00309 {
00310 return internal::traits<Block>::HasSameStorageOrderAsXprType
00311 ? m_xpr.innerStride()
00312 : m_xpr.outerStride();
00313 }
00314
00316 inline Index outerStride() const
00317 {
00318 return m_outerStride;
00319 }
00320
00321 #ifndef __SUNPRO_CC
00322
00323
00324 protected:
00325 #endif
00326
00327 #ifndef EIGEN_PARSED_BY_DOXYGEN
00328
00329 inline Block(XprType& xpr, const Scalar* data, Index blockRows, Index blockCols)
00330 : Base(data, blockRows, blockCols), m_xpr(xpr)
00331 {
00332 init();
00333 }
00334 #endif
00335
00336 protected:
00337 void init()
00338 {
00339 m_outerStride = internal::traits<Block>::HasSameStorageOrderAsXprType
00340 ? m_xpr.outerStride()
00341 : m_xpr.innerStride();
00342 }
00343
00344 const typename XprType::Nested m_xpr;
00345 int m_outerStride;
00346 };
00347
00348
00349 #endif // EIGEN_BLOCK_H