$darkmode
Eigen  5.0.1-dev
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 
10 #ifndef EIGEN_BANDMATRIX_H
11 #define EIGEN_BANDMATRIX_H
12 
13 // IWYU pragma: private
14 #include "./InternalHeaderCheck.h"
15 
16 namespace Eigen {
17 
18 namespace internal {
19 
20 template <typename Derived>
21 class BandMatrixBase : public EigenBase<Derived> {
22  public:
23  enum {
24  Flags = internal::traits<Derived>::Flags,
25  CoeffReadCost = internal::traits<Derived>::CoeffReadCost,
26  RowsAtCompileTime = internal::traits<Derived>::RowsAtCompileTime,
27  ColsAtCompileTime = internal::traits<Derived>::ColsAtCompileTime,
28  MaxRowsAtCompileTime = internal::traits<Derived>::MaxRowsAtCompileTime,
29  MaxColsAtCompileTime = internal::traits<Derived>::MaxColsAtCompileTime,
30  Supers = internal::traits<Derived>::Supers,
31  Subs = internal::traits<Derived>::Subs,
32  Options = internal::traits<Derived>::Options
33  };
34  typedef typename internal::traits<Derived>::Scalar Scalar;
35  typedef Matrix<Scalar, RowsAtCompileTime, ColsAtCompileTime> DenseMatrixType;
36  typedef typename DenseMatrixType::StorageIndex StorageIndex;
37  typedef typename internal::traits<Derived>::CoefficientsType CoefficientsType;
38  typedef EigenBase<Derived> Base;
39 
40  protected:
41  enum {
42  DataRowsAtCompileTime = ((Supers != Dynamic) && (Subs != Dynamic)) ? 1 + Supers + Subs : Dynamic,
43  SizeAtCompileTime = min_size_prefer_dynamic(RowsAtCompileTime, ColsAtCompileTime)
44  };
45 
46  public:
47  using Base::cols;
48  using Base::derived;
49  using Base::rows;
50 
52  inline Index supers() const { return derived().supers(); }
53 
55  inline Index subs() const { return derived().subs(); }
56 
58  inline const CoefficientsType& coeffs() const { return derived().coeffs(); }
59 
61  inline CoefficientsType& coeffs() { return derived().coeffs(); }
62 
66  inline Block<CoefficientsType, Dynamic, 1> col(Index i) {
67  EIGEN_STATIC_ASSERT((int(Options) & int(RowMajor)) == 0, THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES);
68  Index start = 0;
69  Index len = coeffs().rows();
70  if (i <= supers()) {
71  start = supers() - i;
72  len = (std::min)(rows(), std::max<Index>(0, coeffs().rows() - (supers() - i)));
73  } else if (i >= rows() - subs())
74  len = std::max<Index>(0, coeffs().rows() - (i + 1 - rows() + subs()));
75  return Block<CoefficientsType, Dynamic, 1>(coeffs(), start, i, len, 1);
76  }
77 
79  inline Block<CoefficientsType, 1, SizeAtCompileTime> diagonal() {
80  return Block<CoefficientsType, 1, SizeAtCompileTime>(coeffs(), supers(), 0, 1, (std::min)(rows(), cols()));
81  }
82 
84  inline const Block<const CoefficientsType, 1, SizeAtCompileTime> diagonal() const {
85  return Block<const CoefficientsType, 1, SizeAtCompileTime>(coeffs(), supers(), 0, 1, (std::min)(rows(), cols()));
86  }
87 
88  template <int Index>
89  struct DiagonalIntReturnType {
90  enum {
91  ReturnOpposite =
92  (int(Options) & int(SelfAdjoint)) && (((Index) > 0 && Supers == 0) || ((Index) < 0 && Subs == 0)),
93  Conjugate = ReturnOpposite && NumTraits<Scalar>::IsComplex,
94  ActualIndex = ReturnOpposite ? -Index : Index,
95  DiagonalSize =
96  (RowsAtCompileTime == Dynamic || ColsAtCompileTime == Dynamic)
97  ? Dynamic
98  : (ActualIndex < 0 ? min_size_prefer_dynamic(ColsAtCompileTime, RowsAtCompileTime + ActualIndex)
99  : min_size_prefer_dynamic(RowsAtCompileTime, ColsAtCompileTime - ActualIndex))
100  };
101  typedef Block<CoefficientsType, 1, DiagonalSize> BuildType;
102  typedef std::conditional_t<Conjugate, CwiseUnaryOp<internal::scalar_conjugate_op<Scalar>, BuildType>, BuildType>
103  Type;
104  };
105 
107  template <int N>
108  inline typename DiagonalIntReturnType<N>::Type diagonal() {
109  return typename DiagonalIntReturnType<N>::BuildType(coeffs(), supers() - N, (std::max)(0, N), 1, diagonalLength(N));
110  }
111 
113  template <int N>
114  inline const typename DiagonalIntReturnType<N>::Type diagonal() const {
115  return typename DiagonalIntReturnType<N>::BuildType(coeffs(), supers() - N, (std::max)(0, N), 1, diagonalLength(N));
116  }
117 
119  inline Block<CoefficientsType, 1, Dynamic> diagonal(Index i) {
120  eigen_assert((i < 0 && -i <= subs()) || (i >= 0 && i <= supers()));
121  return Block<CoefficientsType, 1, Dynamic>(coeffs(), supers() - i, std::max<Index>(0, i), 1, diagonalLength(i));
122  }
123 
125  inline const Block<const CoefficientsType, 1, Dynamic> diagonal(Index i) const {
126  eigen_assert((i < 0 && -i <= subs()) || (i >= 0 && i <= supers()));
127  return Block<const CoefficientsType, 1, Dynamic>(coeffs(), supers() - i, std::max<Index>(0, i), 1,
128  diagonalLength(i));
129  }
130 
131  template <typename Dest>
132  inline void evalTo(Dest& dst) const {
133  dst.resize(rows(), cols());
134  dst.setZero();
135  dst.diagonal() = diagonal();
136  for (Index i = 1; i <= supers(); ++i) dst.diagonal(i) = diagonal(i);
137  for (Index i = 1; i <= subs(); ++i) dst.diagonal(-i) = diagonal(-i);
138  }
139 
140  DenseMatrixType toDenseMatrix() const {
141  DenseMatrixType res(rows(), cols());
142  evalTo(res);
143  return res;
144  }
145 
146  protected:
147  inline Index diagonalLength(Index i) const {
148  return i < 0 ? (std::min)(cols(), rows() + i) : (std::min)(rows(), cols() - i);
149  }
150 };
151 
171 template <typename Scalar_, int Rows_, int Cols_, int Supers_, int Subs_, int Options_>
172 struct traits<BandMatrix<Scalar_, Rows_, Cols_, Supers_, Subs_, Options_> > {
173  typedef Scalar_ Scalar;
174  typedef Dense StorageKind;
175  typedef Eigen::Index StorageIndex;
176  enum {
177  CoeffReadCost = NumTraits<Scalar>::ReadCost,
178  RowsAtCompileTime = Rows_,
179  ColsAtCompileTime = Cols_,
180  MaxRowsAtCompileTime = Rows_,
181  MaxColsAtCompileTime = Cols_,
182  Flags = LvalueBit,
183  Supers = Supers_,
184  Subs = Subs_,
185  Options = Options_,
186  DataRowsAtCompileTime = ((Supers != Dynamic) && (Subs != Dynamic)) ? 1 + Supers + Subs : Dynamic
187  };
188  typedef Matrix<Scalar, DataRowsAtCompileTime, ColsAtCompileTime, int(Options) & int(RowMajor) ? RowMajor : ColMajor>
189  CoefficientsType;
190 };
191 
192 template <typename Scalar_, int Rows, int Cols, int Supers, int Subs, int Options>
193 class BandMatrix : public BandMatrixBase<BandMatrix<Scalar_, Rows, Cols, Supers, Subs, Options> > {
194  public:
195  typedef typename internal::traits<BandMatrix>::Scalar Scalar;
196  typedef typename internal::traits<BandMatrix>::StorageIndex StorageIndex;
197  typedef typename internal::traits<BandMatrix>::CoefficientsType CoefficientsType;
198 
199  explicit inline BandMatrix(Index rows = Rows, Index cols = Cols, Index supers = Supers, Index subs = Subs)
200  : m_coeffs(1 + supers + subs, cols), m_rows(rows), m_supers(supers), m_subs(subs) {}
201 
203  constexpr Index rows() const { return m_rows.value(); }
204 
206  constexpr Index cols() const { return m_coeffs.cols(); }
207 
209  constexpr Index supers() const { return m_supers.value(); }
210 
212  constexpr Index subs() const { return m_subs.value(); }
213 
214  inline const CoefficientsType& coeffs() const { return m_coeffs; }
215  inline CoefficientsType& coeffs() { return m_coeffs; }
216 
217  protected:
218  CoefficientsType m_coeffs;
219  internal::variable_if_dynamic<Index, Rows> m_rows;
220  internal::variable_if_dynamic<Index, Supers> m_supers;
221  internal::variable_if_dynamic<Index, Subs> m_subs;
222 };
223 
224 template <typename CoefficientsType_, int Rows_, int Cols_, int Supers_, int Subs_, int Options_>
225 class BandMatrixWrapper;
226 
227 template <typename CoefficientsType_, int Rows_, int Cols_, int Supers_, int Subs_, int Options_>
228 struct traits<BandMatrixWrapper<CoefficientsType_, Rows_, Cols_, Supers_, Subs_, Options_> > {
229  typedef typename CoefficientsType_::Scalar Scalar;
230  typedef typename CoefficientsType_::StorageKind StorageKind;
231  typedef typename CoefficientsType_::StorageIndex StorageIndex;
232  enum {
233  CoeffReadCost = internal::traits<CoefficientsType_>::CoeffReadCost,
234  RowsAtCompileTime = Rows_,
235  ColsAtCompileTime = Cols_,
236  MaxRowsAtCompileTime = Rows_,
237  MaxColsAtCompileTime = Cols_,
238  Flags = LvalueBit,
239  Supers = Supers_,
240  Subs = Subs_,
241  Options = Options_,
242  DataRowsAtCompileTime = ((Supers != Dynamic) && (Subs != Dynamic)) ? 1 + Supers + Subs : Dynamic
243  };
244  typedef CoefficientsType_ CoefficientsType;
245 };
246 
247 template <typename CoefficientsType_, int Rows_, int Cols_, int Supers_, int Subs_, int Options_>
248 class BandMatrixWrapper
249  : public BandMatrixBase<BandMatrixWrapper<CoefficientsType_, Rows_, Cols_, Supers_, Subs_, Options_> > {
250  public:
251  typedef typename internal::traits<BandMatrixWrapper>::Scalar Scalar;
252  typedef typename internal::traits<BandMatrixWrapper>::CoefficientsType CoefficientsType;
253  typedef typename internal::traits<BandMatrixWrapper>::StorageIndex StorageIndex;
254 
255  explicit inline BandMatrixWrapper(const CoefficientsType& coeffs, Index rows = Rows_, Index cols = Cols_,
256  Index supers = Supers_, Index subs = Subs_)
257  : m_coeffs(coeffs), m_rows(rows), m_supers(supers), m_subs(subs) {
258  EIGEN_UNUSED_VARIABLE(cols);
259  // eigen_assert(coeffs.cols()==cols() && (supers()+subs()+1)==coeffs.rows());
260  }
261 
263  constexpr Index rows() const { return m_rows.value(); }
264 
266  constexpr Index cols() const { return m_coeffs.cols(); }
267 
269  constexpr Index supers() const { return m_supers.value(); }
270 
272  constexpr Index subs() const { return m_subs.value(); }
273 
274  inline const CoefficientsType& coeffs() const { return m_coeffs; }
275 
276  protected:
277  const CoefficientsType& m_coeffs;
278  internal::variable_if_dynamic<Index, Rows_> m_rows;
279  internal::variable_if_dynamic<Index, Supers_> m_supers;
280  internal::variable_if_dynamic<Index, Subs_> m_subs;
281 };
282 
295 template <typename Scalar, int Size, int Options>
296 class TridiagonalMatrix : public BandMatrix<Scalar, Size, Size, Options & SelfAdjoint ? 0 : 1, 1, Options | RowMajor> {
298  typedef typename Base::StorageIndex StorageIndex;
299 
300  public:
301  explicit TridiagonalMatrix(Index size = Size) : Base(size, size, Options & SelfAdjoint ? 0 : 1, 1) {}
302 
303  inline typename Base::template DiagonalIntReturnType<1>::Type super() { return Base::template diagonal<1>(); }
304  inline const typename Base::template DiagonalIntReturnType<1>::Type super() const {
305  return Base::template diagonal<1>();
306  }
307  inline typename Base::template DiagonalIntReturnType<-1>::Type sub() { return Base::template diagonal<-1>(); }
308  inline const typename Base::template DiagonalIntReturnType<-1>::Type sub() const {
309  return Base::template diagonal<-1>();
310  }
311 
312  protected:
313 };
314 
315 struct BandShape {};
316 
317 template <typename Scalar_, int Rows_, int Cols_, int Supers_, int Subs_, int Options_>
318 struct evaluator_traits<BandMatrix<Scalar_, Rows_, Cols_, Supers_, Subs_, Options_> >
319  : public evaluator_traits_base<BandMatrix<Scalar_, Rows_, Cols_, Supers_, Subs_, Options_> > {
320  typedef BandShape Shape;
321 };
322 
323 template <typename CoefficientsType_, int Rows_, int Cols_, int Supers_, int Subs_, int Options_>
324 struct evaluator_traits<BandMatrixWrapper<CoefficientsType_, Rows_, Cols_, Supers_, Subs_, Options_> >
325  : public evaluator_traits_base<BandMatrixWrapper<CoefficientsType_, Rows_, Cols_, Supers_, Subs_, Options_> > {
326  typedef BandShape Shape;
327 };
328 
329 template <>
330 struct AssignmentKind<DenseShape, BandShape> {
331  typedef EigenBase2EigenBase Kind;
332 };
333 
334 } // end namespace internal
335 
336 } // end namespace Eigen
337 
338 #endif // EIGEN_BANDMATRIX_H
constexpr Index rows() const
Definition: BandMatrix.h:203
const unsigned int LvalueBit
Definition: Constants.h:148
Represents a rectangular matrix with a banded storage.
Definition: BandMatrix.h:193
Namespace containing all symbols from the Eigen library.
Definition: B01_Experimental.dox:1
Eigen::Index Index
The interface type of indices.
Definition: EigenBase.h:43
constexpr Index rows() const noexcept
Definition: EigenBase.h:59
Definition: EigenBase.h:33
constexpr Index cols() const noexcept
Definition: EigenBase.h:61
constexpr Index cols() const
Definition: BandMatrix.h:206
Represents a tridiagonal matrix with a compact banded storage.
Definition: BandMatrix.h:296
constexpr Index subs() const
Definition: BandMatrix.h:212
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:82
constexpr Derived & derived()
Definition: EigenBase.h:49
Definition: Constants.h:227
Definition: Constants.h:320
constexpr Index supers() const
Definition: BandMatrix.h:209
const int Dynamic
Definition: Constants.h:25