// // $COPYRIGHT$ // //=========================================================================== #ifndef MTL_LINALG_VECTOR_H #define MTL_LINALG_VECTOR_H #include #include #include "mtl/refcnt_ptr.h" #include "mtl/dense_iterator.h" #include "mtl/reverse_iter.h" #include "mtl/light1D.h" #include "mtl/mtl_config.h" #include "mtl/matrix_traits.h" #include "mtl/scaled1D.h" #include "mtl/mtl_exception.h" //#include "mtl/external_vector.h" #include "mtl/mxtl_expr.h" namespace mtl { //: Linalg Vector Adaptor //!category: containers, adaptors //!component: type // // This class is obsolete and not used. // //!definition: linalg_vector.h //!tparam: RepType - the underlying representation //!models: Linalg_Vector template class linalg_vec { public: typedef linalg_vec self; typedef RepType rep_type; typedef RepPtr rep_ptr; enum { N = NN }; /**@name Type Definitions */ /* enum { dimension = 1 }; */ typedef oned_tag dimension; //: The sparsity tag typedef dense_tag sparsity; //: The value type //!wheredef: Container typedef typename rep_type::value_type value_type; //: The reference type //!wheredef: Container typedef typename rep_type::reference reference; //: The const reference type //!wheredef: Container typedef typename rep_type::const_reference const_reference; //: The pointer (to the value_type) type //!wheredef: Container typedef typename rep_type::pointer pointer; //: The size type (non negative) //!wheredef: Container typedef typename rep_type::size_type size_type; //: The difference type (an integral type) //!wheredef: Container typedef typename rep_type::difference_type difference_type; #if !defined( _MSVCPP_ ) //: The iterator type //!wheredef: Container typedef dense_iterator iterator; //: The const iterator type //!wheredef: Container typedef dense_iterator const_iterator; #else typedef dense_iterator iterator; typedef dense_iterator const_iterator; #endif //: The reverse iterator type //!wheredef: Reversible Container typedef reverse_iter reverse_iterator; //: The const reverse iterator type //!wheredef: Reversible Container typedef reverse_iter const_reverse_iterator; /* skip over the zeros and report the indices this implements the nonzero structure array */ typedef linalg_vec Vec; typedef size_type Vec_size_type; typedef difference_type Vec_difference_type; typedef iterator Vec_iterator; typedef const_iterator Vec_const_iterator; //: blah //!noindex: class IndexArray { public: typedef Vec_size_type size_type; typedef Vec_difference_type difference_type; typedef Vec_size_type value_type; //: blah //!noindex: class iterator { public: typedef size_type value_type; typedef size_type reference; typedef size_type* pointer; typedef Vec_difference_type difference_type; typedef typename std::iterator_traits::iterator_category iterator_category; iterator(Vec_iterator iter, Vec_iterator e) : i(iter), end(e) { while (*i == Vec_value_type(0)) ++i; } reference operator*() const { return i.index(); } iterator& operator++() { ++i; while (*i == Vec_value_type(0) && i != end) ++i; return *this; } iterator operator++(int) { iterator t = *this; ++(*this); return t; } iterator& operator--() { --i; while (*i == Vec_value_type(0) && i != end) --i; return *this; } iterator operator--(int) { iterator t = *this; --(*this); return t; } difference_type operator-(const iterator& x) const { return i - x.i; } bool operator==(const iterator& x) const { return i == x.i; } bool operator!=(const iterator& x) const { return i != x.i; } bool operator<(const iterator& x) const { return i < x.i; } Vec_iterator i; Vec_iterator end; }; //: blah //!noindex: class const_iterator { public: typedef size_type value_type; typedef size_type reference; typedef size_type* pointer; typedef Vec_difference_type difference_type; typedef typename std::iterator_traits::iterator_category iterator_category; const_iterator(Vec_const_iterator iter, Vec_const_iterator e) : i(iter), end(e) { while (*i == Vec_value_type(0) && i != end) ++i; } reference operator*() const { return i.index(); } const_iterator& operator++() { ++i; while (*i == Vec_value_type(0) && i != end) ++i; return *this; } const_iterator operator++(int) { const_iterator t = *this; ++(*this); return t; } const_iterator& operator--() { --i; while (*i == Vec_value_type(0)) --i; return *this; } const_iterator operator--(int) { const_iterator t = *this; --(*this); return t; } difference_type operator-(const const_iterator& x) const { return i - x.i; } bool operator==(const const_iterator& x) const { return i == x.i; } bool operator!=(const const_iterator& x) const { return i != x.i; } bool operator<(const const_iterator& x) const { return i < x.i; } Vec_const_iterator i; Vec_const_iterator end; }; inline IndexArray(const Vec& v) : vec((Vec*)&v) { } inline iterator begin() { return iterator(vec->begin(), vec->end()); } inline iterator end() { return iterator(vec->end(), vec->end()); } inline const_iterator begin() const{ return const_iterator(((const Vec*)vec)->begin(), ((const Vec*)vec)->end()); } inline const_iterator end() const { return const_iterator(((const Vec*)vec)->end(), ((const Vec*)vec)->end()); } size_type size() const { size_type s = 0; Vec_const_iterator i; for (i = ((const Vec*)vec)->begin(); i != ((const Vec*)vec)->end(); ++i) if (*i != Vec_value_type(0)) ++s; return s; } Vec* vec; }; //: The type for an array of the indices of the element in the vector //!wheredef: Vector typedef IndexArray IndexArrayRef; //: The type for a subrange vector-view of the original vector //!wheredef: Vector typedef light1D subrange_type; typedef std::pair range; /**@name Constructors */ //: Default Constructor (allocates the container) //!wheredef: Container inline linalg_vec() : rep(0) { } //: Normal Constructor inline linalg_vec(rep_ptr x, size_type start_index) : rep(x), first(start_index) { } //: Copy Constructor (shallow copy) //!wheredef: ContainerRef inline linalg_vec(const self& x) : rep(x.rep), first(x.first) { } //: The destructor. //!wheredef: Container inline ~linalg_vec() { } //: Assignment Operator (shallow copy) //!wheredef: AssignableRef inline self& operator=(const self& x) { rep = x.rep; first = x.first; 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(), 0, first); } //: Return an iterator pointing past the end of the vector //!wheredef: Container inline iterator end() { return iterator(rep->begin(), rep->size(), first); } //: Return a const iterator pointing to the begining of the vector //!wheredef: Container inline const_iterator begin() const { return const_iterator(rep->begin(), 0, first); } //: Return a const iterator pointing past the end of the vector //!wheredef: Container inline const_iterator end() const{ return const_iterator(rep->begin(), rep->size(), first); } //: 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 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 reverse_iterator(begin()); } /**@name Element Access Methods */ //: Return a reference to the element with the ith index //!wheredef: Vector inline reference operator[](size_type i) MTL_THROW_ASSERTION { MTL_ASSERT(i < size(), "linalg_vec::operator[]"); return (*rep)[i - first]; } inline subrange_type operator()(range r) MTL_THROW_ASSERTION { return subrange_type(data() + r.first, r.second - r.first); } inline subrange_type operator()(size_type s, size_type f) MTL_THROW_ASSERTION { return subrange_type(data() + s, f - s); } //: Return a const reference to the element with the ith index //!wheredef: Vector inline const_reference operator[](size_type i) const MTL_THROW_ASSERTION { MTL_ASSERT(i < size(), "linalg_vec::operator[]"); return (*rep)[i - first]; } /**@name Size Methods */ //: The size of the vector //!wheredef: Container inline size_type size() const { return rep->size(); } //: The number of non-zeroes in the vector inline size_type nnz() const { return rep->size(); } //: Resize the vector to n inline void resize(size_type n) { rep->resize(n); } //: Resize the vector to n, and assign x to the new positions inline void resize(size_type n, const value_type& x) { rep->resize(n, x); } //: Return the total capacity of the vector size_type capacity() const { return rep->capacity(); } //: Reserve more space in the vector void reserve(size_type n) { rep->reserve(n); } //: Raw Memory Access inline const value_type* data() const { return &(*rep)[0]; } //: Raw Memory Access inline value_type* data() { return &(*rep)[0]; } //: Insert x at the indicated position in the vector //!wheredef: Container inline iterator insert (iterator position, const value_type& x = value_type()) { return iterator(rep->insert(position.base(), x), position.index()+1); /* JGS, not sure about what to do with the index here */ } inline IndexArrayRef nz_struct() const { return IndexArrayRef(*this); } inline self& adjust_index(size_type i) { first += i; return *this; } protected: rep_ptr rep; size_type first; }; //: External 1-D Container //!category: containers //!component: type // // This is similar to dense1D, except that the memory is provided // by the user. This allows for interoperability with other array // packages and even with Fortran. // //!definition: linalg_vec.h //!tparam: T - The element type. //!tparam: NN - The static size of the Vector, 0 if dynamic size //!tparam: SizeT - The size type to use - size_t //!tparam: DiffT - ptrdiff_t //!models: Vector //!example: dot_prod.cc, apply_givens.cc, euclid_norm.cc, max_index.cc template class external_vec : public mxtl_expr< external_vec > { typedef external_vec self; public: enum { N = NN, SIZE = NN }; typedef Orien orientation; typedef external_vec::tag> transpose_type; typedef external_vec IndexArray; /* JGS */ /* Type Definitions */ //: The vector is dense typedef dense_tag sparsity; typedef SizeType size_type; typedef int difference_type; //: The element type typedef T value_type; //: The reference to the value type typedef T& reference; //: The pointer ot the value type typedef T* pointer; typedef const T* const_pointer; //: The const reference type typedef const T& const_reference; #if !defined( _MSVCPP_) //: The iterator type typedef dense_iterator iterator; //: The const iterator type typedef dense_iterator const_iterator; #else typedef dense_iterator iterator; typedef dense_iterator const_iterator; #endif //: The reverse iterator type typedef reverse_iter reverse_iterator; //: The const reverse iterator type typedef reverse_iter const_reverse_iterator; //: //!wheredef: Vector typedef self IndexArrayRef; //: The type for the subrange vector //!wheredef: Vector typedef self subrange_type; typedef std::pair range; //: This is a 1D container typedef oned_tag dimension; /* Constructors */ //: Default Constructor inline external_vec() : rep(0), size_(0), first(0) { } //: External Data Contructor inline external_vec(T* data) : rep(data), size_(N), first(0) { } //: Preallocated Memory Constructor with optional non-zero starting index inline external_vec(T* data, size_type n, size_type start = 0) : rep(data), size_(n), first(start) { } //: Copy Constructor inline external_vec(const self& x) : rep(x.rep), size_(x.size_), first(x.first) { } //: Assignment inline self& operator=(const self& x) { rep = x.rep; size_ = x.size_; first = x.first; return *this; } template inline self& operator=(const Expression& rhs) { typedef Expression RHS; typedef typename CreateLeaf::Leaf_t Leaf_t; evaluate(*this, OpAssign(), MakeReturn::make(CreateLeaf::make(rhs))); return *this; } //: Destructor inline ~external_vec() { } /* Access Methods */ /* Iterator Access Methods */ //: Return an iterator pointing to the beginning of the vector //!wheredef: Container inline iterator begin() { return iterator(rep, 0, first); } //: Return an iterator pointing past the end of the vector //!wheredef: Container inline iterator end() { return iterator(rep, size(), first); } //: Return a const iterator pointing to the begining of the vector //!wheredef: Container inline const_iterator begin() const { return const_iterator(rep, 0, first); } //: Return a const iterator pointing past the end of the vector //!wheredef: Container inline const_iterator end() const{ return const_iterator(rep, size(), first); } //: 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()); } /* Element Access Methods */ //: Return a reference to the element with the ith index //!wheredef: Vector inline reference operator[](size_type i) { return rep[i - first]; } //: Return a const reference to the element with the ith index //!wheredef: Vector inline const_reference operator[](size_type i) const { return rep[i - first]; } //: Return a subrange vector with start at s and finish at f //!wheredef: Vector inline subrange_type operator()(size_type s, size_type f) const { return subrange_type(rep + s - first, f - s, s); } inline subrange_type operator()(range r) MTL_THROW_ASSERTION { return subrange_type(data() + r.first, r.second - r.first); } /* Size Methods */ //: The size of the vector //!wheredef: Container inline size_type size() const { return N ? N : size_; } //: The number of non-zeroes in the vector //!wheredef: Vector inline size_type nnz() const { return size(); } //: Resize the vector to size n #if 0 inline void resize(size_type n) { if (rep) delete [] rep; size_ = n; rep = new T[size_]; } #else inline void resize(size_type n) { size_ = n; } inline void clear() { size_ = 0; } #endif //: Raw Memory Access inline value_type* data() const { return rep; } inline self& adjust_index(size_type i) { first += i; return *this; } //: Push x onto the end of the vector, increasing the size // This function does not allocation memory. // Better hope enough memory is already there! void push_back(const T& x) { rep[size_] = x; ++size_; } protected: T* rep; size_type size_; size_type first; }; //: blah //!noindex: template struct __make_external { template inline external_vec operator()(T* x) { return external_vec(x); } }; /* For converting static arrays into MTL vectors */ #define array_to_vec(x) mtl::__make_external()(x) template inline linalg_vec vec(const Container& x) { return linalg_vec(x); } } /* namespace mtl */ #endif