?? compressed1d.h
字號:
// -*- c++ -*-//// Copyright 1997, 1998, 1999 University of Notre Dame.// Authors: Andrew Lumsdaine, Jeremy G. Siek, Lie-Quan Lee//// This file is part of the Matrix Template Library//// You should have received a copy of the License Agreement for the// Matrix Template Library along with the software; see the// file LICENSE. If not, contact Office of Research, University of Notre// Dame, Notre Dame, IN 46556.//// Permission to modify the code and to distribute modified code is// granted, provided the text of this NOTICE is retained, a notice that// the code was modified is included with the above COPYRIGHT NOTICE and// with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE// file is distributed with the modified code.//// LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.// By way of example, but not limitation, Licensor MAKES NO// REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY// PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS// OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS// OR OTHER RIGHTS.//////===========================================================================#ifndef MTL_COMPRESSED1D_H#define MTL_COMPRESSED1D_H#include <vector>#include <algorithm>#include "mtl/mtl_config.h"#include "mtl/entry.h"#include "mtl/compressed_iter.h"#include "mtl/reverse_iter.h"#include "mtl/matrix_traits.h"#include "mtl/refcnt_ptr.h"#include "mtl/scaled1D.h"#include "mtl/light1D.h"#include "mtl/dense1D.h" /* for VC++ workaround -JGS */namespace mtl {using std::lower_bound;using std::find;//: Compressed Sparse Vector//// The compressed1D Vector is a sparse vector implemented with// a pair of parallel arrays. One array is for the element values,// and the other array is for the indices of those elements.// The elements are ordered by their index as they are inserted// into the compressed1D. compressed1D's can be used to build// matrices with the array storage format, and they can also// be used on their own.//// <pre>// [ (1.2, 3), (4.6, 5), (1.0, 10), (3.7, 32) ] A Sparse Vector//// [ 1.2, 4.6, 1.0, 3.7 ] Value Array// [ 3, 5, 10, 32 ] Index Array// </pre>//// <p>The <tt>compressed1D::iterator</tt> dereferences (<tt>*i</tt>) to// return the element value. One can access the index of that element// with the <tt>i.index()</tt> function. One can also access// the array of indices through the <tt>nz_struct()</tt> method.//// <p>One particularly useful fact is that one can perform// scatters and gathers of sparse elements by using the// <tt>mtl::copy(x,y)</tt> function with a sparse and a// dense vector.////!category: containers//!component: type//!models: Vector//!definition: compressed1D.h//!tparam: T - the element type//!tparam: SizeType - the type for the stored indices - int//!tparam: IND_OFFSET - To handle indexing from 0 or 1 - index_from_zero//!example: gather_scatter.cc, array2D.cc, sparse_copy.cctemplate <class T, class SizeType = int, int IND_OFFSET = index_from_zero>class compressed1D { typedef std::vector<T> values_vec; typedef std::vector<SizeType> indices_vec; typedef indices_vec indices_t; typedef values_vec values_t; typedef refcnt_ptr< values_vec > values_ptr; typedef refcnt_ptr< indices_vec > indices_ptr; typedef compressed1D<T,SizeType,IND_OFFSET> self; typedef typename indices_vec::iterator index_iterator; typedef typename values_vec::iterator value_iterator; typedef typename indices_vec::const_iterator index_const_iterator; typedef typename values_vec::const_iterator value_const_iterator; friend class elt_ref<self>; friend class const_elt_ref<self>;public: /**@name Type Definitions */ enum { N = 0 }; //: This is a sparse vector typedef sparse_tag sparsity; //: This is a 1D container typedef oned_tag dimension; //: Scaled type of this vector typedef scaled1D< self > scaled_type; //: Element type typedef typename values_t::value_type value_type;#if defined(_MSVCPP_) typedef value_type* pointer;#else //: A pointer to the element type typedef typename values_t::pointer pointer;#endif //: Unsigned integral type for dimensions and indices typedef SizeType size_type; //: Integral type for differences in iterators typedef typename values_t::difference_type difference_type; //: Reference to the value type typedef elt_ref<self> reference; //: Const reference to the value type typedef const_elt_ref<self> const_reference; //: Iterator type typedef compressed_iter<0,values_vec, indices_vec,IND_OFFSET> iterator; //: Const iterator type typedef compressed_iter<1,values_vec, indices_vec,IND_OFFSET> const_iterator; //: Reverse iterator type typedef reverse_iter<iterator> reverse_iterator; //: The const reverse iterator type typedef reverse_iter<const_iterator> const_reverse_iterator; //: Reference to the index array typedef const indices_vec& IndexArrayRef; //: The type for the index array typedef const indices_t IndexArray; //: The type for the subrange vector typedef self subrange_type; /* JGS need to think about this */ /**@name Constructors */ //: Default Constructor inline compressed1D() : values(new values_t(0)), indices(new indices_t(0)), size_(0) { } //: Length N Constructor inline compressed1D(size_type n) : values(new values_t(0)), indices(new indices_t(0)), size_(n) { } //: Copy Constructor inline compressed1D(const self& x) : values(x.values), indices(x.indices), size_(x.size_) { } //: Index Array Constructor template <class IndexIter> inline compressed1D(IndexIter first, IndexIter last, size_type n) : values(new values_t(n)), indices(new indices_t(n)), size_(n) { std::copy(first, last, indices->begin()); } //: Assignment Operator inline self& operator=(const self& x) { values = x.values; indices = x.indices; size_ = x.size_; return *this; } /**@name Access Methods */ /**@name Iterator Access Methods */ //: Return an iterator pointing to the beginning of the vector //!wheredef: Container inline iterator begin() { return iterator(values->begin(), indices->begin(), 0); } //: Return an iterator pointing past the end of the vector //!wheredef: Container inline iterator end() { return iterator(values->begin(), indices->begin(), indices->size()); } //: Return a const iterator pointing to the begining of the vector //!wheredef: Container inline const_iterator begin() const { return const_iterator(values->begin(), indices->begin(), 0); } //: Return a const iterator pointing past the end of the vector //!wheredef: Container inline const_iterator end() const { return const_iterator(values->begin(), indices->begin(), indices->size()); } //: Return a reverse iterator pointing to the last element of the vector //!wheredef: Reversible Container inline reverse_iterator rbegin() { return reverse_iterator(end()); } //: Return a reverse iterator pointing past the end of the vector //!wheredef: Reversible Container inline reverse_iterator rend() { return reverse_iterator(begin()); } //: Return a const reverse iterator pointing to the last element of the vector //!wheredef: Reversible Container inline const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); } //: Return a const reverse iterator pointing past the end of the vector //!wheredef: Reversible Container inline const_reverse_iterator rend() const { return const_reverse_iterator(begin()); } /**@name Element Access Methods */ //: Access the element with index i inline reference operator[](size_type i) MTL_THROW_ASSERTION { MTL_ASSERT(i < size(), "compressed1D::operator[]"); return reference(*this, i); } //: Access the element with index i inline const_reference operator[](size_type i) const MTL_THROW_ASSERTION { MTL_ASSERT(i < size(), "compressed1D::operator[]"); return const_reference(*this, i); } //for BEAM only value_type& get_ref(size_type i) { iterator iter = find(i); if ( iter != end() ) { if ( iter.index() != i ) iter = insert(iter, i, T(0)); } else iter = insert(iter, i, T(0)); return *iter; } /* * list operations */ /* OneD required insert method: */ //: Insert val into the vector at index i inline iterator insert(size_type i, const T& val) MTL_THROW_ASSERTION { MTL_ASSERT(i < size(), "compressed1D::insert"); index_iterator index_iter = lower_bound(indices->begin(), indices->end(), i - IND_OFFSET);/* F to C */ index_iter = indices->insert(index_iter, i - IND_OFFSET); /* F to C */ size_type n = index_iter - indices->begin(); value_iterator val_iter = values->insert(values->begin() + n, val); return iterator(index_iter, val_iter); } //: Push back, warning: must insert elements ordered by index. // This method does not change the size() of the vector. inline void push_back(size_type i, const T& val) MTL_THROW_ASSERTION { MTL_ASSERT(i < size(), "compressed1D::push_back"); values->push_back(val); indices->push_back(i); } //: Erase the vector inline void clear() { indices->clear(); values->clear(); } //: The size of the vector (including non-zeroes) inline size_type size() const { return size_; } //: The number of non-zero elements (the number stored) inline size_type nnz() const { return values->size(); } //: Resize the vector to size n inline void resize(size_type n) { size_ = n; } //: Reserve storage for n non-zero elements inline void reserve(size_type n) { values->reserve(n); indices->reserve(n); } //: Returns the array of indices inline IndexArrayRef nz_struct() const { return *indices; } //: Returns the array of indices inline IndexArrayRef nz_struct() { return *indices; }protected: inline iterator find(size_type i) { index_iterator iter = lower_bound(indices->begin(), indices->end(), i - IND_OFFSET); /* F to C */ size_type n = iter - indices->begin(); return iterator(values->begin(), indices->begin(), n); } inline const_iterator find(size_type i) const { index_const_iterator iter = lower_bound(indices->begin(), indices->end(), i - IND_OFFSET); /* F to C */ size_type n = iter - indices->begin(); return const_iterator(values->begin(), indices->begin(), n); } inline iterator insert(iterator iter, size_type i, T v) { index_iterator ind = indices->insert(iter.index_iter(), i - IND_OFFSET); /* F to C */ values->insert(iter.value_iter(), v); size_type n = ind - indices->begin(); return iterator(values->begin(), indices->begin(), n); } protected: values_ptr values; indices_ptr indices; size_type size_;};} /* namespace mtl */#endif#if 0 class elt_inserter { public: inline elt_inserter(const elt_inserter& x) : val(x.val), ind(x.ind) { } inline elt_inserter(T& v, size_type& i) : val(v), ind(i) { } void operator=(const twod_elt<T,size_type>& elt) { val = elt.val(); ind = elt.minor(); } protected: T& val; size_type& ind; }; class insert_iterator { typedef values_vec::iterator val_iter_t; typedef indices_vec::iterator ind_iter_t; typedef insert_iterator self; public: inline insert_iterator(const val_iter_t& v, const ind_iter_t& i) : val_iter(v), ind_iter(i) { } inline elt_inserter operator * () { return elt_inserter(*val_iter, *ind_iter); } inline self& operator ++ () { ++val_iter; ++ind_iter; return *this; } inline self& operator ++ (int) { self t = *this; ++val_iter; ++ind_iter; return t; } protected: val_iter_t val_iter; ind_iter_t ind_iter; }; inline insert_iterator inserter() { return insert_iterator(values->begin(), indices->begin()); }#endif
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -