Diana
0.8.3
|
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