Block.h
Go to the documentation of this file.
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 // Eigen is free software; you can redistribute it and/or
00008 // modify it under the terms of the GNU Lesser General Public
00009 // License as published by the Free Software Foundation; either
00010 // version 3 of the License, or (at your option) any later version.
00011 //
00012 // Alternatively, you can redistribute it and/or
00013 // modify it under the terms of the GNU General Public License as
00014 // published by the Free Software Foundation; either version 2 of
00015 // the License, or (at your option) any later version.
00016 //
00017 // Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
00018 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00019 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
00020 // GNU General Public License for more details.
00021 //
00022 // You should have received a copy of the GNU Lesser General Public
00023 // License and a copy of the GNU General Public License along with
00024 // Eigen. If not, see <http://www.gnu.org/licenses/>.
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         // It is a row if and only if BlockRows==1 and BlockCols==XprType::ColsAtCompileTime,
00125         // and it is a column if and only if BlockRows==XprType::RowsAtCompileTime and BlockCols==1,
00126         // all other cases are invalid.
00127         // The case a 1x1 matrix seems ambiguous, but the result is the same anyway.
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   // FIXME sunstudio is not friendly with the above friend...
00323   // META-FIXME there is no 'friend' keyword around here. Is this obsolete?
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


re_vision
Author(s): Dorian Galvez-Lopez
autogenerated on Sun Jan 5 2014 11:30:48