Eigen  3.3.3
Block.h
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
 All Classes Functions Variables Typedefs Enumerations Enumerator Friends