MOAB
4.9.3pre
|
00001 // This file is part of Eigen, a lightweight C++ template library 00002 // for linear algebra. 00003 // 00004 // Copyright (C) 2009 Gael Guennebaud <[email protected]> 00005 // Copyright (C) 2007-2009 Benoit Jacob <[email protected]> 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 typedef DiagonalWrapper<const CwiseUnaryOp<internal::scalar_multiple_op<Scalar>, const DiagonalVectorType> > ScalarMultipleReturnType; 00075 EIGEN_DEVICE_FUNC 00076 inline const ScalarMultipleReturnType 00077 operator*(const Scalar& scalar) const 00078 { 00079 return ScalarMultipleReturnType(diagonal() * scalar); 00080 } 00081 EIGEN_DEVICE_FUNC 00082 friend inline const ScalarMultipleReturnType 00083 operator*(const Scalar& scalar, const DiagonalBase& other) 00084 { 00085 return ScalarMultipleReturnType(other.diagonal() * scalar); 00086 } 00087 }; 00088 00089 #endif 00090 00104 namespace internal { 00105 template<typename _Scalar, int SizeAtCompileTime, int MaxSizeAtCompileTime> 00106 struct traits<DiagonalMatrix<_Scalar,SizeAtCompileTime,MaxSizeAtCompileTime> > 00107 : traits<Matrix<_Scalar,SizeAtCompileTime,SizeAtCompileTime,0,MaxSizeAtCompileTime,MaxSizeAtCompileTime> > 00108 { 00109 typedef Matrix<_Scalar,SizeAtCompileTime,1,0,MaxSizeAtCompileTime,1> DiagonalVectorType; 00110 typedef DiagonalShape StorageKind; 00111 enum { 00112 Flags = LvalueBit | NoPreferredStorageOrderBit 00113 }; 00114 }; 00115 } 00116 template<typename _Scalar, int SizeAtCompileTime, int MaxSizeAtCompileTime> 00117 class DiagonalMatrix 00118 : public DiagonalBase<DiagonalMatrix<_Scalar,SizeAtCompileTime,MaxSizeAtCompileTime> > 00119 { 00120 public: 00121 #ifndef EIGEN_PARSED_BY_DOXYGEN 00122 typedef typename internal::traits<DiagonalMatrix>::DiagonalVectorType DiagonalVectorType; 00123 typedef const DiagonalMatrix& Nested; 00124 typedef _Scalar Scalar; 00125 typedef typename internal::traits<DiagonalMatrix>::StorageKind StorageKind; 00126 typedef typename internal::traits<DiagonalMatrix>::StorageIndex StorageIndex; 00127 #endif 00128 00129 protected: 00130 00131 DiagonalVectorType m_diagonal; 00132 00133 public: 00134 00136 EIGEN_DEVICE_FUNC 00137 inline const DiagonalVectorType& diagonal() const { return m_diagonal; } 00139 EIGEN_DEVICE_FUNC 00140 inline DiagonalVectorType& diagonal() { return m_diagonal; } 00141 00143 EIGEN_DEVICE_FUNC 00144 inline DiagonalMatrix() {} 00145 00147 EIGEN_DEVICE_FUNC 00148 explicit inline DiagonalMatrix(Index dim) : m_diagonal(dim) {} 00149 00151 EIGEN_DEVICE_FUNC 00152 inline DiagonalMatrix(const Scalar& x, const Scalar& y) : m_diagonal(x,y) {} 00153 00155 EIGEN_DEVICE_FUNC 00156 inline DiagonalMatrix(const Scalar& x, const Scalar& y, const Scalar& z) : m_diagonal(x,y,z) {} 00157 00159 template<typename OtherDerived> 00160 EIGEN_DEVICE_FUNC 00161 inline DiagonalMatrix(const DiagonalBase<OtherDerived>& other) : m_diagonal(other.diagonal()) {} 00162 00163 #ifndef EIGEN_PARSED_BY_DOXYGEN 00164 00165 inline DiagonalMatrix(const DiagonalMatrix& other) : m_diagonal(other.diagonal()) {} 00166 #endif 00167 00169 template<typename OtherDerived> 00170 EIGEN_DEVICE_FUNC 00171 explicit inline DiagonalMatrix(const MatrixBase<OtherDerived>& other) : m_diagonal(other) 00172 {} 00173 00175 template<typename OtherDerived> 00176 EIGEN_DEVICE_FUNC 00177 DiagonalMatrix& operator=(const DiagonalBase<OtherDerived>& other) 00178 { 00179 m_diagonal = other.diagonal(); 00180 return *this; 00181 } 00182 00183 #ifndef EIGEN_PARSED_BY_DOXYGEN 00184 00187 EIGEN_DEVICE_FUNC 00188 DiagonalMatrix& operator=(const DiagonalMatrix& other) 00189 { 00190 m_diagonal = other.diagonal(); 00191 return *this; 00192 } 00193 #endif 00194 00196 EIGEN_DEVICE_FUNC 00197 inline void resize(Index size) { m_diagonal.resize(size); } 00199 EIGEN_DEVICE_FUNC 00200 inline void setZero() { m_diagonal.setZero(); } 00202 EIGEN_DEVICE_FUNC 00203 inline void setZero(Index size) { m_diagonal.setZero(size); } 00205 EIGEN_DEVICE_FUNC 00206 inline void setIdentity() { m_diagonal.setOnes(); } 00208 EIGEN_DEVICE_FUNC 00209 inline void setIdentity(Index size) { m_diagonal.setOnes(size); } 00210 }; 00211 00226 namespace internal { 00227 template<typename _DiagonalVectorType> 00228 struct traits<DiagonalWrapper<_DiagonalVectorType> > 00229 { 00230 typedef _DiagonalVectorType DiagonalVectorType; 00231 typedef typename DiagonalVectorType::Scalar Scalar; 00232 typedef typename DiagonalVectorType::StorageIndex StorageIndex; 00233 typedef DiagonalShape StorageKind; 00234 typedef typename traits<DiagonalVectorType>::XprKind XprKind; 00235 enum { 00236 RowsAtCompileTime = DiagonalVectorType::SizeAtCompileTime, 00237 ColsAtCompileTime = DiagonalVectorType::SizeAtCompileTime, 00238 MaxRowsAtCompileTime = DiagonalVectorType::MaxSizeAtCompileTime, 00239 MaxColsAtCompileTime = DiagonalVectorType::MaxSizeAtCompileTime, 00240 Flags = (traits<DiagonalVectorType>::Flags & LvalueBit) | NoPreferredStorageOrderBit 00241 }; 00242 }; 00243 } 00244 00245 template<typename _DiagonalVectorType> 00246 class DiagonalWrapper 00247 : public DiagonalBase<DiagonalWrapper<_DiagonalVectorType> >, internal::no_assignment_operator 00248 { 00249 public: 00250 #ifndef EIGEN_PARSED_BY_DOXYGEN 00251 typedef _DiagonalVectorType DiagonalVectorType; 00252 typedef DiagonalWrapper Nested; 00253 #endif 00254 00256 EIGEN_DEVICE_FUNC 00257 explicit inline DiagonalWrapper(DiagonalVectorType& a_diagonal) : m_diagonal(a_diagonal) {} 00258 00260 EIGEN_DEVICE_FUNC 00261 const DiagonalVectorType& diagonal() const { return m_diagonal; } 00262 00263 protected: 00264 typename DiagonalVectorType::Nested m_diagonal; 00265 }; 00266 00276 template<typename Derived> 00277 inline const DiagonalWrapper<const Derived> 00278 MatrixBase<Derived>::asDiagonal() const 00279 { 00280 return DiagonalWrapper<const Derived>(derived()); 00281 } 00282 00291 template<typename Derived> 00292 bool MatrixBase<Derived>::isDiagonal(const RealScalar& prec) const 00293 { 00294 using std::abs; 00295 if(cols() != rows()) return false; 00296 RealScalar maxAbsOnDiagonal = static_cast<RealScalar>(-1); 00297 for(Index j = 0; j < cols(); ++j) 00298 { 00299 RealScalar absOnDiagonal = abs(coeff(j,j)); 00300 if(absOnDiagonal > maxAbsOnDiagonal) maxAbsOnDiagonal = absOnDiagonal; 00301 } 00302 for(Index j = 0; j < cols(); ++j) 00303 for(Index i = 0; i < j; ++i) 00304 { 00305 if(!internal::isMuchSmallerThan(coeff(i, j), maxAbsOnDiagonal, prec)) return false; 00306 if(!internal::isMuchSmallerThan(coeff(j, i), maxAbsOnDiagonal, prec)) return false; 00307 } 00308 return true; 00309 } 00310 00311 namespace internal { 00312 00313 template<> struct storage_kind_to_shape<DiagonalShape> { typedef DiagonalShape Shape; }; 00314 00315 struct Diagonal2Dense {}; 00316 00317 template<> struct AssignmentKind<DenseShape,DiagonalShape> { typedef Diagonal2Dense Kind; }; 00318 00319 // Diagonal matrix to Dense assignment 00320 template< typename DstXprType, typename SrcXprType, typename Functor, typename Scalar> 00321 struct Assignment<DstXprType, SrcXprType, Functor, Diagonal2Dense, Scalar> 00322 { 00323 static void run(DstXprType &dst, const SrcXprType &src, const internal::assign_op<typename DstXprType::Scalar> &/*func*/) 00324 { 00325 dst.setZero(); 00326 dst.diagonal() = src.diagonal(); 00327 } 00328 00329 static void run(DstXprType &dst, const SrcXprType &src, const internal::add_assign_op<typename DstXprType::Scalar> &/*func*/) 00330 { dst.diagonal() += src.diagonal(); } 00331 00332 static void run(DstXprType &dst, const SrcXprType &src, const internal::sub_assign_op<typename DstXprType::Scalar> &/*func*/) 00333 { dst.diagonal() -= src.diagonal(); } 00334 }; 00335 00336 } // namespace internal 00337 00338 } // end namespace Eigen 00339 00340 #endif // EIGEN_DIAGONALMATRIX_H