Eigen  5.0.1
 
Loading...
Searching...
No Matches
Diagonal.h
1// This file is part of Eigen, a lightweight C++ template library
2// for linear algebra.
3//
4// Copyright (C) 2007-2009 Benoit Jacob <jacob.benoit.1@gmail.com>
5// Copyright (C) 2009-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
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// SPDX-License-Identifier: MPL-2.0
11
12#ifndef EIGEN_DIAGONAL_H
13#define EIGEN_DIAGONAL_H
14
15// IWYU pragma: private
16#include "./InternalHeaderCheck.h"
17
18namespace Eigen {
19
38
39namespace internal {
40template <typename MatrixType, int DiagIndex>
41struct traits<Diagonal<MatrixType, DiagIndex> > : traits<MatrixType> {
42 using MatrixTypeNested = typename ref_selector<MatrixType>::type;
43 using MatrixTypeNested_ = std::remove_reference_t<MatrixTypeNested>;
44 using StorageKind = typename MatrixType::StorageKind;
45 enum {
46 RowsAtCompileTime = (int(DiagIndex) == DynamicIndex || int(MatrixType::SizeAtCompileTime) == Dynamic)
47 ? Dynamic
48 : (plain_enum_min(MatrixType::RowsAtCompileTime - plain_enum_max(-DiagIndex, 0),
49 MatrixType::ColsAtCompileTime - plain_enum_max(DiagIndex, 0))),
50 ColsAtCompileTime = 1,
51 MaxRowsAtCompileTime =
52 int(MatrixType::MaxSizeAtCompileTime) == Dynamic ? Dynamic
53 : DiagIndex == DynamicIndex
54 ? min_size_prefer_fixed(MatrixType::MaxRowsAtCompileTime, MatrixType::MaxColsAtCompileTime)
55 : (plain_enum_min(MatrixType::MaxRowsAtCompileTime - plain_enum_max(-DiagIndex, 0),
56 MatrixType::MaxColsAtCompileTime - plain_enum_max(DiagIndex, 0))),
57 MaxColsAtCompileTime = 1,
58 MaskLvalueBit = is_lvalue<MatrixType>::value ? LvalueBit : 0,
59 Flags = (unsigned int)MatrixTypeNested_::Flags &
60 (MaskLvalueBit | DirectAccessBit), // FIXME DirectAccessBit should not be handled by expressions
61 MatrixTypeOuterStride = outer_stride_at_compile_time<MatrixType>::value,
62 OuterStrideAtCompileTime = 0
63 };
64 static constexpr int MatrixTypeInnerStride = inner_stride_at_compile_time<MatrixType>::value;
65 static constexpr int InnerStrideAtCompileTime = MatrixTypeOuterStride == Dynamic || MatrixTypeInnerStride == Dynamic
66 ? Dynamic
67 : MatrixTypeOuterStride + MatrixTypeInnerStride;
68};
69
70template <typename MatrixType, int DiagIndex>
71constexpr int traits<Diagonal<MatrixType, DiagIndex>>::MatrixTypeInnerStride;
72
73template <typename MatrixType, int DiagIndex>
74constexpr int traits<Diagonal<MatrixType, DiagIndex>>::InnerStrideAtCompileTime;
75} // namespace internal
76
77template <typename MatrixType, int DiagIndex_>
78class Diagonal : public internal::dense_xpr_base<Diagonal<MatrixType, DiagIndex_> >::type {
79 public:
80 enum { DiagIndex = DiagIndex_ };
81 using Base = typename internal::dense_xpr_base<Diagonal>::type;
82 EIGEN_DENSE_PUBLIC_INTERFACE(Diagonal)
83
84 EIGEN_DEVICE_FUNC constexpr explicit inline Diagonal(MatrixType& matrix, Index a_index = DiagIndex)
85 : m_matrix(matrix), m_index(a_index) {
86 eigen_assert(a_index <= m_matrix.cols() && -a_index <= m_matrix.rows());
87 }
88
89 EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Diagonal)
90
91 EIGEN_DEVICE_FUNC constexpr inline Index rows() const {
92 return m_index.value() < 0 ? numext::mini<Index>(m_matrix.cols(), m_matrix.rows() + m_index.value())
93 : numext::mini<Index>(m_matrix.rows(), m_matrix.cols() - m_index.value());
94 }
95
96 EIGEN_DEVICE_FUNC constexpr Index cols() const noexcept { return 1; }
97
98 EIGEN_DEVICE_FUNC constexpr Index innerStride() const noexcept {
99 return m_matrix.outerStride() + m_matrix.innerStride();
100 }
101
102 EIGEN_DEVICE_FUNC constexpr Index outerStride() const noexcept { return 0; }
103
104 using ScalarWithConstIfNotLvalue = std::conditional_t<internal::is_lvalue<MatrixType>::value, Scalar, const Scalar>;
105
106 EIGEN_DEVICE_FUNC inline ScalarWithConstIfNotLvalue* data() {
107 return rows() > 0 ? &(m_matrix.coeffRef(rowOffset(), colOffset())) : nullptr;
108 }
109 EIGEN_DEVICE_FUNC inline const Scalar* data() const {
110 return rows() > 0 ? &(m_matrix.coeffRef(rowOffset(), colOffset())) : nullptr;
111 }
112
113 EIGEN_DEVICE_FUNC inline Scalar& coeffRef(Index row, Index) {
114 EIGEN_STATIC_ASSERT_LVALUE(MatrixType)
115 return m_matrix.coeffRef(row + rowOffset(), row + colOffset());
116 }
117
118 EIGEN_DEVICE_FUNC inline const Scalar& coeffRef(Index row, Index) const {
119 return m_matrix.coeffRef(row + rowOffset(), row + colOffset());
120 }
121
122 EIGEN_DEVICE_FUNC inline CoeffReturnType coeff(Index row, Index) const {
123 return m_matrix.coeff(row + rowOffset(), row + colOffset());
124 }
125
126 EIGEN_DEVICE_FUNC inline Scalar& coeffRef(Index idx) {
127 EIGEN_STATIC_ASSERT_LVALUE(MatrixType)
128 return m_matrix.coeffRef(idx + rowOffset(), idx + colOffset());
129 }
130
131 EIGEN_DEVICE_FUNC inline const Scalar& coeffRef(Index idx) const {
132 return m_matrix.coeffRef(idx + rowOffset(), idx + colOffset());
133 }
134
135 EIGEN_DEVICE_FUNC inline CoeffReturnType coeff(Index idx) const {
136 return m_matrix.coeff(idx + rowOffset(), idx + colOffset());
137 }
138
139 EIGEN_DEVICE_FUNC constexpr inline const internal::remove_all_t<typename MatrixType::Nested>& nestedExpression()
140 const {
141 return m_matrix;
142 }
143
144 EIGEN_DEVICE_FUNC constexpr inline Index index() const { return m_index.value(); }
145
146 protected:
147 typename internal::ref_selector<MatrixType>::non_const_type m_matrix;
148 const internal::variable_if_dynamicindex<Index, DiagIndex> m_index;
149
150 private:
151 // some compilers may fail to optimize std::max etc in case of compile-time constants...
152 EIGEN_DEVICE_FUNC constexpr Index rowOffset() const noexcept { return m_index.value() > 0 ? 0 : -m_index.value(); }
153 EIGEN_DEVICE_FUNC constexpr Index colOffset() const noexcept { return m_index.value() > 0 ? m_index.value() : 0; }
154 // trigger a compile-time error if someone try to call packet
155 template <int LoadMode>
156 typename MatrixType::PacketReturnType packet(Index) const;
157 template <int LoadMode>
158 typename MatrixType::PacketReturnType packet(Index, Index) const;
159};
160
169template <typename Derived>
170EIGEN_DEVICE_FUNC constexpr typename MatrixBase<Derived>::DiagonalReturnType MatrixBase<Derived>::diagonal() {
171 return DiagonalReturnType(derived());
172}
173
175template <typename Derived>
176EIGEN_DEVICE_FUNC constexpr const typename MatrixBase<Derived>::ConstDiagonalReturnType MatrixBase<Derived>::diagonal()
177 const {
178 return ConstDiagonalReturnType(derived());
179}
180
192template <typename Derived>
193EIGEN_DEVICE_FUNC constexpr Diagonal<Derived, DynamicIndex> MatrixBase<Derived>::diagonal(Index index) {
194 return Diagonal<Derived, DynamicIndex>(derived(), index);
195}
196
198template <typename Derived>
200 Index index) const {
202}
203
204/** \returns an expression of the \a DiagIndex-th sub or super diagonal of the matrix \c *this
205 *
206 * \c *this is not required to be square.
207 *
208 * The template parameter \a DiagIndex represent a super diagonal if \a DiagIndex > 0
209 * and a sub diagonal otherwise. \a DiagIndex == 0 is equivalent to the main diagonal.
210 *
211 * Example: \include MatrixBase_diagonal_template_int.cpp
212 * Output: \verbinclude MatrixBase_diagonal_template_int.out
214 * \sa MatrixBase::diagonal(), class Diagonal */
215template <typename Derived>
216template <int Index_>
218 return Diagonal<Derived, Index_>(derived());
219}
220
222template <typename Derived>
223template <int Index_>
224EIGEN_DEVICE_FUNC constexpr const Diagonal<const Derived, Index_> MatrixBase<Derived>::diagonal() const {
225 return Diagonal<const Derived, Index_>(derived());
226}
227
228} // end namespace Eigen
229
230#endif // EIGEN_DIAGONAL_H
Expression of a diagonal/subdiagonal/superdiagonal in a matrix.
Definition Diagonal.h:78
constexpr DiagonalReturnType diagonal()
Definition Diagonal.h:170
constexpr unsigned int DirectAccessBit
Definition Constants.h:160
constexpr unsigned int LvalueBit
Definition Constants.h:149