![]() |
Eigen
3.3.3
|
00001 // This file is part of Eigen, a lightweight C++ template library 00002 // for linear algebra. 00003 // 00004 // Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr> 00005 // Copyright (C) 2007-2009 Benoit Jacob <jacob.benoit.1@gmail.com> 00006 // 00007 // This Source Code Form is subject to the terms of the Mozilla 00008 // Public License v. 2.0. If a copy of the MPL was not distributed 00009 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 00010 00011 #ifndef EIGEN_DIAGONALMATRIX_H 00012 #define EIGEN_DIAGONALMATRIX_H 00013 00014 namespace Eigen { 00015 00016 #ifndef EIGEN_PARSED_BY_DOXYGEN 00017 template<typename Derived> 00018 class DiagonalBase : public EigenBase<Derived> 00019 { 00020 public: 00021 typedef typename internal::traits<Derived>::DiagonalVectorType DiagonalVectorType; 00022 typedef typename DiagonalVectorType::Scalar Scalar; 00023 typedef typename DiagonalVectorType::RealScalar RealScalar; 00024 typedef typename internal::traits<Derived>::StorageKind StorageKind; 00025 typedef typename internal::traits<Derived>::StorageIndex StorageIndex; 00026 00027 enum { 00028 RowsAtCompileTime = DiagonalVectorType::SizeAtCompileTime, 00029 ColsAtCompileTime = DiagonalVectorType::SizeAtCompileTime, 00030 MaxRowsAtCompileTime = DiagonalVectorType::MaxSizeAtCompileTime, 00031 MaxColsAtCompileTime = DiagonalVectorType::MaxSizeAtCompileTime, 00032 IsVectorAtCompileTime = 0, 00033 Flags = NoPreferredStorageOrderBit 00034 }; 00035 00036 typedef Matrix<Scalar, RowsAtCompileTime, ColsAtCompileTime, 0, MaxRowsAtCompileTime, MaxColsAtCompileTime> DenseMatrixType; 00037 typedef DenseMatrixType DenseType; 00038 typedef DiagonalMatrix<Scalar,DiagonalVectorType::SizeAtCompileTime,DiagonalVectorType::MaxSizeAtCompileTime> PlainObject; 00039 00040 EIGEN_DEVICE_FUNC 00041 inline const Derived& derived() const { return *static_cast<const Derived*>(this); } 00042 EIGEN_DEVICE_FUNC 00043 inline Derived& derived() { return *static_cast<Derived*>(this); } 00044 00045 EIGEN_DEVICE_FUNC 00046 DenseMatrixType toDenseMatrix() const { return derived(); } 00047 00048 EIGEN_DEVICE_FUNC 00049 inline const DiagonalVectorType& diagonal() const { return derived().diagonal(); } 00050 EIGEN_DEVICE_FUNC 00051 inline DiagonalVectorType& diagonal() { return derived().diagonal(); } 00052 00053 EIGEN_DEVICE_FUNC 00054 inline Index rows() const { return diagonal().size(); } 00055 EIGEN_DEVICE_FUNC 00056 inline Index cols() const { return diagonal().size(); } 00057 00058 template<typename MatrixDerived> 00059 EIGEN_DEVICE_FUNC 00060 const Product<Derived,MatrixDerived,LazyProduct> 00061 operator*(const MatrixBase<MatrixDerived> &matrix) const 00062 { 00063 return Product<Derived, MatrixDerived, LazyProduct>(derived(),matrix.derived()); 00064 } 00065 00066 typedef DiagonalWrapper<const CwiseUnaryOp<internal::scalar_inverse_op<Scalar>, const DiagonalVectorType> > InverseReturnType; 00067 EIGEN_DEVICE_FUNC 00068 inline const InverseReturnType 00069 inverse() const 00070 { 00071 return InverseReturnType(diagonal().cwiseInverse()); 00072 } 00073 00074 EIGEN_DEVICE_FUNC 00075 inline const DiagonalWrapper<const EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(DiagonalVectorType,Scalar,product) > 00076 operator*(const Scalar& scalar) const 00077 { 00078 return DiagonalWrapper<const EIGEN_EXPR_BINARYOP_SCALAR_RETURN_TYPE(DiagonalVectorType,Scalar,product) >(diagonal() * scalar); 00079 } 00080 EIGEN_DEVICE_FUNC 00081 friend inline const DiagonalWrapper<const EIGEN_SCALAR_BINARYOP_EXPR_RETURN_TYPE(Scalar,DiagonalVectorType,product) > 00082 operator*(const Scalar& scalar, const DiagonalBase& other) 00083 { 00084 return DiagonalWrapper<const EIGEN_SCALAR_BINARYOP_EXPR_RETURN_TYPE(Scalar,DiagonalVectorType,product) >(scalar * other.diagonal()); 00085 } 00086 }; 00087 00088 #endif 00089 00103 namespace internal { 00104 template<typename _Scalar, int SizeAtCompileTime, int MaxSizeAtCompileTime> 00105 struct traits<DiagonalMatrix<_Scalar,SizeAtCompileTime,MaxSizeAtCompileTime> > 00106 : traits<Matrix<_Scalar,SizeAtCompileTime,SizeAtCompileTime,0,MaxSizeAtCompileTime,MaxSizeAtCompileTime> > 00107 { 00108 typedef Matrix<_Scalar,SizeAtCompileTime,1,0,MaxSizeAtCompileTime,1> DiagonalVectorType; 00109 typedef DiagonalShape StorageKind; 00110 enum { 00111 Flags = LvalueBit | NoPreferredStorageOrderBit 00112 }; 00113 }; 00114 } 00115 template<typename _Scalar, int SizeAtCompileTime, int MaxSizeAtCompileTime> 00116 class DiagonalMatrix 00117 : public DiagonalBase<DiagonalMatrix<_Scalar,SizeAtCompileTime,MaxSizeAtCompileTime> > 00118 { 00119 public: 00120 #ifndef EIGEN_PARSED_BY_DOXYGEN 00121 typedef typename internal::traits<DiagonalMatrix>::DiagonalVectorType DiagonalVectorType; 00122 typedef const DiagonalMatrix& Nested; 00123 typedef _Scalar Scalar; 00124 typedef typename internal::traits<DiagonalMatrix>::StorageKind StorageKind; 00125 typedef typename internal::traits<DiagonalMatrix>::StorageIndex StorageIndex; 00126 #endif 00127 00128 protected: 00129 00130 DiagonalVectorType m_diagonal; 00131 00132 public: 00133 00135 EIGEN_DEVICE_FUNC 00136 inline const DiagonalVectorType& diagonal() const { return m_diagonal; } 00138 EIGEN_DEVICE_FUNC 00139 inline DiagonalVectorType& diagonal() { return m_diagonal; } 00140 00142 EIGEN_DEVICE_FUNC 00143 inline DiagonalMatrix() {} 00144 00146 EIGEN_DEVICE_FUNC 00147 explicit inline DiagonalMatrix(Index dim) : m_diagonal(dim) {} 00148 00150 EIGEN_DEVICE_FUNC 00151 inline DiagonalMatrix(const Scalar& x, const Scalar& y) : m_diagonal(x,y) {} 00152 00154 EIGEN_DEVICE_FUNC 00155 inline DiagonalMatrix(const Scalar& x, const Scalar& y, const Scalar& z) : m_diagonal(x,y,z) {} 00156 00158 template<typename OtherDerived> 00159 EIGEN_DEVICE_FUNC 00160 inline DiagonalMatrix(const DiagonalBase<OtherDerived>& other) : m_diagonal(other.diagonal()) {} 00161 00162 #ifndef EIGEN_PARSED_BY_DOXYGEN 00163 00164 inline DiagonalMatrix(const DiagonalMatrix& other) : m_diagonal(other.diagonal()) {} 00165 #endif 00166 00168 template<typename OtherDerived> 00169 EIGEN_DEVICE_FUNC 00170 explicit inline DiagonalMatrix(const MatrixBase<OtherDerived>& other) : m_diagonal(other) 00171 {} 00172 00174 template<typename OtherDerived> 00175 EIGEN_DEVICE_FUNC 00176 DiagonalMatrix& operator=(const DiagonalBase<OtherDerived>& other) 00177 { 00178 m_diagonal = other.diagonal(); 00179 return *this; 00180 } 00181 00182 #ifndef EIGEN_PARSED_BY_DOXYGEN 00183 00186 EIGEN_DEVICE_FUNC 00187 DiagonalMatrix& operator=(const DiagonalMatrix& other) 00188 { 00189 m_diagonal = other.diagonal(); 00190 return *this; 00191 } 00192 #endif 00193 00195 EIGEN_DEVICE_FUNC 00196 inline void resize(Index size) { m_diagonal.resize(size); } 00198 EIGEN_DEVICE_FUNC 00199 inline void setZero() { m_diagonal.setZero(); } 00201 EIGEN_DEVICE_FUNC 00202 inline void setZero(Index size) { m_diagonal.setZero(size); } 00204 EIGEN_DEVICE_FUNC 00205 inline void setIdentity() { m_diagonal.setOnes(); } 00207 EIGEN_DEVICE_FUNC 00208 inline void setIdentity(Index size) { m_diagonal.setOnes(size); } 00209 }; 00210 00225 namespace internal { 00226 template<typename _DiagonalVectorType> 00227 struct traits<DiagonalWrapper<_DiagonalVectorType> > 00228 { 00229 typedef _DiagonalVectorType DiagonalVectorType; 00230 typedef typename DiagonalVectorType::Scalar Scalar; 00231 typedef typename DiagonalVectorType::StorageIndex StorageIndex; 00232 typedef DiagonalShape StorageKind; 00233 typedef typename traits<DiagonalVectorType>::XprKind XprKind; 00234 enum { 00235 RowsAtCompileTime = DiagonalVectorType::SizeAtCompileTime, 00236 ColsAtCompileTime = DiagonalVectorType::SizeAtCompileTime, 00237 MaxRowsAtCompileTime = DiagonalVectorType::MaxSizeAtCompileTime, 00238 MaxColsAtCompileTime = DiagonalVectorType::MaxSizeAtCompileTime, 00239 Flags = (traits<DiagonalVectorType>::Flags & LvalueBit) | NoPreferredStorageOrderBit 00240 }; 00241 }; 00242 } 00243 00244 template<typename _DiagonalVectorType> 00245 class DiagonalWrapper 00246 : public DiagonalBase<DiagonalWrapper<_DiagonalVectorType> >, internal::no_assignment_operator 00247 { 00248 public: 00249 #ifndef EIGEN_PARSED_BY_DOXYGEN 00250 typedef _DiagonalVectorType DiagonalVectorType; 00251 typedef DiagonalWrapper Nested; 00252 #endif 00253 00255 EIGEN_DEVICE_FUNC 00256 explicit inline DiagonalWrapper(DiagonalVectorType& a_diagonal) : m_diagonal(a_diagonal) {} 00257 00259 EIGEN_DEVICE_FUNC 00260 const DiagonalVectorType& diagonal() const { return m_diagonal; } 00261 00262 protected: 00263 typename DiagonalVectorType::Nested m_diagonal; 00264 }; 00265 00275 template<typename Derived> 00276 inline const DiagonalWrapper<const Derived> 00277 MatrixBase<Derived>::asDiagonal() const 00278 { 00279 return DiagonalWrapper<const Derived>(derived()); 00280 } 00281 00290 template<typename Derived> 00291 bool MatrixBase<Derived>::isDiagonal(const RealScalar& prec) const 00292 { 00293 if(cols() != rows()) return false; 00294 RealScalar maxAbsOnDiagonal = static_cast<RealScalar>(-1); 00295 for(Index j = 0; j < cols(); ++j) 00296 { 00297 RealScalar absOnDiagonal = numext::abs(coeff(j,j)); 00298 if(absOnDiagonal > maxAbsOnDiagonal) maxAbsOnDiagonal = absOnDiagonal; 00299 } 00300 for(Index j = 0; j < cols(); ++j) 00301 for(Index i = 0; i < j; ++i) 00302 { 00303 if(!internal::isMuchSmallerThan(coeff(i, j), maxAbsOnDiagonal, prec)) return false; 00304 if(!internal::isMuchSmallerThan(coeff(j, i), maxAbsOnDiagonal, prec)) return false; 00305 } 00306 return true; 00307 } 00308 00309 namespace internal { 00310 00311 template<> struct storage_kind_to_shape<DiagonalShape> { typedef DiagonalShape Shape; }; 00312 00313 struct Diagonal2Dense {}; 00314 00315 template<> struct AssignmentKind<DenseShape,DiagonalShape> { typedef Diagonal2Dense Kind; }; 00316 00317 // Diagonal matrix to Dense assignment 00318 template< typename DstXprType, typename SrcXprType, typename Functor> 00319 struct Assignment<DstXprType, SrcXprType, Functor, Diagonal2Dense> 00320 { 00321 static void run(DstXprType &dst, const SrcXprType &src, const internal::assign_op<typename DstXprType::Scalar,typename SrcXprType::Scalar> &/*func*/) 00322 { 00323 Index dstRows = src.rows(); 00324 Index dstCols = src.cols(); 00325 if((dst.rows()!=dstRows) || (dst.cols()!=dstCols)) 00326 dst.resize(dstRows, dstCols); 00327 00328 dst.setZero(); 00329 dst.diagonal() = src.diagonal(); 00330 } 00331 00332 static void run(DstXprType &dst, const SrcXprType &src, const internal::add_assign_op<typename DstXprType::Scalar,typename SrcXprType::Scalar> &/*func*/) 00333 { dst.diagonal() += src.diagonal(); } 00334 00335 static void run(DstXprType &dst, const SrcXprType &src, const internal::sub_assign_op<typename DstXprType::Scalar,typename SrcXprType::Scalar> &/*func*/) 00336 { dst.diagonal() -= src.diagonal(); } 00337 }; 00338 00339 } // namespace internal 00340 00341 } // end namespace Eigen 00342 00343 #endif // EIGEN_DIAGONALMATRIX_H