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 // 00006 // This Source Code Form is subject to the terms of the Mozilla 00007 // Public License v. 2.0. If a copy of the MPL was not distributed 00008 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 00009 00010 #ifndef EIGEN_SELFADJOINTMATRIX_H 00011 #define EIGEN_SELFADJOINTMATRIX_H 00012 00013 namespace Eigen { 00014 00031 namespace internal { 00032 template<typename MatrixType, unsigned int UpLo> 00033 struct traits<SelfAdjointView<MatrixType, UpLo> > : traits<MatrixType> 00034 { 00035 typedef typename ref_selector<MatrixType>::non_const_type MatrixTypeNested; 00036 typedef typename remove_all<MatrixTypeNested>::type MatrixTypeNestedCleaned; 00037 typedef MatrixType ExpressionType; 00038 typedef typename MatrixType::PlainObject FullMatrixType; 00039 enum { 00040 Mode = UpLo | SelfAdjoint, 00041 FlagsLvalueBit = is_lvalue<MatrixType>::value ? LvalueBit : 0, 00042 Flags = MatrixTypeNestedCleaned::Flags & (HereditaryBits|FlagsLvalueBit) 00043 & (~(PacketAccessBit | DirectAccessBit | LinearAccessBit)) // FIXME these flags should be preserved 00044 }; 00045 }; 00046 } 00047 00048 // FIXME could also be called SelfAdjointWrapper to be consistent with DiagonalWrapper ?? 00049 template<typename _MatrixType, unsigned int UpLo> class SelfAdjointView 00050 : public TriangularBase<SelfAdjointView<_MatrixType, UpLo> > 00051 { 00052 public: 00053 00054 typedef _MatrixType MatrixType; 00055 typedef TriangularBase<SelfAdjointView> Base; 00056 typedef typename internal::traits<SelfAdjointView>::MatrixTypeNested MatrixTypeNested; 00057 typedef typename internal::traits<SelfAdjointView>::MatrixTypeNestedCleaned MatrixTypeNestedCleaned; 00058 00060 typedef typename internal::traits<SelfAdjointView>::Scalar Scalar; 00061 typedef typename MatrixType::StorageIndex StorageIndex; 00062 00063 enum { 00064 Mode = internal::traits<SelfAdjointView>::Mode, 00065 Flags = internal::traits<SelfAdjointView>::Flags 00066 }; 00067 typedef typename MatrixType::PlainObject PlainObject; 00068 00069 EIGEN_DEVICE_FUNC 00070 explicit inline SelfAdjointView(MatrixType& matrix) : m_matrix(matrix) 00071 {} 00072 00073 EIGEN_DEVICE_FUNC 00074 inline Index rows() const { return m_matrix.rows(); } 00075 EIGEN_DEVICE_FUNC 00076 inline Index cols() const { return m_matrix.cols(); } 00077 EIGEN_DEVICE_FUNC 00078 inline Index outerStride() const { return m_matrix.outerStride(); } 00079 EIGEN_DEVICE_FUNC 00080 inline Index innerStride() const { return m_matrix.innerStride(); } 00081 00085 EIGEN_DEVICE_FUNC 00086 inline Scalar coeff(Index row, Index col) const 00087 { 00088 Base::check_coordinates_internal(row, col); 00089 return m_matrix.coeff(row, col); 00090 } 00091 00095 EIGEN_DEVICE_FUNC 00096 inline Scalar& coeffRef(Index row, Index col) 00097 { 00098 EIGEN_STATIC_ASSERT_LVALUE(SelfAdjointView); 00099 Base::check_coordinates_internal(row, col); 00100 return m_matrix.coeffRef(row, col); 00101 } 00102 00104 EIGEN_DEVICE_FUNC 00105 const MatrixTypeNestedCleaned& _expression() const { return m_matrix; } 00106 00107 EIGEN_DEVICE_FUNC 00108 const MatrixTypeNestedCleaned& nestedExpression() const { return m_matrix; } 00109 EIGEN_DEVICE_FUNC 00110 MatrixTypeNestedCleaned& nestedExpression() { return m_matrix; } 00111 00113 template<typename OtherDerived> 00114 EIGEN_DEVICE_FUNC 00115 const Product<SelfAdjointView,OtherDerived> 00116 operator*(const MatrixBase<OtherDerived>& rhs) const 00117 { 00118 return Product<SelfAdjointView,OtherDerived>(*this, rhs.derived()); 00119 } 00120 00122 template<typename OtherDerived> friend 00123 EIGEN_DEVICE_FUNC 00124 const Product<OtherDerived,SelfAdjointView> 00125 operator*(const MatrixBase<OtherDerived>& lhs, const SelfAdjointView& rhs) 00126 { 00127 return Product<OtherDerived,SelfAdjointView>(lhs.derived(),rhs); 00128 } 00129 00130 friend EIGEN_DEVICE_FUNC 00131 const SelfAdjointView<const CwiseUnaryOp<internal::scalar_multiple_op<Scalar>,MatrixType>,UpLo> 00132 operator*(const Scalar& s, const SelfAdjointView& mat) 00133 { 00134 return (s*mat.nestedExpression()).template selfadjointView<UpLo>(); 00135 } 00136 00147 template<typename DerivedU, typename DerivedV> 00148 EIGEN_DEVICE_FUNC 00149 SelfAdjointView& rankUpdate(const MatrixBase<DerivedU>& u, const MatrixBase<DerivedV>& v, const Scalar& alpha = Scalar(1)); 00150 00161 template<typename DerivedU> 00162 EIGEN_DEVICE_FUNC 00163 SelfAdjointView& rankUpdate(const MatrixBase<DerivedU>& u, const Scalar& alpha = Scalar(1)); 00164 00166 00167 const LLT<PlainObject, UpLo> llt() const; 00168 const LDLT<PlainObject, UpLo> ldlt() const; 00169 00171 00173 typedef typename NumTraits<Scalar>::Real RealScalar; 00175 typedef Matrix<RealScalar, internal::traits<MatrixType>::ColsAtCompileTime, 1> EigenvaluesReturnType; 00176 00177 EIGEN_DEVICE_FUNC 00178 EigenvaluesReturnType eigenvalues() const; 00179 EIGEN_DEVICE_FUNC 00180 RealScalar operatorNorm() const; 00181 00182 protected: 00183 MatrixTypeNested m_matrix; 00184 }; 00185 00186 00187 // template<typename OtherDerived, typename MatrixType, unsigned int UpLo> 00188 // internal::selfadjoint_matrix_product_returntype<OtherDerived,SelfAdjointView<MatrixType,UpLo> > 00189 // operator*(const MatrixBase<OtherDerived>& lhs, const SelfAdjointView<MatrixType,UpLo>& rhs) 00190 // { 00191 // return internal::matrix_selfadjoint_product_returntype<OtherDerived,SelfAdjointView<MatrixType,UpLo> >(lhs.derived(),rhs); 00192 // } 00193 00194 // selfadjoint to dense matrix 00195 00196 namespace internal { 00197 00198 // TODO currently a selfadjoint expression has the form SelfAdjointView<.,.> 00199 // in the future selfadjoint-ness should be defined by the expression traits 00200 // such that Transpose<SelfAdjointView<.,.> > is valid. (currently TriangularBase::transpose() is overloaded to make it work) 00201 template<typename MatrixType, unsigned int Mode> 00202 struct evaluator_traits<SelfAdjointView<MatrixType,Mode> > 00203 { 00204 typedef typename storage_kind_to_evaluator_kind<typename MatrixType::StorageKind>::Kind Kind; 00205 typedef SelfAdjointShape Shape; 00206 }; 00207 00208 template<int UpLo, int SetOpposite, typename DstEvaluatorTypeT, typename SrcEvaluatorTypeT, typename Functor, int Version> 00209 class triangular_dense_assignment_kernel<UpLo,SelfAdjoint,SetOpposite,DstEvaluatorTypeT,SrcEvaluatorTypeT,Functor,Version> 00210 : public generic_dense_assignment_kernel<DstEvaluatorTypeT, SrcEvaluatorTypeT, Functor, Version> 00211 { 00212 protected: 00213 typedef generic_dense_assignment_kernel<DstEvaluatorTypeT, SrcEvaluatorTypeT, Functor, Version> Base; 00214 typedef typename Base::DstXprType DstXprType; 00215 typedef typename Base::SrcXprType SrcXprType; 00216 using Base::m_dst; 00217 using Base::m_src; 00218 using Base::m_functor; 00219 public: 00220 00221 typedef typename Base::DstEvaluatorType DstEvaluatorType; 00222 typedef typename Base::SrcEvaluatorType SrcEvaluatorType; 00223 typedef typename Base::Scalar Scalar; 00224 typedef typename Base::AssignmentTraits AssignmentTraits; 00225 00226 00227 EIGEN_DEVICE_FUNC triangular_dense_assignment_kernel(DstEvaluatorType &dst, const SrcEvaluatorType &src, const Functor &func, DstXprType& dstExpr) 00228 : Base(dst, src, func, dstExpr) 00229 {} 00230 00231 EIGEN_DEVICE_FUNC void assignCoeff(Index row, Index col) 00232 { 00233 eigen_internal_assert(row!=col); 00234 Scalar tmp = m_src.coeff(row,col); 00235 m_functor.assignCoeff(m_dst.coeffRef(row,col), tmp); 00236 m_functor.assignCoeff(m_dst.coeffRef(col,row), numext::conj(tmp)); 00237 } 00238 00239 EIGEN_DEVICE_FUNC void assignDiagonalCoeff(Index id) 00240 { 00241 Base::assignCoeff(id,id); 00242 } 00243 00244 EIGEN_DEVICE_FUNC void assignOppositeCoeff(Index, Index) 00245 { eigen_internal_assert(false && "should never be called"); } 00246 }; 00247 00248 } // end namespace internal 00249 00250 /*************************************************************************** 00251 * Implementation of MatrixBase methods 00252 ***************************************************************************/ 00253 00254 template<typename Derived> 00255 template<unsigned int UpLo> 00256 typename MatrixBase<Derived>::template ConstSelfAdjointViewReturnType<UpLo>::Type 00257 MatrixBase<Derived>::selfadjointView() const 00258 { 00259 return typename ConstSelfAdjointViewReturnType<UpLo>::Type(derived()); 00260 } 00261 00262 template<typename Derived> 00263 template<unsigned int UpLo> 00264 typename MatrixBase<Derived>::template SelfAdjointViewReturnType<UpLo>::Type 00265 MatrixBase<Derived>::selfadjointView() 00266 { 00267 return typename SelfAdjointViewReturnType<UpLo>::Type(derived()); 00268 } 00269 00270 } // end namespace Eigen 00271 00272 #endif // EIGEN_SELFADJOINTMATRIX_H