📄 sparse1d.h
字号:
//// 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_SPARSE1D_H#define MTL_SPARSE1D_H#include <algorithm>#include <set>#include "mtl/mtl_config.h"#include "mtl/entry.h"#include "mtl/sparse_iterator.h"#include "mtl/reverse_iter.h"#include "mtl/not_at.h"#include "mtl/utils.h"#include "mtl/matrix_traits.h"#include "mtl/scaled1D.h"#include "mtl/refcnt_ptr.h"namespace mtl {using std::lower_bound;using std::find;//: class for implementing a view into just the index array of a sparse// row/column//!noindex:template <class RepType>class sp1D_index_array { typedef sp1D_index_array<RepType> self;public: typedef int value_type; typedef int* pointer; typedef const int& reference; typedef const int& const_reference; typedef typename RepType::const_iterator rep_iter; class iterator { typedef iterator self; public: typedef const int& reference; inline iterator() { } inline iterator(rep_iter i) : iter(i) { } inline reference operator*() const { return iter.index(); } inline reference operator[](int n) const { return iter.index(); } inline self& operator++() { ++iter; return *this; } inline self operator++(int) { self t = *this; ++iter; return t; } inline self& operator--() { --iter; return *this; } inline self operator--(int) { self t = *this; --iter; return t; } inline bool operator!=(const self& x) { return iter != x.iter; } inline bool operator<(const self& x) { return iter < x.iter; } inline bool operator==(const self& x) { return iter == x.iter; } inline iterator operator+(int n) { return iterator(iter + n); } inline iterator operator-(int n) { return iterator(iter - n); } protected: rep_iter iter; }; typedef iterator const_iterator; typedef reverse_iter<iterator> reverse_iterator; typedef reverse_iter<const_iterator> const_reverse_iterator; sp1D_index_array(rep_iter s, rep_iter f) : start(s), finish(f) { } sp1D_index_array(const self& x) : start(x.start), finish(x.finish) { } inline const_iterator begin() { return start; } inline const_iterator end() { return finish; } inline const_reverse_iterator rbegin() { return const_reverse_iterator(finish); } inline const_reverse_iterator rend() { return const_reverse_iterator(start); } inline reference operator[](int n) { return start[n]; } /* JGS protected: */ rep_iter start; rep_iter finish;};/* VC++ work around -JGS */template <class T>inline typename T::iterator __sparseoned_find(T* oned, int i, std::set<typename T::entry_type>*) { return oned->__find_set(i);}template <class T, class R>inline typename T::iterator __sparseoned_find(T* oned, int i, R*) { return oned->__find_normal(i);}//: Sparse 1-D Container Adaptor//// This is a sparse vector implementation that can use several// different underlying containers, including <tt>std::vector</tt>,// <tt>std::list</tt>, and <tt>std::set</tt>.// <p>// This adaptor is used in the implementation of the linked_list,// tree, and sparse_pair OneD storage types (used with the array// matrix storage type). This adaptor can also be used as a stand-alone// Vector.// <p>// The value_type of the underlying containers must be entry1, which// is just an index-value pair.// <p>// The elements are ordered by their index as they are inserted.////!category: containers, adaptors//!component: type//!definition: sparse1D.h//!tparam: RepType - The Container type used to store the index value pairs.//!typereqs: The <TT>value_type</TT> of RepType must be of type <TT>entry1</TT>//!models: ContainerRef?//!example: gather_scatter.cctemplate <class RepType>class sparse1D { typedef sparse1D<RepType> self; typedef RepType rep_type; typedef rep_type ref_cont; typedef typename rep_type::iterator rep_type_iterator; typedef typename rep_type::const_iterator const_rep_type_iterator;public: /**@name Type Definitions */ enum { N = 0 }; //: This is a sparse vector typedef sparse_tag sparsity; //: The index-value pair type typedef typename RepType::value_type entry_type; //: This is a 1D container typedef oned_tag dimension; //: The scaled type typedef scaled1D< sparse1D< RepType > > scaled_type; //: The value type typedef typename entry_type::value_type value_type; //: The type for pointers to the value type typedef value_type* pointer; //: The unsigned integral type for dimensions and indices typedef typename RepType::size_type size_type; //: The type for differences between iterators typedef typename RepType::difference_type difference_type; //: The type for references to the value type typedef elt_ref<self> reference; //: The type for const references to the value type typedef value_type const_reference; //: The iterator type typedef sparse_iterator<rep_type_iterator,value_type> iterator; //: The const iterator type typedef const_sparse_iterator<const_rep_type_iterator,value_type> const_iterator; //: The reverse iterator type typedef reverse_iter<iterator> reverse_iterator; //: The const reverse iterator type typedef reverse_iter<const_iterator> const_reverse_iterator; //: The type for the index array typedef sp1D_index_array<RepType> IndexArray; //: The reference type for the index array typedef sp1D_index_array<RepType> IndexArrayRef; //: The type for subrange vectors typedef self subrange_type; friend class elt_ref<self>; friend class const_elt_ref<self>; inline iterator __find_set(int i) { rep_type_iterator pos = rep->lower_bound(entry_type(i)); return iterator(pos); } inline iterator __find_normal(int i) { rep_type_iterator pos = lower_bound(rep->begin(), rep->end(), entry_type(i)); return iterator(rep->begin(), pos); }protected: inline iterator find(int i) { return __sparseoned_find(this, i, rep.operator->()); } /* const versions of find */ inline const_iterator __find(int i, std::set<entry_type>*) const { const_rep_type_iterator pos = rep->lower_bound(entry_type(i)); return const_iterator(pos); } template <class R> inline const_iterator __find(int i, R*) const { const_rep_type_iterator pos = lower_bound(rep->begin(), rep->end(), entry_type(i)); return const_iterator(rep->begin(), pos); } inline const_iterator find(int i) const { return __find(i, rep.operator->()); } inline iterator insert(iterator iter, int i, value_type v) { rep_type_iterator pos = rep->insert(iter.base(), entry_type(i, v)); return iterator(rep->begin(), pos); } public: /**@name Constructors */ //: Default Constructor inline sparse1D() : rep(new ref_cont()), size_(0) { } //: Length N Constructor inline sparse1D(size_type n) : rep(new ref_cont()), size_(n) { } //: Copy Constructor inline sparse1D(const self& x) : rep(x.rep), size_(x.size_) { } //: Construct from index array template <class IndexArray> inline sparse1D(const IndexArray& x, size_type n) : rep(new ref_cont()), size_(n) { typename IndexArray::const_iterator i; for (i = x.begin(); i != x.end(); ++i) rep->push_back(entry_type(*i, value_type(0))); } //: Assignment Operator inline self& operator=(const self& x) { rep = x.rep; 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(rep->begin()); } //: Return an iterator pointing past the end of the vector //!wheredef: Container inline iterator end() { return iterator(rep->begin(), rep->end()); } //: Return a const iterator pointing to the begining of the vector //!wheredef: Container inline const_iterator begin() const { return const_iterator(rep->begin()); } //: Return a const iterator pointing past the end of the vector //!wheredef: Container inline const_iterator end() const { return const_iterator(rep->begin(), rep->end()); } //: 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 */ //: Element Access, return element with index i inline const_reference operator[](int i) const MTL_THROW_ASSERTION { MTL_ASSERT(i < size(), "sparse1D:operator[]"); const_iterator iter = find(i); if (iter != end() && iter.index() == i) return *iter; else return value_type(0); } //: Element Access, return element with index i inline reference operator[](int i) MTL_THROW_ASSERTION { MTL_ASSERT(i < size(), "sparse1D::operator[]"); return reference(*this, i); } //: Insert the value at index i of the vector inline iterator insert(int i, const value_type& value) MTL_THROW_ASSERTION { MTL_ASSERT(i < size(), "sparse1D::insert"); rep_type_iterator pos = lower_bound(rep->begin(), rep->end(), entry_type(i)); return rep->insert(pos, entry_type(i, value)); } inline void clear() { rep->clear(); } inline void push_back(int i, const value_type& value) { MTL_ASSERT(i < size(), "sparse1D::push_back"); rep->insert(rep->end(), entry_type(i, value)); } /**@name Size Methods */ //: Returns length of the vector (including non-zeroes) inline int size() const { return size_; } //: Number of non-zero (stored) elements inline int nnz() const { return rep->size(); } inline void resize_imp(int n, std::set<entry_type>*) { } template <class R> inline void resize_imp(int n, R*) { rep->resize(n); } //: Resizes the vector to size n inline void resize(int n) { resize_imp(n, rep.operator->()); } rep_type& get_rep() { return *rep; } inline void print() const { print_vector(*rep); } //: Return an array of indices describing the non-zero structure inline IndexArrayRef nz_struct() const { return IndexArrayRef(rep->begin(), rep->end()); }protected: refcnt_ptr<rep_type> rep; size_type size_;};} /* namespace mtl */#endif /* obsolete, not used anymore inline void set(int i, value_type val) { rep_type_iterator pos = lower_bound(rep->begin(), rep->end(), entry_type(i)); if (pos != rep->end()) if ((*pos).index != i) rep->insert(pos, entry_type(i, val)); else (*pos).value = val; else rep->insert(pos, entry_type(i, val)); } inline value_type get(int i) { value_type ret; const_rep_type_iterator pos = std::find(rep->begin(), rep->end(), entry_type(i)); if (pos != rep->end()) ret = (*pos).value; else ret = 0.0; return ret; } */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -