vector.hpp
Go to the documentation of this file.
1 /*!
2  * \brief Implements the Dense vector class
3  *
4  * \author O. Krause
5  * \date 2014
6  *
7  *
8  * \par Copyright 1995-2015 Shark Development Team
9  *
10  * <BR><HR>
11  * This file is part of Shark.
12  * <http://image.diku.dk/shark/>
13  *
14  * Shark is free software: you can redistribute it and/or modify
15  * it under the terms of the GNU Lesser General Public License as published
16  * by the Free Software Foundation, either version 3 of the License, or
17  * (at your option) any later version.
18  *
19  * Shark is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22  * GNU Lesser General Public License for more details.
23  *
24  * You should have received a copy of the GNU Lesser General Public License
25  * along with Shark. If not, see <http://www.gnu.org/licenses/>.
26  *
27  */
28 #ifndef SHARK_LINALG_BLAS_VECTOR_HPP
29 #define SHARK_LINALG_BLAS_VECTOR_HPP
30 
31 #include "vector_proxy.hpp"
32 #include <boost/container/vector.hpp>
33 #include <boost/serialization/array.hpp>
34 #include <boost/serialization/nvp.hpp>
35 #include <boost/serialization/collection_size_type.hpp>
36 
37 namespace shark {
38 namespace blas {
39 
40 /** \brief A dense vector of values of type \c T.
41  *
42  * For a \f$n\f$-dimensional vector \f$v\f$ and \f$0\leq i < n\f$ every element \f$v_i\f$ is mapped
43  * to the \f$i\f$-th element of the container. A storage type \c A can be specified which defaults to \c unbounded_array.
44  * Elements are constructed by \c A, which need not initialise their value.
45  *
46  * \tparam T type of the objects stored in the vector (like int, double, complex,...)
47  * \tparam A The type of the storage array of the vector. Default is \c unbounded_array<T>. \c <bounded_array<T> and \c std::vector<T> can also be used
48  */
49 template<class T>
50 class vector:
51  public vector_container<vector<T> > {
52 
53  typedef vector<T> self_type;
54  typedef boost::container::vector<T> array_type;
55 public:
56 
57  typedef typename array_type::size_type size_type;
58  typedef typename array_type::difference_type difference_type;
59  typedef typename array_type::value_type value_type;
60  typedef value_type scalar_type;
61  typedef typename array_type::const_reference const_reference;
62  typedef typename array_type::reference reference;
63  typedef T *pointer;
64  typedef const T *const_pointer;
65 
66  typedef std::size_t index_type;
67  typedef index_type const* const_index_pointer;
68  typedef index_type index_pointer;
69 
70  typedef const vector_reference<const self_type> const_closure_type;
71  typedef vector_reference<self_type> closure_type;
72  typedef self_type vector_temporary_type;
73  typedef dense_tag storage_category;
74  typedef elementwise_tag evaluation_category;
75 
76  // Construction and destruction
77 
78  /// \brief Constructor of a vector
79  /// By default it is empty, i.e. \c size()==0.
80  vector():m_storage() {}
81 
82  /// \brief Constructor of a vector with a predefined size
83  /// By default, its elements are initialized to 0.
84  /// \param size initial size of the vector
85  explicit vector(size_type size):m_storage(size) {}
86 
87  /// \brief Constructs the vector from a predefined range
88  template<class Iter>
89  vector(Iter begin, Iter end):m_storage(begin,end){}
90 
91  /// \brief Constructor of a vector by copying from another container
92  /// This type has the generic name \c array_typ within the vector definition.
93  /// \param data container of type \c A
94  vector(const array_type& data):m_storage(data) {}
95 
96  /// \brief Constructor of a vector with a predefined size and a unique initial value
97  /// \param size of the vector
98  /// \param init value to assign to each element of the vector
99  vector(size_type size, const value_type& init):m_storage(size, init) {}
100 
101  /// \brief Copy-constructor of a vector
102  /// \param v is the vector to be duplicated
103  vector(vector const& v):m_storage(v.m_storage) {}
104 
105  /// \brief Copy-constructor of a vector from a vector_expression
106  /// Depending on the vector_expression, this constructor can have the cost of the computations
107  /// of the expression (trivial to say it, but it is to take into account in your complexity calculations).
108  /// \param e the vector_expression which values will be duplicated into the vector
109  template<class E>
111  :m_storage(e().size()) {
112  assign(*this, e);
113  }
114 
115  // ---------
116  // Dense low level interface
117  // ---------
118 
119  /// \brief Return the size of the vector.
120  size_type size() const {
121  return m_storage.size();
122  }
123 
124  ///\brief Returns the pointer to the beginning of the vector storage
125  ///
126  /// Grants low-level access to the vectors internals. Elements storage()[0]...storage()[size()-1] are valid.
127  pointer storage(){
128  return size()?&m_storage[0]:0;
129  }
130 
131  ///\brief Returns the pointer to the beginning of the vector storage
132  ///
133  /// Grants low-level access to the vectors internals. Elements storage()[0]...storage()[size()-1] are valid.
134  const_pointer storage()const{
135  return size()?&m_storage[0]:0;
136  //~ return &m_storage[0];
137  }
138 
139  ///\brief Returns the stride between the elements in storage()
140  ///
141  /// In general elements of dense storage entities are spaced like storage()[i*stride()] for i=1,...,size()-1
142  /// However for vector strid is guaranteed to be 1.
143  difference_type stride()const{
144  return 1;
145  }
146 
147  // ---------
148  // High level interface
149  // ---------
150 
151  /// \brief Return the maximum size of the data container.
152  /// Return the upper bound (maximum size) on the data container. Depending on the container, it can be bigger than the current size of the vector.
153  size_type max_size() const {
154  return m_storage.max_size();
155  }
156 
157  /// \brief Return true if the vector is empty (\c size==0)
158  /// \return \c true if empty, \c false otherwise
159  bool empty() const {
160  return m_storage.size() == 0;
161  }
162 
163  /// \brief Resize the vector
164  /// \param size new size of the vector
165  void resize(size_type size) {
166  m_storage.resize(size);
167  }
168 
169  // --------------
170  // Element access
171  // --------------
172 
173  /// \brief Return a const reference to the element \f$i\f$
174  /// Return a const reference to the element \f$i\f$. With some compilers, this notation will be faster than \c operator[]
175  /// \param i index of the element
176  const_reference operator()(index_type i) const {
177  return storage()[i];
178  }
179 
180  /// \brief Return a reference to the element \f$i\f$
181  /// Return a reference to the element \f$i\f$. With some compilers, this notation will be faster than \c operator[]
182  /// \param i index of the element
183  reference operator()(index_type i) {
184  return storage()[i];
185  }
186 
187  /// \brief Return a const reference to the element \f$i\f$
188  /// \param i index of the element
189  const_reference operator [](index_type i) const {
190  return (*this)(i);
191  }
192 
193  /// \brief Return a reference to the element \f$i\f$
194  /// \param i index of the element
195  reference operator [](index_type i) {
196  return (*this)(i);
197  }
198 
199  ///\brief Returns the first element of the vector
200  reference front(){
201  return storage()[0];
202  }
203  ///\brief Returns the first element of the vector
204  const_reference front()const{
205  return storage()[0];
206  }
207  ///\brief Returns the last element of the vector
208  reference back(){
209  return storage()[size()-1];
210  }
211  ///\brief Returns the last element of the vector
212  const_reference back()const{
213  return storage()[size()-1];
214  }
215 
216  ///\brief resizes the vector by appending a new element to the end. this invalidates storage
217  void push_back(value_type const& element){
218  m_storage.push_back(element);
219  }
220 
221  /// \brief Clear the vector, i.e. set all values to the \c zero value.
222  void clear() {
223  std::fill(m_storage.begin(), m_storage.end(), value_type/*zero*/());
224  }
225 
226  // -------------------
227  // Assignment operators
228  // -------------------
229 
230  /// \brief Assign a full vector (\e RHS-vector) to the current vector (\e LHS-vector)
231  /// Assign a full vector (\e RHS-vector) to the current vector (\e LHS-vector). This method does not create any temporary.
232  /// \param v is the source vector container
233  /// \return a reference to a vector (i.e. the destination vector)
234  vector& operator = (vector const& v) {
235  m_storage = v.m_storage;
236  return *this;
237  }
238 
239  /// \brief Assign a full vector (\e RHS-vector) to the current vector (\e LHS-vector)
240  /// Assign a full vector (\e RHS-vector) to the current vector (\e LHS-vector). This method does not create any temporary.
241  /// \param v is the source vector container
242  /// \return a reference to a vector (i.e. the destination vector)
243  template<class C> // Container assignment without temporary
245  resize(v().size());
246  return assign(*this, v);
247  }
248 
249  /// \brief Assign the result of a vector_expression to the vector
250  /// Assign the result of a vector_expression to the vector.
251  /// \param e is a const reference to the vector_expression
252  /// \return a reference to the resulting vector
253  template<class E>
255  self_type temporary(e);
256  swap(*this,temporary);
257  return *this;
258  }
259 
260  // Iterator types
261  typedef dense_storage_iterator<value_type> iterator;
262  typedef dense_storage_iterator<value_type const> const_iterator;
263 
264  /// \brief return an iterator on the first element of the vector
265  const_iterator cbegin() const {
266  return const_iterator(storage(),0);
267  }
268 
269  /// \brief return an iterator after the last element of the vector
270  const_iterator cend() const {
271  return const_iterator(storage()+size(),size());
272  }
273 
274  /// \brief return an iterator on the first element of the vector
275  const_iterator begin() const {
276  return cbegin();
277  }
278 
279  /// \brief return an iterator after the last element of the vector
280  const_iterator end() const {
281  return cend();
282  }
283 
284  /// \brief Return an iterator on the first element of the vector
285  iterator begin(){
286  return iterator(storage(),0);
287  }
288 
289  /// \brief Return an iterator at the end of the vector
290  iterator end(){
291  return iterator(storage()+size(),size());
292  }
293 
294  /////////////////sparse interface///////////////////////////////
295  iterator set_element(iterator pos, index_type index, value_type value) {
296  SIZE_CHECK(pos.index() == index);
297  (*this)(index) = value;
298 
299  return pos;
300  }
301 
302  iterator clear_element(iterator pos) {
303  SIZE_CHECK(pos != end());
304  v(pos.index()) = value_type();
305 
306  //return new iterator to the next element
307  return pos+1;
308  }
309 
310  iterator clear_range(iterator start, iterator end) {
311  RANGE_CHECK(start <= end);
312  std::fill(start,end,value_type());
313  return end;
314  }
315 
316  void reserve(size_type) {}
317 
318  /// \brief Swap the content of two vectors
319  /// \param v1 is the first vector. It takes values from v2
320  /// \param v2 is the second vector It takes values from v1
321  friend void swap(vector& v1, vector& v2) {
322  v1.m_storage.swap(v2.m_storage);
323  }
324  // -------------
325  // Serialization
326  // -------------
327 
328  /// Serialize a vector into and archive as defined in Boost
329  /// \param ar Archive object. Can be a flat file, an XML file or any other stream
330  /// \param file_version Optional file version (not yet used)
331  template<class Archive>
332  void serialize(Archive &ar, const unsigned int file_version) {
333  boost::serialization::collection_size_type count(size());
334  ar & count;
335  if(!Archive::is_saving::value){
336  resize(count);
337  }
338  if (!empty())
339  ar & boost::serialization::make_array(storage(),size());
340  (void) file_version;//prevent warning
341  }
342 
343 private:
344  array_type m_storage;
345 };
346 
347 template<class T>
348 struct vector_temporary_type<T,dense_random_access_iterator_tag>{
349  typedef vector<T> type;
350 };
351 
352 template<class T>
353 struct const_expression<vector<T> >{
354  typedef vector<T> const type;
355 };
356 template<class T>
357 struct const_expression<vector<T> const>{
358  typedef vector<T> const type;
359 };
360 
361 }
362 }
363 
364 #endif