You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							605 lines
						
					
					
						
							26 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							605 lines
						
					
					
						
							26 KiB
						
					
					
				
								/* -*- c++ -*- (enables emacs c++ mode) */
							 | 
						|
								/*===========================================================================
							 | 
						|
								 
							 | 
						|
								 Copyright (C) 2003-2012 Yves Renard
							 | 
						|
								 
							 | 
						|
								 This file is a part of GETFEM++
							 | 
						|
								 
							 | 
						|
								 Getfem++  is  free software;  you  can  redistribute  it  and/or modify it
							 | 
						|
								 under  the  terms  of the  GNU  Lesser General Public License as published
							 | 
						|
								 by  the  Free Software Foundation;  either version 3 of the License,  or
							 | 
						|
								 (at your option) any later version along with the GCC Runtime Library
							 | 
						|
								 Exception either version 3.1 or (at your option) any later version.
							 | 
						|
								 This program  is  distributed  in  the  hope  that it will be useful,  but
							 | 
						|
								 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
							 | 
						|
								 or  FITNESS  FOR  A PARTICULAR PURPOSE.  See the GNU Lesser General Public
							 | 
						|
								 License and GCC Runtime Library Exception for more details.
							 | 
						|
								 You  should  have received a copy of the GNU Lesser General Public License
							 | 
						|
								 along  with  this program;  if not, write to the Free Software Foundation,
							 | 
						|
								 Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA.
							 | 
						|
								 
							 | 
						|
								 As a special exception, you  may use  this file  as it is a part of a free
							 | 
						|
								 software  library  without  restriction.  Specifically,  if   other  files
							 | 
						|
								 instantiate  templates  or  use macros or inline functions from this file,
							 | 
						|
								 or  you compile this  file  and  link  it  with other files  to produce an
							 | 
						|
								 executable, this file  does  not  by itself cause the resulting executable
							 | 
						|
								 to be covered  by the GNU Lesser General Public License.  This   exception
							 | 
						|
								 does not  however  invalidate  any  other  reasons why the executable file
							 | 
						|
								 might be covered by the GNU Lesser General Public License.
							 | 
						|
								 
							 | 
						|
								===========================================================================*/
							 | 
						|
								
							 | 
						|
								/**@file gmm_real_part.h
							 | 
						|
								   @author  Yves Renard <Yves.Renard@insa-lyon.fr>
							 | 
						|
								   @date September 18, 2003.
							 | 
						|
								   @brief extract the real/imaginary part of vectors/matrices 
							 | 
						|
								*/
							 | 
						|
								#ifndef GMM_REAL_PART_H
							 | 
						|
								#define GMM_REAL_PART_H
							 | 
						|
								
							 | 
						|
								#include "gmm_def.h"
							 | 
						|
								#include "gmm_vector.h"
							 | 
						|
								
							 | 
						|
								namespace gmm {
							 | 
						|
								
							 | 
						|
								  struct linalg_real_part {};
							 | 
						|
								  struct linalg_imag_part {};
							 | 
						|
								  template <typename R, typename PART> struct which_part {};
							 | 
						|
								  
							 | 
						|
								  template <typename C> typename number_traits<C>::magnitude_type 
							 | 
						|
								  real_or_imag_part(C x, linalg_real_part) { return gmm::real(x); }
							 | 
						|
								  template <typename C> typename number_traits<C>::magnitude_type 
							 | 
						|
								  real_or_imag_part(C x, linalg_imag_part) { return gmm::imag(x); }
							 | 
						|
								  template <typename T, typename C, typename OP> C
							 | 
						|
								  complex_from(T x, C y, OP op, linalg_real_part) { return std::complex<T>(op(std::real(y), x), std::imag(y)); }
							 | 
						|
								  template <typename T, typename C, typename OP> C
							 | 
						|
								  complex_from(T x, C y, OP op,linalg_imag_part) { return std::complex<T>(std::real(y), op(std::imag(y), x)); }
							 | 
						|
								  
							 | 
						|
								  template<typename T> struct project2nd {
							 | 
						|
								    T operator()(T , T b) const { return b; }
							 | 
						|
								  };
							 | 
						|
								  
							 | 
						|
								  template<typename T, typename R, typename PART> class ref_elt_vector<T, which_part<R, PART> > {
							 | 
						|
								
							 | 
						|
								    R r;
							 | 
						|
								    
							 | 
						|
								    public :
							 | 
						|
								
							 | 
						|
								    operator T() const { return real_or_imag_part(std::complex<T>(r), PART()); }
							 | 
						|
								    ref_elt_vector(R r_) : r(r_) {}
							 | 
						|
								    inline ref_elt_vector &operator =(T v)
							 | 
						|
								    { r = complex_from(v, std::complex<T>(r), gmm::project2nd<T>(), PART()); return *this; }
							 | 
						|
								    inline bool operator ==(T v) const { return (r == v); }
							 | 
						|
								    inline bool operator !=(T v) const { return (r != v); }
							 | 
						|
								    inline ref_elt_vector &operator +=(T v)
							 | 
						|
								    { r = complex_from(v, std::complex<T>(r), std::plus<T>(), PART()); return *this; }
							 | 
						|
								    inline ref_elt_vector &operator -=(T v)
							 | 
						|
								      { r = complex_from(v, std::complex<T>(r), std::minus<T>(), PART()); return *this; }
							 | 
						|
								    inline ref_elt_vector &operator /=(T v)
							 | 
						|
								      { r = complex_from(v, std::complex<T>(r), std::divides<T>(), PART()); return *this; }
							 | 
						|
								    inline ref_elt_vector &operator *=(T v)
							 | 
						|
								      { r = complex_from(v, std::complex<T>(r), std::multiplies<T>(), PART()); return *this; }
							 | 
						|
								    inline ref_elt_vector &operator =(const ref_elt_vector &re)
							 | 
						|
								      { *this = T(re); return *this; }
							 | 
						|
								    T operator +()    { return  T(*this);   } // necessary for unknow reason
							 | 
						|
								    T operator -()    { return -T(*this);   } // necessary for unknow reason
							 | 
						|
								    T operator +(T v) { return T(*this)+ v; } // necessary for unknow reason
							 | 
						|
								    T operator -(T v) { return T(*this)- v; } // necessary for unknow reason
							 | 
						|
								    T operator *(T v) { return T(*this)* v; } // necessary for unknow reason
							 | 
						|
								    T operator /(T v) { return T(*this)/ v; } // necessary for unknow reason
							 | 
						|
								  };
							 | 
						|
								
							 | 
						|
								  template<typename reference> struct ref_or_value_type {
							 | 
						|
								    template <typename T, typename W>
							 | 
						|
								    static W r(const T &x, linalg_real_part, W) {
							 | 
						|
								      return gmm::real(x);
							 | 
						|
								    }
							 | 
						|
								    template <typename T, typename W>
							 | 
						|
								    static W r(const T &x, linalg_imag_part, W) {
							 | 
						|
								      return gmm::imag(x);
							 | 
						|
								    }
							 | 
						|
								  };
							 | 
						|
								  
							 | 
						|
								  template<typename U, typename R, typename PART> 
							 | 
						|
								  struct ref_or_value_type<ref_elt_vector<U, which_part<R, PART> > > {
							 | 
						|
								    template<typename T , typename W> 
							 | 
						|
								    static const T &r(const T &x, linalg_real_part, W)
							 | 
						|
								    { return x; }
							 | 
						|
								    template<typename T, typename W> 
							 | 
						|
								    static const T &r(const T &x, linalg_imag_part, W) {
							 | 
						|
								      return x; 
							 | 
						|
								    }
							 | 
						|
								    template<typename T , typename W> 
							 | 
						|
								    static T &r(T &x, linalg_real_part, W)
							 | 
						|
								    { return x; }
							 | 
						|
								    template<typename T, typename W> 
							 | 
						|
								    static T &r(T &x, linalg_imag_part, W) {
							 | 
						|
								      return x; 
							 | 
						|
								    }
							 | 
						|
								  };
							 | 
						|
								
							 | 
						|
								  
							 | 
						|
								  /* ********************************************************************* */
							 | 
						|
								  /*	Reference to the real part of (complex) vectors            	   */
							 | 
						|
								  /* ********************************************************************* */
							 | 
						|
								
							 | 
						|
								  template <typename IT, typename MIT, typename PART>
							 | 
						|
								  struct part_vector_iterator {
							 | 
						|
								    typedef typename std::iterator_traits<IT>::value_type      vtype;
							 | 
						|
								    typedef typename gmm::number_traits<vtype>::magnitude_type value_type;
							 | 
						|
								    typedef value_type                                        *pointer;
							 | 
						|
								    typedef ref_elt_vector<value_type, which_part<typename std::iterator_traits<IT>::reference, PART> > reference;
							 | 
						|
								    typedef typename std::iterator_traits<IT>::difference_type difference_type;
							 | 
						|
								    typedef typename std::iterator_traits<IT>::iterator_category
							 | 
						|
								    iterator_category;
							 | 
						|
								
							 | 
						|
								    IT it;
							 | 
						|
								    
							 | 
						|
								    part_vector_iterator(void) {}
							 | 
						|
								    explicit part_vector_iterator(const IT &i) : it(i) {}
							 | 
						|
								    part_vector_iterator(const part_vector_iterator<MIT, MIT, PART> &i) : it(i.it) {}
							 | 
						|
								    
							 | 
						|
								
							 | 
						|
								    size_type index(void) const { return it.index(); }
							 | 
						|
								    part_vector_iterator operator ++(int)
							 | 
						|
								    { part_vector_iterator tmp = *this; ++it; return tmp; }
							 | 
						|
								    part_vector_iterator operator --(int) 
							 | 
						|
								    { part_vector_iterator tmp = *this; --it; return tmp; }
							 | 
						|
								    part_vector_iterator &operator ++() { ++it; return *this; }
							 | 
						|
								    part_vector_iterator &operator --() { --it; return *this; }
							 | 
						|
								    part_vector_iterator &operator +=(difference_type i)
							 | 
						|
								      { it += i; return *this; }
							 | 
						|
								    part_vector_iterator &operator -=(difference_type i)
							 | 
						|
								      { it -= i; return *this; }
							 | 
						|
								    part_vector_iterator operator +(difference_type i) const
							 | 
						|
								      { part_vector_iterator itb = *this; return (itb += i); }
							 | 
						|
								    part_vector_iterator operator -(difference_type i) const
							 | 
						|
								      { part_vector_iterator itb = *this; return (itb -= i); }
							 | 
						|
								    difference_type operator -(const part_vector_iterator &i) const
							 | 
						|
								      { return difference_type(it - i.it); }
							 | 
						|
								    
							 | 
						|
								    reference operator  *() const { return reference(*it); }
							 | 
						|
								    reference operator [](size_type ii) const { return reference(it[ii]); }
							 | 
						|
								    
							 | 
						|
								    bool operator ==(const part_vector_iterator &i) const
							 | 
						|
								      { return (i.it == it); }
							 | 
						|
								    bool operator !=(const part_vector_iterator &i) const
							 | 
						|
								      { return (i.it != it); }
							 | 
						|
								    bool operator < (const part_vector_iterator &i) const
							 | 
						|
								      { return (it < i.it); }
							 | 
						|
								  };
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								  template <typename PT, typename PART> struct part_vector {
							 | 
						|
								    typedef part_vector<PT, PART> this_type;
							 | 
						|
								    typedef typename std::iterator_traits<PT>::value_type V;
							 | 
						|
								    typedef V * CPT;
							 | 
						|
								    typedef typename select_ref<typename linalg_traits<V>::const_iterator,
							 | 
						|
								            typename linalg_traits<V>::iterator, PT>::ref_type iterator;
							 | 
						|
								    typedef typename linalg_traits<this_type>::reference reference;
							 | 
						|
								    typedef typename linalg_traits<this_type>::value_type value_type;
							 | 
						|
								    typedef typename linalg_traits<this_type>::porigin_type porigin_type;
							 | 
						|
								
							 | 
						|
								    iterator begin_, end_;
							 | 
						|
								    porigin_type origin;
							 | 
						|
								    size_type size_;
							 | 
						|
								
							 | 
						|
								    size_type size(void) const { return size_; }
							 | 
						|
								   
							 | 
						|
								    reference operator[](size_type i) const { 
							 | 
						|
								      return reference(ref_or_value_type<reference>::r(
							 | 
						|
									     linalg_traits<V>::access(origin, begin_, end_, i),
							 | 
						|
									     PART(), value_type()));
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    part_vector(V &v)
							 | 
						|
								      : begin_(vect_begin(v)),  end_(vect_end(v)),
							 | 
						|
									origin(linalg_origin(v)), size_(gmm::vect_size(v)) {}
							 | 
						|
								    part_vector(const V &v) 
							 | 
						|
								      : begin_(vect_begin(const_cast<V &>(v))),
							 | 
						|
								       end_(vect_end(const_cast<V &>(v))),
							 | 
						|
									origin(linalg_origin(const_cast<V &>(v))), size_(gmm::vect_size(v)) {}
							 | 
						|
								    part_vector() {}
							 | 
						|
								    part_vector(const part_vector<CPT, PART> &cr)
							 | 
						|
								      : begin_(cr.begin_),end_(cr.end_),origin(cr.origin), size_(cr.size_) {} 
							 | 
						|
								  };
							 | 
						|
								
							 | 
						|
								  template <typename IT, typename MIT, typename ORG, typename PT,
							 | 
						|
									    typename PART> inline
							 | 
						|
								  void set_to_begin(part_vector_iterator<IT, MIT, PART> &it,
							 | 
						|
										    ORG o, part_vector<PT, PART> *, linalg_modifiable) {
							 | 
						|
								    typedef part_vector<PT, PART> VECT;
							 | 
						|
								    typedef typename linalg_traits<VECT>::V_reference ref_t;
							 | 
						|
								    set_to_begin(it.it, o, typename linalg_traits<VECT>::pV(), ref_t());
							 | 
						|
								  }
							 | 
						|
								  template <typename IT, typename MIT, typename ORG, typename PT,
							 | 
						|
									    typename PART> inline
							 | 
						|
								  void set_to_begin(part_vector_iterator<IT, MIT, PART> &it,
							 | 
						|
										    ORG o, const part_vector<PT, PART> *, linalg_modifiable) {
							 | 
						|
								    typedef part_vector<PT, PART> VECT;
							 | 
						|
								    typedef typename linalg_traits<VECT>::V_reference ref_t;
							 | 
						|
								    set_to_begin(it.it, o, typename linalg_traits<VECT>::pV(), ref_t());
							 | 
						|
								  }
							 | 
						|
								  template <typename IT, typename MIT, typename ORG, typename PT,
							 | 
						|
									    typename PART> inline
							 | 
						|
								  void set_to_end(part_vector_iterator<IT, MIT, PART> &it,
							 | 
						|
										    ORG o, part_vector<PT, PART> *, linalg_modifiable) {
							 | 
						|
								    typedef part_vector<PT, PART> VECT;
							 | 
						|
								    typedef typename linalg_traits<VECT>::V_reference ref_t;
							 | 
						|
								    set_to_end(it.it, o, typename linalg_traits<VECT>::pV(), ref_t());
							 | 
						|
								  }
							 | 
						|
								  template <typename IT, typename MIT, typename ORG,
							 | 
						|
									    typename PT, typename PART> inline
							 | 
						|
								  void set_to_end(part_vector_iterator<IT, MIT, PART> &it,
							 | 
						|
										  ORG o, const part_vector<PT, PART> *,
							 | 
						|
										  linalg_modifiable) {
							 | 
						|
								    typedef part_vector<PT, PART> VECT;
							 | 
						|
								    typedef typename linalg_traits<VECT>::V_reference ref_t;
							 | 
						|
								    set_to_end(it.it, o, typename linalg_traits<VECT>::pV(), ref_t());
							 | 
						|
								  }
							 | 
						|
								  
							 | 
						|
								  template <typename PT, typename PART>
							 | 
						|
								  struct linalg_traits<part_vector<PT, PART> > {
							 | 
						|
								    typedef part_vector<PT, PART> this_type;
							 | 
						|
								    typedef this_type * pthis_type;
							 | 
						|
								    typedef PT pV;
							 | 
						|
								    typedef typename std::iterator_traits<PT>::value_type V;
							 | 
						|
								    typedef typename linalg_traits<V>::index_sorted index_sorted;
							 | 
						|
								    typedef typename linalg_traits<V>::is_reference V_reference;
							 | 
						|
								    typedef typename linalg_traits<V>::origin_type origin_type;
							 | 
						|
								    typedef typename select_ref<const origin_type *, origin_type *,
							 | 
						|
											        PT>::ref_type porigin_type;
							 | 
						|
								    typedef typename which_reference<PT>::is_reference is_reference;
							 | 
						|
								    typedef abstract_vector linalg_type;
							 | 
						|
								    typedef typename linalg_traits<V>::value_type vtype;
							 | 
						|
								    typedef typename number_traits<vtype>::magnitude_type value_type;
							 | 
						|
								    typedef typename select_ref<value_type, ref_elt_vector<value_type,
							 | 
						|
										     which_part<typename linalg_traits<V>::reference,
							 | 
						|
												PART> >, PT>::ref_type reference;
							 | 
						|
								    typedef typename select_ref<typename linalg_traits<V>::const_iterator,
							 | 
						|
									    typename linalg_traits<V>::iterator, PT>::ref_type pre_iterator;
							 | 
						|
								    typedef typename select_ref<abstract_null_type, 
							 | 
						|
									    part_vector_iterator<pre_iterator, pre_iterator, PART>,
							 | 
						|
									    PT>::ref_type iterator;
							 | 
						|
								    typedef part_vector_iterator<typename linalg_traits<V>::const_iterator,
							 | 
						|
												 pre_iterator, PART> const_iterator;
							 | 
						|
								    typedef typename linalg_traits<V>::storage_type storage_type;
							 | 
						|
								    static size_type size(const this_type &v) { return v.size(); }
							 | 
						|
								    static iterator begin(this_type &v) {
							 | 
						|
								      iterator it; it.it = v.begin_;
							 | 
						|
								      if (!is_const_reference(is_reference()) && is_sparse(storage_type()))
							 | 
						|
									set_to_begin(it, v.origin, pthis_type(), is_reference());
							 | 
						|
								      return it;
							 | 
						|
								    }
							 | 
						|
								    static const_iterator begin(const this_type &v) {
							 | 
						|
								      const_iterator it(v.begin_);
							 | 
						|
								      if (!is_const_reference(is_reference()) && is_sparse(storage_type()))
							 | 
						|
									{ set_to_begin(it, v.origin, pthis_type(), is_reference()); }
							 | 
						|
								      return it;
							 | 
						|
								    }
							 | 
						|
								    static iterator end(this_type &v) {
							 | 
						|
								      iterator it(v.end_);
							 | 
						|
								      if (!is_const_reference(is_reference()) && is_sparse(storage_type()))
							 | 
						|
									set_to_end(it, v.origin, pthis_type(), is_reference());
							 | 
						|
								      return it;
							 | 
						|
								    }
							 | 
						|
								    static const_iterator end(const this_type &v) {
							 | 
						|
								      const_iterator it(v.end_);
							 | 
						|
								      if (!is_const_reference(is_reference()) && is_sparse(storage_type()))
							 | 
						|
									set_to_end(it, v.origin, pthis_type(), is_reference());
							 | 
						|
								      return it;
							 | 
						|
								    }
							 | 
						|
								    static origin_type* origin(this_type &v) { return v.origin; }
							 | 
						|
								    static const origin_type* origin(const this_type &v) { return v.origin; }
							 | 
						|
								
							 | 
						|
								    static void clear(origin_type* o, const iterator &begin_,
							 | 
						|
										      const iterator &end_, abstract_sparse) {
							 | 
						|
								      std::deque<size_type> ind;
							 | 
						|
								      iterator it = begin_;
							 | 
						|
								      for (; it != end_; ++it) ind.push_front(it.index());
							 | 
						|
								      for (; !(ind.empty()); ind.pop_back())
							 | 
						|
									access(o, begin_, end_, ind.back()) = value_type(0);
							 | 
						|
								    }
							 | 
						|
								    static void clear(origin_type* o, const iterator &begin_,
							 | 
						|
										      const iterator &end_, abstract_skyline) {
							 | 
						|
								      clear(o, begin_, end_, abstract_sparse());
							 | 
						|
								    }
							 | 
						|
								    static void clear(origin_type* o, const iterator &begin_,
							 | 
						|
										      const iterator &end_, abstract_dense) {
							 | 
						|
								      for (iterator it = begin_; it != end_; ++it) *it = value_type(0);
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								   static void clear(origin_type* o, const iterator &begin_,
							 | 
						|
										      const iterator &end_) 
							 | 
						|
								    { clear(o, begin_, end_, storage_type()); }
							 | 
						|
								    static void do_clear(this_type &v) { clear(v.origin, begin(v), end(v)); }
							 | 
						|
								    static value_type access(const origin_type *o, const const_iterator &it,
							 | 
						|
											     const const_iterator &ite, size_type i) { 
							 | 
						|
								      return  real_or_imag_part(linalg_traits<V>::access(o, it.it, ite.it,i),
							 | 
						|
												PART());
							 | 
						|
								    }
							 | 
						|
								    static reference access(origin_type *o, const iterator &it,
							 | 
						|
											    const iterator &ite, size_type i)
							 | 
						|
								    { return reference(linalg_traits<V>::access(o, it.it, ite.it,i)); }
							 | 
						|
								  };
							 | 
						|
								
							 | 
						|
								  template <typename PT, typename PART> std::ostream &operator <<
							 | 
						|
								    (std::ostream &o, const part_vector<PT, PART>& m)
							 | 
						|
								  { gmm::write(o,m); return o; }
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								  /* ********************************************************************* */
							 | 
						|
								  /*	Reference to the real or imaginary part of (complex) matrices      */
							 | 
						|
								  /* ********************************************************************* */
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								  template <typename PT, typename PART> struct  part_row_ref {
							 | 
						|
								    
							 | 
						|
								    typedef part_row_ref<PT, PART> this_type;
							 | 
						|
								    typedef typename std::iterator_traits<PT>::value_type M;
							 | 
						|
								    typedef M * CPT;
							 | 
						|
								    typedef typename std::iterator_traits<PT>::reference ref_M;
							 | 
						|
								    typedef typename select_ref<typename linalg_traits<this_type>
							 | 
						|
								            ::const_row_iterator, typename linalg_traits<this_type>
							 | 
						|
								            ::row_iterator, PT>::ref_type iterator;
							 | 
						|
								    typedef typename linalg_traits<this_type>::value_type value_type;
							 | 
						|
								    typedef typename linalg_traits<this_type>::reference reference;
							 | 
						|
								    typedef typename linalg_traits<this_type>::porigin_type porigin_type;
							 | 
						|
								
							 | 
						|
								    iterator begin_, end_;
							 | 
						|
								    porigin_type origin;
							 | 
						|
								    size_type nr, nc;
							 | 
						|
								
							 | 
						|
								    part_row_ref(ref_M m)
							 | 
						|
								      : begin_(mat_row_begin(m)), end_(mat_row_end(m)),
							 | 
						|
									origin(linalg_origin(m)), nr(mat_nrows(m)), nc(mat_ncols(m)) {}
							 | 
						|
								
							 | 
						|
								    part_row_ref(const part_row_ref<CPT, PART> &cr) :
							 | 
						|
								      begin_(cr.begin_),end_(cr.end_), origin(cr.origin),nr(cr.nr),nc(cr.nc) {}
							 | 
						|
								
							 | 
						|
								    reference operator()(size_type i, size_type j) const {
							 | 
						|
								      return reference(ref_or_value_type<reference>::r(
							 | 
						|
													 linalg_traits<M>::access(begin_+i, j),
							 | 
						|
													 PART(), value_type()));
							 | 
						|
								    }
							 | 
						|
								  };
							 | 
						|
								
							 | 
						|
								  template <typename PT, typename PART>
							 | 
						|
								  struct linalg_traits<part_row_ref<PT, PART> > {
							 | 
						|
								    typedef part_row_ref<PT, PART> this_type;
							 | 
						|
								    typedef typename std::iterator_traits<PT>::value_type M;
							 | 
						|
								    typedef typename linalg_traits<M>::origin_type origin_type;
							 | 
						|
								    typedef typename select_ref<const origin_type *, origin_type *,
							 | 
						|
											        PT>::ref_type porigin_type;
							 | 
						|
								    typedef typename which_reference<PT>::is_reference is_reference;
							 | 
						|
								    typedef abstract_matrix linalg_type;
							 | 
						|
								    typedef typename linalg_traits<M>::value_type vtype;
							 | 
						|
								    typedef typename number_traits<vtype>::magnitude_type value_type;
							 | 
						|
								    typedef typename linalg_traits<M>::storage_type storage_type;
							 | 
						|
								    typedef abstract_null_type sub_col_type;
							 | 
						|
								    typedef abstract_null_type const_sub_col_type;
							 | 
						|
								    typedef abstract_null_type col_iterator;
							 | 
						|
								    typedef abstract_null_type const_col_iterator;
							 | 
						|
								    typedef typename linalg_traits<M>::const_sub_row_type
							 | 
						|
								            pre_const_sub_row_type;
							 | 
						|
								    typedef typename linalg_traits<M>::sub_row_type pre_sub_row_type;
							 | 
						|
								    typedef part_vector<const pre_const_sub_row_type *, PART>
							 | 
						|
								            const_sub_row_type;
							 | 
						|
								    typedef typename select_ref<abstract_null_type,
							 | 
						|
									    part_vector<pre_sub_row_type *, PART>, PT>::ref_type sub_row_type;
							 | 
						|
								    typedef typename linalg_traits<M>::const_row_iterator const_row_iterator;
							 | 
						|
								    typedef typename select_ref<abstract_null_type, typename
							 | 
						|
								            linalg_traits<M>::row_iterator, PT>::ref_type row_iterator;
							 | 
						|
								    typedef typename select_ref<
							 | 
						|
								            typename linalg_traits<const_sub_row_type>::reference,
							 | 
						|
									    typename linalg_traits<sub_row_type>::reference,
							 | 
						|
												PT>::ref_type reference;
							 | 
						|
								    typedef row_major sub_orientation;
							 | 
						|
								    typedef typename linalg_traits<M>::index_sorted index_sorted;
							 | 
						|
								    static size_type ncols(const this_type &v) { return v.nc; }
							 | 
						|
								    static size_type nrows(const this_type &v) { return v.nr; }
							 | 
						|
								    static const_sub_row_type row(const const_row_iterator &it)
							 | 
						|
								    { return const_sub_row_type(linalg_traits<M>::row(it)); }
							 | 
						|
								    static sub_row_type row(const row_iterator &it)
							 | 
						|
								    { return sub_row_type(linalg_traits<M>::row(it)); }
							 | 
						|
								    static row_iterator row_begin(this_type &m) { return m.begin_; }
							 | 
						|
								    static row_iterator row_end(this_type &m) { return m.end_; }
							 | 
						|
								    static const_row_iterator row_begin(const this_type &m)
							 | 
						|
								    { return m.begin_; }
							 | 
						|
								    static const_row_iterator row_end(const this_type &m) { return m.end_; }
							 | 
						|
								    static origin_type* origin(this_type &v) { return v.origin; }
							 | 
						|
								    static const origin_type* origin(const this_type &v) { return v.origin; }
							 | 
						|
								    static void do_clear(this_type &v);
							 | 
						|
								    static value_type access(const const_row_iterator &itrow, size_type i)
							 | 
						|
								    { return real_or_imag_part(linalg_traits<M>::access(itrow, i), PART()); }
							 | 
						|
								    static reference access(const row_iterator &itrow, size_type i) {
							 | 
						|
								      return reference(ref_or_value_type<reference>::r(
							 | 
						|
													 linalg_traits<M>::access(itrow, i),
							 | 
						|
													 PART(), value_type()));
							 | 
						|
								    }
							 | 
						|
								  };
							 | 
						|
								   
							 | 
						|
								  template <typename PT, typename PART> 
							 | 
						|
								  void linalg_traits<part_row_ref<PT, PART> >::do_clear(this_type &v) { 
							 | 
						|
								    row_iterator it = mat_row_begin(v), ite = mat_row_end(v);
							 | 
						|
								    for (; it != ite; ++it) clear(row(it));
							 | 
						|
								  }
							 | 
						|
								  
							 | 
						|
								  template<typename PT, typename PART> std::ostream &operator <<
							 | 
						|
								    (std::ostream &o, const part_row_ref<PT, PART>& m)
							 | 
						|
								  { gmm::write(o,m); return o; }
							 | 
						|
								
							 | 
						|
								  template <typename PT, typename PART> struct  part_col_ref {
							 | 
						|
								    
							 | 
						|
								    typedef part_col_ref<PT, PART> this_type;
							 | 
						|
								    typedef typename std::iterator_traits<PT>::value_type M;
							 | 
						|
								    typedef M * CPT;
							 | 
						|
								    typedef typename std::iterator_traits<PT>::reference ref_M;
							 | 
						|
								    typedef typename select_ref<typename linalg_traits<this_type>
							 | 
						|
								            ::const_col_iterator, typename linalg_traits<this_type>
							 | 
						|
								            ::col_iterator, PT>::ref_type iterator;
							 | 
						|
								    typedef typename linalg_traits<this_type>::value_type value_type;
							 | 
						|
								    typedef typename linalg_traits<this_type>::reference reference;
							 | 
						|
								    typedef typename linalg_traits<this_type>::porigin_type porigin_type;
							 | 
						|
								
							 | 
						|
								    iterator begin_, end_;
							 | 
						|
								    porigin_type origin;
							 | 
						|
								    size_type nr, nc;
							 | 
						|
								
							 | 
						|
								    part_col_ref(ref_M m)
							 | 
						|
								      : begin_(mat_col_begin(m)), end_(mat_col_end(m)),
							 | 
						|
									origin(linalg_origin(m)), nr(mat_nrows(m)), nc(mat_ncols(m)) {}
							 | 
						|
								
							 | 
						|
								    part_col_ref(const part_col_ref<CPT, PART> &cr) :
							 | 
						|
								      begin_(cr.begin_),end_(cr.end_), origin(cr.origin),nr(cr.nr),nc(cr.nc) {}
							 | 
						|
								
							 | 
						|
								    reference operator()(size_type i, size_type j) const {
							 | 
						|
								      return reference(ref_or_value_type<reference>::r(
							 | 
						|
													 linalg_traits<M>::access(begin_+j, i),
							 | 
						|
													 PART(), value_type()));
							 | 
						|
								    }
							 | 
						|
								  };
							 | 
						|
								
							 | 
						|
								  template <typename PT, typename PART>
							 | 
						|
								  struct linalg_traits<part_col_ref<PT, PART> > {
							 | 
						|
								    typedef part_col_ref<PT, PART> this_type;
							 | 
						|
								    typedef typename std::iterator_traits<PT>::value_type M;
							 | 
						|
								    typedef typename linalg_traits<M>::origin_type origin_type;
							 | 
						|
								    typedef typename select_ref<const origin_type *, origin_type *,
							 | 
						|
											        PT>::ref_type porigin_type;
							 | 
						|
								    typedef typename which_reference<PT>::is_reference is_reference;
							 | 
						|
								    typedef abstract_matrix linalg_type;
							 | 
						|
								    typedef typename linalg_traits<M>::value_type vtype;
							 | 
						|
								    typedef typename number_traits<vtype>::magnitude_type value_type;
							 | 
						|
								    typedef typename linalg_traits<M>::storage_type storage_type;
							 | 
						|
								    typedef abstract_null_type sub_row_type;
							 | 
						|
								    typedef abstract_null_type const_sub_row_type;
							 | 
						|
								    typedef abstract_null_type row_iterator;
							 | 
						|
								    typedef abstract_null_type const_row_iterator;
							 | 
						|
								    typedef typename linalg_traits<M>::const_sub_col_type
							 | 
						|
								            pre_const_sub_col_type;
							 | 
						|
								    typedef typename linalg_traits<M>::sub_col_type pre_sub_col_type;
							 | 
						|
								    typedef part_vector<const pre_const_sub_col_type *, PART>
							 | 
						|
								            const_sub_col_type;
							 | 
						|
								    typedef typename select_ref<abstract_null_type,
							 | 
						|
									    part_vector<pre_sub_col_type *, PART>, PT>::ref_type sub_col_type;
							 | 
						|
								    typedef typename linalg_traits<M>::const_col_iterator const_col_iterator;
							 | 
						|
								    typedef typename select_ref<abstract_null_type, typename
							 | 
						|
								            linalg_traits<M>::col_iterator, PT>::ref_type col_iterator;
							 | 
						|
								    typedef typename select_ref<
							 | 
						|
								            typename linalg_traits<const_sub_col_type>::reference,
							 | 
						|
									    typename linalg_traits<sub_col_type>::reference,
							 | 
						|
												PT>::ref_type reference;
							 | 
						|
								    typedef col_major sub_orientation;
							 | 
						|
								    typedef typename linalg_traits<M>::index_sorted index_sorted;
							 | 
						|
								    static size_type nrows(const this_type &v) { return v.nr; }
							 | 
						|
								    static size_type ncols(const this_type &v) { return v.nc; }
							 | 
						|
								    static const_sub_col_type col(const const_col_iterator &it)
							 | 
						|
								    { return const_sub_col_type(linalg_traits<M>::col(it)); }
							 | 
						|
								    static sub_col_type col(const col_iterator &it)
							 | 
						|
								    { return sub_col_type(linalg_traits<M>::col(it)); }
							 | 
						|
								    static col_iterator col_begin(this_type &m) { return m.begin_; }
							 | 
						|
								    static col_iterator col_end(this_type &m) { return m.end_; }
							 | 
						|
								    static const_col_iterator col_begin(const this_type &m)
							 | 
						|
								    { return m.begin_; }
							 | 
						|
								    static const_col_iterator col_end(const this_type &m) { return m.end_; }
							 | 
						|
								    static origin_type* origin(this_type &v) { return v.origin; }
							 | 
						|
								    static const origin_type* origin(const this_type &v) { return v.origin; }
							 | 
						|
								    static void do_clear(this_type &v);
							 | 
						|
								    static value_type access(const const_col_iterator &itcol, size_type i)
							 | 
						|
								    { return real_or_imag_part(linalg_traits<M>::access(itcol, i), PART()); }
							 | 
						|
								    static reference access(const col_iterator &itcol, size_type i) {
							 | 
						|
								      return reference(ref_or_value_type<reference>::r(
							 | 
						|
													 linalg_traits<M>::access(itcol, i),
							 | 
						|
													 PART(), value_type()));
							 | 
						|
								    }
							 | 
						|
								  };
							 | 
						|
								   
							 | 
						|
								  template <typename PT, typename PART> 
							 | 
						|
								  void linalg_traits<part_col_ref<PT, PART> >::do_clear(this_type &v) { 
							 | 
						|
								    col_iterator it = mat_col_begin(v), ite = mat_col_end(v);
							 | 
						|
								    for (; it != ite; ++it) clear(col(it));
							 | 
						|
								  }
							 | 
						|
								  
							 | 
						|
								  template<typename PT, typename PART> std::ostream &operator <<
							 | 
						|
								    (std::ostream &o, const part_col_ref<PT, PART>& m)
							 | 
						|
								  { gmm::write(o,m); return o; }
							 | 
						|
								
							 | 
						|
								  
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								template <typename TYPE, typename PART, typename PT>
							 | 
						|
								  struct part_return_ {
							 | 
						|
								    typedef abstract_null_type return_type;
							 | 
						|
								  };
							 | 
						|
								  template <typename PT, typename PART>
							 | 
						|
								  struct part_return_<row_major, PART, PT> {
							 | 
						|
								    typedef typename std::iterator_traits<PT>::value_type L;
							 | 
						|
								    typedef typename select_return<part_row_ref<const L *, PART>,
							 | 
						|
										     part_row_ref< L *, PART>, PT>::return_type return_type;
							 | 
						|
								  };
							 | 
						|
								  template <typename PT, typename PART>
							 | 
						|
								  struct part_return_<col_major, PART, PT> {
							 | 
						|
								    typedef typename std::iterator_traits<PT>::value_type L;
							 | 
						|
								    typedef typename select_return<part_col_ref<const L *, PART>,
							 | 
						|
										     part_col_ref<L *, PART>, PT>::return_type return_type;
							 | 
						|
								  };
							 | 
						|
								
							 | 
						|
								  template <typename PT, typename PART, typename LT> struct part_return__{
							 | 
						|
								    typedef abstract_null_type return_type;
							 | 
						|
								  };
							 | 
						|
								
							 | 
						|
								  template <typename PT, typename PART>
							 | 
						|
								  struct part_return__<PT, PART, abstract_matrix> {
							 | 
						|
								    typedef typename std::iterator_traits<PT>::value_type L;
							 | 
						|
								    typedef typename part_return_<typename principal_orientation_type<
							 | 
						|
								      typename linalg_traits<L>::sub_orientation>::potype, PART,
							 | 
						|
								      PT>::return_type return_type;
							 | 
						|
								  };
							 | 
						|
								
							 | 
						|
								  template <typename PT, typename PART>
							 | 
						|
								  struct part_return__<PT, PART, abstract_vector> {
							 | 
						|
								    typedef typename std::iterator_traits<PT>::value_type L;
							 | 
						|
								    typedef typename select_return<part_vector<const L *, PART>,
							 | 
						|
								      part_vector<L *, PART>, PT>::return_type return_type;
							 | 
						|
								  };
							 | 
						|
								
							 | 
						|
								  template <typename PT, typename PART> struct part_return {
							 | 
						|
								    typedef typename std::iterator_traits<PT>::value_type L;
							 | 
						|
								    typedef typename part_return__<PT, PART,
							 | 
						|
								      typename linalg_traits<L>::linalg_type>::return_type return_type;
							 | 
						|
								  };
							 | 
						|
								
							 | 
						|
								  template <typename L> inline 
							 | 
						|
								  typename part_return<const L *, linalg_real_part>::return_type
							 | 
						|
								  real_part(const L &l) {
							 | 
						|
								    return typename part_return<const L *, linalg_real_part>::return_type
							 | 
						|
								      (linalg_cast(const_cast<L &>(l)));
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  template <typename L> inline 
							 | 
						|
								  typename part_return<L *, linalg_real_part>::return_type
							 | 
						|
								  real_part(L &l) {
							 | 
						|
								    return typename part_return<L *, linalg_real_part>::return_type(linalg_cast(l));
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  template <typename L> inline 
							 | 
						|
								  typename part_return<const L *, linalg_imag_part>::return_type
							 | 
						|
								  imag_part(const L &l) {
							 | 
						|
								    return typename part_return<const L *, linalg_imag_part>::return_type
							 | 
						|
								      (linalg_cast(const_cast<L &>(l)));
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  template <typename L> inline 
							 | 
						|
								  typename part_return<L *, linalg_imag_part>::return_type
							 | 
						|
								  imag_part(L &l) {
							 | 
						|
								    return typename part_return<L *, linalg_imag_part>::return_type(linalg_cast(l));
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								#endif //  GMM_REAL_PART_H
							 |