📄 hermitian.hpp
字号:
//// Copyright (c) 2000-2002// Joerg Walter, Mathias Koch//// Permission to use, copy, modify, distribute and sell this software// and its documentation for any purpose is hereby granted without fee,// provided that the above copyright notice appear in all copies and// that both that copyright notice and this permission notice appear// in supporting documentation. The authors make no representations// about the suitability of this software for any purpose.// It is provided "as is" without express or implied warranty.//// The authors gratefully acknowledge the support of// GeNeSys mbH & Co. KG in producing this work.//#ifndef BOOST_UBLAS_HERMITIAN_H#define BOOST_UBLAS_HERMITIAN_H#include <boost/numeric/ublas/config.hpp>#include <boost/numeric/ublas/storage.hpp>#include <boost/numeric/ublas/matrix.hpp>// Iterators based on ideas of Jeremy Siek// Hermitian matrices are square. Thanks to Peter Schmitteckert for spotting this.namespace boost { namespace numeric { namespace ublas { template<class M> bool is_hermitian (const M &m) { typedef typename M::size_type size_type; if (m.size1 () != m.size2 ()) return false; size_type size = BOOST_UBLAS_SAME (m.size1 (), m.size2 ()); for (size_type i = 0; i < size; ++ i) { for (size_type j = i; j < size; ++ j) { if (m (i, j) != conj (m (j, i))) return false; } } return true; }#ifdef BOOST_UBLAS_STRICT_HERMITIAN template<class M> class hermitian_matrix_element: public container_reference<M> { public: typedef M matrix_type; typedef typename M::size_type size_type; typedef typename M::value_type value_type; typedef const value_type &const_reference; typedef value_type &reference; typedef value_type *pointer; // Construction and destruction BOOST_UBLAS_INLINE hermitian_matrix_element (matrix_type &m, size_type i, size_type j, value_type d): container_reference<matrix_type> (m), i_ (i), j_ (j), d_ (d), dirty_ (false) {} BOOST_UBLAS_INLINE hermitian_matrix_element (const hermitian_matrix_element &p): container_reference<matrix_type> (p), i_ (p.i_), d_ (p.d_), dirty_ (p.dirty_) {} BOOST_UBLAS_INLINE ~hermitian_matrix_element () { if (dirty_) ((*this) ()).at (i_, j_, d_); } // Assignment BOOST_UBLAS_INLINE hermitian_matrix_element &operator = (const hermitian_matrix_element &p) { // Overide the implict copy assignment d_ = p.d_; dirty_ = true; return *this; } template<class D> BOOST_UBLAS_INLINE hermitian_matrix_element &operator = (const D &d) { d_ = d; dirty_ = true; return *this; } template<class D> BOOST_UBLAS_INLINE hermitian_matrix_element &operator += (const D &d) { d_ += d; dirty_ = true; return *this; } template<class D> BOOST_UBLAS_INLINE hermitian_matrix_element &operator -= (const D &d) { d_ -= d; dirty_ = true; return *this; } template<class D> BOOST_UBLAS_INLINE hermitian_matrix_element &operator *= (const D &d) { d_ *= d; dirty_ = true; return *this; } template<class D> BOOST_UBLAS_INLINE hermitian_matrix_element &operator /= (const D &d) { d_ /= d; dirty_ = true; return *this; } // Comparison template<class D> BOOST_UBLAS_INLINE bool operator == (const D &d) const { return d_ == d; } template<class D> BOOST_UBLAS_INLINE bool operator != (const D &d) const { return d_ != d; } // Conversion BOOST_UBLAS_INLINE operator const_reference () const { return d_; } // Swapping BOOST_UBLAS_INLINE void swap (hermitian_matrix_element p) { if (this != &p) { dirty_ = true; p.dirty_ = true; std::swap (d_, p.d_); } }#ifndef BOOST_UBLAS_NO_MEMBER_FRIENDS BOOST_UBLAS_INLINE friend void swap (hermitian_matrix_element p1, hermitian_matrix_element p2) { p1.swap (p2); }#endif private: size_type i_; size_type j_; value_type d_; bool dirty_; }; template<class M> struct type_traits<hermitian_matrix_element<M> > { typedef typename M::value_type element_type; typedef type_traits<hermitian_matrix_element<M> > self_type; typedef typename type_traits<element_type>::value_type value_type; typedef typename type_traits<element_type>::const_reference const_reference; typedef hermitian_matrix_element<M> reference; typedef typename type_traits<element_type>::real_type real_type; typedef typename type_traits<element_type>::precision_type precision_type; BOOST_STATIC_CONSTANT (unsigned, plus_complexity = type_traits<element_type>::plus_complexity); BOOST_STATIC_CONSTANT (unsigned, multiplies_complexity = type_traits<element_type>::multiplies_complexity); static BOOST_UBLAS_INLINE real_type real (const_reference t) { return type_traits<element_type>::real (t); } static BOOST_UBLAS_INLINE real_type imag (const_reference t) { return type_traits<element_type>::imag (t); } static BOOST_UBLAS_INLINE value_type conj (const_reference t) { return type_traits<element_type>::conj (t); } static BOOST_UBLAS_INLINE real_type abs (const_reference t) { return type_traits<element_type>::abs (t); } static BOOST_UBLAS_INLINE value_type sqrt (const_reference t) { return type_traits<element_type>::sqrt (t); } static BOOST_UBLAS_INLINE real_type norm_1 (const_reference t) { return type_traits<element_type>::norm_1 (t); } static BOOST_UBLAS_INLINE real_type norm_2 (const_reference t) { return type_traits<element_type>::norm_2 (t); } static BOOST_UBLAS_INLINE real_type norm_inf (const_reference t) { return type_traits<element_type>::norm_inf (t); } static BOOST_UBLAS_INLINE bool equals (const_reference t1, const_reference t2) { return type_traits<element_type>::equals (t1, t2); } }; template<class M1, class T2> struct promote_traits<hermitian_matrix_element<M1>, T2> { typedef typename promote_traits<typename hermitian_matrix_element<M1>::value_type, T2>::promote_type promote_type; }; template<class T1, class M2> struct promote_traits<T1, hermitian_matrix_element<M2> > { typedef typename promote_traits<T1, typename hermitian_matrix_element<M2>::value_type>::promote_type promote_type; }; template<class M1, class M2> struct promote_traits<hermitian_matrix_element<M1>, hermitian_matrix_element<M2> > { typedef typename promote_traits<typename hermitian_matrix_element<M1>::value_type, typename hermitian_matrix_element<M2>::value_type>::promote_type promote_type; };#endif // Array based hermitian matrix class template<class T, class F1, class F2, class A> class hermitian_matrix: public matrix_expression<hermitian_matrix<T, F1, F2, A> > { public:#ifndef BOOST_UBLAS_NO_PROXY_SHORTCUTS BOOST_UBLAS_USING matrix_expression<hermitian_matrix<T, F1, F2, A> >::operator ();#endif typedef typename A::size_type size_type; typedef typename A::difference_type difference_type; typedef T value_type; // FIXME: no better way to not return the address of a temporary? // typedef const T &const_reference; typedef const T const_reference;#ifndef BOOST_UBLAS_STRICT_HERMITIAN typedef T &reference;#else typedef hermitian_matrix_element<hermitian_matrix<T, F1, F2, A> > reference;#endif typedef A array_type; private: typedef T &true_reference; typedef T *pointer; typedef F1 functor1_type; typedef F2 functor2_type; typedef hermitian_matrix<T, F1, F2, A> self_type; public:#ifndef BOOST_UBLAS_CT_REFERENCE_BASE_TYPEDEFS typedef const matrix_const_reference<const self_type> const_closure_type;#else typedef const matrix_reference<const self_type> const_closure_type;#endif typedef matrix_reference<self_type> closure_type; typedef vector<T, A> vector_temporary_type; typedef matrix<T, F2, A> matrix_temporary_type; // general sub-matrix typedef packed_tag storage_category; typedef typename F1::packed_category packed_category; typedef typename F2::orientation_category orientation_category; // Construction and destruction BOOST_UBLAS_INLINE hermitian_matrix (): matrix_expression<self_type> (), size_ (0), data_ (0) {} BOOST_UBLAS_INLINE hermitian_matrix (size_type size): matrix_expression<self_type> (), size_ (BOOST_UBLAS_SAME (size, size)), data_ (functor1_type::packed_size (size, size)) { } BOOST_UBLAS_INLINE hermitian_matrix (size_type size1, size_type size2): matrix_expression<self_type> (), size_ (BOOST_UBLAS_SAME (size1, size2)), data_ (functor1_type::packed_size (size1, size2)) { } BOOST_UBLAS_INLINE hermitian_matrix (size_type size, const array_type &data): matrix_expression<self_type> (), size_ (size), data_ (data) {} BOOST_UBLAS_INLINE hermitian_matrix (const hermitian_matrix &m): matrix_expression<self_type> (), size_ (m.size_), data_ (m.data_) {} template<class AE> BOOST_UBLAS_INLINE hermitian_matrix (const matrix_expression<AE> &ae): matrix_expression<self_type> (), size_ (BOOST_UBLAS_SAME (ae ().size1 (), ae ().size2 ())), data_ (functor1_type::packed_size (size_, size_)) { matrix_assign (scalar_assign<true_reference, BOOST_UBLAS_TYPENAME AE::value_type> (), *this, ae); } // Accessors BOOST_UBLAS_INLINE size_type size1 () const { return size_; } BOOST_UBLAS_INLINE size_type size2 () const { return size_; } BOOST_UBLAS_INLINE const array_type &data () const { return data_; } BOOST_UBLAS_INLINE array_type &data () { return data_; } // Resizing BOOST_UBLAS_INLINE void resize (size_type size, bool preserve = true) { size_ = size; if (preserve) { self_type temporary (size_, size_);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -