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