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.
		
		
		
		
		
			
		
			
				
					
					
						
							969 lines
						
					
					
						
							37 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							969 lines
						
					
					
						
							37 KiB
						
					
					
				
								/* -*- c++ -*- (enables emacs c++ mode) */
							 | 
						|
								/*===========================================================================
							 | 
						|
								 
							 | 
						|
								 Copyright (C) 2002-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_vector.h
							 | 
						|
								   @author  Yves Renard <Yves.Renard@insa-lyon.fr>
							 | 
						|
								   @date October 13, 2002.
							 | 
						|
								   @brief Declaration of the vector types (gmm::rsvector, gmm::wsvector,
							 | 
						|
								     gmm::slvector ,..)
							 | 
						|
								*/
							 | 
						|
								#ifndef GMM_VECTOR_H__
							 | 
						|
								#define GMM_VECTOR_H__
							 | 
						|
								
							 | 
						|
								#include <map>
							 | 
						|
								#include "gmm_interface.h"
							 | 
						|
								
							 | 
						|
								namespace gmm {
							 | 
						|
								
							 | 
						|
								  /*************************************************************************/
							 | 
						|
								  /*                                                                       */
							 | 
						|
								  /* Class ref_elt_vector: reference on a vector component.                */
							 | 
						|
								  /*                                                                       */
							 | 
						|
								  /*************************************************************************/
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								  template<typename T, typename V> class ref_elt_vector {
							 | 
						|
								
							 | 
						|
								    V *pm;
							 | 
						|
								    size_type l;
							 | 
						|
								    
							 | 
						|
								    public :
							 | 
						|
								
							 | 
						|
								    operator T() const { return pm->r(l); }
							 | 
						|
								    ref_elt_vector(V *p, size_type ll) : pm(p), l(ll) {}
							 | 
						|
								    inline ref_elt_vector &operator =(T v)
							 | 
						|
								      { (*pm).w(l,v); return *this; }
							 | 
						|
								    inline bool operator ==(T v) const { return ((*pm).r(l) == v); }
							 | 
						|
								    inline bool operator !=(T v) const { return ((*pm).r(l) != v); }
							 | 
						|
								    inline ref_elt_vector &operator +=(T v)
							 | 
						|
								      { (*pm).w(l,(*pm).r(l) + v); return *this; }
							 | 
						|
								    inline ref_elt_vector &operator -=(T v)
							 | 
						|
								      { (*pm).w(l,(*pm).r(l) - v); return *this; }
							 | 
						|
								    inline ref_elt_vector &operator /=(T v)
							 | 
						|
								      { (*pm).w(l,(*pm).r(l) / v); return *this; }
							 | 
						|
								    inline ref_elt_vector &operator *=(T v)
							 | 
						|
								      { (*pm).w(l,(*pm).r(l) * v); 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 T, typename V> inline
							 | 
						|
								  bool operator ==(T v, const ref_elt_vector<T, V> &re) { return (v==T(re)); }
							 | 
						|
								  template<typename T, typename V> inline
							 | 
						|
								  bool operator !=(T v, const ref_elt_vector<T, V> &re) { return (v!=T(re)); }
							 | 
						|
								  template<typename T, typename V> inline
							 | 
						|
								  T &operator +=(T &v, const ref_elt_vector<T, V> &re) 
							 | 
						|
								  { v += T(re); return v; }
							 | 
						|
								  template<typename T, typename V> inline
							 | 
						|
								  T &operator -=(T &v, const ref_elt_vector<T, V> &re)
							 | 
						|
								  { v -= T(re); return v; }
							 | 
						|
								  template<typename T, typename V> inline
							 | 
						|
								  T &operator *=(T &v, const ref_elt_vector<T, V> &re) 
							 | 
						|
								  { v *= T(re); return v; }
							 | 
						|
								  template<typename T, typename V> inline
							 | 
						|
								  T &operator /=(T &v, const ref_elt_vector<T, V> &re)
							 | 
						|
								  { v /= T(re); return v; }
							 | 
						|
								  template<typename T, typename V> inline
							 | 
						|
								  T operator +(const ref_elt_vector<T, V> &re) { return T(re); }
							 | 
						|
								  template<typename T, typename V> inline
							 | 
						|
								  T operator -(const ref_elt_vector<T, V> &re) { return -T(re); }
							 | 
						|
								  template<typename T, typename V> inline
							 | 
						|
								  T operator +(const ref_elt_vector<T, V> &re, T v) { return T(re)+ v; }
							 | 
						|
								  template<typename T, typename V> inline
							 | 
						|
								  T operator +(T v, const ref_elt_vector<T, V> &re) { return v+ T(re); }
							 | 
						|
								  template<typename T, typename V> inline
							 | 
						|
								  T operator -(const ref_elt_vector<T, V> &re, T v) { return T(re)- v; }
							 | 
						|
								  template<typename T, typename V> inline
							 | 
						|
								  T operator -(T v, const ref_elt_vector<T, V> &re) { return v- T(re); }
							 | 
						|
								  template<typename T, typename V>  inline
							 | 
						|
								  T operator *(const ref_elt_vector<T, V> &re, T v) { return T(re)* v; }
							 | 
						|
								  template<typename T, typename V> inline
							 | 
						|
								  T operator *(T v, const ref_elt_vector<T, V> &re) { return v* T(re); }
							 | 
						|
								  template<typename T, typename V> inline
							 | 
						|
								  T operator /(const ref_elt_vector<T, V> &re, T v) { return T(re)/ v; }
							 | 
						|
								  template<typename T, typename V> inline
							 | 
						|
								  T operator /(T v, const ref_elt_vector<T, V> &re) { return v/ T(re); }
							 | 
						|
								  template<typename T, typename V> inline
							 | 
						|
								  typename number_traits<T>::magnitude_type
							 | 
						|
								  abs(const ref_elt_vector<T, V> &re) { return gmm::abs(T(re)); }
							 | 
						|
								  template<typename T, typename V> inline
							 | 
						|
								  T sqr(const ref_elt_vector<T, V> &re) { return gmm::sqr(T(re)); }
							 | 
						|
								  template<typename T, typename V> inline
							 | 
						|
								  typename number_traits<T>::magnitude_type
							 | 
						|
								  abs_sqr(const ref_elt_vector<T, V> &re) { return gmm::abs_sqr(T(re)); }
							 | 
						|
								  template<typename T, typename V> inline
							 | 
						|
								  T conj(const ref_elt_vector<T, V> &re) { return gmm::conj(T(re)); }
							 | 
						|
								  template<typename T, typename V> std::ostream &operator <<
							 | 
						|
								  (std::ostream &o, const ref_elt_vector<T, V> &re) { o << T(re); return o; }
							 | 
						|
								  template<typename T, typename V> inline
							 | 
						|
								  typename number_traits<T>::magnitude_type
							 | 
						|
								  real(const ref_elt_vector<T, V> &re) { return gmm::real(T(re)); }
							 | 
						|
								  template<typename T, typename V> inline
							 | 
						|
								  typename number_traits<T>::magnitude_type
							 | 
						|
								  imag(const ref_elt_vector<T, V> &re) { return gmm::imag(T(re)); }
							 | 
						|
								
							 | 
						|
								  
							 | 
						|
								
							 | 
						|
								  /*************************************************************************/
							 | 
						|
								  /*                                                                       */
							 | 
						|
								  /* Class wsvector: sparse vector optimized for random write operations.  */
							 | 
						|
								  /*                                                                       */
							 | 
						|
								  /*************************************************************************/
							 | 
						|
								  
							 | 
						|
								  template<typename T> struct wsvector_iterator
							 | 
						|
								    : public std::map<size_type, T>::iterator {
							 | 
						|
								    typedef typename std::map<size_type, T>::iterator base_it_type;
							 | 
						|
								    typedef T                   value_type;
							 | 
						|
								    typedef value_type*         pointer;
							 | 
						|
								    typedef value_type&         reference;
							 | 
						|
								    // typedef size_t              size_type;
							 | 
						|
								    typedef ptrdiff_t           difference_type;
							 | 
						|
								    typedef std::bidirectional_iterator_tag iterator_category;
							 | 
						|
								    
							 | 
						|
								    reference operator *() const { return (base_it_type::operator*()).second; }
							 | 
						|
								    pointer operator->() const { return &(operator*()); }
							 | 
						|
								    size_type index(void) const { return (base_it_type::operator*()).first; }
							 | 
						|
								
							 | 
						|
								    wsvector_iterator(void) {}
							 | 
						|
								    wsvector_iterator(const base_it_type &it) : base_it_type(it) {}
							 | 
						|
								  };
							 | 
						|
								
							 | 
						|
								  template<typename T> struct wsvector_const_iterator
							 | 
						|
								    : public std::map<size_type, T>::const_iterator {
							 | 
						|
								    typedef typename std::map<size_type, T>::const_iterator base_it_type;
							 | 
						|
								    typedef T                   value_type;
							 | 
						|
								    typedef const value_type*   pointer;
							 | 
						|
								    typedef const value_type&   reference;
							 | 
						|
								    // typedef size_t              size_type;
							 | 
						|
								    typedef ptrdiff_t           difference_type;
							 | 
						|
								    typedef std::bidirectional_iterator_tag iterator_category;
							 | 
						|
								    
							 | 
						|
								    reference operator *() const { return (base_it_type::operator*()).second; }
							 | 
						|
								    pointer operator->() const { return &(operator*()); }
							 | 
						|
								    size_type index(void) const { return (base_it_type::operator*()).first; }
							 | 
						|
								
							 | 
						|
								    wsvector_const_iterator(void) {}
							 | 
						|
								    wsvector_const_iterator(const wsvector_iterator<T> &it)
							 | 
						|
								      : base_it_type(it) {}
							 | 
						|
								    wsvector_const_iterator(const base_it_type &it) : base_it_type(it) {}
							 | 
						|
								  };
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								  /**
							 | 
						|
								     sparse vector built upon std::map.
							 | 
						|
								     Read and write access are quite fast (log n)
							 | 
						|
								  */
							 | 
						|
								  template<typename T> class wsvector : public std::map<size_type, T> {
							 | 
						|
								  public:
							 | 
						|
								    
							 | 
						|
								    typedef typename std::map<int, T>::size_type size_type;
							 | 
						|
								    typedef std::map<size_type, T> base_type;
							 | 
						|
								    typedef typename base_type::iterator iterator;
							 | 
						|
								    typedef typename base_type::const_iterator const_iterator;
							 | 
						|
								
							 | 
						|
								  protected:
							 | 
						|
								    size_type nbl;
							 | 
						|
								    
							 | 
						|
								  public:
							 | 
						|
								    void clean(double eps);
							 | 
						|
								    void resize(size_type);
							 | 
						|
								    
							 | 
						|
								    inline ref_elt_vector<T, wsvector<T> > operator [](size_type c)
							 | 
						|
								    { return ref_elt_vector<T, wsvector<T> >(this, c); }
							 | 
						|
								
							 | 
						|
								    inline void w(size_type c, const T &e) {
							 | 
						|
								      GMM_ASSERT2(c < nbl, "out of range");
							 | 
						|
								      if (e == T(0)) { base_type::erase(c); }
							 | 
						|
								      else base_type::operator [](c) = e;
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    inline T r(size_type c) const {
							 | 
						|
								      GMM_ASSERT2(c < nbl, "out of range");
							 | 
						|
								      const_iterator it = this->lower_bound(c);
							 | 
						|
								      if (it != this->end() && c == it->first) return it->second;
							 | 
						|
								      else return T(0);
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    inline T operator [](size_type c) const { return r(c); }
							 | 
						|
								    
							 | 
						|
								    size_type nb_stored(void) const { return base_type::size(); }
							 | 
						|
								    size_type size(void) const { return nbl; }
							 | 
						|
								
							 | 
						|
								    void swap(wsvector<T> &v)
							 | 
						|
								    { std::swap(nbl, v.nbl); std::map<size_type, T>::swap(v); }
							 | 
						|
												       
							 | 
						|
								
							 | 
						|
								    /* Constructeurs */
							 | 
						|
								    void init(size_type l) { nbl = l; this->clear(); }
							 | 
						|
								    explicit wsvector(size_type l){ init(l); }
							 | 
						|
								    wsvector(void) { init(0); }
							 | 
						|
								  };
							 | 
						|
								
							 | 
						|
								  template<typename T>  void wsvector<T>::clean(double eps) {
							 | 
						|
								    iterator it = this->begin(), itf = it, ite = this->end();
							 | 
						|
								    while (it != ite) {
							 | 
						|
								      ++itf; if (gmm::abs(it->second) <= eps) erase(it); it = itf;
							 | 
						|
								    }
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  template<typename T>  void wsvector<T>::resize(size_type n) {
							 | 
						|
								    if (n < nbl) {
							 | 
						|
								      iterator it = this->begin(), itf = it, ite = this->end();
							 | 
						|
								      while (it != ite) { ++itf; if (it->first >= n) this->erase(it); it=itf; }
							 | 
						|
								    }
							 | 
						|
								    nbl = n;
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  template <typename T> struct linalg_traits<wsvector<T> > {
							 | 
						|
								    typedef wsvector<T> this_type;
							 | 
						|
								    typedef this_type origin_type;
							 | 
						|
								    typedef linalg_false is_reference;
							 | 
						|
								    typedef abstract_vector linalg_type;
							 | 
						|
								    typedef T value_type;
							 | 
						|
								    typedef ref_elt_vector<T, wsvector<T> > reference;
							 | 
						|
								    typedef wsvector_iterator<T>  iterator;
							 | 
						|
								    typedef wsvector_const_iterator<T> const_iterator;
							 | 
						|
								    typedef abstract_sparse storage_type;
							 | 
						|
								    typedef linalg_true index_sorted;
							 | 
						|
								    static size_type size(const this_type &v) { return v.size(); }
							 | 
						|
								    static iterator begin(this_type &v) { return v.begin(); }
							 | 
						|
								    static const_iterator begin(const this_type &v) { return v.begin(); }
							 | 
						|
								    static iterator end(this_type &v) { return v.end(); }
							 | 
						|
								    static const_iterator end(const this_type &v) { return v.end(); }
							 | 
						|
								    static origin_type* origin(this_type &v) { return &v; }
							 | 
						|
								    static const origin_type* origin(const this_type &v) { return &v; }
							 | 
						|
								    static void clear(origin_type* o, const iterator &, const iterator &)
							 | 
						|
								    { o->clear(); }
							 | 
						|
								    static void do_clear(this_type &v) { v.clear(); }
							 | 
						|
								    static value_type access(const origin_type *o, const const_iterator &,
							 | 
						|
											     const const_iterator &, size_type i)
							 | 
						|
								    { return (*o)[i]; }
							 | 
						|
								    static reference access(origin_type *o, const iterator &, const iterator &,
							 | 
						|
											    size_type i)
							 | 
						|
								    { return (*o)[i]; }
							 | 
						|
								    static void resize(this_type &v, size_type n) { v.resize(n); }
							 | 
						|
								  };
							 | 
						|
								
							 | 
						|
								  template<typename T> std::ostream &operator <<
							 | 
						|
								  (std::ostream &o, const wsvector<T>& v) { gmm::write(o,v); return o; }
							 | 
						|
								
							 | 
						|
								  /******* Optimized BLAS for wsvector<T> **********************************/
							 | 
						|
								
							 | 
						|
								  template <typename T> inline void copy(const wsvector<T> &v1,
							 | 
						|
													 wsvector<T> &v2) {
							 | 
						|
								    GMM_ASSERT2(vect_size(v1) == vect_size(v2), "dimensions mismatch");
							 | 
						|
								    v2 = v1;
							 | 
						|
								  }
							 | 
						|
								  template <typename T> inline
							 | 
						|
								  void copy(const wsvector<T> &v1, const simple_vector_ref<wsvector<T> *> &v2){
							 | 
						|
								    simple_vector_ref<wsvector<T> *>
							 | 
						|
								      *svr = const_cast<simple_vector_ref<wsvector<T> *> *>(&v2);
							 | 
						|
								    wsvector<T>
							 | 
						|
								      *pv = const_cast<wsvector<T> *>(v2.origin);
							 | 
						|
								    GMM_ASSERT2(vect_size(v1) == vect_size(v2), "dimensions mismatch");
							 | 
						|
								    *pv = v1; svr->begin_ = vect_begin(*pv); svr->end_ = vect_end(*pv);
							 | 
						|
								  }
							 | 
						|
								  template <typename T> inline
							 | 
						|
								  void copy(const simple_vector_ref<const wsvector<T> *> &v1,
							 | 
						|
									    wsvector<T> &v2)
							 | 
						|
								  { copy(*(v1.origin), v2); }
							 | 
						|
								  template <typename T> inline
							 | 
						|
								  void copy(const simple_vector_ref<wsvector<T> *> &v1, wsvector<T> &v2)
							 | 
						|
								  { copy(*(v1.origin), v2); }
							 | 
						|
								
							 | 
						|
								  template <typename T> inline void clean(wsvector<T> &v, double eps) {
							 | 
						|
								    typedef typename number_traits<T>::magnitude_type R;
							 | 
						|
								    typename wsvector<T>::iterator it = v.begin(), ite = v.end(), itc;
							 | 
						|
								    while (it != ite) 
							 | 
						|
								      if (gmm::abs((*it).second) <= R(eps))
							 | 
						|
									{ itc=it; ++it; v.erase(itc); } else ++it; 
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  template <typename T>
							 | 
						|
								  inline void clean(const simple_vector_ref<wsvector<T> *> &l, double eps) {
							 | 
						|
								    simple_vector_ref<wsvector<T> *>
							 | 
						|
								      *svr = const_cast<simple_vector_ref<wsvector<T> *> *>(&l);
							 | 
						|
								    wsvector<T>
							 | 
						|
								      *pv = const_cast<wsvector<T> *>((l.origin));
							 | 
						|
								    clean(*pv, eps);
							 | 
						|
								    svr->begin_ = vect_begin(*pv); svr->end_ = vect_end(*pv);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  template <typename T>
							 | 
						|
								  inline size_type nnz(const wsvector<T>& l) { return l.nb_stored(); }
							 | 
						|
								
							 | 
						|
								  /*************************************************************************/
							 | 
						|
								  /*                                                                       */
							 | 
						|
								  /*    rsvector: sparse vector optimized for linear algebra operations.   */
							 | 
						|
								  /*                                                                       */
							 | 
						|
								  /*************************************************************************/
							 | 
						|
								
							 | 
						|
								  template<typename T> struct elt_rsvector_ {
							 | 
						|
								    size_type c; T e;
							 | 
						|
								    /* e is initialized by default to avoid some false warnings of valgrind..
							 | 
						|
								       (from http://valgrind.org/docs/manual/mc-manual.html:
							 | 
						|
								      
							 | 
						|
								       When memory is read into the CPU's floating point registers, the
							 | 
						|
								       relevant V bits are read from memory and they are immediately
							 | 
						|
								       checked. If any are invalid, an uninitialised value error is
							 | 
						|
								       emitted. This precludes using the floating-point registers to copy
							 | 
						|
								       possibly-uninitialised memory, but simplifies Valgrind in that it
							 | 
						|
								       does not have to track the validity status of the floating-point
							 | 
						|
								       registers.
							 | 
						|
								    */
							 | 
						|
								    elt_rsvector_(void) : e(0) {}
							 | 
						|
								    elt_rsvector_(size_type cc) : c(cc), e(0) {}
							 | 
						|
								    elt_rsvector_(size_type cc, const T &ee) : c(cc), e(ee) {}
							 | 
						|
								    bool operator < (const elt_rsvector_ &a) const { return c < a.c; }
							 | 
						|
								    bool operator == (const elt_rsvector_ &a) const { return c == a.c; }
							 | 
						|
								    bool operator != (const elt_rsvector_ &a) const { return c != a.c; }
							 | 
						|
								  };
							 | 
						|
								
							 | 
						|
								  template<typename T> struct rsvector_iterator {
							 | 
						|
								    typedef typename std::vector<elt_rsvector_<T> >::iterator IT;
							 | 
						|
								    typedef T                   value_type;
							 | 
						|
								    typedef value_type*         pointer;
							 | 
						|
								    typedef value_type&         reference;
							 | 
						|
								    typedef size_t              size_type;
							 | 
						|
								    typedef ptrdiff_t           difference_type;
							 | 
						|
								    typedef std::bidirectional_iterator_tag iterator_category;
							 | 
						|
								    typedef rsvector_iterator<T> iterator;
							 | 
						|
								
							 | 
						|
								    IT it;
							 | 
						|
								
							 | 
						|
								    reference operator *() const { return it->e; }
							 | 
						|
								    pointer operator->() const { return &(operator*()); }
							 | 
						|
								
							 | 
						|
								    iterator &operator ++() { ++it; return *this; }
							 | 
						|
								    iterator operator ++(int) { iterator tmp = *this; ++(*this); return tmp; }
							 | 
						|
								    iterator &operator --() { --it; return *this; }
							 | 
						|
								    iterator operator --(int) { iterator tmp = *this; --(*this); return tmp; }
							 | 
						|
								
							 | 
						|
								    bool operator ==(const iterator &i) const { return it == i.it; }
							 | 
						|
								    bool operator !=(const iterator &i) const { return !(i == *this); }
							 | 
						|
								
							 | 
						|
								    size_type index(void) const { return it->c; }
							 | 
						|
								    rsvector_iterator(void) {}
							 | 
						|
								    rsvector_iterator(const IT &i) : it(i) {}
							 | 
						|
								  };
							 | 
						|
								
							 | 
						|
								  template<typename T> struct rsvector_const_iterator {
							 | 
						|
								    typedef typename std::vector<elt_rsvector_<T> >::const_iterator IT;
							 | 
						|
								    typedef T                   value_type;
							 | 
						|
								    typedef const value_type*   pointer;
							 | 
						|
								    typedef const value_type&   reference;
							 | 
						|
								    typedef size_t              size_type;
							 | 
						|
								    typedef ptrdiff_t           difference_type;
							 | 
						|
								    typedef std::forward_iterator_tag iterator_category;
							 | 
						|
								    typedef rsvector_const_iterator<T> iterator;
							 | 
						|
								
							 | 
						|
								    IT it;
							 | 
						|
								
							 | 
						|
								    reference operator *() const { return it->e; }
							 | 
						|
								    pointer operator->() const { return &(operator*()); }
							 | 
						|
								    size_type index(void) const { return it->c; }
							 | 
						|
								
							 | 
						|
								    iterator &operator ++() { ++it; return *this; }
							 | 
						|
								    iterator operator ++(int) { iterator tmp = *this; ++(*this); return tmp; }
							 | 
						|
								    iterator &operator --() { --it; return *this; }
							 | 
						|
								    iterator operator --(int) { iterator tmp = *this; --(*this); return tmp; }
							 | 
						|
								
							 | 
						|
								    bool operator ==(const iterator &i) const { return it == i.it; }
							 | 
						|
								    bool operator !=(const iterator &i) const { return !(i == *this); }
							 | 
						|
								
							 | 
						|
								    rsvector_const_iterator(void) {}
							 | 
						|
								    rsvector_const_iterator(const rsvector_iterator<T> &i) : it(i.it) {}
							 | 
						|
								    rsvector_const_iterator(const IT &i) : it(i) {}
							 | 
						|
								  };
							 | 
						|
								
							 | 
						|
								  /**
							 | 
						|
								     sparse vector built upon std::vector. Read access is fast,
							 | 
						|
								     but insertion is O(n) 
							 | 
						|
								  */
							 | 
						|
								  template<typename T> class rsvector : public std::vector<elt_rsvector_<T> > {
							 | 
						|
								  public:
							 | 
						|
								    
							 | 
						|
								    typedef std::vector<elt_rsvector_<T> > base_type_;
							 | 
						|
								    typedef typename base_type_::iterator iterator;
							 | 
						|
								    typedef typename base_type_::const_iterator const_iterator;
							 | 
						|
								    typedef typename base_type_::size_type size_type;
							 | 
						|
								    typedef T value_type;
							 | 
						|
								
							 | 
						|
								  protected:
							 | 
						|
								    size_type nbl;    	/* size of the vector.	          	  */
							 | 
						|
								    
							 | 
						|
								  public:
							 | 
						|
								
							 | 
						|
								    void sup(size_type j);
							 | 
						|
								    void base_resize(size_type n) { base_type_::resize(n); }
							 | 
						|
								    void resize(size_type);
							 | 
						|
								    
							 | 
						|
								    ref_elt_vector<T, rsvector<T> > operator [](size_type c)
							 | 
						|
								    { return ref_elt_vector<T, rsvector<T> >(this, c); }
							 | 
						|
								
							 | 
						|
								    void w(size_type c, const T &e);
							 | 
						|
								    T r(size_type c) const;
							 | 
						|
								    void swap_indices(size_type i, size_type j);
							 | 
						|
								
							 | 
						|
								    inline T operator [](size_type c) const { return r(c); }
							 | 
						|
								    
							 | 
						|
								    size_type nb_stored(void) const { return base_type_::size(); }
							 | 
						|
								    size_type size(void) const { return nbl; }
							 | 
						|
								    void clear(void) { base_type_::resize(0); }
							 | 
						|
								    void swap(rsvector<T> &v)
							 | 
						|
								    { std::swap(nbl, v.nbl); std::vector<elt_rsvector_<T> >::swap(v); }
							 | 
						|
								
							 | 
						|
								    /* Constructeurs */
							 | 
						|
								    explicit rsvector(size_type l) : nbl(l) { }
							 | 
						|
								    rsvector(void) : nbl(0) { }
							 | 
						|
								  };
							 | 
						|
								
							 | 
						|
								  template <typename T>
							 | 
						|
								  void rsvector<T>::swap_indices(size_type i, size_type j) {
							 | 
						|
								    if (i > j) std::swap(i, j);
							 | 
						|
								    if (i != j) {
							 | 
						|
								      int situation = 0;
							 | 
						|
								      elt_rsvector_<T> ei(i), ej(j), a;
							 | 
						|
								      iterator it, ite, iti, itj;
							 | 
						|
								      iti = std::lower_bound(this->begin(), this->end(), ei);
							 | 
						|
								      if (iti != this->end() && iti->c == i) situation += 1;
							 | 
						|
								      itj = std::lower_bound(this->begin(), this->end(), ej);
							 | 
						|
								      if (itj != this->end() && itj->c == j) situation += 2;
							 | 
						|
								
							 | 
						|
								      switch (situation) {
							 | 
						|
								      case 1 : a = *iti; a.c = j; it = iti; ++it; ite = this->end();
							 | 
						|
									       for (; it != ite && it->c <= j; ++it, ++iti) *iti = *it;
							 | 
						|
									       *iti = a;
							 | 
						|
									       break;
							 | 
						|
								      case 2 : a = *itj; a.c = i; it = itj; ite = this->begin();
							 | 
						|
									if (it != ite) {
							 | 
						|
									  --it;
							 | 
						|
									  while (it->c >= i) { *itj = *it;  --itj; if (it==ite) break; --it; }
							 | 
						|
									}
							 | 
						|
									*itj = a;
							 | 
						|
									break;
							 | 
						|
								      case 3 : std::swap(iti->e, itj->e);
							 | 
						|
									       break;
							 | 
						|
								      }
							 | 
						|
								    }
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  template <typename T> void rsvector<T>::sup(size_type j) {
							 | 
						|
								    if (nb_stored() != 0) {
							 | 
						|
								      elt_rsvector_<T> ev(j);
							 | 
						|
								      iterator it = std::lower_bound(this->begin(), this->end(), ev);
							 | 
						|
								      if (it != this->end() && it->c == j) {
							 | 
						|
									for (iterator ite = this->end() - 1; it != ite; ++it) *it = *(it+1);
							 | 
						|
									base_type_::resize(nb_stored()-1);
							 | 
						|
								      }
							 | 
						|
								    }
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  template<typename T>  void rsvector<T>::resize(size_type n) {
							 | 
						|
								    if (n < nbl) {
							 | 
						|
								      for (size_type i = 0; i < nb_stored(); ++i)
							 | 
						|
									if (base_type_::operator[](i).c >= n) { base_resize(i); break; }
							 | 
						|
								    }
							 | 
						|
								    nbl = n;
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  template <typename T> void rsvector<T>::w(size_type c, const T &e) {
							 | 
						|
								    GMM_ASSERT2(c < nbl, "out of range");
							 | 
						|
								    if (e == T(0)) sup(c);
							 | 
						|
								    else {
							 | 
						|
								      elt_rsvector_<T> ev(c, e);
							 | 
						|
								      if (nb_stored() == 0) {
							 | 
						|
									base_type_::resize(1,ev);
							 | 
						|
								      }
							 | 
						|
								      else {
							 | 
						|
									iterator it = std::lower_bound(this->begin(), this->end(), ev);
							 | 
						|
									if (it != this->end() && it->c == c) it->e = e;
							 | 
						|
									else {
							 | 
						|
									  size_type ind = it - this->begin();
							 | 
						|
									  base_type_::resize(nb_stored()+1, ev);
							 | 
						|
									  if (ind != nb_stored() - 1) {
							 | 
						|
									    it = this->begin() + ind;
							 | 
						|
									    for (iterator ite = this->end() - 1; ite != it; --ite)
							 | 
						|
									      *ite = *(ite-1);
							 | 
						|
									    *it = ev;
							 | 
						|
									  }
							 | 
						|
									}
							 | 
						|
								      }
							 | 
						|
								    }
							 | 
						|
								  }
							 | 
						|
								  
							 | 
						|
								  template <typename T> T rsvector<T>::r(size_type c) const {
							 | 
						|
								    GMM_ASSERT2(c < nbl, "out of range");
							 | 
						|
								    if (nb_stored() != 0) {
							 | 
						|
								      elt_rsvector_<T> ev(c);
							 | 
						|
								      const_iterator it = std::lower_bound(this->begin(), this->end(), ev);
							 | 
						|
								      if (it != this->end() && it->c == c) return it->e;
							 | 
						|
								    }
							 | 
						|
								    return T(0);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  template <typename T> struct linalg_traits<rsvector<T> > {
							 | 
						|
								    typedef rsvector<T> this_type;
							 | 
						|
								    typedef this_type origin_type;
							 | 
						|
								    typedef linalg_false is_reference;
							 | 
						|
								    typedef abstract_vector linalg_type;
							 | 
						|
								    typedef T value_type;
							 | 
						|
								    typedef ref_elt_vector<T, rsvector<T> > reference;
							 | 
						|
								    typedef rsvector_iterator<T>  iterator;
							 | 
						|
								    typedef rsvector_const_iterator<T> const_iterator;
							 | 
						|
								    typedef abstract_sparse storage_type;
							 | 
						|
								    typedef linalg_true index_sorted;
							 | 
						|
								    static size_type size(const this_type &v) { return v.size(); }
							 | 
						|
								    static iterator begin(this_type &v) { return iterator(v.begin()); }
							 | 
						|
								    static const_iterator begin(const this_type &v)
							 | 
						|
								    { return const_iterator(v.begin()); }
							 | 
						|
								    static iterator end(this_type &v) { return iterator(v.end()); }
							 | 
						|
								    static const_iterator end(const this_type &v)
							 | 
						|
								      { return const_iterator(v.end()); }
							 | 
						|
								    static origin_type* origin(this_type &v) { return &v; }
							 | 
						|
								    static const origin_type* origin(const this_type &v) { return &v; }
							 | 
						|
								    static void clear(origin_type* o, const iterator &, const iterator &)
							 | 
						|
								    { o->clear(); }
							 | 
						|
								    static void do_clear(this_type &v) { v.clear(); }
							 | 
						|
								    static value_type access(const origin_type *o, const const_iterator &,
							 | 
						|
											     const const_iterator &, size_type i)
							 | 
						|
								    { return (*o)[i]; }
							 | 
						|
								    static reference access(origin_type *o, const iterator &, const iterator &,
							 | 
						|
											    size_type i)
							 | 
						|
								    { return (*o)[i]; }
							 | 
						|
								    static void resize(this_type &v, size_type n) { v.resize(n); }
							 | 
						|
								  };
							 | 
						|
								
							 | 
						|
								  template<typename T> std::ostream &operator <<
							 | 
						|
								  (std::ostream &o, const rsvector<T>& v) { gmm::write(o,v); return o; }
							 | 
						|
								
							 | 
						|
								  /******* Optimized operations for rsvector<T> ****************************/
							 | 
						|
								
							 | 
						|
								  template <typename T> inline void copy(const rsvector<T> &v1,
							 | 
						|
								 					 rsvector<T> &v2) {
							 | 
						|
								    GMM_ASSERT2(vect_size(v1) == vect_size(v2), "dimensions mismatch");
							 | 
						|
								    v2 = v1;
							 | 
						|
								  }
							 | 
						|
								  template <typename T> inline
							 | 
						|
								  void copy(const rsvector<T> &v1, const simple_vector_ref<rsvector<T> *> &v2){
							 | 
						|
								    simple_vector_ref<rsvector<T> *>
							 | 
						|
								      *svr = const_cast<simple_vector_ref<rsvector<T> *> *>(&v2);
							 | 
						|
								    rsvector<T>
							 | 
						|
								      *pv = const_cast<rsvector<T> *>((v2.origin));
							 | 
						|
								    GMM_ASSERT2(vect_size(v1) == vect_size(v2), "dimensions mismatch");
							 | 
						|
								    *pv = v1; svr->begin_ = vect_begin(*pv); svr->end_ = vect_end(*pv);
							 | 
						|
								  }
							 | 
						|
								  template <typename T> inline
							 | 
						|
								  void copy(const simple_vector_ref<const rsvector<T> *> &v1,
							 | 
						|
									    rsvector<T> &v2)
							 | 
						|
								  { copy(*(v1.origin), v2); }
							 | 
						|
								  template <typename T> inline
							 | 
						|
								  void copy(const simple_vector_ref<rsvector<T> *> &v1, rsvector<T> &v2)
							 | 
						|
								  { copy(*(v1.origin), v2); }
							 | 
						|
								
							 | 
						|
								  template <typename V, typename T> inline void add(const V &v1,
							 | 
						|
														    rsvector<T> &v2) {
							 | 
						|
								    if ((const void *)(&v1) != (const void *)(&v2)) {
							 | 
						|
								      GMM_ASSERT2(vect_size(v1) == vect_size(v2), "dimensions mismatch");
							 | 
						|
									add_rsvector(v1, v2, typename linalg_traits<V>::storage_type());
							 | 
						|
								    }
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  template <typename V, typename T> 
							 | 
						|
								  inline void add_rsvector(const V &v1, rsvector<T> &v2, abstract_dense)
							 | 
						|
								  { add(v1, v2, abstract_dense(), abstract_sparse()); }
							 | 
						|
								
							 | 
						|
								  template <typename V, typename T> 
							 | 
						|
								  inline void add_rsvector(const V &v1, rsvector<T> &v2, abstract_skyline)
							 | 
						|
								  { add(v1, v2, abstract_skyline(), abstract_sparse()); }
							 | 
						|
								
							 | 
						|
								  template <typename V, typename T> 
							 | 
						|
								  void add_rsvector(const V &v1, rsvector<T> &v2, abstract_sparse) {
							 | 
						|
								    add_rsvector(v1, v2, typename linalg_traits<V>::index_sorted());
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  template <typename V, typename T> 
							 | 
						|
								  void add_rsvector(const V &v1, rsvector<T> &v2, linalg_false) {
							 | 
						|
								    add(v1, v2, abstract_sparse(), abstract_sparse());
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  template <typename V, typename T> 
							 | 
						|
								  void add_rsvector(const V &v1, rsvector<T> &v2, linalg_true) {
							 | 
						|
								    typename linalg_traits<V>::const_iterator it1 = vect_const_begin(v1),
							 | 
						|
								      ite1 = vect_const_end(v1);
							 | 
						|
								    typename rsvector<T>::iterator it2 = v2.begin(), ite2 = v2.end(), it3;
							 | 
						|
								    size_type nbc = 0, old_nbc = v2.nb_stored();
							 | 
						|
								    for (; it1 != ite1 && it2 != ite2 ; ++nbc)
							 | 
						|
								      if (it1.index() == it2->c) { ++it1; ++it2; }
							 | 
						|
								      else if (it1.index() < it2->c) ++it1; else ++it2;
							 | 
						|
								    for (; it1 != ite1; ++it1) ++nbc;
							 | 
						|
								    for (; it2 != ite2; ++it2) ++nbc;
							 | 
						|
								
							 | 
						|
								    v2.base_resize(nbc);
							 | 
						|
								    it3 = v2.begin() + old_nbc;
							 | 
						|
								    it2 = v2.end(); ite2 = v2.begin();
							 | 
						|
								    it1 = vect_end(v1); ite1 = vect_const_begin(v1);
							 | 
						|
								    while (it1 != ite1 && it3 != ite2) {
							 | 
						|
								      --it3; --it1; --it2;
							 | 
						|
								      if (it3->c > it1.index()) { *it2 = *it3; ++it1; }
							 | 
						|
								      else if (it3->c == it1.index()) { *it2=*it3; it2->e+=*it1; }
							 | 
						|
								      else { it2->c = it1.index(); it2->e = *it1; ++it3; }
							 | 
						|
								    }
							 | 
						|
								    while (it1 != ite1) { --it1; --it2; it2->c = it1.index(); it2->e = *it1; }
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  template <typename V, typename T> void copy(const V &v1, rsvector<T> &v2) {
							 | 
						|
								    if ((const void *)(&v1) != (const void *)(&v2)) {
							 | 
						|
								      GMM_ASSERT2(vect_size(v1) == vect_size(v2), "dimensions mismatch");
							 | 
						|
								      if (same_origin(v1, v2))
							 | 
						|
									GMM_WARNING2("a conflict is possible in vector copy\n");
							 | 
						|
								      copy_rsvector(v1, v2, typename linalg_traits<V>::storage_type());
							 | 
						|
								    }
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  template <typename V, typename T> 
							 | 
						|
								  void copy_rsvector(const V &v1, rsvector<T> &v2, abstract_dense)
							 | 
						|
								  { copy_vect(v1, v2, abstract_dense(), abstract_sparse()); }
							 | 
						|
								
							 | 
						|
								  template <typename V, typename T> 
							 | 
						|
								  void copy_rsvector(const V &v1, rsvector<T> &v2, abstract_skyline)
							 | 
						|
								  { copy_vect(v1, v2, abstract_skyline(), abstract_sparse()); }
							 | 
						|
								
							 | 
						|
								  template <typename V, typename T>
							 | 
						|
								  void copy_rsvector(const V &v1, rsvector<T> &v2, abstract_sparse) {
							 | 
						|
								    copy_rsvector(v1, v2, typename linalg_traits<V>::index_sorted());
							 | 
						|
								  }
							 | 
						|
								  
							 | 
						|
								  template <typename V, typename T2>
							 | 
						|
								  void copy_rsvector(const V &v1, rsvector<T2> &v2, linalg_true) {
							 | 
						|
								    typedef typename linalg_traits<V>::value_type T1;
							 | 
						|
								    typename linalg_traits<V>::const_iterator it = vect_const_begin(v1),
							 | 
						|
								      ite = vect_const_end(v1);
							 | 
						|
								    v2.base_resize(nnz(v1));
							 | 
						|
								    typename rsvector<T2>::iterator it2 = v2.begin();
							 | 
						|
								    size_type nn = 0;
							 | 
						|
								    for (; it != ite; ++it)
							 | 
						|
								      if ((*it) != T1(0)) { it2->c = it.index(); it2->e = *it; ++it2; ++nn; }
							 | 
						|
								    v2.base_resize(nn);
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  template <typename V, typename T2>
							 | 
						|
								  void copy_rsvector(const V &v1, rsvector<T2> &v2, linalg_false) {
							 | 
						|
								    typedef typename linalg_traits<V>::value_type T1;
							 | 
						|
								    typename linalg_traits<V>::const_iterator it = vect_const_begin(v1),
							 | 
						|
								      ite = vect_const_end(v1);
							 | 
						|
								    v2.base_resize(nnz(v1));
							 | 
						|
								    typename rsvector<T2>::iterator it2 = v2.begin();
							 | 
						|
								    size_type nn = 0;
							 | 
						|
								    for (; it != ite; ++it)
							 | 
						|
								      if ((*it) != T1(0)) { it2->c = it.index(); it2->e = *it; ++it2; ++nn; }
							 | 
						|
								    v2.base_resize(nn);
							 | 
						|
								    std::sort(v2.begin(), v2.end());
							 | 
						|
								  }
							 | 
						|
								  
							 | 
						|
								  template <typename T> inline void clean(rsvector<T> &v, double eps) {
							 | 
						|
								    typedef typename number_traits<T>::magnitude_type R;
							 | 
						|
								    typename rsvector<T>::iterator it = v.begin(), ite = v.end();
							 | 
						|
								    for (; it != ite; ++it) if (gmm::abs((*it).e) <= eps) break;
							 | 
						|
								    if (it != ite) {
							 | 
						|
								      typename rsvector<T>::iterator itc = it;
							 | 
						|
								      size_type erased = 1;
							 | 
						|
								      for (++it; it != ite; ++it)
							 | 
						|
									{ *itc = *it; if (gmm::abs((*it).e) <= R(eps)) ++erased; else ++itc; }
							 | 
						|
								      v.base_resize(v.nb_stored() - erased);
							 | 
						|
								    }
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  template <typename T>
							 | 
						|
								  inline void clean(const simple_vector_ref<rsvector<T> *> &l, double eps) {
							 | 
						|
								    simple_vector_ref<rsvector<T> *>
							 | 
						|
								      *svr = const_cast<simple_vector_ref<rsvector<T> *> *>(&l);
							 | 
						|
								    rsvector<T>
							 | 
						|
								      *pv = const_cast<rsvector<T> *>((l.origin));
							 | 
						|
								    clean(*pv, eps);
							 | 
						|
								    svr->begin_ = vect_begin(*pv); svr->end_ = vect_end(*pv);
							 | 
						|
								  }
							 | 
						|
								  
							 | 
						|
								  template <typename T>
							 | 
						|
								  inline size_type nnz(const rsvector<T>& l) { return l.nb_stored(); }
							 | 
						|
								
							 | 
						|
								  /*************************************************************************/
							 | 
						|
								  /*                                                                       */
							 | 
						|
								  /* Class slvector: 'sky-line' vector.                                    */
							 | 
						|
								  /*                                                                       */
							 | 
						|
								  /*************************************************************************/
							 | 
						|
								
							 | 
						|
								  template<typename T> struct slvector_iterator {
							 | 
						|
								    typedef T value_type;
							 | 
						|
								    typedef T *pointer;
							 | 
						|
								    typedef T &reference;
							 | 
						|
								    typedef ptrdiff_t difference_type;
							 | 
						|
								    typedef std::random_access_iterator_tag iterator_category;
							 | 
						|
								    typedef size_t size_type;
							 | 
						|
								    typedef slvector_iterator<T> iterator;
							 | 
						|
								    typedef typename std::vector<T>::iterator base_iterator;
							 | 
						|
								
							 | 
						|
								    base_iterator it;
							 | 
						|
								    size_type shift;
							 | 
						|
								    
							 | 
						|
								   
							 | 
						|
								    iterator &operator ++()
							 | 
						|
								    { ++it; ++shift; return *this; }
							 | 
						|
								    iterator &operator --()
							 | 
						|
								    { --it; --shift; return *this; }
							 | 
						|
								    iterator operator ++(int)
							 | 
						|
								    { iterator tmp = *this; ++(*(this)); return tmp; }
							 | 
						|
								    iterator operator --(int)
							 | 
						|
								    { iterator tmp = *this; --(*(this)); return tmp; }
							 | 
						|
								    iterator &operator +=(difference_type i)
							 | 
						|
								    { it += i; shift += i; return *this; }
							 | 
						|
								    iterator &operator -=(difference_type i)
							 | 
						|
								    { it -= i; shift -= i; return *this; }
							 | 
						|
								    iterator operator +(difference_type i) const
							 | 
						|
								    { iterator tmp = *this; return (tmp += i); }
							 | 
						|
								    iterator operator -(difference_type i) const
							 | 
						|
								    { iterator tmp = *this; return (tmp -= i); }
							 | 
						|
								    difference_type operator -(const iterator &i) const
							 | 
						|
								    { return it - i.it; }
							 | 
						|
									
							 | 
						|
								    reference operator *() const
							 | 
						|
								    { return *it; }
							 | 
						|
								    reference operator [](int ii)
							 | 
						|
								    { return *(it + ii); }
							 | 
						|
								    
							 | 
						|
								    bool operator ==(const iterator &i) const
							 | 
						|
								    { return it == i.it; }
							 | 
						|
								    bool operator !=(const iterator &i) const
							 | 
						|
								    { return !(i == *this); }
							 | 
						|
								    bool operator < (const iterator &i) const
							 | 
						|
								    { return it < i.it; }
							 | 
						|
								    size_type index(void) const { return shift; }
							 | 
						|
								
							 | 
						|
								    slvector_iterator(void) {}
							 | 
						|
								    slvector_iterator(const base_iterator &iter, size_type s)
							 | 
						|
								      : it(iter), shift(s) {}
							 | 
						|
								  };
							 | 
						|
								
							 | 
						|
								  template<typename T> struct slvector_const_iterator {
							 | 
						|
								    typedef T value_type;
							 | 
						|
								    typedef const T *pointer;
							 | 
						|
								    typedef value_type reference;
							 | 
						|
								    typedef ptrdiff_t difference_type;
							 | 
						|
								    typedef std::random_access_iterator_tag iterator_category;
							 | 
						|
								    typedef size_t size_type;
							 | 
						|
								    typedef slvector_const_iterator<T> iterator;
							 | 
						|
								    typedef typename std::vector<T>::const_iterator base_iterator;
							 | 
						|
								
							 | 
						|
								    base_iterator it;
							 | 
						|
								    size_type shift;
							 | 
						|
								    
							 | 
						|
								   
							 | 
						|
								    iterator &operator ++()
							 | 
						|
								    { ++it; ++shift; return *this; }
							 | 
						|
								    iterator &operator --()
							 | 
						|
								    { --it; --shift; return *this; }
							 | 
						|
								    iterator operator ++(int)
							 | 
						|
								    { iterator tmp = *this; ++(*(this)); return tmp; }
							 | 
						|
								    iterator operator --(int)
							 | 
						|
								    { iterator tmp = *this; --(*(this)); return tmp; }
							 | 
						|
								    iterator &operator +=(difference_type i)
							 | 
						|
								    { it += i; shift += i; return *this; }
							 | 
						|
								    iterator &operator -=(difference_type i)
							 | 
						|
								    { it -= i; shift -= i; return *this; }
							 | 
						|
								    iterator operator +(difference_type i) const
							 | 
						|
								    { iterator tmp = *this; return (tmp += i); }
							 | 
						|
								    iterator operator -(difference_type i) const
							 | 
						|
								    { iterator tmp = *this; return (tmp -= i); }
							 | 
						|
								    difference_type operator -(const iterator &i) const
							 | 
						|
								    { return it - i.it; }
							 | 
						|
									
							 | 
						|
								    value_type operator *() const
							 | 
						|
								    { return *it; }
							 | 
						|
								    value_type operator [](int ii)
							 | 
						|
								    { return *(it + ii); }
							 | 
						|
								    
							 | 
						|
								    bool operator ==(const iterator &i) const
							 | 
						|
								    { return it == i.it; }
							 | 
						|
								    bool operator !=(const iterator &i) const
							 | 
						|
								    { return !(i == *this); }
							 | 
						|
								    bool operator < (const iterator &i) const
							 | 
						|
								    { return it < i.it; }
							 | 
						|
								    size_type index(void) const { return shift; }
							 | 
						|
								
							 | 
						|
								    slvector_const_iterator(void) {}
							 | 
						|
								    slvector_const_iterator(const slvector_iterator<T>& iter)
							 | 
						|
								      : it(iter.it), shift(iter.shift) {}
							 | 
						|
								    slvector_const_iterator(const base_iterator &iter, size_type s)
							 | 
						|
								      : it(iter), shift(s) {}
							 | 
						|
								  };
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								  /** skyline vector.
							 | 
						|
								   */
							 | 
						|
								  template <typename T> class slvector {
							 | 
						|
								    
							 | 
						|
								  public :
							 | 
						|
								    typedef slvector_iterator<T> iterators;
							 | 
						|
								    typedef slvector_const_iterator<T> const_iterators;
							 | 
						|
								    typedef typename std::vector<T>::size_type size_type;
							 | 
						|
								    typedef T value_type;
							 | 
						|
								
							 | 
						|
								  protected :
							 | 
						|
								    std::vector<T> data;
							 | 
						|
								    size_type shift;
							 | 
						|
								    size_type size_;
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								  public :
							 | 
						|
								
							 | 
						|
								    size_type size(void) const { return size_; }
							 | 
						|
								    size_type first(void) const { return shift; }
							 | 
						|
								    size_type last(void) const { return shift + data.size(); }
							 | 
						|
								    ref_elt_vector<T, slvector<T> > operator [](size_type c)
							 | 
						|
								    { return ref_elt_vector<T, slvector<T> >(this, c); }
							 | 
						|
								
							 | 
						|
								    typename std::vector<T>::iterator data_begin(void) { return data.begin(); }
							 | 
						|
								    typename std::vector<T>::iterator data_end(void) { return data.end(); }
							 | 
						|
								    typename std::vector<T>::const_iterator data_begin(void) const
							 | 
						|
								      { return data.begin(); }
							 | 
						|
								    typename std::vector<T>::const_iterator data_end(void) const
							 | 
						|
								      { return data.end(); }
							 | 
						|
								
							 | 
						|
								    void w(size_type c, const T &e);
							 | 
						|
								    T r(size_type c) const {
							 | 
						|
								      GMM_ASSERT2(c < size_, "out of range");
							 | 
						|
								      if (c < shift || c >= shift + data.size()) return T(0);
							 | 
						|
								      return data[c - shift];
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								    inline T operator [](size_type c) const { return r(c); }
							 | 
						|
								    void resize(size_type);
							 | 
						|
								    void clear(void) { data.resize(0); shift = 0; }
							 | 
						|
								    void swap(slvector<T> &v) {
							 | 
						|
								      std::swap(data, v.data);
							 | 
						|
								      std::swap(shift, v.shift);
							 | 
						|
								      std::swap(size_, v.size_);
							 | 
						|
								    }
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								    slvector(void) : data(0), shift(0), size_(0) {}
							 | 
						|
								    explicit slvector(size_type l) : data(0), shift(0), size_(l) {}
							 | 
						|
								    slvector(size_type l, size_type d, size_type s)
							 | 
						|
								      : data(d), shift(s), size_(l) {}
							 | 
						|
								
							 | 
						|
								  };
							 | 
						|
								
							 | 
						|
								  template<typename T>  void slvector<T>::resize(size_type n) {
							 | 
						|
								    if (n < last()) {
							 | 
						|
								      if (shift >= n) clear(); else { data.resize(n-shift); }
							 | 
						|
								    }
							 | 
						|
								    size_ = n;
							 | 
						|
								  }
							 | 
						|
								
							 | 
						|
								  template<typename T>  void slvector<T>::w(size_type c, const T &e) {
							 | 
						|
								    GMM_ASSERT2(c < size_, "out of range");
							 | 
						|
								    size_type s = data.size();
							 | 
						|
								    if (!s) { data.resize(1); shift = c; }
							 | 
						|
								    else if (c < shift) {
							 | 
						|
								      data.resize(s + shift - c); 
							 | 
						|
								      typename std::vector<T>::iterator it = data.begin(),it2=data.end()-1;
							 | 
						|
								      typename std::vector<T>::iterator it3 = it2 - shift + c;
							 | 
						|
								      for (; it3 >= it; --it3, --it2) *it2 = *it3;
							 | 
						|
								      std::fill(it, it + shift - c, T(0));
							 | 
						|
								      shift = c;
							 | 
						|
								    }
							 | 
						|
								    else if (c >= shift + s) {
							 | 
						|
								      data.resize(c - shift + 1);
							 | 
						|
								      std::fill(data.begin() + s, data.end(), T(0));
							 | 
						|
								    }
							 | 
						|
								    data[c - shift] = e;
							 | 
						|
								  }
							 | 
						|
								  
							 | 
						|
								  template <typename T> struct linalg_traits<slvector<T> > {
							 | 
						|
								    typedef slvector<T> this_type;
							 | 
						|
								    typedef this_type origin_type;
							 | 
						|
								    typedef linalg_false is_reference;
							 | 
						|
								    typedef abstract_vector linalg_type;
							 | 
						|
								    typedef T value_type;
							 | 
						|
								    typedef ref_elt_vector<T, slvector<T> > reference;
							 | 
						|
								    typedef slvector_iterator<T>  iterator;
							 | 
						|
								    typedef slvector_const_iterator<T> const_iterator;
							 | 
						|
								    typedef abstract_skyline storage_type;
							 | 
						|
								    typedef linalg_true index_sorted;
							 | 
						|
								    static size_type size(const this_type &v) { return v.size(); }
							 | 
						|
								    static iterator begin(this_type &v)
							 | 
						|
								      { return iterator(v.data_begin(), v.first()); }
							 | 
						|
								    static const_iterator begin(const this_type &v)
							 | 
						|
								      { return const_iterator(v.data_begin(), v.first()); }
							 | 
						|
								    static iterator end(this_type &v)
							 | 
						|
								      { return iterator(v.data_end(), v.last()); }
							 | 
						|
								    static const_iterator end(const this_type &v)
							 | 
						|
								      { return const_iterator(v.data_end(), v.last()); }
							 | 
						|
								    static origin_type* origin(this_type &v) { return &v; }
							 | 
						|
								    static const origin_type* origin(const this_type &v) { return &v; }
							 | 
						|
								    static void clear(origin_type* o, const iterator &, const iterator &)
							 | 
						|
								    { o->clear(); }
							 | 
						|
								    static void do_clear(this_type &v) { v.clear(); }
							 | 
						|
								    static value_type access(const origin_type *o, const const_iterator &,
							 | 
						|
											     const const_iterator &, size_type i)
							 | 
						|
								    { return (*o)[i]; }
							 | 
						|
								    static reference access(origin_type *o, const iterator &, const iterator &,
							 | 
						|
											    size_type i)
							 | 
						|
								    { return (*o)[i]; }
							 | 
						|
								    static void resize(this_type &v, size_type n) { v.resize(n); }
							 | 
						|
								  };
							 | 
						|
								
							 | 
						|
								  template<typename T> std::ostream &operator <<
							 | 
						|
								  (std::ostream &o, const slvector<T>& v) { gmm::write(o,v); return o; }
							 | 
						|
								
							 | 
						|
								  template <typename T>
							 | 
						|
								  inline size_type nnz(const slvector<T>& l) { return l.last() - l.first(); }
							 | 
						|
								
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								namespace std {
							 | 
						|
								  template <typename T> void swap(gmm::wsvector<T> &v, gmm::wsvector<T> &w)
							 | 
						|
								  { v.swap(w);}
							 | 
						|
								  template <typename T> void swap(gmm::rsvector<T> &v, gmm::rsvector<T> &w)
							 | 
						|
								  { v.swap(w);}
							 | 
						|
								  template <typename T> void swap(gmm::slvector<T> &v, gmm::slvector<T> &w)
							 | 
						|
								  { v.swap(w);}
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								#endif /* GMM_VECTOR_H__ */
							 |