Diana  0.8.3
DianaSparseArray.hpp
00001 /* -----------------------------------------------------------------------------
00002  *  Diana process modelling, simulation and analysis software
00003  *  Copyright (c) 2005, Michael Krasnyk
00004  *  All rights reserved.
00005  *
00006  *  This file is a part of Diana process modelling, simulation and analysis software
00007  *
00008  *  Diana is free software; you can redistribute it and/or modify it
00009  *  under the terms of the GNU General Public License as published
00010  *  by the Free Software Foundation (see accompanying file LICENSE)
00011  * -----------------------------------------------------------------------------
00012  *  $Id: DianaSparseArray.hpp 9627 2012-08-28 13:01:23Z danker $
00013  * -----------------------------------------------------------------------------
00014  *  Description:
00015  */
00016 
00017 #ifndef DIANA_SPARSE_ARRAY_HPP
00018 #define DIANA_SPARSE_ARRAY_HPP
00019 
00020 #include <iterator>
00021 #include <algorithm>
00022 #include <cstddef>
00023 #include "CapeTypes.hpp"
00024 
00025 
00026 namespace Diana{
00027 
00038   template<typename _Ti>
00039   class refiterator {
00040     _Ti                                      _M_current; 
00041   public:
00043     typedef typename std::iterator_traits<typename std::iterator_traits<_Ti>::value_type>::value_type value_type;
00045     typedef std::random_access_iterator_tag  iterator_category;
00047     typedef ptrdiff_t                        difference_type;
00049     typedef value_type*                      pointer;
00051     typedef value_type&                      reference;
00052 
00054     refiterator(const _Ti& _iter) : _M_current(_iter) {};
00056     inline refiterator& operator=(const _Ti& _iter) { _M_current = _iter; return *this; }
00057 
00059     template<typename _Iter>
00060     inline refiterator(const refiterator<_Iter>& __i) : _M_current(__i.base()) {}
00061 
00062     /* Forward iterator requirements */
00064     reference    operator*() const { return *(*_M_current); }
00066     pointer      operator->() const { return &(operator*()); }
00068     refiterator& operator++() { ++_M_current; return *this; }
00070     refiterator  operator++(int) { return refiterator(_M_current++); }
00071       
00072     /* Bidirectional iterator requirements */
00074     refiterator& operator--() { --_M_current; return *this; }
00076     refiterator  operator--(int) { return refiterator(_M_current--); }
00078     inline Common::Types::CapeBoolean  operator==(const refiterator& rhs) { return base()==rhs.base(); }
00080     inline Common::Types::CapeBoolean  operator!=(const refiterator& rhs) { return base()!=rhs.base(); }
00081       
00082     /* Random access iterator requirements */
00084     inline reference       operator[](const difference_type& __n) const { return *(_M_current[__n]); }
00086     inline refiterator&    operator+=(const difference_type& __n) { _M_current += __n; return *this; }
00088     inline refiterator     operator+(const difference_type& __n) const { return refiterator(_M_current + __n); }
00090     inline refiterator&    operator-=(const difference_type& __n) { _M_current -= __n; return *this; }
00092     inline refiterator     operator-(const difference_type& __n) const { return refiterator(_M_current - __n); }
00094     inline Common::Types::CapeBoolean            operator<(const refiterator& rhs) const { return base()<rhs.base(); }
00096     inline Common::Types::CapeBoolean            operator<=(const refiterator& rhs) const { return base()<=rhs.base(); }
00098     inline Common::Types::CapeBoolean            operator>(const refiterator& rhs) const { return base()>rhs.base(); }
00100     inline Common::Types::CapeBoolean            operator>=(const refiterator& rhs) const { return base()>=rhs.base(); }
00102     inline difference_type operator-(const refiterator& rhs) const { return base()-rhs.base(); }
00103 
00105     inline const _Ti&  base() const { return _M_current; }
00106 
00107     template<typename _Tiostr>
00108     friend std::ostream& operator<<(std::ostream& os, const refiterator<_Tiostr>& iter);
00109   };
00110 
00112   template<typename _Ti>
00113   inline refiterator<_Ti> operator+(typename refiterator<_Ti>::difference_type __n, const refiterator<_Ti>& __i)
00114   { return refiterator<_Ti>(__i.base() + __n); };
00115 
00122   template<typename _Tiostr>
00123   std::ostream& operator<<(std::ostream& os, const refiterator<_Tiostr>& iter)
00124   { return os<<(void*)&(*iter._M_current)<<"->("<<*iter<<")"; };
00125 
00126 
00151   class sparray {
00152   public:
00154     enum tstate {
00155       uninitialized,   
00156       unassembled,     
00157       assembled,       
00158       incr_initalize,  
00159       incr_append,     
00160       incr_assembled,  
00161     };
00162 
00163   public:
00164     
00165     typedef Common::Types::CapeDouble         tvalue;          
00166     typedef Common::Types::CapeArrayLong      tindices;        
00167 
00168     struct entry {
00169       entry(const tindices& idx, tvalue val) : indices(idx), value(val) {};
00170       tindices indices;    
00171       tvalue   value;      
00172     };                     
00173 
00174     typedef std::vector<entry>                       tentries;        
00175     typedef std::vector<tentries::iterator>          pentries;        
00176 
00177     typedef refiterator<pentries::iterator>          iterator;        
00178     typedef refiterator<pentries::const_iterator>    const_iterator;  
00179     typedef entry&                                   reference;       
00180     typedef const entry&                             const_reference; 
00181     typedef size_t                                   size_type;       
00182     typedef ptrdiff_t                                difference_type; 
00183     typedef unsigned int                             crc_type;        
00184 
00186     friend std::ostream& operator<<(std::ostream& os, const sparray::entry& ent);
00188     friend std::ostream& operator<<(std::ostream& os, const sparray& ar);
00189   public:
00190 
00202     sparray(int _rank=0);
00203 
00215     sparray(const tindices& _dims);
00216 
00222     sparray(int nrows, int ncols);
00223     
00228     sparray(const sparray& ar);
00229 
00234     sparray& operator=(const sparray& ar);
00235 
00237     virtual ~sparray() {};
00238 
00245     inline int              rank() const { return rank_; }
00246 
00250     inline tstate           state() const { return state_; }
00251 
00252     inline bool             isassembled() const { return ((state_==assembled)||(state_==incr_assembled)); }
00253 
00255     inline size_type        size() const { check_assembled("size"); return entries_rm.size(); }
00256 
00258     inline const tindices&  dimensions() const { check_assembled("dimensions"); return dims; }
00259 
00265     inline bool             isempty() const { check_assembled("empty"); return begin() == end(); }
00266 
00270     bool                    iszero() const;
00271 
00279     inline crc_type         crc32() const { return crc32_; }
00280     
00285     inline iterator         begin() { return begin_rm(); };
00286 
00291     inline iterator         end() { return end_rm(); };
00292 
00297     inline const_iterator   begin() const { return begin_rm(); };
00298 
00303     inline const_iterator   end() const { return end_rm(); };
00304 
00315     inline reference        at(size_type __n) { return at_rm(__n); };
00316 
00327     inline const_reference  at(size_type __n)  const { return at_rm(__n); };
00328 
00337     inline reference        operator[] (size_type __n) { check_assembled("operator[]"); return *entries_rm[__n]; };
00338 
00347     inline const_reference  operator[] (size_type __n) const { check_assembled("operator[]"); return *entries_rm[__n]; };
00348 
00353     inline reference        front() { return front_rm(); };
00354 
00359     inline const_reference  front() const { return front_rm(); };
00360 
00364     inline reference        back() { return back_rm(); };
00365 
00370     inline const_reference  back() const { return back_rm(); };
00371 
00377     inline int              find(const tindices& idx) const { return find_rm(idx); };
00378 
00379 
00384     inline iterator         begin_rm() { check_assembled("begin_rm"); return entries_rm.begin(); };
00385 
00390     inline iterator         end_rm() { check_assembled("end_rm"); return entries_rm.end(); };
00391 
00396     inline const_iterator   begin_rm() const { check_assembled("begin_rm"); return entries_rm.begin(); };
00397 
00402     inline const_iterator   end_rm() const { check_assembled("end_rm"); return entries_rm.end(); };
00403 
00408     iterator                begin_rm(int row);
00409 
00414     iterator                end_rm(int row);
00415 
00420     const_iterator          begin_rm(int row) const;
00421 
00426     const_iterator          end_rm(int row) const;
00427 
00438     inline reference        at_rm(size_type __n) { check_range(__n, "at_rm"); return *entries_rm[__n]; };
00439 
00450     inline const_reference  at_rm(size_type __n) const { check_range(__n, "at_rm"); return *entries_rm[__n]; };
00451 
00456     inline reference        front_rm() { check_assembled("front_rm"); return *begin_rm(); };
00457 
00462     inline const_reference  front_rm() const { check_assembled("front_rm"); return *begin_rm(); };
00463 
00467     inline reference        back_rm() { check_assembled("back_rm"); return *(end_rm() - 1); };
00468 
00473     inline const_reference  back_rm() const { check_assembled("back_rm"); return *(end_rm() - 1); };
00474 
00480     int                     find_rm(const tindices& idx) const;
00481 
00482 
00487     inline iterator         begin_cm() { check_assembled("begin_cm"); return entries_cm.begin(); };
00488 
00493     inline iterator         end_cm() { check_assembled("end_cm"); return entries_cm.end(); };
00494 
00499     inline const_iterator   begin_cm() const { check_assembled("begin_cm"); return entries_cm.begin(); };
00500 
00505     inline const_iterator   end_cm() const { check_assembled("end_cm"); return entries_cm.end(); };
00506 
00511     iterator                begin_cm(int col);
00512 
00517     iterator                end_cm(int col);
00518 
00523     const_iterator          begin_cm(int col) const;
00524 
00529     const_iterator          end_cm(int col) const;
00530 
00541     inline reference        at_cm(size_type __n) { check_range(__n, "at_cm"); return *entries_cm[__n]; };
00542 
00553     inline const_reference  at_cm(size_type __n) const { check_range(__n, "at_cm"); return *entries_cm[__n]; };
00554 
00559     inline reference        front_cm() { check_assembled("front_cm"); return *begin_cm(); };
00560 
00565     inline const_reference  front_cm() const { check_assembled("front_cm"); return *begin_cm(); };
00566 
00570     inline reference        back_cm() { check_assembled("back_cm"); return *(end_cm() - 1); };
00571 
00576     inline const_reference  back_cm() const { check_assembled("back_cm"); return *(end_cm() - 1); };
00577 
00583     int                     find_cm(const tindices& idx) const;
00584   
00588     void                    clear();
00589 
00595     void                    reset();
00596 
00601     void                    assemble();
00602 
00611     void                    append(const tindices& idx, tvalue value);
00612 
00618     void                    set_value(const tindices& idx, tvalue value);
00619 
00624     void                    set_value(tvalue value);
00625 
00631     void                    add_value(const tindices& idx, tvalue value);
00632 
00637     tvalue                  get_value(const tindices& idx) const;
00638 
00646 #ifndef _MSC_VER
00647     tvalue                  get_value(...) const;
00648 #else
00649     tvalue                  get_value(int num_vals, ...) const;
00650 #endif
00651 
00652 
00653       void print_pattern(std::ostream& os) const;
00654 
00662     std::ostream&           print(std::ostream& ostr, int nentries=-1) const;
00663 
00669     std::ostream&           print_matlab(std::ostream& ostr) const;
00670     
00671   private:
00677     void                    check_assembled(const char* func_name=NULL) const;
00678     
00685     void                    check_range(size_type __n, const char* func_name=NULL) const;
00686 
00694     void                    update_value(const tindices& idx, tvalue value, Common::Types::CapeBoolean addition);
00695 
00699     void                    init_structure();
00700 
00707     crc_type                crc32calc(const tindices& buff, unsigned long crc);
00708 
00709 
00710   private:
00711     tstate                  state_;          
00712     int                     rank_;           
00713     crc_type                crc32_;          
00714     tentries                entries;         
00715     tentries                new_entries;     
00716     tindices                dims;            
00717     pentries                entries_rm;      
00718     std::vector<int>        entries_rm_comp; 
00719 
00720 
00721     pentries                entries_cm;      
00722     std::vector<int>        entries_cm_comp; 
00723 
00724 
00725 
00726     std::vector<int>        incr_order;      
00727 
00728     unsigned int            incr_counter;    
00729 
00730   };
00731 
00733   typedef sparray DianaSparseArray;
00734 };
00735 
00736 
00737 #endif // DIANA_SPARSE_ARRAY_HPP