BandMatrix.h
Go to the documentation of this file.
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 #include "./InternalHeaderCheck.h"
14 
15 namespace Eigen {
16 
17 namespace internal {
18 
19 template<typename Derived>
20 class BandMatrixBase : public EigenBase<Derived>
21 {
22  public:
23 
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  typedef typename internal::traits<Derived>::Scalar Scalar;
36  typedef Matrix<Scalar,RowsAtCompileTime,ColsAtCompileTime> DenseMatrixType;
37  typedef typename DenseMatrixType::StorageIndex StorageIndex;
38  typedef typename internal::traits<Derived>::CoefficientsType CoefficientsType;
39  typedef EigenBase<Derived> Base;
40 
41  protected:
42  enum {
43  DataRowsAtCompileTime = ((Supers!=Dynamic) && (Subs!=Dynamic))
44  ? 1 + Supers + Subs
45  : Dynamic,
46  SizeAtCompileTime = min_size_prefer_dynamic(RowsAtCompileTime,ColsAtCompileTime)
47  };
48 
49  public:
50 
51  using Base::derived;
52  using Base::rows;
53  using Base::cols;
54 
56  inline Index supers() const { return derived().supers(); }
57 
59  inline Index subs() const { return derived().subs(); }
60 
62  inline const CoefficientsType& coeffs() const { return derived().coeffs(); }
63 
65  inline CoefficientsType& coeffs() { return derived().coeffs(); }
66 
70  inline Block<CoefficientsType,Dynamic,1> col(Index i)
71  {
72  EIGEN_STATIC_ASSERT((int(Options) & int(RowMajor)) == 0, THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES);
73  Index start = 0;
74  Index len = coeffs().rows();
75  if (i<=supers())
76  {
77  start = supers()-i;
78  len = (std::min)(rows(),std::max<Index>(0,coeffs().rows() - (supers()-i)));
79  }
80  else if (i>=rows()-subs())
81  len = std::max<Index>(0,coeffs().rows() - (i + 1 - rows() + subs()));
82  return Block<CoefficientsType,Dynamic,1>(coeffs(), start, i, len, 1);
83  }
84 
86  inline Block<CoefficientsType,1,SizeAtCompileTime> diagonal()
87  { return Block<CoefficientsType,1,SizeAtCompileTime>(coeffs(),supers(),0,1,(std::min)(rows(),cols())); }
88 
90  inline const Block<const CoefficientsType,1,SizeAtCompileTime> diagonal() const
91  { return Block<const CoefficientsType,1,SizeAtCompileTime>(coeffs(),supers(),0,1,(std::min)(rows(),cols())); }
92 
93  template<int Index> struct DiagonalIntReturnType {
94  enum {
95  ReturnOpposite = (int(Options) & int(SelfAdjoint)) && (((Index) > 0 && Supers == 0) || ((Index) < 0 && Subs == 0)),
96  Conjugate = ReturnOpposite && NumTraits<Scalar>::IsComplex,
97  ActualIndex = ReturnOpposite ? -Index : Index,
98  DiagonalSize = (RowsAtCompileTime==Dynamic || ColsAtCompileTime==Dynamic)
99  ? Dynamic
100  : (ActualIndex<0
101  ? min_size_prefer_dynamic(ColsAtCompileTime, RowsAtCompileTime + ActualIndex)
102  : min_size_prefer_dynamic(RowsAtCompileTime, ColsAtCompileTime - ActualIndex))
103  };
104  typedef Block<CoefficientsType,1, DiagonalSize> BuildType;
105  typedef std::conditional_t<Conjugate,
106  CwiseUnaryOp<internal::scalar_conjugate_op<Scalar>,BuildType >,
107  BuildType> Type;
108  };
109 
111  template<int N> inline typename DiagonalIntReturnType<N>::Type diagonal()
112  {
113  return typename DiagonalIntReturnType<N>::BuildType(coeffs(), supers()-N, (std::max)(0,N), 1, diagonalLength(N));
114  }
115 
117  template<int N> inline const typename DiagonalIntReturnType<N>::Type diagonal() const
118  {
119  return typename DiagonalIntReturnType<N>::BuildType(coeffs(), supers()-N, (std::max)(0,N), 1, diagonalLength(N));
120  }
121 
123  inline Block<CoefficientsType,1,Dynamic> diagonal(Index i)
124  {
125  eigen_assert((i<0 && -i<=subs()) || (i>=0 && i<=supers()));
126  return Block<CoefficientsType,1,Dynamic>(coeffs(), supers()-i, std::max<Index>(0,i), 1, diagonalLength(i));
127  }
128 
130  inline const Block<const CoefficientsType,1,Dynamic> diagonal(Index i) const
131  {
132  eigen_assert((i<0 && -i<=subs()) || (i>=0 && i<=supers()));
133  return Block<const CoefficientsType,1,Dynamic>(coeffs(), supers()-i, std::max<Index>(0,i), 1, diagonalLength(i));
134  }
135 
136  template<typename Dest> inline void evalTo(Dest& dst) const
137  {
138  dst.resize(rows(),cols());
139  dst.setZero();
140  dst.diagonal() = diagonal();
141  for (Index i=1; i<=supers();++i)
142  dst.diagonal(i) = diagonal(i);
143  for (Index i=1; i<=subs();++i)
144  dst.diagonal(-i) = diagonal(-i);
145  }
146 
147  DenseMatrixType toDenseMatrix() const
148  {
149  DenseMatrixType res(rows(),cols());
150  evalTo(res);
151  return res;
152  }
153 
154  protected:
155 
156  inline Index diagonalLength(Index i) const
157  { return i<0 ? (std::min)(cols(),rows()+i) : (std::min)(rows(),cols()-i); }
158 };
159 
179 template<typename Scalar_, int Rows_, int Cols_, int Supers_, int Subs_, int Options_>
180 struct traits<BandMatrix<Scalar_,Rows_,Cols_,Supers_,Subs_,Options_> >
181 {
182  typedef Scalar_ Scalar;
183  typedef Dense StorageKind;
184  typedef Eigen::Index StorageIndex;
185  enum {
186  CoeffReadCost = NumTraits<Scalar>::ReadCost,
187  RowsAtCompileTime = Rows_,
188  ColsAtCompileTime = Cols_,
189  MaxRowsAtCompileTime = Rows_,
190  MaxColsAtCompileTime = Cols_,
191  Flags = LvalueBit,
192  Supers = Supers_,
193  Subs = Subs_,
194  Options = Options_,
195  DataRowsAtCompileTime = ((Supers!=Dynamic) && (Subs!=Dynamic)) ? 1 + Supers + Subs : Dynamic
196  };
197  typedef Matrix<Scalar, DataRowsAtCompileTime, ColsAtCompileTime, int(Options) & int(RowMajor) ? RowMajor : ColMajor> CoefficientsType;
198 };
199 
200 template<typename Scalar_, int Rows, int Cols, int Supers, int Subs, int Options>
201 class BandMatrix : public BandMatrixBase<BandMatrix<Scalar_,Rows,Cols,Supers,Subs,Options> >
202 {
203  public:
204 
205  typedef typename internal::traits<BandMatrix>::Scalar Scalar;
206  typedef typename internal::traits<BandMatrix>::StorageIndex StorageIndex;
207  typedef typename internal::traits<BandMatrix>::CoefficientsType CoefficientsType;
208 
209  explicit inline BandMatrix(Index rows=Rows, Index cols=Cols, Index supers=Supers, Index subs=Subs)
210  : m_coeffs(1+supers+subs,cols),
211  m_rows(rows), m_supers(supers), m_subs(subs)
212  {
213  }
214 
216  inline EIGEN_CONSTEXPR Index rows() const { return m_rows.value(); }
217 
219  inline EIGEN_CONSTEXPR Index cols() const { return m_coeffs.cols(); }
220 
222  inline EIGEN_CONSTEXPR Index supers() const { return m_supers.value(); }
223 
225  inline EIGEN_CONSTEXPR Index subs() const { return m_subs.value(); }
226 
227  inline const CoefficientsType& coeffs() const { return m_coeffs; }
228  inline CoefficientsType& coeffs() { return m_coeffs; }
229 
230  protected:
231 
232  CoefficientsType m_coeffs;
233  internal::variable_if_dynamic<Index, Rows> m_rows;
234  internal::variable_if_dynamic<Index, Supers> m_supers;
235  internal::variable_if_dynamic<Index, Subs> m_subs;
236 };
237 
238 template<typename CoefficientsType_,int Rows_, int Cols_, int Supers_, int Subs_,int Options_>
239 class BandMatrixWrapper;
240 
241 template<typename CoefficientsType_,int Rows_, int Cols_, int Supers_, int Subs_,int Options_>
242 struct traits<BandMatrixWrapper<CoefficientsType_,Rows_,Cols_,Supers_,Subs_,Options_> >
243 {
244  typedef typename CoefficientsType_::Scalar Scalar;
245  typedef typename CoefficientsType_::StorageKind StorageKind;
246  typedef typename CoefficientsType_::StorageIndex StorageIndex;
247  enum {
248  CoeffReadCost = internal::traits<CoefficientsType_>::CoeffReadCost,
249  RowsAtCompileTime = Rows_,
250  ColsAtCompileTime = Cols_,
251  MaxRowsAtCompileTime = Rows_,
252  MaxColsAtCompileTime = Cols_,
253  Flags = LvalueBit,
254  Supers = Supers_,
255  Subs = Subs_,
256  Options = Options_,
257  DataRowsAtCompileTime = ((Supers!=Dynamic) && (Subs!=Dynamic)) ? 1 + Supers + Subs : Dynamic
258  };
259  typedef CoefficientsType_ CoefficientsType;
260 };
261 
262 template<typename CoefficientsType_,int Rows_, int Cols_, int Supers_, int Subs_,int Options_>
263 class BandMatrixWrapper : public BandMatrixBase<BandMatrixWrapper<CoefficientsType_,Rows_,Cols_,Supers_,Subs_,Options_> >
264 {
265  public:
266 
267  typedef typename internal::traits<BandMatrixWrapper>::Scalar Scalar;
268  typedef typename internal::traits<BandMatrixWrapper>::CoefficientsType CoefficientsType;
269  typedef typename internal::traits<BandMatrixWrapper>::StorageIndex StorageIndex;
270 
271  explicit inline BandMatrixWrapper(const CoefficientsType& coeffs, Index rows=Rows_, Index cols=Cols_, Index supers=Supers_, Index subs=Subs_)
272  : m_coeffs(coeffs),
273  m_rows(rows), m_supers(supers), m_subs(subs)
274  {
276  // eigen_assert(coeffs.cols()==cols() && (supers()+subs()+1)==coeffs.rows());
277  }
278 
280  inline EIGEN_CONSTEXPR Index rows() const { return m_rows.value(); }
281 
283  inline EIGEN_CONSTEXPR Index cols() const { return m_coeffs.cols(); }
284 
286  inline EIGEN_CONSTEXPR Index supers() const { return m_supers.value(); }
287 
289  inline EIGEN_CONSTEXPR Index subs() const { return m_subs.value(); }
290 
291  inline const CoefficientsType& coeffs() const { return m_coeffs; }
292 
293  protected:
294 
295  const CoefficientsType& m_coeffs;
296  internal::variable_if_dynamic<Index, Rows_> m_rows;
297  internal::variable_if_dynamic<Index, Supers_> m_supers;
298  internal::variable_if_dynamic<Index, Subs_> m_subs;
299 };
300 
313 template<typename Scalar, int Size, int Options>
314 class TridiagonalMatrix : public BandMatrix<Scalar,Size,Size,Options&SelfAdjoint?0:1,1,Options|RowMajor>
315 {
316  typedef BandMatrix<Scalar,Size,Size,Options&SelfAdjoint?0:1,1,Options|RowMajor> Base;
317  typedef typename Base::StorageIndex StorageIndex;
318  public:
319  explicit TridiagonalMatrix(Index size = Size) : Base(size,size,Options&SelfAdjoint?0:1,1) {}
320 
321  inline typename Base::template DiagonalIntReturnType<1>::Type super()
322  { return Base::template diagonal<1>(); }
323  inline const typename Base::template DiagonalIntReturnType<1>::Type super() const
324  { return Base::template diagonal<1>(); }
325  inline typename Base::template DiagonalIntReturnType<-1>::Type sub()
326  { return Base::template diagonal<-1>(); }
327  inline const typename Base::template DiagonalIntReturnType<-1>::Type sub() const
328  { return Base::template diagonal<-1>(); }
329  protected:
330 };
331 
332 
333 struct BandShape {};
334 
335 template<typename Scalar_, int Rows_, int Cols_, int Supers_, int Subs_, int Options_>
336 struct evaluator_traits<BandMatrix<Scalar_,Rows_,Cols_,Supers_,Subs_,Options_> >
337  : public evaluator_traits_base<BandMatrix<Scalar_,Rows_,Cols_,Supers_,Subs_,Options_> >
338 {
339  typedef BandShape Shape;
340 };
341 
342 template<typename CoefficientsType_,int Rows_, int Cols_, int Supers_, int Subs_,int Options_>
343 struct evaluator_traits<BandMatrixWrapper<CoefficientsType_,Rows_,Cols_,Supers_,Subs_,Options_> >
344  : public evaluator_traits_base<BandMatrixWrapper<CoefficientsType_,Rows_,Cols_,Supers_,Subs_,Options_> >
345 {
346  typedef BandShape Shape;
347 };
348 
349 template<> struct AssignmentKind<DenseShape,BandShape> { typedef EigenBase2EigenBase Kind; };
350 
351 } // end namespace internal
352 
353 } // end namespace Eigen
354 
355 #endif // EIGEN_BANDMATRIX_H
ColXpr col(Index i)
This is the const version of col().
#define EIGEN_CONSTEXPR
Definition: Macros.h:747
#define EIGEN_UNUSED_VARIABLE(var)
Definition: Macros.h:957
#define eigen_assert(x)
Definition: Macros.h:902
cout<< "Here is the matrix m:"<< endl<< m<< endl;Matrix< ptrdiff_t, 3, 1 > res
#define EIGEN_STATIC_ASSERT(X, MSG)
Definition: StaticAssert.h:26
internal::traits< Derived >::StorageIndex StorageIndex
The type used to store indices.
Definition: DenseBase.h:58
@ SelfAdjoint
Definition: Constants.h:227
@ ColMajor
Definition: Constants.h:321
@ RowMajor
Definition: Constants.h:323
const unsigned int LvalueBit
Definition: Constants.h:146
bfloat16() max(const bfloat16 &a, const bfloat16 &b)
Definition: BFloat16.h:690
bfloat16() min(const bfloat16 &a, const bfloat16 &b)
Definition: BFloat16.h:684
constexpr int min_size_prefer_dynamic(A a, B b)
Definition: Meta.h:537
: InteropHeaders
Definition: Core:139
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:82
const int Dynamic
Definition: Constants.h:24
Derived & derived()
Definition: EigenBase.h:48
EIGEN_CONSTEXPR Index cols() const EIGEN_NOEXCEPT
Definition: EigenBase.h:65
EIGEN_CONSTEXPR Index rows() const EIGEN_NOEXCEPT
Definition: EigenBase.h:62