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 | namespace Eigen {
|
---|
14 |
|
---|
15 | namespace internal {
|
---|
16 |
|
---|
17 | template<typename Derived>
|
---|
18 | class BandMatrixBase : public EigenBase<Derived>
|
---|
19 | {
|
---|
20 | public:
|
---|
21 |
|
---|
22 | enum {
|
---|
23 | Flags = internal::traits<Derived>::Flags,
|
---|
24 | CoeffReadCost = internal::traits<Derived>::CoeffReadCost,
|
---|
25 | RowsAtCompileTime = internal::traits<Derived>::RowsAtCompileTime,
|
---|
26 | ColsAtCompileTime = internal::traits<Derived>::ColsAtCompileTime,
|
---|
27 | MaxRowsAtCompileTime = internal::traits<Derived>::MaxRowsAtCompileTime,
|
---|
28 | MaxColsAtCompileTime = internal::traits<Derived>::MaxColsAtCompileTime,
|
---|
29 | Supers = internal::traits<Derived>::Supers,
|
---|
30 | Subs = internal::traits<Derived>::Subs,
|
---|
31 | Options = internal::traits<Derived>::Options
|
---|
32 | };
|
---|
33 | typedef typename internal::traits<Derived>::Scalar Scalar;
|
---|
34 | typedef Matrix<Scalar,RowsAtCompileTime,ColsAtCompileTime> DenseMatrixType;
|
---|
35 | typedef typename DenseMatrixType::Index Index;
|
---|
36 | typedef typename internal::traits<Derived>::CoefficientsType CoefficientsType;
|
---|
37 | typedef EigenBase<Derived> Base;
|
---|
38 |
|
---|
39 | protected:
|
---|
40 | enum {
|
---|
41 | DataRowsAtCompileTime = ((Supers!=Dynamic) && (Subs!=Dynamic))
|
---|
42 | ? 1 + Supers + Subs
|
---|
43 | : Dynamic,
|
---|
44 | SizeAtCompileTime = EIGEN_SIZE_MIN_PREFER_DYNAMIC(RowsAtCompileTime,ColsAtCompileTime)
|
---|
45 | };
|
---|
46 |
|
---|
47 | public:
|
---|
48 |
|
---|
49 | using Base::derived;
|
---|
50 | using Base::rows;
|
---|
51 | using Base::cols;
|
---|
52 |
|
---|
53 | /** \returns the number of super diagonals */
|
---|
54 | inline Index supers() const { return derived().supers(); }
|
---|
55 |
|
---|
56 | /** \returns the number of sub diagonals */
|
---|
57 | inline Index subs() const { return derived().subs(); }
|
---|
58 |
|
---|
59 | /** \returns an expression of the underlying coefficient matrix */
|
---|
60 | inline const CoefficientsType& coeffs() const { return derived().coeffs(); }
|
---|
61 |
|
---|
62 | /** \returns an expression of the underlying coefficient matrix */
|
---|
63 | inline CoefficientsType& coeffs() { return derived().coeffs(); }
|
---|
64 |
|
---|
65 | /** \returns a vector expression of the \a i -th column,
|
---|
66 | * only the meaningful part is returned.
|
---|
67 | * \warning the internal storage must be column major. */
|
---|
68 | inline Block<CoefficientsType,Dynamic,1> col(Index i)
|
---|
69 | {
|
---|
70 | EIGEN_STATIC_ASSERT((Options&RowMajor)==0,THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES);
|
---|
71 | Index start = 0;
|
---|
72 | Index len = coeffs().rows();
|
---|
73 | if (i<=supers())
|
---|
74 | {
|
---|
75 | start = supers()-i;
|
---|
76 | len = (std::min)(rows(),std::max<Index>(0,coeffs().rows() - (supers()-i)));
|
---|
77 | }
|
---|
78 | else if (i>=rows()-subs())
|
---|
79 | len = std::max<Index>(0,coeffs().rows() - (i + 1 - rows() + subs()));
|
---|
80 | return Block<CoefficientsType,Dynamic,1>(coeffs(), start, i, len, 1);
|
---|
81 | }
|
---|
82 |
|
---|
83 | /** \returns a vector expression of the main diagonal */
|
---|
84 | inline Block<CoefficientsType,1,SizeAtCompileTime> diagonal()
|
---|
85 | { return Block<CoefficientsType,1,SizeAtCompileTime>(coeffs(),supers(),0,1,(std::min)(rows(),cols())); }
|
---|
86 |
|
---|
87 | /** \returns a vector expression of the main diagonal (const version) */
|
---|
88 | inline const Block<const CoefficientsType,1,SizeAtCompileTime> diagonal() const
|
---|
89 | { return Block<const CoefficientsType,1,SizeAtCompileTime>(coeffs(),supers(),0,1,(std::min)(rows(),cols())); }
|
---|
90 |
|
---|
91 | template<int Index> struct DiagonalIntReturnType {
|
---|
92 | enum {
|
---|
93 | ReturnOpposite = (Options&SelfAdjoint) && (((Index)>0 && Supers==0) || ((Index)<0 && Subs==0)),
|
---|
94 | Conjugate = ReturnOpposite && NumTraits<Scalar>::IsComplex,
|
---|
95 | ActualIndex = ReturnOpposite ? -Index : Index,
|
---|
96 | DiagonalSize = (RowsAtCompileTime==Dynamic || ColsAtCompileTime==Dynamic)
|
---|
97 | ? Dynamic
|
---|
98 | : (ActualIndex<0
|
---|
99 | ? EIGEN_SIZE_MIN_PREFER_DYNAMIC(ColsAtCompileTime, RowsAtCompileTime + ActualIndex)
|
---|
100 | : EIGEN_SIZE_MIN_PREFER_DYNAMIC(RowsAtCompileTime, ColsAtCompileTime - ActualIndex))
|
---|
101 | };
|
---|
102 | typedef Block<CoefficientsType,1, DiagonalSize> BuildType;
|
---|
103 | typedef typename internal::conditional<Conjugate,
|
---|
104 | CwiseUnaryOp<internal::scalar_conjugate_op<Scalar>,BuildType >,
|
---|
105 | BuildType>::type Type;
|
---|
106 | };
|
---|
107 |
|
---|
108 | /** \returns a vector expression of the \a N -th sub or super diagonal */
|
---|
109 | template<int N> inline typename DiagonalIntReturnType<N>::Type diagonal()
|
---|
110 | {
|
---|
111 | return typename DiagonalIntReturnType<N>::BuildType(coeffs(), supers()-N, (std::max)(0,N), 1, diagonalLength(N));
|
---|
112 | }
|
---|
113 |
|
---|
114 | /** \returns a vector expression of the \a N -th sub or super diagonal */
|
---|
115 | template<int N> inline const typename DiagonalIntReturnType<N>::Type diagonal() const
|
---|
116 | {
|
---|
117 | return typename DiagonalIntReturnType<N>::BuildType(coeffs(), supers()-N, (std::max)(0,N), 1, diagonalLength(N));
|
---|
118 | }
|
---|
119 |
|
---|
120 | /** \returns a vector expression of the \a i -th sub or super diagonal */
|
---|
121 | inline Block<CoefficientsType,1,Dynamic> diagonal(Index i)
|
---|
122 | {
|
---|
123 | eigen_assert((i<0 && -i<=subs()) || (i>=0 && i<=supers()));
|
---|
124 | return Block<CoefficientsType,1,Dynamic>(coeffs(), supers()-i, std::max<Index>(0,i), 1, diagonalLength(i));
|
---|
125 | }
|
---|
126 |
|
---|
127 | /** \returns a vector expression of the \a i -th sub or super diagonal */
|
---|
128 | inline const Block<const CoefficientsType,1,Dynamic> diagonal(Index i) const
|
---|
129 | {
|
---|
130 | eigen_assert((i<0 && -i<=subs()) || (i>=0 && i<=supers()));
|
---|
131 | return Block<const CoefficientsType,1,Dynamic>(coeffs(), supers()-i, std::max<Index>(0,i), 1, diagonalLength(i));
|
---|
132 | }
|
---|
133 |
|
---|
134 | template<typename Dest> inline void evalTo(Dest& dst) const
|
---|
135 | {
|
---|
136 | dst.resize(rows(),cols());
|
---|
137 | dst.setZero();
|
---|
138 | dst.diagonal() = diagonal();
|
---|
139 | for (Index i=1; i<=supers();++i)
|
---|
140 | dst.diagonal(i) = diagonal(i);
|
---|
141 | for (Index i=1; i<=subs();++i)
|
---|
142 | dst.diagonal(-i) = diagonal(-i);
|
---|
143 | }
|
---|
144 |
|
---|
145 | DenseMatrixType toDenseMatrix() const
|
---|
146 | {
|
---|
147 | DenseMatrixType res(rows(),cols());
|
---|
148 | evalTo(res);
|
---|
149 | return res;
|
---|
150 | }
|
---|
151 |
|
---|
152 | protected:
|
---|
153 |
|
---|
154 | inline Index diagonalLength(Index i) const
|
---|
155 | { return i<0 ? (std::min)(cols(),rows()+i) : (std::min)(rows(),cols()-i); }
|
---|
156 | };
|
---|
157 |
|
---|
158 | /**
|
---|
159 | * \class BandMatrix
|
---|
160 | * \ingroup Core_Module
|
---|
161 | *
|
---|
162 | * \brief Represents a rectangular matrix with a banded storage
|
---|
163 | *
|
---|
164 | * \param _Scalar Numeric type, i.e. float, double, int
|
---|
165 | * \param Rows Number of rows, or \b Dynamic
|
---|
166 | * \param Cols Number of columns, or \b Dynamic
|
---|
167 | * \param Supers Number of super diagonal
|
---|
168 | * \param Subs Number of sub diagonal
|
---|
169 | * \param _Options A combination of either \b #RowMajor or \b #ColMajor, and of \b #SelfAdjoint
|
---|
170 | * The former controls \ref TopicStorageOrders "storage order", and defaults to
|
---|
171 | * column-major. The latter controls whether the matrix represents a selfadjoint
|
---|
172 | * matrix in which case either Supers of Subs have to be null.
|
---|
173 | *
|
---|
174 | * \sa class TridiagonalMatrix
|
---|
175 | */
|
---|
176 |
|
---|
177 | template<typename _Scalar, int _Rows, int _Cols, int _Supers, int _Subs, int _Options>
|
---|
178 | struct traits<BandMatrix<_Scalar,_Rows,_Cols,_Supers,_Subs,_Options> >
|
---|
179 | {
|
---|
180 | typedef _Scalar Scalar;
|
---|
181 | typedef Dense StorageKind;
|
---|
182 | typedef DenseIndex Index;
|
---|
183 | enum {
|
---|
184 | CoeffReadCost = NumTraits<Scalar>::ReadCost,
|
---|
185 | RowsAtCompileTime = _Rows,
|
---|
186 | ColsAtCompileTime = _Cols,
|
---|
187 | MaxRowsAtCompileTime = _Rows,
|
---|
188 | MaxColsAtCompileTime = _Cols,
|
---|
189 | Flags = LvalueBit,
|
---|
190 | Supers = _Supers,
|
---|
191 | Subs = _Subs,
|
---|
192 | Options = _Options,
|
---|
193 | DataRowsAtCompileTime = ((Supers!=Dynamic) && (Subs!=Dynamic)) ? 1 + Supers + Subs : Dynamic
|
---|
194 | };
|
---|
195 | typedef Matrix<Scalar,DataRowsAtCompileTime,ColsAtCompileTime,Options&RowMajor?RowMajor:ColMajor> CoefficientsType;
|
---|
196 | };
|
---|
197 |
|
---|
198 | template<typename _Scalar, int Rows, int Cols, int Supers, int Subs, int Options>
|
---|
199 | class BandMatrix : public BandMatrixBase<BandMatrix<_Scalar,Rows,Cols,Supers,Subs,Options> >
|
---|
200 | {
|
---|
201 | public:
|
---|
202 |
|
---|
203 | typedef typename internal::traits<BandMatrix>::Scalar Scalar;
|
---|
204 | typedef typename internal::traits<BandMatrix>::Index Index;
|
---|
205 | typedef typename internal::traits<BandMatrix>::CoefficientsType CoefficientsType;
|
---|
206 |
|
---|
207 | inline BandMatrix(Index rows=Rows, Index cols=Cols, Index supers=Supers, Index subs=Subs)
|
---|
208 | : m_coeffs(1+supers+subs,cols),
|
---|
209 | m_rows(rows), m_supers(supers), m_subs(subs)
|
---|
210 | {
|
---|
211 | }
|
---|
212 |
|
---|
213 | /** \returns the number of columns */
|
---|
214 | inline Index rows() const { return m_rows.value(); }
|
---|
215 |
|
---|
216 | /** \returns the number of rows */
|
---|
217 | inline Index cols() const { return m_coeffs.cols(); }
|
---|
218 |
|
---|
219 | /** \returns the number of super diagonals */
|
---|
220 | inline Index supers() const { return m_supers.value(); }
|
---|
221 |
|
---|
222 | /** \returns the number of sub diagonals */
|
---|
223 | inline Index subs() const { return m_subs.value(); }
|
---|
224 |
|
---|
225 | inline const CoefficientsType& coeffs() const { return m_coeffs; }
|
---|
226 | inline CoefficientsType& coeffs() { return m_coeffs; }
|
---|
227 |
|
---|
228 | protected:
|
---|
229 |
|
---|
230 | CoefficientsType m_coeffs;
|
---|
231 | internal::variable_if_dynamic<Index, Rows> m_rows;
|
---|
232 | internal::variable_if_dynamic<Index, Supers> m_supers;
|
---|
233 | internal::variable_if_dynamic<Index, Subs> m_subs;
|
---|
234 | };
|
---|
235 |
|
---|
236 | template<typename _CoefficientsType,int _Rows, int _Cols, int _Supers, int _Subs,int _Options>
|
---|
237 | class BandMatrixWrapper;
|
---|
238 |
|
---|
239 | template<typename _CoefficientsType,int _Rows, int _Cols, int _Supers, int _Subs,int _Options>
|
---|
240 | struct traits<BandMatrixWrapper<_CoefficientsType,_Rows,_Cols,_Supers,_Subs,_Options> >
|
---|
241 | {
|
---|
242 | typedef typename _CoefficientsType::Scalar Scalar;
|
---|
243 | typedef typename _CoefficientsType::StorageKind StorageKind;
|
---|
244 | typedef typename _CoefficientsType::Index Index;
|
---|
245 | enum {
|
---|
246 | CoeffReadCost = internal::traits<_CoefficientsType>::CoeffReadCost,
|
---|
247 | RowsAtCompileTime = _Rows,
|
---|
248 | ColsAtCompileTime = _Cols,
|
---|
249 | MaxRowsAtCompileTime = _Rows,
|
---|
250 | MaxColsAtCompileTime = _Cols,
|
---|
251 | Flags = LvalueBit,
|
---|
252 | Supers = _Supers,
|
---|
253 | Subs = _Subs,
|
---|
254 | Options = _Options,
|
---|
255 | DataRowsAtCompileTime = ((Supers!=Dynamic) && (Subs!=Dynamic)) ? 1 + Supers + Subs : Dynamic
|
---|
256 | };
|
---|
257 | typedef _CoefficientsType CoefficientsType;
|
---|
258 | };
|
---|
259 |
|
---|
260 | template<typename _CoefficientsType,int _Rows, int _Cols, int _Supers, int _Subs,int _Options>
|
---|
261 | class BandMatrixWrapper : public BandMatrixBase<BandMatrixWrapper<_CoefficientsType,_Rows,_Cols,_Supers,_Subs,_Options> >
|
---|
262 | {
|
---|
263 | public:
|
---|
264 |
|
---|
265 | typedef typename internal::traits<BandMatrixWrapper>::Scalar Scalar;
|
---|
266 | typedef typename internal::traits<BandMatrixWrapper>::CoefficientsType CoefficientsType;
|
---|
267 | typedef typename internal::traits<BandMatrixWrapper>::Index Index;
|
---|
268 |
|
---|
269 | inline BandMatrixWrapper(const CoefficientsType& coeffs, Index rows=_Rows, Index cols=_Cols, Index supers=_Supers, Index subs=_Subs)
|
---|
270 | : m_coeffs(coeffs),
|
---|
271 | m_rows(rows), m_supers(supers), m_subs(subs)
|
---|
272 | {
|
---|
273 | EIGEN_UNUSED_VARIABLE(cols);
|
---|
274 | //internal::assert(coeffs.cols()==cols() && (supers()+subs()+1)==coeffs.rows());
|
---|
275 | }
|
---|
276 |
|
---|
277 | /** \returns the number of columns */
|
---|
278 | inline Index rows() const { return m_rows.value(); }
|
---|
279 |
|
---|
280 | /** \returns the number of rows */
|
---|
281 | inline Index cols() const { return m_coeffs.cols(); }
|
---|
282 |
|
---|
283 | /** \returns the number of super diagonals */
|
---|
284 | inline Index supers() const { return m_supers.value(); }
|
---|
285 |
|
---|
286 | /** \returns the number of sub diagonals */
|
---|
287 | inline Index subs() const { return m_subs.value(); }
|
---|
288 |
|
---|
289 | inline const CoefficientsType& coeffs() const { return m_coeffs; }
|
---|
290 |
|
---|
291 | protected:
|
---|
292 |
|
---|
293 | const CoefficientsType& m_coeffs;
|
---|
294 | internal::variable_if_dynamic<Index, _Rows> m_rows;
|
---|
295 | internal::variable_if_dynamic<Index, _Supers> m_supers;
|
---|
296 | internal::variable_if_dynamic<Index, _Subs> m_subs;
|
---|
297 | };
|
---|
298 |
|
---|
299 | /**
|
---|
300 | * \class TridiagonalMatrix
|
---|
301 | * \ingroup Core_Module
|
---|
302 | *
|
---|
303 | * \brief Represents a tridiagonal matrix with a compact banded storage
|
---|
304 | *
|
---|
305 | * \param _Scalar Numeric type, i.e. float, double, int
|
---|
306 | * \param Size Number of rows and cols, or \b Dynamic
|
---|
307 | * \param _Options Can be 0 or \b SelfAdjoint
|
---|
308 | *
|
---|
309 | * \sa class BandMatrix
|
---|
310 | */
|
---|
311 | template<typename Scalar, int Size, int Options>
|
---|
312 | class TridiagonalMatrix : public BandMatrix<Scalar,Size,Size,Options&SelfAdjoint?0:1,1,Options|RowMajor>
|
---|
313 | {
|
---|
314 | typedef BandMatrix<Scalar,Size,Size,Options&SelfAdjoint?0:1,1,Options|RowMajor> Base;
|
---|
315 | typedef typename Base::Index Index;
|
---|
316 | public:
|
---|
317 | TridiagonalMatrix(Index size = Size) : Base(size,size,Options&SelfAdjoint?0:1,1) {}
|
---|
318 |
|
---|
319 | inline typename Base::template DiagonalIntReturnType<1>::Type super()
|
---|
320 | { return Base::template diagonal<1>(); }
|
---|
321 | inline const typename Base::template DiagonalIntReturnType<1>::Type super() const
|
---|
322 | { return Base::template diagonal<1>(); }
|
---|
323 | inline typename Base::template DiagonalIntReturnType<-1>::Type sub()
|
---|
324 | { return Base::template diagonal<-1>(); }
|
---|
325 | inline const typename Base::template DiagonalIntReturnType<-1>::Type sub() const
|
---|
326 | { return Base::template diagonal<-1>(); }
|
---|
327 | protected:
|
---|
328 | };
|
---|
329 |
|
---|
330 | } // end namespace internal
|
---|
331 |
|
---|
332 | } // end namespace Eigen
|
---|
333 |
|
---|
334 | #endif // EIGEN_BANDMATRIX_H
|
---|