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 // Eigen is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 3 of the License, or (at your option) any later version.
10 //
11 // Alternatively, you can redistribute it and/or
12 // modify it under the terms of the GNU General Public License as
13 // published by the Free Software Foundation; either version 2 of
14 // the License, or (at your option) any later version.
15 //
16 // Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
17 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
19 // GNU General Public License for more details.
20 //
21 // You should have received a copy of the GNU Lesser General Public
22 // License and a copy of the GNU General Public License along with
23 // Eigen. If not, see <http://www.gnu.org/licenses/>.
24 
25 #ifndef EIGEN_BANDMATRIX_H
26 #define EIGEN_BANDMATRIX_H
27 
28 namespace Eigen {
29 
30 namespace internal {
31 
32 template<typename Derived>
33 class BandMatrixBase : public EigenBase<Derived>
34 {
35  public:
36 
37  enum {
38  Flags = internal::traits<Derived>::Flags,
39  CoeffReadCost = internal::traits<Derived>::CoeffReadCost,
40  RowsAtCompileTime = internal::traits<Derived>::RowsAtCompileTime,
41  ColsAtCompileTime = internal::traits<Derived>::ColsAtCompileTime,
42  MaxRowsAtCompileTime = internal::traits<Derived>::MaxRowsAtCompileTime,
43  MaxColsAtCompileTime = internal::traits<Derived>::MaxColsAtCompileTime,
44  Supers = internal::traits<Derived>::Supers,
45  Subs = internal::traits<Derived>::Subs,
46  Options = internal::traits<Derived>::Options
47  };
48  typedef typename internal::traits<Derived>::Scalar Scalar;
49  typedef Matrix<Scalar,RowsAtCompileTime,ColsAtCompileTime> DenseMatrixType;
50  typedef typename DenseMatrixType::Index Index;
51  typedef typename internal::traits<Derived>::CoefficientsType CoefficientsType;
52  typedef EigenBase<Derived> Base;
53 
54  protected:
55  enum {
56  DataRowsAtCompileTime = ((Supers!=Dynamic) && (Subs!=Dynamic))
57  ? 1 + Supers + Subs
58  : Dynamic,
59  SizeAtCompileTime = EIGEN_SIZE_MIN_PREFER_DYNAMIC(RowsAtCompileTime,ColsAtCompileTime)
60  };
61 
62  public:
63 
64  using Base::derived;
65  using Base::rows;
66  using Base::cols;
67 
69  inline Index supers() const { return derived().supers(); }
70 
72  inline Index subs() const { return derived().subs(); }
73 
75  inline const CoefficientsType& coeffs() const { return derived().coeffs(); }
76 
78  inline CoefficientsType& coeffs() { return derived().coeffs(); }
79 
83  inline Block<CoefficientsType,Dynamic,1> col(Index i)
84  {
85  EIGEN_STATIC_ASSERT((Options&RowMajor)==0,THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES);
86  Index start = 0;
87  Index len = coeffs().rows();
88  if (i<=supers())
89  {
90  start = supers()-i;
91  len = (std::min)(rows(),std::max<Index>(0,coeffs().rows() - (supers()-i)));
92  }
93  else if (i>=rows()-subs())
94  len = std::max<Index>(0,coeffs().rows() - (i + 1 - rows() + subs()));
95  return Block<CoefficientsType,Dynamic,1>(coeffs(), start, i, len, 1);
96  }
97 
99  inline Block<CoefficientsType,1,SizeAtCompileTime> diagonal()
100  { return Block<CoefficientsType,1,SizeAtCompileTime>(coeffs(),supers(),0,1,(std::min)(rows(),cols())); }
101 
103  inline const Block<const CoefficientsType,1,SizeAtCompileTime> diagonal() const
104  { return Block<const CoefficientsType,1,SizeAtCompileTime>(coeffs(),supers(),0,1,(std::min)(rows(),cols())); }
105 
106  template<int Index> struct DiagonalIntReturnType {
107  enum {
108  ReturnOpposite = (Options&SelfAdjoint) && (((Index)>0 && Supers==0) || ((Index)<0 && Subs==0)),
109  Conjugate = ReturnOpposite && NumTraits<Scalar>::IsComplex,
110  ActualIndex = ReturnOpposite ? -Index : Index,
111  DiagonalSize = (RowsAtCompileTime==Dynamic || ColsAtCompileTime==Dynamic)
112  ? Dynamic
113  : (ActualIndex<0
114  ? EIGEN_SIZE_MIN_PREFER_DYNAMIC(ColsAtCompileTime, RowsAtCompileTime + ActualIndex)
115  : EIGEN_SIZE_MIN_PREFER_DYNAMIC(RowsAtCompileTime, ColsAtCompileTime - ActualIndex))
116  };
117  typedef Block<CoefficientsType,1, DiagonalSize> BuildType;
118  typedef typename internal::conditional<Conjugate,
119  CwiseUnaryOp<internal::scalar_conjugate_op<Scalar>,BuildType >,
120  BuildType>::type Type;
121  };
122 
124  template<int N> inline typename DiagonalIntReturnType<N>::Type diagonal()
125  {
126  return typename DiagonalIntReturnType<N>::BuildType(coeffs(), supers()-N, (std::max)(0,N), 1, diagonalLength(N));
127  }
128 
130  template<int N> inline const typename DiagonalIntReturnType<N>::Type diagonal() const
131  {
132  return typename DiagonalIntReturnType<N>::BuildType(coeffs(), supers()-N, (std::max)(0,N), 1, diagonalLength(N));
133  }
134 
136  inline Block<CoefficientsType,1,Dynamic> diagonal(Index i)
137  {
138  eigen_assert((i<0 && -i<=subs()) || (i>=0 && i<=supers()));
139  return Block<CoefficientsType,1,Dynamic>(coeffs(), supers()-i, std::max<Index>(0,i), 1, diagonalLength(i));
140  }
141 
143  inline const Block<const CoefficientsType,1,Dynamic> diagonal(Index i) const
144  {
145  eigen_assert((i<0 && -i<=subs()) || (i>=0 && i<=supers()));
146  return Block<const CoefficientsType,1,Dynamic>(coeffs(), supers()-i, std::max<Index>(0,i), 1, diagonalLength(i));
147  }
148 
149  template<typename Dest> inline void evalTo(Dest& dst) const
150  {
151  dst.resize(rows(),cols());
152  dst.setZero();
153  dst.diagonal() = diagonal();
154  for (Index i=1; i<=supers();++i)
155  dst.diagonal(i) = diagonal(i);
156  for (Index i=1; i<=subs();++i)
157  dst.diagonal(-i) = diagonal(-i);
158  }
159 
160  DenseMatrixType toDenseMatrix() const
161  {
162  DenseMatrixType res(rows(),cols());
163  evalTo(res);
164  return res;
165  }
166 
167  protected:
168 
169  inline Index diagonalLength(Index i) const
170  { return i<0 ? (std::min)(cols(),rows()+i) : (std::min)(rows(),cols()-i); }
171 };
172 
192 template<typename _Scalar, int _Rows, int _Cols, int _Supers, int _Subs, int _Options>
193 struct traits<BandMatrix<_Scalar,_Rows,_Cols,_Supers,_Subs,_Options> >
194 {
195  typedef _Scalar Scalar;
196  typedef Dense StorageKind;
197  typedef DenseIndex Index;
198  enum {
199  CoeffReadCost = NumTraits<Scalar>::ReadCost,
200  RowsAtCompileTime = _Rows,
201  ColsAtCompileTime = _Cols,
202  MaxRowsAtCompileTime = _Rows,
203  MaxColsAtCompileTime = _Cols,
204  Flags = LvalueBit,
205  Supers = _Supers,
206  Subs = _Subs,
207  Options = _Options,
208  DataRowsAtCompileTime = ((Supers!=Dynamic) && (Subs!=Dynamic)) ? 1 + Supers + Subs : Dynamic
209  };
210  typedef Matrix<Scalar,DataRowsAtCompileTime,ColsAtCompileTime,Options&RowMajor?RowMajor:ColMajor> CoefficientsType;
211 };
212 
213 template<typename _Scalar, int Rows, int Cols, int Supers, int Subs, int Options>
214 class BandMatrix : public BandMatrixBase<BandMatrix<_Scalar,Rows,Cols,Supers,Subs,Options> >
215 {
216  public:
217 
218  typedef typename internal::traits<BandMatrix>::Scalar Scalar;
219  typedef typename internal::traits<BandMatrix>::Index Index;
220  typedef typename internal::traits<BandMatrix>::CoefficientsType CoefficientsType;
221 
222  inline BandMatrix(Index rows=Rows, Index cols=Cols, Index supers=Supers, Index subs=Subs)
223  : m_coeffs(1+supers+subs,cols),
224  m_rows(rows), m_supers(supers), m_subs(subs)
225  {
226  }
227 
229  inline Index rows() const { return m_rows.value(); }
230 
232  inline Index cols() const { return m_coeffs.cols(); }
233 
235  inline Index supers() const { return m_supers.value(); }
236 
238  inline Index subs() const { return m_subs.value(); }
239 
240  inline const CoefficientsType& coeffs() const { return m_coeffs; }
241  inline CoefficientsType& coeffs() { return m_coeffs; }
242 
243  protected:
244 
245  CoefficientsType m_coeffs;
246  internal::variable_if_dynamic<Index, Rows> m_rows;
247  internal::variable_if_dynamic<Index, Supers> m_supers;
248  internal::variable_if_dynamic<Index, Subs> m_subs;
249 };
250 
251 template<typename _CoefficientsType,int _Rows, int _Cols, int _Supers, int _Subs,int _Options>
252 class BandMatrixWrapper;
253 
254 template<typename _CoefficientsType,int _Rows, int _Cols, int _Supers, int _Subs,int _Options>
255 struct traits<BandMatrixWrapper<_CoefficientsType,_Rows,_Cols,_Supers,_Subs,_Options> >
256 {
257  typedef typename _CoefficientsType::Scalar Scalar;
258  typedef typename _CoefficientsType::StorageKind StorageKind;
259  typedef typename _CoefficientsType::Index Index;
260  enum {
261  CoeffReadCost = internal::traits<_CoefficientsType>::CoeffReadCost,
262  RowsAtCompileTime = _Rows,
263  ColsAtCompileTime = _Cols,
264  MaxRowsAtCompileTime = _Rows,
265  MaxColsAtCompileTime = _Cols,
266  Flags = LvalueBit,
267  Supers = _Supers,
268  Subs = _Subs,
269  Options = _Options,
270  DataRowsAtCompileTime = ((Supers!=Dynamic) && (Subs!=Dynamic)) ? 1 + Supers + Subs : Dynamic
271  };
272  typedef _CoefficientsType CoefficientsType;
273 };
274 
275 template<typename _CoefficientsType,int _Rows, int _Cols, int _Supers, int _Subs,int _Options>
276 class BandMatrixWrapper : public BandMatrixBase<BandMatrixWrapper<_CoefficientsType,_Rows,_Cols,_Supers,_Subs,_Options> >
277 {
278  public:
279 
280  typedef typename internal::traits<BandMatrixWrapper>::Scalar Scalar;
281  typedef typename internal::traits<BandMatrixWrapper>::CoefficientsType CoefficientsType;
282  typedef typename internal::traits<BandMatrixWrapper>::Index Index;
283 
284  inline BandMatrixWrapper(const CoefficientsType& coeffs, Index rows=_Rows, Index cols=_Cols, Index supers=_Supers, Index subs=_Subs)
285  : m_coeffs(coeffs),
286  m_rows(rows), m_supers(supers), m_subs(subs)
287  {
288  EIGEN_UNUSED_VARIABLE(cols);
289  //internal::assert(coeffs.cols()==cols() && (supers()+subs()+1)==coeffs.rows());
290  }
291 
293  inline Index rows() const { return m_rows.value(); }
294 
296  inline Index cols() const { return m_coeffs.cols(); }
297 
299  inline Index supers() const { return m_supers.value(); }
300 
302  inline Index subs() const { return m_subs.value(); }
303 
304  inline const CoefficientsType& coeffs() const { return m_coeffs; }
305 
306  protected:
307 
308  const CoefficientsType& m_coeffs;
309  internal::variable_if_dynamic<Index, _Rows> m_rows;
310  internal::variable_if_dynamic<Index, _Supers> m_supers;
311  internal::variable_if_dynamic<Index, _Subs> m_subs;
312 };
313 
326 template<typename Scalar, int Size, int Options>
327 class TridiagonalMatrix : public BandMatrix<Scalar,Size,Size,Options&SelfAdjoint?0:1,1,Options|RowMajor>
328 {
329  typedef BandMatrix<Scalar,Size,Size,Options&SelfAdjoint?0:1,1,Options|RowMajor> Base;
330  typedef typename Base::Index Index;
331  public:
332  TridiagonalMatrix(Index size = Size) : Base(size,size,Options&SelfAdjoint?0:1,1) {}
333 
334  inline typename Base::template DiagonalIntReturnType<1>::Type super()
335  { return Base::template diagonal<1>(); }
336  inline const typename Base::template DiagonalIntReturnType<1>::Type super() const
337  { return Base::template diagonal<1>(); }
338  inline typename Base::template DiagonalIntReturnType<-1>::Type sub()
339  { return Base::template diagonal<-1>(); }
340  inline const typename Base::template DiagonalIntReturnType<-1>::Type sub() const
341  { return Base::template diagonal<-1>(); }
342  protected:
343 };
344 
345 } // end namespace internal
346 
347 } // end namespace Eigen
348 
349 #endif // EIGEN_BANDMATRIX_H