Eigen  5.0.1-dev+60122df6
 
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 <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// 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 constexpr 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 constexpr StorageIndex startRow() const noexcept { return m_startRow.value(); }
293
294 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr StorageIndex startCol() const noexcept { return m_startCol.value(); }
295
296 protected:
297 XprTypeNested m_xpr;
298 const internal::variable_if_dynamic<StorageIndex, (XprType::RowsAtCompileTime == 1 && BlockRows == 1) ? 0 : Dynamic>
299 m_startRow;
300 const internal::variable_if_dynamic<StorageIndex, (XprType::ColsAtCompileTime == 1 && BlockCols == 1) ? 0 : Dynamic>
301 m_startCol;
302 const internal::variable_if_dynamic<StorageIndex, RowsAtCompileTime> m_blockRows;
303 const internal::variable_if_dynamic<StorageIndex, ColsAtCompileTime> m_blockCols;
304};
305
307template <typename XprType, int BlockRows, int BlockCols, bool InnerPanel>
308class BlockImpl_dense<XprType, BlockRows, BlockCols, InnerPanel, true>
309 : public MapBase<Block<XprType, BlockRows, BlockCols, InnerPanel>> {
310 typedef Block<XprType, BlockRows, BlockCols, InnerPanel> BlockType;
311 typedef typename internal::ref_selector<XprType>::non_const_type XprTypeNested;
312 enum { XprTypeIsRowMajor = (int(traits<XprType>::Flags) & RowMajorBit) != 0 };
313
317 template <typename Scalar>
318 EIGEN_DEVICE_FUNC constexpr EIGEN_ALWAYS_INLINE static Scalar* add_to_nullable_pointer(Scalar* base, Index offset) {
319 return base != nullptr ? base + offset : nullptr;
320 }
321
322 public:
323 typedef MapBase<BlockType> Base;
324 EIGEN_DENSE_PUBLIC_INTERFACE(BlockType)
325 EIGEN_INHERIT_ASSIGNMENT_OPERATORS(BlockImpl_dense)
326
327
329 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE BlockImpl_dense(XprType& xpr, Index i)
330 : Base((BlockRows == 0 || BlockCols == 0)
331 ? nullptr
332 : add_to_nullable_pointer(
333 xpr.data(),
334 i * (((BlockRows == 1) && (BlockCols == XprType::ColsAtCompileTime) && (!XprTypeIsRowMajor)) ||
335 ((BlockRows == XprType::RowsAtCompileTime) && (BlockCols == 1) &&
336 (XprTypeIsRowMajor))
337 ? xpr.innerStride()
338 : xpr.outerStride())),
339 BlockRows == 1 ? 1 : xpr.rows(), BlockCols == 1 ? 1 : xpr.cols()),
340 m_xpr(xpr),
341 m_startRow((BlockRows == 1) && (BlockCols == XprType::ColsAtCompileTime) ? i : 0),
342 m_startCol((BlockRows == XprType::RowsAtCompileTime) && (BlockCols == 1) ? i : 0) {
343 init();
344 }
345
348 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE BlockImpl_dense(XprType& xpr, Index startRow, Index startCol)
349 : Base((BlockRows == 0 || BlockCols == 0)
350 ? nullptr
351 : add_to_nullable_pointer(xpr.data(),
352 xpr.innerStride() * (XprTypeIsRowMajor ? startCol : startRow) +
353 xpr.outerStride() * (XprTypeIsRowMajor ? startRow : startCol))),
354 m_xpr(xpr),
355 m_startRow(startRow),
356 m_startCol(startCol) {
357 init();
358 }
359
362 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE BlockImpl_dense(XprType& xpr, Index startRow, Index startCol, Index blockRows,
363 Index blockCols)
364 : Base((blockRows == 0 || blockCols == 0)
365 ? nullptr
366 : add_to_nullable_pointer(xpr.data(),
367 xpr.innerStride() * (XprTypeIsRowMajor ? startCol : startRow) +
368 xpr.outerStride() * (XprTypeIsRowMajor ? startRow : startCol)),
369 blockRows, blockCols),
370 m_xpr(xpr),
371 m_startRow(startRow),
372 m_startCol(startCol) {
373 init();
374 }
375
376 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const internal::remove_all_t<XprTypeNested>& nestedExpression() const noexcept {
377 return m_xpr;
378 }
379
380 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE XprType& nestedExpression() { return m_xpr; }
381
383 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr Index innerStride() const noexcept {
384 return internal::traits<BlockType>::HasSameStorageOrderAsXprType ? m_xpr.innerStride() : m_xpr.outerStride();
385 }
386
388 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr Index outerStride() const noexcept {
389 return internal::traits<BlockType>::HasSameStorageOrderAsXprType ? m_xpr.outerStride() : m_xpr.innerStride();
390 }
391
392 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr StorageIndex startRow() const noexcept { return m_startRow.value(); }
393
394 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE constexpr StorageIndex startCol() const noexcept { return m_startCol.value(); }
395
396#ifndef __SUNPRO_CC
397 // FIXME sunstudio is not friendly with the above friend...
398 // META-FIXME there is no 'friend' keyword around here. Is this obsolete?
399 protected:
400#endif
401
402#ifndef EIGEN_PARSED_BY_DOXYGEN
404 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE BlockImpl_dense(XprType& xpr, const Scalar* data, Index blockRows,
405 Index blockCols)
406 : Base(data, blockRows, blockCols), m_xpr(xpr) {
407 init();
408 }
409#endif
410
411 protected:
412 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE void init() {
413 m_outerStride =
414 internal::traits<BlockType>::HasSameStorageOrderAsXprType ? m_xpr.outerStride() : m_xpr.innerStride();
415 }
416
417 XprTypeNested m_xpr;
418 const internal::variable_if_dynamic<StorageIndex, (XprType::RowsAtCompileTime == 1 && BlockRows == 1) ? 0 : Dynamic>
419 m_startRow;
420 const internal::variable_if_dynamic<StorageIndex, (XprType::ColsAtCompileTime == 1 && BlockCols == 1) ? 0 : Dynamic>
421 m_startCol;
422 Index m_outerStride;
423};
424
425} // end namespace internal
426
427} // end namespace Eigen
428
429#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 B01_Experimental.dox:1
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition Meta.h:82
const int Dynamic
Definition Constants.h:25