Eigen  3.4.90 (git rev 5a9f66fb35d03a4da9ef8976e67a61b30aa16dcf)
 
Loading...
Searching...
No Matches
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 <[email protected]>
5// Copyright (C) 2006-2010 Benoit Jacob <[email protected]>
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// IWYU pragma: private
15#include "./InternalHeaderCheck.h"
16
17namespace Eigen {
18
19namespace internal {
20template <typename XprType_, int BlockRows, int BlockCols, bool InnerPanel_>
21struct traits<Block<XprType_, BlockRows, BlockCols, InnerPanel_>> : traits<XprType_> {
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 std::remove_reference_t<XprTypeNested> 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 ? int(inner_stride_at_compile_time<XprType_>::ret)
46 : int(outer_stride_at_compile_time<XprType_>::ret),
47 OuterStrideAtCompileTime = HasSameStorageOrderAsXprType ? int(outer_stride_at_compile_time<XprType_>::ret)
48 : int(inner_stride_at_compile_time<XprType_>::ret),
49
50 // FIXME, this traits is rather specialized for dense object and it needs to be cleaned further
51 FlagsLvalueBit = is_lvalue<XprType_>::value ? LvalueBit : 0,
52 FlagsRowMajorBit = IsRowMajor ? RowMajorBit : 0,
53 Flags = (traits<XprType_>::Flags & (DirectAccessBit | (InnerPanel_ ? CompressedAccessBit : 0))) | FlagsLvalueBit |
54 FlagsRowMajorBit,
55 // FIXME DirectAccessBit should not be handled by expressions
56 //
57 // Alignment is needed by MapBase's assertions
58 // We can sefely set it to false here. Internal alignment errors will be detected by an eigen_internal_assert in the
59 // respective evaluator
60 Alignment = 0,
61 InnerPanel = InnerPanel_ ? 1 : 0
62 };
63};
64
65template <typename XprType, int BlockRows = Dynamic, int BlockCols = Dynamic, bool InnerPanel = false,
66 bool HasDirectAccess = internal::has_direct_access<XprType>::ret>
67class BlockImpl_dense;
68
69} // end namespace internal
70
71template <typename XprType, int BlockRows, int BlockCols, bool InnerPanel, typename StorageKind>
72class BlockImpl;
73
108template <typename XprType, int BlockRows, int BlockCols, bool InnerPanel>
109class Block
110 : public BlockImpl<XprType, BlockRows, BlockCols, InnerPanel, typename internal::traits<XprType>::StorageKind> {
111 typedef BlockImpl<XprType, BlockRows, BlockCols, InnerPanel, typename internal::traits<XprType>::StorageKind> Impl;
112 using BlockHelper = internal::block_xpr_helper<Block>;
113
114 public:
115 // typedef typename Impl::Base Base;
116 typedef Impl Base;
117 EIGEN_GENERIC_PUBLIC_INTERFACE(Block)
118 EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Block)
119
120 typedef internal::remove_all_t<XprType> NestedExpression;
121
124 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Block(XprType& xpr, Index i) : Impl(xpr, i) {
125 eigen_assert((i >= 0) && (((BlockRows == 1) && (BlockCols == XprType::ColsAtCompileTime) && i < xpr.rows()) ||
126 ((BlockRows == XprType::RowsAtCompileTime) && (BlockCols == 1) && i < xpr.cols())));
127 }
128
131 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Block(XprType& xpr, Index startRow, Index startCol)
132 : Impl(xpr, startRow, startCol) {
133 EIGEN_STATIC_ASSERT(RowsAtCompileTime != Dynamic && ColsAtCompileTime != Dynamic,
134 THIS_METHOD_IS_ONLY_FOR_FIXED_SIZE)
135 eigen_assert(startRow >= 0 && BlockRows >= 0 && startRow + BlockRows <= xpr.rows() && startCol >= 0 &&
136 BlockCols >= 0 && startCol + BlockCols <= xpr.cols());
137 }
138
141 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Block(XprType& xpr, Index startRow, Index startCol, Index blockRows,
142 Index blockCols)
143 : Impl(xpr, startRow, startCol, blockRows, blockCols) {
144 eigen_assert((RowsAtCompileTime == Dynamic || RowsAtCompileTime == blockRows) &&
145 (ColsAtCompileTime == Dynamic || ColsAtCompileTime == blockCols));
146 eigen_assert(startRow >= 0 && blockRows >= 0 && startRow <= xpr.rows() - blockRows && startCol >= 0 &&
147 blockCols >= 0 && startCol <= xpr.cols() - blockCols);
148 }
149
150 // convert nested blocks (e.g. Block<Block<MatrixType>>) to a simple block expression (Block<MatrixType>)
151
154
155 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE ConstUnwindReturnType unwind() const {
156 return ConstUnwindReturnType(BlockHelper::base(*this), BlockHelper::row(*this, 0), BlockHelper::col(*this, 0),
157 this->rows(), this->cols());
158 }
159
160 template <typename T = Block, typename EnableIf = std::enable_if_t<!std::is_const<T>::value>>
161 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE UnwindReturnType unwind() {
162 return UnwindReturnType(BlockHelper::base(*this), BlockHelper::row(*this, 0), BlockHelper::col(*this, 0),
163 this->rows(), this->cols());
164 }
165};
166
167// The generic default implementation for dense block simply forward to the internal::BlockImpl_dense
168// that must be specialized for direct and non-direct access...
169template <typename XprType, int BlockRows, int BlockCols, bool InnerPanel>
170class BlockImpl<XprType, BlockRows, BlockCols, InnerPanel, Dense>
171 : public internal::BlockImpl_dense<XprType, BlockRows, BlockCols, InnerPanel> {
172 typedef internal::BlockImpl_dense<XprType, BlockRows, BlockCols, InnerPanel> Impl;
173 typedef typename XprType::StorageIndex StorageIndex;
174
175 public:
176 typedef Impl Base;
177 EIGEN_INHERIT_ASSIGNMENT_OPERATORS(BlockImpl)
178 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE BlockImpl(XprType& xpr, Index i) : Impl(xpr, i) {}
179 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE BlockImpl(XprType& xpr, Index startRow, Index startCol)
180 : Impl(xpr, startRow, startCol) {}
181 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE BlockImpl(XprType& xpr, Index startRow, Index startCol, Index blockRows,
182 Index blockCols)
183 : Impl(xpr, startRow, startCol, blockRows, blockCols) {}
184};
185
186namespace internal {
187
189template <typename XprType, int BlockRows, int BlockCols, bool InnerPanel, bool HasDirectAccess>
190class BlockImpl_dense : public internal::dense_xpr_base<Block<XprType, BlockRows, BlockCols, InnerPanel>>::type {
191 typedef Block<XprType, BlockRows, BlockCols, InnerPanel> BlockType;
192 typedef typename internal::ref_selector<XprType>::non_const_type XprTypeNested;
193
194 public:
195 typedef typename internal::dense_xpr_base<BlockType>::type Base;
196 EIGEN_DENSE_PUBLIC_INTERFACE(BlockType)
197 EIGEN_INHERIT_ASSIGNMENT_OPERATORS(BlockImpl_dense)
198
199 // class InnerIterator; // FIXME apparently never used
200
201
203 EIGEN_DEVICE_FUNC inline BlockImpl_dense(XprType& xpr, Index i)
204 : m_xpr(xpr),
205 // It is a row if and only if BlockRows==1 and BlockCols==XprType::ColsAtCompileTime,
206 // and it is a column if and only if BlockRows==XprType::RowsAtCompileTime and BlockCols==1,
207 // all other cases are invalid.
208 // The case a 1x1 matrix seems ambiguous, but the result is the same anyway.
209 m_startRow((BlockRows == 1) && (BlockCols == XprType::ColsAtCompileTime) ? i : 0),
210 m_startCol((BlockRows == XprType::RowsAtCompileTime) && (BlockCols == 1) ? i : 0),
211 m_blockRows(BlockRows == 1 ? 1 : xpr.rows()),
212 m_blockCols(BlockCols == 1 ? 1 : xpr.cols()) {}
213
216 EIGEN_DEVICE_FUNC inline BlockImpl_dense(XprType& xpr, Index startRow, Index startCol)
217 : m_xpr(xpr), m_startRow(startRow), m_startCol(startCol), m_blockRows(BlockRows), m_blockCols(BlockCols) {}
218
221 EIGEN_DEVICE_FUNC inline BlockImpl_dense(XprType& xpr, Index startRow, Index startCol, Index blockRows,
222 Index blockCols)
223 : m_xpr(xpr), m_startRow(startRow), m_startCol(startCol), m_blockRows(blockRows), m_blockCols(blockCols) {}
224
225 EIGEN_DEVICE_FUNC inline Index rows() const { return m_blockRows.value(); }
226 EIGEN_DEVICE_FUNC inline Index cols() const { return m_blockCols.value(); }
227
228 EIGEN_DEVICE_FUNC inline Scalar& coeffRef(Index rowId, Index colId) {
229 EIGEN_STATIC_ASSERT_LVALUE(XprType)
230 return m_xpr.coeffRef(rowId + m_startRow.value(), colId + m_startCol.value());
231 }
232
233 EIGEN_DEVICE_FUNC inline const Scalar& coeffRef(Index rowId, Index colId) const {
234 return m_xpr.derived().coeffRef(rowId + m_startRow.value(), colId + m_startCol.value());
235 }
236
237 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const CoeffReturnType coeff(Index rowId, Index colId) const {
238 return m_xpr.coeff(rowId + m_startRow.value(), colId + m_startCol.value());
239 }
240
241 EIGEN_DEVICE_FUNC inline Scalar& coeffRef(Index index) {
242 EIGEN_STATIC_ASSERT_LVALUE(XprType)
243 return m_xpr.coeffRef(m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index),
244 m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0));
245 }
246
247 EIGEN_DEVICE_FUNC inline const Scalar& coeffRef(Index index) const {
248 return m_xpr.coeffRef(m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index),
249 m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0));
250 }
251
252 EIGEN_DEVICE_FUNC inline const CoeffReturnType coeff(Index index) const {
253 return m_xpr.coeff(m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index),
254 m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0));
255 }
256
257 template <int LoadMode>
258 EIGEN_DEVICE_FUNC inline PacketScalar packet(Index rowId, Index colId) const {
259 return m_xpr.template packet<Unaligned>(rowId + m_startRow.value(), colId + m_startCol.value());
260 }
261
262 template <int LoadMode>
263 EIGEN_DEVICE_FUNC inline void writePacket(Index rowId, Index colId, const PacketScalar& val) {
264 m_xpr.template writePacket<Unaligned>(rowId + m_startRow.value(), colId + m_startCol.value(), val);
265 }
266
267 template <int LoadMode>
268 EIGEN_DEVICE_FUNC inline PacketScalar packet(Index index) const {
269 return m_xpr.template packet<Unaligned>(m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index),
270 m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0));
271 }
272
273 template <int LoadMode>
274 EIGEN_DEVICE_FUNC inline void writePacket(Index index, const PacketScalar& val) {
275 m_xpr.template writePacket<Unaligned>(m_startRow.value() + (RowsAtCompileTime == 1 ? 0 : index),
276 m_startCol.value() + (RowsAtCompileTime == 1 ? index : 0), val);
277 }
278
279#ifdef EIGEN_PARSED_BY_DOXYGEN
281 EIGEN_DEVICE_FUNC inline const Scalar* data() const;
282 EIGEN_DEVICE_FUNC inline Index innerStride() const;
283 EIGEN_DEVICE_FUNC inline Index outerStride() const;
284#endif
285
286 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const internal::remove_all_t<XprTypeNested>& nestedExpression() const {
287 return m_xpr;
288 }
289
290 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE XprType& nestedExpression() { return m_xpr; }
291
292 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR StorageIndex startRow() const EIGEN_NOEXCEPT {
293 return m_startRow.value();
294 }
295
296 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR StorageIndex startCol() const EIGEN_NOEXCEPT {
297 return m_startCol.value();
298 }
299
300 protected:
301 XprTypeNested m_xpr;
302 const internal::variable_if_dynamic<StorageIndex, (XprType::RowsAtCompileTime == 1 && BlockRows == 1) ? 0 : Dynamic>
303 m_startRow;
304 const internal::variable_if_dynamic<StorageIndex, (XprType::ColsAtCompileTime == 1 && BlockCols == 1) ? 0 : Dynamic>
305 m_startCol;
306 const internal::variable_if_dynamic<StorageIndex, RowsAtCompileTime> m_blockRows;
307 const internal::variable_if_dynamic<StorageIndex, ColsAtCompileTime> m_blockCols;
308};
309
311template <typename XprType, int BlockRows, int BlockCols, bool InnerPanel>
312class BlockImpl_dense<XprType, BlockRows, BlockCols, InnerPanel, true>
313 : public MapBase<Block<XprType, BlockRows, BlockCols, InnerPanel>> {
314 typedef Block<XprType, BlockRows, BlockCols, InnerPanel> BlockType;
315 typedef typename internal::ref_selector<XprType>::non_const_type XprTypeNested;
316 enum { XprTypeIsRowMajor = (int(traits<XprType>::Flags) & RowMajorBit) != 0 };
317
321 template <typename Scalar>
322 EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR EIGEN_ALWAYS_INLINE static Scalar* add_to_nullable_pointer(Scalar* base,
323 Index offset) {
324 return base != nullptr ? base + offset : nullptr;
325 }
326
327 public:
328 typedef MapBase<BlockType> Base;
329 EIGEN_DENSE_PUBLIC_INTERFACE(BlockType)
330 EIGEN_INHERIT_ASSIGNMENT_OPERATORS(BlockImpl_dense)
331
332
334 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE BlockImpl_dense(XprType& xpr, Index i)
335 : Base((BlockRows == 0 || BlockCols == 0)
336 ? nullptr
337 : add_to_nullable_pointer(
338 xpr.data(),
339 i * (((BlockRows == 1) && (BlockCols == XprType::ColsAtCompileTime) && (!XprTypeIsRowMajor)) ||
340 ((BlockRows == XprType::RowsAtCompileTime) && (BlockCols == 1) &&
341 (XprTypeIsRowMajor))
342 ? xpr.innerStride()
343 : xpr.outerStride())),
344 BlockRows == 1 ? 1 : xpr.rows(), BlockCols == 1 ? 1 : xpr.cols()),
345 m_xpr(xpr),
346 m_startRow((BlockRows == 1) && (BlockCols == XprType::ColsAtCompileTime) ? i : 0),
347 m_startCol((BlockRows == XprType::RowsAtCompileTime) && (BlockCols == 1) ? i : 0) {
348 init();
349 }
350
353 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE BlockImpl_dense(XprType& xpr, Index startRow, Index startCol)
354 : Base((BlockRows == 0 || BlockCols == 0)
355 ? nullptr
356 : add_to_nullable_pointer(xpr.data(),
357 xpr.innerStride() * (XprTypeIsRowMajor ? startCol : startRow) +
358 xpr.outerStride() * (XprTypeIsRowMajor ? startRow : startCol))),
359 m_xpr(xpr),
360 m_startRow(startRow),
361 m_startCol(startCol) {
362 init();
363 }
364
367 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE BlockImpl_dense(XprType& xpr, Index startRow, Index startCol, Index blockRows,
368 Index blockCols)
369 : Base((blockRows == 0 || blockCols == 0)
370 ? nullptr
371 : add_to_nullable_pointer(xpr.data(),
372 xpr.innerStride() * (XprTypeIsRowMajor ? startCol : startRow) +
373 xpr.outerStride() * (XprTypeIsRowMajor ? startRow : startCol)),
374 blockRows, blockCols),
375 m_xpr(xpr),
376 m_startRow(startRow),
377 m_startCol(startCol) {
378 init();
379 }
380
381 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const internal::remove_all_t<XprTypeNested>& nestedExpression() const
382 EIGEN_NOEXCEPT {
383 return m_xpr;
384 }
385
386 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE XprType& nestedExpression() { return m_xpr; }
387
389 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR Index innerStride() const EIGEN_NOEXCEPT {
390 return internal::traits<BlockType>::HasSameStorageOrderAsXprType ? m_xpr.innerStride() : m_xpr.outerStride();
391 }
392
394 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR Index outerStride() const EIGEN_NOEXCEPT {
395 return internal::traits<BlockType>::HasSameStorageOrderAsXprType ? m_xpr.outerStride() : m_xpr.innerStride();
396 }
397
398 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR StorageIndex startRow() const EIGEN_NOEXCEPT {
399 return m_startRow.value();
400 }
401
402 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR StorageIndex startCol() const EIGEN_NOEXCEPT {
403 return m_startCol.value();
404 }
405
406#ifndef __SUNPRO_CC
407 // FIXME sunstudio is not friendly with the above friend...
408 // META-FIXME there is no 'friend' keyword around here. Is this obsolete?
409 protected:
410#endif
411
412#ifndef EIGEN_PARSED_BY_DOXYGEN
414 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE BlockImpl_dense(XprType& xpr, const Scalar* data, Index blockRows,
415 Index blockCols)
416 : Base(data, blockRows, blockCols), m_xpr(xpr) {
417 init();
418 }
419#endif
420
421 protected:
422 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void init() {
423 m_outerStride =
424 internal::traits<BlockType>::HasSameStorageOrderAsXprType ? m_xpr.outerStride() : m_xpr.innerStride();
425 }
426
427 XprTypeNested m_xpr;
428 const internal::variable_if_dynamic<StorageIndex, (XprType::RowsAtCompileTime == 1 && BlockRows == 1) ? 0 : Dynamic>
429 m_startRow;
430 const internal::variable_if_dynamic<StorageIndex, (XprType::ColsAtCompileTime == 1 && BlockCols == 1) ? 0 : Dynamic>
431 m_startCol;
432 Index m_outerStride;
433};
434
435} // end namespace internal
436
437} // end namespace Eigen
438
439#endif // EIGEN_BLOCK_H
Expression of a fixed-size or dynamic-size block.
Definition Block.h:110
Block(XprType &xpr, Index startRow, Index startCol)
Definition Block.h:131
Block(XprType &xpr, Index startRow, Index startCol, Index blockRows, Index blockCols)
Definition Block.h:141
Block(XprType &xpr, Index i)
Definition Block.h:124
const unsigned int DirectAccessBit
Definition Constants.h:159
const unsigned int LvalueBit
Definition Constants.h:148
const unsigned int RowMajorBit
Definition Constants.h:70
const unsigned int CompressedAccessBit
Definition Constants.h:195
Namespace containing all symbols from the Eigen library.
Definition Core:137
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition Meta.h:83
const int Dynamic
Definition Constants.h:25