Eigen  5.0.1
 
Loading...
Searching...
No Matches
BandMatrix.h
1// This file is part of Eigen, a lightweight C++ template library
2// for linear algebra.
3//
4// Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr>
5//
6// This Source Code Form is subject to the terms of the Mozilla
7// Public License v. 2.0. If a copy of the MPL was not distributed
8// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9// SPDX-License-Identifier: MPL-2.0
10
11#ifndef EIGEN_BANDMATRIX_H
12#define EIGEN_BANDMATRIX_H
13
14// IWYU pragma: private
15#include "./InternalHeaderCheck.h"
16
17namespace Eigen {
18
19namespace internal {
20
21template <typename Derived>
22class BandMatrixBase : public EigenBase<Derived> {
23 public:
24 enum {
25 Flags = internal::traits<Derived>::Flags,
26 CoeffReadCost = internal::traits<Derived>::CoeffReadCost,
27 RowsAtCompileTime = internal::traits<Derived>::RowsAtCompileTime,
28 ColsAtCompileTime = internal::traits<Derived>::ColsAtCompileTime,
29 MaxRowsAtCompileTime = internal::traits<Derived>::MaxRowsAtCompileTime,
30 MaxColsAtCompileTime = internal::traits<Derived>::MaxColsAtCompileTime,
31 Supers = internal::traits<Derived>::Supers,
32 Subs = internal::traits<Derived>::Subs,
33 Options = internal::traits<Derived>::Options
34 };
35 using Scalar = typename internal::traits<Derived>::Scalar;
36 using DenseMatrixType = Matrix<Scalar, RowsAtCompileTime, ColsAtCompileTime>;
37 using StorageIndex = typename DenseMatrixType::StorageIndex;
38 using CoefficientsType = typename internal::traits<Derived>::CoefficientsType;
39 using Base = EigenBase<Derived>;
40
41 protected:
42 enum {
43 DataRowsAtCompileTime = ((Supers != Dynamic) && (Subs != Dynamic)) ? 1 + Supers + Subs : Dynamic,
44 SizeAtCompileTime = min_size_prefer_dynamic(RowsAtCompileTime, ColsAtCompileTime)
45 };
46
47 public:
48 using Base::cols;
49 using Base::derived;
50 using Base::rows;
51
53 inline Index supers() const { return derived().supers(); }
54
56 inline Index subs() const { return derived().subs(); }
57
59 inline const CoefficientsType& coeffs() const { return derived().coeffs(); }
60
62 inline CoefficientsType& coeffs() { return derived().coeffs(); }
63
67 inline Block<CoefficientsType, Dynamic, 1> col(Index i) {
68 EIGEN_STATIC_ASSERT((int(Options) & int(RowMajor)) == 0, THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES);
69 Index start = 0;
70 Index len = coeffs().rows();
71 if (i <= supers()) {
72 start = supers() - i;
73 len = (std::min)(rows(), std::max<Index>(0, coeffs().rows() - (supers() - i)));
74 } else if (i >= rows() - subs())
75 len = std::max<Index>(0, coeffs().rows() - (i + 1 - rows() + subs()));
76 return Block<CoefficientsType, Dynamic, 1>(coeffs(), start, i, len, 1);
77 }
78
80 inline Block<CoefficientsType, 1, SizeAtCompileTime> diagonal() {
81 return Block<CoefficientsType, 1, SizeAtCompileTime>(coeffs(), supers(), 0, 1, (std::min)(rows(), cols()));
82 }
83
85 inline const Block<const CoefficientsType, 1, SizeAtCompileTime> diagonal() const {
86 return Block<const CoefficientsType, 1, SizeAtCompileTime>(coeffs(), supers(), 0, 1, (std::min)(rows(), cols()));
87 }
88
89 template <int Index>
90 struct DiagonalIntReturnType {
91 enum {
92 ReturnOpposite =
93 (int(Options) & int(SelfAdjoint)) && (((Index) > 0 && Supers == 0) || ((Index) < 0 && Subs == 0)),
94 Conjugate = ReturnOpposite && NumTraits<Scalar>::IsComplex,
95 ActualIndex = ReturnOpposite ? -Index : Index,
96 DiagonalSize =
97 (RowsAtCompileTime == Dynamic || ColsAtCompileTime == Dynamic)
98 ? Dynamic
99 : (ActualIndex < 0 ? min_size_prefer_dynamic(ColsAtCompileTime, RowsAtCompileTime + ActualIndex)
100 : min_size_prefer_dynamic(RowsAtCompileTime, ColsAtCompileTime - ActualIndex))
101 };
102 using BuildType = Block<CoefficientsType, 1, DiagonalSize>;
103 using Type =
104 std::conditional_t<Conjugate, CwiseUnaryOp<internal::scalar_conjugate_op<Scalar>, BuildType>, BuildType>;
105 };
106
108 template <int N>
109 inline typename DiagonalIntReturnType<N>::Type diagonal() {
110 return typename DiagonalIntReturnType<N>::BuildType(coeffs(), supers() - N, (std::max)(0, N), 1, diagonalLength(N));
111 }
112
114 template <int N>
115 inline const typename DiagonalIntReturnType<N>::Type diagonal() const {
116 return typename DiagonalIntReturnType<N>::BuildType(coeffs(), supers() - N, (std::max)(0, N), 1, diagonalLength(N));
117 }
118
120 inline Block<CoefficientsType, 1, Dynamic> diagonal(Index i) {
121 eigen_assert((i < 0 && -i <= subs()) || (i >= 0 && i <= supers()));
122 return Block<CoefficientsType, 1, Dynamic>(coeffs(), supers() - i, std::max<Index>(0, i), 1, diagonalLength(i));
123 }
124
126 inline const Block<const CoefficientsType, 1, Dynamic> diagonal(Index i) const {
127 eigen_assert((i < 0 && -i <= subs()) || (i >= 0 && i <= supers()));
128 return Block<const CoefficientsType, 1, Dynamic>(coeffs(), supers() - i, std::max<Index>(0, i), 1,
129 diagonalLength(i));
130 }
131
132 template <typename Dest>
133 inline void evalTo(Dest& dst) const {
134 dst.resize(rows(), cols());
135 dst.setZero();
136 dst.diagonal() = diagonal();
137 for (Index i = 1; i <= supers(); ++i) dst.diagonal(i) = diagonal(i);
138 for (Index i = 1; i <= subs(); ++i) dst.diagonal(-i) = diagonal(-i);
139 }
140
141 DenseMatrixType toDenseMatrix() const {
142 DenseMatrixType res(rows(), cols());
143 evalTo(res);
144 return res;
145 }
146
147 protected:
148 inline Index diagonalLength(Index i) const {
149 return i < 0 ? (std::min)(cols(), rows() + i) : (std::min)(rows(), cols() - i);
150 }
151};
152
171
172template <typename Scalar_, int Rows_, int Cols_, int Supers_, int Subs_, int Options_>
173struct traits<BandMatrix<Scalar_, Rows_, Cols_, Supers_, Subs_, Options_> > {
174 using Scalar = Scalar_;
175 using StorageKind = Dense;
176 using StorageIndex = Eigen::Index;
177 enum {
178 CoeffReadCost = NumTraits<Scalar>::ReadCost,
179 RowsAtCompileTime = Rows_,
180 ColsAtCompileTime = Cols_,
181 MaxRowsAtCompileTime = Rows_,
182 MaxColsAtCompileTime = Cols_,
183 Flags = LvalueBit,
184 Supers = Supers_,
185 Subs = Subs_,
186 Options = Options_,
187 DataRowsAtCompileTime = ((Supers != Dynamic) && (Subs != Dynamic)) ? 1 + Supers + Subs : Dynamic
188 };
189 using CoefficientsType =
190 Matrix<Scalar, DataRowsAtCompileTime, ColsAtCompileTime, int(Options) & int(RowMajor) ? RowMajor : ColMajor>;
191};
192
193template <typename Scalar_, int Rows, int Cols, int Supers, int Subs, int Options>
194class BandMatrix : public BandMatrixBase<BandMatrix<Scalar_, Rows, Cols, Supers, Subs, Options> > {
195 public:
196 using Scalar = typename internal::traits<BandMatrix>::Scalar;
197 using StorageIndex = typename internal::traits<BandMatrix>::StorageIndex;
198 using CoefficientsType = typename internal::traits<BandMatrix>::CoefficientsType;
199
200 explicit inline BandMatrix(Index rows = Rows, Index cols = Cols, Index supers = Supers, Index subs = Subs)
201 : m_coeffs(1 + supers + subs, cols), m_rows(rows), m_supers(supers), m_subs(subs) {}
202
204 constexpr Index rows() const { return m_rows.value(); }
205
207 constexpr Index cols() const { return m_coeffs.cols(); }
208
210 constexpr Index supers() const { return m_supers.value(); }
211
213 constexpr Index subs() const { return m_subs.value(); }
214
215 inline const CoefficientsType& coeffs() const { return m_coeffs; }
216 inline CoefficientsType& coeffs() { return m_coeffs; }
217
218 protected:
219 CoefficientsType m_coeffs;
220 internal::variable_if_dynamic<Index, Rows> m_rows;
221 internal::variable_if_dynamic<Index, Supers> m_supers;
222 internal::variable_if_dynamic<Index, Subs> m_subs;
223};
224
225template <typename CoefficientsType_, int Rows_, int Cols_, int Supers_, int Subs_, int Options_>
226class BandMatrixWrapper;
227
228template <typename CoefficientsType_, int Rows_, int Cols_, int Supers_, int Subs_, int Options_>
229struct traits<BandMatrixWrapper<CoefficientsType_, Rows_, Cols_, Supers_, Subs_, Options_> > {
230 using Scalar = typename CoefficientsType_::Scalar;
231 using StorageKind = typename CoefficientsType_::StorageKind;
232 using StorageIndex = typename CoefficientsType_::StorageIndex;
233 enum {
234 CoeffReadCost = internal::traits<CoefficientsType_>::CoeffReadCost,
235 RowsAtCompileTime = Rows_,
236 ColsAtCompileTime = Cols_,
237 MaxRowsAtCompileTime = Rows_,
238 MaxColsAtCompileTime = Cols_,
239 Flags = LvalueBit,
240 Supers = Supers_,
241 Subs = Subs_,
242 Options = Options_,
243 DataRowsAtCompileTime = ((Supers != Dynamic) && (Subs != Dynamic)) ? 1 + Supers + Subs : Dynamic
244 };
245 using CoefficientsType = CoefficientsType_;
246};
247
248template <typename CoefficientsType_, int Rows_, int Cols_, int Supers_, int Subs_, int Options_>
249class BandMatrixWrapper
250 : public BandMatrixBase<BandMatrixWrapper<CoefficientsType_, Rows_, Cols_, Supers_, Subs_, Options_> > {
251 public:
252 using Scalar = typename internal::traits<BandMatrixWrapper>::Scalar;
253 using CoefficientsType = typename internal::traits<BandMatrixWrapper>::CoefficientsType;
254 using StorageIndex = typename internal::traits<BandMatrixWrapper>::StorageIndex;
255
256 explicit inline BandMatrixWrapper(const CoefficientsType& coeffs, Index rows = Rows_, Index cols = Cols_,
257 Index supers = Supers_, Index subs = Subs_)
258 : m_coeffs(coeffs), m_rows(rows), m_supers(supers), m_subs(subs) {
259 EIGEN_UNUSED_VARIABLE(cols);
260 // eigen_assert(coeffs.cols()==cols() && (supers()+subs()+1)==coeffs.rows());
261 }
262
264 constexpr Index rows() const { return m_rows.value(); }
265
267 constexpr Index cols() const { return m_coeffs.cols(); }
268
270 constexpr Index supers() const { return m_supers.value(); }
271
273 constexpr Index subs() const { return m_subs.value(); }
274
275 inline const CoefficientsType& coeffs() const { return m_coeffs; }
276
277 protected:
278 const CoefficientsType& m_coeffs;
279 internal::variable_if_dynamic<Index, Rows_> m_rows;
280 internal::variable_if_dynamic<Index, Supers_> m_supers;
281 internal::variable_if_dynamic<Index, Subs_> m_subs;
282};
283
296template <typename Scalar, int Size, int Options>
297class TridiagonalMatrix : public BandMatrix<Scalar, Size, Size, Options & SelfAdjoint ? 0 : 1, 1, Options | RowMajor> {
298 using Base = BandMatrix<Scalar, Size, Size, Options & SelfAdjoint ? 0 : 1, 1, Options | RowMajor>;
299 using StorageIndex = typename Base::StorageIndex;
300
301 public:
302 explicit TridiagonalMatrix(Index size = Size) : Base(size, size, Options & SelfAdjoint ? 0 : 1, 1) {}
303
304 inline typename Base::template DiagonalIntReturnType<1>::Type super() { return Base::template diagonal<1>(); }
305 inline const typename Base::template DiagonalIntReturnType<1>::Type super() const {
306 return Base::template diagonal<1>();
307 }
308 inline typename Base::template DiagonalIntReturnType<-1>::Type sub() { return Base::template diagonal<-1>(); }
309 inline const typename Base::template DiagonalIntReturnType<-1>::Type sub() const {
310 return Base::template diagonal<-1>();
311 }
312};
313
314template <typename Scalar_, int Rows_, int Cols_, int Supers_, int Subs_, int Options_>
315struct evaluator_traits<BandMatrix<Scalar_, Rows_, Cols_, Supers_, Subs_, Options_> >
316 : public evaluator_traits_base<BandMatrix<Scalar_, Rows_, Cols_, Supers_, Subs_, Options_> > {
317 using Shape = BandShape;
318};
319
320template <typename CoefficientsType_, int Rows_, int Cols_, int Supers_, int Subs_, int Options_>
321struct evaluator_traits<BandMatrixWrapper<CoefficientsType_, Rows_, Cols_, Supers_, Subs_, Options_> >
322 : public evaluator_traits_base<BandMatrixWrapper<CoefficientsType_, Rows_, Cols_, Supers_, Subs_, Options_> > {
323 using Shape = BandShape;
324};
325
326template <>
327struct AssignmentKind<DenseShape, BandShape> {
328 using Kind = EigenBase2EigenBase;
329};
330
331} // end namespace internal
332
333} // end namespace Eigen
334
335#endif // EIGEN_BANDMATRIX_H
Represents a rectangular matrix with a banded storage.
Definition BandMatrix.h:194
constexpr Index cols() const
Definition BandMatrix.h:207
constexpr Index supers() const
Definition BandMatrix.h:210
constexpr Index subs() const
Definition BandMatrix.h:213
constexpr Index rows() const
Definition BandMatrix.h:204
@ SelfAdjoint
Definition Constants.h:228
@ ColMajor
Definition Constants.h:319
@ RowMajor
Definition Constants.h:321
constexpr unsigned int LvalueBit
Definition Constants.h:149
constexpr Index cols() const noexcept
Definition EigenBase.h:62
constexpr Derived & derived()
Definition EigenBase.h:50
constexpr Index rows() const noexcept
Definition EigenBase.h:60
constexpr Index size() const noexcept
Definition EigenBase.h:65
Eigen::Index Index
The interface type of indices.
Definition EigenBase.h:44