Eigen  3.2.92
Block.h
1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra.
3 //
4 // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
5 // Copyright (C) 2006-2010 Benoit Jacob <jacob.benoit.1@gmail.com>
6 //
7 // This Source Code Form is subject to the terms of the Mozilla
8 // Public License v. 2.0. If a copy of the MPL was not distributed
9 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
10 
11 #ifndef EIGEN_BLOCK_H
12 #define EIGEN_BLOCK_H
13 
14 namespace Eigen {
15 
51 namespace internal {
52 template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel>
53 struct traits<Block<XprType, BlockRows, BlockCols, InnerPanel> > : traits<XprType>
54 {
55  typedef typename traits<XprType>::Scalar Scalar;
56  typedef typename traits<XprType>::StorageKind StorageKind;
57  typedef typename traits<XprType>::XprKind XprKind;
58  typedef typename ref_selector<XprType>::type XprTypeNested;
59  typedef typename remove_reference<XprTypeNested>::type _XprTypeNested;
60  enum{
61  MatrixRows = traits<XprType>::RowsAtCompileTime,
62  MatrixCols = traits<XprType>::ColsAtCompileTime,
63  RowsAtCompileTime = MatrixRows == 0 ? 0 : BlockRows,
64  ColsAtCompileTime = MatrixCols == 0 ? 0 : BlockCols,
65  MaxRowsAtCompileTime = BlockRows==0 ? 0
66  : RowsAtCompileTime != Dynamic ? int(RowsAtCompileTime)
67  : int(traits<XprType>::MaxRowsAtCompileTime),
68  MaxColsAtCompileTime = BlockCols==0 ? 0
69  : ColsAtCompileTime != Dynamic ? int(ColsAtCompileTime)
70  : int(traits<XprType>::MaxColsAtCompileTime),
71 
72  XprTypeIsRowMajor = (int(traits<XprType>::Flags)&RowMajorBit) != 0,
73  IsRowMajor = (MaxRowsAtCompileTime==1&&MaxColsAtCompileTime!=1) ? 1
74  : (MaxColsAtCompileTime==1&&MaxRowsAtCompileTime!=1) ? 0
75  : XprTypeIsRowMajor,
76  HasSameStorageOrderAsXprType = (IsRowMajor == XprTypeIsRowMajor),
77  InnerSize = IsRowMajor ? int(ColsAtCompileTime) : int(RowsAtCompileTime),
78  InnerStrideAtCompileTime = HasSameStorageOrderAsXprType
79  ? int(inner_stride_at_compile_time<XprType>::ret)
80  : int(outer_stride_at_compile_time<XprType>::ret),
81  OuterStrideAtCompileTime = HasSameStorageOrderAsXprType
82  ? int(outer_stride_at_compile_time<XprType>::ret)
83  : int(inner_stride_at_compile_time<XprType>::ret),
84 
85  // FIXME, this traits is rather specialized for dense object and it needs to be cleaned further
86  FlagsLvalueBit = is_lvalue<XprType>::value ? LvalueBit : 0,
87  FlagsRowMajorBit = IsRowMajor ? RowMajorBit : 0,
88  Flags = (traits<XprType>::Flags & (DirectAccessBit | (InnerPanel?CompressedAccessBit:0))) | FlagsLvalueBit | FlagsRowMajorBit,
89  // FIXME DirectAccessBit should not be handled by expressions
90  //
91  // Alignment is needed by MapBase's assertions
92  // We can sefely set it to false here. Internal alignment errors will be detected by an eigen_internal_assert in the respective evaluator
93  Alignment = 0
94  };
95 };
96 
97 template<typename XprType, int BlockRows=Dynamic, int BlockCols=Dynamic, bool InnerPanel = false,
98  bool HasDirectAccess = internal::has_direct_access<XprType>::ret> class BlockImpl_dense;
99 
100 } // end namespace internal
101 
102 template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel, typename StorageKind> class BlockImpl;
103 
104 template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel> class Block
105  : public BlockImpl<XprType, BlockRows, BlockCols, InnerPanel, typename internal::traits<XprType>::StorageKind>
106 {
107  typedef BlockImpl<XprType, BlockRows, BlockCols, InnerPanel, typename internal::traits<XprType>::StorageKind> Impl;
108  public:
109  //typedef typename Impl::Base Base;
110  typedef Impl Base;
111  EIGEN_GENERIC_PUBLIC_INTERFACE(Block)
112  EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Block)
113 
114  typedef typename internal::remove_all<XprType>::type NestedExpression;
115 
118  EIGEN_DEVICE_FUNC
119  inline Block(XprType& xpr, Index i) : Impl(xpr,i)
120  {
121  eigen_assert( (i>=0) && (
122  ((BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) && i<xpr.rows())
123  ||((BlockRows==XprType::RowsAtCompileTime) && (BlockCols==1) && i<xpr.cols())));
124  }
125 
128  EIGEN_DEVICE_FUNC
129  inline Block(XprType& xpr, Index startRow, Index startCol)
130  : Impl(xpr, startRow, startCol)
131  {
132  EIGEN_STATIC_ASSERT(RowsAtCompileTime!=Dynamic && ColsAtCompileTime!=Dynamic,THIS_METHOD_IS_ONLY_FOR_FIXED_SIZE)
133  eigen_assert(startRow >= 0 && BlockRows >= 1 && startRow + BlockRows <= xpr.rows()
134  && startCol >= 0 && BlockCols >= 1 && startCol + BlockCols <= xpr.cols());
135  }
136 
139  EIGEN_DEVICE_FUNC
140  inline Block(XprType& xpr,
141  Index startRow, Index startCol,
142  Index blockRows, Index blockCols)
143  : Impl(xpr, startRow, startCol, blockRows, blockCols)
144  {
145  eigen_assert((RowsAtCompileTime==Dynamic || RowsAtCompileTime==blockRows)
146  && (ColsAtCompileTime==Dynamic || ColsAtCompileTime==blockCols));
147  eigen_assert(startRow >= 0 && blockRows >= 0 && startRow <= xpr.rows() - blockRows
148  && startCol >= 0 && blockCols >= 0 && startCol <= xpr.cols() - blockCols);
149  }
150 };
151 
152 // The generic default implementation for dense block simplu forward to the internal::BlockImpl_dense
153 // that must be specialized for direct and non-direct access...
154 template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel>
155 class BlockImpl<XprType, BlockRows, BlockCols, InnerPanel, Dense>
156  : public internal::BlockImpl_dense<XprType, BlockRows, BlockCols, InnerPanel>
157 {
158  typedef internal::BlockImpl_dense<XprType, BlockRows, BlockCols, InnerPanel> Impl;
159  typedef typename XprType::StorageIndex StorageIndex;
160  public:
161  typedef Impl Base;
162  EIGEN_INHERIT_ASSIGNMENT_OPERATORS(BlockImpl)
163  EIGEN_DEVICE_FUNC inline BlockImpl(XprType& xpr, Index i) : Impl(xpr,i) {}
164  EIGEN_DEVICE_FUNC inline BlockImpl(XprType& xpr, Index startRow, Index startCol) : Impl(xpr, startRow, startCol) {}
165  EIGEN_DEVICE_FUNC
166  inline BlockImpl(XprType& xpr, Index startRow, Index startCol, Index blockRows, Index blockCols)
167  : Impl(xpr, startRow, startCol, blockRows, blockCols) {}
168 };
169 
170 namespace internal {
171 
173 template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel, bool HasDirectAccess> class BlockImpl_dense
174  : public internal::dense_xpr_base<Block<XprType, BlockRows, BlockCols, InnerPanel> >::type
175 {
177  public:
178 
179  typedef typename internal::dense_xpr_base<BlockType>::type Base;
180  EIGEN_DENSE_PUBLIC_INTERFACE(BlockType)
181  EIGEN_INHERIT_ASSIGNMENT_OPERATORS(BlockImpl_dense)
182 
183  // class InnerIterator; // FIXME apparently never used
184 
185 
187  EIGEN_DEVICE_FUNC
188  inline BlockImpl_dense(XprType& xpr, Index i)
189  : m_xpr(xpr),
190  // It is a row if and only if BlockRows==1 and BlockCols==XprType::ColsAtCompileTime,
191  // and it is a column if and only if BlockRows==XprType::RowsAtCompileTime and BlockCols==1,
192  // all other cases are invalid.
193  // The case a 1x1 matrix seems ambiguous, but the result is the same anyway.
194  m_startRow( (BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) ? i : 0),
195  m_startCol( (BlockRows==XprType::RowsAtCompileTime) && (BlockCols==1) ? i : 0),
196  m_blockRows(BlockRows==1 ? 1 : xpr.rows()),
197  m_blockCols(BlockCols==1 ? 1 : xpr.cols())
198  {}
199 
202  EIGEN_DEVICE_FUNC
203  inline BlockImpl_dense(XprType& xpr, Index startRow, Index startCol)
204  : m_xpr(xpr), m_startRow(startRow), m_startCol(startCol),
205  m_blockRows(BlockRows), m_blockCols(BlockCols)
206  {}
207 
210  EIGEN_DEVICE_FUNC
211  inline BlockImpl_dense(XprType& xpr,
212  Index startRow, Index startCol,
213  Index blockRows, Index blockCols)
214  : m_xpr(xpr), m_startRow(startRow), m_startCol(startCol),
215  m_blockRows(blockRows), m_blockCols(blockCols)
216  {}
217 
218  EIGEN_DEVICE_FUNC inline Index rows() const { return m_blockRows.value(); }
219  EIGEN_DEVICE_FUNC inline Index cols() const { return m_blockCols.value(); }
220 
221  EIGEN_DEVICE_FUNC
222  inline Scalar& coeffRef(Index rowId, Index colId)
223  {
224  EIGEN_STATIC_ASSERT_LVALUE(XprType)
225  return m_xpr.const_cast_derived()
226  .coeffRef(rowId + m_startRow.value(), colId + m_startCol.value());
227  }
228 
229  EIGEN_DEVICE_FUNC
230  inline const Scalar& coeffRef(Index rowId, Index colId) const
231  {
232  return m_xpr.derived()
233  .coeffRef(rowId + m_startRow.value(), colId + m_startCol.value());
234  }
235 
236  EIGEN_DEVICE_FUNC
237  EIGEN_STRONG_INLINE const CoeffReturnType coeff(Index rowId, Index colId) const
238  {
239  return m_xpr.coeff(rowId + m_startRow.value(), colId + m_startCol.value());
240  }
241 
242  EIGEN_DEVICE_FUNC
243  inline Scalar& coeffRef(Index index)
244  {
245  EIGEN_STATIC_ASSERT_LVALUE(XprType)
246  return m_xpr.const_cast_derived()
247  .coeffRef(m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index),
248  m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0));
249  }
250 
251  EIGEN_DEVICE_FUNC
252  inline const Scalar& coeffRef(Index index) const
253  {
254  return m_xpr.const_cast_derived()
255  .coeffRef(m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index),
256  m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0));
257  }
258 
259  EIGEN_DEVICE_FUNC
260  inline const CoeffReturnType coeff(Index index) const
261  {
262  return m_xpr
263  .coeff(m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index),
264  m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0));
265  }
266 
267  template<int LoadMode>
268  inline PacketScalar packet(Index rowId, Index colId) const
269  {
270  return m_xpr.template packet<Unaligned>
271  (rowId + m_startRow.value(), colId + m_startCol.value());
272  }
273 
274  template<int LoadMode>
275  inline void writePacket(Index rowId, Index colId, const PacketScalar& val)
276  {
277  m_xpr.const_cast_derived().template writePacket<Unaligned>
278  (rowId + m_startRow.value(), colId + m_startCol.value(), val);
279  }
280 
281  template<int LoadMode>
282  inline PacketScalar packet(Index index) const
283  {
284  return m_xpr.template packet<Unaligned>
285  (m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index),
286  m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0));
287  }
288 
289  template<int LoadMode>
290  inline void writePacket(Index index, const PacketScalar& val)
291  {
292  m_xpr.const_cast_derived().template writePacket<Unaligned>
293  (m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index),
294  m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0), val);
295  }
296 
297  #ifdef EIGEN_PARSED_BY_DOXYGEN
298 
299  EIGEN_DEVICE_FUNC inline const Scalar* data() const;
300  EIGEN_DEVICE_FUNC inline Index innerStride() const;
301  EIGEN_DEVICE_FUNC inline Index outerStride() const;
302  #endif
303 
304  EIGEN_DEVICE_FUNC
305  const typename internal::remove_all<typename XprType::Nested>::type& nestedExpression() const
306  {
307  return m_xpr;
308  }
309 
310  EIGEN_DEVICE_FUNC
311  StorageIndex startRow() const
312  {
313  return m_startRow.value();
314  }
315 
316  EIGEN_DEVICE_FUNC
317  StorageIndex startCol() const
318  {
319  return m_startCol.value();
320  }
321 
322  protected:
323 
324  const typename XprType::Nested m_xpr;
325  const internal::variable_if_dynamic<StorageIndex, XprType::RowsAtCompileTime == 1 ? 0 : Dynamic> m_startRow;
326  const internal::variable_if_dynamic<StorageIndex, XprType::ColsAtCompileTime == 1 ? 0 : Dynamic> m_startCol;
327  const internal::variable_if_dynamic<StorageIndex, RowsAtCompileTime> m_blockRows;
328  const internal::variable_if_dynamic<StorageIndex, ColsAtCompileTime> m_blockCols;
329 };
330 
332 template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel>
333 class BlockImpl_dense<XprType,BlockRows,BlockCols, InnerPanel,true>
334  : public MapBase<Block<XprType, BlockRows, BlockCols, InnerPanel> >
335 {
337  enum {
338  XprTypeIsRowMajor = (int(traits<XprType>::Flags)&RowMajorBit) != 0
339  };
340  public:
341 
342  typedef MapBase<BlockType> Base;
343  EIGEN_DENSE_PUBLIC_INTERFACE(BlockType)
344  EIGEN_INHERIT_ASSIGNMENT_OPERATORS(BlockImpl_dense)
345 
346 
348  EIGEN_DEVICE_FUNC
349  inline BlockImpl_dense(XprType& xpr, Index i)
350  : Base(xpr.data() + i * ( ((BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) && (!XprTypeIsRowMajor))
351  || ((BlockRows==XprType::RowsAtCompileTime) && (BlockCols==1) && ( XprTypeIsRowMajor)) ? xpr.innerStride() : xpr.outerStride()),
352  BlockRows==1 ? 1 : xpr.rows(),
353  BlockCols==1 ? 1 : xpr.cols()),
354  m_xpr(xpr)
355  {
356  init();
357  }
358 
361  EIGEN_DEVICE_FUNC
362  inline BlockImpl_dense(XprType& xpr, Index startRow, Index startCol)
363  : Base(xpr.data()+xpr.innerStride()*(XprTypeIsRowMajor?startCol:startRow) + xpr.outerStride()*(XprTypeIsRowMajor?startRow:startCol)),
364  m_xpr(xpr)
365  {
366  init();
367  }
368 
371  EIGEN_DEVICE_FUNC
372  inline BlockImpl_dense(XprType& xpr,
373  Index startRow, Index startCol,
374  Index blockRows, Index blockCols)
375  : Base(xpr.data()+xpr.innerStride()*(XprTypeIsRowMajor?startCol:startRow) + xpr.outerStride()*(XprTypeIsRowMajor?startRow:startCol), blockRows, blockCols),
376  m_xpr(xpr)
377  {
378  init();
379  }
380 
381  EIGEN_DEVICE_FUNC
382  const typename internal::remove_all<typename XprType::Nested>::type& nestedExpression() const
383  {
384  return m_xpr;
385  }
386 
388  EIGEN_DEVICE_FUNC
389  inline Index innerStride() const
390  {
391  return internal::traits<BlockType>::HasSameStorageOrderAsXprType
392  ? m_xpr.innerStride()
393  : m_xpr.outerStride();
394  }
395 
397  EIGEN_DEVICE_FUNC
398  inline Index outerStride() const
399  {
400  return m_outerStride;
401  }
402 
403  #ifndef __SUNPRO_CC
404  // FIXME sunstudio is not friendly with the above friend...
405  // META-FIXME there is no 'friend' keyword around here. Is this obsolete?
406  protected:
407  #endif
408 
409  #ifndef EIGEN_PARSED_BY_DOXYGEN
410 
411  EIGEN_DEVICE_FUNC
412  inline BlockImpl_dense(XprType& xpr, const Scalar* data, Index blockRows, Index blockCols)
413  : Base(data, blockRows, blockCols), m_xpr(xpr)
414  {
415  init();
416  }
417  #endif
418 
419  protected:
420  EIGEN_DEVICE_FUNC
421  void init()
422  {
423  m_outerStride = internal::traits<BlockType>::HasSameStorageOrderAsXprType
424  ? m_xpr.outerStride()
425  : m_xpr.innerStride();
426  }
427 
428  typename XprType::Nested m_xpr;
429  Index m_outerStride;
430 };
431 
432 } // end namespace internal
433 
434 } // end namespace Eigen
435 
436 #endif // EIGEN_BLOCK_H
Base class for Map and Block expression with direct access.
Definition: ForwardDeclarations.h:117
const unsigned int CompressedAccessBit
Definition: Constants.h:185
const unsigned int DirectAccessBit
Definition: Constants.h:149
const unsigned int LvalueBit
Definition: Constants.h:138
Definition: LDLT.h:16
const unsigned int RowMajorBit
Definition: Constants.h:61
Block(XprType &xpr, Index startRow, Index startCol, Index blockRows, Index blockCols)
Definition: Block.h:140
Block(XprType &xpr, Index i)
Definition: Block.h:119
Definition: Eigen_Colamd.h:54
Expression of a fixed-size or dynamic-size block.
Definition: Block.h:104
Block(XprType &xpr, Index startRow, Index startCol)
Definition: Block.h:129