00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef EIGEN_BANDMATRIX_H
00026 #define EIGEN_BANDMATRIX_H
00027
00028 namespace internal {
00029
00030
00031 template<typename Derived>
00032 class BandMatrixBase : public EigenBase<Derived>
00033 {
00034 public:
00035
00036 enum {
00037 Flags = internal::traits<Derived>::Flags,
00038 CoeffReadCost = internal::traits<Derived>::CoeffReadCost,
00039 RowsAtCompileTime = internal::traits<Derived>::RowsAtCompileTime,
00040 ColsAtCompileTime = internal::traits<Derived>::ColsAtCompileTime,
00041 MaxRowsAtCompileTime = internal::traits<Derived>::MaxRowsAtCompileTime,
00042 MaxColsAtCompileTime = internal::traits<Derived>::MaxColsAtCompileTime,
00043 Supers = internal::traits<Derived>::Supers,
00044 Subs = internal::traits<Derived>::Subs,
00045 Options = internal::traits<Derived>::Options
00046 };
00047 typedef typename internal::traits<Derived>::Scalar Scalar;
00048 typedef Matrix<Scalar,RowsAtCompileTime,ColsAtCompileTime> DenseMatrixType;
00049 typedef typename DenseMatrixType::Index Index;
00050 typedef typename internal::traits<Derived>::CoefficientsType CoefficientsType;
00051 typedef EigenBase<Derived> Base;
00052
00053 protected:
00054 enum {
00055 DataRowsAtCompileTime = ((Supers!=Dynamic) && (Subs!=Dynamic))
00056 ? 1 + Supers + Subs
00057 : Dynamic,
00058 SizeAtCompileTime = EIGEN_SIZE_MIN_PREFER_DYNAMIC(RowsAtCompileTime,ColsAtCompileTime)
00059 };
00060
00061 public:
00062
00063 using Base::derived;
00064 using Base::rows;
00065 using Base::cols;
00066
00068 inline Index supers() const { return derived().supers(); }
00069
00071 inline Index subs() const { return derived().subs(); }
00072
00074 inline const CoefficientsType& coeffs() const { return derived().coeffs(); }
00075
00077 inline CoefficientsType& coeffs() { return derived().coeffs(); }
00078
00082 inline Block<CoefficientsType,Dynamic,1> col(Index i)
00083 {
00084 EIGEN_STATIC_ASSERT((Options&RowMajor)==0,THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES);
00085 Index start = 0;
00086 Index len = coeffs().rows();
00087 if (i<=supers())
00088 {
00089 start = supers()-i;
00090 len = std::min(rows(),std::max<Index>(0,coeffs().rows() - (supers()-i)));
00091 }
00092 else if (i>=rows()-subs())
00093 len = std::max<Index>(0,coeffs().rows() - (i + 1 - rows() + subs()));
00094 return Block<CoefficientsType,Dynamic,1>(coeffs(), start, i, len, 1);
00095 }
00096
00098 inline Block<CoefficientsType,1,SizeAtCompileTime> diagonal()
00099 { return Block<CoefficientsType,1,SizeAtCompileTime>(coeffs(),supers(),0,1,std::min(rows(),cols())); }
00100
00102 inline const Block<const CoefficientsType,1,SizeAtCompileTime> diagonal() const
00103 { return Block<const CoefficientsType,1,SizeAtCompileTime>(coeffs(),supers(),0,1,std::min(rows(),cols())); }
00104
00105 template<int Index> struct DiagonalIntReturnType {
00106 enum {
00107 ReturnOpposite = (Options&SelfAdjoint) && (((Index)>0 && Supers==0) || ((Index)<0 && Subs==0)),
00108 Conjugate = ReturnOpposite && NumTraits<Scalar>::IsComplex,
00109 ActualIndex = ReturnOpposite ? -Index : Index,
00110 DiagonalSize = (RowsAtCompileTime==Dynamic || ColsAtCompileTime==Dynamic)
00111 ? Dynamic
00112 : (ActualIndex<0
00113 ? EIGEN_SIZE_MIN_PREFER_DYNAMIC(ColsAtCompileTime, RowsAtCompileTime + ActualIndex)
00114 : EIGEN_SIZE_MIN_PREFER_DYNAMIC(RowsAtCompileTime, ColsAtCompileTime - ActualIndex))
00115 };
00116 typedef Block<CoefficientsType,1, DiagonalSize> BuildType;
00117 typedef typename internal::conditional<Conjugate,
00118 CwiseUnaryOp<internal::scalar_conjugate_op<Scalar>,BuildType >,
00119 BuildType>::type Type;
00120 };
00121
00123 template<int N> inline typename DiagonalIntReturnType<N>::Type diagonal()
00124 {
00125 return typename DiagonalIntReturnType<N>::BuildType(coeffs(), supers()-N, std::max(0,N), 1, diagonalLength(N));
00126 }
00127
00129 template<int N> inline const typename DiagonalIntReturnType<N>::Type diagonal() const
00130 {
00131 return typename DiagonalIntReturnType<N>::BuildType(coeffs(), supers()-N, std::max(0,N), 1, diagonalLength(N));
00132 }
00133
00135 inline Block<CoefficientsType,1,Dynamic> diagonal(Index i)
00136 {
00137 eigen_assert((i<0 && -i<=subs()) || (i>=0 && i<=supers()));
00138 return Block<CoefficientsType,1,Dynamic>(coeffs(), supers()-i, std::max<Index>(0,i), 1, diagonalLength(i));
00139 }
00140
00142 inline const Block<const CoefficientsType,1,Dynamic> diagonal(Index i) const
00143 {
00144 eigen_assert((i<0 && -i<=subs()) || (i>=0 && i<=supers()));
00145 return Block<const CoefficientsType,1,Dynamic>(coeffs(), supers()-i, std::max<Index>(0,i), 1, diagonalLength(i));
00146 }
00147
00148 template<typename Dest> inline void evalTo(Dest& dst) const
00149 {
00150 dst.resize(rows(),cols());
00151 dst.setZero();
00152 dst.diagonal() = diagonal();
00153 for (Index i=1; i<=supers();++i)
00154 dst.diagonal(i) = diagonal(i);
00155 for (Index i=1; i<=subs();++i)
00156 dst.diagonal(-i) = diagonal(-i);
00157 }
00158
00159 DenseMatrixType toDenseMatrix() const
00160 {
00161 DenseMatrixType res(rows(),cols());
00162 evalTo(res);
00163 return res;
00164 }
00165
00166 protected:
00167
00168 inline Index diagonalLength(Index i) const
00169 { return i<0 ? std::min(cols(),rows()+i) : std::min(rows(),cols()-i); }
00170 };
00171
00191 template<typename _Scalar, int _Rows, int _Cols, int _Supers, int _Subs, int _Options>
00192 struct traits<BandMatrix<_Scalar,_Rows,_Cols,_Supers,_Subs,_Options> >
00193 {
00194 typedef _Scalar Scalar;
00195 typedef Dense StorageKind;
00196 typedef DenseIndex Index;
00197 enum {
00198 CoeffReadCost = NumTraits<Scalar>::ReadCost,
00199 RowsAtCompileTime = _Rows,
00200 ColsAtCompileTime = _Cols,
00201 MaxRowsAtCompileTime = _Rows,
00202 MaxColsAtCompileTime = _Cols,
00203 Flags = LvalueBit,
00204 Supers = _Supers,
00205 Subs = _Subs,
00206 Options = _Options,
00207 DataRowsAtCompileTime = ((Supers!=Dynamic) && (Subs!=Dynamic)) ? 1 + Supers + Subs : Dynamic
00208 };
00209 typedef Matrix<Scalar,DataRowsAtCompileTime,ColsAtCompileTime,Options&RowMajor?RowMajor:ColMajor> CoefficientsType;
00210 };
00211
00212 template<typename _Scalar, int Rows, int Cols, int Supers, int Subs, int Options>
00213 class BandMatrix : public BandMatrixBase<BandMatrix<_Scalar,Rows,Cols,Supers,Subs,Options> >
00214 {
00215 public:
00216
00217 typedef typename internal::traits<BandMatrix>::Scalar Scalar;
00218 typedef typename internal::traits<BandMatrix>::Index Index;
00219 typedef typename internal::traits<BandMatrix>::CoefficientsType CoefficientsType;
00220
00221 inline BandMatrix(Index rows=Rows, Index cols=Cols, Index supers=Supers, Index subs=Subs)
00222 : m_coeffs(1+supers+subs,cols),
00223 m_rows(rows), m_supers(supers), m_subs(subs)
00224 {
00225 }
00226
00228 inline Index rows() const { return m_rows.value(); }
00229
00231 inline Index cols() const { return m_coeffs.cols(); }
00232
00234 inline Index supers() const { return m_supers.value(); }
00235
00237 inline Index subs() const { return m_subs.value(); }
00238
00239 inline const CoefficientsType& coeffs() const { return m_coeffs; }
00240 inline CoefficientsType& coeffs() { return m_coeffs; }
00241
00242 protected:
00243
00244 CoefficientsType m_coeffs;
00245 internal::variable_if_dynamic<Index, Rows> m_rows;
00246 internal::variable_if_dynamic<Index, Supers> m_supers;
00247 internal::variable_if_dynamic<Index, Subs> m_subs;
00248 };
00249
00250 template<typename _CoefficientsType,int _Rows, int _Cols, int _Supers, int _Subs,int _Options>
00251 class BandMatrixWrapper;
00252
00253 template<typename _CoefficientsType,int _Rows, int _Cols, int _Supers, int _Subs,int _Options>
00254 struct traits<BandMatrixWrapper<_CoefficientsType,_Rows,_Cols,_Supers,_Subs,_Options> >
00255 {
00256 typedef typename _CoefficientsType::Scalar Scalar;
00257 typedef typename _CoefficientsType::StorageKind StorageKind;
00258 typedef typename _CoefficientsType::Index Index;
00259 enum {
00260 CoeffReadCost = internal::traits<_CoefficientsType>::CoeffReadCost,
00261 RowsAtCompileTime = _Rows,
00262 ColsAtCompileTime = _Cols,
00263 MaxRowsAtCompileTime = _Rows,
00264 MaxColsAtCompileTime = _Cols,
00265 Flags = LvalueBit,
00266 Supers = _Supers,
00267 Subs = _Subs,
00268 Options = _Options,
00269 DataRowsAtCompileTime = ((Supers!=Dynamic) && (Subs!=Dynamic)) ? 1 + Supers + Subs : Dynamic
00270 };
00271 typedef _CoefficientsType CoefficientsType;
00272 };
00273
00274 template<typename _CoefficientsType,int _Rows, int _Cols, int _Supers, int _Subs,int _Options>
00275 class BandMatrixWrapper : public BandMatrixBase<BandMatrixWrapper<_CoefficientsType,_Rows,_Cols,_Supers,_Subs,_Options> >
00276 {
00277 public:
00278
00279 typedef typename internal::traits<BandMatrixWrapper>::Scalar Scalar;
00280 typedef typename internal::traits<BandMatrixWrapper>::CoefficientsType CoefficientsType;
00281 typedef typename internal::traits<BandMatrixWrapper>::Index Index;
00282
00283 inline BandMatrixWrapper(const CoefficientsType& coeffs, Index rows=_Rows, Index cols=_Cols, Index supers=_Supers, Index subs=_Subs)
00284 : m_coeffs(coeffs),
00285 m_rows(rows), m_supers(supers), m_subs(subs)
00286 {
00287
00288 }
00289
00291 inline Index rows() const { return m_rows.value(); }
00292
00294 inline Index cols() const { return m_coeffs.cols(); }
00295
00297 inline Index supers() const { return m_supers.value(); }
00298
00300 inline Index subs() const { return m_subs.value(); }
00301
00302 inline const CoefficientsType& coeffs() const { return m_coeffs; }
00303
00304 protected:
00305
00306 const CoefficientsType& m_coeffs;
00307 internal::variable_if_dynamic<Index, _Rows> m_rows;
00308 internal::variable_if_dynamic<Index, _Supers> m_supers;
00309 internal::variable_if_dynamic<Index, _Subs> m_subs;
00310 };
00311
00324 template<typename Scalar, int Size, int Options>
00325 class TridiagonalMatrix : public BandMatrix<Scalar,Size,Size,Options&SelfAdjoint?0:1,1,Options|RowMajor>
00326 {
00327 typedef BandMatrix<Scalar,Size,Size,Options&SelfAdjoint?0:1,1,Options|RowMajor> Base;
00328 typedef typename Base::Index Index;
00329 public:
00330 TridiagonalMatrix(Index size = Size) : Base(size,size,Options&SelfAdjoint?0:1,1) {}
00331
00332 inline typename Base::template DiagonalIntReturnType<1>::Type super()
00333 { return Base::template diagonal<1>(); }
00334 inline const typename Base::template DiagonalIntReturnType<1>::Type super() const
00335 { return Base::template diagonal<1>(); }
00336 inline typename Base::template DiagonalIntReturnType<-1>::Type sub()
00337 { return Base::template diagonal<-1>(); }
00338 inline const typename Base::template DiagonalIntReturnType<-1>::Type sub() const
00339 { return Base::template diagonal<-1>(); }
00340 protected:
00341 };
00342
00343 }
00344
00345 #endif // EIGEN_BANDMATRIX_H