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
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049 template<typename _Scalar, int Rows, int Cols, int Supers, int Subs, int Options>
00050 struct traits<BandMatrix<_Scalar,Rows,Cols,Supers,Subs,Options> >
00051 {
00052 typedef _Scalar Scalar;
00053 typedef Dense StorageKind;
00054 typedef DenseIndex Index;
00055 enum {
00056 CoeffReadCost = NumTraits<Scalar>::ReadCost,
00057 RowsAtCompileTime = Rows,
00058 ColsAtCompileTime = Cols,
00059 MaxRowsAtCompileTime = Rows,
00060 MaxColsAtCompileTime = Cols,
00061 Flags = LvalueBit
00062 };
00063 };
00064
00065 template<typename _Scalar, int Rows, int Cols, int Supers, int Subs, int Options>
00066 class BandMatrix : public EigenBase<BandMatrix<_Scalar,Rows,Cols,Supers,Subs,Options> >
00067 {
00068 public:
00069
00070 enum {
00071 Flags = internal::traits<BandMatrix>::Flags,
00072 CoeffReadCost = internal::traits<BandMatrix>::CoeffReadCost,
00073 RowsAtCompileTime = internal::traits<BandMatrix>::RowsAtCompileTime,
00074 ColsAtCompileTime = internal::traits<BandMatrix>::ColsAtCompileTime,
00075 MaxRowsAtCompileTime = internal::traits<BandMatrix>::MaxRowsAtCompileTime,
00076 MaxColsAtCompileTime = internal::traits<BandMatrix>::MaxColsAtCompileTime
00077 };
00078 typedef typename internal::traits<BandMatrix>::Scalar Scalar;
00079 typedef Matrix<Scalar,RowsAtCompileTime,ColsAtCompileTime> DenseMatrixType;
00080 typedef typename DenseMatrixType::Index Index;
00081
00082 protected:
00083 enum {
00084 DataRowsAtCompileTime = ((Supers!=Dynamic) && (Subs!=Dynamic))
00085 ? 1 + Supers + Subs
00086 : Dynamic,
00087 SizeAtCompileTime = EIGEN_SIZE_MIN_PREFER_DYNAMIC(Rows,Cols)
00088 };
00089 typedef Matrix<Scalar,DataRowsAtCompileTime,ColsAtCompileTime,Options&RowMajor?RowMajor:ColMajor> DataType;
00090
00091 public:
00092
00093 inline BandMatrix(Index rows=Rows, Index cols=Cols, Index supers=Supers, Index subs=Subs)
00094 : m_data(1+supers+subs,cols),
00095 m_rows(rows), m_supers(supers), m_subs(subs)
00096 {
00097
00098 }
00099
00100
00101 inline Index rows() const { return m_rows.value(); }
00102
00103
00104 inline Index cols() const { return m_data.cols(); }
00105
00106
00107 inline Index supers() const { return m_supers.value(); }
00108
00109
00110 inline Index subs() const { return m_subs.value(); }
00111
00112
00113
00114
00115 inline Block<DataType,Dynamic,1> col(Index i)
00116 {
00117 EIGEN_STATIC_ASSERT((Options&RowMajor)==0,THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES);
00118 Index start = 0;
00119 Index len = m_data.rows();
00120 if (i<=supers())
00121 {
00122 start = supers()-i;
00123 len = std::min(rows(),std::max<Index>(0,m_data.rows() - (supers()-i)));
00124 }
00125 else if (i>=rows()-subs())
00126 len = std::max<Index>(0,m_data.rows() - (i + 1 - rows() + subs()));
00127 return Block<DataType,Dynamic,1>(m_data, start, i, len, 1);
00128 }
00129
00130
00131 inline Block<DataType,1,SizeAtCompileTime> diagonal()
00132 { return Block<DataType,1,SizeAtCompileTime>(m_data,supers(),0,1,std::min(rows(),cols())); }
00133
00134
00135 inline const Block<const DataType,1,SizeAtCompileTime> diagonal() const
00136 { return Block<const DataType,1,SizeAtCompileTime>(m_data,supers(),0,1,std::min(rows(),cols())); }
00137
00138 template<int Index> struct DiagonalIntReturnType {
00139 enum {
00140 ReturnOpposite = (Options&SelfAdjoint) && (((Index)>0 && Supers==0) || ((Index)<0 && Subs==0)),
00141 Conjugate = ReturnOpposite && NumTraits<Scalar>::IsComplex,
00142 ActualIndex = ReturnOpposite ? -Index : Index,
00143 DiagonalSize = (RowsAtCompileTime==Dynamic || ColsAtCompileTime==Dynamic)
00144 ? Dynamic
00145 : (ActualIndex<0
00146 ? EIGEN_SIZE_MIN_PREFER_DYNAMIC(ColsAtCompileTime, RowsAtCompileTime + ActualIndex)
00147 : EIGEN_SIZE_MIN_PREFER_DYNAMIC(RowsAtCompileTime, ColsAtCompileTime - ActualIndex))
00148 };
00149 typedef Block<DataType,1, DiagonalSize> BuildType;
00150 typedef typename internal::conditional<Conjugate,
00151 CwiseUnaryOp<internal::scalar_conjugate_op<Scalar>,BuildType >,
00152 BuildType>::type Type;
00153 };
00154
00155
00156 template<int N> inline typename DiagonalIntReturnType<N>::Type diagonal()
00157 {
00158 return typename DiagonalIntReturnType<N>::BuildType(m_data, supers()-N, std::max(0,N), 1, diagonalLength(N));
00159 }
00160
00161
00162 template<int N> inline const typename DiagonalIntReturnType<N>::Type diagonal() const
00163 {
00164 return typename DiagonalIntReturnType<N>::BuildType(m_data, supers()-N, std::max(0,N), 1, diagonalLength(N));
00165 }
00166
00167
00168 inline Block<DataType,1,Dynamic> diagonal(Index i)
00169 {
00170 eigen_assert((i<0 && -i<=subs()) || (i>=0 && i<=supers()));
00171 return Block<DataType,1,Dynamic>(m_data, supers()-i, std::max<Index>(0,i), 1, diagonalLength(i));
00172 }
00173
00174
00175 inline const Block<const DataType,1,Dynamic> diagonal(Index i) const
00176 {
00177 eigen_assert((i<0 && -i<=subs()) || (i>=0 && i<=supers()));
00178 return Block<const DataType,1,Dynamic>(m_data, supers()-i, std::max<Index>(0,i), 1, diagonalLength(i));
00179 }
00180
00181 template<typename Dest> inline void evalTo(Dest& dst) const
00182 {
00183 dst.resize(rows(),cols());
00184 dst.setZero();
00185 dst.diagonal() = diagonal();
00186 for (Index i=1; i<=supers();++i)
00187 dst.diagonal(i) = diagonal(i);
00188 for (Index i=1; i<=subs();++i)
00189 dst.diagonal(-i) = diagonal(-i);
00190 }
00191
00192 DenseMatrixType toDenseMatrix() const
00193 {
00194 DenseMatrixType res(rows(),cols());
00195 evalTo(res);
00196 return res;
00197 }
00198
00199 protected:
00200
00201 inline Index diagonalLength(Index i) const
00202 { return i<0 ? std::min(cols(),rows()+i) : std::min(rows(),cols()-i); }
00203
00204 DataType m_data;
00205 internal::variable_if_dynamic<Index, Rows> m_rows;
00206 internal::variable_if_dynamic<Index, Supers> m_supers;
00207 internal::variable_if_dynamic<Index, Subs> m_subs;
00208 };
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222 template<typename Scalar, int Size, int Options>
00223 class TridiagonalMatrix : public BandMatrix<Scalar,Size,Size,Options&SelfAdjoint?0:1,1,Options|RowMajor>
00224 {
00225 typedef BandMatrix<Scalar,Size,Size,Options&SelfAdjoint?0:1,1,Options|RowMajor> Base;
00226 typedef typename Base::Index Index;
00227 public:
00228 TridiagonalMatrix(Index size = Size) : Base(size,size,Options&SelfAdjoint?0:1,1) {}
00229
00230 inline typename Base::template DiagonalIntReturnType<1>::Type super()
00231 { return Base::template diagonal<1>(); }
00232 inline const typename Base::template DiagonalIntReturnType<1>::Type super() const
00233 { return Base::template diagonal<1>(); }
00234 inline typename Base::template DiagonalIntReturnType<-1>::Type sub()
00235 { return Base::template diagonal<-1>(); }
00236 inline const typename Base::template DiagonalIntReturnType<-1>::Type sub() const
00237 { return Base::template diagonal<-1>(); }
00238 protected:
00239 };
00240
00241 }
00242
00243 #endif // EIGEN_BANDMATRIX_H