Eigen  3.4.90 (git rev a4098ac676528a83cfb73d4d26ce1b42ec05f47c)
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#include "./InternalHeaderCheck.h"
15
16namespace Eigen {
17
18namespace internal {
19template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel>
20struct traits<Block<XprType, BlockRows, BlockCols, InnerPanel> > : traits<XprType>
21{
22 typedef typename traits<XprType>::Scalar Scalar;
23 typedef typename traits<XprType>::StorageKind StorageKind;
24 typedef typename traits<XprType>::XprKind XprKind;
25 typedef typename ref_selector<XprType>::type XprTypeNested;
26 typedef typename remove_reference<XprTypeNested>::type _XprTypeNested;
27 enum{
28 MatrixRows = traits<XprType>::RowsAtCompileTime,
29 MatrixCols = traits<XprType>::ColsAtCompileTime,
30 RowsAtCompileTime = MatrixRows == 0 ? 0 : BlockRows,
31 ColsAtCompileTime = MatrixCols == 0 ? 0 : BlockCols,
32 MaxRowsAtCompileTime = BlockRows==0 ? 0
33 : RowsAtCompileTime != Dynamic ? int(RowsAtCompileTime)
34 : int(traits<XprType>::MaxRowsAtCompileTime),
35 MaxColsAtCompileTime = BlockCols==0 ? 0
36 : ColsAtCompileTime != Dynamic ? int(ColsAtCompileTime)
37 : int(traits<XprType>::MaxColsAtCompileTime),
38
39 XprTypeIsRowMajor = (int(traits<XprType>::Flags)&RowMajorBit) != 0,
40 IsRowMajor = (MaxRowsAtCompileTime==1&&MaxColsAtCompileTime!=1) ? 1
41 : (MaxColsAtCompileTime==1&&MaxRowsAtCompileTime!=1) ? 0
42 : XprTypeIsRowMajor,
43 HasSameStorageOrderAsXprType = (IsRowMajor == XprTypeIsRowMajor),
44 InnerSize = IsRowMajor ? int(ColsAtCompileTime) : int(RowsAtCompileTime),
45 InnerStrideAtCompileTime = HasSameStorageOrderAsXprType
46 ? int(inner_stride_at_compile_time<XprType>::ret)
47 : int(outer_stride_at_compile_time<XprType>::ret),
48 OuterStrideAtCompileTime = HasSameStorageOrderAsXprType
49 ? int(outer_stride_at_compile_time<XprType>::ret)
50 : int(inner_stride_at_compile_time<XprType>::ret),
51
52 // FIXME, this traits is rather specialized for dense object and it needs to be cleaned further
53 FlagsLvalueBit = is_lvalue<XprType>::value ? LvalueBit : 0,
54 FlagsRowMajorBit = IsRowMajor ? RowMajorBit : 0,
55 Flags = (traits<XprType>::Flags & (DirectAccessBit | (InnerPanel?CompressedAccessBit:0))) | FlagsLvalueBit | FlagsRowMajorBit,
56 // FIXME DirectAccessBit should not be handled by expressions
57 //
58 // Alignment is needed by MapBase's assertions
59 // We can sefely set it to false here. Internal alignment errors will be detected by an eigen_internal_assert in the respective evaluator
60 Alignment = 0
61 };
62};
63
64template<typename XprType, int BlockRows=Dynamic, int BlockCols=Dynamic, bool InnerPanel = false,
65 bool HasDirectAccess = internal::has_direct_access<XprType>::ret> class BlockImpl_dense;
66
67} // end namespace internal
68
69template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel, typename StorageKind> class BlockImpl;
70
105template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel> class Block
106 : public BlockImpl<XprType, BlockRows, BlockCols, InnerPanel, typename internal::traits<XprType>::StorageKind>
107{
108 typedef BlockImpl<XprType, BlockRows, BlockCols, InnerPanel, typename internal::traits<XprType>::StorageKind> Impl;
109 public:
110 //typedef typename Impl::Base Base;
111 typedef Impl Base;
112 EIGEN_GENERIC_PUBLIC_INTERFACE(Block)
113 EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Block)
114
115 typedef typename internal::remove_all<XprType>::type NestedExpression;
116
119 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
120 Block(XprType& xpr, Index i) : Impl(xpr,i)
121 {
122 eigen_assert( (i>=0) && (
123 ((BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) && i<xpr.rows())
124 ||((BlockRows==XprType::RowsAtCompileTime) && (BlockCols==1) && i<xpr.cols())));
125 }
126
129 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
130 Block(XprType& xpr, Index startRow, Index startCol)
131 : Impl(xpr, startRow, startCol)
132 {
133 EIGEN_STATIC_ASSERT(RowsAtCompileTime!=Dynamic && ColsAtCompileTime!=Dynamic,THIS_METHOD_IS_ONLY_FOR_FIXED_SIZE)
134 eigen_assert(startRow >= 0 && BlockRows >= 0 && startRow + BlockRows <= xpr.rows()
135 && startCol >= 0 && BlockCols >= 0 && startCol + BlockCols <= xpr.cols());
136 }
137
140 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
141 Block(XprType& xpr,
142 Index startRow, Index startCol,
143 Index blockRows, Index blockCols)
144 : Impl(xpr, startRow, startCol, blockRows, blockCols)
145 {
146 eigen_assert((RowsAtCompileTime==Dynamic || RowsAtCompileTime==blockRows)
147 && (ColsAtCompileTime==Dynamic || ColsAtCompileTime==blockCols));
148 eigen_assert(startRow >= 0 && blockRows >= 0 && startRow <= xpr.rows() - blockRows
149 && startCol >= 0 && blockCols >= 0 && startCol <= xpr.cols() - blockCols);
150 }
151};
152
153// The generic default implementation for dense block simplu forward to the internal::BlockImpl_dense
154// that must be specialized for direct and non-direct access...
155template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel>
156class BlockImpl<XprType, BlockRows, BlockCols, InnerPanel, Dense>
157 : public internal::BlockImpl_dense<XprType, BlockRows, BlockCols, InnerPanel>
158{
159 typedef internal::BlockImpl_dense<XprType, BlockRows, BlockCols, InnerPanel> Impl;
160 typedef typename XprType::StorageIndex StorageIndex;
161 public:
162 typedef Impl Base;
163 EIGEN_INHERIT_ASSIGNMENT_OPERATORS(BlockImpl)
164 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE BlockImpl(XprType& xpr, Index i) : Impl(xpr,i) {}
165 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE BlockImpl(XprType& xpr, Index startRow, Index startCol) : Impl(xpr, startRow, startCol) {}
166 EIGEN_DEVICE_FUNC
167 EIGEN_STRONG_INLINE BlockImpl(XprType& xpr, Index startRow, Index startCol, Index blockRows, Index blockCols)
168 : Impl(xpr, startRow, startCol, blockRows, blockCols) {}
169};
170
171namespace internal {
172
174template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel, bool HasDirectAccess> class BlockImpl_dense
175 : public internal::dense_xpr_base<Block<XprType, BlockRows, BlockCols, InnerPanel> >::type
176{
177 typedef Block<XprType, BlockRows, BlockCols, InnerPanel> BlockType;
178 typedef typename internal::ref_selector<XprType>::non_const_type XprTypeNested;
179 public:
180
181 typedef typename internal::dense_xpr_base<BlockType>::type Base;
182 EIGEN_DENSE_PUBLIC_INTERFACE(BlockType)
183 EIGEN_INHERIT_ASSIGNMENT_OPERATORS(BlockImpl_dense)
184
185 // class InnerIterator; // FIXME apparently never used
186
187
189 EIGEN_DEVICE_FUNC
190 inline BlockImpl_dense(XprType& xpr, Index i)
191 : m_xpr(xpr),
192 // It is a row if and only if BlockRows==1 and BlockCols==XprType::ColsAtCompileTime,
193 // and it is a column if and only if BlockRows==XprType::RowsAtCompileTime and BlockCols==1,
194 // all other cases are invalid.
195 // The case a 1x1 matrix seems ambiguous, but the result is the same anyway.
196 m_startRow( (BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) ? i : 0),
197 m_startCol( (BlockRows==XprType::RowsAtCompileTime) && (BlockCols==1) ? i : 0),
198 m_blockRows(BlockRows==1 ? 1 : xpr.rows()),
199 m_blockCols(BlockCols==1 ? 1 : xpr.cols())
200 {}
201
204 EIGEN_DEVICE_FUNC
205 inline BlockImpl_dense(XprType& xpr, Index startRow, Index startCol)
206 : m_xpr(xpr), m_startRow(startRow), m_startCol(startCol),
207 m_blockRows(BlockRows), m_blockCols(BlockCols)
208 {}
209
212 EIGEN_DEVICE_FUNC
213 inline BlockImpl_dense(XprType& xpr,
214 Index startRow, Index startCol,
215 Index blockRows, Index blockCols)
216 : m_xpr(xpr), m_startRow(startRow), m_startCol(startCol),
217 m_blockRows(blockRows), m_blockCols(blockCols)
218 {}
219
220 EIGEN_DEVICE_FUNC inline Index rows() const { return m_blockRows.value(); }
221 EIGEN_DEVICE_FUNC inline Index cols() const { return m_blockCols.value(); }
222
223 EIGEN_DEVICE_FUNC
224 inline Scalar& coeffRef(Index rowId, Index colId)
225 {
226 EIGEN_STATIC_ASSERT_LVALUE(XprType)
227 return m_xpr.coeffRef(rowId + m_startRow.value(), colId + m_startCol.value());
228 }
229
230 EIGEN_DEVICE_FUNC
231 inline const Scalar& coeffRef(Index rowId, Index colId) const
232 {
233 return m_xpr.derived().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.coeffRef(m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index),
247 m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0));
248 }
249
250 EIGEN_DEVICE_FUNC
251 inline const Scalar& coeffRef(Index index) const
252 {
253 return m_xpr.coeffRef(m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index),
254 m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0));
255 }
256
257 EIGEN_DEVICE_FUNC
258 inline const CoeffReturnType coeff(Index index) const
259 {
260 return m_xpr.coeff(m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index),
261 m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0));
262 }
263
264 template<int LoadMode>
265 EIGEN_DEVICE_FUNC inline PacketScalar packet(Index rowId, Index colId) const
266 {
267 return m_xpr.template packet<Unaligned>(rowId + m_startRow.value(), colId + m_startCol.value());
268 }
269
270 template<int LoadMode>
271 EIGEN_DEVICE_FUNC inline void writePacket(Index rowId, Index colId, const PacketScalar& val)
272 {
273 m_xpr.template writePacket<Unaligned>(rowId + m_startRow.value(), colId + m_startCol.value(), val);
274 }
275
276 template<int LoadMode>
277 EIGEN_DEVICE_FUNC inline PacketScalar packet(Index index) const
278 {
279 return m_xpr.template packet<Unaligned>
280 (m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index),
281 m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0));
282 }
283
284 template<int LoadMode>
285 EIGEN_DEVICE_FUNC inline void writePacket(Index index, const PacketScalar& val)
286 {
287 m_xpr.template writePacket<Unaligned>
288 (m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index),
289 m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0), val);
290 }
291
292 #ifdef EIGEN_PARSED_BY_DOXYGEN
294 EIGEN_DEVICE_FUNC inline const Scalar* data() const;
295 EIGEN_DEVICE_FUNC inline Index innerStride() const;
296 EIGEN_DEVICE_FUNC inline Index outerStride() const;
297 #endif
298
299 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
300 const typename internal::remove_all<XprTypeNested>::type& nestedExpression() const
301 {
302 return m_xpr;
303 }
304
305 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
306 XprType& nestedExpression() { return m_xpr; }
307
308 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
309 StorageIndex startRow() const EIGEN_NOEXCEPT
310 {
311 return m_startRow.value();
312 }
313
314 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
315 StorageIndex startCol() const EIGEN_NOEXCEPT
316 {
317 return m_startCol.value();
318 }
319
320 protected:
321
322 XprTypeNested m_xpr;
323 const internal::variable_if_dynamic<StorageIndex, (XprType::RowsAtCompileTime == 1 && BlockRows==1) ? 0 : Dynamic> m_startRow;
324 const internal::variable_if_dynamic<StorageIndex, (XprType::ColsAtCompileTime == 1 && BlockCols==1) ? 0 : Dynamic> m_startCol;
325 const internal::variable_if_dynamic<StorageIndex, RowsAtCompileTime> m_blockRows;
326 const internal::variable_if_dynamic<StorageIndex, ColsAtCompileTime> m_blockCols;
327};
328
330template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel>
331class BlockImpl_dense<XprType,BlockRows,BlockCols, InnerPanel,true>
332 : public MapBase<Block<XprType, BlockRows, BlockCols, InnerPanel> >
333{
334 typedef Block<XprType, BlockRows, BlockCols, InnerPanel> BlockType;
335 typedef typename internal::ref_selector<XprType>::non_const_type XprTypeNested;
336 enum {
337 XprTypeIsRowMajor = (int(traits<XprType>::Flags)&RowMajorBit) != 0
338 };
339 public:
340
341 typedef MapBase<BlockType> Base;
342 EIGEN_DENSE_PUBLIC_INTERFACE(BlockType)
343 EIGEN_INHERIT_ASSIGNMENT_OPERATORS(BlockImpl_dense)
344
345
347 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
348 BlockImpl_dense(XprType& xpr, Index i)
349 : Base(xpr.data() + i * ( ((BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) && (!XprTypeIsRowMajor))
350 || ((BlockRows==XprType::RowsAtCompileTime) && (BlockCols==1) && ( XprTypeIsRowMajor)) ? xpr.innerStride() : xpr.outerStride()),
351 BlockRows==1 ? 1 : xpr.rows(),
352 BlockCols==1 ? 1 : xpr.cols()),
353 m_xpr(xpr),
354 m_startRow( (BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) ? i : 0),
355 m_startCol( (BlockRows==XprType::RowsAtCompileTime) && (BlockCols==1) ? i : 0)
356 {
357 init();
358 }
359
362 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
363 BlockImpl_dense(XprType& xpr, Index startRow, Index startCol)
364 : Base(xpr.data()+xpr.innerStride()*(XprTypeIsRowMajor?startCol:startRow) + xpr.outerStride()*(XprTypeIsRowMajor?startRow:startCol)),
365 m_xpr(xpr), m_startRow(startRow), m_startCol(startCol)
366 {
367 init();
368 }
369
372 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
373 BlockImpl_dense(XprType& xpr,
374 Index startRow, Index startCol,
375 Index blockRows, Index blockCols)
376 : Base(xpr.data()+xpr.innerStride()*(XprTypeIsRowMajor?startCol:startRow) + xpr.outerStride()*(XprTypeIsRowMajor?startRow:startCol), blockRows, blockCols),
377 m_xpr(xpr), m_startRow(startRow), m_startCol(startCol)
378 {
379 init();
380 }
381
382 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
383 const typename internal::remove_all<XprTypeNested>::type& nestedExpression() const EIGEN_NOEXCEPT
384 {
385 return m_xpr;
386 }
387
388 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
389 XprType& nestedExpression() { return m_xpr; }
390
392 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
393 Index innerStride() const EIGEN_NOEXCEPT
394 {
395 return internal::traits<BlockType>::HasSameStorageOrderAsXprType
396 ? m_xpr.innerStride()
397 : m_xpr.outerStride();
398 }
399
401 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
402 Index outerStride() const EIGEN_NOEXCEPT
403 {
404 return internal::traits<BlockType>::HasSameStorageOrderAsXprType
405 ? m_xpr.outerStride()
406 : m_xpr.innerStride();
407 }
408
409 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
410 StorageIndex startRow() const EIGEN_NOEXCEPT { return m_startRow.value(); }
411
412 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
413 StorageIndex startCol() const EIGEN_NOEXCEPT { return m_startCol.value(); }
414
415 #ifndef __SUNPRO_CC
416 // FIXME sunstudio is not friendly with the above friend...
417 // META-FIXME there is no 'friend' keyword around here. Is this obsolete?
418 protected:
419 #endif
420
421 #ifndef EIGEN_PARSED_BY_DOXYGEN
423 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
424 BlockImpl_dense(XprType& xpr, const Scalar* data, Index blockRows, Index blockCols)
425 : Base(data, blockRows, blockCols), m_xpr(xpr)
426 {
427 init();
428 }
429 #endif
430
431 protected:
432 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
433 void init()
434 {
435 m_outerStride = internal::traits<BlockType>::HasSameStorageOrderAsXprType
436 ? m_xpr.outerStride()
437 : m_xpr.innerStride();
438 }
439
440 XprTypeNested m_xpr;
441 const internal::variable_if_dynamic<StorageIndex, (XprType::RowsAtCompileTime == 1 && BlockRows==1) ? 0 : Dynamic> m_startRow;
442 const internal::variable_if_dynamic<StorageIndex, (XprType::ColsAtCompileTime == 1 && BlockCols==1) ? 0 : Dynamic> m_startCol;
443 Index m_outerStride;
444};
445
446} // end namespace internal
447
448} // end namespace Eigen
449
450#endif // EIGEN_BLOCK_H
Expression of a fixed-size or dynamic-size block.
Definition: Block.h:107
Block(XprType &xpr, Index startRow, Index startCol)
Definition: Block.h:130
Block(XprType &xpr, Index startRow, Index startCol, Index blockRows, Index blockCols)
Definition: Block.h:141
Block(XprType &xpr, Index i)
Definition: Block.h:120
const unsigned int DirectAccessBit
Definition: Constants.h:157
const unsigned int LvalueBit
Definition: Constants.h:146
const unsigned int RowMajorBit
Definition: Constants.h:68
const unsigned int CompressedAccessBit
Definition: Constants.h:193
Namespace containing all symbols from the Eigen library.
Definition: B01_Experimental.dox:1
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:59
const int Dynamic
Definition: Constants.h:24